summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/font-fbk.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-fbk.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/font-fbk.lua402
1 files changed, 172 insertions, 230 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-fbk.lua b/Master/texmf-dist/tex/context/base/font-fbk.lua
index 1ad1cc781a8..6712fbe888e 100644
--- a/Master/texmf-dist/tex/context/base/font-fbk.lua
+++ b/Master/texmf-dist/tex/context/base/font-fbk.lua
@@ -7,146 +7,79 @@ if not modules then modules = { } end modules ['font-fbk'] = {
}
local cos, tan, rad, format = math.cos, math.tan, math.rad, string.format
+local utfbyte, utfchar = utf.byte, utf.char
-local trace_combining = false trackers.register("fonts.combining", function(v) trace_combining = v end)
+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)
---[[ldx--
-<p>This is very experimental code!</p>
---ldx]]--
-
-fonts.fallbacks = fonts.fallbacks or { }
-
-local vf = fonts.vf
-local tfm = fonts.tfm
-
-vf.aux.combine.commands["enable-tracing"] = function(g,v)
- trace_combining = true
-end
-
-vf.aux.combine.commands["disable-tracing"] = function(g,v)
- trace_combining = false
-end
-
-vf.aux.combine.commands["set-tracing"] = function(g,v)
- if v[2] == nil then
- trace_combining = true
- else
- trace_combining = v[2]
- end
-end
+local force_combining = false -- just for demo purposes (see mk)
-function vf.aux.combine.initialize_trace()
- if trace_combining then
- return "special", "pdf: .8 0 0 rg .8 0 0 RG", "pdf: 0 .8 0 rg 0 .8 0 RG", "pdf: 0 0 .8 rg 0 0 .8 RG", "pdf: 0 g 0 G"
- else
- return "comment", "", "", "", ""
- end
-end
+trackers.register("fonts.composing", "fonts.combining")
-vf.aux.combine.force_fallback = false
+local report_combining = logs.reporter("fonts","combining")
-vf.aux.combine.commands["fake-character"] = function(g,v) -- g, nr, fallback_id
- local index, fallback = v[2], v[3]
- if vf.aux.combine.force_fallback or not g.characters[index] then
- if fonts.fallbacks[fallback] then
- g.characters[index], g.descriptions[index] = fonts.fallbacks[fallback](g)
- end
- end
-end
+local allocate = utilities.storage.allocate
-fonts.fallbacks['textcent'] = function (g)
- local c = ("c"):byte()
- local t = table.fastcopy(g.characters[c])
- local a = - tan(rad(g.italicangle or 0))
- local special, red, green, blue, black = vf.aux.combine.initialize_trace()
- local quad = g.parameters.quad
- if a == 0 then
- t.commands = {
- {"push"}, {"slot", 1, c}, {"pop"},
- {"right", .5*t.width},
- {"down", .2*t.height},
- {special, green},
- {"rule", 1.4*t.height, .02*quad},
- {special, black},
- }
- else
- t.commands = {
- {"push"},
- {"right", .5*t.width-.025*quad},
- {"down", .2*t.height},
- {"special",format("pdf: q 1 0 %s 1 0 0 cm",a)},
- {special, green},
- {"rule", 1.4*t.height, .025*quad},
- {special, black},
- {"special","pdf: Q"},
- {"pop"},
- {"slot", 1, c} -- last else problems with cm
- }
- 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
+--[[ldx--
+<p>This is very experimental code!</p>
+--ldx]]--
-fonts.fallbacks['texteuro'] = function (g)
- local c = ("C"):byte()
- local t = table.fastcopy(g.characters[c])
- local d = cos(rad(90+(g.italicangle)))
- local special, red, green, blue, black = vf.aux.combine.initialize_trace()
- local quad = g.parameters.quad
- t.width = 1.05*t.width
- t.commands = {
- {"right", .05*t.width},
- {"push"}, {"slot", 1, c}, {"pop"},
- {"right", .5*t.width*d},
- {"down", -.5*t.height},
- {special, green},
- {"rule", .05*quad, .4*quad},
- {special, black},
- }
- g.virtualized = true
- return t, g.descriptions[c]
-end
+local fonts = fonts
+local handlers = fonts.handlers
+local constructors = fonts.constructors
+local vf = handlers.vf
+local commands = vf.combiner.commands
--- maybe store llx etc instead of bbox in tfm blob / more efficient
+local otffeatures = constructors.newfeatures("otf")
+local registerotffeature = otffeatures.register
-vf.aux.combine.force_composed = false
+local afmfeatures = constructors.newfeatures("afm")
+local registerafmfeature = afmfeatures.register
-local push, pop = { "push" }, { "pop" }
+local unicodecharacters = characters.data
+local unicodefallbacks = characters.fallbacks
-local cache = { } -- we could make these weak
+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 X = ("X"):byte()
- local xchar = chars[X]
- local xdesc = descs[X]
- if xchar and xdesc then
- local scale = g.factor or 1
- local cap_lly = scale*xdesc.boundingbox[4]
- local ita_cor = cos(rad(90+(g.italicangle or 0)))
- local force = vf.aux.combine.force_composed
- local fallbacks = characters.fallbacks
- local special, red, green, blue, black
+ 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 = parameters.factor or 1
+ local deltaxheight = scale * (Xdesc.boundingbox[4] - xdesc.boundingbox[4])
+ local extraxheight = fraction * deltaxheight -- maybe use compose value
+ local italicfactor = parameters.italicfactor or 0
+ local vfspecials = backends.tables.vfspecials --brr
+ local red, green, blue, black
if trace_combining then
- special, red, green, blue, black = vf.aux.combine.initialize_trace()
- red, green, blue, black = { special, red }, { special, green }, { special, blue }, { special, black }
+ red = vfspecials.red
+ green = vfspecials.green
+ blue = vfspecials.blue
+ black = vfspecials.black
+ end
+ 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
- if force 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
+ if cc == 'll' or cc == 'lu' or cc == 'lt' then -- characters.is_letter[cc]
local acc = s[3]
local t = { }
for k, v in next, charschr do
@@ -154,163 +87,172 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location
t[k] = v
end
end
- local charsacc = chars[acc]
---~ local ca = charsacc.category
---~ if ca == "mn" then
---~ -- mark nonspacing
---~ elseif ca == "ms" then
---~ -- mark spacing combining
---~ elseif ca == "me" then
---~ -- mark enclosing
---~ else
- if not charsacc then
- acc = fallbacks[acc]
- charsacc = acc and chars[acc]
+ local charsacc = characters[acc]
+ --~ local ca = charsacc.category
+ --~ if ca == "mn" then
+ --~ -- mark nonspacing
+ --~ elseif ca == "ms" then
+ --~ -- mark spacing combining
+ --~ elseif ca == "me" then
+ --~ -- mark enclosing
+ --~ else
+ if not charsacc then -- fallback accents
+ acc = unicodefallbacks[acc]
+ charsacc = acc and characters[acc]
+ end
+ local chr_t = cache[chr]
+ if not chr_t then
+ chr_t = {"slot", 1, chr}
+ cache[chr] = chr_t
end
if charsacc then
- local chr_t = cache[chr]
- if not cht_t then
- chr_t = {"slot", 1, chr}
- cache[chr] = chr_t
+ if trace_combining_all then
+ report_combining("%s (U+%05X) = %s (U+%05X) + %s (U+%05X)",utfchar(i),i,utfchar(chr),chr,utfchar(acc),acc)
end
local acc_t = cache[acc]
if not acc_t then
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,
- }
+ 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 }
+ end
+ elseif c_ury > a_lly then -- messy test
+ 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
- t.commands = {
- push,
- {"right", dx-dd},
- acc_t,
- pop,
- chr_t,
- }
+ dy = - deltaxheight + extraxheight
end
- elseif c_ury > a_lly then
- local dy = cap_lly-a_lly
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
+ else
+ t.commands = { chr_t } -- else index mess
+ end
+ else
+ if trace_combining_all then
+ report_combining("%s (U+%05X) = %s (U+%05X) (simplified)",utfchar(i),i,utfchar(chr),chr)
end
+ t.commands = { chr_t } -- else index mess
end
- chars[i] = t
+ done = true
+ 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"
- -- d.unicode = i
- descs[i] = d
+ descriptions[i] = d
end
end
end
end
end
if done then
- g.virtualized = true
+ properties.virtualized = true
end
end
end
-vf.aux.combine.commands["complete-composed-characters"] = function(g,v)
- vf.aux.compose_characters(g)
+registerotffeature {
+ name = "compose",
+ description = "additional composed characters",
+ manipulators = {
+ base = composecharacters,
+ node = composecharacters,
+ }
+}
+
+registerafmfeature {
+ name = "compose",
+ description = "additional composed characters",
+ manipulators = {
+ base = composecharacters,
+ node = composecharacters,
+ }
+}
+
+vf.helpers.composecharacters = composecharacters
+
+-- This installs the builder into the regular virtual font builder,
+-- which only makes sense as demo.
+
+commands["compose.trace.enable"] = function()
+ trace_combining = true
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'},
+commands["compose.trace.disable"] = function()
+ trace_combining = false
+end
--- for documentation purposes we provide:
+commands["compose.force.enable"] = function()
+ force_combining = true
+end
-fonts.define.methods.install("fallback", { -- todo: auto-fallback with loop over data.characters
- { "fake-character", 0x00A2, 'textcent' },
- { "fake-character", 0x20AC, 'texteuro' }
-})
+commands["compose.force.disable"] = function()
+ force_combining = false
+end
-vf.aux.combine.commands["enable-force"] = function(g,v)
- vf.aux.combine.force_composed = true
- vf.aux.combine.force_fallback = true
+commands["compose.trace.set"] = function(g,v)
+ if v[2] == nil then
+ trace_combining = true
+ else
+ trace_combining = v[2]
+ end
end
-vf.aux.combine.commands["disable-force"] = function(g,v)
- vf.aux.combine.force_composed = false
- vf.aux.combine.force_fallback = false
+
+commands["compose.apply"] = function(g,v)
+ composecharacters(g)
end
-fonts.define.methods.install("demo-2", {
- { "enable-tracing" },
- { "enable-force" },
- { "initialize" },
- { "include-method", "fallback" },
- { "complete-composed-characters" },
- { "disable-tracing" },
- { "disable-force" },
-})
+-- vf builder
-fonts.define.methods.install("demo-3", {
- { "enable-tracing" },
- { "initialize" },
- { "complete-composed-characters" },
- { "disable-tracing" },
-})
+-- {'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'},