diff options
Diffstat (limited to 'tex/context/base/font-fbk.lua')
-rw-r--r-- | tex/context/base/font-fbk.lua | 282 |
1 files changed, 87 insertions, 195 deletions
diff --git a/tex/context/base/font-fbk.lua b/tex/context/base/font-fbk.lua index 586af127b..d5cec59c9 100644 --- a/tex/context/base/font-fbk.lua +++ b/tex/context/base/font-fbk.lua @@ -12,6 +12,8 @@ local utfbyte, utfchar = utf.byte, utf.char local trace_combining = false trackers.register("fonts.combining", function(v) trace_combining = v end) local trace_combining_all = false trackers.register("fonts.combining.all", function(v) trace_combining_all = v end) +local force_combining = false -- just for demo purposes (see mk) + trackers.register("fonts.composing", "fonts.combining") local report_combining = logs.reporter("fonts","combining") @@ -22,66 +24,59 @@ local allocate = utilities.storage.allocate <p>This is very experimental code!</p> --ldx]]-- -local fonts = fonts -local vf = fonts.vf -local tfm = fonts.tfm - -fonts.fallbacks = allocate() -local fallbacks = fonts.fallbacks -local commands = vf.aux.combine.commands - -local push, pop = { "push" }, { "pop" } - -commands["enable-tracing"] = function(g,v) - trace_combining = true -end - -commands["disable-tracing"] = function(g,v) - trace_combining = false -end +local fonts = fonts +local handlers = fonts.handlers +local constructors = fonts.constructors +local vf = handlers.vf +local commands = vf.combiner.commands -commands["set-tracing"] = function(g,v) - if v[2] == nil then - trace_combining = true - else - trace_combining = v[2] - end -end +local otffeatures = constructors.newfeatures("otf") +local registerotffeature = otffeatures.register --- maybe store llx etc instead of bbox in tfm blob / more efficient +local afmfeatures = constructors.newfeatures("afm") +local registerafmfeature = afmfeatures.register -local force_composed = false +local unicodecharacters = characters.data +local unicodefallbacks = characters.fallbacks -local cache = { } -- we could make these weak -local fraction = 0.15 -- 30 units for lucida +local push = vf.predefined.push +local pop = vf.predefined.pop +local force_composed = false +local cache = { } -- we could make these weak +local fraction = 0.15 -- 30 units for lucida -function vf.aux.compose_characters(g) -- todo: scaling depends on call location +local function composecharacters(tfmdata) -- this assumes that slot 1 is self, there will be a proper self some day - local chars, descs = g.characters, g.descriptions - local Xdesc, xdesc = descs[utfbyte("X")], descs[utfbyte("x")] + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local parameters = tfmdata.parameters + local properties = tfmdata.properties + local Xdesc = descriptions[utfbyte("X")] + local xdesc = descriptions[utfbyte("x")] if Xdesc and xdesc then - local scale = g.factor or 1 + local scale = parameters.factor or 1 local deltaxheight = scale * (Xdesc.boundingbox[4] - xdesc.boundingbox[4]) local extraxheight = fraction * deltaxheight -- maybe use compose value - -- local cap_ury = scale*xdesc.boundingbox[4] - local ita_cor = cos(rad(90+(g.italicangle or 0))) - local fallbacks = characters.fallbacks - local vfspecials = backends.tables.vfspecials + local italicfactor = parameters.italicfactor or 0 + local vfspecials = backends.tables.vfspecials --brr local red, green, blue, black if trace_combining then - red, green, blue, black = vfspecials.red, vfspecials.green, vfspecials.blue, vfspecials.black + red = vfspecials.red + green = vfspecials.green + blue = vfspecials.blue + black = vfspecials.black end - local compose = fonts.goodies.getcompositions(g) + local compose = fonts.goodies.getcompositions(tfmdata) if compose and trace_combining then report_combining("using compose information from goodies file") end local done = false - for i,c in next, characters.data do -- loop over all characters ... not that efficient but a specials hash takes memory - if force_composed or not chars[i] then + for i,c in next, unicodecharacters do -- loop over all characters ... not that efficient but a specials hash takes memory + if force_combining or not characters[i] then local s = c.specials if s and s[1] == 'char' then local chr = s[2] - local charschr = chars[chr] + local charschr = characters[chr] if charschr then local cc = c.category if cc == 'll' or cc == 'lu' or cc == 'lt' then -- characters.is_letter[cc] @@ -92,7 +87,7 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location t[k] = v end end - local charsacc = chars[acc] + local charsacc = characters[acc] --~ local ca = charsacc.category --~ if ca == "mn" then --~ -- mark nonspacing @@ -102,8 +97,8 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location --~ -- mark enclosing --~ else if not charsacc then -- fallback accents - acc = fallbacks[acc] - charsacc = acc and chars[acc] + acc = unicodefallbacks[acc] + charsacc = acc and characters[acc] end local chr_t = cache[chr] if not chr_t then @@ -119,15 +114,15 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location acc_t = {"slot", 1, acc} cache[acc] = acc_t end - local cb = descs[chr].boundingbox - local ab = descs[acc].boundingbox + local cb = descriptions[chr].boundingbox + local ab = descriptions[acc].boundingbox -- todo: adapt height if cb and ab then -- can be sped up for scale == 1 local c_llx, c_lly, c_urx, c_ury = scale*cb[1], scale*cb[2], scale*cb[3], scale*cb[4] local a_llx, a_lly, a_urx, a_ury = scale*ab[1], scale*ab[2], scale*ab[3], scale*ab[4] local dx = (c_urx - a_urx - a_llx + c_llx)/2 - local dd = (c_urx - c_llx)*ita_cor + local dd = (c_urx - c_llx)*italicfactor if a_ury < 0 then if trace_combining then t.commands = { push, {"right", dx-dd}, red, acc_t, black, pop, chr_t } @@ -135,7 +130,6 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location t.commands = { push, {"right", dx-dd}, acc_t, pop, chr_t } end elseif c_ury > a_lly then -- messy test - -- local dy = cap_ury - a_lly local dy if compose then -- experimental: we could use sx but all that testing @@ -187,180 +181,78 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location t.commands = { chr_t } -- else index mess end done = true - chars[i] = t + characters[i] = t local d = { } - for k, v in next, descs[chr] do + for k, v in next, descriptions[chr] do d[k] = v end - -- d.name = c.adobename or "unknown" -- TOO TRICKY ! CAN CLASH WITH THE SUBSETTER - -- d.unicode = i - descs[i] = d + descriptions[i] = d end end end end end if done then - g.type = "virtual" -- for the moment, to be sure - g.virtualized = true + properties.virtualized = true end end end -commands["complete-composed-characters"] = function(g,v) - vf.aux.compose_characters(g) -end +registerotffeature { + name = "compose", + description = "additional composed characters", + manipulators = { + base = composecharacters, + node = composecharacters, + } +} --- {'special', 'pdf: q ' .. s .. ' 0 0 '.. s .. ' 0 0 cm'}, --- {'special', 'pdf: q 1 0 0 1 ' .. -w .. ' ' .. -h .. ' cm'}, --- {'special', 'pdf: /Fm\XX\space Do'}, --- {'special', 'pdf: Q'}, --- {'special', 'pdf: Q'}, +registerafmfeature { + name = "compose", + description = "additional composed characters", + manipulators = { + base = composecharacters, + node = composecharacters, + } +} -local force_fallback = false +vf.helpers.composecharacters = composecharacters -commands["fake-character"] = function(g,v) -- g, nr, fallback_id - local index, fallback = v[2], v[3] - if (force_fallback or not g.characters[index]) and fallbacks[fallback] then - g.characters[index], g.descriptions[index] = fallbacks[fallback](g) - end -end +-- This installs the builder into the regular virtual font builder, +-- which only makes sense as demo. -commands["enable-force"] = function(g,v) - force_composed = true - force_fallback = true +commands["compose.trace.enable"] = function() + trace_combining = true end -commands["disable-force"] = function(g,v) - force_composed = false - force_fallback = false +commands["compose.trace.disable"] = function() + trace_combining = false end -local install = fonts.definers.methods.install - --- these are just examples used in the manuals, so they will end up in --- modules eventually +commands["compose.force.enable"] = function() + force_combining = true +end -fallbacks['textcent'] = function (g) - local c = utfbyte("c") - local t = table.fastcopy(g.characters[c],true) - local a = - tan(rad(g.italicangle or 0)) - local vfspecials = backends.tables.vfspecials - local green, black - if trace_combining then - green, black = vfspecials.green, vfspecials.black - end - local startslant, stopslant = vfspecials.startslant, vfspecials.stopslant - local quad = g.parameters.quad - if a == 0 then - if trace_combining then - t.commands = { - push, {"slot", 1, c}, pop, - {"right", .5*t.width}, - {"down", .2*t.height}, - green, - {"rule", 1.4*t.height, .02*quad}, - black, - } - else - t.commands = { - push, {"slot", 1, c}, pop, - {"right", .5*t.width}, - {"down", .2*t.height}, - {"rule", 1.4*t.height, .02*quad}, - } - end - else - if trace_combining then - t.commands = { - push, - {"right", .5*t.width-.025*quad}, - {"down", .2*t.height}, - startslant(a), - green, - {"rule", 1.4*t.height, .025*quad}, - black, - stopslant, - pop, - {"slot", 1, c} -- last else problems with cm - } - else - t.commands = { - push, - {"right", .5*t.width-.025*quad}, - {"down", .2*t.height}, - startslant(a), - {"rule", 1.4*t.height, .025*quad}, - stopslant, - pop, - {"slot", 1, c} -- last else problems with cm - } - end - end - -- somehow the width is messed up now - -- todo: set height - t.height = 1.2*t.height - t.depth = 0.2*t.height - g.virtualized = true - local d = g.descriptions - return t, d and d[c] +commands["compose.force.disable"] = function() + force_combining = false end -fallbacks['texteuro'] = function (g) - local c = utfbyte("C") - local t = table.fastcopy(g.characters[c],true) - local d = cos(rad(90+(g.italicangle))) - local vfspecials = backends.tables.vfspecials - local green, black - if trace_combining then - green, black = vfspecials.green, vfspecials.black - end - local quad = g.parameters.quad - t.width = 1.05*t.width - if trace_combining then - t.commands = { - {"right", .05*t.width}, - push, {"slot", 1, c}, pop, - {"right", .5*t.width*d}, - {"down", -.5*t.height}, - green, - {"rule", .05*quad, .4*quad}, - black, - } +commands["compose.trace.set"] = function(g,v) + if v[2] == nil then + trace_combining = true else - t.commands = { - {"right", .05*t.width}, - push, {"slot", 1, c}, pop, - {"right", .5*t.width*d}, - {"down", -.5*t.height}, - {"rule", .05*quad, .4*quad}, - } + trace_combining = v[2] end - g.virtualized = true - return t, g.descriptions[c] end +commands["compose.apply"] = function(g,v) + composecharacters(g) +end -install("fallback", { -- todo: auto-fallback with loop over data.characters - { "fake-character", 0x00A2, 'textcent' }, - { "fake-character", 0x20AC, 'texteuro' } -}) - -install("demo-2", { - { "enable-tracing" }, - { "enable-force" }, - { "initialize" }, - { "include-method", "fallback" }, - { "complete-composed-characters" }, - { "disable-tracing" }, - { "disable-force" }, -}) - -install("demo-3", { - { "enable-tracing" }, - { "initialize" }, - { "complete-composed-characters" }, - { "disable-tracing" }, -}) +-- vf builder --- end of examples +-- {'special', 'pdf: q ' .. s .. ' 0 0 '.. s .. ' 0 0 cm'}, +-- {'special', 'pdf: q 1 0 0 1 ' .. -w .. ' ' .. -h .. ' cm'}, +-- {'special', 'pdf: /Fm\XX\space Do'}, +-- {'special', 'pdf: Q'}, +-- {'special', 'pdf: Q'}, |