diff options
| author | Philipp Gesang <phg42.2a@gmail.com> | 2013-05-01 18:34:44 +0200 | 
|---|---|---|
| committer | Philipp Gesang <phg42.2a@gmail.com> | 2013-05-01 18:34:44 +0200 | 
| commit | 7cf60286cb69e8b5ffc47c06bdc9a18bb941e306 (patch) | |
| tree | bc11ccbfd25d8a4482c8f897c9ac1d615681db9a | |
| parent | 4466687a3a53e7868bd157ed6f8eac637ea182b5 (diff) | |
| download | luaotfload-7cf60286cb69e8b5ffc47c06bdc9a18bb941e306.tar.gz | |
add feature related functionality to auxlib
| -rw-r--r-- | luaotfload-auxiliary.lua | 164 | ||||
| -rwxr-xr-x | mkglyphlist | 6 | ||||
| -rw-r--r-- | tests/pln-aux-1.tex | 4 | ||||
| -rw-r--r-- | tests/pln-aux-2.tex | 102 | 
4 files changed, 273 insertions, 3 deletions
| diff --git a/luaotfload-auxiliary.lua b/luaotfload-auxiliary.lua index 1f0c79c..2d55db5 100644 --- a/luaotfload-auxiliary.lua +++ b/luaotfload-auxiliary.lua @@ -18,9 +18,15 @@ luaotfload.aux              = luaotfload.aux or { }  config                      = config or { }  config.luaotfload           = config.luaotfload or { } -local utf8 = unicode.utf8 +local aux           = luaotfload.aux +local log           = luaotfload.log +local identifiers   = fonts.hashes.identifiers -local aux = luaotfload.aux + +local utf8          = unicode.utf8 +local stringlower   = string.lower +local stringformat  = string.format +local stringgsub    = string.gsub  -----------------------------------------------------------------------  ---                          font patches @@ -81,7 +87,7 @@ luatexbase.add_to_callback(    "luaotfload.aux.patch_cambria_domh")  ----------------------------------------------------------------------- ----                              fonts +---                             glyphs  -----------------------------------------------------------------------  --- int -> int -> bool @@ -114,4 +120,156 @@ end  aux.do_if_glyph_else = do_if_glyph_else +----------------------------------------------------------------------- +---                 features / scripts / languages +----------------------------------------------------------------------- +--- lots of arrowcode ahead + +--[[doc-- +This function, modeled after “check_script()” from fontspec, returns +true if in the given font, the script “asked_script” is accounted for in at +least one feature. +--doc]]-- + +--- int -> string -> bool +local provides_script = function (font_id, asked_script) +  asked_script = stringlower(asked_script) +  if font_id and font_id > 0 then +    local fontdata = identifiers[font_id].shared.rawdata +    if fontdata then +      local fontname = fontdata.metadata.fontname +      local features = fontdata.resources.features +      for method, featuredata in next, features do +        --- where method: "gpos" | "gsub" +        for feature, data in next, featuredata do +          if data[asked_script] then +            log(stringformat( +              "font no %d (%s) defines feature %s for script %s", +              font_id, fontname, feature, asked_script)) +            return true +          end +        end +      end +      log(stringformat( +        "font no %d (%s) defines no feature for script %s", +        font_id, fontname, asked_script)) +    end +  end +  log(stringformat("no font with id %d", font_id)) +  return false +end + +aux.provides_script = provides_script + +--[[doc-- +This function, modeled after “check_language()” from fontspec, returns +true if in the given font, the language with tage “asked_language” is +accounted for in the script with tag “asked_script” in at least one +feature. +--doc]]-- + +--- int -> string -> string -> bool +local provides_language = function (font_id, asked_script, asked_language) +  asked_script     = stringlower(asked_script) +  asked_language   = stringlower(asked_language) +  if font_id and font_id > 0 then +    local fontdata = identifiers[font_id].shared.rawdata +    if fontdata then +      local fontname = fontdata.metadata.fontname +      local features = fontdata.resources.features +      for method, featuredata in next, features do +        --- where method: "gpos" | "gsub" +        for feature, data in next, featuredata do +          local scriptdata = data[asked_script] +          if scriptdata and scriptdata[asked_language] then +            log(stringformat("font no %d (%s) defines feature %s " +                          .. "for script %s with language %s", +                             font_id, fontname, feature, +                             asked_script, asked_language)) +            return true +          end +        end +      end +      log(stringformat( +        "font no %d (%s) defines no feature for script %s with language %s", +        font_id, fontname, asked_script, asked_language)) +    end +  end +  log(stringformat("no font with id %d", font_id)) +  return false +end + +aux.provides_language = provides_language + +--[[doc-- +We strip the syntax elements from feature definitions (shouldn’t +actually be there in the first place, but who cares ...) +--doc]]-- + +local lpeg        = require"lpeg" +local C, P, S     = lpeg.C, lpeg.P, lpeg.S +local lpegmatch   = lpeg.match + +local sign            = S"+-" +local rhs             = P"=" * P(1)^0 * P(-1) +local strip_garbage   = sign^-1 * C((1 - rhs)^1) + +--s   = "+foo"        --> foo +--ss  = "-bar"        --> bar +--sss = "baz"         --> baz +--t   = "foo=bar"     --> foo +--tt  = "+bar=baz"    --> bar +--ttt = "-baz=true"   --> baz +-- +--print(lpeg.match(strip_garbage, s)) +--print(lpeg.match(strip_garbage, ss)) +--print(lpeg.match(strip_garbage, sss)) +--print(lpeg.match(strip_garbage, t)) +--print(lpeg.match(strip_garbage, tt)) +--print(lpeg.match(strip_garbage, ttt)) + +--[[doc-- +This function, modeled after “check_feature()” from fontspec, returns +true if in the given font, the language with tag “asked_language” is +accounted for in the script with tag “asked_script” in feature +“asked_feature”. +--doc]]-- + +--- int -> string -> string -> string -> bool +local provides_feature = function(font_id,        asked_script, +                                  asked_language, asked_feature) +  asked_script    = stringlower(asked_script) +  asked_language  = stringlower(asked_language) +  asked_feature   = lpegmatch(strip_garbage, asked_feature) + +  if font_id and font_id > 0 then +    local fontdata = identifiers[font_id].shared.rawdata +    if fontdata then +      local features = fontdata.resources.features +      local fontname = fontdata.metadata.fontname +      for method, featuredata in next, features do +        --- where method: "gpos" | "gsub" +        local feature = featuredata[asked_feature] +        if feature then +          local scriptdata = feature[asked_script] +          if scriptdata and scriptdata[asked_language] then +            log(stringformat("font no %d (%s) defines feature %s " +                          .. "for script %s with language %s", +                             font_id, fontname, asked_feature, +                             asked_script, asked_language)) +            return true +          end +        end +      end +      log(stringformat( +        "font no %d (%s) does not define feature %s for script %s with language %s", +        font_id, fontname, asked_feature, asked_script, asked_language)) +    end +  end +  log(stringformat("no font with id %d", font_id)) +  return false +end + +aux.provides_feature = provides_feature +  -- vim:tw=71:sw=2:ts=2:expandtab diff --git a/mkglyphlist b/mkglyphlist index 9ee1528..d73a608 100755 --- a/mkglyphlist +++ b/mkglyphlist @@ -8,6 +8,12 @@  --      VERSION:  1.0  --      CREATED:  04/23/2013 12:42:17 PM CEST  ----------------------------------------------------------------------- +-- interesting thread on the Context list: +-- http://www.ntg.nl/pipermail/ntg-context/2008/029057.html +----------------------------------------------------------------------- + + +-----------------------------------------------------------------------  --                              config  -----------------------------------------------------------------------  local glyphfile     = "./glyphlist.txt" diff --git a/tests/pln-aux-1.tex b/tests/pln-aux-1.tex index f33ef21..a504850 100644 --- a/tests/pln-aux-1.tex +++ b/tests/pln-aux-1.tex @@ -1,4 +1,8 @@  \input luaotfload.sty + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% usage for glyph tests +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  \baselineskip=17.28pt  \font\iwonaregular=name:iwona at 14.4pt diff --git a/tests/pln-aux-2.tex b/tests/pln-aux-2.tex new file mode 100644 index 0000000..62192a5 --- /dev/null +++ b/tests/pln-aux-2.tex @@ -0,0 +1,102 @@ +\input luaotfload.sty +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% script, features, and language +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\font\minionregular=file:MinionPro_Regular.otf  at 9pt +\font\biolinum=file:LinBiolinum_R.otf  at 9pt +\font\cmuregular=file:cmunrm.otf  at 9pt + +%% (1) luaotfload.aux.provides_script(font_id, script) +%%      #1 defined font; #2 OT script tag +\def\providesscript[#1][#2]{% +  \bgroup#1% +  let’s see whether \detokenize{#1} has script #2: +  \directlua{ +    local aux = luaotfload.aux +    local succ = aux.provides_script(font.current(), [[#2]]) +    if succ then tex.sprint"true" else tex.sprint"false" end +  }% +  \egroup +  \endgraf% +} + +\providesscript [\minionregular][latn]%% Latin +\providesscript      [\biolinum][latn] +\providesscript    [\cmuregular][latn] +\providesscript [\minionregular][cyrl]%% Cyrillic +\providesscript      [\biolinum][cyrl] +\providesscript    [\cmuregular][cyrl] +\providesscript [\minionregular][tibt]%% Tibetan +\providesscript      [\biolinum][tibt] +\providesscript    [\cmuregular][tibt] + +\hrule % -------------------------------------------------------------- + +%% (2) luaotfload.aux.provides_language(font_id, script, language) +%%      #1 defined font; #2 OT script tag; #3 OT language tag +\def\provideslanguage[#1][#2][#3]{% +  \bgroup#1% +  let’s see whether \detokenize{#1} supports language #3 for script #2: +  \directlua{ +    local aux = luaotfload.aux +    local succ = aux.provides_language(font.current(), [[#2]], [[#3]]) +    if succ then tex.sprint"true" else tex.sprint"false" end +  }% +  \egroup +  \endgraf% +} + +\provideslanguage [\minionregular][latn][nld]%% Latin/Dutch +\provideslanguage      [\biolinum][latn][nld] +\provideslanguage    [\cmuregular][latn][nld] +\provideslanguage [\minionregular][latn][deu]%% Latin/German +\provideslanguage      [\biolinum][latn][deu] +\provideslanguage    [\cmuregular][latn][deu] +\provideslanguage [\minionregular][cyrl][rus]%% Cyrillic/Russian +\provideslanguage      [\biolinum][cyrl][rus] +\provideslanguage    [\cmuregular][cyrl][rus] +\provideslanguage [\minionregular][cyrl][klm]%% Cyrillic/Kalmyk +\provideslanguage      [\biolinum][cyrl][klm] +\provideslanguage    [\cmuregular][cyrl][klm] +\provideslanguage [\minionregular][cyrl][srb]%% Cyrillic/Serbian +\provideslanguage      [\biolinum][cyrl][srb] +\provideslanguage    [\cmuregular][cyrl][srb] +\provideslanguage [\minionregular][tibt][tib]%% Tibetan +\provideslanguage      [\biolinum][tibt][tib] +\provideslanguage    [\cmuregular][tibt][tib] + +\hrule % -------------------------------------------------------------- + +%% (3) luaotfload.aux.provides_feature( +%%                      font_id, script, language, feature) +%%      #1 defined font;    #2 OT script tag; +%%      #3 OT language tag; #4 OT feature +\def\providesfeature[#1][#2][#3][#4]{%this is getting ridiculous +  \bgroup#1% +  let’s see whether \detokenize{#1} supports feature #4 for the +  combination of script #2 with language #3: +  \directlua{ +    local aux = luaotfload.aux +    local succ = aux.provides_feature( +      font.current(), [[#2]], [[#3]], [[#4]]) +    if succ then tex.sprint"true" else tex.sprint"false" end +  }% +  \egroup +  \endgraf% +} + +\providesfeature [\minionregular][latn][nld][liga]%% Latin/Dutch +\providesfeature      [\biolinum][latn][nld][liga] +\providesfeature    [\cmuregular][latn][nld][liga] +\providesfeature [\minionregular][latn][deu][liga]%% Latin/German +\providesfeature      [\biolinum][latn][deu][liga] +\providesfeature    [\cmuregular][latn][deu][liga] +\providesfeature [\minionregular][cyrl][srb][liga]%% Cyrillic/Serbian +\providesfeature      [\biolinum][cyrl][srb][liga] +\providesfeature    [\cmuregular][cyrl][srb][liga] +\providesfeature [\minionregular][tibt][tib][liga]%% Tibetan +\providesfeature      [\biolinum][tibt][tib][liga] +\providesfeature    [\cmuregular][tibt][tib][liga] + +\bye | 
