diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/good-ctx.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/good-ctx.lua | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/good-ctx.lua b/Master/texmf-dist/tex/context/base/mkiv/good-ctx.lua new file mode 100644 index 00000000000..00e4ed78d89 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/good-ctx.lua @@ -0,0 +1,300 @@ +if not modules then modules = { } end modules ['good-ctx'] = { + version = 1.000, + comment = "companion to font-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- depends on ctx + +local type, next, tonumber = type, next, tonumber +local find, splitup = string.find, string.splitup + +local fonts = fonts +local nodes = nodes +local attributes = attributes + +----- trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) +----- report_goodies = logs.reporter("fonts","goodies") + +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex + +local implement = interfaces.implement + +local registerotffeature = fonts.handlers.otf.features.register +----- registerafmfeature = fonts.handlers.afm.features.register +----- registertfmfeature = fonts.handlers.tfm.features.register + +local fontgoodies = fonts.goodies or { } + +local glyph_code = nodes.nodecodes.glyph + +local nuts = nodes.nuts +local tonut = nuts.tonut +local getfont = nuts.getfont +local getchar = nuts.getchar +local getattr = nuts.getattr +local traverse_id = nuts.traverse_id + +-- colorschemes + +local colorschemes = fontgoodies.colorschemes or allocate { } +fontgoodies.colorschemes = colorschemes +colorschemes.data = colorschemes.data or { } + +local privatestoo = true + +local function setcolorscheme(tfmdata,scheme) + if type(scheme) == "string" then + local goodies = tfmdata.goodies + -- todo : check for already defined in shared + if goodies then + local what + for i=1,#goodies do + -- last one counts + local g = goodies[i] + what = g.colorschemes and g.colorschemes[scheme] or what + end + if type(what) == "table" then + -- this is font bound but we can share them if needed + -- just as we could hash the conversions (per font) + local hash = tfmdata.resources.unicodes + local reverse = { } + local characters = tfmdata.characters + for i=1,#what do + local w = what[i] + for j=1,#w do + local name = w[j] + local kind = type(name) + if name == "*" then + -- inefficient but only used for tracing anyway + for _, unicode in next, hash do + reverse[unicode] = i + end + elseif kind == "number" then + reverse[name] = i + elseif kind ~= "string" then + -- ignore invalid entries + elseif find(name,":",1,true) then + local start, stop = splitup(name,":") + start = tonumber(start) + stop = tonumber(stop) + if start and stop then + -- limited usage: we only deal with non reassigned + -- maybe some day I'll also support the ones with a + -- tounicode in this range + for unicode=start,stop do + if characters[unicode] then + reverse[unicode] = i + end + end + end + else + local unicode = hash[name] + if unicode then + reverse[unicode] = i + end + end + end + end + if privatestoo then + local private = fonts.constructors.privateoffset + local descriptions = tfmdata.descriptions + for unicode, data in next, characters do + if unicode >= private then + if not reverse[unicode] then + local d = descriptions[unicode] + if d then + local u = d.unicode + if u then + local r = reverse[u] -- also catches tables + if r then + reverse[unicode] = r + end + end + end + end + end + end + end + tfmdata.properties.colorscheme = reverse + return + end + end + end + tfmdata.properties.colorscheme = false +end + +local fontproperties = fonts.hashes.properties + +local a_colorscheme = attributes.private('colorscheme') +local setnodecolor = nodes.tracers.colors.set + +-- function colorschemes.coloring(head) +-- local lastfont, lastscheme +-- local done = false +-- for n in traverse_id(glyph_code,tonut(head)) do +-- local a = getattr(n,a_colorscheme) +-- if a then +-- local f = getfont(n) +-- if f ~= lastfont then +-- lastscheme = fontproperties[f].colorscheme +-- lastfont = f +-- end +-- if lastscheme then +-- local sc = lastscheme[getchar(n)] +-- if sc then +-- done = true +-- setnodecolor(n,"colorscheme:"..a..":"..sc) -- slow +-- end +-- end +-- end +-- end +-- return head, done +-- end + +-- seldom used, mostly in manuals, so non critical .. anyhow, somewhat faster: + +-- function colorschemes.coloring(head) +-- local lastfont = nil +-- local lastattr = nil +-- local lastscheme = nil +-- local lastprefix = nil +-- local done = nil +-- for n in traverse_id(glyph_code,tonut(head)) do +-- local a = getattr(n,a_colorscheme) +-- if a then +-- if a ~= lastattr then +-- lastattr = a +-- lastprefix = "colorscheme:" .. a .. ":" +-- end +-- local f = getfont(n) +-- if f ~= lastfont then +-- lastfont = f +-- lastscheme = fontproperties[f].colorscheme +-- end +-- if lastscheme then +-- local sc = lastscheme[getchar(n)] +-- if sc then +-- setnodecolor(n,lastprefix .. sc) -- slow +-- done = true +-- end +-- end +-- end +-- end +-- return head, done +-- end + +-- ok, in case we have hundreds of pages colored: + +local cache = { } -- this could be a weak table + +setmetatableindex(cache,function(t,a) + local v = { } + setmetatableindex(v,function(t,c) + local v = "colorscheme:" .. a .. ":" .. c + t[c] = v + return v + end) + t[a]= v + return v +end) + +function colorschemes.coloring(head) + local lastfont = nil + local lastattr = nil + local lastcache = nil + local lastscheme = nil + local done = nil + for n in traverse_id(glyph_code,tonut(head)) do + local a = getattr(n,a_colorscheme) + if a then + local f = getfont(n) + if f ~= lastfont then + lastfont = f + lastscheme = fontproperties[f].colorscheme + end + if a ~= lastattr then + lastattr = a + lastcache = cache[a] + end + if lastscheme then + local sc = lastscheme[getchar(n)] + if sc then + setnodecolor(n,lastcache[sc]) -- we could inline this one + done = true + end + end + end + end + return head, done +end + +function colorschemes.enable() + nodes.tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring") + function colorschemes.enable() end +end + +registerotffeature { + name = "colorscheme", + description = "goodie color scheme", + initializers = { + base = setcolorscheme, + node = setcolorscheme, + } +} + +-- kern hackery: +-- +-- yes : use goodies table +-- auto : assume features to be set (often ccmp only) + +local function setkeepligatures(tfmdata) + if not tfmdata.properties.keptligatures then + local goodies = tfmdata.goodies + if goodies then + for i=1,#goodies do + local g = goodies[i] + local letterspacing = g.letterspacing + if letterspacing then + local keptligatures = letterspacing.keptligatures + if keptligatures then + local unicodes = tfmdata.resources.unicodes -- so we accept names + local hash = { } + for k, v in next, keptligatures do + local u = unicodes[k] + if u then + hash[u] = true + else + -- error: unknown name + end + end + tfmdata.properties.keptligatures = hash + end + end + end + end + end +end + +registerotffeature { + name = "keepligatures", + description = "keep ligatures in letterspacing", + initializers = { + base = setkeepligatures, + node = setkeepligatures, + } +} + +if implement then + + implement { + name = "enablefontcolorschemes", + onlyonce = true, + actions = colorschemes.enable, + overload = true, -- for now, permits new font loader + } + +end |