1if not modules then modules = { } end modules ['font-mpf'] = {
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 tonumber, unpack, type = tonumber, unpack, type
10
11local context = context
12local metapost = metapost
13
14local metafonts = { }
15metapost.metafonts = metafonts
16
17local sortedhash = table.sortedhash
18
19local addcharacters = fonts.constructors.addcharacters
20local fontdata = fonts.hashes.identifiers
21
22local otf = fonts.handlers.otf
23local otfregister = otf.features.register
24
25local getshapes = fonts.dropins.getshapes
26
27local setparameterset = metapost.setparameterset
28local simplemetapost = metapost.simple
29
30local register = fonts.collections.register
31local checkenabled = fonts.collections.checkenabled
32local newprivateslot = fonts.helpers.newprivateslot
33
34local currentfont = font.current
35
36local function setmetaglyphs(category,fontid,unicode,specification)
37 if unicode then
38 local tfmdata = fontdata[fontid]
39 local characters = tfmdata.characters
40 specification.unicode = unicode
41 specification.category = category
42
43
44
45
46 local code = specification.code
47 if code then
48 setparameterset("mpsfont",specification)
49
50 simplemetapost("simplefun",code)
51
52 end
53
54
55 local shapes = getshapes(category)
56 local units = shapes.parameters.units
57 local scale = tfmdata.parameters.size / units
58 local shape = shapes.glyphs[unicode]
59 if shape then
60
61 local llx, lly, urx, ury = unpack(shape.boundingbox)
62 llx = llx * scale
63 urx = urx * scale
64 lly = lly * scale
65 ury = ury * scale
66
67 local newdata = { }
68 characters[unicode] = newdata
69 fonts.dropins.swapone("mps",tfmdata,shape,unicode)
70
71 local olddata = characters[unicode]
72 newdata.width = urx - llx
73 newdata.height = ury
74 newdata.depth = -lly
75 newdata.unicode = unicode
76
77 if llx ~= 0 then
78 newdata.commands = { { "offset", -llx, 0 }, newdata.commands[1] }
79 end
80
81 characters[unicode] = newdata
82
83 addcharacters(fontid, { characters = { [unicode] = newdata } })
84 return fontid, unicode
85 else
86 logs.report("metaglyph", "bad shape %U in font %i", unicode, fontid)
87 end
88 end
89end
90
91local function setmetaglyph(specification)
92 if specification then
93 local category = specification.category
94 local name = specification.name
95 if category and name then
96 local fontid = specification.fontid or currentfont()
97 local private = newprivateslot(name)
98 register(fontid,private,function(font,char)
99 return setmetaglyphs(category,font,char,specification) end
100 )
101 checkenabled()
102 end
103 end
104end
105
106local function initializempf(tfmdata,kind,value)
107 local metafont = metafonts[value]
108 if value then
109 local font = tfmdata.properties.id
110 for char, spec in sortedhash(metafont) do
111 if type(char) == "string" then
112 char = newprivateslot(char)
113 end
114 register(font,char,function(font,char)
115 return setmetaglyphs(value,font,char,spec)
116 end)
117 end
118 checkenabled()
119 end
120end
121
122fonts.helpers.setmetaglyphs = setmetaglyphs
123fonts.helpers.setmetaglyph = setmetaglyph
124
125otfregister {
126 name = "metafont",
127 description = "metafont glyphs",
128 manipulators = {
129 base = initializempf,
130 node = initializempf,
131 }
132}
133
134do
135
136 local scanners = tokens.scanners
137 local scanopen = scanners.scanopen
138 local scanclose = scanners.scanclose
139 local scanword = scanners.word
140 local scanstring = scanners.string
141
142 interfaces.implement {
143 name = "setmetaglyph",
144 public = true,
145 protected = true,
146 actions = function(t)
147 local t = { }
148 if scanopen() then
149 while not scanclose() do
150 local key = scanword()
151 if key == "shapes" then
152 if scanopen() then
153 local tt = { }
154 local nn = 0
155 while not scanclose() do
156 if scanopen() then
157 local ttt = { }
158 while not scanclose() do
159 local key = scanword()
160 ttt[key] = scanstring()
161 end
162 nn= nn + 1
163 tt[nn] = ttt
164 end
165 end
166 t[key] = tt
167 end
168 else
169 t[key] = scanstring()
170 end
171 end
172 end
173 setmetaglyph(t)
174 end
175 }
176
177end
178 |