From c6ae1bb6230894346094364eb08d3aca0efdea9a Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 2 Jul 2021 14:01:19 +0200 Subject: 2021-07-02 13:18:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-mis.lua | 2 +- tex/context/base/mkiv/font-otl.lua | 15 +- tex/context/base/mkiv/font-oup.lua | 71 +++--- tex/context/base/mkiv/font-shp.lua | 2 +- tex/context/base/mkiv/font-ttf.lua | 258 +++++++++++-------- tex/context/base/mkiv/mult-fun.lua | 2 +- tex/context/base/mkiv/status-files.pdf | Bin 23614 -> 23607 bytes tex/context/base/mkiv/status-lua.pdf | Bin 248360 -> 248393 bytes tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 2 +- tex/context/base/mkxl/font-fil.mklx | 2 +- tex/context/base/mkxl/lang-dis.lmt | 22 ++ tex/context/base/mkxl/luat-ini.mkxl | 28 ++- tex/context/base/mkxl/mlib-lmt.lmt | 56 ++--- tex/context/base/mkxl/mlib-scn.lmt | 207 ++++++++------- tex/context/base/mkxl/page-cst.mkxl | 1 - tex/context/base/mkxl/page-mcl.mkxl | 3 +- tex/context/base/mkxl/page-sid.mkxl | 8 +- tex/context/modules/mkiv/s-fonts-variable.lua | 10 +- tex/context/modules/mkiv/s-fonts-variable.mkiv | 40 +-- tex/generic/context/luatex/luatex-fonts-merged.lua | 277 +++++++++++++-------- 25 files changed, 603 insertions(+), 413 deletions(-) (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 4f89d4da4..e5b37429a 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2021.06.30 19:17} +\newcontextversion{2021.07.02 13:15} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 4f837ca24..6be166bff 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2021.06.30 19:17} +\edef\contextversion{2021.07.02 13:15} %D For those who want to use this: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 2ac550b26..d044a93b6 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.06.30 19:17} +\newcontextversion{2021.07.02 13:15} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index cd6c8d866..d543d7a37 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2021.06.30 19:17} +\edef\contextversion{2021.07.02 13:15} %D Kind of special: diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua index 1748640d2..a72f1bf42 100644 --- a/tex/context/base/mkiv/font-mis.lua +++ b/tex/context/base/mkiv/font-mis.lua @@ -21,7 +21,7 @@ local readers = otf.readers if readers then - otf.version = otf.version or 3.117 + otf.version = otf.version or 3.118 otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true) function fonts.helpers.getfeatures(name,save) diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index eadf05890..74f209b0a 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.117 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.118 -- beware: also sync font-mis.lua and in mtx-fonts otf.cache = containers.define("fonts", "otl", otf.version, true) otf.svgcache = containers.define("fonts", "svg", otf.version, true) otf.pngcache = containers.define("fonts", "png", otf.version, true) @@ -512,10 +512,15 @@ elseif CONTEXTLMTXMODE then local maxindex = data.nofglyphs or metadata.nofglyphs if maxindex then for u, d in sortedhash(duplicates) do - for uu in sortedhash(d) do - maxindex = maxindex + 1 - descriptions[uu].dupindex = descriptions[u].index - descriptions[uu].index = maxindex + local du = descriptions[u] + if du then + for uu in sortedhash(d) do + maxindex = maxindex + 1 + descriptions[uu].dupindex = du.index + descriptions[uu].index = maxindex + end + else + -- report_otf("no %U in font %a, duplicates ignored",u,filename) end end end diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua index 6733b6efb..4e70bf936 100644 --- a/tex/context/base/mkiv/font-oup.lua +++ b/tex/context/base/mkiv/font-oup.lua @@ -37,16 +37,12 @@ local f_index = formatters["I%05X"] local f_character_y = formatters["%C"] local f_character_n = formatters["[ %C ]"] -local check_duplicates = true -- can become an option (pseudo feature) / always needed anyway -local check_soft_hyphen = true -- can become an option (pseudo feature) / needed for tagging +local check_duplicates = true -- can become an option (pseudo feature) / always needed anyway +local check_soft_hyphen = context -- only in context --- if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then --- check_soft_hyphen = false -- solved better elsewhere --- else --- directives.register("otf.checksofthyphen",function(v) --- check_soft_hyphen = v --- end) --- end +directives.register("otf.checksofthyphen",function(v) + check_soft_hyphen = v -- only for testing +end) local function replaced(list,index,replacement) if type(list) == "number" then @@ -457,31 +453,48 @@ local function copyduplicates(fontdata) local resources = fontdata.resources local duplicates = resources.duplicates if check_soft_hyphen then - -- ebgaramond has a zero width empty soft hyphen - -- antykwatorunska lacks a soft hyphen - local ds = descriptions[0xAD] - if not ds or ds.width == 0 then - if ds then + -- ebgaramond has a zero width empty soft hyphen + -- antykwatorunska lacks a soft hyphen + -- lucidaot has a halfwidth soft hyphen + + -- local dh = descriptions[0x2D] + -- if dh then + -- descriptions[0xAD] = nil + -- local d = duplicates[0x2D] + -- if d then + -- d[#d+1] = { [0xAD] = true } + -- else + -- duplicates[0x2D] = { [0xAD] = true } + -- end + -- end + + local dh = descriptions[0x2D] + if dh then + local ds = descriptions[0xAD] + if not ds or ds.width ~= dh.width then descriptions[0xAD] = nil - if trace_unicodes then - report_unicodes("patching soft hyphen") + if ds then + if trace_unicodes then + report_unicodes("patching soft hyphen") + end + else + if trace_unicodes then + report_unicodes("adding soft hyphen") + end end - else - if trace_unicodes then - report_unicodes("adding soft hyphen") + if not duplicates then + duplicates = { } + resources.duplicates = duplicates + end + local d = duplicates[0x2D] + if d then + d[0xAD] = true + else + duplicates[0x2D] = { [0xAD] = true } end - end - if not duplicates then - duplicates = { } - resources.duplicates = duplicates - end - local dh = duplicates[0x2D] - if dh then - dh[#dh+1] = { [0xAD] = true } - else - duplicates[0x2D] = { [0xAD] = true } end end + end if duplicates then for u, d in next, duplicates do diff --git a/tex/context/base/mkiv/font-shp.lua b/tex/context/base/mkiv/font-shp.lua index 145c4e0e4..2ca3011a5 100644 --- a/tex/context/base/mkiv/font-shp.lua +++ b/tex/context/base/mkiv/font-shp.lua @@ -17,7 +17,7 @@ local pfb = fonts.handlers.pfb local hashes = fonts.hashes local identifiers = hashes.identifiers -local version = 0.010 +local version = otf.version or 0.011 local shapescache = containers.define("fonts", "shapes", version, true) local streamscache = containers.define("fonts", "streams", version, true) diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua index 69b202b3c..d8abed329 100644 --- a/tex/context/base/mkiv/font-ttf.lua +++ b/tex/context/base/mkiv/font-ttf.lua @@ -35,7 +35,7 @@ if not modules then modules = { } end modules ['font-ttf'] = { local next, type, unpack = next, type, unpack local band, rshift = bit32.band, bit32.rshift -local sqrt, round = math.sqrt, math.round +local sqrt, round, abs, min, max = math.sqrt, math.round, math.abs, math.min, math.max local char, rep = string.char, string.rep local concat = table.concat local idiv = number.idiv @@ -207,77 +207,177 @@ end -- We had two loops (going backward) but can do it in one loop .. but maybe we -- should only accept fonts with proper hvar tables. +local xv = { } -- we share this cache +local yv = { } -- we share this cache + local function applyaxis(glyph,shape,deltas,dowidth) local points = shape.points if points then local nofpoints = #points - local h = nofpoints + 2 -- weird, the example font seems to have left first - local l = nofpoints + 1 - ----- v = nofpoints + 3 - ----- t = nofpoints + 4 local dw = 0 local dl = 0 for i=1,#deltas do local deltaset = deltas[i] local xvalues = deltaset.xvalues local yvalues = deltaset.yvalues - local dpoints = deltaset.points - local factor = deltaset.factor - if dpoints then - -- todo: interpolate - local nofdpoints = #dpoints - for i=1,nofdpoints do - local d = dpoints[i] - local p = points[d] - if p then - if xvalues then - local x = xvalues[i] - if x and x ~= 0 then - p[1] = p[1] + factor * x + if xvalues and yvalues then + local dpoints = deltaset.points + local factor = deltaset.factor + if dpoints then + local cnt = #dpoints + if dowidth then + cnt = cnt - 4 + end + if cnt == 1 then + local d = dpoints[1] + local x = xvalues[d] * factor + local y = yvalues[d] * factor + for i=1,nofpoints do + local p = points[i] + if x ~= 0 then + p[1] = p[1] + x + end + if y ~= 0 then + p[2] = p[2] + y end end - if yvalues then - local y = yvalues[i] - if y and y ~= 0 then - p[2] = p[2] + factor * y + else + -- Not the most efficient solution but we seldom do this. We + -- actually need to avoid the extra points here but I'll deal + -- with that when needed. + local function find(i) + local prv = cnt + for j=1,cnt do + local nxt = dpoints[j] + if nxt == i then + return false, j, false + elseif nxt > i then + return prv, false, j + end + prv = j + end + return prv, false, 1 + end + -- We need the first and last points untouched so we first + -- collect data. + for i=1,nofpoints do + local d1, d2, d3 = find(i) + local p2 = points[i] + if d2 then + xv[i] = xvalues[d2] + yv[i] = yvalues[d2] + else + local n1 = dpoints[d1] + local n3 = dpoints[d3] + local p1 = points[n1] + local p3 = points[n3] + local p1x = p1[1] + local p2x = p2[1] + local p3x = p3[1] + local p1y = p1[2] + local p2y = p2[2] + local p3y = p3[2] + local x1 = xvalues[d1] + local y1 = yvalues[d1] + local x3 = xvalues[d3] + local y3 = yvalues[d3] + -- + local fx + local fy + -- + if p1x == p3x then + if x1 == x3 then + fx = x1 + else + fx = 0 + end + elseif p2x <= min(p1x,p3x) then + if p1x < p3x then + fx = x1 + else + fx = x3 + end + elseif p2x >= max(p1x,p3x) then + if p1x > p3x then + fx = x1 + else + fx = x3 + end + else + fx = (p2x - p1x)/(p3x - p1x) + fx = (1 - fx) * x1 + fx * x3 + end + -- + if p1y == p3y then + if y1 == y3 then + fy = y1 + else + fy = 0 + end + elseif p2y <= min(p1y,p3y) then + if p1y < p3y then + fy = y1 + else + fy = y3 + end + elseif p2y >= max(p1y,p3y) then + if p1y > p3y then + fy = y1 + else + fy = y3 + end + else + fy = (p2y - p1y)/(p3y - p1y) + fy = (1 - fy) * y1 + fy * y3 + end + -- -- maybe: + -- if p1y ~= p3y then + -- fy = (p2y - p1y)/(p3y - p1y) + -- fy = (1 - fy) * y1 + fy * y3 + -- elseif abs(p1y-p2y) < abs(p3y-p2y) then + -- fy = y1 + -- else + -- fy = y3 + -- end + -- + xv[i] = fx + yv[i] = fy end end - elseif dowidth then - -- we've now ran into phantom points which is a bit fuzzy because: - -- are there gaps in there? - -- - -- todo: move this outside the loop (when we can be sure of all 4 being there) - if d == h then - -- we have a phantom point hadvance - local x = xvalues[i] - if x then - dw = dw + factor * x + for i=1,nofpoints do + local pi = points[i] + local fx = xv[i] + local fy = yv[i] + if fx ~= 0 then + pi[1] = pi[1] + factor * fx end - elseif d == l then - local x = xvalues[i] - if x then - dl = dl + factor * x + if fy ~= 0 then + pi[2] = pi[2] + factor * fy end end end - end - else - for i=1,nofpoints do - local p = points[i] - if xvalues then + else + for i=1,nofpoints do + local p = points[i] local x = xvalues[i] - if x and x ~= 0 then - p[1] = p[1] + factor * x - end - end - if yvalues then - local y = yvalues[i] - if y and y ~= 0 then - p[2] = p[2] + factor * y + if x then + local y = yvalues[i] + if x ~= 0 then + p[1] = p[1] + factor * x + end + if y ~= 0 then + p[2] = p[2] + factor * y + end + else + break end end end if dowidth then + local h = nofpoints + 2 -- weird, the example font seems to have left first + local l = nofpoints + 1 + ----- v = nofpoints + 3 + ----- t = nofpoints + 4 local x = xvalues[h] if x then dw = dw + factor * x @@ -934,13 +1034,13 @@ local function readcomposite(f) yoffset = yoffset * yscale end elseif band(flags,0x0080) ~= 0 then -- f_matrix - xscale = read2dot14(f) - xrotate = read2dot14(f) - yrotate = read2dot14(f) - yscale = read2dot14(f) + xscale = read2dot14(f) -- xxpart + xrotate = read2dot14(f) -- yxpart + yrotate = read2dot14(f) -- xypart + yscale = read2dot14(f) -- yypart if f_xyarg and f_offset then - xoffset = xoffset * sqrt(xscale ^2 + xrotate^2) - yoffset = yoffset * sqrt(yrotate^2 + yscale ^2) + xoffset = xoffset * sqrt(xscale ^2 + yrotate^2) -- was xrotate + yoffset = yoffset * sqrt(xrotate^2 + yscale ^2) -- was yrotate end end nofcomponents = nofcomponents + 1 @@ -1120,50 +1220,6 @@ local function readpoints(f) end end -local function readdeltas(f,nofpoints) - local deltas = { } - local p = 0 - local z = 0 - while nofpoints > 0 do - local control = readbyte(f) -if not control then - break -end - local allzero = band(control,0x80) ~= 0 - local runlength = band(control,0x3F) + 1 - if allzero then - z = z + runlength - else - local runreader = band(control,0x40) ~= 0 and readshort or readinteger - if z > 0 then - for i=1,z do - p = p + 1 - deltas[p] = 0 - end - z = 0 - end - for i=1,runlength do - p = p + 1 - deltas[p] = runreader(f) - end - end - nofpoints = nofpoints - runlength - end - -- saves space --- if z > 0 then --- for i=1,z do --- p = p + 1 --- deltas[p] = 0 --- end --- end - if p > 0 then - -- forget about trailing zeros - return deltas - else - -- forget about all zeros - end -end - local function readdeltas(f,nofpoints) local deltas = { } local p = 0 @@ -1334,7 +1390,8 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata) -- local start = start and start[i] or 0 -- local stop = stop and stop [i] or 0 local start = start and start[i] or (peak < 0 and peak or 0) - local stop = stop and stop [i] or (peak > 0 and peak or 0) + local stop = stop and stop [i] or (peak > 0 and peak or 0) -- or 1 ? +-- local stop = stop and stop [i] or (peak > 0 and peak or 1) -- or 1 ? -- do we really need these tests ... can't we assume sane values if start > peak or peak > stop then -- * 1 @@ -1347,7 +1404,6 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata) s = 0 break elseif f < peak then --- s = - s * (f - start) / (peak - start) s = s * (f - start) / (peak - start) elseif f > peak then s = s * (stop - f) / (stop - peak) diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua index 2cfe76951..f049422bf 100644 --- a/tex/context/base/mkiv/mult-fun.lua +++ b/tex/context/base/mkiv/mult-fun.lua @@ -38,7 +38,7 @@ return { "popparameters", "definecolor", -- - "newrecord", "setrecord", "getrecord", + "record", "newrecord", "setrecord", "getrecord", -- "anchorxy", "anchorx", "anchory", "anchorht", "anchordp", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 5339844ef..20b39c38c 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index ca5ba949d..3159027b6 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index db941e888..d977c4982 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.06.30 19:17} +\newcontextversion{2021.07.02 13:15} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index 529d2cb2e..a509a9205 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.06.30 19:17} +\immutable\edef\contextversion{2021.07.02 13:15} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/font-fil.mklx b/tex/context/base/mkxl/font-fil.mklx index 57ed47fa2..b71f8df69 100644 --- a/tex/context/base/mkxl/font-fil.mklx +++ b/tex/context/base/mkxl/font-fil.mklx @@ -379,6 +379,6 @@ % bonus -% \currentfontinstancespec % define ad the lua end +% \currentfontinstancespec % defined at the lua end \protect \endinput diff --git a/tex/context/base/mkxl/lang-dis.lmt b/tex/context/base/mkxl/lang-dis.lmt index 1236ba749..5c4ab1e34 100644 --- a/tex/context/base/mkxl/lang-dis.lmt +++ b/tex/context/base/mkxl/lang-dis.lmt @@ -26,6 +26,7 @@ local getsubtype = nuts.getsubtype local setsubtype = nuts.setsubtype local getchar = nuts.getchar local setchar = nuts.setchar +local getdiscpart = nuts.getdiscpart local getdisc = nuts.getdisc local setdisc = nuts.setdisc local getlanguage = nuts.getlanguage @@ -39,6 +40,7 @@ local remove_node = nuts.remove ----- flushnode = nuts.flushnode local nextdisc = nuts.traversers.disc +local nextglyph = nuts.traversers.glyph local new_disc = nuts.pool.disc @@ -48,6 +50,12 @@ local disccodes = nodes.disccodes local disc_code = nodecodes.disc local glyph_code = nodecodes.glyph +local discoptioncodes = tex.discoptioncodes +local pre_part_code = discoptioncodes.pre +local post_part_code = discoptioncodes.post +local replace_part_code = discoptioncodes.replace +local always_part_code = discoptioncodes.always + local explicitdisc_code = disccodes.explicit local a_visualize = attributes.private("visualizediscretionary") @@ -76,6 +84,20 @@ function languages.visualizediscretionaries(head) end end end + for g in nextglyph, head do + if getattr(g,a_visualize) then + local c = getdiscpart(g) + if c == pre_part_code then + setlistcolor(g,"darkmagenta") + elseif c == post_part_code then + setlistcolor(g,"darkcyan") + elseif c == replace_part_code then + setlistcolor(g,"darkyellow") + elseif c == always_part_code then + setlistcolor(g,"darkgray") + end + end + end return head end diff --git a/tex/context/base/mkxl/luat-ini.mkxl b/tex/context/base/mkxl/luat-ini.mkxl index 98095a4de..d1a84f60c 100644 --- a/tex/context/base/mkxl/luat-ini.mkxl +++ b/tex/context/base/mkxl/luat-ini.mkxl @@ -59,8 +59,32 @@ %D It is nicer for checking with \type {s-system-macros} if we have some meaning: \pushoverloadmode - % \aliased\let\-\explicitdiscretionary - \permanent\protected\def\-{\begingroup\hyphenationmode\explicithyphenationmodecode\explicitdiscretionary\endgroup} + + % We anyway need this: + + \permanent\protected\def\superexplicitdiscretionary + {\begingroup + \hyphenationmode\explicithyphenationmodecode\explicitdiscretionary + \endgroup} + + % Conceptually the best: + + \aliased\let\-\explicitdiscretionary + + % But we could do this to be compatible: + + % \permanent\protected\def\-{\begingroup\hyphenationmode\explicithyphenationmodecode\explicitdiscretionary\endgroup} + + % Or maybe even this: + + % \aliased\let\lang_explicit_discretionary_nop\explicitdiscretionary + % + % \permanent\protected\def\lang_explicit_discretionary_yes-% + % {\superexplicitdiscretionary} + % + % \permanent\protected\def\-% + % {\doifelsenextcharcs-\lang_explicit_discretionary_yes\lang_explicit_discretionary_nop} + \popoverloadmode \ifdefined\n \else \mutable\def\n{n} \fi \ifdefined\r \else \mutable\def\r{r} \fi diff --git a/tex/context/base/mkxl/mlib-lmt.lmt b/tex/context/base/mkxl/mlib-lmt.lmt index 651a98be5..55485e5f8 100644 --- a/tex/context/base/mkxl/mlib-lmt.lmt +++ b/tex/context/base/mkxl/mlib-lmt.lmt @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['mlib-lmt'] = { -- todo: check for possible inject usage local type = type -local round = math.round +local round, abs = math.round, math.abs local aux = mp.aux local mpdirect = aux.direct @@ -154,44 +154,36 @@ todecimal = xdecimal and xdecimal.new or tonumber -- bonus -- mail on list by Mikael Sundqvist and Taco's analysis of near duplicate points (2021/02/11+) registerscript("scrutenized", function() - local p = scanpath() - local d = 10^scannumeric() - for i=1,#p do - local pi = p[i] - pi[1] = round(pi[1] * d) / d - pi[2] = round(pi[2] * d) / d - end - local x1 = round(p[1][1]) - local y1 = round(p[1][2]) - local n = 1 - local m = #p - local t = { p[1], cycle = p.cycle } - for i=2,m-1 do - local pi = p[i] - local x2 = round(pi[1]) - local y2 = round(pi[2]) - if x1 ~= x2 or y1 ~= y2 then - n = n + 1 - t[n] = p[i] - x1 = x2 - y1 = y2 + local pth = scanpath() + local d = 1/10^scannumeric() -- decimals + local p1 = pth[1] + local x1 = p1[1] + local y1 = p1[2] + local res = { pth[1] } + local r = 1 + for i=2,#pth do + local pi = pth[i] + x2 = pi[1] + y2 = pi[2] + if abs(x1-x2) > d or abs(y1-y2) > d then + r = r + 1 res[r] = pi end + x1 = x2 + y1 = y2 end - local x1 = round(p[1][1]) - local y1 = round(p[1][2]) - local x2 = round(p[m][1]) - local y2 = round(p[m][2]) - if x1 ~= x2 or y1 ~= y2 then - n = n + 1 - t[n] = p[m] + if pth.cycle then + res.cycle = true + if abs(x1-p1[1]) > d or abs(y1-p1[2]) > d then + -- keep + else + res[r] = nil + end end - -- mp.path(t) - injectpath(t) + injectpath(res) end) -- A goodie, mostly a side effect of updating the metafun manual. - local labtorgb = attributes.colors.labtorgb registerscript("labtorgb", function() diff --git a/tex/context/base/mkxl/mlib-scn.lmt b/tex/context/base/mkxl/mlib-scn.lmt index 1d6514a0b..4f76ca545 100644 --- a/tex/context/base/mkxl/mlib-scn.lmt +++ b/tex/context/base/mkxl/mlib-scn.lmt @@ -767,129 +767,144 @@ end -- This is an experiment for Alan and me. -local records = { } -local stack = setmetatableindex("table") -local nofrecords = 0 -local interim = 0 - -registerdirect("newrecord", function() - scantoken() -- semicolon - local p = get_parameters() - local n = 0 - if interim > 0 then - records[interim] = p - local top = stack[interim] - if top then - top = stack[interim][#top] +do + + local records = { } + local stack = setmetatableindex("table") + local nofrecords = 0 + local interim = 0 + local names = { } + -- local types = { } + + registerdirect("newrecord", function() + scantoken() -- semicolon + local p = get_parameters() + local n = 0 + if interim > 0 then + records[interim] = p + local top = stack[interim] if top then - setmetatableindex(p,top) + top = stack[interim][#top] + if top then + setmetatableindex(p,top) + end end + n = interim + interim = 0 + else + nofrecords = nofrecords + 1 + records[nofrecords] = p + n = nofrecords end - n = interim - interim = 0 - else - nofrecords = nofrecords + 1 - records[nofrecords] = p - n = nofrecords - end - return n -end) - -local function merge(old,new) - for knew, vnew in next, new do - local vold = old[knew] - if vold then - if type(vnew) == "table" then - if type(vold) == "table" then - merge(vold,vnew) + return n + end) + + local function merge(old,new) + for knew, vnew in next, new do + local vold = old[knew] + if vold then + if type(vnew) == "table" then + if type(vold) == "table" then + merge(vold,vnew) + else + old[knew] = vnew + end else old[knew] = vnew end else old[knew] = vnew end - else - old[knew] = vnew end end -end -registerdirect("setrecord", function() - scantoken() -- semicolon - local p = get_parameters() - local n = 0 - if interim > 0 then - local r = records[interim] - if r then - merge(r,p) - else - records[interim] = p - end - local top = stack[interim] - if top then - top = stack[interim][#top] + registerdirect("setrecord", function() + scantoken() -- semicolon + local p = get_parameters() + local n = 0 + if interim > 0 then + local r = records[interim] + if r then + merge(r,p) + else + records[interim] = p + end + local top = stack[interim] if top then - setmetatableindex(p,top) + top = stack[interim][#top] + if top then + setmetatableindex(p,top) + end end + n = interim + interim = 0 + else + nofrecords = nofrecords + 1 + records[nofrecords] = p + n = nofrecords end - n = interim - interim = 0 - else - nofrecords = nofrecords + 1 - records[nofrecords] = p - n = nofrecords - end - return n -end) + return n + end) -registerdirect("getrecord", function() - local n = scaninteger() - local v = records[n] - while true do - local t = scansymbol(true) - if t == ";" or t == ")" or t == ":" then - return v - elseif t == "." then - scansymbol() - elseif t == "#" or t == "##" then -- from tex's we get a double - scansymbol() - t = scansymbol() - v = v[t] - return type(v) == "table" and #v or 0 - elseif t == "[" then - scansymbol() - t = scansymbol(true) - if t == "]" then + registerdirect("getrecord", function() + local n = scaninteger() + local v = records[n] + while true do + local t = scansymbol(true) + if t == ";" or t == ")" or t == ":" then + return v + elseif t == "." then scansymbol() - return #v - else - t = scaninteger() + elseif t == "#" or t == "##" then -- from tex's we get a double + scansymbol() + t = scansymbol() v = v[t] - if scansymbol(true) == "]" then + return type(v) == "table" and #v or 0 + elseif t == "[" then + scansymbol() + t = scansymbol(true) + if t == "]" then scansymbol() + return #v else - report("] expected") + t = scaninteger() + v = v[t] + if scansymbol(true) == "]" then + scansymbol() + else + report("] expected") + end end + else + t = scansymbol() + v = v[t] end - else - t = scansymbol() - v = v[t] + end + end) + + function metapost.getrecord(name) + local index = names[name] + if index then + return records[index] end end -end) -function metapost.runinternal(action,index,kind) - if action == 0 then - -- allocate - elseif action == 1 then - -- save - insert(stack[index],records[index]) - interim = index - elseif action == 2 then - -- restore - records[index] = remove(stack[index]) or records[index] + function metapost.runinternal(action,index,kind,name) + if action == 0 then + -- allocate + names[name] = index + -- types[index] = kind + elseif action == 1 then + -- save + insert(stack[index],records[index]) + interim = index + elseif action == 2 then + -- restore + records[index] = remove(stack[index]) or records[index] + end end + end -- goodies diff --git a/tex/context/base/mkxl/page-cst.mkxl b/tex/context/base/mkxl/page-cst.mkxl index 0afc2a645..12ee0bd38 100644 --- a/tex/context/base/mkxl/page-cst.mkxl +++ b/tex/context/base/mkxl/page-cst.mkxl @@ -255,7 +255,6 @@ \fi \endgroup} - \protected\def\page_grd_command_set_vsize {\clf_setvsizecolumnset{\currentpagegrid}% \ifdim\d_page_grd_gap_height<\lineheight diff --git a/tex/context/base/mkxl/page-mcl.mkxl b/tex/context/base/mkxl/page-mcl.mkxl index d36e76d94..e88371da1 100644 --- a/tex/context/base/mkxl/page-mcl.mkxl +++ b/tex/context/base/mkxl/page-mcl.mkxl @@ -125,6 +125,7 @@ \fi \fi \c_page_mcl_n_of_lines\noflines} + % \protected\def\page_mcl_command_set_vsize % {%%\page_one_command_set_vsize % indeed? % \page_mcl_set_n_of_lines\zeropoint @@ -187,7 +188,7 @@ {\scratchdimen\dimexpr \d_page_mcl_saved_pagetotal -\d_page_mcl_preceding_height - -\topskip + % -\topskip % no, this is already part of the saved total \relax \box\b_page_mcl_preceding \kern\scratchdimen} diff --git a/tex/context/base/mkxl/page-sid.mkxl b/tex/context/base/mkxl/page-sid.mkxl index fd9f6837a..dccfcbce9 100644 --- a/tex/context/base/mkxl/page-sid.mkxl +++ b/tex/context/base/mkxl/page-sid.mkxl @@ -472,10 +472,10 @@ \installcorenamespace{sidefloatsteps} -\setvalue{\??sidefloatsteps\v!line }{\strut} -\setvalue{\??sidefloatsteps\v!big }{\strut} -\setvalue{\??sidefloatsteps\v!medium}{\halflinestrut} % was \halfstrut -\setvalue{\??sidefloatsteps\v!small }{\noheightstrut} % was \quarterstrut +\defcsname\??sidefloatsteps\v!line \endcsname{\strut} +\defcsname\??sidefloatsteps\v!big \endcsname{\strut} +\defcsname\??sidefloatsteps\v!medium\endcsname{\halflinestrut} % was \halfstrut +\defcsname\??sidefloatsteps\v!small \endcsname{\noheightstrut} % was \quarterstrut \def\page_sides_flush_floats_tracer {\dontleavehmode diff --git a/tex/context/modules/mkiv/s-fonts-variable.lua b/tex/context/modules/mkiv/s-fonts-variable.lua index 43f5f0d3d..b84b78ada 100644 --- a/tex/context/modules/mkiv/s-fonts-variable.lua +++ b/tex/context/modules/mkiv/s-fonts-variable.lua @@ -55,9 +55,9 @@ function moduledata.fonts.variable.showvariations(specification) -- return -- end -if not fontdata.shared.rawdata.metadata.fullname then - fontdata.shared.rawdata.metadata.fullname = fontdata.shared.rawdata.metadata.fontname -end + if not fontdata.shared.rawdata.metadata.fullname then + fontdata.shared.rawdata.metadata.fullname = fontdata.shared.rawdata.metadata.fontname + end context.starttitle { title = fontdata.shared.rawdata.metadata.fullname } @@ -111,7 +111,7 @@ end local designaxis = variabledata.designaxis context.startsubject { title = "design axis" } - if designaxis then + if designaxis and #designaxis > 0 then context.starttabulate { "||||c|c|c|c|c|" } NC() bold("tag") NC() bold("name") @@ -159,7 +159,7 @@ end local list = { } context.startsubject { title = "axis" } - if axis then + if axis and #axis > 0 then context.starttabulate { "|||c|c|c|" } NC() bold("tag") NC() bold("name") diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv index 6e4b1773f..cb8bd1f9a 100644 --- a/tex/context/modules/mkiv/s-fonts-variable.mkiv +++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv @@ -53,26 +53,26 @@ \starttext - \startbuffer[zycon] - \char008986\relax\quad - \char009728\relax\quad - \char010031\relax\quad - \char010143\relax\quad - \char011044\relax\quad - \char127773\relax\quad - \char127989\relax\quad - \char128008\relax\quad - \char128021\relax\quad - \char128034\relax\quad - \char128161\relax\quad - \char128274\relax\quad - \char128347\relax\quad - \char128400\relax\quad - \char128692\relax\quad - \char129417\relax\quad - \char129422\relax\quad - \char983040\relax\par - \stopbuffer +% \startbuffer[zycon] +% \char008986\relax\quad +% \char009728\relax\quad +% \char010031\relax\quad +% \char010143\relax\quad +% \char011044\relax\quad +% \char127773\relax\quad +% \char127989\relax\quad +% \char128008\relax\quad +% \char128021\relax\quad +% \char128034\relax\quad +% \char128161\relax\quad +% \char128274\relax\quad +% \char128347\relax\quad +% \char128400\relax\quad +% \char128692\relax\quad +% \char129417\relax\quad +% \char129422\relax\quad +% \char983040\relax\par +% \stopbuffer % \showfontvariations % [font=file:adobevfprototype.otf] diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 39670cb36..0d8121a41 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2021-06-30 19:17 +-- merge date : 2021-07-02 13:15 do -- begin closure to overcome local limits and interference @@ -15129,7 +15129,7 @@ if not modules then modules={} end modules ['font-ttf']={ } local next,type,unpack=next,type,unpack local band,rshift=bit32.band,bit32.rshift -local sqrt,round=math.sqrt,math.round +local sqrt,round,abs,min,max=math.sqrt,math.round,math.abs,math.min,math.max local char,rep=string.char,string.rep local concat=table.concat local idiv=number.idiv @@ -15263,69 +15263,156 @@ local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), r_x,r_y,"c" end +local xv={} +local yv={} local function applyaxis(glyph,shape,deltas,dowidth) local points=shape.points if points then local nofpoints=#points - local h=nofpoints+2 - local l=nofpoints+1 local dw=0 local dl=0 for i=1,#deltas do local deltaset=deltas[i] local xvalues=deltaset.xvalues local yvalues=deltaset.yvalues - local dpoints=deltaset.points - local factor=deltaset.factor - if dpoints then - local nofdpoints=#dpoints - for i=1,nofdpoints do - local d=dpoints[i] - local p=points[d] - if p then - if xvalues then - local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x + if xvalues and yvalues then + local dpoints=deltaset.points + local factor=deltaset.factor + if dpoints then + local cnt=#dpoints + if dowidth then + cnt=cnt-4 + end + if cnt==1 then + local d=dpoints[1] + local x=xvalues[d]*factor + local y=yvalues[d]*factor + for i=1,nofpoints do + local p=points[i] + if x~=0 then + p[1]=p[1]+x + end + if y~=0 then + p[2]=p[2]+y end end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y + else + local function find(i) + local prv=cnt + for j=1,cnt do + local nxt=dpoints[j] + if nxt==i then + return false,j,false + elseif nxt>i then + return prv,false,j + end + prv=j + end + return prv,false,1 + end + for i=1,nofpoints do + local d1,d2,d3=find(i) + local p2=points[i] + if d2 then + xv[i]=xvalues[d2] + yv[i]=yvalues[d2] + else + local n1=dpoints[d1] + local n3=dpoints[d3] + local p1=points[n1] + local p3=points[n3] + local p1x=p1[1] + local p2x=p2[1] + local p3x=p3[1] + local p1y=p1[2] + local p2y=p2[2] + local p3y=p3[2] + local x1=xvalues[d1] + local y1=yvalues[d1] + local x3=xvalues[d3] + local y3=yvalues[d3] + local fx + local fy + if p1x==p3x then + if x1==x3 then + fx=x1 + else + fx=0 + end + elseif p2x<=min(p1x,p3x) then + if p1x=max(p1x,p3x) then + if p1x>p3x then + fx=x1 + else + fx=x3 + end + else + fx=(p2x-p1x)/(p3x-p1x) + fx=(1-fx)*x1+fx*x3 + end + if p1y==p3y then + if y1==y3 then + fy=y1 + else + fy=0 + end + elseif p2y<=min(p1y,p3y) then + if p1y=max(p1y,p3y) then + if p1y>p3y then + fy=y1 + else + fy=y3 + end + else + fy=(p2y-p1y)/(p3y-p1y) + fy=(1-fy)*y1+fy*y3 + end + xv[i]=fx + yv[i]=fy end end - elseif dowidth then - if d==h then - local x=xvalues[i] - if x then - dw=dw+factor*x + for i=1,nofpoints do + local pi=points[i] + local fx=xv[i] + local fy=yv[i] + if fx~=0 then + pi[1]=pi[1]+factor*fx end - elseif d==l then - local x=xvalues[i] - if x then - dl=dl+factor*x + if fy~=0 then + pi[2]=pi[2]+factor*fy end end end - end - else - for i=1,nofpoints do - local p=points[i] - if xvalues then + else + for i=1,nofpoints do + local p=points[i] local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x - end - end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y + if x then + local y=yvalues[i] + if x~=0 then + p[1]=p[1]+factor*x + end + if y~=0 then + p[2]=p[2]+factor*y + end + else + break end end end if dowidth then + local h=nofpoints+2 + local l=nofpoints+1 local x=xvalues[h] if x then dw=dw+factor*x @@ -15904,13 +15991,13 @@ local function readcomposite(f) yoffset=yoffset*yscale end elseif band(flags,0x0080)~=0 then - xscale=read2dot14(f) - xrotate=read2dot14(f) - yrotate=read2dot14(f) - yscale=read2dot14(f) + xscale=read2dot14(f) + xrotate=read2dot14(f) + yrotate=read2dot14(f) + yscale=read2dot14(f) if f_xyarg and f_offset then - xoffset=xoffset*sqrt(xscale^2+xrotate^2) - yoffset=yoffset*sqrt(yrotate^2+yscale^2) + xoffset=xoffset*sqrt(xscale^2+yrotate^2) + yoffset=yoffset*sqrt(xrotate^2+yscale^2) end end nofcomponents=nofcomponents+1 @@ -16065,40 +16152,6 @@ local function readpoints(f) return points,p end end -local function readdeltas(f,nofpoints) - local deltas={} - local p=0 - local z=0 - while nofpoints>0 do - local control=readbyte(f) -if not control then - break -end - local allzero=band(control,0x80)~=0 - local runlength=band(control,0x3F)+1 - if allzero then - z=z+runlength - else - local runreader=band(control,0x40)~=0 and readshort or readinteger - if z>0 then - for i=1,z do - p=p+1 - deltas[p]=0 - end - z=0 - end - for i=1,runlength do - p=p+1 - deltas[p]=runreader(f) - end - end - nofpoints=nofpoints-runlength - end - if p>0 then - return deltas - else - end -end local function readdeltas(f,nofpoints) local deltas={} local p=0 @@ -20859,7 +20912,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.117 +otf.version=3.118 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) otf.pngcache=containers.define("fonts","png",otf.version,true) @@ -21239,10 +21292,14 @@ elseif CONTEXTLMTXMODE then local maxindex=data.nofglyphs or metadata.nofglyphs if maxindex then for u,d in sortedhash(duplicates) do - for uu in sortedhash(d) do - maxindex=maxindex+1 - descriptions[uu].dupindex=descriptions[u].index - descriptions[uu].index=maxindex + local du=descriptions[u] + if du then + for uu in sortedhash(d) do + maxindex=maxindex+1 + descriptions[uu].dupindex=du.index + descriptions[uu].index=maxindex + end + else end end end @@ -23537,7 +23594,10 @@ local f_index=formatters["I%05X"] local f_character_y=formatters["%C"] local f_character_n=formatters["[ %C ]"] local check_duplicates=true -local check_soft_hyphen=true +local check_soft_hyphen=context +directives.register("otf.checksofthyphen",function(v) + check_soft_hyphen=v +end) local function replaced(list,index,replacement) if type(list)=="number" then return replacement @@ -23925,27 +23985,30 @@ local function copyduplicates(fontdata) local resources=fontdata.resources local duplicates=resources.duplicates if check_soft_hyphen then - local ds=descriptions[0xAD] - if not ds or ds.width==0 then - if ds then + local dh=descriptions[0x2D] + if dh then + local ds=descriptions[0xAD] + if not ds or ds.width~=dh.width then descriptions[0xAD]=nil - if trace_unicodes then - report_unicodes("patching soft hyphen") + if ds then + if trace_unicodes then + report_unicodes("patching soft hyphen") + end + else + if trace_unicodes then + report_unicodes("adding soft hyphen") + end end - else - if trace_unicodes then - report_unicodes("adding soft hyphen") + if not duplicates then + duplicates={} + resources.duplicates=duplicates + end + local d=duplicates[0x2D] + if d then + d[0xAD]=true + else + duplicates[0x2D]={ [0xAD]=true } end - end - if not duplicates then - duplicates={} - resources.duplicates=duplicates - end - local dh=duplicates[0x2D] - if dh then - dh[#dh+1]={ [0xAD]=true } - else - duplicates[0x2D]={ [0xAD]=true } end end end @@ -36228,7 +36291,7 @@ local afm=fonts.handlers.afm local pfb=fonts.handlers.pfb local hashes=fonts.hashes local identifiers=hashes.identifiers -local version=0.010 +local version=otf.version or 0.011 local shapescache=containers.define("fonts","shapes",version,true) local streamscache=containers.define("fonts","streams",version,true) local compact_streams=false -- cgit v1.2.3