1if not modules then modules = { } end modules ['font-imp-scripts'] = {
2 version = 1.001,
3 comment = "companion to font-ini.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local getrange = characters.getrange
10
11local settings_to_hash = utilities.parsers.settings_to_hash
12
13if not context then return end
14
15
16
17local next, type, tonumber = next, type, tonumber
18local gmatch = string.gmatch
19local max = math.max
20
21local fonts = fonts
22local utilities = utilities
23
24local helpers = fonts.helpers
25local charcommand = helpers.commands.char
26local downcommand = helpers.commands.down
27local upcommand = helpers.commands.up
28
29local handlers = fonts.handlers
30local otf = handlers.otf
31local afm = handlers.afm
32local registerotffeature = otf.features.register
33local registerafmfeature = afm.features.register
34
35local settings_to_hash = utilities.parsers.settings_to_hash
36local sortedhash = table.sortedhash
37
38local handlers = fonts.handlers
39
40local sup = nil
41local sub = nil
42
43local function initialize(tfmdata,key,value)
44
45 if not sup then
46 sup = { }
47 sub = { }
48 for unicode, data in next, characters.data do
49 local specials = data.specials
50 if specials then
51 local what = specials[1]
52 if what == "super" then
53 sup[unicode] = specials[2]
54 elseif what == "sub" then
55 sub[unicode] = specials[2]
56 end
57 end
58 end
59 end
60
61 local spec
62 if value == true then
63 spec = { factor = 3/5, up = 5/4, down = 1/4 }
64 elseif type(value) == "number" then
65 spec = { factor = value, up = 5/4, down = 1/4 }
66 else
67 spec = settings_to_hash(value)
68 end
69 local factor = tonumber(spec.factor) or 3/5
70 local up = tonumber(spec.up) or 5/4
71 local down = tonumber(spec.down) or 1/4
72
73 local characters = tfmdata.characters
74 local parameters = tfmdata.parameters
75 local up = parameters.xheight * up
76 local down = -parameters.xheight * down
77
78 local function add(unicode,other,go_up)
79 local old = characters[other]
80 if old then
81 local shift = go_up and up or down
82 local width = (old.width or 0) * factor
83 local height = (old.height or 0) * factor + shift
84 local depth = go_up and 0 or max((old.depth or 0) * factor + down,0)
85 characters[unicode] = {
86 width = width,
87 height = height,
88 depth = depth,
89 commands = { { "offset", 0, shift, other, factor, factor } },
90
91
92
93
94 }
95 end
96 end
97 for unicode, other in sortedhash(sup) do
98 add(unicode,other,true)
99 end
100 for unicode, other in sortedhash(sub) do
101 add(unicode,other,false)
102 end
103end
104
105local specification = {
106 name = "scripts",
107 description = "add superiors and inferiors",
108 manipulators = {
109 base = initialize,
110 node = initialize,
111 }
112}
113
114registerotffeature(specification)
115registerafmfeature(specification)
116
117
118
119local function initialize(tfmdata,key,value)
120 if value then
121 local detail = type(value) == "string" and settings_to_hash(value) or { }
122 local orientation = tonumber(detail.orientation) or 0
123 if orientation == 1 or orientation == 3 then
124 local characters = tfmdata.characters
125 local parameters = tfmdata.parameters
126 local emwidth = parameters.quad
127 local exheight = parameters.xheight
128 local ranges = detail.ranges
129 local downshift = exheight * (tonumber(detail.down) or 0)
130 local rightshift = exheight * (tonumber(detail.right) or 0)
131 local orientate
132 if orientation == 1 then
133 orientate = function(character)
134 local width = character.width or 0
135 local height = character.height or 0
136 local depth = character.depth or 0
137 character.width = height + depth + rightshift + rightshift
138 character.height = width - downshift
139 character.depth = shift
140 character.xoffset = depth + rightshift
141 character.yoffset = width - downshift
142 character.orientation = orientation
143 end
144 else
145 orientate = function(character)
146 local width = character.width or 0
147 local height = character.height or 0
148 local depth = character.depth or 0
149
150 character.height = width - downshift
151 character.depth = shift
152
153
154
155 end
156 end
157 if ranges then
158 for s in gmatch(ranges,"[^, ]+") do
159 local start, stop, description, gaps = getrange(s,true)
160 if start and stop then
161 for unicode=start,stop do
162 local character = characters[unicode]
163 if character then
164 orientate(character)
165 end
166 end
167 end
168 end
169 else
170 for unicode, character in next, characters do
171 orientate(character)
172 end
173 end
174 end
175 end
176end
177
178local specification = {
179 name = "vertical",
180 description = "vertical",
181 manipulators = {
182 base = initialize,
183 node = initialize,
184 }
185}
186
187registerotffeature(specification)
188registerafmfeature(specification)
189 |