summaryrefslogtreecommitdiff
path: root/otfl-font-tfm.lua
diff options
context:
space:
mode:
Diffstat (limited to 'otfl-font-tfm.lua')
-rw-r--r--otfl-font-tfm.lua817
1 files changed, 21 insertions, 796 deletions
diff --git a/otfl-font-tfm.lua b/otfl-font-tfm.lua
index 5e841b2..b9bb1bd 100644
--- a/otfl-font-tfm.lua
+++ b/otfl-font-tfm.lua
@@ -1,813 +1,38 @@
-if not modules then modules = { } end modules ['font-tfm'] = {
+if not modules then modules = { } end modules ['luatex-fonts-tfm'] = {
version = 1.001,
- comment = "companion to font-ini.mkiv",
+ comment = "companion to luatex-*.tex",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-local utf = unicode.utf8
-
-local next, format, match, lower, gsub = next, string.format, string.match, string.lower, string.gsub
-local concat, sortedkeys, utfbyte, serialize = table.concat, table.sortedkeys, utf.byte, table.serialize
-
-local allocate = utilities.storage.allocate
-
-local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
-local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end)
-
-local report_defining = logs.reporter("fonts","defining")
-
--- tfmdata has also fast access to indices and unicodes
--- to be checked: otf -> tfm -> tfmscaled
---
--- watch out: no negative depths and negative eights permitted in regular fonts
-
---[[ldx--
-<p>Here we only implement a few helper functions.</p>
---ldx]]--
-
-local fonts = fonts
-local tfm = fonts.tfm
-
-fonts.loaded = allocate()
-fonts.dontembed = allocate()
-fonts.triggers = fonts.triggers or { } -- brrr
-fonts.initializers = fonts.initializers or { }
-fonts.initializers.common = fonts.initializers.common or { }
-
-local set_attribute = node.set_attribute
-local findbinfile = resolvers.findbinfile
-
-local readers = fonts.tfm.readers
-local fontdata = fonts.identifiers
-local nodecodes = nodes.nodecodes
-
-local disc_code = nodecodes.disc
-local glyph_code = nodecodes.glyph
-
---[[ldx--
-<p>The next function encapsulates the standard <l n='tfm'/> loader as
-supplied by <l n='luatex'/>.</p>
---ldx]]--
-
-tfm.resolvevirtualtoo = true -- false
-tfm.sharebasekerns = false -- true (.5 sec slower on mk but brings down mem from 410M to 310M, beware: then script/lang share too)
-tfm.mathactions = { }
-tfm.fontnamemode = "fullpath"
-
-tfm.enhance = tfm.enhance or function() end
-
-local function read_from_tfm(specification)
- local fname, tfmdata = specification.filename or "", nil
- if fname ~= "" then
- if trace_defining then
- report_defining("loading tfm file %s at size %s",fname,specification.size)
- end
- tfmdata = font.read_tfm(fname,specification.size) -- not cached, fast enough
- if tfmdata then
- tfmdata.descriptions = tfmdata.descriptions or { }
- if tfm.resolvevirtualtoo then
- fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here
- fname = findbinfile(specification.name, 'ovf')
- if fname and fname ~= "" then
- local vfdata = font.read_vf(fname,specification.size) -- not cached, fast enough
- if vfdata then
- local chars = tfmdata.characters
- for k,v in next, vfdata.characters do
- chars[k].commands = v.commands
- end
- tfmdata.type = 'virtual'
- tfmdata.fonts = vfdata.fonts
- end
- end
- end
- tfm.enhance(tfmdata,specification)
- end
- elseif trace_defining then
- report_defining("loading tfm with name %s fails",specification.name)
- end
- return tfmdata
-end
-
---[[ldx--
-<p>We need to normalize the scale factor (in scaled points). This has to
-do with the fact that <l n='tex'/> uses a negative multiple of 1000 as
-a signal for a font scaled based on the design size.</p>
---ldx]]--
-
-local factors = {
- pt = 65536.0,
- bp = 65781.8,
-}
-
-function tfm.setfactor(f)
- tfm.factor = factors[f or 'pt'] or factors.pt
-end
-
-tfm.setfactor()
-
-function tfm.scaled(scaledpoints, designsize) -- handles designsize in sp as well
- if scaledpoints < 0 then
- if designsize then
- if designsize > tfm.factor then -- or just 1000 / when? mp?
- return (- scaledpoints/1000) * designsize -- sp's
- else
- return (- scaledpoints/1000) * designsize * tfm.factor
- end
- else
- return (- scaledpoints/1000) * 10 * tfm.factor
- end
- 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>
---ldx]]--
-
---~ function tfm.getvirtualid(tfmdata)
---~ -- since we don't know the id yet, we use 0 as signal
---~ local tf = tfmdata.fonts
---~ if not tf then
---~ tfmdata.type = "virtual"
---~ tfmdata.fonts = { { id = 0 } }
---~ return 1
---~ else
---~ local ntf = #tf + 1
---~ tf[ntf] = { id = 0 }
---~ return ntf
---~ end
---~ end
-
-function tfm.getvirtualid(tfmdata)
- -- since we don't know the id yet, we use 0 as signal
- local tf = tfmdata.fonts
- if not tf then
- tf = { }
- tfmdata.type = "virtual"
- tfmdata.fonts = tf
- end
- local ntf = #tf + 1
- tf[ntf] = { id = 0 }
- return ntf
-end
-
-function tfm.checkvirtualid(tfmdata, id)
- if tfmdata and tfmdata.type == "virtual" then
- if not tfmdata.fonts or #tfmdata.fonts == 0 then
- tfmdata.type, tfmdata.fonts = "real", nil
- else
- local vfonts = tfmdata.fonts
- for f=1,#vfonts do
- local fnt = vfonts[f]
- if fnt.id and fnt.id == 0 then
- fnt.id = id
- end
- end
- end
- end
+if context then
+ texio.write_nl("fatal error: this module is not for context")
+ os.exit()
end
---[[ldx--
-<p>Beware, the boundingbox is passed as reference so we may not overwrite it
-in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to
-excessive memory usage in CJK fonts, we no longer pass the boundingbox.)</p>
---ldx]]--
-
-fonts.trace_scaling = false
-
--- the following hack costs a bit of runtime but safes memory
---
--- basekerns are scaled and will be hashed by table id
--- sharedkerns are unscaled and are be hashed by concatenated indexes
-
---~ function tfm.check_base_kerns(tfmdata)
---~ if tfm.sharebasekerns then
---~ local sharedkerns = tfmdata.sharedkerns
---~ if sharedkerns then
---~ local basekerns = { }
---~ tfmdata.basekerns = basekerns
---~ return sharedkerns, basekerns
---~ end
---~ end
---~ return nil, nil
---~ end
-
---~ function tfm.prepare_base_kerns(tfmdata)
---~ if tfm.sharebasekerns and not tfmdata.sharedkerns then
---~ local sharedkerns = { }
---~ tfmdata.sharedkerns = sharedkerns
---~ for u, chr in next, tfmdata.characters do
---~ local kerns = chr.kerns
---~ if kerns then
---~ local hash = concat(sortedkeys(kerns), " ")
---~ local base = sharedkerns[hash]
---~ if not base then
---~ sharedkerns[hash] = kerns
---~ else
---~ chr.kerns = base
---~ end
---~ end
---~ end
---~ end
---~ end
-
--- we can have cache scaled characters when we are in node mode and don't have
--- protruding and expansion: hash == fullname @ size @ protruding @ expansion
--- but in practice (except from mk) the otf hash will be enough already so it
--- makes no sense to mess up the code now
-
-local charactercache = { }
-
--- The scaler is only used for otf and afm and virtual fonts. If
--- a virtual font has italic correction make sure to set the
--- has_italic flag. Some more flags will be added in the future.
-
---[[ldx--
-<p>The reason why the scaler was originally split, is that for a while we experimented
-with a helper function. However, in practice the <l n='api'/> calls are too slow to
-make this profitable and the <l n='lua'/> based variant was just faster. A days
-wasted day but an experience richer.</p>
---ldx]]--
+local fonts = fonts
+local tfm = { }
+fonts.handlers.tfm = tfm
+fonts.formats.tfm = "type1" -- we need to have at least a value here
-tfm.autocleanup = true
-
-local lastfont = nil
-
--- we can get rid of the tfm instance when we have fast access to the
--- scaled character dimensions at the tex end, e.g. a fontobject.width
---
--- flushing the kern and ligature tables from memory saves a lot (only
--- base mode) but it complicates vf building where the new characters
--- demand this data .. solution: functions that access them
-
--- we don't need the glyph data as we can use the description .. but we will
--- have to wait till we can access the internal tfm table efficiently in which
--- case characters will become a metatable afterwards
-
-function tfm.cleanuptable(tfmdata) -- we need a cleanup callback, now we miss the last one
- if tfm.autocleanup then -- ok, we can hook this into everyshipout or so ... todo
- if tfmdata.type == 'virtual' or tfmdata.virtualized then
- for k, v in next, tfmdata.characters do
- if v.commands then v.commands = nil end
- -- if v.kerns then v.kerns = nil end
- end
- else
- -- for k, v in next, tfmdata.characters do
- -- if v.kerns then v.kerns = nil end
- -- end
- end
- end
-end
-
-function tfm.cleanup(tfmdata) -- we need a cleanup callback, now we miss the last one
-end
-
-function tfm.calculatescale(tfmtable, scaledpoints)
- if scaledpoints < 0 then
- scaledpoints = (- scaledpoints/1000) * tfmtable.designsize -- already in sp
- end
- local units = tfmtable.units or 1000
- local delta = scaledpoints/units -- brr, some open type fonts have 2048
- return scaledpoints, delta, units
-end
-
-function tfm.scale(tfmtable, scaledpoints, relativeid)
- -- tfm.prepare_base_kerns(tfmtable) -- optimalization
- local t = { } -- the new table
- local scaledpoints, delta, units = tfm.calculatescale(tfmtable, scaledpoints, relativeid)
- -- is just a trigger for the backend
- t.units_per_em = units or 1000
- --
- local hdelta, vdelta = delta, delta
- -- unicoded unique descriptions shared cidinfo characters changed parameters indices
- for k,v in next, tfmtable do
- if type(v) == "table" then
- -- print(k)
- else
- t[k] = v
- end
- end
- local extend_factor = tfmtable.extend_factor or 0
- if extend_factor ~= 0 and extend_factor ~= 1 then
- hdelta = hdelta * extend_factor
- t.extend = extend_factor * 1000
- else
- t.extend = 1000
- end
- local slant_factor = tfmtable.slant_factor or 0
- if slant_factor ~= 0 then
- t.slant = slant_factor * 1000
- else
- t.slant = 0
- end
- -- status
- local isvirtual = tfmtable.type == "virtual" or tfmtable.virtualized
- local hasmath = (tfmtable.mathparameters ~= nil and next(tfmtable.mathparameters) ~= nil) or (tfmtable.MathConstants ~= nil and next(tfmtable.MathConstants) ~= nil)
- local nodemode = tfmtable.mode == "node"
- local hasquality = tfmtable.auto_expand or tfmtable.auto_protrude
- local hasitalic = tfmtable.has_italic
- local descriptions = tfmtable.descriptions or { }
- --
- if hasmath then
- t.has_math = true -- this will move to elsewhere
- end
- --
- t.parameters = { }
- t.characters = { }
- t.MathConstants = { }
- -- fast access
- t.unscaled = tfmtable -- the original unscaled one (temp)
- t.unicodes = tfmtable.unicodes
- t.indices = tfmtable.indices
- t.marks = tfmtable.marks
- -- this will move to some subtable so that it is copied at once
- t.goodies = tfmtable.goodies
- t.colorscheme = tfmtable.colorscheme
- t.postprocessors = tfmtable.postprocessors
- --
- -- t.embedding = tfmtable.embedding
- t.descriptions = descriptions
- if tfmtable.fonts then
- t.fonts = table.fastcopy(tfmtable.fonts) -- hm also at the end
- end
- local tp = t.parameters
- local mp = t.mathparameters
- local tfmp = tfmtable.parameters -- let's check for indexes
- --
- tp.slant = (tfmp.slant or tfmp[1] or 0)
- tp.space = (tfmp.space or tfmp[2] or 0)*hdelta
- tp.space_stretch = (tfmp.space_stretch or tfmp[3] or 0)*hdelta
- tp.space_shrink = (tfmp.space_shrink or tfmp[4] or 0)*hdelta
- tp.x_height = (tfmp.x_height or tfmp[5] or 0)*vdelta
- tp.quad = (tfmp.quad or tfmp[6] or 0)*hdelta
- tp.extra_space = (tfmp.extra_space or tfmp[7] or 0)*hdelta
- local protrusionfactor = (tp.quad ~= 0 and 1000/tp.quad) or 0
- local tc = t.characters
- local characters = tfmtable.characters
- local nameneeded = not tfmtable.shared.otfdata --hack
- local changed = tfmtable.changed or { } -- for base mode
- local ischanged = changed and next(changed)
- local indices = tfmtable.indices
- local luatex = tfmtable.luatex
- local tounicode = luatex and luatex.tounicode
- local defaultwidth = luatex and luatex.defaultwidth or 0
- local defaultheight = luatex and luatex.defaultheight or 0
- local defaultdepth = luatex and luatex.defaultdepth or 0
- -- experimental, sharing kerns (unscaled and scaled) saves memory
- -- local sharedkerns, basekerns = tfm.check_base_kerns(tfmtable)
- -- loop over descriptions (afm and otf have descriptions, tfm not)
- -- there is no need (yet) to assign a value to chr.tonunicode
- local scaledwidth = defaultwidth * hdelta
- local scaledheight = defaultheight * vdelta
- local scaleddepth = defaultdepth * vdelta
- local stackmath = tfmtable.ignore_stack_math ~= true
- local private = fonts.privateoffset
- local sharedkerns = { }
- for k,v in next, characters do
- local chr, description, index
- if ischanged then
- -- basemode hack
- local c = changed[k]
- if c then
- description = descriptions[c] or v
- v = characters[c] or v
- index = (indices and indices[c]) or c
- else
- description = descriptions[k] or v
- index = (indices and indices[k]) or k
- end
- else
- description = descriptions[k] or v
- index = (indices and indices[k]) or k
- end
- local width = description.width
- local height = description.height
- local depth = description.depth
- if width then width = hdelta*width else width = scaledwidth end
- if height then height = vdelta*height else height = scaledheight end
- -- if depth then depth = vdelta*depth else depth = scaleddepth end
- if depth and depth ~= 0 then
- depth = delta*depth
- if nameneeded then
- chr = {
- name = description.name,
- index = index,
- height = height,
- depth = depth,
- width = width,
- }
- else
- chr = {
- index = index,
- height = height,
- depth = depth,
- width = width,
- }
- end
+function fonts.readers.tfm(specification)
+ local fullname = specification.filename or ""
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ fullname = specification.name .. "." .. forced
else
- -- this saves a little bit of memory time and memory, esp for big cjk fonts
- if nameneeded then
- chr = {
- name = description.name,
- index = index,
- height = height,
- width = width,
- }
- else
- chr = {
- index = index,
- height = height,
- width = width,
- }
- end
- end
- -- if trace_scaling then
- -- report_defining("t=%s, u=%s, i=%s, n=%s c=%s",k,chr.tounicode or "",index or 0,description.name or '-',description.class or '-')
- -- end
- if tounicode then
- local tu = tounicode[index] -- nb: index!
- if tu then
- chr.tounicode = tu
- end
- end
- if hasquality then
- -- we could move these calculations elsewhere (saves calculations)
- local ve = v.expansion_factor
- if ve then
- chr.expansion_factor = ve*1000 -- expansionfactor, hm, can happen elsewhere
- end
- local vl = v.left_protruding
- if vl then
- chr.left_protruding = protrusionfactor*width*vl
- end
- local vr = v.right_protruding
- if vr then
- chr.right_protruding = protrusionfactor*width*vr
- end
- end
- -- todo: hasitalic
- if hasitalic then
- local vi = description.italic or v.italic
- if vi and vi ~= 0 then
- chr.italic = vi*hdelta
- end
- end
- -- to be tested
- if hasmath then
- -- todo, just operate on descriptions.math
- local vn = v.next
- if vn then
- chr.next = vn
- --~ if v.vert_variants or v.horiz_variants then
- --~ report_defining("glyph 0x%05X has combination of next, vert_variants and horiz_variants",index)
- --~ end
- else
- local vv = v.vert_variants
- if vv then
- local t = { }
- for i=1,#vv do
- local vvi = vv[i]
- t[i] = {
- ["start"] = (vvi["start"] or 0)*vdelta,
- ["end"] = (vvi["end"] or 0)*vdelta,
- ["advance"] = (vvi["advance"] or 0)*vdelta,
- ["extender"] = vvi["extender"],
- ["glyph"] = vvi["glyph"],
- }
- end
- chr.vert_variants = t
- --~ local ic = v.vert_italic_correction
- --~ if ic then
- --~ chr.italic = ic * hdelta
- --~ print(format("0x%05X -> %s",k,chr.italic))
- --~ end
- else
- local hv = v.horiz_variants
- if hv then
- local t = { }
- for i=1,#hv do
- local hvi = hv[i]
- t[i] = {
- ["start"] = (hvi["start"] or 0)*hdelta,
- ["end"] = (hvi["end"] or 0)*hdelta,
- ["advance"] = (hvi["advance"] or 0)*hdelta,
- ["extender"] = hvi["extender"],
- ["glyph"] = hvi["glyph"],
- }
- end
- chr.horiz_variants = t
- end
- end
- end
- local vt = description.top_accent
- if vt then
- chr.top_accent = vdelta*vt
- end
- if stackmath then
- local mk = v.mathkerns
- if mk then
- local kerns = { }
- local v = mk.top_right if v then local k = { } for i=1,#v do local vi = v[i]
- k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern }
- end kerns.top_right = k end
- local v = mk.top_left if v then local k = { } for i=1,#v do local vi = v[i]
- k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern }
- end kerns.top_left = k end
- local v = mk.bottom_left if v then local k = { } for i=1,#v do local vi = v[i]
- k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern }
- end kerns.bottom_left = k end
- local v = mk.bottom_right if v then local k = { } for i=1,#v do local vi = v[i]
- k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern }
- end kerns.bottom_right = k end
- chr.mathkern = kerns -- singular
- end
- end
- end
- if not nodemode then
- local vk = v.kerns
- if vk then
- --~ if sharedkerns then
- --~ local base = basekerns[vk] -- hashed by table id, not content
- --~ if not base then
- --~ base = {}
- --~ for k,v in next, vk do base[k] = v*hdelta end
- --~ basekerns[vk] = base
- --~ end
- --~ chr.kerns = base
- --~ else
- --~ local tt = {}
- --~ for k,v in next, vk do tt[k] = v*hdelta end
- --~ chr.kerns = tt
- --~ end
- local s = sharedkerns[vk]
- if not s then
- s = { }
- for k,v in next, vk do s[k] = v*hdelta end
- sharedkerns[vk] = s
- end
- chr.kerns = s
- end
- local vl = v.ligatures
- if vl then
- if true then
- chr.ligatures = vl -- shared
- else
- local tt = { }
- for i,l in next, vl do
- tt[i] = l
- end
- chr.ligatures = tt
- end
- end
+ fullname = specification.name
end
- if isvirtual then
- local vc = v.commands
- if vc then
- -- we assume non scaled commands here
- -- tricky .. we need to scale pseudo math glyphs too
- -- which is why we deal with rules too
- local ok = false
- for i=1,#vc do
- local key = vc[i][1]
- if key == "right" or key == "down" then
- ok = true
- break
- end
- end
- if ok then
- local tt = { }
- for i=1,#vc do
- local ivc = vc[i]
- local key = ivc[1]
- if key == "right" then
- tt[i] = { key, ivc[2]*hdelta }
- elseif key == "down" then
- tt[i] = { key, ivc[2]*vdelta }
- elseif key == "rule" then
- tt[i] = { key, ivc[2]*vdelta, ivc[3]*hdelta }
- else -- not comment
- tt[i] = ivc -- shared since in cache and untouched
- end
- end
- chr.commands = tt
- else
- chr.commands = vc
- end
- chr.index = nil
- end
- end
- tc[k] = chr
- end
- -- t.encodingbytes, t.filename, t.fullname, t.name: elsewhere
- t.size = scaledpoints
- t.factor = delta
- t.hfactor = hdelta
- t.vfactor = vdelta
- if t.fonts then
- t.fonts = table.fastcopy(t.fonts) -- maybe we virtualize more afterwards
- end
- if hasmath then
- -- mathematics.extras.copy(t) -- can be done elsewhere if needed
- local ma = tfm.mathactions
- for i=1,#ma do
- ma[i](t,tfmtable,delta,hdelta,vdelta) -- what delta?
- end
- end
- -- needed for \high cum suis
- local tpx = tp.x_height
- if hasmath then
- if not tp[13] then tp[13] = .86*tpx end -- mathsupdisplay
- if not tp[14] then tp[14] = .86*tpx end -- mathsupnormal
- if not tp[15] then tp[15] = .86*tpx end -- mathsupcramped
- if not tp[16] then tp[16] = .48*tpx end -- mathsubnormal
- if not tp[17] then tp[17] = .48*tpx end -- mathsubcombined
- if not tp[22] then tp[22] = 0 end -- mathaxisheight
- if t.MathConstants then t.MathConstants.AccentBaseHeight = nil end -- safeguard
- end
- t.tounicode = 1
- t.cidinfo = tfmtable.cidinfo
- -- we have t.name=metricfile and t.fullname=RealName and t.filename=diskfilename
- -- when collapsing fonts, luatex looks as both t.name and t.fullname as ttc files
- -- can have multiple subfonts
- if hasmath then
- if trace_defining then
- report_defining("math enabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
- end
- else
- if trace_defining then
- report_defining("math disabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
- end
- t.nomath, t.MathConstants = true, nil
end
- if not t.psname then
- -- name used in pdf file as well as for selecting subfont in ttc/dfont
- t.psname = t.fontname or (t.fullname and fonts.names.cleanname(t.fullname))
- end
- if trace_defining then
- report_defining("used for accessing (sub)font: '%s'",t.psname or "nopsname")
- report_defining("used for subsetting: '%s'",t.fontname or "nofontname")
- end
- -- this will move up (side effect of merging split call)
- t.factor = delta
- t.ascender = delta*(tfmtable.ascender or 0)
- t.descender = delta*(tfmtable.descender or 0)
- t.shared = tfmtable.shared or { }
- t.unique = table.fastcopy(tfmtable.unique or {})
- tfm.cleanup(t)
- -- print(t.fontname,table.serialize(t.MathConstants))
- return t
-end
-
---[[ldx--
-<p>Analyzers run per script and/or language and are needed in order to
-process features right.</p>
---ldx]]--
-
-fonts.analyzers = fonts.analyzers or { }
-local analyzers = fonts.analyzers
-
-analyzers.aux = analyzers.aux or { }
-analyzers.methods = analyzers.methods or { }
-analyzers.initializers = analyzers.initializers or { }
-
--- todo: analyzers per script/lang, cross font, so we need an font id hash -> script
--- e.g. latin -> hyphenate, arab -> 1/2/3 analyze
-
--- an example analyzer (should move to font-ota.lua)
-
-local state = attributes.private('state')
-
-function analyzers.aux.setstate(head,font)
- local useunicodemarks = analyzers.useunicodemarks
- 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
- local id = current.id
- if id == glyph_code and current.font == font then
- local char = current.char
- local d = descriptions[char]
- if d then
- if d.class == "mark" or (useunicodemarks and categories[char] == "mn") then
- done = true
- set_attribute(current,state,5) -- mark
- elseif n == 0 then
- first, last, n = current, current, 1
- set_attribute(current,state,1) -- init
- else
- last, n = current, n+1
- set_attribute(current,state,2) -- medi
- end
- else -- finish
- if first and first == last then
- set_attribute(last,state,4) -- isol
- elseif last then
- set_attribute(last,state,3) -- fina
- end
- first, last, n = nil, nil, 0
- end
- elseif id == disc_code then
- -- always in the middle
- set_attribute(current,state,2) -- midi
- last = current
- else -- finish
- if first and first == last then
- set_attribute(last,state,4) -- isol
- elseif last then
- set_attribute(last,state,3) -- fina
- end
- first, last, n = nil, nil, 0
- end
- current = current.next
- end
- if first and first == last then
- set_attribute(last,state,4) -- isol
- elseif last then
- set_attribute(last,state,3) -- fina
- end
- return head, done
-end
-
-function tfm.replacements(tfm,value)
- -- tfm.characters[0x0022] = table.fastcopy(tfm.characters[0x201D])
- -- tfm.characters[0x0027] = table.fastcopy(tfm.characters[0x2019])
- -- tfm.characters[0x0060] = table.fastcopy(tfm.characters[0x2018])
- -- tfm.characters[0x0022] = tfm.characters[0x201D]
- tfm.characters[0x0027] = tfm.characters[0x2019]
- -- tfm.characters[0x0060] = tfm.characters[0x2018]
-end
-
--- checking
-
-function tfm.checkedfilename(metadata,whatever)
- local foundfilename = metadata.foundfilename
- if not foundfilename then
- local askedfilename = metadata.filename or ""
- if askedfilename ~= "" then
- askedfilename = resolvers.resolve(askedfilename) -- no shortcut
- foundfilename = findbinfile(askedfilename,"") or ""
- if foundfilename == "" then
- report_defining("source file '%s' is not found",askedfilename)
- foundfilename = findbinfile(file.basename(askedfilename),"") or ""
- if foundfilename ~= "" then
- report_defining("using source file '%s' (cache mismatch)",foundfilename)
- end
- end
- elseif whatever then
- report_defining("no source file for '%s'",whatever)
- foundfilename = ""
- end
- metadata.foundfilename = foundfilename
- -- report_defining("using source file '%s'",foundfilename)
- end
- return foundfilename
-end
-
--- status info
-
-statistics.register("fonts load time", function()
- return statistics.elapsedseconds(fonts)
-end)
-
--- readers
-
-fonts.formats.tfm = "type1" -- we need to have at least a value here
-
-local function check_tfm(specification,fullname)
- -- ofm directive blocks local path search unless set; btw, in context we
- -- don't support ofm files anyway as this format is obsolete
- local foundname = findbinfile(fullname, 'tfm') or "" -- just to be sure
+ local foundname = resolvers.findbinfile(fullname, 'tfm') or ""
if foundname == "" then
- foundname = findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context
- end
- if foundname == "" then
- foundname = fonts.names.getfilename(fullname,"tfm")
+ foundname = resolvers.findbinfile(fullname, 'ofm') or ""
end
if foundname ~= "" then
- specification.filename, specification.format = foundname, "ofm"
- return read_from_tfm(specification)
- end
-end
-
-readers.check_tfm = check_tfm
-
-function readers.tfm(specification)
- local fullname, tfmtable = specification.filename or "", nil
- if fullname == "" then
- local forced = specification.forced or ""
- if forced ~= "" then
- tfmtable = check_tfm(specification,specification.name .. "." .. forced)
- end
- if not tfmtable then
- tfmtable = check_tfm(specification,specification.name)
- end
- else
- tfmtable = check_tfm(specification,fullname)
+ specification.filename = foundname
+ specification.format = "ofm"
+ return font.read_tfm(specification.filename,specification.size)
end
- return tfmtable
end