diff options
author | Marius <mariausol@gmail.com> | 2013-05-20 03:20:28 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2013-05-20 03:20:28 +0300 |
commit | 5fc5cfb5014ddcc2942e13a559f4082fb66aa6e7 (patch) | |
tree | 53f81e99fac8c80ddd2fb70e233a7e5d5735722f /tex/context/base/font-col.lua | |
parent | 13ec4b540e0d46c97fd7b089e0b7413da81e0a9f (diff) | |
download | context-5fc5cfb5014ddcc2942e13a559f4082fb66aa6e7.tar.gz |
beta 2013.05.20 02:00
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 b8b221fc4..20c99c9b4 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 |