diff options
author | Marius <mariausol@gmail.com> | 2013-05-19 20:40:34 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2013-05-19 20:40:34 +0300 |
commit | 13ec4b540e0d46c97fd7b089e0b7413da81e0a9f (patch) | |
tree | bebfa563a17c06b3bd3bf8f6f4ba6d025e00d107 /tex/context/base/font-col.lua | |
parent | 69ad13650cda027526271179e95b5294694143a1 (diff) | |
download | context-13ec4b540e0d46c97fd7b089e0b7413da81e0a9f.tar.gz |
beta 2013.05.19 19:27
Diffstat (limited to 'tex/context/base/font-col.lua')
-rw-r--r-- | tex/context/base/font-col.lua | 476 |
1 files changed, 238 insertions, 238 deletions
diff --git a/tex/context/base/font-col.lua b/tex/context/base/font-col.lua index 20c99c9b4..b8b221fc4 100644 --- a/tex/context/base/font-col.lua +++ b/tex/context/base/font-col.lua @@ -1,238 +1,238 @@ -if not modules then modules = { } end modules ['font-col'] = { - version = 1.001, - comment = "companion to font-ini.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- possible optimization: delayed initialization of vectors - -local context, commands, trackers, logs = context, commands, trackers, logs -local node, nodes, fonts, characters = node, nodes, fonts, characters -local file, lpeg, table, string = file, lpeg, table, string - -local type, next, toboolean = type, next, toboolean -local gmatch = string.gmatch -local fastcopy = table.fastcopy ------ P, Cc, lpegmatch = lpeg.P, lpeg.Cc, lpeg.match - -local traverse_id = node.traverse_id -local settings_to_hash = utilities.parsers.settings_to_hash - -local trace_collecting = false trackers.register("fonts.collecting", function(v) trace_collecting = v end) - -local report_fonts = logs.reporter("fonts","collections") - -local collections = fonts.collections or { } -fonts.collections = collections - -local definitions = collections.definitions or { } -collections.definitions = definitions - -local vectors = collections.vectors or { } -collections.vectors = vectors - -local fontdata = fonts.hashes.identifiers -local glyph_code = nodes.nodecodes.glyph -local currentfont = font.current - -local fontpatternhassize = fonts.helpers.fontpatternhassize - -local list = { } -local current = 0 -local enabled = false - --- maybe also a copy - -function collections.reset(name,font) - if font and font ~= "" then - local d = definitions[name] - if d then - d[font] = nil - if not next(d) then - definitions[name] = nil - end - end - else - definitions[name] = nil - end -end - -function collections.define(name,font,ranges,details) - -- todo: details -> method=force|conditional rscale= - -- todo: remap=name - local d = definitions[name] - if not d then - d = { } - definitions[name] = d - end - if name and trace_collecting then - report_fonts("extending collection %a using %a",name,font) - end - details = settings_to_hash(details) - -- todo, combine per font start/stop as arrays - for s in gmatch(ranges,"[^, ]+") do - local start, stop, description = characters.getrange(s) - if start and stop then - if trace_collecting then - if description then - report_fonts("using range %a, slots %U - %U, description %a)",s,start,stop,description) - end - for i=1,#d do - local di = d[i] - if (start >= di.start and start <= di.stop) or (stop >= di.start and stop <= di.stop) then - report_fonts("overlapping ranges %U - %U and %U - %U",start,stop,di.start,di.stop) - end - end - end - details.font, details.start, details.stop = font, start, stop - d[#d+1] = fastcopy(details) - end - end -end - --- todo: provide a lua variant (like with definefont) - -function collections.registermain(name) - local last = currentfont() - if trace_collecting then - report_fonts("registering font %a with name %a",last,name) - end - list[#list+1] = last -end - -function collections.clonevector(name) - statistics.starttiming(fonts) - local d = definitions[name] - local t = { } - if trace_collecting then - report_fonts("processing collection %a",name) - end - for i=1,#d do - local f = d[i] - local id = list[i] - local start, stop = f.start, f.stop - if trace_collecting then - report_fonts("remapping font %a to %a for range %U - %U",current,id,start,stop) - end - local check = toboolean(f.check or "false",true) - local force = toboolean(f.force or "true",true) - local remap = f.remap or nil - -- check: when true, only set when present in font - -- force: when false, then not set when already set - local oldchars = fontdata[current].characters - local newchars = fontdata[id].characters - if check then - for i=start,stop do - if newchars[i] and (force or (not t[i] and not oldchars[i])) then - if remap then - t[i] = { id, remap[i] } - else - t[i] = id - end - end - end - else - for i=start,stop do - if force or (not t[i] and not oldchars[i]) then - if remap then - t[i] = { id, remap[i] } - else - t[i] = id - end - end - end - end - end - vectors[current] = t - if trace_collecting then - report_fonts("activating collection %a for font %a",name,current) - end - if not enabled then - nodes.tasks.enableaction("processors","fonts.collections.process") - enabled = true - end - statistics.stoptiming(fonts) -end - --- we already have this parser --- --- local spec = (P("sa") + P("at") + P("scaled") + P("at") + P("mo")) * P(" ")^1 * (1-P(" "))^1 * P(" ")^0 * -1 --- local okay = ((1-spec)^1 * spec * Cc(true)) + Cc(false) --- --- if lpegmatch(okay,name) then - -function collections.prepare(name) - current = currentfont() - if vectors[current] then - return - end - local d = definitions[name] - if d then - if trace_collecting then - local filename = file.basename(fontdata[current].properties.filename or "?") - report_fonts("applying collection %a to %a, file %a",name,current,filename) - end - list = { } - context.pushcatcodes("prt") -- context.unprotect() - context.font_fallbacks_start_cloning() - for i=1,#d do - local f = d[i] - local name = f.font - local scale = f.rscale or 1 - if fontpatternhassize(name) then - context.font_fallbacks_clone_unique(name,scale) - else - context.font_fallbacks_clone_inherited(name,scale) - end - context.font_fallbacks_register_main(name) - end - context.font_fallbacks_prepare_clone_vectors(name) - context.font_fallbacks_stop_cloning() - context.popcatcodes() -- context.protect() - elseif trace_collecting then - local filename = file.basename(fontdata[current].properties.filename or "?") - report_fonts("error while applying collection %a to %a, file %a",name,current,filename) - end -end - -function collections.report(message) - if trace_collecting then - report_fonts("tex: %s",message) - end -end - -function collections.process(head) -- this way we keep feature processing - local done = false - for n in traverse_id(glyph_code,head) do - local v = vectors[n.font] - if v then - local id = v[n.char] - if id then - if type(id) == "table" then - local newid, newchar = id[1], id[2] - if trace_collecting then - report_fonts("remapping character %a in font %a to character %a in font %a",n.char,n.font,newchar,newid) - end - n.font, n.char = newid, newchar - else - if trace_collecting then - report_fonts("remapping font %a to %a for character %a",n.font,id,n.char) - end - n.font = id - end - end - end - end - return head, done -end - --- interface - -commands.fontcollectiondefine = collections.define -commands.fontcollectionreset = collections.reset -commands.fontcollectionprepare = collections.prepare -commands.fontcollectionreport = collections.report -commands.fontcollectionregister = collections.registermain -commands.fontcollectionclone = collections.clonevector +if not modules then modules = { } end modules ['font-col'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- possible optimization: delayed initialization of vectors
+
+local context, commands, trackers, logs = context, commands, trackers, logs
+local node, nodes, fonts, characters = node, nodes, fonts, characters
+local file, lpeg, table, string = file, lpeg, table, string
+
+local type, next, toboolean = type, next, toboolean
+local gmatch = string.gmatch
+local fastcopy = table.fastcopy
+----- P, Cc, lpegmatch = lpeg.P, lpeg.Cc, lpeg.match
+
+local traverse_id = node.traverse_id
+local settings_to_hash = utilities.parsers.settings_to_hash
+
+local trace_collecting = false trackers.register("fonts.collecting", function(v) trace_collecting = v end)
+
+local report_fonts = logs.reporter("fonts","collections")
+
+local collections = fonts.collections or { }
+fonts.collections = collections
+
+local definitions = collections.definitions or { }
+collections.definitions = definitions
+
+local vectors = collections.vectors or { }
+collections.vectors = vectors
+
+local fontdata = fonts.hashes.identifiers
+local glyph_code = nodes.nodecodes.glyph
+local currentfont = font.current
+
+local fontpatternhassize = fonts.helpers.fontpatternhassize
+
+local list = { }
+local current = 0
+local enabled = false
+
+-- maybe also a copy
+
+function collections.reset(name,font)
+ if font and font ~= "" then
+ local d = definitions[name]
+ if d then
+ d[font] = nil
+ if not next(d) then
+ definitions[name] = nil
+ end
+ end
+ else
+ definitions[name] = nil
+ end
+end
+
+function collections.define(name,font,ranges,details)
+ -- todo: details -> method=force|conditional rscale=
+ -- todo: remap=name
+ local d = definitions[name]
+ if not d then
+ d = { }
+ definitions[name] = d
+ end
+ if name and trace_collecting then
+ report_fonts("extending collection %a using %a",name,font)
+ end
+ details = settings_to_hash(details)
+ -- todo, combine per font start/stop as arrays
+ for s in gmatch(ranges,"[^, ]+") do
+ local start, stop, description = characters.getrange(s)
+ if start and stop then
+ if trace_collecting then
+ if description then
+ report_fonts("using range %a, slots %U - %U, description %a)",s,start,stop,description)
+ end
+ for i=1,#d do
+ local di = d[i]
+ if (start >= di.start and start <= di.stop) or (stop >= di.start and stop <= di.stop) then
+ report_fonts("overlapping ranges %U - %U and %U - %U",start,stop,di.start,di.stop)
+ end
+ end
+ end
+ details.font, details.start, details.stop = font, start, stop
+ d[#d+1] = fastcopy(details)
+ end
+ end
+end
+
+-- todo: provide a lua variant (like with definefont)
+
+function collections.registermain(name)
+ local last = currentfont()
+ if trace_collecting then
+ report_fonts("registering font %a with name %a",last,name)
+ end
+ list[#list+1] = last
+end
+
+function collections.clonevector(name)
+ statistics.starttiming(fonts)
+ local d = definitions[name]
+ local t = { }
+ if trace_collecting then
+ report_fonts("processing collection %a",name)
+ end
+ for i=1,#d do
+ local f = d[i]
+ local id = list[i]
+ local start, stop = f.start, f.stop
+ if trace_collecting then
+ report_fonts("remapping font %a to %a for range %U - %U",current,id,start,stop)
+ end
+ local check = toboolean(f.check or "false",true)
+ local force = toboolean(f.force or "true",true)
+ local remap = f.remap or nil
+ -- check: when true, only set when present in font
+ -- force: when false, then not set when already set
+ local oldchars = fontdata[current].characters
+ local newchars = fontdata[id].characters
+ if check then
+ for i=start,stop do
+ if newchars[i] and (force or (not t[i] and not oldchars[i])) then
+ if remap then
+ t[i] = { id, remap[i] }
+ else
+ t[i] = id
+ end
+ end
+ end
+ else
+ for i=start,stop do
+ if force or (not t[i] and not oldchars[i]) then
+ if remap then
+ t[i] = { id, remap[i] }
+ else
+ t[i] = id
+ end
+ end
+ end
+ end
+ end
+ vectors[current] = t
+ if trace_collecting then
+ report_fonts("activating collection %a for font %a",name,current)
+ end
+ if not enabled then
+ nodes.tasks.enableaction("processors","fonts.collections.process")
+ enabled = true
+ end
+ statistics.stoptiming(fonts)
+end
+
+-- we already have this parser
+--
+-- local spec = (P("sa") + P("at") + P("scaled") + P("at") + P("mo")) * P(" ")^1 * (1-P(" "))^1 * P(" ")^0 * -1
+-- local okay = ((1-spec)^1 * spec * Cc(true)) + Cc(false)
+--
+-- if lpegmatch(okay,name) then
+
+function collections.prepare(name)
+ current = currentfont()
+ if vectors[current] then
+ return
+ end
+ local d = definitions[name]
+ if d then
+ if trace_collecting then
+ local filename = file.basename(fontdata[current].properties.filename or "?")
+ report_fonts("applying collection %a to %a, file %a",name,current,filename)
+ end
+ list = { }
+ context.pushcatcodes("prt") -- context.unprotect()
+ context.font_fallbacks_start_cloning()
+ for i=1,#d do
+ local f = d[i]
+ local name = f.font
+ local scale = f.rscale or 1
+ if fontpatternhassize(name) then
+ context.font_fallbacks_clone_unique(name,scale)
+ else
+ context.font_fallbacks_clone_inherited(name,scale)
+ end
+ context.font_fallbacks_register_main(name)
+ end
+ context.font_fallbacks_prepare_clone_vectors(name)
+ context.font_fallbacks_stop_cloning()
+ context.popcatcodes() -- context.protect()
+ elseif trace_collecting then
+ local filename = file.basename(fontdata[current].properties.filename or "?")
+ report_fonts("error while applying collection %a to %a, file %a",name,current,filename)
+ end
+end
+
+function collections.report(message)
+ if trace_collecting then
+ report_fonts("tex: %s",message)
+ end
+end
+
+function collections.process(head) -- this way we keep feature processing
+ local done = false
+ for n in traverse_id(glyph_code,head) do
+ local v = vectors[n.font]
+ if v then
+ local id = v[n.char]
+ if id then
+ if type(id) == "table" then
+ local newid, newchar = id[1], id[2]
+ if trace_collecting then
+ report_fonts("remapping character %a in font %a to character %a in font %a",n.char,n.font,newchar,newid)
+ end
+ n.font, n.char = newid, newchar
+ else
+ if trace_collecting then
+ report_fonts("remapping font %a to %a for character %a",n.font,id,n.char)
+ end
+ n.font = id
+ end
+ end
+ end
+ end
+ return head, done
+end
+
+-- interface
+
+commands.fontcollectiondefine = collections.define
+commands.fontcollectionreset = collections.reset
+commands.fontcollectionprepare = collections.prepare
+commands.fontcollectionreport = collections.report
+commands.fontcollectionregister = collections.registermain
+commands.fontcollectionclone = collections.clonevector
|