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 newdata.width = urx - llx
72 newdata.height = ury
73 newdata.depth = -lly
74 newdata.unicode = unicode
75
76 if llx ~= 0 then
77 newdata.commands = { { "offset", -llx, 0 }, newdata.commands[1] }
78 end
79
80 characters[unicode] = newdata
81
82 addcharacters(fontid, { characters = { [unicode] = newdata } })
83 return fontid, unicode
84 else
85 logs.report("metaglyph", "bad shape %U in font %i", unicode, fontid)
86 end
87 end
88end
89
90local function setmetaglyph(specification)
91 if specification then
92 local category = specification.category
93 local name = specification.name
94 if category and name then
95 local fontid = specification.fontid or currentfont()
96 local private = newprivateslot(name)
97 register(fontid,private,function(font,char)
98 return setmetaglyphs(category,font,char,specification) end
99 )
100 checkenabled()
101 end
102 end
103end
104
105local function initializempf(tfmdata,kind,value)
106 local metafont = metafonts[value]
107 if value then
108 local font = tfmdata.properties.id
109 for char, spec in sortedhash(metafont) do
110 local char = type(char) == "string" and newprivateslot(char) or char
111 register(font,char,function(font,char)
112 return setmetaglyphs(value,font,char,spec)
113 end)
114 end
115 checkenabled()
116 end
117end
118
119fonts.helpers.setmetaglyphs = setmetaglyphs
120fonts.helpers.setmetaglyph = setmetaglyph
121
122otfregister {
123 name = "metafont",
124 description = "metafont glyphs",
125 manipulators = {
126 base = initializempf,
127 node = initializempf,
128 }
129}
130
131do
132
133 local scanners = tokens.scanners
134 local scanopen = scanners.scanopen
135 local scanclose = scanners.scanclose
136 local scanword = scanners.word
137 local scanstring = scanners.string
138
139 interfaces.implement {
140 name = "setmetaglyph",
141 public = true,
142 protected = true,
143 actions = function(t)
144 local t = { }
145 if scanopen() then
146 while not scanclose() do
147 local key = scanword()
148 if key == "shapes" then
149 if scanopen() then
150 local tt = { }
151 local nn = 0
152 while not scanclose() do
153 if scanopen() then
154 local ttt = { }
155 while not scanclose() do
156 local key = scanword()
157 ttt[key] = scanstring()
158 end
159 nn= nn + 1
160 tt[nn] = ttt
161 end
162 end
163 t[key] = tt
164 end
165 else
166 t[key] = scanstring()
167 end
168 end
169 end
170 setmetaglyph(t)
171 end
172 }
173
174end
175 |