summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--otfl-font-dum.lua121
-rw-r--r--tests/opbd.fea244
-rw-r--r--tests/opbd.tex9
3 files changed, 363 insertions, 11 deletions
diff --git a/otfl-font-dum.lua b/otfl-font-dum.lua
index 8e13b5b..1d79ab1 100644
--- a/otfl-font-dum.lua
+++ b/otfl-font-dum.lua
@@ -155,20 +155,119 @@ fonts.protrusions.setups = fonts.protrusions.setups or { }
local setups = fonts.protrusions.setups
+-- As this is experimental code, users should not depend on it. The
+-- implications are still discussed on the ConTeXt Dev List and we're
+-- not sure yet what exactly the spec is (the next code is tested with
+-- a gyre font patched by / fea file made by Khaled Hosny). The double
+-- trick should not be needed it proper hanging punctuation is used in
+-- which case values < 1 can be used.
+--
+-- preferred (in context, usine vectors):
+--
+-- \definefontfeature[whatever][default][mode=node,protrusion=quality]
+--
+-- using lfbd and rtbd, with possibibility to enable only one side :
+--
+-- \definefontfeature[whocares][default][mode=node,protrusion=yes, opbd=yes,script=latn]
+-- \definefontfeature[whocares][default][mode=node,protrusion=right,opbd=yes,script=latn]
+--
+-- idem, using multiplier
+--
+-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn]
+-- \definefontfeature[whocares][default][mode=node,protrusion=double,opbd=yes,script=latn]
+--
+-- idem, using named feature file (less frozen):
+--
+-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea]
+
+local function map_opbd_onto_protrusion(tfmdata,value,opbd)
+ local characters, descriptions = tfmdata.characters, tfmdata.descriptions
+ local otfdata = tfmdata.shared.otfdata
+ local singles = otfdata.shared.featuredata.gpos_single
+ local script, language = tfmdata.script, tfmdata.language
+ local done, factor, left, right = false, 1, 1, 1
+ local setup = setups[value]
+ if setup then
+ factor = setup.factor or 1
+ left = setup.left or 1
+ right = setup.right or 1
+ else
+ factor = tonumber(value) or 1
+ end
+ if opbd ~= "right" then
+ local validlookups, lookuplist = fonts.otf.collect_lookups(otfdata,"lfbd",script,language)
+ if validlookups then
+ for i=1,#lookuplist do
+ local lookup = lookuplist[i]
+ local data = singles[lookup]
+ if data then
+ if trace_protrusion then
+ logs.report("fonts","set left protrusion using lfbd lookup '%s'",lookup)
+ end
+ for k, v in next, data do
+ -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same
+ local p = - (v[1] / 1000) * factor * left
+ characters[k].left_protruding = p
+ if trace_protrusion then
+ logs.report("opbd","lfbd -> %s -> 0x%05X (%s) -> %0.03f (%s)",lookup,k,utfchar(k),p,concat(v," "))
+ end
+ end
+ done = true
+ end
+ end
+ end
+ end
+ if opbd ~= "left" then
+ local validlookups, lookuplist = fonts.otf.collect_lookups(otfdata,"rtbd",script,language)
+ if validlookups then
+ for i=1,#lookuplist do
+ local lookup = lookuplist[i]
+ local data = singles[lookup]
+ if data then
+ if trace_protrusion then
+ logs.report("fonts","set right protrusion using rtbd lookup '%s'",lookup)
+ end
+ for k, v in next, data do
+ -- local p = v[3] / descriptions[k].width -- or 3
+ local p = (v[1] / 1000) * factor * right
+ characters[k].right_protruding = p
+ if trace_protrusion then
+ logs.report("opbd","rtbd -> %s -> 0x%05X (%s) -> %0.03f (%s)",lookup,k,utfchar(k),p,concat(v," "))
+ end
+ end
+ end
+ done = true
+ end
+ end
+ end
+ tfmdata.auto_protrude = done
+end
+
+-- The opbd test is just there because it was discussed on the
+-- context development list. However, the mentioned fxlbi.otf font
+-- only has some kerns for digits. So, consider this feature not
+-- supported till we have a proper test font.
+
function fonts.initializers.common.protrusion(tfmdata,value)
if value then
- local setup = setups[value]
- if setup then
- local factor, left, right = setup.factor or 1, setup.left or 1, setup.right or 1
- local emwidth = tfmdata.parameters.quad
- tfmdata.auto_protrude = true
- for i, chr in next, tfmdata.characters do
- local v, pl, pr = setup[i], nil, nil
- if v then
- pl, pr = v[1], v[2]
+ local opbd = tfmdata.shared.features.opbd
+ if opbd then
+ -- possible values: left right both yes no (experimental)
+ map_opbd_onto_protrusion(tfmdata,value,opbd)
+ elseif value then
+ local setup = setups[value]
+ if setup then
+ local factor, left, right = setup.factor or 1, setup.left or 1, setup.right or 1
+ local emwidth = tfmdata.parameters.quad
+ tfmdata.auto_protrude = true
+ for i, chr in next, tfmdata.characters do
+ local v, pl, pr = setup[i], nil, nil
+ if v then
+ pl, pr = v[1], v[2]
+ end
+ if pl and pl ~= 0 then chr.left_protruding = left *pl*factor end
+ if pr and pr ~= 0 then chr.right_protruding = right*pr*factor end
end
- if pl and pl ~= 0 then chr.left_protruding = left *pl*factor end
- if pr and pr ~= 0 then chr.right_protruding = right*pr*factor end
end
end
end
diff --git a/tests/opbd.fea b/tests/opbd.fea
new file mode 100644
index 0000000..affc3c5
--- /dev/null
+++ b/tests/opbd.fea
@@ -0,0 +1,244 @@
+
+lookup RightBounds {
+ lookupflag 0;
+ pos \exclam <100 0 0 0>;
+ pos \percent <100 0 0 0>;
+ pos \ampersand <100 0 0 0>;
+ pos \parenright <300 0 0 0>;
+ pos \asterisk <200 0 0 0>;
+ pos \plus <250 0 0 0>;
+ pos \comma <500 0 0 0>;
+ pos \hyphen <500 0 0 0>;
+ pos \period <700 0 0 0>;
+ pos \slash <300 0 0 0>;
+ pos \one <100 0 0 0>;
+ pos \seven <50 0 0 0>;
+ pos \colon <500 0 0 0>;
+ pos \semicolon <500 0 0 0>;
+ pos \question <200 0 0 0>;
+ pos \at <50 0 0 0>;
+ pos \A <50 0 0 0>;
+ pos \K <50 0 0 0>;
+ pos \L <50 0 0 0>;
+ pos \T <50 0 0 0>;
+ pos \V <50 0 0 0>;
+ pos \W <50 0 0 0>;
+ pos \X <50 0 0 0>;
+ pos \Y <50 0 0 0>;
+ pos \k <50 0 0 0>;
+ pos \p <50 0 0 0>;
+ pos \r <50 0 0 0>;
+ pos \v <50 0 0 0>;
+ pos \w <50 0 0 0>;
+ pos \x <50 0 0 0>;
+ pos \y <70 0 0 0>;
+ pos \asciitilde <250 0 0 0>;
+ pos \Agrave <50 0 0 0>;
+ pos \Aacute <50 0 0 0>;
+ pos \Acircumflex <50 0 0 0>;
+ pos \Atilde <50 0 0 0>;
+ pos \Adieresis <50 0 0 0>;
+ pos \Aring <50 0 0 0>;
+ pos \Amacron <50 0 0 0>;
+ pos \Abreve <50 0 0 0>;
+ pos \Aogonek <50 0 0 0>;
+ pos \Kcommaaccent <50 0 0 0>;
+ pos \kcommaaccent <50 0 0 0>;
+ pos \Lacute <50 0 0 0>;
+ pos \Lcommaaccent <50 0 0 0>;
+ pos \Lcaron <50 0 0 0>;
+ pos \Ldot <50 0 0 0>;
+ pos \Lslash <50 0 0 0>;
+ pos \racute <50 0 0 0>;
+ pos \rcommaaccent <50 0 0 0>;
+ pos \rcaron <50 0 0 0>;
+ pos \wcircumflex <50 0 0 0>;
+ pos \ycircumflex <70 0 0 0>;
+ pos \Acaron <50 0 0 0>;
+ pos \Aringacute <50 0 0 0>;
+ pos \Adblgrave <50 0 0 0>;
+ pos \rdblgrave <50 0 0 0>;
+ pos \uni021A <50 0 0 0>;
+ pos \Alpha <50 0 0 0>;
+ pos \Kappa <50 0 0 0>;
+ pos \Lambda <50 0 0 0>;
+ pos \Tau <50 0 0 0>;
+ pos \Ldotbelow <50 0 0 0>;
+ pos \Ldotbelowmacron <50 0 0 0>;
+ pos \rdotaccent <50 0 0 0>;
+ pos \rdotbelow <50 0 0 0>;
+ pos \rdotbelowmacron <50 0 0 0>;
+ pos \Tdotbelow <50 0 0 0>;
+ pos \Tlinebelow <50 0 0 0>;
+ pos \wgrave <50 0 0 0>;
+ pos \wacute <50 0 0 0>;
+ pos \wdieresis <50 0 0 0>;
+ pos \Ahookabove <50 0 0 0>;
+ pos \Acircumflexacute <50 0 0 0>;
+ pos \Acircumflexgrave <50 0 0 0>;
+ pos \Acircumflexhookabove <50 0 0 0>;
+ pos \Acircumflextilde <50 0 0 0>;
+ pos \Acircumflexdotbelow <50 0 0 0>;
+ pos \Abreveacute <50 0 0 0>;
+ pos \Abrevegrave <50 0 0 0>;
+ pos \Abrevehookabove <50 0 0 0>;
+ pos \Abrevetilde <50 0 0 0>;
+ pos \Abrevedotbelow <50 0 0 0>;
+ pos \ygrave <70 0 0 0>;
+ pos \ydotbelow <70 0 0 0>;
+ pos \yhookabove <70 0 0 0>;
+ pos \ytilde <70 0 0 0>;
+ pos \endash <300 0 0 0>;
+ pos \emdash <200 0 0 0>;
+ pos \quoteleft <700 0 0 0>;
+ pos \quoteright <700 0 0 0>;
+ pos \quotedblleft <400 0 0 0>;
+ pos \quotedblright <400 0 0 0>;
+ pos \Aogonekacute <50 0 0 0>;
+ pos \L_uni0303 <50 0 0 0>;
+ pos \T_uni0303 <50 0 0 0>;
+ pos \T_uni0308 <50 0 0 0>;
+} RightBounds;
+
+lookup LeftBounds {
+ lookupflag 0;
+ pos \percent <-100 0 -100 0>;
+ pos \ampersand <-50 0 -50 0>;
+ pos \parenleft <-100 0 -100 0>;
+ pos \asterisk <-200 0 -200 0>;
+ pos \plus <-250 0 -250 0>;
+ pos \hyphen <-400 0 -400 0>;
+ pos \slash <-200 0 -200 0>;
+ pos \one <-100 0 -100 0>;
+ pos \at <-50 0 -50 0>;
+ pos \A <-50 0 -50 0>;
+ pos \J <-50 0 -50 0>;
+ pos \T <-50 0 -50 0>;
+ pos \V <-50 0 -50 0>;
+ pos \W <-50 0 -50 0>;
+ pos \X <-50 0 -50 0>;
+ pos \Y <-50 0 -50 0>;
+ pos \p <-50 0 -50 0>;
+ pos \q <-50 0 -50 0>;
+ pos \v <-50 0 -50 0>;
+ pos \w <-50 0 -50 0>;
+ pos \x <-50 0 -50 0>;
+ pos \y <-50 0 -50 0>;
+ pos \asciitilde <-200 0 -200 0>;
+ pos \Agrave <-50 0 -50 0>;
+ pos \Aacute <-50 0 -50 0>;
+ pos \Acircumflex <-50 0 -50 0>;
+ pos \Atilde <-50 0 -50 0>;
+ pos \Adieresis <-50 0 -50 0>;
+ pos \Aring <-50 0 -50 0>;
+ pos \Amacron <-50 0 -50 0>;
+ pos \Abreve <-50 0 -50 0>;
+ pos \Aogonek <-50 0 -50 0>;
+ pos \Jcircumflex <-50 0 -50 0>;
+ pos \wcircumflex <-50 0 -50 0>;
+ pos \ycircumflex <-50 0 -50 0>;
+ pos \Acaron <-50 0 -50 0>;
+ pos \Aringacute <-50 0 -50 0>;
+ pos \Adblgrave <-50 0 -50 0>;
+ pos \uni021A <-50 0 -50 0>;
+ pos \Alpha <-50 0 -50 0>;
+ pos \Lambda <-50 0 -50 0>;
+ pos \Tau <-50 0 -50 0>;
+ pos \Tdotbelow <-50 0 -50 0>;
+ pos \Tlinebelow <-50 0 -50 0>;
+ pos \wgrave <-50 0 -50 0>;
+ pos \wacute <-50 0 -50 0>;
+ pos \wdieresis <-50 0 -50 0>;
+ pos \Ahookabove <-50 0 -50 0>;
+ pos \Acircumflexacute <-50 0 -50 0>;
+ pos \Acircumflexgrave <-50 0 -50 0>;
+ pos \Acircumflexhookabove <-50 0 -50 0>;
+ pos \Acircumflextilde <-50 0 -50 0>;
+ pos \Acircumflexdotbelow <-50 0 -50 0>;
+ pos \Abreveacute <-50 0 -50 0>;
+ pos \Abrevegrave <-50 0 -50 0>;
+ pos \Abrevehookabove <-50 0 -50 0>;
+ pos \Abrevetilde <-50 0 -50 0>;
+ pos \Abrevedotbelow <-50 0 -50 0>;
+ pos \ygrave <-50 0 -50 0>;
+ pos \ydotbelow <-50 0 -50 0>;
+ pos \yhookabove <-50 0 -50 0>;
+ pos \ytilde <-50 0 -50 0>;
+ pos \endash <-300 0 -300 0>;
+ pos \emdash <-200 0 -200 0>;
+ pos \quoteleft <-500 0 -500 0>;
+ pos \quoteright <-500 0 -500 0>;
+ pos \quotedblleft <-300 0 -300 0>;
+ pos \quotedblright <-300 0 -300 0>;
+ pos \Aogonekacute <-50 0 -50 0>;
+ pos \J_uni030C.cap <-50 0 -50 0>;
+ pos \T_uni0303 <-50 0 -50 0>;
+ pos \T_uni0308 <-50 0 -50 0>;
+} LeftBounds;
+
+feature rtbd {
+
+ script DFLT;
+ language dflt ;
+ lookup RightBounds;
+
+ script grek;
+ language dflt ;
+ lookup RightBounds;
+
+ script latn;
+ language dflt ;
+ lookup RightBounds;
+ language AZE exclude_dflt;
+ lookup RightBounds;
+ language CRT exclude_dflt;
+ lookup RightBounds;
+ language MOL exclude_dflt;
+ lookup RightBounds;
+ language NLD exclude_dflt;
+ lookup RightBounds;
+ language PLK exclude_dflt;
+ lookup RightBounds;
+ language ROM exclude_dflt;
+ lookup RightBounds;
+ language TRK exclude_dflt;
+ lookup RightBounds;
+
+ script thai;
+ language dflt ;
+ lookup RightBounds;
+} rtbd;
+
+feature lfbd {
+
+ script DFLT;
+ language dflt ;
+ lookup LeftBounds;
+
+ script grek;
+ language dflt ;
+ lookup LeftBounds;
+
+ script latn;
+ language dflt ;
+ lookup LeftBounds;
+ language AZE exclude_dflt;
+ lookup LeftBounds;
+ language CRT exclude_dflt;
+ lookup LeftBounds;
+ language MOL exclude_dflt;
+ lookup LeftBounds;
+ language NLD exclude_dflt;
+ lookup LeftBounds;
+ language PLK exclude_dflt;
+ lookup LeftBounds;
+ language ROM exclude_dflt;
+ lookup LeftBounds;
+ language TRK exclude_dflt;
+ lookup LeftBounds;
+
+ script thai;
+ language dflt ;
+ lookup LeftBounds;
+} lfbd;
+
diff --git a/tests/opbd.tex b/tests/opbd.tex
new file mode 100644
index 0000000..4c45781
--- /dev/null
+++ b/tests/opbd.tex
@@ -0,0 +1,9 @@
+\input luaotfload.sty
+
+\pdfprotrudechars2 \pdfadjustspacing2
+
+\font\testa=file:texgyrepagella-regular:script=latn at 12pt
+\font\testb=file:texgyrepagella-regular:mode=node;script=latn;protrusion=yes;featurefile=opbd.fea;+opbd at 12pt
+\testa \input tufte \par
+\testb \input tufte \par
+\bye