diff options
-rw-r--r-- | luaotfload-features.lua | 99 |
1 files changed, 83 insertions, 16 deletions
diff --git a/luaotfload-features.lua b/luaotfload-features.lua index 7ae035b..1635fba 100644 --- a/luaotfload-features.lua +++ b/luaotfload-features.lua @@ -9,6 +9,7 @@ if not modules then modules = { } end modules ["features"] = { local format, insert = string.format, table.insert local type, next = type, next local lpegmatch = lpeg.match +local mathceil = math.ceil ---[[ begin included font-ltx.lua ]] --- this appears to be based in part on luatex-fonts-def.lua @@ -877,22 +878,83 @@ end --doc]]-- -local strip_leading_sign = function (s) - --- handle option list keys - local first = stringsub(s, 1, 1) - if first == "+" or first == "-" then --- Xetex style - return stringsub(s, 2) +--local strip_leading_sign = function (s) +-- --- handle option list keys +-- local first = stringsub(s, 1, 1) +-- if first == "+" or first == "-" then --- Xetex style +-- return stringsub(s, 2) +-- end +-- return s +--end +-- +--local toboolean = function (s) +-- --- handle option list values +-- if s == "true" then return true end +-- if s == "false" then return false end +-- --if s == "yes" then return true end --- Context style +-- --if s == "no" then return false end +-- return stringlower(s) +--end + +local handle_normal_option = function (key, val) + val = stringlower(val) + --- the former “toboolean()” handler + if val == "true" then + val = true + elseif val == "false" then + val = false end - return s + return key, val end -local toboolean = function (s) - --- handle option list values - if s == "true" then return true end - if s == "false" then return false end - --if s == "yes" then return true end --- Context style - --if s == "no" then return false end - return stringlower(s) +--[[doc-- + + Xetex style indexing begins at zero which we just increment before + passing it along to the font loader. Ymmv. + + However, some non-indexed options expect scalars, so we cannot just + blindly add to *any* feature value. Instead we restrict it to those + features that are known to accept an index value, for instance GSUB + lookup type 3 ones like “ssty”. + + http://partners.adobe.com/public/developer/opentype/index_table_formats1.html#ASF1 + +--doc]]-- + +local indexed_features = table.tohash ({ + --- Note that this list is not definitive and was gathered by + --- grepping Adobe’s feature tag spec. + "aalt", + "cswh", + "curs", + "falt", + "hngl", + "jalt", + "jp78", + "nalt", + "ornm", + "rand", + "rlig", + "salt", + "ssty", + "swsh", + "trad", +}, true) + +local handle_xetex_option = function (key, val) + local numeric = tonumber(val) --- decimal only; keeps colors intact + if numeric then --- ugh + if mathceil(numeric) == numeric -- integer, possible index + and indexed_features[key] + then + val = tostring(numeric + 1) + end + elseif val == "true" then + val = true + elseif val == "false" then + val = false + end + return key, val end --[[doc-- @@ -977,10 +1039,15 @@ local path_lookup = lbrk * Cg(C((1-rbrk)^1), "path") * rbrk --- features ---------------------------------------------------------- local field = (anum + S"+-.")^1 --- sic! --- assignments are “lhs=rhs” +--- or “+lhs=rhs” (Xetex-style) --- switches are “+key” | “-key” -local assignment = (field / strip_leading_sign) * ws - * equals * ws - * (field / toboolean) +local normal_option = C(field) * ws * equals * ws * C(field) * ws +local xetex_option = P"+" * ws * normal_option +local assignment = xetex_option / handle_xetex_option + + normal_option / handle_normal_option +----- assignment = (field / strip_leading_sign) * ws +----- * equals * ws +----- * (field / toboolean) local switch = P"+" * ws * C(field) * Cc(true) + P"-" * ws * C(field) * Cc(false) + C(field) * Cc(true) -- catch crap |