From 772472f057060460c83828cf7fd1631298165e37 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 15 Sep 2017 21:00:20 +0200 Subject: 2017-09-15 20:09:00 --- colors/icc/profiles/default_gray.icc | Bin 0 -> 416 bytes .../general/manuals/mkiv-publications.pdf | Bin 528274 -> 528258 bytes doc/context/documents/general/qrcs/setup-cs.pdf | Bin 816073 -> 816202 bytes doc/context/documents/general/qrcs/setup-de.pdf | Bin 816651 -> 816792 bytes doc/context/documents/general/qrcs/setup-en.pdf | Bin 818532 -> 818669 bytes doc/context/documents/general/qrcs/setup-fr.pdf | Bin 811829 -> 811959 bytes doc/context/documents/general/qrcs/setup-it.pdf | Bin 815342 -> 815470 bytes doc/context/documents/general/qrcs/setup-nl.pdf | Bin 810022 -> 810140 bytes doc/context/documents/general/qrcs/setup-ro.pdf | Bin 812593 -> 812727 bytes .../sources/general/manuals/xml/xml-mkiv.tex | 3 +- scripts/context/lua/mtx-fonts.lua | 2 +- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-ro.mkii | 2 + tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-dsp.lua | 30 +- tex/context/base/mkiv/font-ini.lua | 3 +- tex/context/base/mkiv/font-otc.lua | 4 +- tex/context/base/mkiv/font-otj.lua | 215 ++++-- tex/context/base/mkiv/font-otr.lua | 6 +- tex/context/base/mkiv/font-ots.lua | 605 +++++++-------- tex/context/base/mkiv/font-oup.lua | 69 +- tex/context/base/mkiv/math-ali.mkiv | 21 +- tex/context/base/mkiv/status-files.pdf | Bin 25849 -> 25846 bytes tex/context/base/mkiv/status-lua.pdf | Bin 426575 -> 426573 bytes tex/context/interface/mkii/keys-ro.xml | 2 + tex/context/interface/mkiv/i-context.pdf | Bin 818532 -> 818669 bytes tex/context/interface/mkiv/i-readme.pdf | Bin 60775 -> 60774 bytes tex/context/modules/mkiv/s-fonts-variable.mkiv | 6 +- tex/context/modules/mkiv/s-present-lines.mkiv | 8 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 836 ++++++++++++--------- tex/generic/context/luatex/luatex-fonts-mis.lua | 32 + tex/generic/context/luatex/luatex-fonts.lua | 1 + 34 files changed, 1078 insertions(+), 775 deletions(-) create mode 100644 colors/icc/profiles/default_gray.icc create mode 100644 tex/generic/context/luatex/luatex-fonts-mis.lua diff --git a/colors/icc/profiles/default_gray.icc b/colors/icc/profiles/default_gray.icc new file mode 100644 index 000000000..daaa7480a Binary files /dev/null and b/colors/icc/profiles/default_gray.icc differ diff --git a/doc/context/documents/general/manuals/mkiv-publications.pdf b/doc/context/documents/general/manuals/mkiv-publications.pdf index 7b12abb9d..22e9f4ccf 100644 Binary files a/doc/context/documents/general/manuals/mkiv-publications.pdf and b/doc/context/documents/general/manuals/mkiv-publications.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf index 39fb283a7..49afa30e7 100644 Binary files a/doc/context/documents/general/qrcs/setup-cs.pdf and b/doc/context/documents/general/qrcs/setup-cs.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf index 5a7be9981..05acbe68a 100644 Binary files a/doc/context/documents/general/qrcs/setup-de.pdf and b/doc/context/documents/general/qrcs/setup-de.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf index 750f687f2..bf72c9fcc 100644 Binary files a/doc/context/documents/general/qrcs/setup-en.pdf and b/doc/context/documents/general/qrcs/setup-en.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf index 3d5fb8459..f5ca50d89 100644 Binary files a/doc/context/documents/general/qrcs/setup-fr.pdf and b/doc/context/documents/general/qrcs/setup-fr.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf index eb627a48f..7bae220c5 100644 Binary files a/doc/context/documents/general/qrcs/setup-it.pdf and b/doc/context/documents/general/qrcs/setup-it.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf index a2abb50f0..77066eb39 100644 Binary files a/doc/context/documents/general/qrcs/setup-nl.pdf and b/doc/context/documents/general/qrcs/setup-nl.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf index 5446f9467..1e3add650 100644 Binary files a/doc/context/documents/general/qrcs/setup-ro.pdf and b/doc/context/documents/general/qrcs/setup-ro.pdf differ diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv.tex b/doc/context/sources/general/manuals/xml/xml-mkiv.tex index 4834c4555..ec9be1c6e 100644 --- a/doc/context/sources/general/manuals/xml/xml-mkiv.tex +++ b/doc/context/sources/general/manuals/xml/xml-mkiv.tex @@ -1778,7 +1778,6 @@ In addition, \type {=} equals \type {==} and \type {!=} is the same as \type \stopsection - \startsection[title={css selectors}] \startbuffer[selector-001] @@ -1837,7 +1836,7 @@ supported too. In fact, you can combine both methods. Depending on what you select, the \CSS\ one can be a little bit faster too. It has the advantage that one can select more in one go but at the same time looks a bit less attractive. This method was added just to show that it can be done but might be useful too. A -selector is gogen between curly braces (after all \CSS\ uses them and they have no +selector is given between curly braces (after all \CSS\ uses them and they have no function yet in the parser. \starttyping diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua index 2bc5d370a..d42013d33 100644 --- a/scripts/context/lua/mtx-fonts.lua +++ b/scripts/context/lua/mtx-fonts.lua @@ -414,7 +414,7 @@ function scripts.fonts.list() end elseif pattern then --~ mtxrun --script font --list --pattern=*somename* - list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info) + list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info) elseif given then --~ mtxrun --script font --list somename list_matches(fonts.names.list(given,reload,all),info) diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 805595e50..f31bce976 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{2017.09.08 17:24} +\newcontextversion{2017.09.15 20:03} %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 cdaac874c..93dd75394 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{2017.09.08 17:24} +\edef\contextversion{2017.09.15 20:03} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index 6ae2fe671..bceff14e4 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -753,6 +753,7 @@ \setinterfaceconstant{direction}{directie} \setinterfaceconstant{directory}{director} \setinterfaceconstant{display}{display} +\setinterfaceconstant{displaythreshold}{displaythreshold} \setinterfaceconstant{distance}{distanta} \setinterfaceconstant{domain}{domain} \setinterfaceconstant{dot}{punct} @@ -862,6 +863,7 @@ \setinterfaceconstant{index}{index} \setinterfaceconstant{indicator}{indicator} \setinterfaceconstant{initialsep}{initialsep} +\setinterfaceconstant{inlinethreshold}{inlinethreshold} \setinterfaceconstant{inner}{intern} \setinterfaceconstant{innermargin}{innermargin} \setinterfaceconstant{inputfile}{inputfile} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index bfb0e6be1..c3305ba66 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2017.09.08 17:24} +\newcontextversion{2017.09.15 20:03} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index d7f63e76e..4033f2c7d 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -41,7 +41,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2017.09.08 17:24} +\edef\contextversion{2017.09.15 20:03} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index dee115a6b..34497ece7 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -2046,8 +2046,8 @@ do local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) - local sequences = fontdata.sequences or { } - local sublookuplist = fontdata.sublookups or { } + local sequences = fontdata.sequences or { } + local sublookuplist = fontdata.sublookups or { } fontdata.sequences = sequences fontdata.sublookups = sublookuplist local nofsublookups = #sublookuplist @@ -2062,6 +2062,8 @@ do local noflookups = #lookups local lookupprefix = sub(what,2,2) -- g[s|p][ub|os] -- + local usedlookups = false -- setmetatableindex("number") + -- for lookupid=1,noflookups do local lookup = lookups[lookupid] local lookuptype = lookup.type @@ -2131,12 +2133,26 @@ do current[i] = tohash(current[i]) end end + else + -- weird lookup end if after then for i=1,#after do after[i] = tohash(after[i]) end end + if usedlookups then + local lookups = rule.lookups + if lookups then + for k, v in next, lookups do + if v then + for k, v in next, v do + usedlookups[v] = usedlookups[v] + 1 + end + end + end + end + end end end end @@ -2188,6 +2204,10 @@ do end end + if usedlookups then + report("used %s lookups: % t",what,sortedkeys(usedlookups)) + end + -- When we have a context, we have sublookups that resolve into lookups for which we need to -- know the type. We split the main lookuptable in two parts: sequences (the main lookups) -- and subtable lookups (simple specs with no features). We could keep them merged and might do @@ -2243,7 +2263,7 @@ do if d then nofsublookups = nofsublookups + 1 -- report("registering %i as sublookup %i",lookupid,nofsublookups) - h = { + local l = { index = nofsublookups, -- handy for tracing name = f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), derived = true, -- handy for tracing @@ -2254,7 +2274,7 @@ do flags = d.flags, -- chain = d.chain, } - sublookuplist[nofsublookups] = copy(h) -- we repack later + sublookuplist[nofsublookups] = copy(l) -- we repack later sublookuphash[lookupid] = nofsublookups sublookupcheck[lookupid] = 1 h = nofsublookups @@ -2277,7 +2297,9 @@ do end end end +-- report("before : % t",rlookups[index]) rlookups[index] = noffound > 0 and found or false +-- report("after : % t",rlookups[index]) else rlookups[index] = false end diff --git a/tex/context/base/mkiv/font-ini.lua b/tex/context/base/mkiv/font-ini.lua index e0ad46cac..3d5dd27a2 100644 --- a/tex/context/base/mkiv/font-ini.lua +++ b/tex/context/base/mkiv/font-ini.lua @@ -15,8 +15,7 @@ local allocate = utilities.storage.allocate fonts = fonts or { } local fonts = fonts -fonts.hashes = { identifiers = allocate() } - +fonts.hashes = fonts.hashes or { identifiers = allocate() } fonts.tables = fonts.tables or { } fonts.helpers = fonts.helpers or { } fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua index 7014761f1..1d0db7b81 100644 --- a/tex/context/base/mkiv/font-otc.lua +++ b/tex/context/base/mkiv/font-otc.lua @@ -466,10 +466,10 @@ local function addfeature(data,feature,specifications) subtype = lookup.type end else - lookups[k] = { false } -- new + lookups[k] = false -- { false } -- new end else - lookups[k] = { false } -- new + lookups[k] = false -- { false } -- new end end end diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua index 74e052408..1f9fd1ac1 100644 --- a/tex/context/base/mkiv/font-otj.lua +++ b/tex/context/base/mkiv/font-otj.lua @@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['font-otj'] = { } -- This property based variant is not faster but looks nicer than the attribute one. We --- need to use rawget (which is apbout 4 times slower than a direct access but we cannot +-- need to use rawget (which is about 4 times slower than a direct access but we cannot -- get/set that one for our purpose! This version does a bit more with discretionaries -- (and Kai has tested it with his collection of weird fonts.) @@ -49,6 +49,7 @@ local attributes, nodes, node = attributes, nodes, node fonts = fonts local hashes = fonts.hashes local fontdata = hashes.identifiers +local fontmarks = hashes.marks ----- parameters = fonts.hashes.parameters -- not in generic ----- resources = fonts.hashes.resources -- not in generic @@ -157,9 +158,9 @@ end function injections.reset(n) local p = rawget(properties,n) if p then - p.injections = false -- { } + p.injections = false -- { } -- nil should work too as we use rawget else - properties[n] = false -- { injections = { } } + properties[n] = false -- { injections = { } } -- nil should work too as we use rawget end end @@ -192,7 +193,7 @@ function injections.copy(target,source) end end -function injections.setligaindex(n,index) +function injections.setligaindex(n,index) -- todo: don't set when 0 local p = rawget(properties,n) if p then local i = p.injections @@ -397,43 +398,43 @@ function injections.setmove(current,factor,rlmode,x,injection) if not injection then injection = "injections" end -if rlmode and rlmode < 0 then - -- we need to swap with a single so then we also need to to it here - -- as move is just a simple single - if p then - local i = p[injection] - if i then - i.rightkern = dx + (i.rightkern or 0) + if rlmode and rlmode < 0 then + -- we need to swap with a single so then we also need to to it here + -- as move is just a simple single + if p then + local i = p[injection] + if i then + i.rightkern = dx + (i.rightkern or 0) + else + p[injection] = { + rightkern = dx, + } + end else - p[injection] = { - rightkern = dx, + properties[current] = { + [injection] = { + rightkern = dx, + }, } end else - properties[current] = { - [injection] = { - rightkern = dx, - }, - } - end -else - if p then - local i = p[injection] - if i then - i.leftkern = dx + (i.leftkern or 0) + if p then + local i = p[injection] + if i then + i.leftkern = dx + (i.leftkern or 0) + else + p[injection] = { + leftkern = dx, + } + end else - p[injection] = { - leftkern = dx, + properties[current] = { + [injection] = { + leftkern = dx, + }, } end - else - properties[current] = { - [injection] = { - leftkern = dx, - }, - } end -end return dx, nofregisteredkerns else return 0, 0 @@ -454,9 +455,15 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmar if i.markmark then -- out of order mkmk: yes or no or option else - i.markx = dx - i.marky = dy - i.markdir = rlmode or 0 + if dx ~= 0 then + i.markx = dx + end + if y ~= 0 then + i.marky = dy + end + if rlmode then + i.markdir = rlmode + end i.markbase = nofregisteredmarks i.markbasenode = base i.markmark = mkmk @@ -792,12 +799,12 @@ local function inject_positions_only(head,where) local leftkern = i.leftkern local rightkern = i.rightkern if leftkern and leftkern ~= 0 then -if rightkern and leftkern == -rightkern then - setoffsets(current,leftkern,false) - rightkern = 0 -else - head = insert_node_before(head,current,fontkern(leftkern)) -end + if rightkern and leftkern == -rightkern then + setoffsets(current,leftkern,false) + rightkern = 0 + else + head = insert_node_before(head,current,fontkern(leftkern)) + end end if rightkern and rightkern ~= 0 then insert_node_after(head,current,fontkern(rightkern)) @@ -1040,16 +1047,16 @@ local function inject_everything(head,where) rightkern = pp.rightkern end end + local markdir = pn.markdir if rightkern then -- x and w ~= 0 - if pn.markdir < 0 then + ox = px - (pn.markx or 0) - rightkern + if markdir and markdir < 0 then -- kern(w-x) glyph(p) kern(x) mark(n) - ox = px - pn.markx - rightkern if not pn.markmark then ox = ox + (pn.leftkern or 0) end else -- kern(x) glyph(p) kern(w-x) mark(n) - -- ox = px - getwidth(p) + pn.markx - pp.leftkern -- -- According to Kai we don't need to handle leftkern here but I'm -- pretty sure I've run into a case where it was needed so maybe @@ -1057,7 +1064,6 @@ local function inject_everything(head,where) -- -- maybe we need to apply both then -- - ox = px - pn.markx - rightkern -- seguiemj needs the rightkern if false then -- a mark with kerning (maybe husayni needs it ) local leftkern = pp.leftkern @@ -1067,16 +1073,14 @@ local function inject_everything(head,where) end end else - if pn.markdir < 0 then - ox = px - pn.markx + ox = px - (pn.markx or 0) + if markdir and markdir < 0 then if not pn.markmark then local leftkern = pn.leftkern if leftkern then ox = ox + leftkern -- husayni needs it end end - else - ox = px - pn.markx end if pn.checkmark then local wn = getwidth(n) -- in arial marks have widths @@ -1101,7 +1105,7 @@ local function inject_everything(head,where) end end end - local oy = ny + py + pn.marky + local oy = ny + py + (pn.marky or 0) if not pn.markmark then local yoffset = pn.yoffset if yoffset then @@ -1113,15 +1117,72 @@ local function inject_everything(head,where) showoffset(n,true) end end + -- begin of temp fix -- + local base = nil -- bah, some arabic fonts have no mark anchoring + -- end of temp fix -- while current do local next = getnext(current) local char, id = ischar(current) if char then local p = rawget(properties,current) + -- begin of temp fix -- + if hascursives then + if not p then + local m = fontmarks[getfont(current)] + if m and m[char] then + if base then + p = { injections = { markbasenode = base } } + nofmarks = nofmarks + 1 + marks[nofmarks] = current + properties[current] = p + hasmarks = true + end + else + base = current + end + end + end + -- end of temp fix if p then local i = p.injections + -- begin of temp fix -- + if hascursives then + if not i then + local m = fontmarks[getfont(current)] + if m and m[char] then + if base then + i = { markbasenode = base } + nofmarks = nofmarks + 1 + marks[nofmarks] = current + p.injections = i + hasmarks = true + end + else + base = current + end + end + end + -- end of temp fix -- if i then local pm = i.markbasenode + -- begin of temp fix -- + if hascursives then + if not pm then + local m = fontmarks[getfont(current)] + if m and m[char] then + if base then + pm = base + i.markbasenode = pm + hasmarks = true + end + else + base = current + end + else + base = current + end + end + -- end of temp fix -- if pm then nofmarks = nofmarks + 1 marks[nofmarks] = current @@ -1185,12 +1246,12 @@ local function inject_everything(head,where) local leftkern = i.leftkern local rightkern = i.rightkern if leftkern and leftkern ~= 0 then -if rightkern and leftkern == -rightkern then - setoffsets(current,leftkern,false) - rightkern = 0 -else - head = insert_node_before(head,current,fontkern(leftkern)) -end + if rightkern and leftkern == -rightkern then + setoffsets(current,leftkern,false) + rightkern = 0 + else + head = insert_node_before(head,current,fontkern(leftkern)) + end end if rightkern and rightkern ~= 0 then insert_node_after(head,current,fontkern(rightkern)) @@ -1401,6 +1462,7 @@ end else prevglyph = nil prevdisc = nil +base = nil end prev = current current = next @@ -1532,7 +1594,6 @@ local function injectspaces(head) if not triggers then return head, false end - local lastfont = nil local spacekerns = nil local leftkerns = nil @@ -1584,23 +1645,25 @@ local function injectspaces(head) if old > threshold then if rightkern then if useitalickerns then - local new = old + (leftkern + rightkern) * factor - if trace_spaces then - report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) - end - setwidth(n,new) - else - local new = (leftkern + rightkern) * factor + local lnew = leftkern * factor + local rnew = rightkern * factor if trace_spaces then - report_spaces("%C [%p + %p] %C",prevchar,old,new,nextchar) + report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) end - local h = insert_node_before(nuthead,n,italickern(new)) + local h = insert_node_before(nuthead,n,italickern(lnew)) if h == nuthead then head = tonode(h) nuthead = h end + insert_node_after(nuthead,n,italickern(rnew)) + else + local new = old + (leftkern + rightkern) * factor + if trace_spaces then + report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) + end + setwidth(n,new) end - leftkern = false + rightkern = false else if useitalickerns then local new = leftkern * factor @@ -1621,11 +1684,19 @@ local function injectspaces(head) elseif rightkern then local old = getwidth(n) if old > threshold then - local new = old + rightkern * factor - if trace_spaces then - report_spaces("[%p -> %p] %C",nextchar,old,new) + if useitalickerns then + local new = rightkern * factor + if trace_spaces then + report_spaces("%C [%p + %p]",nextchar,old,new) + end + insert_node_after(nuthead,n,italickern(new)) + else + local new = old + rightkern * factor + if trace_spaces then + report_spaces("[%p -> %p] %C",nextchar,old,new) + end + setwidth(n,new) end - setwidth(n,new) end rightkern = false end diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index 8f08dc5eb..8fd84015a 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -2128,9 +2128,9 @@ local function readdata(f,offset,specification) if factors then specification.factors = factors fontdata.factors = factors - report("factors: % t",factors) - else - report("bad factors") + -- report("factors: % t",factors) + -- else + -- report("bad factors") end else -- report("unknown instance") diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 031cf3baa..3d0606caf 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -543,12 +543,13 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou -- we can be more clever here: "not deletemarks or (skiphash and not skiphash[char])" -- and such: elseif not deletemarks then + -- we can get a loop when the font expects otherwise (i.e. unexpected deletemarks) setligaindex(start,baseindex + getligaindex(start,componentindex)) if trace_marks then logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) end local n = copy_node(start) - copyinjection(n,start) + copyinjection(n,start) -- is this ok ? we position later anyway head, current = insert_node_after(head,current,n) -- unlikely that mark has components elseif trace_marks then logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char)) @@ -2352,7 +2353,7 @@ end -- are real torture tests because they have many steps with one context (having -- multiple contexts makes more sense) also because we (can) reduce them. Instead of -- a match boolean variable and check for that I decided to use a goto with labels --- instead. This is one of the cases where it makes th ecode more readable and we +-- instead. This is one of the cases where it makes the code more readable and we -- might even gain a bit performance. local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash) @@ -2381,254 +2382,134 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s startnext = getboth(start) local done -- = false - -- hm, contexts can also be nested + -- we can have multiple hits and as we scan (currently) all we need to check + -- if we have a match ... contextchains have no real coverage table (with + -- unique entries) - for k=1,contexts.n do -- or #contexts do + -- fonts can have many steps (each doing one check) or many contexts + + -- todo: make a per-char cache so that we have small contexts (when we have a context + -- n == 1 and otherwise it can be more so we can even distingish n == 1 or more) + + local nofcontexts = contexts.n -- #contexts + + local startchar = nofcontext == 1 or ischar(start,currentfont) -- only needed in a chain + + + for k=1,nofcontexts do + + local ck = contexts[k] + local seq = ck[3] + local f = ck[4] -- first current + if not startchar or not seq[f][startchar] then + -- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts) + goto next + end + local s = seq.n -- or #seq + local l = ck[5] -- last current local current = start local last = start - local ck = contexts[k] - local seq = ck[3] - -- local s = #seq - local s = seq.n -- or #seq - -- f..l = mid string - if s == 1 then - -- this seldom happens as it makes no sense (bril, ebgaramond, husayni, minion) - local char = ischar(current,currentfont) - if char and not seq[1][char] then - goto next - end - else - -- maybe we need a better space check (maybe check for glue or category or combination) - local f = ck[4] - local l = ck[5] - -- current match - -- seq[f][ischar(current,currentfont)] is not nil - if l > f then - -- before/current/after | before/current | current/after - local discfound -- = nil - local n = f + 1 - last = startnext -- the second in current (first already matched) - while n <= l do - if postreplace and not last then - last = getnext(sweepnode) - sweeptype = nil - end - if last then - local char, id = ischar(last,currentfont) - if char then - if skiphash and skiphash[char] then - skipped = true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end + + -- current match + + if l > f then + -- before/current/after | before/current | current/after + local discfound -- = nil + local n = f + 1 + last = startnext -- the second in current (first already matched) + while n <= l do + if postreplace and not last then + last = getnext(sweepnode) + sweeptype = nil + end + if last then + local char, id = ischar(last,currentfont) + if char then + if skiphash and skiphash[char] then + skipped = true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + last = getnext(last) + elseif seq[n][char] then + if n < l then last = getnext(last) - elseif seq[n][char] then - if n < l then - last = getnext(last) - end - n = n + 1 - elseif discfound then - notmatchreplace[discfound] = true - if notmatchpre[discfound] then - goto next - else - break - end - else - goto next end - elseif char == false then - if discfound then - notmatchreplace[discfound] = true - if notmatchpre[discfound] then - goto next - else - break - end + n = n + 1 + elseif discfound then + notmatchreplace[discfound] = true + if notmatchpre[discfound] then + goto next else + break + end + else + goto next + end + elseif char == false then + if discfound then + notmatchreplace[discfound] = true + if notmatchpre[discfound] then goto next + else + break end - elseif id == disc_code then - -- elseif id == disc_code and (not discs or discs[last]) then - diskseen = true - discfound = last - notmatchpre[last] = nil - notmatchpost[last] = true - notmatchreplace[last] = nil - local pre, post, replace = getdisc(last) - if pre then - local n = n - while pre do - if seq[n][getchar(pre)] then - n = n + 1 - if n > l then - break - end - pre = getnext(pre) - else - notmatchpre[last] = true + else + goto next + end + elseif id == disc_code then + -- elseif id == disc_code and (not discs or discs[last]) then + diskseen = true + discfound = last + notmatchpre[last] = nil + notmatchpost[last] = true + notmatchreplace[last] = nil + local pre, post, replace = getdisc(last) + if pre then + local n = n + while pre do + if seq[n][getchar(pre)] then + n = n + 1 + if n > l then break end - end - if n <= l then + pre = getnext(pre) + else notmatchpre[last] = true + break end - else - notmatchpre[last] = true end - if replace then - -- so far we never entered this branch - while replace do - if seq[n][getchar(replace)] then - n = n + 1 - if n > l then - break - end - replace = getnext(replace) - else - notmatchreplace[last] = true - if notmatchpre[last] then - goto next - else - break - end - end - end - -- why here again - if notmatchpre[last] then - goto next - end + if n <= l then + notmatchpre[last] = true end - -- maybe only if match - last = getnext(last) else - goto next + notmatchpre[last] = true end - else - goto next - end - end - end - -- before - if f > 1 then - if startprev then - local prev = startprev - if prereplace and prev == checkdisc then - prev = getprev(sweepnode) - end - if prev then - local discfound -- = nil - local n = f - 1 - while n >= 1 do - if prev then - local char, id = ischar(prev,currentfont) - if char then - if skiphash and skiphash[char] then - skipped = true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - prev = getprev(prev) - elseif seq[n][char] then - if n > 1 then - prev = getprev(prev) - end - n = n - 1 - elseif discfound then - notmatchreplace[discfound] = true - if notmatchpost[discfound] then - goto next - else - break - end - else - goto next + if replace then + -- so far we never entered this branch + while replace do + if seq[n][getchar(replace)] then + n = n + 1 + if n > l then + break end - elseif char == false then - if discfound then - notmatchreplace[discfound] = true - if notmatchpost[discfound] then - goto next - end - else + replace = getnext(replace) + else + notmatchreplace[last] = true + if notmatchpre[last] then goto next - end - break - elseif id == disc_code then - -- elseif id == disc_code and (not discs or discs[prev]) then - -- the special case: f i where i becomes dottless i .. - diskseen = true - discfound = prev - notmatchpre[prev] = true - notmatchpost[prev] = nil - notmatchreplace[prev] = nil - local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true) - if pre ~= start and post ~= start and replace ~= start then - if post then - local n = n - while posttail do - if seq[n][getchar(posttail)] then - n = n - 1 - if posttail == post or n < 1 then - break - else - posttail = getprev(posttail) - end - else - notmatchpost[prev] = true - break - end - end - if n >= 1 then - notmatchpost[prev] = true - end - else - notmatchpost[prev] = true - end - if replace then - -- we seldom enter this branch (e.g. on brill efficient) - while replacetail do - if seq[n][getchar(replacetail)] then - n = n - 1 - if replacetail == replace or n < 1 then - break - else - replacetail = getprev(replacetail) - end - else - notmatchreplace[prev] = true - if notmatchpost[prev] then - goto next - else - break - end - end - end - end - end - prev = getprev(prev) - -- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then - -- elseif seq[n][32] and spaces[prev] then - -- n = n - 1 - -- prev = getprev(prev) - elseif id == glue_code then - local sn = seq[n] - if (sn[32] and spaces[prev]) or sn[0xFFFC] then - n = n - 1 - prev = getprev(prev) else - goto next + break end - elseif seq[n][0xFFFC] then - n = n - 1 - prev = getprev(prev) - else - goto next end - else + end + -- why here again + if notmatchpre[last] then goto next end end + -- maybe only if match + last = getnext(last) else goto next end @@ -2636,33 +2517,37 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s goto next end end - -- after - if s > l then - local current = last and getnext(last) - if not current and postreplace then - current = getnext(sweepnode) + end + + -- before + + if f > 1 then + if startprev then + local prev = startprev + if prereplace and prev == checkdisc then + prev = getprev(sweepnode) end - if current then + if prev then local discfound -- = nil - local n = l + 1 - while n <= s do - if current then - local char, id = ischar(current,currentfont) + local n = f - 1 + while n >= 1 do + if prev then + local char, id = ischar(prev,currentfont) if char then if skiphash and skiphash[char] then skipped = true if trace_skips then show_skip(dataset,sequence,char,ck,classes[char]) end - current = getnext(current) -- was absent + prev = getprev(prev) elseif seq[n][char] then - if n < s then -- new test - current = getnext(current) -- was absent + if n > 1 then + prev = getprev(prev) end - n = n + 1 + n = n - 1 elseif discfound then notmatchreplace[discfound] = true - if notmatchpre[discfound] then + if notmatchpost[discfound] then goto next else break @@ -2673,82 +2558,81 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s elseif char == false then if discfound then notmatchreplace[discfound] = true - if notmatchpre[discfound] then + if notmatchpost[discfound] then goto next - else - break end else goto next end + break elseif id == disc_code then - -- elseif id == disc_code and (not discs or discs[current]) then - diskseen = true - discfound = current - notmatchpre[current] = nil - notmatchpost[current] = true - notmatchreplace[current] = nil - local pre, post, replace = getdisc(current) - if pre then - local n = n - while pre do - if seq[n][getchar(pre)] then - n = n + 1 - if n > s then - break + -- elseif id == disc_code and (not discs or discs[prev]) then + -- the special case: f i where i becomes dottless i .. + diskseen = true + discfound = prev + notmatchpre[prev] = true + notmatchpost[prev] = nil + notmatchreplace[prev] = nil + local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true) + if pre ~= start and post ~= start and replace ~= start then + if post then + local n = n + while posttail do + if seq[n][getchar(posttail)] then + n = n - 1 + if posttail == post or n < 1 then + break + else + posttail = getprev(posttail) + end else - pre = getnext(pre) + notmatchpost[prev] = true + break end - else - notmatchpre[current] = true - break end + if n >= 1 then + notmatchpost[prev] = true + end + else + notmatchpost[prev] = true end - if n <= s then - notmatchpre[current] = true - end - else - notmatchpre[current] = true - end - if replace then - -- so far we never entered this branch - while replace do - if seq[n][getchar(replace)] then - n = n + 1 - if n > s then - break - else - replace = getnext(replace) - end - else - notmatchreplace[current] = true - -- different than others, needs checking if "not" is okay - if not notmatchpre[current] then - goto next + if replace then + -- we seldom enter this branch (e.g. on brill efficient) + while replacetail do + if seq[n][getchar(replacetail)] then + n = n - 1 + if replacetail == replace or n < 1 then + break + else + replacetail = getprev(replacetail) + end else - break + notmatchreplace[prev] = true + if notmatchpost[prev] then + goto next + else + break + end end end end - else - -- skip 'm end - current = getnext(current) - -- elseif id == glue_code and seq[n][32] and isspace(current,threshold,id) then - -- elseif seq[n][32] and spaces[current] then - -- n = n + 1 - -- current = getnext(current) + prev = getprev(prev) + -- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then + -- elseif seq[n][32] and spaces[prev] then + -- n = n - 1 + -- prev = getprev(prev) elseif id == glue_code then local sn = seq[n] - if (sn[32] and spaces[current]) or sn[0xFFFC] then - n = n + 1 - current = getnext(current) + if (sn[32] and spaces[prev]) or sn[0xFFFC] then + n = n - 1 + prev = getprev(prev) else goto next end elseif seq[n][0xFFFC] then - n = n + 1 - current = getnext(current) + n = n - 1 + prev = getprev(prev) else goto next end @@ -2759,8 +2643,137 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s else goto next end + else + goto next + end + end + + -- after + + if s > l then + local current = last and getnext(last) + if not current and postreplace then + current = getnext(sweepnode) + end + if current then + local discfound -- = nil + local n = l + 1 + while n <= s do + if current then + local char, id = ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + skipped = true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + current = getnext(current) -- was absent + elseif seq[n][char] then + if n < s then -- new test + current = getnext(current) -- was absent + end + n = n + 1 + elseif discfound then + notmatchreplace[discfound] = true + if notmatchpre[discfound] then + goto next + else + break + end + else + goto next + end + elseif char == false then + if discfound then + notmatchreplace[discfound] = true + if notmatchpre[discfound] then + goto next + else + break + end + else + goto next + end + elseif id == disc_code then + -- elseif id == disc_code and (not discs or discs[current]) then + diskseen = true + discfound = current + notmatchpre[current] = nil + notmatchpost[current] = true + notmatchreplace[current] = nil + local pre, post, replace = getdisc(current) + if pre then + local n = n + while pre do + if seq[n][getchar(pre)] then + n = n + 1 + if n > s then + break + else + pre = getnext(pre) + end + else + notmatchpre[current] = true + break + end + end + if n <= s then + notmatchpre[current] = true + end + else + notmatchpre[current] = true + end + if replace then + -- so far we never entered this branch + while replace do + if seq[n][getchar(replace)] then + n = n + 1 + if n > s then + break + else + replace = getnext(replace) + end + else + notmatchreplace[current] = true + -- different than others, needs checking if "not" is okay + if not notmatchpre[current] then + goto next + else + break + end + end + end + else + -- skip 'm + end + current = getnext(current) + -- elseif id == glue_code and seq[n][32] and isspace(current,threshold,id) then + -- elseif seq[n][32] and spaces[current] then + -- n = n + 1 + -- current = getnext(current) + elseif id == glue_code then + local sn = seq[n] + if (sn[32] and spaces[current]) or sn[0xFFFC] then + n = n + 1 + current = getnext(current) + else + goto next + end + elseif seq[n][0xFFFC] then + n = n + 1 + current = getnext(current) + else + goto next + end + else + goto next + end + end + else + goto next end end + if trace_contexts then chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true) end diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua index da9ed1a77..79ac76abe 100644 --- a/tex/context/base/mkiv/font-oup.lua +++ b/tex/context/base/mkiv/font-oup.lua @@ -2655,10 +2655,6 @@ function readers.expand(data) end end - checkmerge(sequence) - checkflags(sequence,resources) - checksteps(sequence) - for i=1,nofsteps do local step = steps[i] local baseclasses = step.baseclasses @@ -2675,13 +2671,14 @@ function readers.expand(data) end local rules = step.rules if rules then - local rulehash = { n = 0 } + local rulehash = { n = 0 } -- is contexts in font-ots local rulesize = 0 local coverage = { } local lookuptype = sequence.type + local nofrules = #rules step.coverage = coverage -- combined hits - for nofrules=1,#rules do - local rule = rules[nofrules] + for currentrule=1,nofrules do + local rule = rules[currentrule] local current = rule.current local before = rule.before local after = rule.after @@ -2712,7 +2709,7 @@ function readers.expand(data) for i=1,#lookups do local lookups = lookups[i] if lookups then - for k, v in next, lookups do + for k, v in next, lookups do -- actually this one is indexed local lookup = sublookups[v] if lookup then lookups[k] = lookup @@ -2728,9 +2725,8 @@ function readers.expand(data) end if sequence[1] then -- we merge coverage into one sequence.n = #sequence -- tiny speedup - rulesize = rulesize + 1 - rulehash[rulesize] = { - nofrules, -- 1 + local ruledata = { + currentrule, -- 1 -- original rule number, only use this for tracing! lookuptype, -- 2 sequence, -- 3 start, -- 4 @@ -2739,19 +2735,56 @@ function readers.expand(data) replacements, -- 7 subtype, -- 8 } - for unic in next, sequence[start] do - local cu = coverage[unic] - if not cu then - coverage[unic] = rulehash -- can now be done cleaner i think - else - -- we can have a problem + -- + -- possible optimization: per [unic] a rulehash, but beware: + -- contexts have unique coverage and chains can have multiple + -- hits (rules) per coverage entry + -- + -- so: we can combine multiple steps as well as multiple rules + -- but that takes careful checking, in which case we can go the + -- step list approach and turn contexts into steps .. in fact, + -- if we turn multiple contexts into steps we're already ok as + -- steps gets a coverage hash by metatable + -- + rulesize = rulesize + 1 + rulehash[rulesize] = ruledata + rulehash.n = rulesize -- tiny speedup + -- + if true then -- nofrules > 1 + + for unic in next, sequence[start] do + local cu = coverage[unic] + if cu then + local n = #cu+1 + cu[n] = ruledata + cu.n = n + else + coverage[unic] = { ruledata, n = 1 } + end + end + + else + + for unic in next, sequence[start] do + local cu = coverage[unic] + if cu then + -- we can have a contextchains with many matches which we + -- can actually optimize + else + coverage[unic] = rulehash + end end + end - rulehash.n = rulesize -- tiny speedup end end end end + + checkmerge(sequence) + checkflags(sequence,resources) + checksteps(sequence) + end end end diff --git a/tex/context/base/mkiv/math-ali.mkiv b/tex/context/base/mkiv/math-ali.mkiv index 40da3d4c9..2b0cc0bc1 100644 --- a/tex/context/base/mkiv/math-ali.mkiv +++ b/tex/context/base/mkiv/math-ali.mkiv @@ -831,7 +831,8 @@ \unexpanded\def\math_matrix_start_cell {\dostarttagged\t!mathtablecell\empty - \math_left_of_equalign + \hss + %\math_left_of_equalign \startimath \math_matrix_set_style \tabskip\zeropoint @@ -839,7 +840,8 @@ \unexpanded\def\math_matrix_stop_cell {\stopimath - \math_right_of_eqalign + %\math_right_of_eqalign + \hss \dostoptagged} % We could construct a preamble with alignment and such embedded but the number @@ -1187,25 +1189,22 @@ %D %D \typebuffer which gives \getbuffer +% no tagging yet : how is it supposed to be coded? + \unexpanded\def\startsubstack {\begingroup \vcenter\bgroup \baselineskip\mathstacktotal \lineskip\mathstackvgap \lineskiplimit\lineskip - \let\stopmathmode\relax - \def\NC{\math_matrix_NC}% - \def\MC{\math_matrix_NC\startmathmode}% - \global\let\math_matrix_NC\math_matrix_NC_indeed - \def\NR - {\stopmathmode - \global\let\math_matrix_NC\math_matrix_NC_indeed - \crcr}% \mathsurround\zeropoint \everycr\emptytoks + \let\NC\relax + \let\MC\relax + \let\NR\crcr \halign\bgroup\hfil\normalstartimath\scriptstyle\alignmark\alignmark\normalstopimath\hfil\crcr} -\def\stopsubstack +\def\stopsubstack % todo: \unexpanded and delayed {\crcr \egroup \egroup diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index a91d6f73c..e45d0d6c3 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 89040ffec..59f1db86f 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/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index 7f7fc14ad..e0f46ecb5 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -759,6 +759,7 @@ + @@ -868,6 +869,7 @@ + diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 750f687f2..bf72c9fcc 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index 09ceb5d6c..8f5f4a254 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv index 69f4a7843..d024ddc05 100644 --- a/tex/context/modules/mkiv/s-fonts-variable.mkiv +++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv @@ -72,9 +72,9 @@ \char983040\relax\par \stopbuffer -% \showfontvariations -% [font=file:VotoSerifGX.ttf, -% max=6] + \showfontvariations + [font=file:VotoSerifGX.ttf, + ]% max=6] \showfontvariations [font=file:adobevfprototype.otf] diff --git a/tex/context/modules/mkiv/s-present-lines.mkiv b/tex/context/modules/mkiv/s-present-lines.mkiv index 6d4c59a03..3a2fdae53 100644 --- a/tex/context/modules/mkiv/s-present-lines.mkiv +++ b/tex/context/modules/mkiv/s-present-lines.mkiv @@ -153,7 +153,13 @@ [state=start, color=maincolor, contrastcolor=maincolor, - style=bold] + style=] + +\setuptyping + [color=maincolor] + +\setuptype + [color=maincolor] \usemodule[abr-04] diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 4bd3958c8..1952a9819 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 : 09/08/17 17:24:08 +-- merge date : 09/15/17 20:03:34 do -- begin closure to overcome local limits and interference @@ -7550,7 +7550,7 @@ if not modules then modules={} end modules ['font-ini']={ local allocate=utilities.storage.allocate fonts=fonts or {} local fonts=fonts -fonts.hashes={ identifiers=allocate() } +fonts.hashes=fonts.hashes or { identifiers=allocate() } fonts.tables=fonts.tables or {} fonts.helpers=fonts.helpers or {} fonts.tracers=fonts.tracers or {} @@ -7567,6 +7567,38 @@ end -- closure do -- begin closure to overcome local limits and interference +if not modules then modules={} end modules ['luatex-font-mis']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + texio.write_nl("fatal error: this module is not for context") + os.exit() +end +local currentfont=font.current +local hashes=fonts.hashes +local identifiers=hashes.identifiers or {} +local marks=hashes.marks or {} +hashes.identifiers=identifiers +hashes.marks=marks +table.setmetatableindex(marks,function(t,k) + if k==true then + return marks[currentfont()] + else + local resources=identifiers[k].resources or {} + local marks=resources.marks or {} + t[k]=marks + return marks + end +end) + +end -- closure + +do -- begin closure to overcome local limits and interference + if not modules then modules={} end modules ['font-con']={ version=1.001, comment="companion to font-ini.mkiv", @@ -11087,9 +11119,6 @@ local function readdata(f,offset,specification) if factors then specification.factors=factors fontdata.factors=factors - report("factors: % t",factors) - else - report("bad factors") end else end @@ -16029,7 +16058,7 @@ do end local f_lookupname=formatters["%s_%s_%s"] local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) - local sequences=fontdata.sequences or {} + local sequences=fontdata.sequences or {} local sublookuplist=fontdata.sublookups or {} fontdata.sequences=sequences fontdata.sublookups=sublookuplist @@ -16044,6 +16073,7 @@ do local nofglyphs=fontdata.nofglyphs or #glyphs local noflookups=#lookups local lookupprefix=sub(what,2,2) + local usedlookups=false for lookupid=1,noflookups do local lookup=lookups[lookupid] local lookuptype=lookup.type @@ -16107,12 +16137,25 @@ do current[i]=tohash(current[i]) end end + else end if after then for i=1,#after do after[i]=tohash(after[i]) end end + if usedlookups then + local lookups=rule.lookups + if lookups then + for k,v in next,lookups do + if v then + for k,v in next,v do + usedlookups[v]=usedlookups[v]+1 + end + end + end + end + end end end end @@ -16159,6 +16202,9 @@ do report("no handler for lookup %a with type %a",lookupid,lookuptype) end end + if usedlookups then + report("used %s lookups: % t",what,sortedkeys(usedlookups)) + end local reported={} local function report_issue(i,what,sequence,kind) local name=sequence.name @@ -16200,7 +16246,7 @@ do local d=lookup.done if d then nofsublookups=nofsublookups+1 - h={ + local l={ index=nofsublookups, name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), derived=true, @@ -16210,7 +16256,7 @@ do markclass=d.markclass or nil, flags=d.flags, } - sublookuplist[nofsublookups]=copy(h) + sublookuplist[nofsublookups]=copy(l) sublookuphash[lookupid]=nofsublookups sublookupcheck[lookupid]=1 h=nofsublookups @@ -19606,9 +19652,6 @@ function readers.expand(data) sequence.markclass=markclasses[markclass] end end - checkmerge(sequence) - checkflags(sequence,resources) - checksteps(sequence) for i=1,nofsteps do local step=steps[i] local baseclasses=step.baseclasses @@ -19625,13 +19668,14 @@ function readers.expand(data) end local rules=step.rules if rules then - local rulehash={ n=0 } + local rulehash={ n=0 } local rulesize=0 local coverage={} local lookuptype=sequence.type + local nofrules=#rules step.coverage=coverage - for nofrules=1,#rules do - local rule=rules[nofrules] + for currentrule=1,nofrules do + local rule=rules[currentrule] local current=rule.current local before=rule.before local after=rule.after @@ -19662,7 +19706,7 @@ function readers.expand(data) for i=1,#lookups do local lookups=lookups[i] if lookups then - for k,v in next,lookups do + for k,v in next,lookups do local lookup=sublookups[v] if lookup then lookups[k]=lookup @@ -19677,9 +19721,8 @@ function readers.expand(data) end if sequence[1] then sequence.n=#sequence - rulesize=rulesize+1 - rulehash[rulesize]={ - nofrules, + local ruledata={ + currentrule, lookuptype, sequence, start, @@ -19688,18 +19731,36 @@ function readers.expand(data) replacements, subtype, } - for unic in next,sequence[start] do - local cu=coverage[unic] - if not cu then - coverage[unic]=rulehash - else + rulesize=rulesize+1 + rulehash[rulesize]=ruledata + rulehash.n=rulesize + if true then + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + local n=#cu+1 + cu[n]=ruledata + cu.n=n + else + coverage[unic]={ ruledata,n=1 } + end + end + else + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + else + coverage[unic]=rulehash + end end end - rulehash.n=rulesize end end end end + checkmerge(sequence) + checkflags(sequence,resources) + checksteps(sequence) end end end @@ -20875,6 +20936,7 @@ local attributes,nodes,node=attributes,nodes,node fonts=fonts local hashes=fonts.hashes local fontdata=hashes.identifiers +local fontmarks=hashes.marks nodes.injections=nodes.injections or {} local injections=nodes.injections local tracers=nodes.tracers @@ -20990,7 +21052,7 @@ function injections.copy(target,source) end end end -function injections.setligaindex(n,index) +function injections.setligaindex(n,index) local p=rawget(properties,n) if p then local i=p.injections @@ -21170,41 +21232,41 @@ function injections.setmove(current,factor,rlmode,x,injection) if not injection then injection="injections" end -if rlmode and rlmode<0 then - if p then - local i=p[injection] - if i then - i.rightkern=dx+(i.rightkern or 0) + if rlmode and rlmode<0 then + if p then + local i=p[injection] + if i then + i.rightkern=dx+(i.rightkern or 0) + else + p[injection]={ + rightkern=dx, + } + end else - p[injection]={ - rightkern=dx, + properties[current]={ + [injection]={ + rightkern=dx, + }, } end else - properties[current]={ - [injection]={ - rightkern=dx, - }, - } - end -else - if p then - local i=p[injection] - if i then - i.leftkern=dx+(i.leftkern or 0) + if p then + local i=p[injection] + if i then + i.leftkern=dx+(i.leftkern or 0) + else + p[injection]={ + leftkern=dx, + } + end else - p[injection]={ - leftkern=dx, + properties[current]={ + [injection]={ + leftkern=dx, + }, } end - else - properties[current]={ - [injection]={ - leftkern=dx, - }, - } end -end return dx,nofregisteredkerns else return 0,0 @@ -21222,9 +21284,15 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmar if i then if i.markmark then else - i.markx=dx - i.marky=dy - i.markdir=rlmode or 0 + if dx~=0 then + i.markx=dx + end + if y~=0 then + i.marky=dy + end + if rlmode then + i.markdir=rlmode + end i.markbase=nofregisteredmarks i.markbasenode=base i.markmark=mkmk @@ -21530,12 +21598,12 @@ local function inject_positions_only(head,where) local leftkern=i.leftkern local rightkern=i.rightkern if leftkern and leftkern~=0 then -if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 -else - head=insert_node_before(head,current,fontkern(leftkern)) -end + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + else + head=insert_node_before(head,current,fontkern(leftkern)) + end end if rightkern and rightkern~=0 then insert_node_after(head,current,fontkern(rightkern)) @@ -21762,14 +21830,14 @@ local function inject_everything(head,where) rightkern=pp.rightkern end end + local markdir=pn.markdir if rightkern then - if pn.markdir<0 then - ox=px-pn.markx-rightkern + ox=px-(pn.markx or 0)-rightkern + if markdir and markdir<0 then if not pn.markmark then ox=ox+(pn.leftkern or 0) end else - ox=px-pn.markx-rightkern if false then local leftkern=pp.leftkern if leftkern then @@ -21778,16 +21846,14 @@ local function inject_everything(head,where) end end else - if pn.markdir<0 then - ox=px-pn.markx + ox=px-(pn.markx or 0) + if markdir and markdir<0 then if not pn.markmark then local leftkern=pn.leftkern if leftkern then ox=ox+leftkern end end - else - ox=px-pn.markx end if pn.checkmark then local wn=getwidth(n) @@ -21801,7 +21867,7 @@ local function inject_everything(head,where) end end end - local oy=ny+py+pn.marky + local oy=ny+py+(pn.marky or 0) if not pn.markmark then local yoffset=pn.yoffset if yoffset then @@ -21813,15 +21879,64 @@ local function inject_everything(head,where) showoffset(n,true) end end + local base=nil while current do local next=getnext(current) local char,id=ischar(current) if char then local p=rawget(properties,current) + if hascursives then + if not p then + local m=fontmarks[getfont(current)] + if m and m[char] then + if base then + p={ injections={ markbasenode=base } } + nofmarks=nofmarks+1 + marks[nofmarks]=current + properties[current]=p + hasmarks=true + end + else + base=current + end + end + end if p then local i=p.injections + if hascursives then + if not i then + local m=fontmarks[getfont(current)] + if m and m[char] then + if base then + i={ markbasenode=base } + nofmarks=nofmarks+1 + marks[nofmarks]=current + p.injections=i + hasmarks=true + end + else + base=current + end + end + end if i then local pm=i.markbasenode + if hascursives then + if not pm then + local m=fontmarks[getfont(current)] + if m and m[char] then + if base then + pm=base + i.markbasenode=pm + hasmarks=true + end + else + base=current + end + else + base=current + end + end if pm then nofmarks=nofmarks+1 marks[nofmarks]=current @@ -21884,12 +21999,12 @@ local function inject_everything(head,where) local leftkern=i.leftkern local rightkern=i.rightkern if leftkern and leftkern~=0 then -if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 -else - head=insert_node_before(head,current,fontkern(leftkern)) -end + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + else + head=insert_node_before(head,current,fontkern(leftkern)) + end end if rightkern and rightkern~=0 then insert_node_after(head,current,fontkern(rightkern)) @@ -22092,6 +22207,7 @@ end else prevglyph=nil prevdisc=nil +base=nil end prev=current current=next @@ -22226,23 +22342,25 @@ local function injectspaces(head) if old>threshold then if rightkern then if useitalickerns then - local new=old+(leftkern+rightkern)*factor + local lnew=leftkern*factor + local rnew=rightkern*factor if trace_spaces then - report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) + report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) end - setwidth(n,new) - else - local new=(leftkern+rightkern)*factor - if trace_spaces then - report_spaces("%C [%p + %p] %C",prevchar,old,new,nextchar) - end - local h=insert_node_before(nuthead,n,italickern(new)) + local h=insert_node_before(nuthead,n,italickern(lnew)) if h==nuthead then head=tonode(h) nuthead=h end + insert_node_after(nuthead,n,italickern(rnew)) + else + local new=old+(leftkern+rightkern)*factor + if trace_spaces then + report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) + end + setwidth(n,new) end - leftkern=false + rightkern=false else if useitalickerns then local new=leftkern*factor @@ -22263,11 +22381,19 @@ local function injectspaces(head) elseif rightkern then local old=getwidth(n) if old>threshold then - local new=old+rightkern*factor - if trace_spaces then - report_spaces("[%p -> %p] %C",nextchar,old,new) + if useitalickerns then + local new=rightkern*factor + if trace_spaces then + report_spaces("%C [%p + %p]",nextchar,old,new) + end + insert_node_after(nuthead,n,italickern(new)) + else + local new=old+rightkern*factor + if trace_spaces then + report_spaces("[%p -> %p] %C",nextchar,old,new) + end + setwidth(n,new) end - setwidth(n,new) end rightkern=false end @@ -23037,7 +23163,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) end local n=copy_node(start) - copyinjection(n,start) + copyinjection(n,start) head,current=insert_node_after(head,current,n) elseif trace_marks then logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char)) @@ -24598,233 +24724,112 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s local startprev, startnext=getboth(start) local done - for k=1,contexts.n do - local current=start - local last=start + local nofcontexts=contexts.n + local startchar=nofcontext==1 or ischar(start,currentfont) + for k=1,nofcontexts do local ck=contexts[k] local seq=ck[3] - local s=seq.n - if s==1 then - local char=ischar(current,currentfont) - if char and not seq[1][char] then - goto next - end - else - local f=ck[4] - local l=ck[5] - if l>f then - local discfound - local n=f+1 - last=startnext - while n<=l do - if postreplace and not last then - last=getnext(sweepnode) - sweeptype=nil - end - if last then - local char,id=ischar(last,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end + local f=ck[4] + if not startchar or not seq[f][startchar] then + goto next + end + local s=seq.n + local l=ck[5] + local current=start + local last=start + if l>f then + local discfound + local n=f+1 + last=startnext + while n<=l do + if postreplace and not last then + last=getnext(sweepnode) + sweeptype=nil + end + if last then + local char,id=ischar(last,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + last=getnext(last) + elseif seq[n][char] then + if nl then - break - end - pre=getnext(pre) - else - notmatchpre[last]=true + else + goto next + end + elseif id==disc_code then + diskseen=true + discfound=last + notmatchpre[last]=nil + notmatchpost[last]=true + notmatchreplace[last]=nil + local pre,post,replace=getdisc(last) + if pre then + local n=n + while pre do + if seq[n][getchar(pre)] then + n=n+1 + if n>l then break end - end - if n<=l then + pre=getnext(pre) + else notmatchpre[last]=true + break end - else - notmatchpre[last]=true end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>l then - break - end - replace=getnext(replace) - else - notmatchreplace[last]=true - if notmatchpre[last] then - goto next - else - break - end - end - end - if notmatchpre[last] then - goto next - end + if n<=l then + notmatchpre[last]=true end - last=getnext(last) else - goto next + notmatchpre[last]=true end - else - goto next - end - end - end - if f>1 then - if startprev then - local prev=startprev - if prereplace and prev==checkdisc then - prev=getprev(sweepnode) - end - if prev then - local discfound - local n=f-1 - while n>=1 do - if prev then - local char,id=ischar(prev,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - prev=getprev(prev) - elseif seq[n][char] then - if n>1 then - prev=getprev(prev) - end - n=n-1 - elseif discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - else - break - end - else - goto next + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>l then + break end - elseif char==false then - if discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - end - else + replace=getnext(replace) + else + notmatchreplace[last]=true + if notmatchpre[last] then goto next - end - break - elseif id==disc_code then - diskseen=true - discfound=prev - notmatchpre[prev]=true - notmatchpost[prev]=nil - notmatchreplace[prev]=nil - local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true) - if pre~=start and post~=start and replace~=start then - if post then - local n=n - while posttail do - if seq[n][getchar(posttail)] then - n=n-1 - if posttail==post or n<1 then - break - else - posttail=getprev(posttail) - end - else - notmatchpost[prev]=true - break - end - end - if n>=1 then - notmatchpost[prev]=true - end - else - notmatchpost[prev]=true - end - if replace then - while replacetail do - if seq[n][getchar(replacetail)] then - n=n-1 - if replacetail==replace or n<1 then - break - else - replacetail=getprev(replacetail) - end - else - notmatchreplace[prev]=true - if notmatchpost[prev] then - goto next - else - break - end - end - end - end - end - prev=getprev(prev) - elseif id==glue_code then - local sn=seq[n] - if (sn[32] and spaces[prev]) or sn[0xFFFC] then - n=n-1 - prev=getprev(prev) else - goto next + break end - elseif seq[n][0xFFFC] then - n=n-1 - prev=getprev(prev) - else - goto next end - else + end + if notmatchpre[last] then goto next end end + last=getnext(last) else goto next end @@ -24832,32 +24837,34 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s goto next end end - if s>l then - local current=last and getnext(last) - if not current and postreplace then - current=getnext(sweepnode) + end + if f>1 then + if startprev then + local prev=startprev + if prereplace and prev==checkdisc then + prev=getprev(sweepnode) end - if current then + if prev then local discfound - local n=l+1 - while n<=s do - if current then - local char,id=ischar(current,currentfont) + local n=f-1 + while n>=1 do + if prev then + local char,id=ischar(prev,currentfont) if char then if skiphash and skiphash[char] then skipped=true if trace_skips then show_skip(dataset,sequence,char,ck,classes[char]) end - current=getnext(current) + prev=getprev(prev) elseif seq[n][char] then - if n1 then + prev=getprev(prev) end - n=n+1 + n=n-1 elseif discfound then notmatchreplace[discfound]=true - if notmatchpre[discfound] then + if notmatchpost[discfound] then goto next else break @@ -24868,74 +24875,74 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s elseif char==false then if discfound then notmatchreplace[discfound]=true - if notmatchpre[discfound] then + if notmatchpost[discfound] then goto next - else - break end else goto next end + break elseif id==disc_code then diskseen=true - discfound=current - notmatchpre[current]=nil - notmatchpost[current]=true - notmatchreplace[current]=nil - local pre,post,replace=getdisc(current) - if pre then - local n=n - while pre do - if seq[n][getchar(pre)] then - n=n+1 - if n>s then - break + discfound=prev + notmatchpre[prev]=true + notmatchpost[prev]=nil + notmatchreplace[prev]=nil + local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true) + if pre~=start and post~=start and replace~=start then + if post then + local n=n + while posttail do + if seq[n][getchar(posttail)] then + n=n-1 + if posttail==post or n<1 then + break + else + posttail=getprev(posttail) + end else - pre=getnext(pre) + notmatchpost[prev]=true + break end - else - notmatchpre[current]=true - break end + if n>=1 then + notmatchpost[prev]=true + end + else + notmatchpost[prev]=true end - if n<=s then - notmatchpre[current]=true - end - else - notmatchpre[current]=true - end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>s then - break - else - replace=getnext(replace) - end - else - notmatchreplace[current]=true - if not notmatchpre[current] then - goto next + if replace then + while replacetail do + if seq[n][getchar(replacetail)] then + n=n-1 + if replacetail==replace or n<1 then + break + else + replacetail=getprev(replacetail) + end else - break + notmatchreplace[prev]=true + if notmatchpost[prev] then + goto next + else + break + end end end end - else end - current=getnext(current) + prev=getprev(prev) elseif id==glue_code then local sn=seq[n] - if (sn[32] and spaces[current]) or sn[0xFFFC] then - n=n+1 - current=getnext(current) + if (sn[32] and spaces[prev]) or sn[0xFFFC] then + n=n-1 + prev=getprev(prev) else goto next end elseif seq[n][0xFFFC] then - n=n+1 - current=getnext(current) + n=n-1 + prev=getprev(prev) else goto next end @@ -24946,6 +24953,123 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s else goto next end + else + goto next + end + end + if s>l then + local current=last and getnext(last) + if not current and postreplace then + current=getnext(sweepnode) + end + if current then + local discfound + local n=l+1 + while n<=s do + if current then + local char,id=ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + current=getnext(current) + elseif seq[n][char] then + if ns then + break + else + pre=getnext(pre) + end + else + notmatchpre[current]=true + break + end + end + if n<=s then + notmatchpre[current]=true + end + else + notmatchpre[current]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>s then + break + else + replace=getnext(replace) + end + else + notmatchreplace[current]=true + if not notmatchpre[current] then + goto next + else + break + end + end + end + else + end + current=getnext(current) + elseif id==glue_code then + local sn=seq[n] + if (sn[32] and spaces[current]) or sn[0xFFFC] then + n=n+1 + current=getnext(current) + else + goto next + end + elseif seq[n][0xFFFC] then + n=n+1 + current=getnext(current) + else + goto next + end + else + goto next + end + end + else + goto next end end if trace_contexts then @@ -29051,10 +29175,10 @@ local function addfeature(data,feature,specifications) subtype=lookup.type end else - lookups[k]={ false } + lookups[k]=false end else - lookups[k]={ false } + lookups[k]=false end end end diff --git a/tex/generic/context/luatex/luatex-fonts-mis.lua b/tex/generic/context/luatex/luatex-fonts-mis.lua new file mode 100644 index 000000000..02a5b60db --- /dev/null +++ b/tex/generic/context/luatex/luatex-fonts-mis.lua @@ -0,0 +1,32 @@ +if not modules then modules = { } end modules ['luatex-font-mis'] = { + version = 1.001, + comment = "companion to luatex-*.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if context then + texio.write_nl("fatal error: this module is not for context") + os.exit() +end + +local currentfont = font.current + +local hashes = fonts.hashes +local identifiers = hashes.identifiers or { } +local marks = hashes.marks or { } + +hashes.identifiers = identifiers +hashes.marks = marks + +table.setmetatableindex(marks,function(t,k) + if k == true then + return marks[currentfont()] + else + local resources = identifiers[k].resources or { } + local marks = resources.marks or { } + t[k] = marks + return marks + end +end) diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua index 93ead749e..ef3bb74dc 100644 --- a/tex/generic/context/luatex/luatex-fonts.lua +++ b/tex/generic/context/luatex/luatex-fonts.lua @@ -219,6 +219,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then -- --reload --force --simple option). loadmodule('font-ini.lua') + loadmodule('luatex-fonts-mis.lua') loadmodule('font-con.lua') loadmodule('luatex-fonts-enc.lua') -- will load font-age on demand loadmodule('font-cid.lua') -- cgit v1.2.3