From 4a713e7180d2de832a5cd69f4ebf706e927f7032 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 25 Mar 2015 23:36:13 +0100 Subject: [fontloader] sync with Context as of 2015-03-25 --- src/fontloader/misc/fontloader-font-map.lua | 4 +- src/fontloader/misc/fontloader-l-lpeg.lua | 198 ++++++++++++++++++++++++---- 2 files changed, 178 insertions(+), 24 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-font-map.lua b/src/fontloader/misc/fontloader-font-map.lua index e26f28e..449a00f 100644 --- a/src/fontloader/misc/fontloader-font-map.lua +++ b/src/fontloader/misc/fontloader-font-map.lua @@ -23,6 +23,8 @@ local fonts = fonts or { } local mappings = fonts.mappings or { } fonts.mappings = mappings +local allocate = utilities.storage.allocate + --[[ldx--

Eventually this code will disappear because map files are kind of obsolete. Some code may move to runtime or auxiliary modules.

@@ -194,7 +196,7 @@ local namesplitter = Ct(C((1 - ligseparator - varseparator)^1) * (ligseparator * -- to be completed .. for fonts that use unicodes for ligatures which -- is a actually a bad thing and should be avoided in the first place -local overloads = { +local overloads = allocate { IJ = { name = "I_J", unicode = { 0x49, 0x4A }, mess = 0x0132 }, ij = { name = "i_j", unicode = { 0x69, 0x6A }, mess = 0x0133 }, ff = { name = "f_f", unicode = { 0x66, 0x66 }, mess = 0xFB00 }, diff --git a/src/fontloader/misc/fontloader-l-lpeg.lua b/src/fontloader/misc/fontloader-l-lpeg.lua index 192e32f..0c89706 100644 --- a/src/fontloader/misc/fontloader-l-lpeg.lua +++ b/src/fontloader/misc/fontloader-l-lpeg.lua @@ -888,24 +888,155 @@ end -- return make(tree) -- end +local p_false = P(false) +local p_true = P(true) + +-- local function make(t,hash) +-- local p = p_false +-- local keys = sortedkeys(t) +-- for i=1,#keys do +-- local k = keys[i] +-- local v = t[k] +-- local h = hash[v] +-- if h then +-- if next(v) then +-- p = p + P(k) * (make(v,hash) + p_true) +-- else +-- p = p + P(k) * p_true +-- end +-- else +-- if next(v) then +-- p = p + P(k) * make(v,hash) +-- else +-- p = p + P(k) +-- end +-- end +-- end +-- return p +-- end + +-- local function make(t,hash) +-- local p = p_false +-- local keys = sortedkeys(t) +-- local function making(t,w) +-- local p = p_false +-- local keys = sortedkeys(t) +-- for i=1,#keys do +-- local k = keys[i] +-- local v = t[k] +-- if w then +-- if next(v) then +-- p = p + P(k) * (making(v,w) + p_true) +-- else +-- p = p + P(k) * p_true +-- end +-- else +-- if next(v) then +-- p = p + P(k) * making(v,w) +-- else +-- p = p + P(k) +-- end +-- end +-- end +-- return p +-- end +-- for i=1,#keys do +-- local k = keys[i] +-- local v = t[k] +-- local h = hash[v] +-- if h then +-- if next(v) then +-- p = p + P(k) * (making(v,true) + p_true) +-- else +-- p = p + P(k) * p_true +-- end +-- else +-- if next(v) then +-- p = p + P(k) * making(v,false) +-- else +-- p = p + P(k) +-- end +-- end +-- end +-- return p +-- end +-- +-- function lpeg.utfchartabletopattern(list) -- goes to util-lpg +-- local tree = { } +-- local hash = { } +-- local n = #list +-- if n == 0 then +-- for s in next, list do +-- local t = tree +-- for c in gmatch(s,".") do +-- local tc = t[c] +-- if not tc then +-- tc = { } +-- t[c] = tc +-- end +-- t = tc +-- end +-- hash[t] = s +-- end +-- else +-- for i=1,n do +-- local t = tree +-- local s = list[i] +-- for c in gmatch(s,".") do +-- local tc = t[c] +-- if not tc then +-- tc = { } +-- t[c] = tc +-- end +-- t = tc +-- end +-- hash[t] = s +-- end +-- end +-- return make(tree,hash) +-- end + + local function make(t,hash) - local p = P(false) + local p = p_false local keys = sortedkeys(t) + local function making(t,w) + local p = p_false + local keys = sortedkeys(t) + for i=1,#keys do + local k = keys[i] + local v = t[k] + if w then + if v == true then + p = p + P(k) * p_true + else + p = p + P(k) * (making(v,w) + p_true) + end + else + if v == true then + p = p + P(k) + else + p = p + P(k) * making(v,w) + end + end + end + return p + end for i=1,#keys do local k = keys[i] local v = t[k] local h = hash[v] if h then - if next(v) then - p = p + P(k) * (make(v,hash) + P(true)) + if v == true then + p = p + P(k) * p_true else - p = p + P(k) * P(true) + p = p + P(k) * (making(v,true) + p_true) end else - if next(v) then - p = p + P(k) * make(v,hash) - else + if v == true then p = p + P(k) + else + p = p + P(k) * making(v,false) end end end @@ -914,41 +1045,62 @@ end function lpeg.utfchartabletopattern(list) -- goes to util-lpg local tree = { } - local hash = { } +-- local hash = { } + local hash local n = #list if n == 0 then - -- we could always use this branch + hash = list for s in next, list do local t = tree + local p, pk for c in gmatch(s,".") do - local tc = t[c] - if not tc then - tc = { } - t[c] = tc + if t == true then + t = { [c] = true } + p[pk] = t + p = t + t = true + else + local tc = t[c] + if not tc then + tc = true + t[c] = tc + end + p = t + t = tc end - t = tc + pk = c end - hash[t] = s end else + hash = { } for i=1,n do local t = tree local s = list[i] + local p, pk for c in gmatch(s,".") do - local tc = t[c] - if not tc then - tc = { } - t[c] = tc + if t == true then + t = { [c] = true } + p[pk] = t + p = t + t = true + else + local tc = t[c] + if not tc then + tc = true + t[c] = true + end + p = t + t = tc end - t = tc + pk = c end - hash[t] = s + hash[s] = true end end return make(tree,hash) end --- inspect ( lpeg.utfchartabletopattern { +-- lpeg.utfchartabletopattern { -- utfchar(0x00A0), -- nbsp -- utfchar(0x2000), -- enquad -- utfchar(0x2001), -- emquad @@ -964,7 +1116,7 @@ end -- utfchar(0x200B), -- zerowidthspace -- utfchar(0x202F), -- narrownobreakspace -- utfchar(0x205F), -- math thinspace --- } ) +-- } -- a few handy ones: -- -- cgit v1.2.3 From 237d0436d8505bb4263a477022d42c8a291f5b36 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 29 Mar 2015 11:49:58 +0200 Subject: [fontloader] sync with Context as of 2015-03-29 --- src/fontloader/misc/fontloader-l-lpeg.lua | 270 ++++++++---------------------- 1 file changed, 72 insertions(+), 198 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-l-lpeg.lua b/src/fontloader/misc/fontloader-l-lpeg.lua index 0c89706..9225b57 100644 --- a/src/fontloader/misc/fontloader-l-lpeg.lua +++ b/src/fontloader/misc/fontloader-l-lpeg.lua @@ -834,209 +834,45 @@ end -- experiment: --- local function make(t) --- local p --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- if not p then --- if next(v) then --- p = P(k) * make(v) --- else --- p = P(k) --- end --- else --- if next(v) then --- p = p + P(k) * make(v) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end - --- local function make(t) --- local p = P(false) --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- if next(v) then --- p = p + P(k) * make(v) --- else --- p = p + P(k) --- end --- end --- return p --- end - --- function lpeg.utfchartabletopattern(list) -- goes to util-lpg --- local tree = { } --- for i=1,#list do --- local t = tree --- for c in gmatch(list[i],".") do --- local tc = t[c] --- if not tc then --- tc = { } --- t[c] = tc --- end --- t = tc --- end --- end --- return make(tree) --- end - local p_false = P(false) local p_true = P(true) --- local function make(t,hash) --- local p = p_false --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- local h = hash[v] --- if h then --- if next(v) then --- p = p + P(k) * (make(v,hash) + p_true) --- else --- p = p + P(k) * p_true --- end --- else --- if next(v) then --- p = p + P(k) * make(v,hash) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end - --- local function make(t,hash) --- local p = p_false --- local keys = sortedkeys(t) --- local function making(t,w) --- local p = p_false --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- if w then --- if next(v) then --- p = p + P(k) * (making(v,w) + p_true) --- else --- p = p + P(k) * p_true --- end --- else --- if next(v) then --- p = p + P(k) * making(v,w) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- local h = hash[v] --- if h then --- if next(v) then --- p = p + P(k) * (making(v,true) + p_true) --- else --- p = p + P(k) * p_true --- end --- else --- if next(v) then --- p = p + P(k) * making(v,false) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end --- --- function lpeg.utfchartabletopattern(list) -- goes to util-lpg --- local tree = { } --- local hash = { } --- local n = #list --- if n == 0 then --- for s in next, list do --- local t = tree --- for c in gmatch(s,".") do --- local tc = t[c] --- if not tc then --- tc = { } --- t[c] = tc --- end --- t = tc --- end --- hash[t] = s --- end --- else --- for i=1,n do --- local t = tree --- local s = list[i] --- for c in gmatch(s,".") do --- local tc = t[c] --- if not tc then --- tc = { } --- t[c] = tc --- end --- t = tc --- end --- hash[t] = s --- end --- end --- return make(tree,hash) --- end - - -local function make(t,hash) - local p = p_false - local keys = sortedkeys(t) - local function making(t,w) +local function make(t) + local function making(t) local p = p_false local keys = sortedkeys(t) + local okay = t[""] for i=1,#keys do local k = keys[i] - local v = t[k] - if w then + if k ~= "" then + local v = t[k] if v == true then p = p + P(k) * p_true + elseif v == false then + -- can't happen + elseif okay then + p = p + P(k) * (making(v) + p_true) else - p = p + P(k) * (making(v,w) + p_true) - end - else - if v == true then - p = p + P(k) - else - p = p + P(k) * making(v,w) + p = p + P(k) * making(v) end end end return p end + local p = p_false + local keys = sortedkeys(t) for i=1,#keys do local k = keys[i] - local v = t[k] - local h = hash[v] - if h then + if k ~= "" then + local v = t[k] if v == true then p = p + P(k) * p_true + elseif v == false then + -- can't happen + elseif v[""] then + p = p + P(k) * (making(v) + p_true) else - p = p + P(k) * (making(v,true) + p_true) - end - else - if v == true then - p = p + P(k) - else - p = p + P(k) * making(v,false) + p = p + P(k) * making(v) end end end @@ -1045,61 +881,99 @@ end function lpeg.utfchartabletopattern(list) -- goes to util-lpg local tree = { } --- local hash = { } - local hash local n = #list if n == 0 then - hash = list for s in next, list do local t = tree local p, pk for c in gmatch(s,".") do if t == true then - t = { [c] = true } + t = { [c] = true, [""] = true } + p[pk] = t + p = t + t = false + elseif t == false then + t = { [c] = false } p[pk] = t p = t - t = true + t = false else local tc = t[c] if not tc then - tc = true - t[c] = tc + tc = false + t[c] = false end p = t t = tc end pk = c end + if t == false then + p[pk] = true + elseif t == true then + -- okay + else + t[""] = true + end end else - hash = { } for i=1,n do - local t = tree local s = list[i] + local t = tree local p, pk for c in gmatch(s,".") do if t == true then - t = { [c] = true } + t = { [c] = true, [""] = true } p[pk] = t p = t - t = true + t = false + elseif t == false then + t = { [c] = false } + p[pk] = t + p = t + t = false else local tc = t[c] if not tc then - tc = true - t[c] = true + tc = false + t[c] = false end p = t t = tc end pk = c end - hash[s] = true + if t == false then + p[pk] = true + elseif t == true then + -- okay + else + t[""] = true + end end end - return make(tree,hash) +-- inspect(tree) + return make(tree) end +-- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef" } +-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) +-- +-- inspect(lpegmatch(p,"a")) +-- inspect(lpegmatch(p,"aaaa")) +-- inspect(lpegmatch(p,"ac")) +-- inspect(lpegmatch(p,"bc")) +-- inspect(lpegmatch(p,"zzbczz")) +-- inspect(lpegmatch(p,"zzabezz")) +-- inspect(lpegmatch(p,"ab")) +-- inspect(lpegmatch(p,"abc")) +-- inspect(lpegmatch(p,"abe")) +-- inspect(lpegmatch(p,"xa")) +-- inspect(lpegmatch(p,"bx")) +-- inspect(lpegmatch(p,"bax")) +-- inspect(lpegmatch(p,"abxyz")) +-- inspect(lpegmatch(p,"foobarbefcrap")) + -- lpeg.utfchartabletopattern { -- utfchar(0x00A0), -- nbsp -- utfchar(0x2000), -- enquad -- cgit v1.2.3 From d843b6cca2d31197c6d416293bce344c911fbbfb Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 13 Apr 2015 00:11:28 +0200 Subject: [fontloader] sync with Context as of 2015-04-13 --- src/fontloader/misc/fontloader-font-con.lua | 22 +++++++++++++++++++ src/fontloader/misc/fontloader-font-otf.lua | 33 +++++++++++++++++++---------- src/fontloader/misc/fontloader-l-lpeg.lua | 26 +++++++++++++++++------ 3 files changed, 63 insertions(+), 18 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-font-con.lua b/src/fontloader/misc/fontloader-font-con.lua index bb96912..72fbb5c 100644 --- a/src/fontloader/misc/fontloader-font-con.lua +++ b/src/fontloader/misc/fontloader-font-con.lua @@ -507,6 +507,7 @@ function constructors.scale(tfmdata,specification) local nonames = properties.noglyphnames local haskerns = properties.haskerns or properties.mode == "base" -- we can have afm in node mode local hasligatures = properties.hasligatures or properties.mode == "base" -- we can have afm in node mode + local realdimensions = properties.realdimensions -- if changed and not next(changed) then changed = false @@ -618,6 +619,27 @@ function constructors.scale(tfmdata,specification) local width = description.width local height = description.height local depth = description.depth + if realdimensions then + -- this is mostly for checking issues + if not height or height == 0 then + local bb = description.boundingbox + local ht = bb[4] + if ht ~= 0 then + height = ht + end + if not depth or depth == 0 then + local dp = -bb[2] + if dp ~= 0 then + depth = dp + end + end + elseif not depth or depth == 0 then + local dp = -description.boundingbox[2] + if dp ~= 0 then + depth = dp + end + end + end if width then width = hdelta*width else width = scaledwidth end if height then height = vdelta*height else height = scaledheight end -- if depth then depth = vdelta*depth else depth = scaleddepth end diff --git a/src/fontloader/misc/fontloader-font-otf.lua b/src/fontloader/misc/fontloader-font-otf.lua index c7e83a4..85eebaa 100644 --- a/src/fontloader/misc/fontloader-font-otf.lua +++ b/src/fontloader/misc/fontloader-font-otf.lua @@ -107,6 +107,7 @@ registerdirective("fonts.otf.loader.pack", function(v) packdata = registerdirective("fonts.otf.loader.syncspace", function(v) syncspace = v end) registerdirective("fonts.otf.loader.forcenotdef", function(v) forcenotdef = v end) registerdirective("fonts.otf.loader.overloadkerns", function(v) overloadkerns = v end) +-----------------("fonts.otf.loader.alldimensions", function(v) alldimensions = v end) function otf.fileformat(filename) local leader = lower(io.loadchunk(filename,4)) @@ -637,17 +638,27 @@ actions["add dimensions"] = function(data,filename) -- d.name = ".notdef" -- end if bb then - local ht, dp = bb[4], -bb[2] - if ht == 0 or ht < 0 then - -- not set - else - d.height = ht - end - if dp == 0 or dp < 0 then - -- not set - else - d.depth = dp - end + local ht = bb[4] + local dp = -bb[2] + -- if alldimensions then + -- if ht ~= 0 then + -- d.height = ht + -- end + -- if dp ~= 0 then + -- d.depth = dp + -- end + -- else + if ht == 0 or ht < 0 then + -- not set + else + d.height = ht + end + if dp == 0 or dp < 0 then + -- not set + else + d.depth = dp + end + -- end end end end diff --git a/src/fontloader/misc/fontloader-l-lpeg.lua b/src/fontloader/misc/fontloader-l-lpeg.lua index 9225b57..4aadadb 100644 --- a/src/fontloader/misc/fontloader-l-lpeg.lua +++ b/src/fontloader/misc/fontloader-l-lpeg.lua @@ -841,7 +841,7 @@ local function make(t) local function making(t) local p = p_false local keys = sortedkeys(t) - local okay = t[""] +-- local okay = t[""] for i=1,#keys do local k = keys[i] if k ~= "" then @@ -850,13 +850,16 @@ local function make(t) p = p + P(k) * p_true elseif v == false then -- can't happen - elseif okay then - p = p + P(k) * (making(v) + p_true) +-- elseif okay then +-- p = p + P(k) * (making(v) + p_true) else p = p + P(k) * making(v) end end end + if t[""] then + p = p + p_true + end return p end local p = p_false @@ -869,8 +872,8 @@ local function make(t) p = p + P(k) * p_true elseif v == false then -- can't happen - elseif v[""] then - p = p + P(k) * (making(v) + p_true) +-- elseif v[""] then +-- p = p + P(k) * (making(v) + p_true) else p = p + P(k) * making(v) end @@ -956,10 +959,11 @@ function lpeg.utfchartabletopattern(list) -- goes to util-lpg return make(tree) end --- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef" } +-- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef","aa" } -- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) --- + -- inspect(lpegmatch(p,"a")) +-- inspect(lpegmatch(p,"aa")) -- inspect(lpegmatch(p,"aaaa")) -- inspect(lpegmatch(p,"ac")) -- inspect(lpegmatch(p,"bc")) @@ -974,6 +978,14 @@ end -- inspect(lpegmatch(p,"abxyz")) -- inspect(lpegmatch(p,"foobarbefcrap")) +-- local t = { ["^"] = 1, ["^^"] = 2, ["^^^"] = 3, ["^^^^"] = 4 } +-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/t + 1)^1) +-- inspect(lpegmatch(p," ^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ ")) + +-- local t = { ["^^"] = 2, ["^^^"] = 3, ["^^^^"] = 4 } +-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/t + 1)^1) +-- inspect(lpegmatch(p," ^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ ")) + -- lpeg.utfchartabletopattern { -- utfchar(0x00A0), -- nbsp -- utfchar(0x2000), -- enquad -- cgit v1.2.3 From cf9acafee841175295d83b07d99420ac24b6e683 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 15 Apr 2015 08:16:50 +0200 Subject: [fontloader] sync with Context as of 2015-04-15 --- src/fontloader/misc/fontloader-fonts-otn.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-fonts-otn.lua b/src/fontloader/misc/fontloader-fonts-otn.lua index 3f53078..343e182 100644 --- a/src/fontloader/misc/fontloader-fonts-otn.lua +++ b/src/fontloader/misc/fontloader-fonts-otn.lua @@ -29,7 +29,6 @@ if not modules then modules = { } end modules ['font-otn'] = { -- todo: -- --- kerning is probably not yet ok for latin around dics nodes (interesting challenge) -- extension infrastructure (for usage out of context) -- sorting features according to vendors/renderers -- alternative loop quitters @@ -169,6 +168,7 @@ local report_chain = logs.reporter("fonts","otf chain") local report_process = logs.reporter("fonts","otf process") local report_prepare = logs.reporter("fonts","otf prepare") local report_warning = logs.reporter("fonts","otf warning") +local report_run = logs.reporter("fonts","otf run") registertracker("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end) registertracker("otf.normal_chain", function(v) otf.setcontextchain(v and "normal") end) @@ -197,12 +197,18 @@ local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar +local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local delete_node = nuts.delete +local remove_node = nuts.remove local copy_node = nuts.copy +local copy_node_list = nuts.copy_list local find_node_tail = nuts.tail local flush_node_list = nuts.flush_list +local free_node = nuts.free local end_of_math = nuts.end_of_math +local traverse_nodes = nuts.traverse +local traverse_id = nuts.traverse_id local setmetatableindex = table.setmetatableindex @@ -226,13 +232,15 @@ local dir_code = whatcodes.dir local localpar_code = whatcodes.localpar local discretionary_code = disccodes.discretionary +local regular_code = disccodes.regular +local automatic_code = disccodes.automatic local ligature_code = glyphcodes.ligature local privateattribute = attributes.private -- Something is messed up: we have two mark / ligature indices, one at the injection --- end and one here ... this is bases in KE's patches but there is something fishy +-- end and one here ... this is based on KE's patches but there is something fishy -- there as I'm pretty sure that for husayni we need some connection (as it's much -- more complex than an average font) but I need proper examples of all cases, not -- of only some. @@ -2627,6 +2635,7 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then if trace_steps then -- ? registerstep(head) end + end head = tonode(head) -- cgit v1.2.3 From da74e7f4d597b566ad99c995f2dd49fb41e218e0 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 20 Apr 2015 08:04:16 +0200 Subject: [fontloader] sync with Context as of 2015-04-20 --- src/fontloader/misc/fontloader-l-math.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-l-math.lua b/src/fontloader/misc/fontloader-l-math.lua index 43f60b5..ec62919 100644 --- a/src/fontloader/misc/fontloader-l-math.lua +++ b/src/fontloader/misc/fontloader-l-math.lua @@ -8,6 +8,10 @@ if not modules then modules = { } end modules ['l-math'] = { local floor, sin, cos, tan = math.floor, math.sin, math.cos, math.tan +if not math.ceiling then + math.ceiling = math.ceil +end + if not math.round then function math.round(x) return floor(x + 0.5) end end -- cgit v1.2.3 From 136826a4dc6e9505ed1ff1cfa6c862451a4a280a Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 3 May 2015 22:30:08 +0200 Subject: [fontloader] sync with Context as of 2015-05-03 --- src/fontloader/misc/fontloader-l-lpeg.lua | 40 ++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-l-lpeg.lua b/src/fontloader/misc/fontloader-l-lpeg.lua index 4aadadb..55a0d89 100644 --- a/src/fontloader/misc/fontloader-l-lpeg.lua +++ b/src/fontloader/misc/fontloader-l-lpeg.lua @@ -10,6 +10,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = { -- if i can use new features like capture / 2 and .B (at first sight the xml -- parser is some 5% slower) +-- lpeg.P("abc") is faster than lpeg.P("a") * lpeg.P("b") * lpeg.P("c") + -- a new lpeg fails on a #(1-P(":")) test and really needs a + P(-1) -- move utf -> l-unicode @@ -19,7 +21,7 @@ lpeg = require("lpeg") -- The latest lpeg doesn't have print any more, and even the new ones are not -- available by default (only when debug mode is enabled), which is a pitty as --- as it helps nailign down bottlenecks. Performance seems comparable: some 10% +-- as it helps nailing down bottlenecks. Performance seems comparable: some 10% -- slower pattern compilation, same parsing speed, although, -- -- local p = lpeg.C(lpeg.P(1)^0 * lpeg.P(-1)) @@ -841,7 +843,6 @@ local function make(t) local function making(t) local p = p_false local keys = sortedkeys(t) --- local okay = t[""] for i=1,#keys do local k = keys[i] if k ~= "" then @@ -850,8 +851,6 @@ local function make(t) p = p + P(k) * p_true elseif v == false then -- can't happen --- elseif okay then --- p = p + P(k) * (making(v) + p_true) else p = p + P(k) * making(v) end @@ -872,8 +871,6 @@ local function make(t) p = p + P(k) * p_true elseif v == false then -- can't happen --- elseif v[""] then --- p = p + P(k) * (making(v) + p_true) else p = p + P(k) * making(v) end @@ -882,6 +879,33 @@ local function make(t) return p end +local function collapse(t,x) + if type(t) ~= "table" then + return t, x + else + local n = next(t) + if n == nil then + return t, x + elseif next(t,n) == nil then + -- one entry + local k = n + local v = t[k] + if type(v) == "table" then + return collapse(v,x..k) + else + return v, x .. k + end + else + local tt = { } + for k, v in next, t do + local vv, kk = collapse(v,k) + tt[kk] = vv + end + return tt, x + end + end +end + function lpeg.utfchartabletopattern(list) -- goes to util-lpg local tree = { } local n = #list @@ -955,10 +979,14 @@ function lpeg.utfchartabletopattern(list) -- goes to util-lpg end end end +-- collapse(tree,"") -- needs testing, maybe optional, slightly faster because P("x")*P("X") seems slower than P"(xX") (why) -- inspect(tree) return make(tree) end +-- local t = { "start", "stoep", "staart", "paard" } +-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) + -- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef","aa" } -- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) -- cgit v1.2.3 From fe729cc9736391f61a75ccbee5c0fc162a2c99bd Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 4 May 2015 23:06:20 +0200 Subject: [fontloader] sync with Context as of 2015-05-04 --- src/fontloader/misc/fontloader-util-str.lua | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-util-str.lua b/src/fontloader/misc/fontloader-util-str.lua index a677a82..de4a87e 100644 --- a/src/fontloader/misc/fontloader-util-str.lua +++ b/src/fontloader/misc/fontloader-util-str.lua @@ -44,7 +44,12 @@ end if not number then number = { } end -- temp hack for luatex-fonts -local stripper = patterns.stripzeros +local stripper = patterns.stripzeros +local newline = patterns.newline +local endofstring = patterns.endofstring +local whitespace = patterns.whitespace +local spacer = patterns.spacer +local spaceortab = patterns.spaceortab local function points(n) n = tonumber(n) @@ -62,12 +67,12 @@ number.basepoints = basepoints -- str = " \n \ntest \n test\ntest " -- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]") -local rubish = patterns.spaceortab^0 * patterns.newline -local anyrubish = patterns.spaceortab + patterns.newline +local rubish = spaceortab^0 * newline +local anyrubish = spaceortab + newline local anything = patterns.anything -local stripped = (patterns.spaceortab^1 / "") * patterns.newline +local stripped = (spaceortab^1 / "") * newline local leading = rubish^0 / "" -local trailing = (anyrubish^1 * patterns.endofstring) / "" +local trailing = (anyrubish^1 * endofstring) / "" local redundant = rubish^3 / "\n" local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0) @@ -129,7 +134,7 @@ local pattern = return "" end end - + patterns.newline * Cp() / function(position) + + newline * Cp() / function(position) extra, start = 0, position end + patterns.anything @@ -162,11 +167,6 @@ end -- return str -- end -local newline = patterns.newline -local endofstring = patterns.endofstring -local whitespace = patterns.whitespace -local spacer = patterns.spacer - local space = spacer^0 local nospace = space/"" local endofline = nospace * newline @@ -1117,3 +1117,9 @@ local pattern = function string.optionalquoted(str) return lpegmatch(pattern,str) or str end + +local pattern = Cs((newline / os.newline + 1)^0) + +function string.replacenewlines(str) + return lpegmatch(pattern,str) +end -- cgit v1.2.3 From 43e07194f3d4d72b1eb2ebb6511209288664ca1a Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 12 May 2015 21:30:10 +0200 Subject: [fontloader] sync with Context as of 2015-05-12 --- src/fontloader/misc/fontloader-fonts-inj.lua | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-fonts-inj.lua b/src/fontloader/misc/fontloader-fonts-inj.lua index cb9ed89..332e920 100644 --- a/src/fontloader/misc/fontloader-fonts-inj.lua +++ b/src/fontloader/misc/fontloader-fonts-inj.lua @@ -647,10 +647,10 @@ local function inject_cursives(glyphs,nofglyphs) end end -local function inject_kerns(head,glyphs,nofglyphs) +local function inject_kerns(head,list,length) -- todo: pre/post/replace - for i=1,#glyphs do - local n = glyphs[i] + for i=1,length do + local n = list[i] local pn = rawget(properties,n) if pn then local i = rawget(pn,"injections") @@ -688,6 +688,9 @@ local function inject_everything(head,where) end inject_kerns(head,glyphs,nofglyphs) end + if nofmarks > 0 then + inject_kerns(head,marks,nofmarks) + end if keepregisteredcounts then keepregisteredcounts = false else @@ -998,7 +1001,7 @@ local function inject_pairs_only(head,where) if getsubtype(n) < 256 then local p = rawget(properties,n) if p then - local i = rawget(pn,"replaceinjections") + local i = rawget(p,"replaceinjections") if i then local yoffset = i.yoffset if yoffset and yoffset ~= 0 then -- cgit v1.2.3 From 7bad2f7429de8354f0105108ea495c0c6b85291b Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 26 May 2015 08:13:25 +0200 Subject: [fontloader] sync with Context as of 2015-05-26 --- src/fontloader/misc/fontloader-basics.tex | 70 ++++++ src/fontloader/misc/fontloader-font-map.lua | 53 +++++ src/fontloader/misc/fontloader-font-otf.lua | 343 ++++++++++++++++----------- src/fontloader/misc/fontloader-font-otp.lua | 2 + src/fontloader/misc/fontloader-fonts-cbk.lua | 42 ++++ src/fontloader/misc/fontloader-fonts-otn.lua | 20 +- src/fontloader/misc/fontloader-l-table.lua | 280 ++++++++++++++-------- src/fontloader/misc/fontloader-mplib.tex | 1 + src/fontloader/misc/fontloader-plain.tex | 1 + src/fontloader/misc/fontloader-util-str.lua | 2 +- 10 files changed, 560 insertions(+), 254 deletions(-) (limited to 'src/fontloader/misc') diff --git a/src/fontloader/misc/fontloader-basics.tex b/src/fontloader/misc/fontloader-basics.tex index abe4989..1180c68 100644 --- a/src/fontloader/misc/fontloader-basics.tex +++ b/src/fontloader/misc/fontloader-basics.tex @@ -20,4 +20,74 @@ {\global\advance\lastallocatedattribute 1 \attributedef#1\lastallocatedattribute} +% maybe we will have luatex-basics.lua some day for instance when more +% (pdf) primitives have moved to macros) + +\directlua { + + gadgets = gadgets or { } % reserved namespace + + gadgets.functions = { } + local registered = {} + + function gadgets.functions.reverve() + local numb = newtoken.scan_int() + local name = newtoken.scan_string() + local okay = string.gsub(name,"[\string\\ ]","") + registered[okay] = numb + texio.write_nl("reserving lua function '"..okay.."' with number "..numb) + end + + function gadgets.functions.register(name,f) + local okay = string.gsub(name,"[\string\\ ]","") + local numb = registered[okay] + if numb then + texio.write_nl("registering lua function '"..okay.."' with number "..numb) + lua.get_functions_table()[numb] = f + else + texio.write_nl("lua function '"..okay.."' is not reserved") + end + end + +} + +\newcount\lastallocatedluafunction + +\def\newluafunction#1% + {\ifdefined#1\else + \global\advance\lastallocatedluafunction 1 + \global\chardef#1\lastallocatedluafunction + \directlua{gadgets.functions.reserve()}#1{\detokenize{#1}}% + \fi} + +% an example of usage (if we ever support it it will go to the plain gadgets module): +% +% \directlua { +% +% local cct = nil +% local chr = nil +% +% gadgets.functions.register("UcharcatLuaOne",function() +% chr = newtoken.scan_int() +% cct = tex.getcatcode(chr) +% tex.setcatcode(chr,newtoken.scan_int()) +% tex.sprint(unicode.utf8.char(chr)) +% end) +% +% gadgets.functions.register("UcharcatLuaTwo",function() +% tex.setcatcode(chr,cct) +% end) +% +% } +% +% \def\Ucharcat +% {\expandafter\expandafter\expandafter\luafunction +% \expandafter\expandafter\expandafter\UcharcatLuaTwo +% \luafunction\UcharcatLuaOne} +% +% A:\the\catcode65:\Ucharcat 65 11:A:\the\catcode65\par +% A:\the\catcode65:\Ucharcat 65 5:A:\the\catcode65\par +% A:\the\catcode65:\Ucharcat 65 11:A:\the\catcode65\par + + \endinput diff --git a/src/fontloader/misc/fontloader-font-map.lua b/src/fontloader/misc/fontloader-font-map.lua index 449a00f..69474ba 100644 --- a/src/fontloader/misc/fontloader-font-map.lua +++ b/src/fontloader/misc/fontloader-font-map.lua @@ -313,6 +313,59 @@ function mappings.addtounicode(data,filename) -- The next time I look into this, I'll add an extra analysis step to the otf loader (we can -- resolve some tounicodes by looking into the gsub data tables that are bound to glyphs. -- +-- a real tricky last resort: +-- +-- local lookups = glyph.lookups +-- if lookups then +-- for _, lookup in next, lookups do -- assume consistency else we need to sort +-- for i=1,#lookup do +-- local l = lookup[i] +-- if l.type == "ligature" then +-- local s = l.specification +-- if s.char == glyph.name then +-- local components = s.components +-- if components then +-- local t, n = { }, 0 +-- unicode = true +-- for l=1,#components do +-- local base = components[l] +-- local u = unicodes[base] or unicodevector[base] +-- if not u then +-- break +-- elseif type(u) == "table" then +-- if u[1] >= private then +-- unicode = false +-- break +-- end +-- n = n + 1 +-- t[n] = u[1] +-- else +-- if u >= private then +-- unicode = false +-- break +-- end +-- n = n + 1 +-- t[n] = u +-- end +-- end +-- if n == 0 then -- done then +-- -- nothing +-- elseif n == 1 then +-- glyph.unicode = t[1] +-- else +-- glyph.unicode = t +-- end +-- nl = nl + 1 +-- break +-- end +-- end +-- end +-- end +-- if unicode then +-- break +-- end +-- end +-- end if not unicode or unicode == "" then local split = lpegmatch(namesplitter,name) local nsplit = split and #split or 0 diff --git a/src/fontloader/misc/fontloader-font-otf.lua b/src/fontloader/misc/fontloader-font-otf.lua index 85eebaa..e7a97c6 100644 --- a/src/fontloader/misc/fontloader-font-otf.lua +++ b/src/fontloader/misc/fontloader-font-otf.lua @@ -36,6 +36,7 @@ local elapsedtime = statistics.elapsedtime local findbinfile = resolvers.findbinfile local trace_private = false registertracker("otf.private", function(v) trace_private = v end) +local trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) local trace_features = false registertracker("otf.features", function(v) trace_features = v end) local trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) @@ -53,7 +54,7 @@ local otf = fonts.handlers.otf otf.glists = { "gsub", "gpos" } -otf.version = 2.803 -- beware: also sync font-mis.lua +otf.version = 2.812 -- beware: also sync font-mis.lua otf.cache = containers.define("fonts", "otf", otf.version, true) local hashes = fonts.hashes @@ -699,6 +700,7 @@ end -- not setting hasitalics and class (when nil) during table cronstruction can save some mem actions["prepare glyphs"] = function(data,filename,raw) + local tableversion = tonumber(raw.table_version) or 0 local rawglyphs = raw.glyphs local rawsubfonts = raw.subfonts local rawcidinfo = raw.cidinfo @@ -722,81 +724,139 @@ actions["prepare glyphs"] = function(data,filename,raw) local cidmap = fonts.cid.getmap(rawcidinfo) if cidmap then rawcidinfo.usedname = cidmap.usedname - local nofnames, nofunicodes = 0, 0 - local cidunicodes, cidnames = cidmap.unicodes, cidmap.names + local nofnames = 0 + local nofunicodes = 0 + local cidunicodes = cidmap.unicodes + local cidnames = cidmap.names + local cidtotal = 0 + local unique = trace_subfonts and { } for cidindex=1,#rawsubfonts do local subfont = rawsubfonts[cidindex] local cidglyphs = subfont.glyphs if includesubfonts then metadata.subfonts[cidindex] = somecopy(subfont) end - -- we have delayed loading so we cannot use next - for index=0,subfont.glyphcnt-1 do -- we could take the previous glyphcnt instead of 0 - local glyph = cidglyphs[index] - if glyph then - local unicode = glyph.unicode - if unicode >= 0x00E000 and unicode <= 0x00F8FF then - unicode = -1 - elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFD then - unicode = -1 - elseif unicode >= 0x100000 and unicode <= 0x10FFFD then - unicode = -1 - end - local name = glyph.name or cidnames[index] - if not unicode or unicode == -1 then -- or unicode >= criterium then - unicode = cidunicodes[index] - end - if unicode and descriptions[unicode] then - if trace_private then - report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) + local cidcnt, cidmin, cidmax + if tableversion > 0.3 then + -- we have delayed loading so we cannot use next + cidcnt = subfont.glyphcnt + cidmin = subfont.glyphmin + cidmax = subfont.glyphmax + else + cidcnt = subfont.glyphcnt + cidmin = 0 + cidmax = cidcnt - 1 + end + if trace_subfonts then + local cidtot = cidmax - cidmin + 1 + cidtotal = cidtotal + cidtot + report_otf("subfont: %i, min: %i, max: %i, cnt: %i, n: %i",cidindex,cidmin,cidmax,cidtot,cidcnt) + end + if cidcnt > 0 then + for cidslot=cidmin,cidmax do + local glyph = cidglyphs[cidslot] + if glyph then + local index = tableversion > 0.3 and glyph.orig_pos or cidslot + if trace_subfonts then + unique[index] = true end - unicode = -1 - end - if not unicode or unicode == -1 then -- or unicode >= criterium then - if not name then - name = format("u%06X.ctx",private) + local unicode = glyph.unicode + if unicode >= 0x00E000 and unicode <= 0x00F8FF then + unicode = -1 + elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFD then + unicode = -1 + elseif unicode >= 0x100000 and unicode <= 0x10FFFD then + unicode = -1 end - unicode = private - unicodes[name] = private - if trace_private then - report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) + local name = glyph.name or cidnames[index] + if not unicode or unicode == -1 then -- or unicode >= criterium then + unicode = cidunicodes[index] end - private = private + 1 - nofnames = nofnames + 1 - else - -- if unicode > criterium then - -- local taken = descriptions[unicode] - -- if taken then - -- private = private + 1 - -- descriptions[private] = taken - -- unicodes[taken.name] = private - -- indices[taken.index] = private - -- if trace_private then - -- report_otf("slot %U is moved to %U due to private in font",unicode) - -- end - -- end - -- end - if not name then - name = format("u%06X.ctx",unicode) + if unicode and descriptions[unicode] then + if trace_private then + report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) + end + unicode = -1 + end + if not unicode or unicode == -1 then -- or unicode >= criterium then + if not name then + name = format("u%06X.ctx",private) + end + unicode = private + unicodes[name] = private + if trace_private then + report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) + end + private = private + 1 + nofnames = nofnames + 1 + else + -- if unicode > criterium then + -- local taken = descriptions[unicode] + -- if taken then + -- private = private + 1 + -- descriptions[private] = taken + -- unicodes[taken.name] = private + -- indices[taken.index] = private + -- if trace_private then + -- report_otf("slot %U is moved to %U due to private in font",unicode) + -- end + -- end + -- end + if not name then + name = format("u%06X.ctx",unicode) + end + unicodes[name] = unicode + nofunicodes = nofunicodes + 1 end - unicodes[name] = unicode - nofunicodes = nofunicodes + 1 + indices[index] = unicode -- each index is unique (at least now) + local description = { + -- width = glyph.width, + boundingbox = glyph.boundingbox, + -- name = glyph.name or name or "unknown", -- uniXXXX + name = name or "unknown", -- uniXXXX + cidindex = cidindex, + index = cidslot, + glyph = glyph, + } + descriptions[unicode] = description +local altuni = glyph.altuni +if altuni then + -- local d + for i=1,#altuni do + local a = altuni[i] + local u = a.unicode + if u ~= unicode then + local v = a.variant + if v then + -- tricky: no addition to d? needs checking but in practice such dups are either very simple + -- shapes or e.g cjk with not that many features + local vv = variants[v] + if vv then + vv[u] = unicode + else -- xits-math has some: + vv = { [u] = unicode } + variants[v] = vv + end + -- elseif d then + -- d[#d+1] = u + -- else + -- d = { u } + end + end + end + -- if d then + -- duplicates[unicode] = d -- is this needed ? + -- end +end end - indices[index] = unicode -- each index is unique (at least now) - local description = { - -- width = glyph.width, - boundingbox = glyph.boundingbox, - name = glyph.name or name or "unknown", -- uniXXXX - cidindex = cidindex, - index = index, - glyph = glyph, - } - descriptions[unicode] = description - else - -- report_otf("potential problem: glyph %U is used but empty",index) end + else + report_otf("potential problem: no glyphs found in subfont %i",cidindex) end end + if trace_subfonts then + report_otf("nofglyphs: %i, unique: %i",cidtotal,table.count(unique)) + end if trace_loading then report_otf("cid font remapped, %s unicode points, %s symbolic names, %s glyphs",nofunicodes, nofnames, nofunicodes+nofnames) end @@ -809,87 +869,97 @@ actions["prepare glyphs"] = function(data,filename,raw) else - for index=0,raw.glyphcnt-1 do -- not raw.glyphmax-1 (as that will crash) - local glyph = rawglyphs[index] - if glyph then - local unicode = glyph.unicode - local name = glyph.name - if not unicode or unicode == -1 then -- or unicode >= criterium then - unicode = private - unicodes[name] = private - if trace_private then - report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) - end - private = private + 1 - else - -- We have a font that uses and exposes the private area. As this is rather unreliable it's - -- advised no to trust slots here (better use glyphnames). Anyway, we need a double check: - -- we need to move already moved entries and we also need to bump the next private to after - -- the (currently) last slot. This could leave us with a hole but we have holes anyway. - if unicode > criterium then - -- \definedfont[file:HANBatang-LVT.ttf] \fontchar{uF0135} \char"F0135 - local taken = descriptions[unicode] - if taken then - if unicode >= private then - private = unicode + 1 -- restart private (so we can have mixed now) + local cnt = raw.glyphcnt or 0 + local min = tableversion > 0.3 and raw.glyphmin or 0 + local max = tableversion > 0.3 and raw.glyphmax or (raw.glyphcnt - 1) + if cnt > 0 then +-- for index=0,cnt-1 do + for index=min,max do + local glyph = rawglyphs[index] + if glyph then + local unicode = glyph.unicode + local name = glyph.name + if not unicode or unicode == -1 then -- or unicode >= criterium then + unicode = private + unicodes[name] = private + if trace_private then + report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) + end + private = private + 1 + else + -- We have a font that uses and exposes the private area. As this is rather unreliable it's + -- advised no to trust slots here (better use glyphnames). Anyway, we need a double check: + -- we need to move already moved entries and we also need to bump the next private to after + -- the (currently) last slot. This could leave us with a hole but we have holes anyway. + if unicode > criterium then + -- \definedfont[file:HANBatang-LVT.ttf] \fontchar{uF0135} \char"F0135 + local taken = descriptions[unicode] + if taken then + if unicode >= private then + private = unicode + 1 -- restart private (so we can have mixed now) + else + private = private + 1 -- move on + end + descriptions[private] = taken + unicodes[taken.name] = private + indices[taken.index] = private + if trace_private then + report_otf("slot %U is moved to %U due to private in font",unicode) + end else - private = private + 1 -- move on - end - descriptions[private] = taken - unicodes[taken.name] = private - indices[taken.index] = private - if trace_private then - report_otf("slot %U is moved to %U due to private in font",unicode) - end - else - if unicode >= private then - private = unicode + 1 -- restart (so we can have mixed now) + if unicode >= private then + private = unicode + 1 -- restart (so we can have mixed now) + end end end + unicodes[name] = unicode end - unicodes[name] = unicode - end - indices[index] = unicode - -- if not name then - -- name = format("u%06X",unicode) -- u%06X.ctx - -- end - descriptions[unicode] = { - -- width = glyph.width, - boundingbox = glyph.boundingbox, - name = name, - index = index, - glyph = glyph, - } - local altuni = glyph.altuni - if altuni then - -- local d - for i=1,#altuni do - local a = altuni[i] - local u = a.unicode - local v = a.variant - if v then - -- tricky: no addition to d? needs checking but in practice such dups are either very simple - -- shapes or e.g cjk with not that many features - local vv = variants[v] - if vv then - vv[u] = unicode - else -- xits-math has some: - vv = { [u] = unicode } - variants[v] = vv + indices[index] = unicode + -- if not name then + -- name = format("u%06X",unicode) -- u%06X.ctx + -- end + descriptions[unicode] = { + -- width = glyph.width, + boundingbox = glyph.boundingbox, + name = name, + index = index, + glyph = glyph, + } + local altuni = glyph.altuni + if altuni then + -- local d + for i=1,#altuni do + local a = altuni[i] + local u = a.unicode + if u ~= unicode then + local v = a.variant + if v then + -- tricky: no addition to d? needs checking but in practice such dups are either very simple + -- shapes or e.g cjk with not that many features + local vv = variants[v] + if vv then + vv[u] = unicode + else -- xits-math has some: + vv = { [u] = unicode } + variants[v] = vv + end + -- elseif d then + -- d[#d+1] = u + -- else + -- d = { u } + end end - -- elseif d then - -- d[#d+1] = u - -- else - -- d = { u } end + -- if d then + -- duplicates[unicode] = d -- is this needed ? + -- end end - -- if d then - -- duplicates[unicode] = d -- is this needed ? - -- end + else + report_otf("potential problem: glyph %U is used but empty",index) end - else - report_otf("potential problem: glyph %U is used but empty",index) end + else + report_otf("potential problem: no glyphs found") end end @@ -974,8 +1044,8 @@ actions["check encoding"] = function(data,filename,raw) end if mapdata then - mapdata.map = { } -- clear some memory - mapdata.backmap = { } -- clear some memory + mapdata.map = { } -- clear some memory (virtual and created each time anyway) + mapdata.backmap = { } -- clear some memory (virtual and created each time anyway) end end @@ -991,7 +1061,6 @@ actions["add duplicates"] = function(data,filename,raw) local unicodes = resources.unicodes -- name to unicode local indices = resources.indices -- index to unicodes local duplicates = resources.duplicates - for unicode, d in next, duplicates do local nofduplicates = #d if nofduplicates > 4 then diff --git a/src/fontloader/misc/fontloader-font-otp.lua b/src/fontloader/misc/fontloader-font-otp.lua index 63e4184..ebf36ed 100644 --- a/src/fontloader/misc/fontloader-font-otp.lua +++ b/src/fontloader/misc/fontloader-font-otp.lua @@ -9,6 +9,8 @@ if not modules then modules = { } end modules ['font-otp'] = { -- todo: pack math (but not that much to share) -- -- pitfall 5.2: hashed tables can suddenly become indexed with nil slots +-- +-- unless we sort all hashes we can get a different pack order (no big deal but size can differ) local next, type = next, type local sort, concat = table.sort, table.concat diff --git a/src/fontloader/misc/fontloader-fonts-cbk.lua b/src/fontloader/misc/fontloader-fonts-cbk.lua index ce19c88..81b5b6e 100644 --- a/src/fontloader/misc/fontloader-fonts-cbk.lua +++ b/src/fontloader/misc/fontloader-fonts-cbk.lua @@ -17,6 +17,9 @@ local nodes = nodes -- Fonts: (might move to node-gef.lua) local traverse_id = node.traverse_id +local free_node = node.free +local remove_node = node.remove + local glyph_code = nodes.nodecodes.glyph local disc_code = nodes.nodecodes.disc @@ -57,6 +60,8 @@ function nodes.handlers.nodepass(head) local basefonts = { } local prevfont = nil local basefont = nil + local variants = nil + local redundant = nil for n in traverse_id(glyph_code,head) do local font = n.font if font ~= prevfont then @@ -78,9 +83,46 @@ function nodes.handlers.nodepass(head) basefonts[#basefonts+1] = basefont end end + local resources = tfmdata.resources + variants = resources and resources.variants + variants = variants and next(variants) and variants or false + end + else + local tfmdata = fontdata[prevfont] + if tfmdata then + local resources = tfmdata.resources + variants = resources and resources.variants + variants = variants and next(variants) and variants or false end end end + if variants then + local char = n.char + if char >= 0xFE00 and (char <= 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF)) then + local hash = variants[char] + if hash then + local p = n.prev + if p and p.id == glyph_code then + local variant = hash[p.char] + if variant then + p.char = variant + if not redundant then + redundant = { n } + else + redundant[#redundant+1] = n + end + end + end + end + end + end + end + if redundant then + for i=1,#redundant do + local n = redundant[i] + remove_node(head,n) + free_node(n) + end end for d in traverse_id(disc_code,head) do local r = d.replace diff --git a/src/fontloader/misc/fontloader-fonts-otn.lua b/src/fontloader/misc/fontloader-fonts-otn.lua index 343e182..dd3aa61 100644 --- a/src/fontloader/misc/fontloader-fonts-otn.lua +++ b/src/fontloader/misc/fontloader-fonts-otn.lua @@ -376,7 +376,7 @@ local function copy_glyph(g) -- next and prev are untouched ! end end --- +-- -- start is a mark and we need to keep that one @@ -1834,15 +1834,8 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq break end end - elseif f == 2 then - match = seq[1][32] else - for n=f-1,1 do - if not seq[n][32] then - match = false - break - end - end + match = false end end -- after @@ -1895,15 +1888,8 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq break end end - elseif s-l == 1 then - match = seq[s][32] else - for n=l+1,s do - if not seq[n][32] then - match = false - break - end - end + match = false end end end diff --git a/src/fontloader/misc/fontloader-l-table.lua b/src/fontloader/misc/fontloader-l-table.lua index 97e0441..b02f210 100644 --- a/src/fontloader/misc/fontloader-l-table.lua +++ b/src/fontloader/misc/fontloader-l-table.lua @@ -39,7 +39,7 @@ end function table.keys(t) if t then local keys, k = { }, 0 - for key, _ in next, t do + for key in next, t do k = k + 1 keys[k] = key end @@ -50,44 +50,126 @@ function table.keys(t) end -- local function compare(a,b) --- local ta, tb = type(a), type(b) -- needed, else 11 < 2 --- if ta == tb then +-- local ta = type(a) -- needed, else 11 < 2 +-- local tb = type(b) -- needed, else 11 < 2 +-- if ta == tb and ta == "number" then -- return a < b -- else -- return tostring(a) < tostring(b) -- not that efficient -- end -- end +-- local function compare(a,b) +-- local ta = type(a) -- needed, else 11 < 2 +-- local tb = type(b) -- needed, else 11 < 2 +-- if ta == tb and (ta == "number" or ta == "string") then +-- return a < b +-- else +-- return tostring(a) < tostring(b) -- not that efficient +-- end +-- end + +-- local function sortedkeys(tab) +-- if tab then +-- local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed +-- for key in next, tab do +-- s = s + 1 +-- srt[s] = key +-- if category == 3 then +-- -- no further check +-- else +-- local tkey = type(key) +-- if tkey == "string" then +-- category = (category == 2 and 3) or 1 +-- elseif tkey == "number" then +-- category = (category == 1 and 3) or 2 +-- else +-- category = 3 +-- end +-- end +-- end +-- if category == 0 or category == 3 then +-- sort(srt,compare) +-- else +-- sort(srt) +-- end +-- return srt +-- else +-- return { } +-- end +-- end + +-- local function compare(a,b) +-- local ta = type(a) -- needed, else 11 < 2 +-- local tb = type(b) -- needed, else 11 < 2 +-- if ta == tb and (ta == "number" or ta == "string") then +-- return a < b +-- else +-- return tostring(a) < tostring(b) -- not that efficient +-- end +-- end + +-- local function compare(a,b) +-- local ta = type(a) -- needed, else 11 < 2 +-- if ta == "number" or ta == "string" then +-- local tb = type(b) -- needed, else 11 < 2 +-- if ta == tb then +-- return a < b +-- end +-- end +-- return tostring(a) < tostring(b) -- not that efficient +-- end + local function compare(a,b) local ta = type(a) -- needed, else 11 < 2 - local tb = type(b) -- needed, else 11 < 2 - if ta == tb and ta == "number" then - return a < b - else - return tostring(a) < tostring(b) -- not that efficient + if ta == "number" then + local tb = type(b) -- needed, else 11 < 2 + if ta == tb then + return a < b + elseif tb == "string" then + return tostring(a) < b + end + elseif ta == "string" then + local tb = type(b) -- needed, else 11 < 2 + if ta == tb then + return a < b + else + return a < tostring(b) + end end + return tostring(a) < tostring(b) -- not that efficient end local function sortedkeys(tab) if tab then local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed - for key,_ in next, tab do + for key in next, tab do s = s + 1 srt[s] = key if category == 3 then -- no further check + elseif category == 1 then + if type(key) ~= "string" then + category = 3 + end + elseif category == 2 then + if type(key) ~= "number" then + category = 3 + end else local tkey = type(key) if tkey == "string" then - category = (category == 2 and 3) or 1 + category = 1 elseif tkey == "number" then - category = (category == 1 and 3) or 2 + category = 2 else category = 3 end end end - if category == 0 or category == 3 then + if s < 2 then + -- nothing to sort + elseif category == 3 then sort(srt,compare) else sort(srt) @@ -101,13 +183,15 @@ end local function sortedhashonly(tab) if tab then local srt, s = { }, 0 - for key,_ in next, tab do + for key in next, tab do if type(key) == "string" then s = s + 1 srt[s] = key end end - sort(srt) + if s > 1 then + sort(srt) + end return srt else return { } @@ -117,13 +201,15 @@ end local function sortedindexonly(tab) if tab then local srt, s = { }, 0 - for key,_ in next, tab do + for key in next, tab do if type(key) == "number" then s = s + 1 srt[s] = key end end - sort(srt) + if s > 1 then + sort(srt) + end return srt else return { } @@ -133,13 +219,15 @@ end local function sortedhashkeys(tab,cmp) -- fast one if tab then local srt, s = { }, 0 - for key,_ in next, tab do + for key in next, tab do if key then s= s + 1 srt[s] = key end end - sort(srt,cmp) + if s > 1 then + sort(srt,cmp) + end return srt else return { } @@ -149,7 +237,7 @@ end function table.allkeys(t) local keys = { } for k, v in next, t do - for k, v in next, v do + for k in next, v do keys[k] = true end end @@ -172,19 +260,21 @@ local function sortedhash(t,cmp) else s = sortedkeys(t) -- the robust one end - local n = 0 local m = #s - local function kv() -- (s) - if n < m then - n = n + 1 - local k = s[n] - return k, t[k] + if m == 1 then + return next, t + elseif m > 0 then + local n = 0 + return function() + if n < m then + n = n + 1 + local k = s[n] + return k, t[k] + end end end - return kv -- , s - else - return nothing end + return nothing end table.sortedhash = sortedhash @@ -328,7 +418,7 @@ end local function copy(t, tables) -- taken from lua wiki, slightly adapted tables = tables or { } - local tcopy = {} + local tcopy = { } if not tables[t] then tables[t] = tcopy end @@ -388,7 +478,7 @@ function table.fromhash(t) return hsh end -local noquotes, hexify, handle, reduce, compact, inline, functions +local noquotes, hexify, handle, compact, inline, functions local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if', @@ -396,33 +486,67 @@ local reserved = table.tohash { -- intercept a language inconvenience: no reserv 'NaN', 'goto', } +-- local function simple_table(t) +-- if #t > 0 then +-- local n = 0 +-- for _,v in next, t do +-- n = n + 1 +-- end +-- if n == #t then +-- local tt, nt = { }, 0 +-- for i=1,#t do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "number" then +-- nt = nt + 1 +-- if hexify then +-- tt[nt] = format("0x%X",v) +-- else +-- tt[nt] = tostring(v) -- tostring not needed +-- end +-- elseif tv == "string" then +-- nt = nt + 1 +-- tt[nt] = format("%q",v) +-- elseif tv == "boolean" then +-- nt = nt + 1 +-- tt[nt] = v and "true" or "false" +-- else +-- return nil +-- end +-- end +-- return tt +-- end +-- end +-- return nil +-- end + local function simple_table(t) - if #t > 0 then + local nt = #t + if nt > 0 then local n = 0 for _,v in next, t do n = n + 1 + -- if type(v) == "table" then + -- return nil + -- end end - if n == #t then - local tt, nt = { }, 0 - for i=1,#t do + if n == nt then + local tt = { } + for i=1,nt do local v = t[i] local tv = type(v) if tv == "number" then - nt = nt + 1 if hexify then - tt[nt] = format("0x%X",v) + tt[i] = format("0x%X",v) else - tt[nt] = tostring(v) -- tostring not needed + tt[i] = tostring(v) -- tostring not needed end elseif tv == "string" then - nt = nt + 1 - tt[nt] = format("%q",v) + tt[i] = format("%q",v) elseif tv == "boolean" then - nt = nt + 1 - tt[nt] = v and "true" or "false" + tt[i] = v and "true" or "false" else - tt = nil - break + return nil end end return tt @@ -480,14 +604,6 @@ local function do_serialize(root,name,depth,level,indexed) end -- we could check for k (index) being number (cardinal) if root and next(root) ~= nil then - -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone) - -- if compact then - -- -- NOT: for k=1,#root do (we need to quit at nil) - -- for k,v in ipairs(root) do -- can we use next? - -- if not first then first = k end - -- last = last + 1 - -- end - -- end local first, last = nil, 0 if compact then last = #root @@ -503,12 +619,10 @@ local function do_serialize(root,name,depth,level,indexed) end local sk = sortedkeys(root) for i=1,#sk do - local k = sk[i] - local v = root[k] - --~ if v == root then - -- circular - --~ else - local tv, tk = type(v), type(k) + local k = sk[i] + local v = root[k] + local tv = type(v) + local tk = type(k) if compact and first and tk == "number" and k >= first and k <= last then if tv == "number" then if hexify then @@ -517,11 +631,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s %s,",depth,v)) -- %.99g end elseif tv == "string" then - if reduce and tonumber(v) then - handle(format("%s %s,",depth,v)) - else - handle(format("%s %q,",depth,v)) - end + handle(format("%s %q,",depth,v)) elseif tv == "table" then if next(v) == nil then handle(format("%s {},",depth)) @@ -577,34 +687,18 @@ local function do_serialize(root,name,depth,level,indexed) end end elseif tv == "string" then - if reduce and tonumber(v) then - if tk == "number" then - if hexify then - handle(format("%s [0x%X]=%s,",depth,k,v)) - else - handle(format("%s [%s]=%s,",depth,k,v)) - end - elseif tk == "boolean" then - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%s,",depth,k,v)) + if tk == "number" then + if hexify then + handle(format("%s [0x%X]=%q,",depth,k,v)) else - handle(format("%s [%q]=%s,",depth,k,v)) + handle(format("%s [%s]=%q,",depth,k,v)) end + elseif tk == "boolean" then + handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s=%q,",depth,k,v)) else - if tk == "number" then - if hexify then - handle(format("%s [0x%X]=%q,",depth,k,v)) - else - handle(format("%s [%s]=%q,",depth,k,v)) - end - elseif tk == "boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%q,",depth,k,v)) - else - handle(format("%s [%q]=%q,",depth,k,v)) - end + handle(format("%s [%q]=%q,",depth,k,v)) end elseif tv == "table" then if next(v) == nil then @@ -690,7 +784,6 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%q]=%q,",depth,k,tostring(v))) end end - --~ end end end if level > 0 then @@ -707,7 +800,6 @@ local function serialize(_handle,root,name,specification) -- handle wins noquotes = specification.noquotes hexify = specification.hexify handle = _handle or specification.handle or print - reduce = specification.reduce or false functions = specification.functions compact = specification.compact inline = specification.inline and compact @@ -724,7 +816,6 @@ local function serialize(_handle,root,name,specification) -- handle wins noquotes = false hexify = false handle = _handle or print - reduce = false compact = true inline = true functions = true @@ -798,15 +889,6 @@ end table.tohandle = serialize --- sometimes tables are real use (zapfino extra pro is some 85M) in which --- case a stepwise serialization is nice; actually, we could consider: --- --- for line in table.serializer(root,name,reduce,noquotes) do --- ...(line) --- end --- --- so this is on the todo list - local maxtab = 2*1024 function table.tofile(filename,root,name,specification) diff --git a/src/fontloader/misc/fontloader-mplib.tex b/src/fontloader/misc/fontloader-mplib.tex index 8af9f2d..09dd179 100644 --- a/src/fontloader/misc/fontloader-mplib.tex +++ b/src/fontloader/misc/fontloader-mplib.tex @@ -61,6 +61,7 @@ %D Now load the needed \LUA\ code. \directlua{dofile(kpse.find_file('luatex-mplib.lua'))} +% \directlua{dofile(resolvers.findfile('luatex-mplib.lua'))} %D The following code takes care of encapsulating the literals: diff --git a/src/fontloader/misc/fontloader-plain.tex b/src/fontloader/misc/fontloader-plain.tex index 1ea8558..c9a9e36 100644 --- a/src/fontloader/misc/fontloader-plain.tex +++ b/src/fontloader/misc/fontloader-plain.tex @@ -20,6 +20,7 @@ \input {luatex-math}% \input {luatex-languages}% \input {luatex-mplib}% + % \input {luatex-gadgets}% } \edef\fmtversion{\fmtversion+luatex} diff --git a/src/fontloader/misc/fontloader-util-str.lua b/src/fontloader/misc/fontloader-util-str.lua index de4a87e..c2139b1 100644 --- a/src/fontloader/misc/fontloader-util-str.lua +++ b/src/fontloader/misc/fontloader-util-str.lua @@ -1118,7 +1118,7 @@ function string.optionalquoted(str) return lpegmatch(pattern,str) or str end -local pattern = Cs((newline / os.newline + 1)^0) +local pattern = Cs((newline / (os.newline or "\r") + 1)^0) function string.replacenewlines(str) return lpegmatch(pattern,str) -- cgit v1.2.3