diff options
author | Hans Hagen <pragma@wxs.nl> | 2017-06-27 18:48:11 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2017-06-27 18:48:11 +0200 |
commit | f8d48a62bd62df77685bd8581c1b8311ae26525f (patch) | |
tree | 56d8e9d605c1877d2f1c14b878c962d29d52cc9f /tex/context/base/mkiv/font-ext.lua | |
parent | 5c9b859165af46407543b25589ce8852ee079620 (diff) | |
download | context-f8d48a62bd62df77685bd8581c1b8311ae26525f.tar.gz |
2017-06-27 18:10:00
Diffstat (limited to 'tex/context/base/mkiv/font-ext.lua')
-rw-r--r-- | tex/context/base/mkiv/font-ext.lua | 163 |
1 files changed, 161 insertions, 2 deletions
diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua index da629c045..85e39e877 100644 --- a/tex/context/base/mkiv/font-ext.lua +++ b/tex/context/base/mkiv/font-ext.lua @@ -7,9 +7,9 @@ if not modules then modules = { } end modules ['font-ext'] = { } local next, type, tonumber = next, type, tonumber -local formatters = string.formatters -local byte = string.byte +local byte, find, formatters = string.byte, string.find, string.formatters local utfchar = utf.char +local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort local context = context local fonts = fonts @@ -1350,3 +1350,162 @@ do } end + +do + + -- This is a rather special test-only feature that I added for the sake of testing + -- Idris's husayni. We wanted to know if uniscribe obeys the order of lookups in a + -- font, in spite of what the description of handling arabic suggests. And indeed, + -- mixed-in lookups of other features (like all these ss* in husayni) are handled + -- the same in context as in uniscribe. If one sets reorderlookups=arab then we sort + -- according to the "assumed" order so e.g. the ss* move to after the standard + -- features. The observed difference in rendering is an indication that uniscribe is + -- quite faithful to the font (while e.g. tests with the hb plugin demonstrate some + -- interference, apart from some hard coded init etc expectations). Anyway, it means + -- that we're okay with the (generic) node processor. A pitfall is that in context + -- we can actually control more, so we can trigger an analyze pass with e.g. + -- dflt/dflt while the libraries depend on the script settings for that. Uniscribe + -- probably also parses the string and when seeing arabic will follow a different + -- code path, although it seems to treat all features equal. + + local trace_reorder = trackers.register("fonts.reorderlookups",function(v) trace_reorder = v end) + local report_reorder = logs.reporter("fonts","reorder") + + local vectors = { } + + vectors.arab = { + gsub = { + ccmp = 1, + init = 2, + medi = 3, + fina = 4, + isol = 5, + rlig = 6, + rclt = 7, + calt = 8, + liga = 9, + dlig = 10, + cswh = 11, + mset = 12, + }, + gpos = { + curs = 1, + kern = 2, + mark = 3, + mkmk = 4, + }, + } + + function otf.reorderlookups(tfmdata,vector) + local order = vectors[vector] + if not order then + return + end + local oldsequences = tfmdata.resources.sequences + if oldsequences then + local sequences = { } + for i=1,#oldsequences do + sequences[i] = oldsequences[i] + end + for i=1,#sequences do + local s = sequences[i] + local features = s.features + local kind = s.type + local index = s.index + if features then + local when + local what + for feature in sortedhash(features) do + if not what then + what = find(kind,"^gsub") and "gsub" or "gpos" + end + local newwhen = order[what][feature] + if not newwhen then + -- skip + elseif not when then + when = newwhen + elseif newwhen < when then + when = newwhen + end + end + s.ondex = s.index + s.index = i + s.what = what == "gsub" and 1 or 2 + s.when = when or 99 + else + s.ondex = s.index + s.index = i + s.what = 1 + s.when = 99 + end + end + sort(sequences,function(a,b) + local what_a = a.what + local what_b = b.what + if what_a ~= what_b then + return a.index < b.index + end + local when_a = a.when + local when_b = b.when + if when_a == when_b then + return a.index < b.index + else + return when_a < when_b + end + end) + local swapped = 0 + for i=1,#sequences do + local sequence = sequences[i] + local features = sequence.features + if features then + local index = sequence.index + if index ~= i then + swapped = swapped + 1 + end + if trace_reorder then + if swapped == 1 then + report_reorder() + report_reorder("start swapping lookups in font %!font:name!",tfmdata) + report_reorder() + report_reorder("gsub order: % t",table.swapped(order.gsub)) + report_reorder("gpos order: % t",table.swapped(order.gpos)) + report_reorder() + end + report_reorder("%03i : lookup %03i, type %s, sorted %2i, moved %s, % t", + i,index,sequence.what == 1 and "gsub" or "gpos",sequence.when or 99, + (index > i and "-") or (index < i and "+") or "=",sortedkeys(features)) + end + end + sequence.what = nil + sequence.when = nil + sequence.index = sequence.ondex + end + if swapped > 0 then + if trace_reorder then + report_reorder() + report_reorder("stop swapping lookups, %i lookups swapped",swapped) + report_reorder() + end + tfmdata.resources.sequences = sequences + end + end + end + + -- maybe delay till ra is filled + + local function reorderlookups(tfmdata,key,value) + if value then + otf.reorderlookups(tfmdata,value) + end + end + + registerotffeature { + name = "reorderlookups", + description = "reorder lookups", + manipulators = { + base = reorderlookups, + node = reorderlookups, + } + } + +end |