diff options
Diffstat (limited to 'tex/context/base/font-fbk.lua')
-rw-r--r-- | tex/context/base/font-fbk.lua | 316 |
1 files changed, 178 insertions, 138 deletions
diff --git a/tex/context/base/font-fbk.lua b/tex/context/base/font-fbk.lua index 865e92623..ea6854456 100644 --- a/tex/context/base/font-fbk.lua +++ b/tex/context/base/font-fbk.lua @@ -7,12 +7,14 @@ if not modules then modules = { } end modules ['font-fbk'] = { } local cos, tan, rad, format = math.cos, math.tan, math.rad, string.format -local byte = utf.byte - --- maybe use compose instead of combine +local utfbyte, utfchar = utf.byte, utf.char local trace_combining = false trackers.register("fonts.combining", function(v) trace_combining = v end) +trackers.register("fonts.composing", "fonts.combining") + +local report_combining = logs.new("combining") + local allocate = utilities.storage.allocate --[[ldx-- @@ -45,129 +47,22 @@ commands["set-tracing"] = function(g,v) end end -local force_fallback = false - -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 - -fallbacks['textcent'] = function (g) - local c = ("c"):byte() - 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] -end - -fallbacks['texteuro'] = function (g) - local c = ("C"):byte() - 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, - } - 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}, - } - end - g.virtualized = true - return t, g.descriptions[c] -end - -- maybe store llx etc instead of bbox in tfm blob / more efficient local force_composed = false -local cache = { } -- we could make these weak +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 -- this assumes that slot 1 is self, there will be a proper self some day local chars, descs = g.characters, g.descriptions - local X = byte("X") - local xchar = chars[X] - local xdesc = descs[X] - if xchar and xdesc then + local Xdesc, xdesc = descs[utfbyte("X")], descs[utfbyte("x")] + if Xdesc and xdesc then local scale = g.factor or 1 - local cap_ury = scale*xdesc.boundingbox[4] + 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 @@ -175,6 +70,10 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location if trace_combining then red, green, blue, black = vfspecials.red, vfspecials.green, vfspecials.blue, vfspecials.black end + local compose = fonts.goodies.getcompositions(g) + 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 if force_composed or not chars[i] then @@ -206,6 +105,9 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location charsacc = acc and chars[acc] end if charsacc then + if trace_combining then + report_combining("%s (0x%05X) = %s (0x%05X) + %s (0x%05X)",utfchar(i),i,utfchar(chr),chr,utfchar(acc),acc) + end local chr_t = cache[chr] if not chr_t then chr_t = {"slot", 1, chr} @@ -218,6 +120,7 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location end local cb = descs[chr].boundingbox local ab = descs[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] @@ -226,39 +129,64 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location local dd = (c_urx - c_llx)*ita_cor if a_ury < 0 then if trace_combining then - t.commands = { push, {"right", dx-dd}, red, acc_t, black, pop, chr_t } + t.commands = { push, {"right", dx-dd}, red, acc_t, black, pop, chr_t } else - t.commands = { push, {"right", dx-dd}, acc_t, pop, chr_t } + 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 + -- takes time and code + dy = compose[i] + if dy then + dy = dy.DY + end + if not dy then + dy = compose[acc] + if dy then + dy = dy and dy.DY + end + end + if not dy then + dy = compose.DY + end + if not dy then + dy = - deltaxheight + extraxheight + elseif dy > -1.5 and dy < 1.5 then + -- we assume a fraction of (percentage) + dy = - dy * deltaxheight + else + -- we assume fontunits (value smaller than 2 make no sense) + dy = - dy * scale + end + else + dy = - deltaxheight + extraxheight end - elseif c_ury > a_lly then ---~ local dy = cap_ury - a_lly -local lower_x = byte("x") -local upper_x = byte("X") -local Xdesc = descs[upper_x] -local xdesc = descs[lower_x] -local dy = scale*(Xdesc.boundingbox[4] - xdesc.boundingbox[4] - 30) -- x height - if trace_combining then - t.commands = { push, {"right", dx+dd}, {"down", -dy}, green, acc_t, black, pop, chr_t } + t.commands = { push, {"right", dx+dd}, {"down", dy}, green, acc_t, black, pop, chr_t } else - t.commands = { push, {"right", dx+dd}, {"down", -dy}, acc_t, pop, chr_t } + t.commands = { push, {"right", dx+dd}, {"down", dy}, acc_t, pop, chr_t } end else if trace_combining then - t.commands = { push, {"right", dx+dd}, blue, acc_t, black, pop, chr_t } + t.commands = { push, {"right", dx+dd}, blue, acc_t, black, pop, chr_t } else - t.commands = { push, {"right", dx+dd}, acc_t, pop, chr_t } + t.commands = { push, {"right", dx+dd}, acc_t, pop, chr_t } end end done = true end + elseif trace_combining then + report_combining("%s (0x%05X) = %s (0x%05X)",utfchar(i),i,utfchar(chr),chr) end chars[i] = t local d = { } for k, v in next, descs[chr] do d[k] = v end - d.name = c.adobename or "unknown" + -- d.name = c.adobename or "unknown" -- TOO TRICKY ! CAN CLASH WITH THE SUBSETTER -- d.unicode = i descs[i] = d end @@ -276,13 +204,20 @@ commands["complete-composed-characters"] = function(g,v) vf.aux.compose_characters(g) end ---~ {'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'}, +-- {'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'}, --- for documentation purposes we provide: +local force_fallback = false + +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 commands["enable-force"] = function(g,v) force_composed = true @@ -296,6 +231,109 @@ end local install = fonts.definers.methods.install +-- these are just examples used in the manuals, so they will end up in +-- modules eventually + +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] +end + +fallbacks['texteuro'] = function (g) + local c = byte("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, + } + 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}, + } + end + g.virtualized = true + return t, g.descriptions[c] +end + + install("fallback", { -- todo: auto-fallback with loop over data.characters { "fake-character", 0x00A2, 'textcent' }, { "fake-character", 0x20AC, 'texteuro' } @@ -317,3 +355,5 @@ install("demo-3", { { "complete-composed-characters" }, { "disable-tracing" }, }) + +-- end of examples |