summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/font-ext.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-ext.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/font-ext.lua313
1 files changed, 297 insertions, 16 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-ext.lua b/Master/texmf-dist/tex/context/base/font-ext.lua
index 4ea9cf3caa0..331ffbdfa91 100644
--- a/Master/texmf-dist/tex/context/base/font-ext.lua
+++ b/Master/texmf-dist/tex/context/base/font-ext.lua
@@ -8,18 +8,18 @@ if not modules then modules = { } end modules ['font-ext'] = {
local utf = unicode.utf8
local next, type, byte = next, type, string.byte
-local gmatch, concat = string.gmatch, table.concat
+local gmatch, concat, format = string.gmatch, table.concat, string.format
local utfchar = utf.char
local getparameters = utilities.parsers.getparameters
-local allocate = utilities.storage.allocate
-
local trace_protrusion = false trackers.register("fonts.protrusion", function(v) trace_protrusion = v end)
local trace_expansion = false trackers.register("fonts.expansion", function(v) trace_expansion = v end)
local report_expansions = logs.reporter("fonts","expansions")
local report_protrusions = logs.reporter("fonts","protrusions")
+-- todo: byte(..) => 0xHHHH
+
--[[ldx--
<p>When we implement functions that deal with features, most of them
will depend of the font format. Here we define the few that are kind
@@ -27,6 +27,7 @@ of neutral.</p>
--ldx]]--
local fonts = fonts
+local fontdata = fonts.hashes.identifiers
local otffeatures = fonts.constructors.newfeatures("otf")
local registerotffeature = otffeatures.register
@@ -34,6 +35,10 @@ local registerotffeature = otffeatures.register
local afmfeatures = fonts.constructors.newfeatures("afm")
local registerafmfeature = afmfeatures.register
+local allocate = utilities.storage.allocate
+local settings_to_array = utilities.parsers.settings_to_array
+local setmetatableindex = table.setmetatableindex
+
-- -- -- -- -- --
-- shared
-- -- -- -- -- --
@@ -475,7 +480,7 @@ fonts.goodies.register("protrusions", function(...) return fonts.goodies.report(
-- -- --
local function initializenostackmath(tfmdata,value)
- tfmdata.properties.no_stackmath = value and true
+ tfmdata.properties.nostackmath = value and true
end
registerotffeature {
@@ -487,20 +492,16 @@ registerotffeature {
}
}
-local function initializeitlc(tfmdata,value)
+local function initializeitlc(tfmdata,value) -- hm, always value
if value then
- -- the magic 40 and it formula come from Dohyun Kim
+ -- the magic 40 and it formula come from Dohyun Kim but we might need another guess
local parameters = tfmdata.parameters
local italicangle = parameters.italicangle
if italicangle and italicangle ~= 0 then
- local uwidth = (parameters.uwidth or 40)/2
- for unicode, d in next, tfmdata.descriptions do
- local it = d.boundingbox[3] - d.width + uwidth
- if it ~= 0 then
- d.italic = it
- end
- end
- tfmdata.properties.italic_correction = true
+ local properties = tfmdata.properties
+ local factor = tonumber(value) or 1
+ properties.hasitalics = true
+ properties.autoitalicamount = factor * (parameters.uwidth or 40)/2
end
end
end
@@ -523,6 +524,30 @@ registerafmfeature {
}
}
+local function initializetextitalics(tfmdata,value) -- yes no delay
+ local delay = value == "delay"
+ tfmdata.properties.textitalics = delay and true or value
+ tfmdata.properties.delaytextitalics = delay
+end
+
+registerotffeature {
+ name = "textitalics",
+ description = "use alternative text italic correction",
+ initializers = {
+ base = initializetextitalics,
+ node = initializetextitalics,
+ }
+}
+
+registerafmfeature {
+ name = "textitalics",
+ description = "use alternative text italic correction",
+ initializers = {
+ base = initializetextitalics,
+ node = initializetextitalics,
+ }
+}
+
-- slanting
local function initializeslant(tfmdata,value)
@@ -534,7 +559,7 @@ local function initializeslant(tfmdata,value)
elseif value < -1 then
value = -1
end
- tfmdata.parameters.slant_factor = value
+ tfmdata.parameters.slantfactor = value
end
registerotffeature {
@@ -564,7 +589,7 @@ local function initializeextend(tfmdata,value)
elseif value < -10 then
value = -10
end
- tfmdata.parameters.extend_factor = value
+ tfmdata.parameters.extendfactor = value
end
registerotffeature {
@@ -585,6 +610,202 @@ registerafmfeature {
}
}
+-- For Wolfgang Schuster:
+--
+-- \definefontfeature[thisway][default][script=hang,language=zhs,dimensions={2,2,2}]
+-- \definedfont[file:kozminpr6nregular*thisway]
+--
+-- For the moment we don't mess with the descriptions.
+
+local function manipulatedimensions(tfmdata,key,value)
+ if type(value) == "string" and value ~= "" then
+ local characters = tfmdata.characters
+ local parameters = tfmdata.parameters
+ local emwidth = parameters.quad
+ local exheight = parameters.xheight
+ local spec = settings_to_array(value)
+ local width = (spec[1] or 0) * emwidth
+ local height = (spec[2] or 0) * exheight
+ local depth = (spec[3] or 0) * exheight
+ if width > 0 then
+ local resources = tfmdata.resources
+ local additions = { }
+ local private = resources.private
+ for unicode, old_c in next, characters do
+ local oldwidth = old_c.width
+ if oldwidth ~= width then
+ -- Defining the tables in one step is more efficient
+ -- than adding fields later.
+ private = private + 1
+ local new_c
+ local commands = {
+ { "right", (width - oldwidth) / 2 },
+ { "slot", 1, private },
+ }
+ if height > 0 then
+ if depth > 0 then
+ new_c = {
+ width = width,
+ height = height,
+ depth = depth,
+ commands = commands,
+ }
+ else
+ new_c = {
+ width = width,
+ height = height,
+ commands = commands,
+ }
+ end
+ else
+ if depth > 0 then
+ new_c = {
+ width = width,
+ depth = depth,
+ commands = commands,
+ }
+ else
+ new_c = {
+ width = width,
+ commands = commands,
+ }
+ end
+ end
+ setmetatableindex(new_c,old_c)
+ characters[unicode] = new_c
+ additions[private] = old_c
+ end
+ end
+ for k, v in next, additions do
+ characters[k] = v
+ end
+ resources.private = private
+ elseif height > 0 and depth > 0 then
+ for unicode, old_c in next, characters do
+ old_c.height = height
+ old_c.depth = depth
+ end
+ elseif height > 0 then
+ for unicode, old_c in next, characters do
+ old_c.height = height
+ end
+ elseif depth > 0 then
+ for unicode, old_c in next, characters do
+ old_c.depth = depth
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "dimensions",
+ description = "force dimensions",
+ manipulators = {
+ base = manipulatedimensions,
+ node = manipulatedimensions,
+ }
+}
+
+-- for zhichu chen (see mailing list archive): we might add a few more variants
+-- in due time
+--
+-- \definefontfeature[boxed][default][boundingbox=yes] % paleblue
+--
+-- maybe:
+--
+-- \definecolor[DummyColor][s=.75,t=.5,a=1] {\DummyColor test} \nopdfcompression
+--
+-- local gray = { "special", "pdf: /Tr1 gs .75 g" }
+-- local black = { "special", "pdf: /Tr0 gs 0 g" }
+
+local push = { "push" }
+local pop = { "pop" }
+local gray = { "special", "pdf: .75 g" }
+local black = { "special", "pdf: 0 g" }
+
+local downcache = { } -- handy for huge cjk fonts
+local rulecache = { } -- handy for huge cjk fonts
+
+setmetatableindex(downcache,function(t,d)
+ local v = { "down", d }
+ t[d] = v
+ return v
+end)
+
+setmetatableindex(rulecache,function(t,h)
+ local v = { }
+ t[h] = v
+ setmetatableindex(v,function(t,w)
+ local v = { "rule", h, w }
+ t[w] = v
+ return v
+ end)
+ return v
+end)
+
+local function showboundingbox(tfmdata,key,value)
+ if value then
+ local vfspecials = backends.pdf.tables.vfspecials
+ local gray = vfspecials and (vfspecials.rulecolors[value] or vfspecials.rulecolors.palegray) or gray
+ local characters = tfmdata.characters
+ local resources = tfmdata.resources
+ local additions = { }
+ local private = resources.private
+ for unicode, old_c in next, characters do
+ private = private + 1
+ local width = old_c.width or 0
+ local height = old_c.height or 0
+ local depth = old_c.depth or 0
+ local new_c
+ if depth == 0 then
+ new_c = {
+ width = width,
+ height = height,
+ commands = {
+ push,
+ gray,
+ rulecache[height][width],
+ black,
+ pop,
+ { "slot", 1, private },
+ }
+ }
+ else
+ new_c = {
+ width = width,
+ height = height,
+ depth = depth,
+ commands = {
+ push,
+ downcache[depth],
+ gray,
+ rulecache[height+depth][width],
+ black,
+ pop,
+ { "slot", 1, private },
+ }
+ }
+ end
+ setmetatableindex(new_c,old_c)
+ characters[unicode] = new_c
+ additions[private] = old_c
+ end
+ for k, v in next, additions do
+ characters[k] = v
+ end
+ resources.private = private
+ end
+end
+
+registerotffeature {
+ name = "boundingbox",
+ description = "show boundingbox",
+ manipulators = {
+ base = showboundingbox,
+ node = showboundingbox,
+ }
+}
+
-- -- historic stuff, move from font-ota (handled differently, typo-rep)
--
-- local delete_node = nodes.delete
@@ -651,3 +872,63 @@ registerafmfeature {
-- node = processformatters,
-- }
-- }
+
+-- a handy helper (might change or be moved to another namespace)
+
+local new_special = nodes.pool.special
+local new_glyph = nodes.pool.glyph
+local hpack_node = node.hpack
+
+function fonts.helpers.addprivate(tfmdata,name,characterdata)
+ local properties = tfmdata.properties
+ local privates = properties.privates
+ local lastprivate = properties.lastprivate
+ if lastprivate then
+ lastprivate = lastprivate + 1
+ else
+ lastprivate = 0xE000
+ end
+ if not privates then
+ privates = { }
+ properties.privates = privates
+ end
+ privates[name] = lastprivate
+ properties.lastprivate = lastprivate
+ tfmdata.characters[lastprivate] = characterdata
+ if properties.finalized then
+ properties.lateprivates = true
+ end
+ return lastprivate
+end
+
+function fonts.helpers.getprivatenode(tfmdata,name)
+ local properties = tfmdata.properties
+ local privates = properties and properties.privates
+ if privates then
+ local p = privates[name]
+ if p then
+ local char = tfmdata.characters[p]
+ local commands = char.commands
+ if commands then
+ local fake = hpack_node(new_special(commands[1][2]))
+ fake.width = char.width
+ fake.height = char.height
+ fake.depth = char.depth
+ return fake
+ else
+ -- todo: set current attribibutes
+ return new_glyph(properties.id,p)
+ end
+ end
+ end
+end
+
+function fonts.helpers.hasprivate(tfmdata,name)
+ local properties = tfmdata.properties
+ local privates = properties and properties.privates
+ return privates and privates[name] or false
+end
+
+function commands.getprivatechar(name)
+ context(fonts.helpers.getprivatenode(fontdata[font.current()],name))
+end