summaryrefslogtreecommitdiff
path: root/tex/context/base/font-ext.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2009-05-28 11:23:00 +0200
committerHans Hagen <pragma@wxs.nl>2009-05-28 11:23:00 +0200
commit1d3090326210c6e6f7ec5432799ded25b75bba46 (patch)
treec5921203789ec669e6bccaba4bd56f9c072dc56b /tex/context/base/font-ext.lua
parent94d83f84758766511c5e324721e39fea6ab71dae (diff)
downloadcontext-1d3090326210c6e6f7ec5432799ded25b75bba46.tar.gz
beta 2009.05.28 11:23
Diffstat (limited to 'tex/context/base/font-ext.lua')
-rw-r--r--tex/context/base/font-ext.lua304
1 files changed, 271 insertions, 33 deletions
diff --git a/tex/context/base/font-ext.lua b/tex/context/base/font-ext.lua
index c3979fad6..17c302c53 100644
--- a/tex/context/base/font-ext.lua
+++ b/tex/context/base/font-ext.lua
@@ -6,7 +6,191 @@ if not modules then modules = { } end modules ['font-ext'] = {
license = "see context related readme files"
}
-local byte = string.byte
+local next, type, byte = next, type, string.byte
+
+--[[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
+of neutral.</p>
+--ldx]]--
+
+fonts.triggers = fonts.triggers or { }
+fonts.initializers = fonts.initializers or { }
+fonts.initializers.common = fonts.initializers.common or { }
+
+local initializers = fonts.initializers
+
+--[[ldx--
+<p>This feature will remove inter-digit kerns.</p>
+--ldx]]--
+
+table.insert(fonts.triggers,"equaldigits")
+
+function initializers.common.equaldigits(tfmdata,value)
+ if value then
+ local chr = tfmdata.characters
+ for i = utfbyte('0'), utfbyte('9') do
+ local c = chr[i]
+ if c then
+ c.kerns = nil
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>This feature will give all glyphs an equal height and/or depth. Valid
+values are <type>none</type>, <type>height</type>, <type>depth</type> and
+<type>both</type>.</p>
+--ldx]]--
+
+table.insert(fonts.triggers,"lineheight")
+
+function initializers.common.lineheight(tfmdata,value)
+ if value and type(value) == "string" then
+ if value == "none" then
+ for _,v in next, tfmdata.characters do
+ v.height, v.depth = 0, 0
+ end
+ else
+ local ascender, descender = tfmdata.ascender, tfmdata.descender
+ if ascender and descender then
+ local ht, dp = ascender or 0, descender or 0
+ if value == "height" then
+ dp = 0
+ elseif value == "depth" then
+ ht = 0
+ end
+ if ht > 0 then
+ if dp > 0 then
+ for _,v in next, tfmdata.characters do
+ v.height, v.depth = ht, dp
+ end
+ else
+ for _,v in next, tfmdata.characters do
+ v.height = ht
+ end
+ end
+ elseif dp > 0 then
+ for _,v in next, tfmdata.characters do
+ v.depth = dp
+ end
+ end
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>It does not make sense any more to support messed up encoding vectors
+so we stick to those that implement oldstyle and small caps. After all,
+we move on. We can extend the next function on demand. This features is
+only used with <l n='afm'/> files.</p>
+--ldx]]--
+
+--~ do
+--~
+--~ local smallcaps = lpeg.P(".sc") + lpeg.P(".smallcaps") + lpeg.P(".caps") + lpeg.P("small")
+--~ local oldstyle = lpeg.P(".os") + lpeg.P(".oldstyle") + lpeg.P(".onum")
+--~
+--~ smallcaps = lpeg.Cs((1-smallcaps)^1) * smallcaps^1
+--~ oldstyle = lpeg.Cs((1-oldstyle )^1) * oldstyle ^1
+--~
+--~ function initializers.common.encoding(tfmdata,value)
+--~ if value then
+--~ local afmdata = tfmdata.shared.afmdata
+--~ if afmdata then
+--~ local encodingfile = value .. '.enc'
+--~ local encoding = fonts.enc.load(encodingfile)
+--~ if encoding then
+--~ local vector = encoding.vector
+--~ local characters = tfmdata.characters
+--~ local unicodes = afmdata.luatex.unicodes
+--~ local function remap(pattern,name)
+--~ local p = pattern:match(name)
+--~ if p then
+--~ local oldchr, newchr = unicodes[p], unicodes[name]
+--~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+--~ -- logs.report("encoding","%s (%s) -> %s (%s)",p,oldchr or -1,name,newchr or -1)
+--~ characters[oldchr] = characters[newchr]
+--~ end
+--~ end
+--~ return p
+--~ end
+--~ for _, name in next, vector do
+--~ local ok = remap(smallcaps,name) or remap(oldstyle,name)
+--~ end
+--~ if fonts.map.data[tfmdata.name] then
+--~ fonts.map.data[tfmdata.name].encoding = encodingfile
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~
+--~ -- when needed we can provide this as features in e.g. afm files
+--~
+--~ function initializers.common.remap(tfmdata,value,pattern) -- will go away
+--~ if value then
+--~ local afmdata = tfmdata.shared.afmdata
+--~ if afmdata then
+--~ local characters = tfmdata.characters
+--~ local descriptions = tfmdata.descriptions
+--~ local unicodes = afmdata.luatex.unicodes
+--~ local done = false
+--~ for u, _ in next, characters do
+--~ local name = descriptions[u].name
+--~ if name then
+--~ local p = pattern:match(name)
+--~ if p then
+--~ local oldchr, newchr = unicodes[p], unicodes[name]
+--~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+--~ characters[oldchr] = characters[newchr]
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~
+--~ function initializers.common.oldstyle(tfmdata,value)
+--~ initializers.common.remap(tfmdata,value,oldstyle)
+--~ end
+--~ function initializers.common.smallcaps(tfmdata,value)
+--~ initializers.common.remap(tfmdata,value,smallcaps)
+--~ end
+--~
+--~ function initializers.common.fakecaps(tfmdata,value)
+--~ if value then
+--~ -- todo: scale down
+--~ local afmdata = tfmdata.shared.afmdata
+--~ if afmdata then
+--~ local characters = tfmdata.characters
+--~ local descriptions = tfmdata.descriptions
+--~ local unicodes = afmdata.luatex.unicodes
+--~ for u, _ in next, characters do
+--~ local name = descriptions[u].name
+--~ if name then
+--~ local p = lower(name)
+--~ if p then
+--~ local oldchr, newchr = unicodes[p], unicodes[name]
+--~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+--~ characters[oldchr] = characters[newchr]
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~
+--~ end
+--~
+--~ function initializers.common.install(format,feature) -- 'afm','lineheight'
+--~ initializers.base[format][feature] = initializers.common[feature]
+--~ initializers.node[format][feature] = initializers.common[feature]
+--~ end
-- -- -- -- -- --
-- expansion (hz)
@@ -16,19 +200,23 @@ fonts.expansions = fonts.expansions or { }
fonts.expansions.classes = fonts.expansions.classes or { }
fonts.expansions.vectors = fonts.expansions.vectors or { }
+local expansions = fonts.expansions
+local classes = fonts.expansions.classes
+local vectors = fonts.expansions.vectors
+
-- beware, pdftex itself uses percentages * 10
-fonts.expansions.classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 }
+classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 }
function commands.setupfontexpansion(class,settings)
- aux.getparameters(fonts.expansions.classes,class,'preset',settings)
+ aux.getparameters(classes,class,'preset',settings)
end
-fonts.expansions.classes['quality'] = {
+classes['quality'] = {
stretch = 2, shrink = 2, step = .5, vector = 'default', factor = 1
}
-fonts.expansions.vectors['default'] = {
+vectors['default'] = {
[byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7,
[byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7,
[byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7,
@@ -40,11 +228,11 @@ fonts.expansions.vectors['default'] = {
[byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7,
}
-function fonts.initializers.common.expansion(tfmdata,value)
+function initializers.common.expansion(tfmdata,value)
if value then
- local class = fonts.expansions.classes[value]
+ local class = classes[value]
if class then
- local vector = fonts.expansions.vectors[class.vector]
+ local vector = vectors[class.vector]
if vector then
tfmdata.stretch = (class.stretch or 0) * 10
tfmdata.shrink = (class.shrink or 0) * 10
@@ -52,7 +240,7 @@ function fonts.initializers.common.expansion(tfmdata,value)
tfmdata.auto_expand = true
local factor = class.factor or 1
local data = characters.data
- for i, chr in pairs(tfmdata.characters) do
+ for i, chr in next, tfmdata.characters do
local v = vector[i]
if not v then
local d = data[i]
@@ -80,11 +268,11 @@ end
table.insert(fonts.manipulators,"expansion")
-fonts.initializers.base.otf.expansion = fonts.initializers.common.expansion
-fonts.initializers.node.otf.expansion = fonts.initializers.common.expansion
+initializers.base.otf.expansion = initializers.common.expansion
+initializers.node.otf.expansion = initializers.common.expansion
-fonts.initializers.base.afm.expansion = fonts.initializers.common.expansion
-fonts.initializers.node.afm.expansion = fonts.initializers.common.expansion
+initializers.base.afm.expansion = initializers.common.expansion
+initializers.node.afm.expansion = initializers.common.expansion
-- -- -- -- -- --
-- protrusion
@@ -94,28 +282,32 @@ fonts.protrusions = fonts.protrusions or { }
fonts.protrusions.classes = fonts.protrusions.classes or { }
fonts.protrusions.vectors = fonts.protrusions.vectors or { }
+local protrusions = fonts.protrusions
+local classes = fonts.protrusions.classes
+local vectors = fonts.protrusions.vectors
+
-- the values need to be revisioned
-fonts.protrusions.classes.preset = { factor = 1 }
+classes.preset = { factor = 1 }
function commands.setupfontprotrusion(class,settings)
- aux.getparameters(fonts.protrusions.classes,class,'preset',settings)
+ aux.getparameters(classes,class,'preset',settings)
end
-fonts.protrusions.classes['pure'] = {
+classes['pure'] = {
vector = 'pure', factor = 1
}
-fonts.protrusions.classes['punctuation'] = {
+classes['punctuation'] = {
vector = 'punctuation', factor = 1
}
-fonts.protrusions.classes['alpha'] = {
+classes['alpha'] = {
vector = 'alpha', factor = 1
}
-fonts.protrusions.classes['quality'] = {
+classes['quality'] = {
vector = 'quality', factor = 1
}
-fonts.protrusions.vectors['pure'] = {
+vectors['pure'] = {
[0x002C] = { 0, 1 }, -- comma
[0x002E] = { 0, 1 }, -- period
@@ -126,10 +318,13 @@ fonts.protrusions.vectors['pure'] = {
[0x2014] = { 0, 0.33 }, -- emdash
[0x3001] = { 0, 1 }, -- ideographic comma 、
[0x3002] = { 0, 1 }, -- ideographic full stop 。
+ [0x060C] = { 0, 1 }, -- arabic comma ،
+ [0x061B] = { 0, 1 }, -- arabic semicolon ؛
+ [0x06D4] = { 0, 1 }, -- arabic full stop ۔
}
-fonts.protrusions.vectors['punctuation'] = {
+vectors['punctuation'] = {
[0x003F] = { 0, 0.20 }, -- ?
[0x00BF] = { 0, 0.20 }, -- ¿
@@ -146,6 +341,10 @@ fonts.protrusions.vectors['punctuation'] = {
[0x002D] = { 0, 0.70 }, -- hyphen
[0x2013] = { 0, 0.30 }, -- endash
[0x2014] = { 0, 0.20 }, -- emdash
+ [0x060C] = { 0, 0.70 }, -- arabic comma
+ [0x061B] = { 0, 0.50 }, -- arabic semicolon
+ [0x06D4] = { 0, 0.70 }, -- arabic full stop
+ [0x061F] = { 0, 0.20 }, -- ؟
-- todo: left and right quotes: .5 double, .7 single
@@ -165,7 +364,7 @@ fonts.protrusions.vectors['punctuation'] = {
}
-fonts.protrusions.vectors['alpha'] = {
+vectors['alpha'] = {
[byte("A")] = { .05, .05 },
[byte("F")] = { 0, .05 },
@@ -188,21 +387,22 @@ fonts.protrusions.vectors['alpha'] = {
}
-fonts.protrusions.vectors['quality'] = table.merge( {},
- fonts.protrusions.vectors['punctuation'],
- fonts.protrusions.vectors['alpha']
+vectors['quality'] = table.merge( {},
+ vectors['punctuation'],
+ vectors['alpha']
)
-function fonts.initializers.common.protrusion(tfmdata,value)
+function initializers.common.protrusion(tfmdata,value)
if value then
- local class = fonts.protrusions.classes[value]
+ local class = classes[value]
if class then
- local vector = fonts.protrusions.vectors[class.vector]
+ local vector = vectors[class.vector]
if vector then
local factor = class.factor or 1
local data = characters.data
local emwidth = tfmdata.parameters.quad
- for i, chr in pairs(tfmdata.characters) do
+ tfmdata.auto_protrude = true
+ for i, chr in next, tfmdata.characters do
local v, pl, pr = vector[i], nil, nil
if v then
pl, pr = v[1], v[2]
@@ -234,8 +434,46 @@ end
table.insert(fonts.manipulators,"protrusion")
-fonts.initializers.base.otf.protrusion = fonts.initializers.common.protrusion
-fonts.initializers.node.otf.protrusion = fonts.initializers.common.protrusion
+initializers.base.otf.protrusion = initializers.common.protrusion
+initializers.node.otf.protrusion = initializers.common.protrusion
+
+initializers.base.afm.protrusion = initializers.common.protrusion
+initializers.node.afm.protrusion = initializers.common.protrusion
+
+function initializers.common.nostackmath(tfmdata,value)
+ tfmdata.ignore_stack_math = value
+end
+
+table.insert(fonts.manipulators,"nostackmath")
+
+initializers.base.otf.nostackmath = initializers.common.nostackmath
+initializers.node.otf.nostackmath = initializers.common.nostackmath
+
+table.insert(fonts.triggers,"itlc")
+
+function initializers.common.itlc(tfmdata,value)
+ if value then
+ -- the magic 40 and it formula come from Dohyun Kim
+ local fontdata = tfmdata.shared.otfdata or tfmdata.shared.afmdata
+ local metadata = fontdata and fontdata.metadata
+ if metadata then
+ local italicangle = metadata.italicangle
+ if italicangle and italicangle ~= 0 then
+ local uwidth = (metadata.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.has_italic = true
+ end
+ end
+ end
+end
+
+initializers.base.otf.itlc = initializers.common.itlc
+initializers.node.otf.itlc = initializers.common.itlc
-fonts.initializers.base.afm.protrusion = fonts.initializers.common.protrusion
-fonts.initializers.node.afm.protrusion = fonts.initializers.common.protrusion
+initializers.base.afm.itlc = initializers.common.itlc
+initializers.node.afm.itlc = initializers.common.itlc