diff options
| author | Khaled Hosny <khaledhosny@eglug.org> | 2010-04-02 17:14:01 +0200 | 
|---|---|---|
| committer | Khaled Hosny <khaledhosny@eglug.org> | 2010-04-02 17:28:28 +0200 | 
| commit | 00ac320063ff016aea9f997948aa104d31bc95ff (patch) | |
| tree | 34285fa0a2a8c9fa728aba4d8a7fbe6f21251d8c | |
| parent | ae2c3eb500962f22cb836f415d3bab6da97e1fdd (diff) | |
| download | luaotfload-00ac320063ff016aea9f997948aa104d31bc95ff.tar.gz | |
Support 'opbd' (OpenType protrusion) feature
Code scrapped from ConTeXt, AFAIK, no font implements OpenType optical
bounds (on of Linux Libertine font has traces of it), but I plan to use
it in my fonts. The committed feature file is prepared for Pagella, we
can later have font specific feature files like this.
| -rw-r--r-- | otfl-font-dum.lua | 121 | ||||
| -rw-r--r-- | tests/opbd.fea | 244 | ||||
| -rw-r--r-- | tests/opbd.tex | 9 | 
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 | 
