summaryrefslogtreecommitdiff
path: root/tex/context/base/font-tfm.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2008-10-31 13:58:00 +0100
committerHans Hagen <pragma@wxs.nl>2008-10-31 13:58:00 +0100
commit94d83f84758766511c5e324721e39fea6ab71dae (patch)
treef167feb88a41f95f09e3b9cee5f2db2f765de38e /tex/context/base/font-tfm.lua
parent560319dff7b42057a116447a8043b59d56d21cd8 (diff)
downloadcontext-94d83f84758766511c5e324721e39fea6ab71dae.tar.gz
stable 2008.10.31 13:58
Diffstat (limited to 'tex/context/base/font-tfm.lua')
-rw-r--r--tex/context/base/font-tfm.lua208
1 files changed, 120 insertions, 88 deletions
diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua
index 02f5c45a6..1955b58bc 100644
--- a/tex/context/base/font-tfm.lua
+++ b/tex/context/base/font-tfm.lua
@@ -48,7 +48,6 @@ function tfm.enhance(tfmdata,specification)
if fonts.trace then
logs.report("define font","mapping %s onto %s",k,v)
end
- -- characters[k] = characters[v]
characters[k] = original[v]
end
end
@@ -76,6 +75,7 @@ function tfm.read_from_tfm(specification)
end
tfmdata = font.read_tfm(fname,specification.size) -- not cached, fast enough
if tfmdata then
+ tfmdata.descriptions = tfmdata.descriptions or { }
if tfm.resolve_vf then
fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here
fname = input.findbinfile(specification.name, 'ovf')
@@ -90,7 +90,6 @@ function tfm.read_from_tfm(specification)
tfmdata.fonts = vfdata.fonts
end
end
---~ print(table.serialize(tfmdata))
end
tfm.enhance(tfmdata,specification)
end
@@ -139,14 +138,6 @@ function tfm.scaled(scaledpoints, designsize) -- handles designsize in sp as wel
end
end
---~ function tfm.scaled(scaledpoints, designsize)
---~ if scaledpoints < 0 then
---~ return (- scaledpoints/1000) * (designsize or 10) * tfm.factor
---~ else
---~ return scaledpoints
---~ end
---~ end
-
--[[ldx--
<p>Before a font is passed to <l n='tex'/> we scale it. Here we also need
to scale virtual characters.</p>
@@ -191,6 +182,7 @@ function tfm.do_scale(tfmtable, scaledpoints)
if scaledpoints < 0 then
scaledpoints = (- scaledpoints/1000) * tfmtable.designsize -- already in sp
end
+--~ print(">>>",tfmtable.units)
local delta = scaledpoints/(tfmtable.units or 1000) -- brr, some open type fonts have 2048
local t = { }
t.factor = delta
@@ -213,27 +205,37 @@ function tfm.do_scale(tfmtable, scaledpoints)
tp.extra_space = (tfmp.extra_space or tfmp[7] or 0)*delta
local protrusionfactor = (tp.quad ~= 0 and 1000/tp.quad) or 0
local tc = t.characters
+ -- we can loop over (descriptions or characters), in which case
+ -- we don't need to init characters in afm/otf (saves some mem)
+ -- but then .. beware of protruding etc
+ local descriptions = tfmtable.descriptions or { }
+ t.descriptions = descriptions
+ local nameneeded = not tfmtable.shared.otfdata --hack
+-- loop over descriptions
+ -- afm and otf have descriptions, tfm not
for k,v in pairs(tfmtable.characters) do
- local description = v.description or v -- shared data
- local chr = {
- description = description,
- unicode = description.unicode,
- name = description.name,
- index = description.index or k,
- width = delta*(description.width or 0),
- height = delta*(description.height or 0),
- depth = delta*(description.depth or 0),
- class = description.class
- }
+ local description = descriptions[k] or v
+ local chr
+ -- there is no need (yet) to assign a value to chr.tonunicode
+ if nameneeded then
+ chr = {
+ name = description.name, -- is this used at all?
+ index = description.index or k,
+ width = delta*(description.width or 0),
+ height = delta*(description.height or 0),
+ depth = delta*(description.depth or 0),
+ }
+ else
+ chr = {
+ index = description.index or k,
+ width = delta*(description.width or 0),
+ height = delta*(description.height or 0),
+ depth = delta*(description.depth or 0),
+ }
+ end
if trace then
- logs.report("define font","n=%s, u=%s, i=%s, n=%s c=%s",k,description.unicode,description.index,description.name or '-',description.class or '-')
- end
- -- local vb = v.boundingbox
- -- if vb then
- -- chr.boundingbox = { vb[1]*delta, vb[2]*delta, vb[3]*delta, vb[4]*delta }
- -- else
- -- -- chr.boundingbox = zerobox -- most afm en otf files have bboxes so ..
- -- end
+ logs.report("define font","t=%s, u=%s, i=%s, n=%s c=%s",k,chr.tounicode or k,description.index,description.name or '-',description.class or '-')
+ end
local ve = v.expansion_factor
if ve then
chr.expansion_factor = ve*1000 -- expansionfactor
@@ -274,7 +276,8 @@ function tfm.do_scale(tfmtable, scaledpoints)
local ok = false
for i=1,#vc do
local key = vc[i][1]
- if key == "right" or key == "left" or key == "down" or key == "up" then
+ -- if key == "right" or key == "left" or key == "down" or key == "up" then
+ if key == "right" or key == "down" then
ok = true
break
end
@@ -284,7 +287,8 @@ function tfm.do_scale(tfmtable, scaledpoints)
for i=1,#vc do
local ivc = vc[i]
local key = ivc[1]
- if key == "right" or key == "left" or key == "down" or key == "up" then
+ -- if key == "right" or key == "left" or key == "down" or key == "up" then
+ if key == "right" or key == "down" then
tt[#tt+1] = { key, ivc[2]*delta }
else -- not comment
tt[#tt+1] = ivc -- shared since in cache and untouched
@@ -316,17 +320,22 @@ tfm.auto_cleanup = true
local lastfont = nil
-function tfm.cleanup(tfmdata) -- we need a cleanup callback, now we miss the last one
+-- we can get rid of the tfm instance when we hav efast access to the
+-- scaled character dimensions at the tex end, e.g. a fontobject.width
+
+function tfm.cleanup_table(tfmdata) -- we need a cleanup callback, now we miss the last one
if tfm.auto_cleanup then -- ok, we can hook this into everyshipout or so ... todo
- if lastfont and lastfont.type == 'virtual' then
- for k, v in pairs(lastfont.characters) do
+ if tfmdata.type == 'virtual' then
+ for k, v in pairs(tfmdata.characters) do
if v.commands then v.commands = nil end
end
end
- lastfont = type(tfmdata) == "table" and tfmdata
end
end
+function tfm.cleanup(tfmdata) -- we need a cleanup callback, now we miss the last one
+end
+
function tfm.scale(tfmtable, scaledpoints)
local t, factor = tfm.do_scale(tfmtable, scaledpoints)
t.factor = factor
@@ -357,12 +366,25 @@ function fonts.logger.save(tfmtable,source,specification) -- save file name in s
end
end
+--~ function fonts.logger.report(separator)
+--~ local s = table.sortedkeys(fonts.loaded)
+--~ if #s > 0 then
+--~ local t = { }
+--~ for _,v in ipairs(s) do
+--~ t[#t+1] = v .. ":" .. fonts.loaded[v].source
+--~ end
+--~ return table.concat(t,separator or " ")
+--~ else
+--~ return "none"
+--~ end
+--~ end
+
function fonts.logger.report(separator)
- local s = table.sortedkeys(fonts.loaded)
+ local s = table.sortedkeys(fonts.used)
if #s > 0 then
local t = { }
for _,v in ipairs(s) do
- t[#t+1] = v .. ":" .. fonts.loaded[v].source
+ t[#t+1] = v .. ":" .. fonts.used[v]
end
return table.concat(t,separator or " ")
else
@@ -461,30 +483,31 @@ do
function fonts.initializers.common.encoding(tfmdata,value)
if value then
- local encodingfile = value .. '.enc'
- local encoding = fonts.enc.load(encodingfile)
- if encoding then
- -- tfmdata.encoding = value
- local vector = encoding.vector
- local afmdata = tfmdata.shared.afmdata
- local characters = tfmdata.characters
- local unicodes = afmdata.luatex.unicodes
- local function remap(pattern,name)
- local p = pattern:match(name)
- if p then
- local oldchr, newchr = unicodes[p], unicodes[name]
- if oldchr and newchr then
- -- logs.report("encoding","%s (%s) -> %s (%s)",p,oldchr or -1,name,newchr or -1)
- characters[oldchr] = characters[newchr]
+ local afmdata = tfmdata.shared.afmdata
+ if afmdata then
+ local encodingfile = value .. '.enc'
+ local encoding = fonts.enc.load(encodingfile)
+ if encoding then
+ local vector = encoding.vector
+ local characters = tfmdata.characters
+ local unicodes = afmdata.luatex.unicodes
+ local function remap(pattern,name)
+ local p = pattern:match(name)
+ if p then
+ local oldchr, newchr = unicodes[p], unicodes[name]
+ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+ -- logs.report("encoding","%s (%s) -> %s (%s)",p,oldchr or -1,name,newchr or -1)
+ characters[oldchr] = characters[newchr]
+ end
end
+ return p
+ end
+ for _, name in pairs(vector) do
+ local ok = remap(smallcaps,name) or remap(oldstyle,name)
+ end
+ if fonts.map.data[tfmdata.name] then
+ fonts.map.data[tfmdata.name].encoding = encodingfile
end
- return p
- end
- for _, name in pairs(vector) do
- local ok = remap(smallcaps,name) or remap(oldstyle,name)
- end
- if fonts.map.data[tfmdata.name] then
- fonts.map.data[tfmdata.name].encoding = encodingfile
end
end
end
@@ -495,17 +518,20 @@ do
function fonts.initializers.common.remap(tfmdata,value,pattern) -- will go away
if value then
local afmdata = tfmdata.shared.afmdata
- local characters = tfmdata.characters
- local unicodes = afmdata.luatex.unicodes
- local done = false
- for i, blob in pairs(characters) do
- local name = blob.description.name
- if name then
- local p = pattern:match(name)
- if p then
- local oldchr, newchr = unicodes[p], unicodes[name]
- if oldchr and newchr then
- characters[oldchr] = characters[newchr]
+ if afmdata then
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local unicodes = afmdata.luatex.unicodes
+ local done = false
+ for u, _ in pairs(characters) do
+ local name = descriptions[u].name
+ if name then
+ local p = pattern:match(name)
+ if p then
+ local oldchr, newchr = unicodes[p], unicodes[name]
+ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+ characters[oldchr] = characters[newchr]
+ end
end
end
end
@@ -524,16 +550,19 @@ do
if value then
-- todo: scale down
local afmdata = tfmdata.shared.afmdata
- local characters = tfmdata.characters
- local unicodes = afmdata.luatex.unicodes
- for i, blob in pairs(characters) do
- local name = blob.description.name
- if name then
- local p = name:lower()
- if p then
- local oldchr, newchr = unicodes[p], unicodes[name]
- if oldchr and newchr then
- characters[oldchr] = characters[newchr]
+ if afmdata then
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local unicodes = afmdata.luatex.unicodes
+ for u, _ in pairs(characters) do
+ local name = descriptions[u].name
+ if name then
+ local p = name:lower()
+ if p then
+ local oldchr, newchr = unicodes[p], unicodes[name]
+ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+ characters[oldchr] = characters[newchr]
+ end
end
end
end
@@ -574,13 +603,15 @@ do
-- an example analyzer
function fonts.analyzers.aux.setstate(head,font)
- local characters = fontdata[font].characters
+ local tfmdata = fontdata[font]
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean
while current do
if current.id == glyph and current.font == font then
- local c = characters[current.char]
- if c then
- if c.description.class == "mark" then
+ local d = descriptions[current.char]
+ if d then
+ if d.class == "mark" then
done = true
set_attribute(current,state,5) -- mark
elseif n == 0 then
@@ -632,11 +663,12 @@ do
function fonts.pushmarks(head,font)
local tfmdata = fontdata[font]
local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
local current, last, done, n = head, nil, false, 0
while current do
if current.id == glyph and current.font == font then
- local c = characters[current.char]
- if c and c.description.class == "mark" then
+ local d = descriptions[current.char]
+ if d and d.class == "mark" then
-- check if head
if last and not last.components then
last.components = current
@@ -677,9 +709,9 @@ do
end
function fonts.removemarks(head,font)
- local current, done, characters = head, false, tfmdata.characters
+ local current, done, characters, descriptions = head, false, tfmdata.characters, tfmdata.descriptions
while current do
- if current.id == glyph and current.font == font and characters[current.char].description.class == "mark" then
+ if current.id == glyph and current.font == font and descriptions[current.char].class == "mark" then
local next, prev = current.next, current.prev
if next then
next.prev = prev