summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/good-ctx.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/good-ctx.lua')
-rw-r--r--tex/context/base/mkiv/good-ctx.lua300
1 files changed, 300 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/good-ctx.lua b/tex/context/base/mkiv/good-ctx.lua
new file mode 100644
index 000000000..00e4ed78d
--- /dev/null
+++ b/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