diff options
author | Context Git Mirror Bot <phg42.2a@gmail.com> | 2014-12-03 19:15:05 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2014-12-03 19:15:05 +0100 |
commit | 606f30879286f37c0cf0ef42bc225e835d0d596d (patch) | |
tree | 969577a4f86a2d1e9c085bda80812ebb45c074cb /tex | |
parent | 8fa06810ed0fdc14d3c45eefff9a41800a84150b (diff) | |
download | context-606f30879286f37c0cf0ef42bc225e835d0d596d.tar.gz |
2014-12-03 18:28:00
Diffstat (limited to 'tex')
99 files changed, 4347 insertions, 3465 deletions
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 8b9cc0a93..afa71115e 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2014.11.26 21:43} +\newcontextversion{2014.12.03 18:26} %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/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex c11445498..debfb27f9 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 196f20623..b93063b1d 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -28,7 +28,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2014.11.26 21:43} +\edef\contextversion{2014.12.03 18:26} \edef\contextkind {beta} %D For those who want to use this: @@ -404,6 +404,7 @@ \loadmarkfile{typo-drp} \loadmarkfile{typo-fln} \loadmarkfile{typo-sus} +\loadmarkfile{typo-lig} \loadmkvifile{type-ini} \loadmarkfile{type-set} diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv index 6f9343587..5447288d7 100644 --- a/tex/context/base/core-env.mkiv +++ b/tex/context/base/core-env.mkiv @@ -390,13 +390,13 @@ \unexpanded\def\startsetups{} % to please dep checker \unexpanded\def\stopsetups {} % to please dep checker -\expanded % will become obsolete - {\def\expandafter\noexpand\csname\e!start\v!setups\endcsname - {\begingroup\noexpand\doifnextoptionalcselse - {\noexpand\dostartsetupsA\expandafter\noexpand\csname\e!stop\v!setups\endcsname} - {\noexpand\dostartsetupsB\expandafter\noexpand\csname\e!stop\v!setups\endcsname}}} - -\letvalue{\e!stop\v!setups}\relax +% \expanded % will become obsolete +% {\def\expandafter\noexpand\csname\e!start\v!setups\endcsname +% {\begingroup\noexpand\doifnextoptionalcselse +% {\noexpand\dostartsetupsA\expandafter\noexpand\csname\e!stop\v!setups\endcsname} +% {\noexpand\dostartsetupsB\expandafter\noexpand\csname\e!stop\v!setups\endcsname}}} +% +% \letvalue{\e!stop\v!setups}\relax \unexpanded\def\setups{\doifnextbgroupelse\syst_setups_a\syst_setups_b} % {..} or [..] \unexpanded\def\setup {\doifnextbgroupelse\syst_setups \syst_setups_c} % {..} or [..] diff --git a/tex/context/base/core-sys.mkiv b/tex/context/base/core-sys.mkiv index bd73ba08c..cb712fd7c 100644 --- a/tex/context/base/core-sys.mkiv +++ b/tex/context/base/core-sys.mkiv @@ -265,6 +265,17 @@ \unexpanded\def\highlight[#1]% {\typo_highlights_indeed{#1}} +\unexpanded\def\starthighlight[#1]% + {\begingroup + \def\currenthighlight{#1}% + \dostarttagged\t!highlight\currenthighlight + \usehighlightstyleandcolor\c!style\c!color + \dotaghighlight} + +\unexpanded\def\stophighlight + {\dostoptagged + \endgroup} + \let\directhighlight\typo_highlights_indeed \unexpanded\def\defineexpandable diff --git a/tex/context/base/font-hsh.lua b/tex/context/base/font-hsh.lua index 2be84165a..07acf2138 100644 --- a/tex/context/base/font-hsh.lua +++ b/tex/context/base/font-hsh.lua @@ -36,6 +36,7 @@ local lastmathids = hashes.lastmathids or allocate() local dynamics = hashes.dynamics or allocate() local unicodes = hashes.unicodes or allocate() local originals = hashes.originals or allocate() +local modes = hashes.modes or allocate() hashes.characters = characters hashes.descriptions = descriptions @@ -54,6 +55,7 @@ hashes.lastmathids = lastmathids hashes.dynamics = dynamics hashes.unicodes = unicodes hashes.originals = originals +hashes.modes = modes local nodepool = nodes.pool local dummyglyph = nodepool.register(nodepool.glyph()) @@ -291,6 +293,16 @@ setmetatableindex(originals, function(t,k) -- always a unicode end end) +setmetatableindex(modes, function(t,k) + if k == true then + return modes[currentfont()] + else + local mode = properties[k].mode or "base" + t[k] = mode + return mode + end +end) + function font.getfont(id) return identifiers[id] end diff --git a/tex/context/base/font-inj.lua b/tex/context/base/font-inj.lua new file mode 100644 index 000000000..4687e1ea7 --- /dev/null +++ b/tex/context/base/font-inj.lua @@ -0,0 +1,1269 @@ +if not modules then modules = { } end modules ['font-inj'] = { + version = 1.001, + comment = "companion to font-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- 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 +-- get/set that one for our purpose! + +if not nodes.properties then return end + +local next, rawget = next, rawget +local utfchar = utf.char + +local trace_injections = false trackers.register("fonts.injections", function(v) trace_injections = v end) + +local report_injections = logs.reporter("fonts","injections") + +report_injections("using experimental injector") + +local attributes, nodes, node = attributes, nodes, node + +fonts = fonts +local fontdata = fonts.hashes.identifiers + +nodes.injections = nodes.injections or { } +local injections = nodes.injections + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local kern_code = nodecodes.kern + +local nuts = nodes.nuts +local nodepool = nuts.pool + +local newkern = nodepool.kern + +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfield = nuts.getfield +local setfield = nuts.setfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar + +local traverse_id = nuts.traverse_id +local traverse = nuts.traverse +local insert_node_before = nuts.insert_before +local insert_node_after = nuts.insert_after +local find_tail = nuts.tail + +local properties = nodes.properties.data + +function injections.installnewkern(nk) + newkern = nk or newkern +end + +local nofregisteredkerns = 0 +local nofregisteredpairs = 0 +local nofregisteredmarks = 0 +local nofregisteredcursives = 0 +----- markanchors = { } -- one base can have more marks + +function injections.reset(n) + local p = rawget(properties,start) + if p and p.injections then + -- todo: decrement counters? tricky as we then need to change the nof* to not increment + -- when we change a property + p.injections = nil -- should we keep the liga index? + end +end + +function injections.setligaindex(n,index) + local p = rawget(properties,n) + if p then + p = p.injections + end + if p then + p.ligaindex = index + else + properties[n] = { + injections = { + ligaindex = index + } + } + end +end + +function injections.getligaindex(n,default) + local p = rawget(properties,n) + if p then + p = p.injections + if p then + return p.ligaindex or default + end + end + return default +end + +function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) -- hm: nuts or nodes + local dx = factor*(exit[1]-entry[1]) + local dy = -factor*(exit[2]-entry[2]) + local ws, wn = tfmstart.width, tfmnext.width + nofregisteredcursives = nofregisteredcursives + 1 + if rlmode < 0 then + dx = -(dx + wn) + else + dx = dx - ws + end + -- + local p = rawget(properties,start) + if p then + p = p.injections + end + if p then + p.cursiveanchor = true + else + properties[start] = { + injections = { + cursiveanchor = true, + }, + } + end + local p = rawget(properties,nxt) + if p then + p = p.injections + end + if p then + p.cursivex = dx + p.cursivey = dy + else + properties[nxt] = { + injections = { + cursivex = dx, + cursivey = dy, + }, + } + end + return dx, dy, nofregisteredcursives +end + +function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) -- r2lflag & tfmchr not used + local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4] + if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then -- okay? + local yoffset = y - h + local leftkern = x + local rightkern = w - x + if leftkern ~= 0 or rightkern ~= 0 or yoffset ~= 0 then + nofregisteredpairs = nofregisteredpairs + 1 + if rlmode and rlmode < 0 then + leftkern, rightkern = rightkern, leftkern + end + local p = rawget(properties,current) + if p then + p = p.injections + end + if p then + if leftkern ~= 0 or rightkern ~= 0 then + p.leftkern = (p.leftkern or 0) + leftkern + p.rightkern = (p.rightkern or 0) + rightkern + end + if yoffset ~= 0 then + p.yoffset = (p.yoffset or 0) + yoffset + end + elseif leftkern ~= 0 or rightkern ~= 0 then + properties[current] = { + injections = { + leftkern = leftkern, + rightkern = rightkern, + yoffset = yoffset, + }, + } + else + properties[current] = { + injections = { + yoffset = yoffset, + }, + } + end + return x, y, w, h, nofregisteredpairs + end + end + return x, y, w, h -- no bound +end + +-- this needs checking for rl < 0 but it is unlikely that a r2l script +-- uses kernclasses between glyphs so we're probably safe (KE has a +-- problematic font where marks interfere with rl < 0 in the previous +-- case) + +function injections.setkern(current,factor,rlmode,x,injection) + local dx = factor * x + if dx ~= 0 then + nofregisteredkerns = nofregisteredkerns + 1 + local p = rawget(properties,current) + if not injection then + injection = "injections" + end + if p then + p = p[injection] + end + if p then + p.leftkern = dx + (p.leftkern or 0) + else + properties[current] = { + [injection] = { + leftkern = dx, + }, + } + end + return dx, nofregisteredkerns + else + return 0, 0 + end +end + +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) -- ba=baseanchor, ma=markanchor + local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) + nofregisteredmarks = nofregisteredmarks + 1 + -- markanchors[nofregisteredmarks] = base + if rlmode >= 0 then + dx = tfmbase.width - dx -- see later commented ox + end + local p = rawget(properties,start) + if p then + p = p.injections + end + if p then + p.markx = dx + p.marky = dy + p.markdir = rlmode or 0 + p.markbase = nofregisteredmarks + p.markbasenode = base + else + properties[start] = { + injections = { + markx = dx, + marky = dy, + markdir = rlmode or 0, + markbase = nofregisteredmarks, + markbasenode = base, + }, + } + end + return dx, dy, nofregisteredmarks +end + +local function dir(n) + return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" +end + +local function trace(head) + report_injections("begin run: %s kerns, %s pairs, %s marks and %s cursives registered", + nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives) + for n in traverse_id(glyph_code,head) do + if getsubtype(n) < 256 then + local char = getchar(n) + report_injections("font %s, char %U, glyph %c",getfont(n),char,char) + local p = rawget(properties,n) + if p then + p = p.injections + end + if p then + local leftkern = p.leftkern or 0 + local rightkern = p.rightkern or 0 + local yoffset = p.yoffset or 0 + local markx = p.markx or 0 + local marky = p.marky or 0 + local markdir = p.markdir or 0 + local markbase = p.markbase or 0 -- will be markbasenode + local cursivex = p.cursivex or 0 + local cursivey = p.cursivey or 0 + local ligaindex = p.ligaindex or 0 + if rightkern ~= 0 or yoffset ~= 0 then + report_injections(" pair: lx %p, rx %p, dy %p",leftkern,rightkern,yoffset) + elseif leftkern ~= 0 then + report_injections(" kern: dx %p",leftkern) + end + if markx ~= 0 or marky ~= 0 or markbase ~= 0 then + report_injections(" mark: dx %p, dy %p, dir %s, base %s",markx,marky,markdir,markbase ~= 0 and "yes" or "no") + end + if cursivex ~= 0 or cursivey ~= 0 then + report_injections(" curs: dx %p, dy %p",cursivex,cursivey) + end + if ligaindex ~= 0 then + report_injections(" liga: index %i",ligaindex) + end + end + end + end + report_injections("end run") +end + +local function show_result(head) + local current = head + local skipping = false + while current do + local id = getid(current) + if id == glyph_code then + report_injections("char: %C, width %p, xoffset %p, yoffset %p", + getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) + skipping = false + elseif id == kern_code then + report_injections("kern: %p",getfield(current,"kern")) + skipping = false + elseif not skipping then + report_injections() + skipping = true + end + current = getnext(current) + end +end + +-- function injections.handler(head,where,keep) -- optimize for n=1 +-- if nofregisteredmarks > 0 or nofregisteredcursives > 0 then +-- head = tonut(head) +-- if trace_injections then +-- trace(head) +-- end +-- -- in the future variant we will not copy items but refs to tables +-- local glyphs, nofglyphs = { }, 0 +-- local marks, nofmarks = { }, 0 +-- -- maybe merge loops +-- if nofregisteredpairs > 0 then +-- local nf, tm = nil, nil +-- for n in traverse_id(glyph_code,head) do -- only needed for relevant fonts +-- if getsubtype(n) < 256 then +-- local pn = rawget(properties,n) +-- if pn then +-- pn = pn.injections +-- end +-- local f = getfont(n) +-- if f ~= nf then +-- nf = f +-- tm = fontdata[nf].resources.marks -- other hash in ctx +-- end +-- if tm and tm[getchar(n)] then +-- nofmarks = nofmarks + 1 +-- marks[nofmarks] = n +-- else +-- nofglyphs = nofglyphs + 1 +-- glyphs[nofglyphs] = n +-- end +-- -- yoffsets can influence curs steps +-- if pn then +-- local yoffset = pn.yoffset +-- if yoffset and yoffset ~= 0 then +-- setfield(n,"yoffset",yoffset) +-- end +-- end +-- end +-- end +-- else +-- local nf, tm = nil, nil +-- for n in traverse_id(glyph_code,head) do +-- if getsubtype(n) < 256 then +-- -- local pn = rawget(properties,n) +-- -- if pn then +-- -- pn = pn.injections +-- -- end +-- local f = getfont(n) +-- if f ~= nf then +-- nf = f +-- tm = fontdata[nf].resources.marks -- other hash in ctx +-- end +-- if tm and tm[getchar(n)] then +-- nofmarks = nofmarks + 1 +-- marks[nofmarks] = n +-- else +-- nofglyphs = nofglyphs + 1 +-- glyphs[nofglyphs] = n +-- end +-- end +-- end +-- end +-- if nofglyphs > 0 then +-- if nofregisteredcursives > 0 then +-- local cursiveanchor, lastanchor = nil, nil +-- local minc, maxc, last = 0, 0, nil +-- for i=1,nofglyphs do +-- local n = glyphs[i] +-- local pn = rawget(properties,n) +-- if pn then +-- pn = pn.injections +-- end +-- if pn then +-- local cursivex = pn.cursivex +-- if cursivex then +-- if cursiveanchor then +-- if cursivex ~= 0 then +-- pn.leftkern = (pn.leftkern or 0) + cursivex +-- end +-- if lastanchor then +-- if maxc == 0 then +-- minc = lastanchor +-- end +-- maxc = lastanchor +-- properties[cursiveanchor].cursivedy = pn.cursivey +-- end +-- last = n +-- else +-- maxc = 0 +-- end +-- elseif maxc > 0 then +-- local ny = getfield(n,"yoffset") +-- for i=maxc,minc,-1 do +-- local ti = glyphs[i] +-- ny = ny + properties[ti].cursivedy +-- setfield(ti,"yoffset",ny) -- why not add ? +-- end +-- maxc = 0 +-- end +-- if pn.cursiveanchor then +-- cursiveanchor = n +-- lastanchor = i +-- else +-- cursiveanchor = nil +-- lastanchor = nil +-- if maxc > 0 then +-- local ny = getfield(n,"yoffset") +-- for i=maxc,minc,-1 do +-- local ti = glyphs[i] +-- ny = ny + properties[ti].cursivedy +-- setfield(ti,"yoffset",ny) -- why not add ? +-- end +-- maxc = 0 +-- end +-- end +-- elseif maxc > 0 then +-- local ny = getfield(n,"yoffset") +-- for i=maxc,minc,-1 do +-- local ti = glyphs[i] +-- ny = ny + properties[ti].cursivedy +-- setfield(ti,"yoffset",getfield(ti,"yoffset") + ny) -- ? +-- end +-- maxc = 0 +-- cursiveanchor = nil +-- lastanchor = nil +-- end +-- -- if maxc > 0 and not cursiveanchor then +-- -- local ny = getfield(n,"yoffset") +-- -- for i=maxc,minc,-1 do +-- -- local ti = glyphs[i] +-- -- ny = ny + properties[ti].cursivedy +-- -- setfield(ti,"yoffset",ny) -- why not add ? +-- -- end +-- -- maxc = 0 +-- -- end +-- end +-- if last and maxc > 0 then +-- local ny = getfield(last,"yoffset") +-- for i=maxc,minc,-1 do +-- local ti = glyphs[i] +-- ny = ny + properties[ti].cursivedy +-- setfield(ti,"yoffset",ny) -- why not add ? +-- end +-- end +-- end +-- if nofregisteredmarks > 0 then +-- for i=1,nofmarks do +-- local n = marks[i] +-- local pn = rawget(properties,n) +-- if pn then +-- pn = pn.injections +-- end +-- if pn then +-- -- local markbase = pn.markbase +-- -- if markbase then +-- -- local p = markanchors[markbase] +-- local p = pn.markbasenode +-- if p then +-- local px = getfield(p,"xoffset") +-- local ox = 0 +-- local pp = rawget(properties,p) +-- local rightkern = pp and pp.rightkern +-- if rightkern then -- x and w ~= 0 +-- if pn.markdir < 0 then +-- -- kern(w-x) glyph(p) kern(x) mark(n) +-- ox = px - pn.markx - rightkern +-- -- report_injections("r2l case 1: %p",ox) +-- else +-- -- kern(x) glyph(p) kern(w-x) mark(n) +-- -- ox = px - getfield(p,"width") + pn.markx - pp.leftkern +-- ox = px - pn.markx - pp.leftkern +-- -- report_injections("l2r case 1: %p",ox) +-- end +-- else +-- -- we need to deal with fonts that have marks with width +-- -- if pn.markdir < 0 then +-- -- ox = px - pn.markx +-- -- -- report_injections("r2l case 3: %p",ox) +-- -- else +-- -- -- ox = px - getfield(p,"width") + pn.markx +-- ox = px - pn.markx +-- -- report_injections("l2r case 3: %p",ox) +-- -- end +-- local wn = getfield(n,"width") -- in arial marks have widths +-- if wn ~= 0 then +-- -- bad: we should center +-- -- insert_node_before(head,n,newkern(-wn/2)) +-- -- insert_node_after(head,n,newkern(-wn/2)) +-- pn.leftkern = -wn/2 +-- pn.rightkern = -wn/2 +-- -- wx[n] = { 0, -wn/2, 0, -wn } +-- end +-- -- so far +-- end +-- setfield(n,"xoffset",ox) +-- -- +-- local py = getfield(p,"yoffset") +-- local oy = 0 +-- if marks[p] then +-- oy = py + pn.marky +-- else +-- oy = getfield(n,"yoffset") + py + pn.marky +-- end +-- setfield(n,"yoffset",oy) +-- else +-- -- normally this can't happen (only when in trace mode which is a special case anyway) +-- -- report_injections("missing mark anchor %i",pn.markbase or 0) +-- end +-- -- end +-- end +-- end +-- end +-- for i=1,#glyphs do +-- local n = glyphs[i] +-- local pn = rawget(properties,n) +-- if pn then +-- pn = pn.injections +-- end +-- if pn then +-- local leftkern = pn.leftkern +-- if leftkern ~= 0 then +-- insert_node_before(head,n,newkern(leftkern)) -- type 0/2 +-- end +-- local rightkern = pn.rightkern +-- if rightkern ~= 0 then +-- insert_node_after(head,n,newkern(rightkern)) -- type 0/2 +-- end +-- end +-- end +-- end +-- if not keep then +-- nofregisteredkerns = 0 +-- nofregisteredpairs = 0 +-- nofregisteredmarks = 0 +-- nofregisteredcursives = 0 +-- end +-- return tonode(head), true +-- elseif nofregisteredpairs > 0 then +-- head = tonut(head) +-- if trace_injections then +-- trace(head) +-- end +-- for n in traverse_id(glyph_code,head) do +-- if getsubtype(n) < 256 then +-- local pn = rawget(properties,n) +-- if pn then +-- pn = pn.injections +-- end +-- if pn then +-- local yoffset = pn.yoffset +-- if yoffset and yoffset ~= 0 then +-- setfield(n,"yoffset",yoffset) +-- end +-- local leftkern = pn.leftkern +-- if leftkern and leftkern ~= 0 then +-- insert_node_before(head,n,newkern(leftkern)) +-- end +-- local rightkern = pn.rightkern +-- if rightkern and rightkern ~= 0 then +-- insert_node_after(head,n,newkern(rightkern)) +-- else +-- -- simple (e.g. kernclass kerns) +-- end +-- end +-- end +-- end +-- if not keep then +-- nofregisteredpairs = 0 +-- nofregisteredkerns = 0 +-- end +-- return tonode(head), true +-- elseif nofregisteredkerns > 0 then +-- head = tonut(head) +-- if trace_injections then +-- trace(head) +-- end +-- for n in traverse_id(glyph_code,head) do +-- if getsubtype(n) < 256 then +-- local pn = rawget(properties,n) +-- if pn then +-- pn = pn.injections +-- end +-- if pn then +-- local leftkern = pn.leftkern +-- if leftkern ~= 0 then +-- insert_node_before(head,n,newkern(leftkern)) +-- end +-- end +-- end +-- end +-- if not keep then +-- nofregisteredkerns = 0 +-- end +-- return tonode(head), true +-- else +-- return head, false +-- end +-- end + +-------- todo: store pre/post/replace state, see todo + +-- in the future variant we will not copy items but refs to tables + +-- we could also check for marks here but maybe not all are registered (needs checking) + +local function collect_glyphs_1(head) + local glyphs, nofglyphs = { }, 0 + local marks, nofmarks = { }, 0 + local nf, tm = nil, nil + for n in traverse_id(glyph_code,head) do -- only needed for relevant fonts + if getsubtype(n) < 256 then + local pn = rawget(properties,n) + if pn then + pn = pn.injections + end + local f = getfont(n) + if f ~= nf then + nf = f + tm = fontdata[nf].resources.marks -- other hash in ctx + end + if tm and tm[getchar(n)] then + nofmarks = nofmarks + 1 + marks[nofmarks] = n + else + nofglyphs = nofglyphs + 1 + glyphs[nofglyphs] = n + end + -- yoffsets can influence curs steps + if pn then + local yoffset = pn.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + end + end + end + return glyphs, nofglyphs, marks, nofmarks +end + +-- local function run(n) +-- local pn = rawget(properties,n) +-- if pn then +-- pn = pn.injections +-- end +-- local f = getfont(n) +-- if f ~= nf then +-- nf = f +-- tm = fontdata[nf].resources.marks -- other hash in ctx +-- end +-- if tm and tm[getchar(n)] then -- also in disc? +-- nofmarks = nofmarks + 1 +-- marks[nofmarks] = n +-- else +-- nofglyphs = nofglyphs + 1 +-- glyphs[nofglyphs] = n +-- end +-- -- yoffsets can influence curs steps +-- if pn then +-- local yoffset = pn.yoffset +-- if yoffset and yoffset ~= 0 then +-- setfield(n,"yoffset",yoffset) +-- end +-- end +-- end +-- local n = head +-- while n do +-- if getsubtype(n) < 256 then +-- local id = getid(n) +-- if id == glyph_code then +-- run(n) +-- elseif id == disc_code then +-- local d = getfield(n,"pre") if d then for n in traverse(d) do run(d) end end +-- local d = getfield(n,"post") if d then for n in traverse(d) do run(d) end end +-- local d = getfield(n,"replace") if d then for n in traverse(d) do run(d) end end +-- end +-- end +-- n = getnext(n) +-- end + +local function collect_glyphs_2(head) + local glyphs, nofglyphs = { }, 0 + local marks, nofmarks = { }, 0 + local nf, tm = nil, nil + for n in traverse_id(glyph_code,head) do + if getsubtype(n) < 256 then + local f = getfont(n) + if f ~= nf then + nf = f + tm = fontdata[nf].resources.marks -- other hash in ctx + end + if tm and tm[getchar(n)] then + nofmarks = nofmarks + 1 + marks[nofmarks] = n + else + nofglyphs = nofglyphs + 1 + glyphs[nofglyphs] = n + end + end + end + return glyphs, nofglyphs, marks, nofmarks +end + +-- local function run(n) +-- local f = getfont(n) +-- if f ~= nf then +-- nf = f +-- tm = fontdata[nf].resources.marks -- other hash in ctx +-- end +-- if tm and tm[getchar(n)] then +-- nofmarks = nofmarks + 1 +-- marks[nofmarks] = n +-- else +-- nofglyphs = nofglyphs + 1 +-- glyphs[nofglyphs] = n +-- end +-- end +-- -- +-- local n = head +-- while n do +-- if getsubtype(n) < 256 then +-- local id = getid(n) +-- if id == glyph_code then +-- run(n) +-- elseif id == disc_code then +-- local d = getfield(n,"pre") if d then for n in traverse(d) do run(d) end end +-- local d = getfield(n,"post") if d then for n in traverse(d) do run(d) end end +-- local d = getfield(n,"replace") if d then for n in traverse(d) do run(d) end end +-- end +-- end +-- n = getnext(n) +-- end + +local function inject_marks(marks,nofmarks) + for i=1,nofmarks do + local n = marks[i] + local pn = rawget(properties,n) + if pn then + pn = pn.injections + end + if pn then + -- local markbase = pn.markbase + -- if markbase then + -- local p = markanchors[markbase] + local p = pn.markbasenode + if p then + local px = getfield(p,"xoffset") + local ox = 0 + local pp = rawget(properties,p) + local rightkern = pp and pp.rightkern + if rightkern then -- x and w ~= 0 + if pn.markdir < 0 then + -- kern(w-x) glyph(p) kern(x) mark(n) + ox = px - pn.markx - rightkern + -- report_injections("r2l case 1: %p",ox) + else + -- kern(x) glyph(p) kern(w-x) mark(n) + -- ox = px - getfield(p,"width") + pn.markx - pp.leftkern + ox = px - pn.markx - pp.leftkern + -- report_injections("l2r case 1: %p",ox) + end + else + -- we need to deal with fonts that have marks with width + -- if pn.markdir < 0 then + -- ox = px - pn.markx + -- -- report_injections("r2l case 3: %p",ox) + -- else + -- -- ox = px - getfield(p,"width") + pn.markx + ox = px - pn.markx + -- report_injections("l2r case 3: %p",ox) + -- end + local wn = getfield(n,"width") -- in arial marks have widths + if wn ~= 0 then + -- bad: we should center + -- insert_node_before(head,n,newkern(-wn/2)) + -- insert_node_after(head,n,newkern(-wn/2)) + pn.leftkern = -wn/2 + pn.rightkern = -wn/2 + -- wx[n] = { 0, -wn/2, 0, -wn } + end + -- so far + end + setfield(n,"xoffset",ox) + -- + local py = getfield(p,"yoffset") + local oy = 0 + if marks[p] then + oy = py + pn.marky + else + oy = getfield(n,"yoffset") + py + pn.marky + end + setfield(n,"yoffset",oy) + else + -- normally this can't happen (only when in trace mode which is a special case anyway) + -- report_injections("missing mark anchor %i",pn.markbase or 0) + end + -- end + end + end +end + +local function inject_cursives(glyphs,nofglyphs) + local cursiveanchor, lastanchor = nil, nil + local minc, maxc, last = 0, 0, nil + for i=1,nofglyphs do + local n = glyphs[i] + local pn = rawget(properties,n) + if pn then + pn = pn.injections + end + if pn then + local cursivex = pn.cursivex + if cursivex then + if cursiveanchor then + if cursivex ~= 0 then + pn.leftkern = (pn.leftkern or 0) + cursivex + end + if lastanchor then + if maxc == 0 then + minc = lastanchor + end + maxc = lastanchor + properties[cursiveanchor].cursivedy = pn.cursivey + end + last = n + else + maxc = 0 + end + elseif maxc > 0 then + local ny = getfield(n,"yoffset") + for i=maxc,minc,-1 do + local ti = glyphs[i] + ny = ny + properties[ti].cursivedy + setfield(ti,"yoffset",ny) -- why not add ? + end + maxc = 0 + end + if pn.cursiveanchor then + cursiveanchor = n + lastanchor = i + else + cursiveanchor = nil + lastanchor = nil + if maxc > 0 then + local ny = getfield(n,"yoffset") + for i=maxc,minc,-1 do + local ti = glyphs[i] + ny = ny + properties[ti].cursivedy + setfield(ti,"yoffset",ny) -- why not add ? + end + maxc = 0 + end + end + elseif maxc > 0 then + local ny = getfield(n,"yoffset") + for i=maxc,minc,-1 do + local ti = glyphs[i] + ny = ny + properties[ti].cursivedy + setfield(ti,"yoffset",getfield(ti,"yoffset") + ny) -- ? + end + maxc = 0 + cursiveanchor = nil + lastanchor = nil + end + -- if maxc > 0 and not cursiveanchor then + -- local ny = getfield(n,"yoffset") + -- for i=maxc,minc,-1 do + -- local ti = glyphs[i] + -- ny = ny + properties[ti].cursivedy + -- setfield(ti,"yoffset",ny) -- why not add ? + -- end + -- maxc = 0 + -- end + end + if last and maxc > 0 then + local ny = getfield(last,"yoffset") + for i=maxc,minc,-1 do + local ti = glyphs[i] + ny = ny + properties[ti].cursivedy + setfield(ti,"yoffset",ny) -- why not add ? + end + end +end + +local function inject_kerns(glyphs,nofglyphs) + -- todo: pre/post/replace + for i=1,#glyphs do + local n = glyphs[i] + local pn = rawget(properties,n) + if pn then + pn = pn.injections + end + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + insert_node_before(head,n,newkern(leftkern)) -- type 0/2 + end + local rightkern = pn.rightkern + if rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) -- type 0/2 + end + end + end +end + +local function inject_everything(head,where,keep) + head = tonut(head) + if trace_injections then + trace(head) + end + local glyphs, nofglyphs, marks, nofmarks + if nofregisteredpairs > 0 then + glyphs, nofglyphs, marks, nofmarks = collect_glyphs_1(head) + else + glyphs, nofglyphs, marks, nofmarks = collect_glyphs_2(head) + end + if nofglyphs > 0 then + if nofregisteredcursives > 0 then + inject_cursives(glyphs,nofglyphs) + end + if nofregisteredmarks > 0 then + inject_marks(marks,nofmarks) + end + inject_kerns(glyphs,nofglyphs) + end + if not keep then + nofregisteredkerns = 0 + nofregisteredpairs = 0 + nofregisteredmarks = 0 + nofregisteredcursives = 0 + end + return tonode(head), true +end + +local function inject_kerns_only(head,where,keep) + head = tonut(head) + if trace_injections then + trace(head) + end + local n = head + local p = nil + while n do + local id = getid(n) + if id == glyph_code then + local pn = rawget(properties,n) + if pn then + if p then + local d = getfield(p,"post") + if d then + local pn = pn.postinjections + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + local t = find_tail(d) + insert_node_after(d,t,newkern(leftkern)) + end + end + end + local d = getfield(p,"replace") + if d then + local pn = pn.replaceinjections + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + local t = find_tail(d) + insert_node_after(d,t,newkern(leftkern)) + end + end + else + local pn = pn.injections + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + setfield(p,"replace",newkern(leftkern)) + end + end + end + else + local pn = pn.injections + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + head = insert_node_before(head,n,newkern(leftkern)) + end + end + end + end + p = nil + elseif id == disc_code then + local d = getfield(n,"pre") + if d then + local h = d + for n in traverse(d) do + local pn = rawget(properties,n) + if pn then + pn = pn.preinjections + end + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + end + end + if h ~= d then + setfield(n,"pre",h) + end + end + local d = getfield(n,"post") + if d then + local h = d + for n in traverse(d) do + local pn = rawget(properties,n) + if pn then + pn = pn.postinjections + end + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + end + end + if h ~= d then + setfield(n,"post",h) + end + end + local d = getfield(n,"replace") + if d then + local h = d + for n in traverse(d) do + local pn = rawget(properties,n) + if pn then + pn = pn.replaceinjections + end + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + end + end + if h ~= d then + setfield(n,"replace",h) + end + end + p = n + else + p = nil + end + n = getnext(n) + end + -- + if not keep then + nofregisteredkerns = 0 + end + return tonode(head), true +end + +local function inject_pairs_only(head,where,keep) + head = tonut(head) + if trace_injections then + trace(head) + end + -- + local n = head + local p = nil + while n do + local id = getid(n) + if id == glyph_code then + local pn = rawget(properties,n) + if pn then + if p then + local d = getfield(p,"post") + if d then + local pn = pn.postinjections + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + local t = find_tail(d) + insert_node_after(d,t,newkern(leftkern)) + end + -- local rightkern = pn.rightkern + -- if rightkern and rightkern ~= 0 then + -- insert_node_after(head,n,newkern(rightkern)) + -- n = getnext(n) -- to be checked + -- end + end + end + local d = getfield(p,"replace") + if d then + local pn = pn.replaceinjections + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + local t = find_tail(d) + insert_node_after(d,t,newkern(leftkern)) + end + -- local rightkern = pn.rightkern + -- if rightkern and rightkern ~= 0 then + -- insert_node_after(head,n,newkern(rightkern)) + -- n = getnext(n) -- to be checked + -- end + end + else + local pn = pn.injections + if pn then + local leftkern = pn.leftkern + if leftkern ~= 0 then + setfield(p,"replace",newkern(leftkern)) + end + -- local rightkern = pn.rightkern + -- if rightkern and rightkern ~= 0 then + -- insert_node_after(head,n,newkern(rightkern)) + -- n = getnext(n) -- to be checked + -- end + end + end + else + -- this is the most common case + local pn = pn.injections + if pn then + local yoffset = pn.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + local leftkern = pn.leftkern + if leftkern ~= 0 then + insert_node_before(head,n,newkern(leftkern)) + end + local rightkern = pn.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) + n = getnext(n) -- to be checked + end + end + end + end + p = nil + elseif id == disc_code then + local d = getfield(n,"pre") + if d then + local h = d + for n in traverse(d) do + local pn = rawget(properties,n) + if pn then + pn = pn.preinjections + end + if pn then + local yoffset = pn.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + local leftkern = pn.leftkern + if leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + local rightkern = pn.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) + n = getnext(n) -- to be checked + end + end + end + if h ~= d then + setfield(n,"pre",h) + end + end + local d = getfield(n,"post") + if d then + local h = d + for n in traverse(d) do + local pn = rawget(properties,n) + if pn then + pn = pn.postinjections + end + if pn then + local yoffset = pn.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + local leftkern = pn.leftkern + if leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + local rightkern = pn.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) + n = getnext(n) -- to be checked + end + end + end + if h ~= d then + setfield(n,"post",h) + end + end + local d = getfield(n,"replace") + if d then + local h = d + for n in traverse(d) do + local pn = rawget(properties,n) + if pn then + pn = pn.replaceinjections + end + if pn then + local yoffset = pn.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + local leftkern = pn.leftkern + if leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + local rightkern = pn.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) + n = getnext(n) -- to be checked + end + end + end + if h ~= d then + setfield(n,"replace",h) + end + end + p = n + else + p = nil + end + n = getnext(n) + end + -- + if not keep then + nofregisteredpairs = 0 + nofregisteredkerns = 0 + end + return tonode(head), true +end + +function injections.handler(head,where,keep) -- optimize for n=1 ? + if nofregisteredmarks > 0 or nofregisteredcursives > 0 then + return inject_everything(head,where,keep) + elseif nofregisteredpairs > 0 then + return inject_pairs_only(head,where,keep) + elseif nofregisteredkerns > 0 then + return inject_kerns_only(head,where,keep) + else + return head, false + end +end diff --git a/tex/context/base/font-lib.mkvi b/tex/context/base/font-lib.mkvi index 01a142307..be1e305b5 100644 --- a/tex/context/base/font-lib.mkvi +++ b/tex/context/base/font-lib.mkvi @@ -39,12 +39,13 @@ \registerctxluafile{font-otf}{1.001} % otf main \registerctxluafile{font-otb}{1.001} % otf main base -\doiffileelse{font-inj.lua} - {\registerctxluafile{font-inj}{1.001}} % new method (for the moment only local) - {\registerctxluafile{node-inj}{1.001}} % old method +% \doiffileelse{font-inj.lua} +% {\registerctxluafile{font-inj}{1.001}} % new method (for the moment only local) +% {\registerctxluafile{node-inj}{1.001}} % old method -%registerctxluafile{font-ota}{1.001} % otf analyzers -\registerctxluafile{font-otx}{1.001} % otf analyzers +\registerctxluafile{font-inj}{1.001} % the old method (lacks some features) + +\registerctxluafile{font-ota}{1.001} % otf analyzers \registerctxluafile{font-otn}{1.001} % otf main node \registerctxluafile{font-otd}{1.001} % otf dynamics (does an overload) \registerctxluafile{font-otp}{1.001} % otf pack diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua index c090927f5..dc0469e39 100644 --- a/tex/context/base/font-ota.lua +++ b/tex/context/base/font-ota.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['font-ota'] = { +if not modules then modules = { } end modules ['font-otx'] = { version = 1.001, comment = "companion to font-otf.lua (analysing)", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -6,10 +6,7 @@ if not modules then modules = { } end modules ['font-ota'] = { license = "see context related readme files" } --- this might become scrp-*.lua - --- [attr] : getprop or getattr --- [attr] : setprop or setattr +-- context only local type = type @@ -29,21 +26,35 @@ local methods = allocate() analyzers.initializers = initializers analyzers.methods = methods -analyzers.useunicodemarks = false +---------.useunicodemarks = false local a_state = attributes.private('state') +local nuts = nodes.nuts +local tonut = nuts.tonut + +local getfield = nuts.getfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getprop = nuts.getprop +local setprop = nuts.setprop +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar + +local traverse_id = nuts.traverse_id +local traverse_node_list = nuts.traverse +local end_of_math = nuts.end_of_math + local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc local math_code = nodecodes.math -local traverse_id = node.traverse_id -local traverse_node_list = node.traverse -local end_of_math = node.end_of_math - local fontdata = fonts.hashes.identifiers local categories = characters and characters.categories or { } -- sorry, only in context +local chardata = characters and characters.data local otffeatures = fonts.constructors.newfeatures("otf") local registerotffeature = otffeatures.register @@ -90,63 +101,68 @@ local features = { pstf = s_pstf, } -analyzers.states = states -analyzers.features = features +analyzers.states = states +analyzers.features = features +analyzers.useunicodemarks = false -- todo: analyzers per script/lang, cross font, so we need an font id hash -> script -- e.g. latin -> hyphenate, arab -> 1/2/3 analyze -- its own namespace -function analyzers.setstate(head,font) +function analyzers.setstate(head,font) -- we can skip math local useunicodemarks = analyzers.useunicodemarks local tfmdata = fontdata[font] local descriptions = tfmdata.descriptions local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean + current = tonut(current) while current do - local id = current.id - if id == glyph_code and current.font == font then + local id = getid(current) + if id == glyph_code and getfont(current) == font then done = true - local char = current.char + local char = getchar(current) local d = descriptions[char] if d then - if d.class == "mark" or (useunicodemarks and categories[char] == "mn") then + if d.class == "mark" then + done = true + setprop(current,a_state,s_mark) + elseif useunicodemarks and categories[char] == "mn" then done = true - current[a_state] = s_mark + setprop(current,a_state,s_mark) elseif n == 0 then first, last, n = current, current, 1 - current[a_state] = s_init + setprop(current,a_state,s_init) else last, n = current, n+1 - current[a_state] = s_medi + setprop(current,a_state,s_medi) end else -- finish if first and first == last then - last[a_state] = s_isol + setprop(last,a_state,s_isol) elseif last then - last[a_state] = s_fina + setprop(last,a_state,s_fina) end first, last, n = nil, nil, 0 end elseif id == disc_code then -- always in the middle - current[a_state] = s_medi + setprop(current,a_state,s_medi) last = current else -- finish if first and first == last then - last[a_state] = s_isol + setprop(last,a_state,s_isol) elseif last then - last[a_state] = s_fina + setprop(last,a_state,s_fina) end first, last, n = nil, nil, 0 if id == math_code then current = end_of_math(current) end end - current = current.next + current = getnext(current) end if first and first == last then - last[a_state] = s_isol + setprop(last,a_state,s_isol) elseif last then - last[a_state] = s_fina + setprop(last,a_state,s_fina) end return head, done end @@ -204,238 +220,192 @@ registerotffeature { methods.latn = analyzers.setstate --- This info eventually can go into char-def and we will have a state --- table for generic then (unicode recognized all states but in practice --- only has only --- --- isolated : isol --- final : isol_fina --- medial : isol_fina_medi_init --- --- so in practice, without analyzer it's rather useless info which is --- why having it in char-def makes only sense for special purposes (like) --- like tracing cq. visualizing. - -local tatweel = 0x0640 -local zwnj = 0x200C -local zwj = 0x200D - -local isolated = { -- isol - [0x0600] = true, [0x0601] = true, [0x0602] = true, [0x0603] = true, - [0x0604] = true, - [0x0608] = true, [0x060B] = true, [0x0621] = true, [0x0674] = true, - [0x06DD] = true, - -- mandaic - [0x0856] = true, [0x0858] = true, [0x0857] = true, - -- n'ko - [0x07FA] = true, - -- also here: - [zwnj] = true, - -- 7 - [0x08AD] = true, -} - -local final = { -- isol_fina - [0x0622] = true, [0x0623] = true, [0x0624] = true, [0x0625] = true, - [0x0627] = true, [0x0629] = true, [0x062F] = true, [0x0630] = true, - [0x0631] = true, [0x0632] = true, [0x0648] = true, [0x0671] = true, - [0x0672] = true, [0x0673] = true, [0x0675] = true, [0x0676] = true, - [0x0677] = true, [0x0688] = true, [0x0689] = true, [0x068A] = true, - [0x068B] = true, [0x068C] = true, [0x068D] = true, [0x068E] = true, - [0x068F] = true, [0x0690] = true, [0x0691] = true, [0x0692] = true, - [0x0693] = true, [0x0694] = true, [0x0695] = true, [0x0696] = true, - [0x0697] = true, [0x0698] = true, [0x0699] = true, [0x06C0] = true, - [0x06C3] = true, [0x06C4] = true, [0x06C5] = true, [0x06C6] = true, - [0x06C7] = true, [0x06C8] = true, [0x06C9] = true, [0x06CA] = true, - [0x06CB] = true, [0x06CD] = true, [0x06CF] = true, [0x06D2] = true, - [0x06D3] = true, [0x06D5] = true, [0x06EE] = true, [0x06EF] = true, - [0x0759] = true, [0x075A] = true, [0x075B] = true, [0x076B] = true, - [0x076C] = true, [0x0771] = true, [0x0773] = true, [0x0774] = true, - [0x0778] = true, [0x0779] = true, - [0x08AA] = true, [0x08AB] = true, [0x08AC] = true, - [0xFEF5] = true, [0xFEF7] = true, [0xFEF9] = true, [0xFEFB] = true, - -- syriac - [0x0710] = true, [0x0715] = true, [0x0716] = true, [0x0717] = true, - [0x0718] = true, [0x0719] = true, [0x0728] = true, [0x072A] = true, - [0x072C] = true, [0x071E] = true, - [0x072F] = true, [0x074D] = true, - -- mandaic - [0x0840] = true, [0x0849] = true, [0x0854] = true, [0x0846] = true, - [0x084F] = true, - -- 7 - [0x08AE] = true, [0x08B1] = true, [0x08B2] = true, -} - -local medial = { -- isol_fina_medi_init - [0x0626] = true, [0x0628] = true, [0x062A] = true, [0x062B] = true, - [0x062C] = true, [0x062D] = true, [0x062E] = true, [0x0633] = true, - [0x0634] = true, [0x0635] = true, [0x0636] = true, [0x0637] = true, - [0x0638] = true, [0x0639] = true, [0x063A] = true, [0x063B] = true, - [0x063C] = true, [0x063D] = true, [0x063E] = true, [0x063F] = true, - [0x0641] = true, [0x0642] = true, [0x0643] = true, - [0x0644] = true, [0x0645] = true, [0x0646] = true, [0x0647] = true, - [0x0649] = true, [0x064A] = true, [0x066E] = true, [0x066F] = true, - [0x0678] = true, [0x0679] = true, [0x067A] = true, [0x067B] = true, - [0x067C] = true, [0x067D] = true, [0x067E] = true, [0x067F] = true, - [0x0680] = true, [0x0681] = true, [0x0682] = true, [0x0683] = true, - [0x0684] = true, [0x0685] = true, [0x0686] = true, [0x0687] = true, - [0x069A] = true, [0x069B] = true, [0x069C] = true, [0x069D] = true, - [0x069E] = true, [0x069F] = true, [0x06A0] = true, [0x06A1] = true, - [0x06A2] = true, [0x06A3] = true, [0x06A4] = true, [0x06A5] = true, - [0x06A6] = true, [0x06A7] = true, [0x06A8] = true, [0x06A9] = true, - [0x06AA] = true, [0x06AB] = true, [0x06AC] = true, [0x06AD] = true, - [0x06AE] = true, [0x06AF] = true, [0x06B0] = true, [0x06B1] = true, - [0x06B2] = true, [0x06B3] = true, [0x06B4] = true, [0x06B5] = true, - [0x06B6] = true, [0x06B7] = true, [0x06B8] = true, [0x06B9] = true, - [0x06BA] = true, [0x06BB] = true, [0x06BC] = true, [0x06BD] = true, - [0x06BE] = true, [0x06BF] = true, [0x06C1] = true, [0x06C2] = true, - [0x06CC] = true, [0x06CE] = true, [0x06D0] = true, [0x06D1] = true, - [0x06FA] = true, [0x06FB] = true, [0x06FC] = true, [0x06FF] = true, - [0x0750] = true, [0x0751] = true, [0x0752] = true, [0x0753] = true, - [0x0754] = true, [0x0755] = true, [0x0756] = true, [0x0757] = true, - [0x0758] = true, [0x075C] = true, [0x075D] = true, [0x075E] = true, - [0x075F] = true, [0x0760] = true, [0x0761] = true, [0x0762] = true, - [0x0763] = true, [0x0764] = true, [0x0765] = true, [0x0766] = true, - [0x0767] = true, [0x0768] = true, [0x0769] = true, [0x076A] = true, - [0x076D] = true, [0x076E] = true, [0x076F] = true, [0x0770] = true, - [0x0772] = true, [0x0775] = true, [0x0776] = true, [0x0777] = true, - [0x077A] = true, [0x077B] = true, [0x077C] = true, [0x077D] = true, - [0x077E] = true, [0x077F] = true, - [0x08A0] = true, [0x08A2] = true, [0x08A4] = true, [0x08A5] = true, - [0x08A6] = true, [0x0620] = true, [0x08A8] = true, [0x08A9] = true, - [0x08A7] = true, [0x08A3] = true, - -- syriac - [0x0712] = true, [0x0713] = true, [0x0714] = true, [0x071A] = true, - [0x071B] = true, [0x071C] = true, [0x071D] = true, [0x071F] = true, - [0x0720] = true, [0x0721] = true, [0x0722] = true, [0x0723] = true, - [0x0724] = true, [0x0725] = true, [0x0726] = true, [0x0727] = true, - [0x0729] = true, [0x072B] = true, [0x072D] = true, [0x072E] = true, - [0x074E] = true, [0x074F] = true, - -- mandaic - [0x0841] = true, [0x0842] = true, [0x0843] = true, [0x0844] = true, - [0x0845] = true, [0x0847] = true, [0x0848] = true, [0x0855] = true, - [0x0851] = true, [0x084E] = true, [0x084D] = true, [0x084A] = true, - [0x084B] = true, [0x084C] = true, [0x0850] = true, [0x0852] = true, - [0x0853] = true, - -- n'ko - [0x07D7] = true, [0x07E8] = true, [0x07D9] = true, [0x07EA] = true, - [0x07CA] = true, [0x07DB] = true, [0x07CC] = true, [0x07DD] = true, - [0x07CE] = true, [0x07DF] = true, [0x07D4] = true, [0x07E5] = true, - [0x07E9] = true, [0x07E7] = true, [0x07E3] = true, [0x07E2] = true, - [0x07E0] = true, [0x07E1] = true, [0x07DE] = true, [0x07DC] = true, - [0x07D1] = true, [0x07DA] = true, [0x07D8] = true, [0x07D6] = true, - [0x07D2] = true, [0x07D0] = true, [0x07CF] = true, [0x07CD] = true, - [0x07CB] = true, [0x07D3] = true, [0x07E4] = true, [0x07D5] = true, - [0x07E6] = true, - -- also here: - [tatweel]= true, [zwj] = true, - -- 7 - [0x08A1] = true, [0x08AF] = true, [0x08B0] = true, -} - local arab_warned = { } --- todo: gref - local function warning(current,what) - local char = current.char + local char = getchar(current) if not arab_warned[char] then log.report("analyze","arab: character %C has no %a class",char,what) arab_warned[char] = true end end --- potential optimization: local medial_final = table.merged(medial,final) +local mappers = { + l = s_init, -- left + d = s_medi, -- double + c = s_medi, -- joiner + r = s_fina, -- right + u = s_isol, -- nonjoiner +} -local function finish(first,last) - if last then - if first == last then - local fc = first.char - if medial[fc] or final[fc] then - first[a_state] = s_isol - else - warning(first,"isol") - first[a_state] = s_error +local classifiers = { } -- we can also use this trick for devanagari + +local first_arabic, last_arabic = characters.blockrange("arabic") +local first_syriac, last_syriac = characters.blockrange("syriac") +local first_mandiac, last_mandiac = characters.blockrange("mandiac") +local first_nko, last_nko = characters.blockrange("nko") + +table.setmetatableindex(classifiers,function(t,k) + local c = chardata[k] + local v = false + if c then + local arabic = c.arabic + if arabic then + v = mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + -- error + v = false end - else - local lc = last.char - if medial[lc] or final[lc] then - -- if laststate == 1 or laststate == 2 or laststate == 4 then - last[a_state] = s_fina + elseif k >= first_arabic and k <= last_arabic or k >= first_syriac and k <= last_syriac or + k >= first_mandiac and k <= last_mandiac or k >= first_nko and k <= last_nko then + if categories[k] == "mn" then + v = s_mark else - warning(last,"fina") - last[a_state] = s_error + v = s_rest end - end - first, last = nil, nil - elseif first then - -- first and last are either both set so we never com here - local fc = first.char - if medial[fc] or final[fc] then - first[a_state] = s_isol else - warning(first,"isol") - first[a_state] = s_error end - first = nil end - return first, last -end + t[k] = v + return v +end) function methods.arab(head,font,attr) - local useunicodemarks = analyzers.useunicodemarks - local tfmdata = fontdata[font] - local marks = tfmdata.resources.marks - local first, last, current, done = nil, nil, head, false + local first, last = nil, nil + local c_first, c_last = nil, nil + local current, done = head, false + current = tonut(current) while current do - local id = current.id - if id == glyph_code and current.font == font and current.subtype<256 and not current[a_state] then + local id = getid(current) + if id == glyph_code and getfont(current) == font and getsubtype(current)<256 and not getprop(current,a_state) then done = true - local char = current.char - if marks[char] or (useunicodemarks and categories[char] == "mn") then - current[a_state] = s_mark - elseif isolated[char] then -- can be zwj or zwnj too - first, last = finish(first,last) - current[a_state] = s_isol - first, last = nil, nil - elseif not first then - if medial[char] then - current[a_state] = s_init - first, last = first or current, current - elseif final[char] then - current[a_state] = s_isol + local char = getchar(current) + local classifier = classifiers[char] + if not classifier then + if last then + if c_last == s_medi or c_last == s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + first, last = nil, nil + elseif first then + if c_first == s_medi or c_first == s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first = nil + end + elseif classifier == s_mark then + setprop(current,a_state,s_mark) + elseif classifier == s_isol then + if last then + if c_last == s_medi or c_last == s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end first, last = nil, nil - else -- no arab - first, last = finish(first,last) + elseif first then + if c_first == s_medi or c_first == s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first = nil end - elseif medial[char] then - first, last = first or current, current - current[a_state] = s_medi - elseif final[char] then - if not last[a_state] == s_init then - -- tricky, we need to check what last may be ! - last[a_state] = s_medi + setprop(current,a_state,s_isol) + elseif classifier == s_medi then + if first then + last = current + c_last = classifier + setprop(current,a_state,s_medi) + else + setprop(current,a_state,s_init) + first = current + c_first = classifier + end + elseif classifier == s_fina then + if last then + if getprop(last,a_state) ~= s_init then + setprop(last,a_state,s_medi) + end + setprop(current,a_state,s_fina) + first, last = nil, nil + elseif first then + -- if getprop(first,a_state) ~= s_init then + -- -- needs checking + -- setprop(first,a_state,s_medi) + -- end + setprop(current,a_state,s_fina) + first = nil + else + setprop(current,a_state,s_isol) + end + else -- classifier == s_rest + setprop(current,a_state,s_rest) + if last then + if c_last == s_medi or c_last == s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + first, last = nil, nil + elseif first then + if c_first == s_medi or c_first == s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first = nil end - current[a_state] = s_fina - first, last = nil, nil - elseif char >= 0x0600 and char <= 0x06FF then -- needs checking - current[a_state] = s_rest - first, last = finish(first,last) - else -- no - first, last = finish(first,last) end else - if first or last then - first, last = finish(first,last) + if last then + if c_last == s_medi or c_last == s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + first, last = nil, nil + elseif first then + if c_first == s_medi or c_first == s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first = nil end - if id == math_code then + if id == math_code then -- a bit duplicate as we test for glyphs twice current = end_of_math(current) end end - current = current.next + current = getnext(current) end - if first or last then - finish(first,last) + if last then + if c_last == s_medi or c_last == s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + elseif first then + if c_first == s_medi or c_first == s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end end return head, done end diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 32dc820d3..e23a1366c 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -129,16 +129,14 @@ results in different tables.</p> -- Todo: make plugin feature that operates on char/glyphnode arrays -local concat, insert, remove = table.concat, table.insert, table.remove -local gmatch, gsub, find, match, lower, strip = string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip -local type, next, tonumber, tostring = type, next, tonumber, tostring -local lpegmatch = lpeg.match +local type, next, tonumber = type, next, tonumber local random = math.random local formatters = string.formatters local logs, trackers, nodes, attributes = logs, trackers, nodes, attributes -local registertracker = trackers.register +local registertracker = trackers.register +local registerdirective = directives.register local fonts = fonts local otf = fonts.handlers.otf @@ -160,6 +158,11 @@ local trace_steps = false registertracker("otf.steps", function(v local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end) local trace_directions = false registertracker("otf.directions", function(v) trace_directions = v end) +local kernruns = true registerdirective("otf.kernruns", function(v) kernruns = v end) +local discruns = true registerdirective("otf.discruns", function(v) discruns = v end) +local compruns = true registerdirective("otf.compruns", function(v) compruns = v end) +local zwnjruns = true registerdirective("otf.zwnjruns", function(v) zwnjruns = v end) + local report_direct = logs.reporter("fonts","otf direct") local report_subchain = logs.reporter("fonts","otf subchain") local report_chain = logs.reporter("fonts","otf chain") @@ -194,12 +197,14 @@ local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar +local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local delete_node = nuts.delete local copy_node = nuts.copy local find_node_tail = nuts.tail local flush_node_list = nuts.flush_list local end_of_math = nuts.end_of_math +local traverse_nodes = nuts.traverse local setmetatableindex = table.setmetatableindex @@ -416,9 +421,36 @@ local function getcomponentindex(start) end end --- eventually we will do positioning in an other way (needs addional w/h/d fields) +local a_noligature = attributes.private("noligature") +local prehyphenchar = languages and languages.prehyphenchar +local posthyphenchar = languages and languages.posthyphenchar + +if not prehyphenchar then + + local newlang = lang.new + local getpre = lang.prehyphenchar + local getpost = lang.posthyphenchar + + prehyphenchar = function(l) local l = newlang(l) return l and getpre (l) or -1 end + posthyphenchar = function(l) local l = newlang(l) return l and getpost(l) or -1 end + +end local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) -- brr head + + -- not here: + + -- for n in nuts.traverse(glyph_code,start) do + -- if getid(n) == glyph_code and getchar(n) == zwnj then + -- return head, start + -- end + -- if n == stop then break end + -- end + + if getattr(start,a_noligature) == 1 then + -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first) + return head, start + end if start == stop and getchar(start) == char then resetinjection(start) setfield(start,"char",char) @@ -426,6 +458,7 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun end local prev = getprev(start) local next = getnext(stop) + local comp = start setfield(start,"prev",nil) setfield(stop,"next",nil) local base = copy_glyph(start) @@ -435,7 +468,7 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun resetinjection(base) setfield(base,"char",char) setfield(base,"subtype",ligature_code) - setfield(base,"components",start) -- start can have components + setfield(base,"components",comp) -- start can have components .. do we need to flush? if prev then setfield(prev,"next",base) end @@ -483,6 +516,56 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun end start = getnext(start) end + elseif not kernruns or not discruns or not compruns then + -- disabled + elseif getsubtype(discfound) == discretionary_code then + -- maybe some day + else + -- forget about marks .. probably no scripts that hyphenate and have marks + -- todo: check for special disc nodes (with pre's and so) + -- todo: use insert_before + local prev = getfield(discfound,"prev") + local next = getfield(discfound,"next") + if prev and next then + setfield(next,"prev",nil) + setfield(prev,"next",nil) + local l = getfield(comp,"lang") + local p = prehyphenchar(l) + if p and p > 0 then + local c = copy_node(comp) + local t = find_node_tail(comp) + setfield(c,"char",p) + comp = insert_node_after(comp,t,c) + end + local p = posthyphenchar(l) + if p and p > 0 then + local c = copy_node(next) + setfield(c,"char",p) + next = insert_node_before(next,next,c) + end + setfield(discfound,"pre",comp) + setfield(discfound,"post",next) + -- + local prev = getfield(base,"prev") + local next = getfield(base,"next") + -- + -- remove_node(prev,prev) + -- insert_node_after(prev,prev,discfound) + -- + setfield(prev,"next",discfound) + setfield(next,"prev",discfound) + setfield(discfound,"next",next) + setfield(discfound,"prev",prev) + -- + setfield(base,"next",nil) + setfield(base,"prev",nil) + setfield(base,"components",nil) + setfield(discfound,"replace",base) + setfield(discfound,"subtype",discretionary_code) + base = next + else + -- weird disc .. maybe some day + end end return head, base end @@ -587,7 +670,7 @@ function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence) end function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) - local s, stop, discfound = getnext(start), nil, false + local s, stop = getnext(start), nil local startchar = getchar(start) if marks[startchar] then while s do @@ -615,25 +698,26 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) else head, start = markstoligature(kind,lookupname,head,start,stop,lig) end - return head, start, true + return head, start, true, false else -- ok, goto next lookup end end else - local skipmark = sequence.flags[1] + local skipmark = sequence.flags[1] + local discfound = false while s do local id = getid(s) - if id == glyph_code and getsubtype(s)<256 then - if getfont(s) == currentfont then + if id == glyph_code and getsubtype(s)<256 then -- not needed + if getfont(s) == currentfont then -- also not needed only when mark local char = getchar(s) if skipmark and marks[char] then s = getnext(s) else - local lg = ligature[char] + local lg = ligature[char] -- can there be multiple in a row? maybe in a bad font if lg then - stop = s ligature = lg + stop = s s = getnext(s) else break @@ -643,7 +727,8 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) break end elseif id == disc_code then - discfound = true + discfound = s + stop = s s = getnext(s) else break @@ -667,12 +752,12 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig)) end end - return head, start, true + return head, start, true, discfound else -- weird but happens end end - return head, start, false + return head, start, false, discfound end --[[ldx-- @@ -920,16 +1005,16 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) end end -function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) +function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence,injection) local startchar = getchar(start) - local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) + local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,injection) -- ,characters[startchar]) if trace_kerns then logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) end return head, start, false end -function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) +function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence,lookuphash,i,injection) -- todo: kerns in disc nodes: pre, post, replace -> loop over disc too -- todo: kerns in components of ligatures local snext = getnext(start) @@ -953,14 +1038,14 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) local a, b = krn[2], krn[3] if a and #a > 0 then local startchar = getchar(start) - local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) + local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,injection) -- characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then local startchar = getchar(start) - local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) + local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,injection) -- characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end @@ -980,7 +1065,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) end done = true elseif krn ~= 0 then - local k = setkern(snext,factor,rlmode,krn) + local k = setkern(snext,factor,rlmode,krn,injection) if trace_kerns then logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) end @@ -1107,7 +1192,7 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo local current = start local subtables = currentlookup.subtables if #subtables > 1 then - logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) + logwarning("todo: check if we need to loop over the replacements: % t",subtables) end while current do if getid(current) == glyph_code then @@ -1263,8 +1348,12 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, while s do local id = getid(s) if id == disc_code then + discfound = s +if s == stop then + break -- okay? +else s = getnext(s) - discfound = true +end else local schar = getchar(s) if skipmark and marks[schar] then -- marks @@ -1297,7 +1386,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end end head, start = toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) - return head, start, true, nofreplacements + return head, start, true, nofreplacements, discfound elseif trace_bugs then if start == stop then logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) @@ -1307,7 +1396,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end end end - return head, start, false, 0 + return head, start, false, 0, false end chainmores.gsub_ligature = chainprocs.gsub_ligature @@ -1579,7 +1668,7 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo if kerns then kerns = kerns[startchar] -- needed ? if kerns then - local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) + local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns) -- ,characters[startchar]) if trace_kerns then logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) end @@ -1619,14 +1708,14 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local a, b = krn[2], krn[3] if a and #a > 0 then local startchar = getchar(start) - local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) + local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a) -- ,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then local startchar = getchar(start) - local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) + local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b) -- ,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end @@ -1680,11 +1769,11 @@ local function show_skip(kind,chainname,char,ck,class) end end -local quit_on_no_replacement = true +local quit_on_no_replacement = true -- maybe per font +local quit_on_discretionary = false -- only for experiments -directives.register("otf.chain.quitonnoreplacement",function(value) -- maybe per font - quit_on_no_replacement = value -end) +registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement = value end) +registerdirective("otf.chain.quitondiscretionary",function(value) quit_on_discretionary = value end) local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash) -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6] @@ -1755,7 +1844,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq break end elseif id == disc_code then - last = getnext(last) + if quit_on_discretionary then + match = false + break + else + last = getnext(last) + end else match = false break @@ -1801,7 +1895,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq break end elseif id == disc_code then - -- skip 'm + if quit_on_discretionary then + match = false + break + else + -- skip 'm + end elseif seq[n][32] then n = n -1 else @@ -1810,7 +1909,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end prev = getprev(prev) elseif seq[n][32] then -- somewhat special, as zapfino can have many preceding spaces - n = n -1 + n = n - 1 else match = false break @@ -1862,7 +1961,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq break end elseif id == disc_code then - -- skip 'm + if quit_on_discretionary then + match = false + break + else + -- skip 'm + end elseif seq[n][32] then -- brrr n = n + 1 else @@ -2149,6 +2253,124 @@ end -- -- the action -- end +-- assumptions: +-- +-- * languages that use complex disc nodes + +-- optimization comes later ... + +local function kernrun(disc,run) -- we can assume that prev and next are glyphs + if kernruns then + -- + local prev = getprev(disc) -- todo, keep these in the main loop + local next = getnext(disc) -- todo, keep these in the main loop + -- + local pre = getfield(disc,"pre") + if not pre then + -- go on + elseif prev then + setfield(pre,"prev",prev) + setfield(prev,"next",pre) + run(prev,"preinjections") + setfield(pre,"prev",nil) + setfield(prev,"next",disc) + else + run(pre,"preinjections") + end + -- + local post = getfield(disc,"post") + if not post then + -- go on + elseif next then + local tail = find_node_tail(post) + setfield(tail,"next",next) + setfield(next,"prev",tail) + run(post,"postinjections",tail) + setfield(tail,"next",nil) + setfield(next,"prev",disc) + else + run(post,"postinjections") + end + -- + local replace = getfield(disc,"replace") + if not replace then + -- this should be already done by discfound + elseif prev and next then + local tail = find_node_tail(replace) + setfield(replace,"prev",prev) + setfield(prev,"next",replace) + setfield(tail,"next",next) + setfield(next,"prev",tail) + run(prev,"replaceinjections",tail) + setfield(replace,"prev",nil) + setfield(prev,"next",disc) + setfield(tail,"next",nil) + setfield(next,"prev",disc) + elseif prev then + setfield(replace,"prev",prev) + setfield(prev,"next",replace) + run(prev,"replaceinjections") + setfield(replace,"prev",nil) + setfield(prev,"next",disc) + elseif next then + local tail = find_node_tail(replace) + setfield(tail,"next",next) + setfield(next,"prev",tail) + run(replace,"replaceinjections",tail) + setfield(tail,"next",nil) + setfield(next,"prev",disc) + else + run(replace,"replaceinjections") + end + -- + end +end + +local function comprun(disc,run) + if compruns then + -- + local pre = getfield(disc,"pre") + if pre then + local new = run(pre) + if new ~= pre then + setfield(disc,"pre",new) + end + end + -- + local post = getfield(disc,"post") + if post then + local new = run(post) + if new ~= post then + setfield(disc,"post",new) + end + end + -- + local replace = getfield(disc,"replace") + if replace then + local new = run(replace) + if new ~= replace then + setfield(disc,"replace",new) + end + end + -- + end +end + +local function discrun(disc,run) + local next = getnext(disc) + if discruns and next then + local prev = getprev(disc) + if prev then + setfield(prev,"next",next) + -- setfield(next,"prev",prev) + run(disc) + setfield(prev,"next",disc) + -- setfield(next,"prev",disc) + end + end + return next +end + local function featuresprocessor(head,font,attr) local lookuphash = lookuphashes[font] -- we can also check sequences here @@ -2193,21 +2415,25 @@ local function featuresprocessor(head,font,attr) -- todo: retain prev + -- We don't goto the next node of a disc node is created so that we can then treat + -- the pre, post and replace. It's abit of a hack but works out ok for most cases. + for s=1,#datasets do - local dataset = datasets[s] - featurevalue = dataset[1] -- todo: pass to function instead of using a global - - local sequence = dataset[5] -- sequences[s] -- also dataset[5] - local rlparmode = 0 - local topstack = 0 - local success = false - local attribute = dataset[2] - local chain = dataset[3] -- sequence.chain or 0 - local typ = sequence.type - local subtables = sequence.subtables + local dataset = datasets[s] + featurevalue = dataset[1] -- todo: pass to function instead of using a global + local attribute = dataset[2] + local chain = dataset[3] -- sequence.chain or 0 + local kind = dataset[4] + local sequence = dataset[5] -- sequences[s] -- also dataset[5] + local rlparmode = 0 + local topstack = 0 + local success = false + local typ = sequence.type + local gpossing = typ == "gpos_single" or typ == "gpos_pair" + local subtables = sequence.subtables + local handler = handlers[typ] if chain < 0 then -- this is a limited case, no special treatments like 'init' etc - local handler = handlers[typ] -- we need to get rid of this slide! probably no longer needed in latest luatex local start = find_node_tail(head) -- slow (we can store tail because there's always a skip at the end): todo while start do @@ -2227,7 +2453,8 @@ local function featuresprocessor(head,font,attr) if lookupcache then local lookupmatch = lookupcache[getchar(start)] if lookupmatch then - head, start, success = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + -- todo: disc? + head, start, success = handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,i) if success then break end @@ -2248,7 +2475,6 @@ local function featuresprocessor(head,font,attr) end end else - local handler = handlers[typ] local ns = #subtables local start = head -- local ? rlmode = 0 -- to be checked ? @@ -2259,8 +2485,7 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) else - local function subrun(start) - -- mostly for gsub, gpos would demand a more clever approach + local function c_run(start) local head = start local done = false while start do @@ -2277,7 +2502,7 @@ local function featuresprocessor(head,font,attr) if lookupmatch then -- sequence kan weg local ok - head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) + head, start, ok = handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,1) if ok then done = true end @@ -2292,43 +2517,64 @@ local function featuresprocessor(head,font,attr) end if done then success = true - return head end + return head end - local function kerndisc(disc) -- we can assume that prev and next are glyphs - local prev = getprev(disc) - local next = getnext(disc) - if prev and next then - setfield(prev,"next",next) - -- setfield(next,"prev",prev) - local a = getattr(prev,0) - if a then - a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) - else - a = not attribute or getprop(prev,a_state) == attribute + local function d_run(prev) -- we can assume that prev and next are glyphs + local a = getattr(prev,0) + if a then + a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) + else + a = not attribute or getprop(prev,a_state) == attribute + end + if a then + local lookupmatch = lookupcache[getchar(prev)] + if lookupmatch then + -- sequence kan weg + local h, d, ok = handler(head,prev,kind,lookupname,lookupmatch,sequence,lookuphash,1) + if ok then + done = true + success = true + end end - if a then - local lookupmatch = lookupcache[getchar(prev)] - if lookupmatch then - -- sequence kan weg - local h, d, ok = handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) - if ok then - done = true - success = true + end + end + + local function k_run(sub,injection,last) + local a = getattr(sub,0) + if a then + a = (a == attr) and (not attribute or getprop(sub,a_state) == attribute) + else + a = not attribute or getprop(sub,a_state) == attribute + end + if a then + -- sequence kan weg + for n in traverse_nodes(sub) do -- only gpos + local id = getid(n) + if id == glyph_code then + local lookupmatch = lookupcache[getchar(n)] + if lookupmatch then + local h, d, ok = handler(sub,n,kind,lookupname,lookupmatch,sequence,lookuphash,1,injection) + if ok then + done = true + success = true + end end + else + -- message + end + if n == last then + break end end - setfield(prev,"next",disc) - -- setfield(next,"prev",disc) end - return next end while start do local id = getid(start) if id == glyph_code then - if getfont(start) == font and getsubtype(start) < 256 then + if getfont(start) == font and getsubtype(start) < 256 then -- why a 256 test ... local a = getattr(start,0) if a then a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) @@ -2336,14 +2582,19 @@ local function featuresprocessor(head,font,attr) a = not attribute or getprop(start,a_state) == attribute end if a then - local lookupmatch = lookupcache[getchar(start)] + local char = getchar(start) + local lookupmatch = lookupcache[char] if lookupmatch then -- sequence kan weg local ok - head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) + head, start, ok = handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,1) if ok then success = true + elseif gpossing and zwnjruns and char == zwnj then + discrun(start,d_run) end + elseif gpossing and zwnjruns and char == zwnj then + discrun(start,d_run) end if start then start = getnext(start) end else @@ -2353,25 +2604,15 @@ local function featuresprocessor(head,font,attr) start = getnext(start) end elseif id == disc_code then - -- mostly for gsub - if getsubtype(start) == discretionary_code then - local pre = getfield(start,"pre") - if pre then - local new = subrun(pre) - if new then setfield(start,"pre",new) end - end - local post = getfield(start,"post") - if post then - local new = subrun(post) - if new then setfield(start,"post",new) end - end - local replace = getfield(start,"replace") - if replace then - local new = subrun(replace) - if new then setfield(start,"replace",new) end + local discretionary = getsubtype(start) == discretionary_code + if gpossing then + if discretionary then + kernrun(start,k_run) + else + discrun(start,d_run) end -elseif typ == "gpos_single" or typ == "gpos_pair" then - kerndisc(start) + elseif discretionary then + comprun(start,c_run) end start = getnext(start) elseif id == whatsit_code then -- will be function @@ -2418,10 +2659,10 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then end end end + else - local function subrun(start) - -- mostly for gsub, gpos would demand a more clever approach + local function c_run(start) local head = start local done = false while start do @@ -2442,7 +2683,7 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then if lookupmatch then -- we could move all code inline but that makes things even more unreadable local ok - head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + head, start, ok = handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,i) if ok then done = true break @@ -2465,45 +2706,75 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then end if done then success = true - return head end + return head end - local function kerndisc(disc) -- we can assume that prev and next are glyphs - local prev = getprev(disc) - local next = getnext(disc) - if prev and next then - setfield(prev,"next",next) - -- setfield(next,"prev",prev) - local a = getattr(prev,0) - if a then - a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) - else - a = not attribute or getprop(prev,a_state) == attribute + local function d_run(prev) + local a = getattr(prev,0) + if a then + a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) + else + a = not attribute or getprop(prev,a_state) == attribute + end + if a then + local char = getchar(prev) + for i=1,ns do + local lookupname = subtables[i] + local lookupcache = lookuphash[lookupname] + if lookupcache then + local lookupmatch = lookupcache[char] + if lookupmatch then + -- we could move all code inline but that makes things even more unreadable + local h, d, ok = handler(head,prev,kind,lookupname,lookupmatch,sequence,lookuphash,i) + if ok then + done = true + break + end + end + else + report_missing_cache(typ,lookupname) + end end - if a then - for i=1,ns do - local lookupname = subtables[i] - local lookupcache = lookuphash[lookupname] - if lookupcache then - local lookupmatch = lookupcache[getchar(prev)] - if lookupmatch then - -- we could move all code inline but that makes things even more unreadable - local h, d, ok = handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) - if ok then - done = true - break + end + end + + local function k_run(sub,injection,last) + local a = getattr(sub,0) + if a then + a = (a == attr) and (not attribute or getprop(sub,a_state) == attribute) + else + a = not attribute or getprop(sub,a_state) == attribute + end + if a then + for n in traverse_nodes(sub) do -- only gpos + local id = getid(n) + if id == glyph_code then + local char = getchar(n) + for i=1,ns do + local lookupname = subtables[i] + local lookupcache = lookuphash[lookupname] + if lookupcache then + local lookupmatch = lookupcache[char] + if lookupmatch then + local h, d, ok = handler(head,n,kind,lookupname,lookupmatch,sequence,lookuphash,i,injection) + if ok then + done = true + break + end end + else + report_missing_cache(typ,lookupname) end - else - report_missing_cache(typ,lookupname) end + else + -- message + end + if n == last then + break end end - setfield(prev,"next",disc) - -- setfield(next,"prev",disc) end - return next end while start do @@ -2521,18 +2792,23 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then local lookupname = subtables[i] local lookupcache = lookuphash[lookupname] if lookupcache then - local lookupmatch = lookupcache[getchar(start)] + local char = getchar(start) + local lookupmatch = lookupcache[char] if lookupmatch then -- we could move all code inline but that makes things even more unreadable local ok - head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + head, start, ok = handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,i) if ok then success = true break elseif not start then -- don't ask why ... shouldn't happen break + elseif gpossing and zwnjruns and char == zwnj then + discrun(start,d_run) end + elseif gpossing and zwnjruns and char == zwnj then + discrun(start,d_run) end else report_missing_cache(typ,lookupname) @@ -2546,25 +2822,15 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then start = getnext(start) end elseif id == disc_code then - -- mostly for gsub - if getsubtype(start) == discretionary_code then - local pre = getfield(start,"pre") - if pre then - local new = subrun(pre) - if new then setfield(start,"pre",new) end - end - local post = getfield(start,"post") - if post then - local new = subrun(post) - if new then setfield(start,"post",new) end - end - local replace = getfield(start,"replace") - if replace then - local new = subrun(replace) - if new then setfield(start,"replace",new) end + local discretionary = getsubtype(start) == discretionary_code + if gpossing then + if discretionary then + kernrun(start,k_run) + else + discrun(start,d_run) end -elseif typ == "gpos_single" or typ == "gpos_pair" then - kerndisc(start) + elseif discretionary then + comprun(start,c_run) end start = getnext(start) elseif id == whatsit_code then diff --git a/tex/context/base/font-otx.lua b/tex/context/base/font-otx.lua deleted file mode 100644 index dc0469e39..000000000 --- a/tex/context/base/font-otx.lua +++ /dev/null @@ -1,419 +0,0 @@ -if not modules then modules = { } end modules ['font-otx'] = { - version = 1.001, - comment = "companion to font-otf.lua (analysing)", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- context only - -local type = type - -if not trackers then trackers = { register = function() end } end - ------ trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end) - -local fonts, nodes, node = fonts, nodes, node - -local allocate = utilities.storage.allocate - -local otf = fonts.handlers.otf - -local analyzers = fonts.analyzers -local initializers = allocate() -local methods = allocate() - -analyzers.initializers = initializers -analyzers.methods = methods ----------.useunicodemarks = false - -local a_state = attributes.private('state') - -local nuts = nodes.nuts -local tonut = nuts.tonut - -local getfield = nuts.getfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getprop = nuts.getprop -local setprop = nuts.setprop -local getfont = nuts.getfont -local getsubtype = nuts.getsubtype -local getchar = nuts.getchar - -local traverse_id = nuts.traverse_id -local traverse_node_list = nuts.traverse -local end_of_math = nuts.end_of_math - -local nodecodes = nodes.nodecodes -local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc -local math_code = nodecodes.math - -local fontdata = fonts.hashes.identifiers -local categories = characters and characters.categories or { } -- sorry, only in context -local chardata = characters and characters.data - -local otffeatures = fonts.constructors.newfeatures("otf") -local registerotffeature = otffeatures.register - ---[[ldx-- -<p>Analyzers run per script and/or language and are needed in order to -process features right.</p> ---ldx]]-- - --- never use these numbers directly - -local s_init = 1 local s_rphf = 7 -local s_medi = 2 local s_half = 8 -local s_fina = 3 local s_pref = 9 -local s_isol = 4 local s_blwf = 10 -local s_mark = 5 local s_pstf = 11 -local s_rest = 6 - -local states = { - init = s_init, - medi = s_medi, - fina = s_fina, - isol = s_isol, - mark = s_mark, - rest = s_rest, - rphf = s_rphf, - half = s_half, - pref = s_pref, - blwf = s_blwf, - pstf = s_pstf, -} - -local features = { - init = s_init, - medi = s_medi, - fina = s_fina, - isol = s_isol, - -- mark = s_mark, - -- rest = s_rest, - rphf = s_rphf, - half = s_half, - pref = s_pref, - blwf = s_blwf, - pstf = s_pstf, -} - -analyzers.states = states -analyzers.features = features -analyzers.useunicodemarks = false - --- todo: analyzers per script/lang, cross font, so we need an font id hash -> script --- e.g. latin -> hyphenate, arab -> 1/2/3 analyze -- its own namespace - -function analyzers.setstate(head,font) -- we can skip math - local useunicodemarks = analyzers.useunicodemarks - local tfmdata = fontdata[font] - local descriptions = tfmdata.descriptions - local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean - current = tonut(current) - while current do - local id = getid(current) - if id == glyph_code and getfont(current) == font then - done = true - local char = getchar(current) - local d = descriptions[char] - if d then - if d.class == "mark" then - done = true - setprop(current,a_state,s_mark) - elseif useunicodemarks and categories[char] == "mn" then - done = true - setprop(current,a_state,s_mark) - elseif n == 0 then - first, last, n = current, current, 1 - setprop(current,a_state,s_init) - else - last, n = current, n+1 - setprop(current,a_state,s_medi) - end - else -- finish - if first and first == last then - setprop(last,a_state,s_isol) - elseif last then - setprop(last,a_state,s_fina) - end - first, last, n = nil, nil, 0 - end - elseif id == disc_code then - -- always in the middle - setprop(current,a_state,s_medi) - last = current - else -- finish - if first and first == last then - setprop(last,a_state,s_isol) - elseif last then - setprop(last,a_state,s_fina) - end - first, last, n = nil, nil, 0 - if id == math_code then - current = end_of_math(current) - end - end - current = getnext(current) - end - if first and first == last then - setprop(last,a_state,s_isol) - elseif last then - setprop(last,a_state,s_fina) - end - return head, done -end - --- in the future we will use language/script attributes instead of the --- font related value, but then we also need dynamic features which is --- somewhat slower; and .. we need a chain of them - -local function analyzeinitializer(tfmdata,value) -- attr - local script, language = otf.scriptandlanguage(tfmdata) -- attr - local action = initializers[script] - if not action then - -- skip - elseif type(action) == "function" then - return action(tfmdata,value) - else - local action = action[language] - if action then - return action(tfmdata,value) - end - end -end - -local function analyzeprocessor(head,font,attr) - local tfmdata = fontdata[font] - local script, language = otf.scriptandlanguage(tfmdata,attr) - local action = methods[script] - if not action then - -- skip - elseif type(action) == "function" then - return action(head,font,attr) - else - action = action[language] - if action then - return action(head,font,attr) - end - end - return head, false -end - -registerotffeature { - name = "analyze", - description = "analysis of character classes", - default = true, - initializers = { - node = analyzeinitializer, - }, - processors = { - position = 1, - node = analyzeprocessor, - } -} - --- latin - -methods.latn = analyzers.setstate - -local arab_warned = { } - -local function warning(current,what) - local char = getchar(current) - if not arab_warned[char] then - log.report("analyze","arab: character %C has no %a class",char,what) - arab_warned[char] = true - end -end - -local mappers = { - l = s_init, -- left - d = s_medi, -- double - c = s_medi, -- joiner - r = s_fina, -- right - u = s_isol, -- nonjoiner -} - -local classifiers = { } -- we can also use this trick for devanagari - -local first_arabic, last_arabic = characters.blockrange("arabic") -local first_syriac, last_syriac = characters.blockrange("syriac") -local first_mandiac, last_mandiac = characters.blockrange("mandiac") -local first_nko, last_nko = characters.blockrange("nko") - -table.setmetatableindex(classifiers,function(t,k) - local c = chardata[k] - local v = false - if c then - local arabic = c.arabic - if arabic then - v = mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - -- error - v = false - end - elseif k >= first_arabic and k <= last_arabic or k >= first_syriac and k <= last_syriac or - k >= first_mandiac and k <= last_mandiac or k >= first_nko and k <= last_nko then - if categories[k] == "mn" then - v = s_mark - else - v = s_rest - end - else - end - end - t[k] = v - return v -end) - -function methods.arab(head,font,attr) - local first, last = nil, nil - local c_first, c_last = nil, nil - local current, done = head, false - current = tonut(current) - while current do - local id = getid(current) - if id == glyph_code and getfont(current) == font and getsubtype(current)<256 and not getprop(current,a_state) then - done = true - local char = getchar(current) - local classifier = classifiers[char] - if not classifier then - if last then - if c_last == s_medi or c_last == s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first, last = nil, nil - elseif first then - if c_first == s_medi or c_first == s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first = nil - end - elseif classifier == s_mark then - setprop(current,a_state,s_mark) - elseif classifier == s_isol then - if last then - if c_last == s_medi or c_last == s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first, last = nil, nil - elseif first then - if c_first == s_medi or c_first == s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first = nil - end - setprop(current,a_state,s_isol) - elseif classifier == s_medi then - if first then - last = current - c_last = classifier - setprop(current,a_state,s_medi) - else - setprop(current,a_state,s_init) - first = current - c_first = classifier - end - elseif classifier == s_fina then - if last then - if getprop(last,a_state) ~= s_init then - setprop(last,a_state,s_medi) - end - setprop(current,a_state,s_fina) - first, last = nil, nil - elseif first then - -- if getprop(first,a_state) ~= s_init then - -- -- needs checking - -- setprop(first,a_state,s_medi) - -- end - setprop(current,a_state,s_fina) - first = nil - else - setprop(current,a_state,s_isol) - end - else -- classifier == s_rest - setprop(current,a_state,s_rest) - if last then - if c_last == s_medi or c_last == s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first, last = nil, nil - elseif first then - if c_first == s_medi or c_first == s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first = nil - end - end - else - if last then - if c_last == s_medi or c_last == s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first, last = nil, nil - elseif first then - if c_first == s_medi or c_first == s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first = nil - end - if id == math_code then -- a bit duplicate as we test for glyphs twice - current = end_of_math(current) - end - end - current = getnext(current) - end - if last then - if c_last == s_medi or c_last == s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - elseif first then - if c_first == s_medi or c_first == s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - end - return head, done -end - -methods.syrc = methods.arab -methods.mand = methods.arab -methods.nko = methods.arab - -directives.register("otf.analyze.useunicodemarks",function(v) - analyzers.useunicodemarks = v -end) diff --git a/tex/context/base/lang-hyp.lua b/tex/context/base/lang-hyp.lua index 4bf2845fd..b13a8e965 100644 --- a/tex/context/base/lang-hyp.lua +++ b/tex/context/base/lang-hyp.lua @@ -1177,6 +1177,8 @@ if context then word[1] = char size = 1 start = current + else + size = 0 end else size = 0 diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua index bc12867ed..0dec3a7b2 100644 --- a/tex/context/base/math-noa.lua +++ b/tex/context/base/math-noa.lua @@ -1039,9 +1039,9 @@ local function collapsepair(pointer,what,n,parent,nested) -- todo: switch to tur setfield(next_noad,"sub",nil) free_node(next_noad) collapsepair(pointer,what,n,parent,true) - if not nested and movesub[current_char] then - movesubscript(parent,current_nucleus,current_char) - end + -- if not nested and movesub[current_char] then + -- movesubscript(parent,current_nucleus,current_char) + -- end end elseif not nested and movesub[current_char] then movesubscript(parent,current_nucleus,current_char) diff --git a/tex/context/base/mult-de.mkii b/tex/context/base/mult-de.mkii index fce49f985..02c0aa389 100644 --- a/tex/context/base/mult-de.mkii +++ b/tex/context/base/mult-de.mkii @@ -422,7 +422,7 @@ \setinterfacevariable{september}{september} \setinterfacevariable{serif}{serif} \setinterfacevariable{serried}{kleinerabstand} -\setinterfacevariable{setups}{impostazioni} +\setinterfacevariable{setups}{setups} \setinterfacevariable{sheet}{sheet} \setinterfacevariable{short}{kurz} \setinterfacevariable{simplefonts}{simplefonts} @@ -1285,6 +1285,7 @@ \setinterfacecommand{definetabletemplate}{definieretabellenvorlage} \setinterfacecommand{definetabulate}{definieretabulator} \setinterfacecommand{definetext}{definieretext} +\setinterfacecommand{definetextbackground}{definetextbackground} \setinterfacecommand{definetextposition}{definetextposition} \setinterfacecommand{definetextvariable}{definetextvariable} \setinterfacecommand{definetype}{definetype} @@ -1454,6 +1455,7 @@ \setinterfacecommand{placeheadtext}{placeheadtext} \setinterfacecommand{placelegend}{platzierelegende} \setinterfacecommand{placelist}{platziereliste} +\setinterfacecommand{placelistofsynonyms}{placelistofsynonyms} \setinterfacecommand{placelocalfootnotes}{platzierelokalefussnoten} \setinterfacecommand{placelogos}{platzierelogo} \setinterfacecommand{placeongrid}{amgitterausrichten} @@ -1606,7 +1608,6 @@ \setinterfacecommand{setupregister}{stelleregisterein} \setinterfacecommand{setuprotate}{stelledrehenein} \setinterfacecommand{setuprule}{setuprule} -\setinterfacecommand{setups}{einstellungen} \setinterfacecommand{setupscreens}{stellerasterein} \setinterfacecommand{setupsection}{stelleabschnittein} \setinterfacecommand{setupsectionblock}{stelleabschnittsblockein} @@ -1624,6 +1625,7 @@ \setinterfacecommand{setuptables}{stelletabellenein} \setinterfacecommand{setuptabulate}{stelletabulatorein} \setinterfacecommand{setuptext}{stelletextein} +\setinterfacecommand{setuptextbackground}{setuptextbackground} \setinterfacecommand{setuptextposition}{setuptextposition} \setinterfacecommand{setuptextrules}{stelletextumrissein} \setinterfacecommand{setuptexttexts}{stelletexttexteein} @@ -1670,6 +1672,7 @@ \setinterfacecommand{startdocument}{startdokument} \setinterfacecommand{startenvironment}{startumgebung} \setinterfacecommand{startfigure}{startabbildung} +\setinterfacecommand{startframed}{startframed} \setinterfacecommand{startglobal}{startglobal} \setinterfacecommand{startline}{startzeile} \setinterfacecommand{startlinecorrection}{startzeilenkorrektur} @@ -1696,6 +1699,7 @@ \setinterfacecommand{starttable}{starttabelle} \setinterfacecommand{starttables}{starttabellen} \setinterfacecommand{starttext}{starttext} +\setinterfacecommand{starttextbackground}{starttextbackground} \setinterfacecommand{starttextrule}{starttextlinie} \setinterfacecommand{startunpacked}{startgrosserdurchschuss} \setinterfacecommand{startversion}{startversion} @@ -1710,6 +1714,7 @@ \setinterfacecommand{stopcomponent}{stopkomponente} \setinterfacecommand{stopdocument}{stopdokument} \setinterfacecommand{stopenvironment}{stopumgebung} +\setinterfacecommand{stopframed}{stopframed} \setinterfacecommand{stopglobal}{stopglobal} \setinterfacecommand{stopline}{stopzeile} \setinterfacecommand{stoplinecorrection}{stopzeilenkorrektur} @@ -1735,6 +1740,7 @@ \setinterfacecommand{stoptable}{stoptabelle} \setinterfacecommand{stoptables}{stoptabellen} \setinterfacecommand{stoptext}{stoptext} +\setinterfacecommand{stoptextbackground}{stoptextbackground} \setinterfacecommand{stoptextrule}{stoptextlinie} \setinterfacecommand{stopunpacked}{stopgrosserdurchschuss} \setinterfacecommand{stopversion}{stopversion} diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua index d0e4cbb4d..afbc1001a 100644 --- a/tex/context/base/mult-def.lua +++ b/tex/context/base/mult-def.lua @@ -1275,6 +1275,10 @@ return { ["pe"]="تعریفمترادفها", ["ro"]="definestesinonim", }, + ["placelistofsynonyms"]={ + ["en"]="placelistofsynonyms", + ["nl"]="plaatslijstmetsynoniemen", + }, ["definetabletemplate"]={ ["cs"]="definujsablonutabulky", ["de"]="definieretabellenvorlage", @@ -4509,16 +4513,6 @@ return { ["pe"]="بارگذاریخط", ["ro"]="seteazarigla", }, - ["setups"]={ - ["cs"]="nastaveni", - ["de"]="einstellungen", - ["en"]="setups", - ["fr"]="reglages", - ["it"]="impostazioni", - ["nl"]="instellingen", - ["pe"]="بارگذاریها", - ["ro"]="setari", - }, ["setupscreens"]={ ["cs"]="nastavrastr", ["de"]="stellerasterein", @@ -5039,6 +5033,30 @@ return { ["pe"]="شروعتنظیم", ["ro"]="startaliniere", }, + ["starttextbackground"]={ + ["en"]="starttextbackground", + ["nl"]="starttekstachtergrond", + }, + ["stoptextbackground"]={ + ["en"]="stoptextbackground", + ["nl"]="stoptekstachtergrond", + }, + ["setuptextbackground"]={ + ["en"]="setuptextbackground", + ["nl"]="steltekstachtergrondin", + }, + ["definetextbackground"]={ + ["en"]="definetextbackground", + ["nl"]="definieertekstachtergrond", + }, + ["startframed"]={ + ["en"]="startframed", + ["nl"]="startomlijnd", + }, + ["stopframed"]={ + ["en"]="stopframed", + ["nl"]="stopomlijnd", + }, ["startbackground"]={ ["cs"]="startpozadi", ["de"]="starthintergrund", @@ -6454,6 +6472,10 @@ return { }, }, ["constants"]={ + ["setups"]={ + ["comment"]="no translations", + ["en"]="setups", + }, -- select/simplefonts ["regularfont"] ={ ["en"]="regularfont" }, ["boldfont"] ={ ["en"]="boldfont" }, @@ -10136,16 +10158,6 @@ return { ["pe"]="قراربده", ["ro"]="set", }, - ["setups"]={ - ["cs"]="setups", - ["de"]="setups", - ["en"]="setups", - ["fr"]="reglages", - ["it"]="setups", - ["nl"]="setups", - ["pe"]="بارگذاریها", - ["ro"]="setups", - }, ["shrink"]={ ["en"]="shrink", ["nl"]="krimp", @@ -11405,6 +11417,10 @@ return { }, }, ["variables"]={ + ["setups"]={ + ["comment"]="no translations", + ["en"]="setups", + }, ["followingpage"]={ ["en"]="followingpage", ["nl"]="opvolgendepagina", @@ -15505,16 +15521,6 @@ return { ["pe"]="تنگهم", ["ro"]="serried", }, - ["setups"]={ - ["cs"]="einstellungen", - ["de"]="impostazioni", - ["en"]="setups", - ["fr"]="reglages", - ["it"]="nastaveni", - ["nl"]="instellingen", - ["pe"]="بارگذاریها", - ["ro"]="setari", - }, ["sheet"]={ ["cs"]="sheet", ["de"]="sheet", diff --git a/tex/context/base/mult-en.mkii b/tex/context/base/mult-en.mkii index 2c38f7a8d..f522519e4 100644 --- a/tex/context/base/mult-en.mkii +++ b/tex/context/base/mult-en.mkii @@ -1285,6 +1285,7 @@ \setinterfacecommand{definetabletemplate}{definetabletemplate} \setinterfacecommand{definetabulate}{definetabulate} \setinterfacecommand{definetext}{definetext} +\setinterfacecommand{definetextbackground}{definetextbackground} \setinterfacecommand{definetextposition}{definetextposition} \setinterfacecommand{definetextvariable}{definetextvariable} \setinterfacecommand{definetype}{definetype} @@ -1454,6 +1455,7 @@ \setinterfacecommand{placeheadtext}{placeheadtext} \setinterfacecommand{placelegend}{placelegend} \setinterfacecommand{placelist}{placelist} +\setinterfacecommand{placelistofsynonyms}{placelistofsynonyms} \setinterfacecommand{placelocalfootnotes}{placelocalfootnotes} \setinterfacecommand{placelogos}{placelogos} \setinterfacecommand{placeongrid}{placeongrid} @@ -1606,7 +1608,6 @@ \setinterfacecommand{setupregister}{setupregister} \setinterfacecommand{setuprotate}{setuprotate} \setinterfacecommand{setuprule}{setuprule} -\setinterfacecommand{setups}{setups} \setinterfacecommand{setupscreens}{setupscreens} \setinterfacecommand{setupsection}{setupsection} \setinterfacecommand{setupsectionblock}{setupsectionblock} @@ -1624,6 +1625,7 @@ \setinterfacecommand{setuptables}{setuptables} \setinterfacecommand{setuptabulate}{setuptabulate} \setinterfacecommand{setuptext}{setuptext} +\setinterfacecommand{setuptextbackground}{setuptextbackground} \setinterfacecommand{setuptextposition}{setuptextposition} \setinterfacecommand{setuptextrules}{setuptextrules} \setinterfacecommand{setuptexttexts}{setuptexttexts} @@ -1670,6 +1672,7 @@ \setinterfacecommand{startdocument}{startdocument} \setinterfacecommand{startenvironment}{startenvironment} \setinterfacecommand{startfigure}{startfigure} +\setinterfacecommand{startframed}{startframed} \setinterfacecommand{startglobal}{startglobal} \setinterfacecommand{startline}{startline} \setinterfacecommand{startlinecorrection}{startlinecorrection} @@ -1696,6 +1699,7 @@ \setinterfacecommand{starttable}{starttable} \setinterfacecommand{starttables}{starttables} \setinterfacecommand{starttext}{starttext} +\setinterfacecommand{starttextbackground}{starttextbackground} \setinterfacecommand{starttextrule}{starttextrule} \setinterfacecommand{startunpacked}{startunpacked} \setinterfacecommand{startversion}{startversion} @@ -1710,6 +1714,7 @@ \setinterfacecommand{stopcomponent}{stopcomponent} \setinterfacecommand{stopdocument}{stopdocument} \setinterfacecommand{stopenvironment}{stopenvironment} +\setinterfacecommand{stopframed}{stopframed} \setinterfacecommand{stopglobal}{stopglobal} \setinterfacecommand{stopline}{stopline} \setinterfacecommand{stoplinecorrection}{stoplinecorrection} @@ -1735,6 +1740,7 @@ \setinterfacecommand{stoptable}{stoptable} \setinterfacecommand{stoptables}{stoptables} \setinterfacecommand{stoptext}{stoptext} +\setinterfacecommand{stoptextbackground}{stoptextbackground} \setinterfacecommand{stoptextrule}{stoptextrule} \setinterfacecommand{stopunpacked}{stopunpacked} \setinterfacecommand{stopversion}{stopversion} diff --git a/tex/context/base/mult-fr.mkii b/tex/context/base/mult-fr.mkii index 6b653d88d..9c611b32c 100644 --- a/tex/context/base/mult-fr.mkii +++ b/tex/context/base/mult-fr.mkii @@ -422,7 +422,7 @@ \setinterfacevariable{september}{septembre} \setinterfacevariable{serif}{serif} \setinterfacevariable{serried}{serried} -\setinterfacevariable{setups}{reglages} +\setinterfacevariable{setups}{setups} \setinterfacevariable{sheet}{sheet} \setinterfacevariable{short}{short} \setinterfacevariable{simplefonts}{simplefonts} @@ -1006,7 +1006,7 @@ \setinterfaceconstant{separatorcolor}{separatorcolor} \setinterfaceconstant{separatorstyle}{separatorstyle} \setinterfaceconstant{set}{set} -\setinterfaceconstant{setups}{reglages} +\setinterfaceconstant{setups}{setups} \setinterfaceconstant{shrink}{shrink} \setinterfaceconstant{side}{cote} \setinterfaceconstant{sidealign}{sidealign} @@ -1285,6 +1285,7 @@ \setinterfacecommand{definetabletemplate}{definittrametableau} \setinterfacecommand{definetabulate}{definittabulation} \setinterfacecommand{definetext}{definittexte} +\setinterfacecommand{definetextbackground}{definetextbackground} \setinterfacecommand{definetextposition}{definitpositiontexte} \setinterfacecommand{definetextvariable}{definitvariabletexte} \setinterfacecommand{definetype}{definittype} @@ -1454,6 +1455,7 @@ \setinterfacecommand{placeheadtext}{placetextetete} \setinterfacecommand{placelegend}{placelegende} \setinterfacecommand{placelist}{placeliste} +\setinterfacecommand{placelistofsynonyms}{placelistofsynonyms} \setinterfacecommand{placelocalfootnotes}{placenotespdplocales} \setinterfacecommand{placelogos}{placelogos} \setinterfacecommand{placeongrid}{placesurgrille} @@ -1606,7 +1608,6 @@ \setinterfacecommand{setupregister}{regleregistre} \setinterfacecommand{setuprotate}{regleoriente} \setinterfacecommand{setuprule}{regleregle} -\setinterfacecommand{setups}{reglages} \setinterfacecommand{setupscreens}{regleecrans} \setinterfacecommand{setupsection}{reglesection} \setinterfacecommand{setupsectionblock}{regleblocsection} @@ -1624,6 +1625,7 @@ \setinterfacecommand{setuptables}{regletableaux} \setinterfacecommand{setuptabulate}{regletabulation} \setinterfacecommand{setuptext}{regletexte} +\setinterfacecommand{setuptextbackground}{setuptextbackground} \setinterfacecommand{setuptextposition}{reglepositiontexte} \setinterfacecommand{setuptextrules}{reglelignesreglestexte} \setinterfacecommand{setuptexttexts}{regletextestexte} @@ -1670,6 +1672,7 @@ \setinterfacecommand{startdocument}{demarredocument} \setinterfacecommand{startenvironment}{demarreenvironement} \setinterfacecommand{startfigure}{demarrefigure} +\setinterfacecommand{startframed}{startframed} \setinterfacecommand{startglobal}{demarreglobal} \setinterfacecommand{startline}{demarreligne} \setinterfacecommand{startlinecorrection}{demarrecorrectionligne} @@ -1696,6 +1699,7 @@ \setinterfacecommand{starttable}{demarretableau} \setinterfacecommand{starttables}{demarretableaux} \setinterfacecommand{starttext}{demarretexte} +\setinterfacecommand{starttextbackground}{starttextbackground} \setinterfacecommand{starttextrule}{demarreligneregleetexte} \setinterfacecommand{startunpacked}{demarredegroupe} \setinterfacecommand{startversion}{demarreversion} @@ -1710,6 +1714,7 @@ \setinterfacecommand{stopcomponent}{stoppecomposant} \setinterfacecommand{stopdocument}{stoppedocument} \setinterfacecommand{stopenvironment}{stoppeenvironement} +\setinterfacecommand{stopframed}{stopframed} \setinterfacecommand{stopglobal}{stoppeglobal} \setinterfacecommand{stopline}{stoppeligne} \setinterfacecommand{stoplinecorrection}{stoppecorrectionligne} @@ -1735,6 +1740,7 @@ \setinterfacecommand{stoptable}{stoppetableau} \setinterfacecommand{stoptables}{stoppetableaux} \setinterfacecommand{stoptext}{stoppetexte} +\setinterfacecommand{stoptextbackground}{stoptextbackground} \setinterfacecommand{stoptextrule}{stoppeligneregleetexte} \setinterfacecommand{stopunpacked}{stoppedegroupe} \setinterfacecommand{stopversion}{stoppeversion} diff --git a/tex/context/base/mult-it.mkii b/tex/context/base/mult-it.mkii index fc7f29664..c5221fa5d 100644 --- a/tex/context/base/mult-it.mkii +++ b/tex/context/base/mult-it.mkii @@ -422,7 +422,7 @@ \setinterfacevariable{september}{settembre} \setinterfacevariable{serif}{serif} \setinterfacevariable{serried}{vicino} -\setinterfacevariable{setups}{nastaveni} +\setinterfacevariable{setups}{setups} \setinterfacevariable{sheet}{sheet} \setinterfacevariable{short}{short} \setinterfacevariable{simplefonts}{simplefonts} @@ -1285,6 +1285,7 @@ \setinterfacecommand{definetabletemplate}{definiscimodellotabella} \setinterfacecommand{definetabulate}{definiscitabulato} \setinterfacecommand{definetext}{definiscitesto} +\setinterfacecommand{definetextbackground}{definetextbackground} \setinterfacecommand{definetextposition}{definisciposizionetesto} \setinterfacecommand{definetextvariable}{definiscivariabiletesto} \setinterfacecommand{definetype}{definiscitype} @@ -1454,6 +1455,7 @@ \setinterfacecommand{placeheadtext}{posizionatestotesta} \setinterfacecommand{placelegend}{mettilegenda} \setinterfacecommand{placelist}{mettielenco} +\setinterfacecommand{placelistofsynonyms}{placelistofsynonyms} \setinterfacecommand{placelocalfootnotes}{mettinotepdplocali} \setinterfacecommand{placelogos}{mettiloghi} \setinterfacecommand{placeongrid}{mettiingriglia} @@ -1606,7 +1608,6 @@ \setinterfacecommand{setupregister}{impostaregistro} \setinterfacecommand{setuprotate}{impostarotazione} \setinterfacecommand{setuprule}{impostalinea} -\setinterfacecommand{setups}{impostazioni} \setinterfacecommand{setupscreens}{impostaschermi} \setinterfacecommand{setupsection}{impostasezione} \setinterfacecommand{setupsectionblock}{impostabloccosezione} @@ -1624,6 +1625,7 @@ \setinterfacecommand{setuptables}{impostatabelle} \setinterfacecommand{setuptabulate}{impostatabulato} \setinterfacecommand{setuptext}{impostatesto} +\setinterfacecommand{setuptextbackground}{setuptextbackground} \setinterfacecommand{setuptextposition}{impostaposizionetesto} \setinterfacecommand{setuptextrules}{impostalineetesto} \setinterfacecommand{setuptexttexts}{impostatestotesti} @@ -1670,6 +1672,7 @@ \setinterfacecommand{startdocument}{iniziadocumento} \setinterfacecommand{startenvironment}{iniziaambiente} \setinterfacecommand{startfigure}{iniziafigura} +\setinterfacecommand{startframed}{startframed} \setinterfacecommand{startglobal}{iniziaglobale} \setinterfacecommand{startline}{iniziariga} \setinterfacecommand{startlinecorrection}{iniziacorrezioneriga} @@ -1696,6 +1699,7 @@ \setinterfacecommand{starttable}{iniziatabella} \setinterfacecommand{starttables}{iniziatabelle} \setinterfacecommand{starttext}{iniziatesto} +\setinterfacecommand{starttextbackground}{starttextbackground} \setinterfacecommand{starttextrule}{inizialineatesto} \setinterfacecommand{startunpacked}{iniziaunpacked} \setinterfacecommand{startversion}{iniziaversione} @@ -1710,6 +1714,7 @@ \setinterfacecommand{stopcomponent}{terminacomponente} \setinterfacecommand{stopdocument}{terminadocumento} \setinterfacecommand{stopenvironment}{terminaambiente} +\setinterfacecommand{stopframed}{stopframed} \setinterfacecommand{stopglobal}{terminaglobale} \setinterfacecommand{stopline}{terminariga} \setinterfacecommand{stoplinecorrection}{terminacorrezioneriga} @@ -1735,6 +1740,7 @@ \setinterfacecommand{stoptable}{terminatabella} \setinterfacecommand{stoptables}{terminatabelle} \setinterfacecommand{stoptext}{terminatesto} +\setinterfacecommand{stoptextbackground}{stoptextbackground} \setinterfacecommand{stoptextrule}{terminalineatesto} \setinterfacecommand{stopunpacked}{terminaunpacked} \setinterfacecommand{stopversion}{terminaversioni} diff --git a/tex/context/base/mult-nl.mkii b/tex/context/base/mult-nl.mkii index ab2a01641..4d2322ac9 100644 --- a/tex/context/base/mult-nl.mkii +++ b/tex/context/base/mult-nl.mkii @@ -422,7 +422,7 @@ \setinterfacevariable{september}{september} \setinterfacevariable{serif}{serif} \setinterfacevariable{serried}{aanelkaar} -\setinterfacevariable{setups}{instellingen} +\setinterfacevariable{setups}{setups} \setinterfacevariable{sheet}{sheet} \setinterfacevariable{short}{kort} \setinterfacevariable{simplefonts}{simplefonts} @@ -1285,6 +1285,7 @@ \setinterfacecommand{definetabletemplate}{definieertabelvorm} \setinterfacecommand{definetabulate}{definieertabulatie} \setinterfacecommand{definetext}{definieertekst} +\setinterfacecommand{definetextbackground}{definieertekstachtergrond} \setinterfacecommand{definetextposition}{definieertekstpositie} \setinterfacecommand{definetextvariable}{definieertekstvariabele} \setinterfacecommand{definetype}{definieertype} @@ -1454,6 +1455,7 @@ \setinterfacecommand{placeheadtext}{plaatskoptekst} \setinterfacecommand{placelegend}{plaatslegenda} \setinterfacecommand{placelist}{plaatslijst} +\setinterfacecommand{placelistofsynonyms}{plaatslijstmetsynoniemen} \setinterfacecommand{placelocalfootnotes}{plaatslokalevoetnoten} \setinterfacecommand{placelogos}{plaatsbeeldmerken} \setinterfacecommand{placeongrid}{plaatsopgrid} @@ -1606,7 +1608,6 @@ \setinterfacecommand{setupregister}{stelregisterin} \setinterfacecommand{setuprotate}{stelroterenin} \setinterfacecommand{setuprule}{stellijnin} -\setinterfacecommand{setups}{instellingen} \setinterfacecommand{setupscreens}{stelrastersin} \setinterfacecommand{setupsection}{stelsectiein} \setinterfacecommand{setupsectionblock}{stelsectieblokin} @@ -1624,6 +1625,7 @@ \setinterfacecommand{setuptables}{steltabellenin} \setinterfacecommand{setuptabulate}{steltabulatiein} \setinterfacecommand{setuptext}{steltekstin} +\setinterfacecommand{setuptextbackground}{steltekstachtergrondin} \setinterfacecommand{setuptextposition}{steltekstpositiein} \setinterfacecommand{setuptextrules}{steltekstlijnenin} \setinterfacecommand{setuptexttexts}{stelteksttekstenin} @@ -1670,6 +1672,7 @@ \setinterfacecommand{startdocument}{startdocument} \setinterfacecommand{startenvironment}{startomgeving} \setinterfacecommand{startfigure}{startfiguur} +\setinterfacecommand{startframed}{startomlijnd} \setinterfacecommand{startglobal}{startglobaal} \setinterfacecommand{startline}{startregel} \setinterfacecommand{startlinecorrection}{startregelcorrectie} @@ -1696,6 +1699,7 @@ \setinterfacecommand{starttable}{starttabel} \setinterfacecommand{starttables}{starttabellen} \setinterfacecommand{starttext}{starttekst} +\setinterfacecommand{starttextbackground}{starttekstachtergrond} \setinterfacecommand{starttextrule}{starttekstlijn} \setinterfacecommand{startunpacked}{startvanelkaar} \setinterfacecommand{startversion}{startversie} @@ -1710,6 +1714,7 @@ \setinterfacecommand{stopcomponent}{stoponderdeel} \setinterfacecommand{stopdocument}{stopdocument} \setinterfacecommand{stopenvironment}{stopomgeving} +\setinterfacecommand{stopframed}{stopomlijnd} \setinterfacecommand{stopglobal}{stopglobaal} \setinterfacecommand{stopline}{stopregel} \setinterfacecommand{stoplinecorrection}{stopregelcorrectie} @@ -1735,6 +1740,7 @@ \setinterfacecommand{stoptable}{stoptabel} \setinterfacecommand{stoptables}{stoptabellen} \setinterfacecommand{stoptext}{stoptekst} +\setinterfacecommand{stoptextbackground}{stoptekstachtergrond} \setinterfacecommand{stoptextrule}{stoptekstlijn} \setinterfacecommand{stopunpacked}{stopvanelkaar} \setinterfacecommand{stopversion}{stopversie} diff --git a/tex/context/base/mult-pe.mkii b/tex/context/base/mult-pe.mkii index 792cbb479..57fe99565 100644 --- a/tex/context/base/mult-pe.mkii +++ b/tex/context/base/mult-pe.mkii @@ -422,7 +422,7 @@ \setinterfacevariable{september}{سپتامبر} \setinterfacevariable{serif}{سریف} \setinterfacevariable{serried}{تنگهم} -\setinterfacevariable{setups}{بارگذاریها} +\setinterfacevariable{setups}{setups} \setinterfacevariable{sheet}{ورقه} \setinterfacevariable{short}{short} \setinterfacevariable{simplefonts}{simplefonts} @@ -1006,7 +1006,7 @@ \setinterfaceconstant{separatorcolor}{separatorcolor} \setinterfaceconstant{separatorstyle}{separatorstyle} \setinterfaceconstant{set}{قراربده} -\setinterfaceconstant{setups}{بارگذاریها} +\setinterfaceconstant{setups}{setups} \setinterfaceconstant{shrink}{shrink} \setinterfaceconstant{side}{کنار} \setinterfaceconstant{sidealign}{تنظیمکنار} @@ -1285,6 +1285,7 @@ \setinterfacecommand{definetabletemplate}{تعریفالگویجدول} \setinterfacecommand{definetabulate}{تعریفجدولبندی} \setinterfacecommand{definetext}{تعریفمتن} +\setinterfacecommand{definetextbackground}{definetextbackground} \setinterfacecommand{definetextposition}{تعریفمکانمتن} \setinterfacecommand{definetextvariable}{تعریفمتغیرمتن} \setinterfacecommand{definetype}{تعریفتایپ} @@ -1454,6 +1455,7 @@ \setinterfacecommand{placeheadtext}{درجمتنسر} \setinterfacecommand{placelegend}{درجراهنما} \setinterfacecommand{placelist}{درجلیست} +\setinterfacecommand{placelistofsynonyms}{placelistofsynonyms} \setinterfacecommand{placelocalfootnotes}{درجپانوشتهایموضعی} \setinterfacecommand{placelogos}{درجآرمها} \setinterfacecommand{placeongrid}{درجدرتوری} @@ -1606,7 +1608,6 @@ \setinterfacecommand{setupregister}{بارگذاریثبت} \setinterfacecommand{setuprotate}{بارگذاریدوران} \setinterfacecommand{setuprule}{بارگذاریخط} -\setinterfacecommand{setups}{بارگذاریها} \setinterfacecommand{setupscreens}{بارگذاریپردهها} \setinterfacecommand{setupsection}{بارگذاریبخش} \setinterfacecommand{setupsectionblock}{بارگذاریبلوکبخش} @@ -1624,6 +1625,7 @@ \setinterfacecommand{setuptables}{بارگذاریجدولها} \setinterfacecommand{setuptabulate}{بارگذاریجدولبندی} \setinterfacecommand{setuptext}{بارگذاریمتن} +\setinterfacecommand{setuptextbackground}{setuptextbackground} \setinterfacecommand{setuptextposition}{بارگذاریمکانمتن} \setinterfacecommand{setuptextrules}{بارگذاریخطهایمتن} \setinterfacecommand{setuptexttexts}{بارگذاریمتنمتنها} @@ -1670,6 +1672,7 @@ \setinterfacecommand{startdocument}{شروعنوشتار} \setinterfacecommand{startenvironment}{شروعمحیط} \setinterfacecommand{startfigure}{شروعشکل} +\setinterfacecommand{startframed}{startframed} \setinterfacecommand{startglobal}{شروعسراسری} \setinterfacecommand{startline}{شروعخط} \setinterfacecommand{startlinecorrection}{شروعتصحیحخط} @@ -1696,6 +1699,7 @@ \setinterfacecommand{starttable}{شروعجدول} \setinterfacecommand{starttables}{شروعجدولها} \setinterfacecommand{starttext}{شروعمتن} +\setinterfacecommand{starttextbackground}{starttextbackground} \setinterfacecommand{starttextrule}{شروعخطمتن} \setinterfacecommand{startunpacked}{شروعغیرفشرده} \setinterfacecommand{startversion}{شروعنسخه} @@ -1710,6 +1714,7 @@ \setinterfacecommand{stopcomponent}{پایانمولفه} \setinterfacecommand{stopdocument}{پایاننوشتار} \setinterfacecommand{stopenvironment}{پایانمحیط} +\setinterfacecommand{stopframed}{stopframed} \setinterfacecommand{stopglobal}{پایانسراسری} \setinterfacecommand{stopline}{پایانخط} \setinterfacecommand{stoplinecorrection}{پایانتصحیحخط} @@ -1735,6 +1740,7 @@ \setinterfacecommand{stoptable}{پایانجدول} \setinterfacecommand{stoptables}{پایانجدولها} \setinterfacecommand{stoptext}{پایانمتن} +\setinterfacecommand{stoptextbackground}{stoptextbackground} \setinterfacecommand{stoptextrule}{پایانخطمتن} \setinterfacecommand{stopunpacked}{پایانغیرفشرده} \setinterfacecommand{stopversion}{پایاننسخه} diff --git a/tex/context/base/mult-ro.mkii b/tex/context/base/mult-ro.mkii index a6c54efc6..284cf8b0d 100644 --- a/tex/context/base/mult-ro.mkii +++ b/tex/context/base/mult-ro.mkii @@ -422,7 +422,7 @@ \setinterfacevariable{september}{septembrie} \setinterfacevariable{serif}{serif} \setinterfacevariable{serried}{serried} -\setinterfacevariable{setups}{setari} +\setinterfacevariable{setups}{setups} \setinterfacevariable{sheet}{sheet} \setinterfacevariable{short}{short} \setinterfacevariable{simplefonts}{simplefonts} @@ -1285,6 +1285,7 @@ \setinterfacecommand{definetabletemplate}{definestesablontabel} \setinterfacecommand{definetabulate}{definestetabulatori} \setinterfacecommand{definetext}{definestetext} +\setinterfacecommand{definetextbackground}{definetextbackground} \setinterfacecommand{definetextposition}{definestepozitietext} \setinterfacecommand{definetextvariable}{definestevariabilatext} \setinterfacecommand{definetype}{definetype} @@ -1454,6 +1455,7 @@ \setinterfacecommand{placeheadtext}{placeheadtext} \setinterfacecommand{placelegend}{punelegenda} \setinterfacecommand{placelist}{punelista} +\setinterfacecommand{placelistofsynonyms}{placelistofsynonyms} \setinterfacecommand{placelocalfootnotes}{punenotesubsollocale} \setinterfacecommand{placelogos}{punelogouri} \setinterfacecommand{placeongrid}{plaseazapegrid} @@ -1606,7 +1608,6 @@ \setinterfacecommand{setupregister}{seteazaregistru} \setinterfacecommand{setuprotate}{seteazarotare} \setinterfacecommand{setuprule}{seteazarigla} -\setinterfacecommand{setups}{setari} \setinterfacecommand{setupscreens}{seteazaecrane} \setinterfacecommand{setupsection}{seteazasectiune} \setinterfacecommand{setupsectionblock}{seteazablocsectiune} @@ -1624,6 +1625,7 @@ \setinterfacecommand{setuptables}{seteazatabele} \setinterfacecommand{setuptabulate}{seteazatabulatori} \setinterfacecommand{setuptext}{seteazatext} +\setinterfacecommand{setuptextbackground}{setuptextbackground} \setinterfacecommand{setuptextposition}{seteazapozitietext} \setinterfacecommand{setuptextrules}{seteazarigletext} \setinterfacecommand{setuptexttexts}{seteazatextetext} @@ -1670,6 +1672,7 @@ \setinterfacecommand{startdocument}{startdocument} \setinterfacecommand{startenvironment}{startmediu} \setinterfacecommand{startfigure}{startfigura} +\setinterfacecommand{startframed}{startframed} \setinterfacecommand{startglobal}{startglobal} \setinterfacecommand{startline}{startlinie} \setinterfacecommand{startlinecorrection}{startcorectielinie} @@ -1696,6 +1699,7 @@ \setinterfacecommand{starttable}{starttabel} \setinterfacecommand{starttables}{starttabele} \setinterfacecommand{starttext}{starttext} +\setinterfacecommand{starttextbackground}{starttextbackground} \setinterfacecommand{starttextrule}{startriglatext} \setinterfacecommand{startunpacked}{startneimpachetat} \setinterfacecommand{startversion}{startversiune} @@ -1710,6 +1714,7 @@ \setinterfacecommand{stopcomponent}{stopcomponenta} \setinterfacecommand{stopdocument}{stopdocument} \setinterfacecommand{stopenvironment}{stopmediu} +\setinterfacecommand{stopframed}{stopframed} \setinterfacecommand{stopglobal}{stopblobal} \setinterfacecommand{stopline}{stoplinie} \setinterfacecommand{stoplinecorrection}{stopcorectielinie} @@ -1735,6 +1740,7 @@ \setinterfacecommand{stoptable}{stoptabel} \setinterfacecommand{stoptables}{stoptabele} \setinterfacecommand{stoptext}{stoptext} +\setinterfacecommand{stoptextbackground}{stoptextbackground} \setinterfacecommand{stoptextrule}{stopriglatext} \setinterfacecommand{stopunpacked}{stopneimpachetat} \setinterfacecommand{stopversion}{stopversiune} diff --git a/tex/context/base/mult-sys.mkiv b/tex/context/base/mult-sys.mkiv index c79bc023d..11a276fe8 100644 --- a/tex/context/base/mult-sys.mkiv +++ b/tex/context/base/mult-sys.mkiv @@ -265,6 +265,10 @@ \definesystemconstant {current} \definesystemconstant {chain} +% translating setups is asking for a mess so we keep them as-is: + +\definesystemconstant {setups} + \definesystemconstant {cite} \definesystemconstant {nocite} \definesystemconstant {list} diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua index 7000c4fd7..f036239fc 100644 --- a/tex/context/base/node-fnt.lua +++ b/tex/context/base/node-fnt.lua @@ -31,6 +31,7 @@ local handlers = nodes.handlers local nuts = nodes.nuts local tonut = nuts.tonut +local tonode = nuts.tonode local getattr = nuts.getattr local getid = nuts.getid @@ -38,6 +39,8 @@ local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar local getnext = nuts.getnext +local getprev = nuts.getprev +local getfield = nuts.getfield local traverse_id = nuts.traverse_id @@ -111,11 +114,17 @@ fonts.hashes.processes = fontprocesses -- inside a run which means that we need to keep track of this which in turn complicates matters -- in a way i don't like +-- we need to deal with the basemode fonts here and can only run over ranges as we +-- otherwise get luatex craches due to all kind of asserts in the disc/lig builder + +local ligaturing = builders.kernel.ligaturing +local kerning = builders.kernel.kerning + function handlers.characters(head) -- either next or not, but definitely no already processed list starttiming(nodes) - local usedfonts, attrfonts = { }, { } - local a, u, prevfont, prevattr, done = 0, 0, nil, 0, false + local usedfonts, attrfonts, basefonts = { }, { }, { } + local a, u, b, prevfont, prevattr, done, basefont = 0, 0, 0, nil, 0, false, nil if trace_fontrun then run = run + 1 report_fonts() @@ -141,6 +150,9 @@ function handlers.characters(head) local font = getfont(n) local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context if font ~= prevfont or attr ~= prevattr then + if basefont then + basefont[2] = tonode(getprev(n)) -- todo, save p + end if attr > 0 then local used = attrfonts[font] if not used then @@ -152,6 +164,10 @@ function handlers.characters(head) if fd then used[attr] = fd[attr] a = a + 1 + else + b = b + 1 + basefont = { tonode(n), nil } + basefonts[b] = basefont end end else @@ -161,7 +177,11 @@ function handlers.characters(head) if fp then usedfonts[font] = fp u = u + 1 - end + else + b = b + 1 + basefont = { tonode(n), nil } + basefonts[b] = basefont + end end end prevfont = font @@ -171,8 +191,9 @@ function handlers.characters(head) end if trace_fontrun then report_fonts() - report_fonts("statics : %s",(u > 0 and concat(keys(usedfonts)," ")) or "none") - report_fonts("dynamics: %s",(a > 0 and concat(keys(attrfonts)," ")) or "none") + report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") + report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none") + report_fonts("built-in: %s",b > 0 and b or "none") report_fonts() end -- in context we always have at least 2 processors @@ -224,6 +245,26 @@ function handlers.characters(head) end end end + if b == 0 then + -- skip + elseif b == 1 then + local range = basefonts[1] + local start, stop = range[1], range[2] + ligaturing(start,stop) + kerning(start,stop) + else + for i=1,b do + local range = basefonts[i] + local start, stop = range[1], range[2] + if stop then + ligaturing(start,stop) + kerning(start,stop) + else + ligaturing(start) + kerning(start) + end + end + end stoptiming(nodes) if trace_characters then nodes.report(head,done) @@ -292,7 +333,9 @@ end -- return false -- end -- end) - +-- +-- -- TODO: basepasses! +-- -- function handlers.characters(head) -- -- either next or not, but definitely no already processed list -- starttiming(nodes) @@ -408,3 +451,13 @@ local d_unprotect_glyphs = nuts.unprotect_glyphs handlers.protectglyphs = function(n) return d_protect_glyphs (tonut(n)) end handlers.unprotectglyphs = function(n) return d_unprotect_glyphs(tonut(n)) end + +-- function handlers.protectglyphs(h) +-- local h = tonut(h) +-- for n in traverse_id(disc_code,h) do +-- local d = getfield(n,"pre") if d then d_protect_glyphs(d) end +-- local d = getfield(n,"post") if d then d_protect_glyphs(d) end +-- local d = getfield(n,"replace") if d then d_protect_glyphs(d) end +-- end +-- return d_protect_glyphs(h) +-- end diff --git a/tex/context/base/node-ltp.lua b/tex/context/base/node-ltp.lua index 5a826cc0d..3e77bc167 100644 --- a/tex/context/base/node-ltp.lua +++ b/tex/context/base/node-ltp.lua @@ -1243,6 +1243,7 @@ local function post_line_break(par) setfield(prevlast,"post",nil) end elseif subtype == first_disc_code then + -- what is v ... next probably if not (getid(v) == disc_code and getsubtype(v) == second_disc_code) then report_parbuilders('unsupported disc at location %a',4) end diff --git a/tex/context/base/node-nut.lua b/tex/context/base/node-nut.lua index 4c2883445..50274c2ab 100644 --- a/tex/context/base/node-nut.lua +++ b/tex/context/base/node-nut.lua @@ -665,6 +665,12 @@ if propertydata then -- direct.set_properties_mode(true,false) -- shallow copy ... problem: in fonts we then affect the originals too direct.set_properties_mode(true,true) -- create metatable, slower but needed for font-inj.lua (unless we use an intermediate table) + -- todo: + -- + -- function direct.set_properties_mode() + -- -- we really need the set modes + -- end + -- experimental code with respect to copying attributes has been removed -- as it doesn't pay of (most attributes are only accessed once anyway) diff --git a/tex/context/base/node-tex.lua b/tex/context/base/node-tex.lua index 2170e0603..9f6df031b 100644 --- a/tex/context/base/node-tex.lua +++ b/tex/context/base/node-tex.lua @@ -12,28 +12,31 @@ builders = builders or { } builders.kernel = builders.kernel or { } local kernel = builders.kernel -local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming local hyphenate, ligaturing, kerning = lang.hyphenate, node.ligaturing, node.kerning function kernel.hyphenation(head) - -- starttiming(kernel) local done = hyphenate(head) - -- stoptiming(kernel) return head, done end -function kernel.ligaturing(head) - -- starttiming(kernel) - local head, tail, done = ligaturing(head) -- todo: check what is returned - -- stoptiming(kernel) - return head, done +function kernel.ligaturing(head,tail) + if tail then + local head, tail, done = ligaturing(head,tail) + return head, done + else -- sensitive for second arg nil + local head, tail, done = ligaturing(head) + return head, done + end end -function kernel.kerning(head) - -- starttiming(kernel) - local head, tail, done = kerning(head) -- todo: check what is returned - -- stoptiming(kernel) - return head, done +function kernel.kerning(head,tail) + if tail then + local head, tail, done = kerning(head,tail) + return head, done + else -- sensitive for second arg nil + local head, tail, done = kerning(head) + return head, done + end end callbacks.register('hyphenate' , false, "normal hyphenation routine, called elsewhere") diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv index 4bc606d9a..8dee6d176 100644 --- a/tex/context/base/pack-rul.mkiv +++ b/tex/context/base/pack-rul.mkiv @@ -804,6 +804,8 @@ % \def\pack_framed_start_framed_indeed % {\pack_framed_process_indeed % \bgroup} +% +% no longer .. we also accept \startframed[tag] \unexpanded\def\pack_framed_process_framed[#1]% {\bgroup @@ -820,17 +822,55 @@ \pack_framed_initialize \dosingleempty\pack_framed_process_framed} +% \unexpanded\def\startframed +% {\dosingleempty\pack_framed_start_framed} +% +% \def\pack_framed_start_framed[#1]% +% {\bgroup +% \advance\c_pack_framed_nesting\plusone +% \expandafter\let\csname\??framed>\the\c_pack_framed_nesting:\s!parent\endcsname\??framed +% \edef\currentframed{>\the\c_pack_framed_nesting}% +% \pack_framed_initialize +% \bgroup +% \iffirstargument +% \secondargumenttrue % dirty trick +% \setupcurrentframed[#1]% here ! +% \fi +% \pack_framed_process_indeed +% \bgroup +% \ignorespaces} + \unexpanded\def\startframed {\dosingleempty\pack_framed_start_framed} \def\pack_framed_start_framed[#1]% {\bgroup - \advance\c_pack_framed_nesting\plusone + \doifassignmentelse{#1}\pack_framed_start_framed_yes\pack_framed_start_framed_nop{#1}} + +\def\pack_framed_start_framed_yes#1% + {\advance\c_pack_framed_nesting\plusone \expandafter\let\csname\??framed>\the\c_pack_framed_nesting:\s!parent\endcsname\??framed \iffirstargument\secondargumenttrue\fi % dirty trick \edef\currentframed{>\the\c_pack_framed_nesting}% \pack_framed_initialize - \pack_framed_process_framed[#1]% can be inlined + \bgroup + \iffirstargument + \secondargumenttrue % dirty trick + \setupcurrentframed[#1]% here ! + \fi + \pack_framed_process_indeed + \bgroup + \ignorespaces} + +\def\pack_framed_start_framed_nop#1% + {\edef\currentframed{#1}% + \dosingleempty\pack_framed_start_framed_nop_indeed} + +\def\pack_framed_start_framed_nop_indeed[#1]% + {\pack_framed_initialize + \bgroup + \setupcurrentframed[#1]% here ! + \pack_framed_process_indeed \bgroup \ignorespaces} @@ -1943,10 +1983,10 @@ %D \stoplinecorrection %D %D \startbuffer -%D \framed[strut=nee,offset=.5cm] {rule based learning} -%D \framed[strut=nee,offset=0cm] {rule based learning} -%D \framed[strut=nee,offset=none] {rule based learning} -%D \framed[strut=nee,offset=overlay]{rule based learning} +%D \framed[strut=no,offset=.5cm] {rule based learning} +%D \framed[strut=no,offset=0cm] {rule based learning} +%D \framed[strut=no,offset=none] {rule based learning} +%D \framed[strut=no,offset=overlay]{rule based learning} %D \stopbuffer %D %D \typebuffer @@ -1956,9 +1996,9 @@ %D \stoplinecorrection %D %D \startbuffer -%D \framed[width=3cm,align=left] {rule\\based\\learning} -%D \framed[width=3cm,align=middle] {rule\\based\\learning} -%D \framed[width=3cm,align=right] {rule\\based\\learning} +%D \framed[width=3cm,align=left] {rule\\based\\learning} +%D \framed[width=3cm,align=middle] {rule\\based\\learning} +%D \framed[width=3cm,align=right] {rule\\based\\learning} %D \framed[width=fit,align=middle] {rule\\based\\learning} %D \stopbuffer %D @@ -2025,7 +2065,6 @@ % \vbox{\hbox{x}} % \stopTEXpage - % \def\pack_framed_forgetall{\forgetall} \def\pack_framed_set_foregroundcolor diff --git a/tex/context/base/page-lay.mkiv b/tex/context/base/page-lay.mkiv index f25316c63..716967f27 100644 --- a/tex/context/base/page-lay.mkiv +++ b/tex/context/base/page-lay.mkiv @@ -1424,6 +1424,7 @@ \definepapersize [SW] [\c!width=800pt,\c!height=450pt] % wide \definepapersize [HD] [\c!width=1920pt,\c!height=1080pt] \definepapersize [HD+] [\c!width=1920pt,\c!height=1200pt] +\definepapersize [HD-] [\c!width=960pt,\c!height=540pt] %D These are handy too: diff --git a/tex/context/base/page-mix.mkiv b/tex/context/base/page-mix.mkiv index b85784ac9..fd72a6b49 100644 --- a/tex/context/base/page-mix.mkiv +++ b/tex/context/base/page-mix.mkiv @@ -292,18 +292,28 @@ \installcorenamespace{mixedcolumnsseparator} -\setvalue{\??mixedcolumnsseparator\v!rule}% - {\starttextproperties - \usemixedcolumnscolorparameter\c!rulecolor - \vrule\s!width\mixedcolumnsparameter\c!rulethickness - \stoptextproperties} +\unexpanded\def\installmixedcolumnseparator#1#2% + {\setvalue{\??mixedcolumnsseparator#1}{#2}} + +\installmixedcolumnseparator\v!rule + {\vrule\mixedcolumnsparameter\c!rulethickness\relax} \unexpanded\def\page_mix_command_inject_separator - {\bgroup + {\begingroup + \setbox\scratchbox\hbox to \zeropoint \bgroup + \hss + \starttextproperties + \usemixedcolumnscolorparameter\c!rulecolor + \csname\??mixedcolumnsseparator\p_separator\endcsname % was \c!rule + \stoptextproperties + \hss + \egroup + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint \hss - \csname\??mixedcolumnsseparator\mixedcolumnsparameter\c!separator\endcsname % was \c!rule + \box\scratchbox \hss - \egroup} + \endgroup} %D We've now arrived at the real code. The start command mostly sets up the %D environment and variables that are used in the splitter. One of the last @@ -549,6 +559,31 @@ }}% \deadcycles\zerocount} +\newdimen\mixedcolumnseparatorheight +\newdimen\mixedcolumnseparatordepth +\newdimen\mixedcolumnseparatorwidth + +\def\page_mix_routine_package_step + {% needs packaging anyway + \setbox\scratchbox\page_mix_command_package_column + \page_marks_synchronize_column\plusone\c_page_mix_n_of_columns\recurselevel\scratchbox + % backgrounds + \anch_mark_column_box\scratchbox + % for the moment a quick and dirty patch .. we need to go into the box (hence the \plusone) .. a slowdowner + \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_mix_n_of_columns\plusone + % the framed needs a reset of strut, align, setups etc + \mixedcolumnseparatorheight\ht\scratchbox + \mixedcolumnseparatordepth \dp\scratchbox + \inheritedmixedcolumnsframedbox\currentmixedcolumns\scratchbox + % optional + \ifnum\recurselevel<\c_page_mix_n_of_columns + \ifcsname\??mixedcolumnsseparator\p_separator\endcsname + \page_mix_command_inject_separator + \else + \hss + \fi + \fi} + \unexpanded\def\page_mix_routine_package {\ctxcommand{mixfinalize()}% \setbox\b_page_mix_collected\vbox \bgroup @@ -560,21 +595,9 @@ \fi \hskip\d_page_mix_leftskip \page_mix_hbox to \d_page_mix_max_width \bgroup - \dorecurse\c_page_mix_n_of_columns{% - % needs packaging anyway - \setbox\scratchbox\page_mix_command_package_column - \page_marks_synchronize_column\plusone\c_page_mix_n_of_columns\recurselevel\scratchbox - % backgrounds - \anch_mark_column_box\scratchbox - % for the moment a quick and dirty patch .. we need to go into the box (hence the \plusone) .. a slowdowner - \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_mix_n_of_columns\plusone - % the framed needs a reset of strut, align, setups etc - \inheritedmixedcolumnsframedbox\currentmixedcolumns\scratchbox - % optional - \ifnum\recurselevel<\c_page_mix_n_of_columns - \page_mix_command_inject_separator - \fi - }% + \edef\p_separator{\mixedcolumnsparameter\c!separator}% + \mixedcolumnseparatorwidth\d_page_mix_distance % \mixedcolumnsparameter\c!rulethickness\relax + \dorecurse\c_page_mix_n_of_columns\page_mix_routine_package_step \egroup \egroup} diff --git a/tex/context/base/s-abr-01.tex b/tex/context/base/s-abr-01.tex index 044b30f32..71c377418 100644 --- a/tex/context/base/s-abr-01.tex +++ b/tex/context/base/s-abr-01.tex @@ -66,6 +66,8 @@ \logo [CMYK] {cmyk} \logo [CODHOST] {CodHost} \logo [CONTEXT] {\ConTeXt} +\logo [CONTEXTWIKI] {\ConTeXt\ Wiki} +\logo [CONTEXTGROUP] {\ConTeXt\ Group} \logo [CSS] {css} \logo [CTAN] {ctan} \logo [CTXTOOLS] {ctxtools} @@ -236,6 +238,7 @@ \logo [SSD] {ssd} \logo [SVG] {svg} \logo [STIX] {Stix} +\logo [SUMATRAPDF] {SumatraPDF} \logo [SWIG] {swig} \logo [SWIGLIB] {SwigLib} \logo [TABLE] {\TaBlE} @@ -263,6 +266,7 @@ \logo [TEXTOOLS] {\TeX tools} \logo [TEXUTIL] {\TeX util} \logo [TEXWORK] {\TeX work} +\logo [TEXWORKS] {\TeX works} \logo [TEXXET] {\TeX\XeT} \def\XeT{XeT} \logo [TFM] {tfm} \logo [TIF] {tif} diff --git a/tex/context/base/s-art-01.mkiv b/tex/context/base/s-art-01.mkiv index e2584a357..601ee1adc 100644 --- a/tex/context/base/s-art-01.mkiv +++ b/tex/context/base/s-art-01.mkiv @@ -2,7 +2,7 @@ \startmodule[art-01] -\definemeasure [article:margin] [\paperheight/15] +\definemeasure [article:margin] [\paperheight/20] % was 15, see xtables-mkiv for results \definemeasure [overview:margin] [\paperheight/30] \definelayout @@ -10,7 +10,7 @@ [\c!topspace=\measure{article:margin}, \c!bottomspace=\measure{article:margin}, \c!backspace=\measure{article:margin}, - \c!header=\measure{overview:margin}, + \c!header=\measure{article:margin}, \c!footer=0pt, \c!width=\v!middle, \c!height=\v!middle] diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index 3afddc79a..88c6d30da 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -42,6 +42,7 @@ local nodes, node, trackers, attributes, context, commands, tex = nodes, node, local texlists = tex.lists local texgetdimen = tex.getdimen +local texsetdimen = tex.setdimen local texnest = tex.nest local variables = interfaces.variables @@ -109,6 +110,7 @@ local nodepool = nuts.pool local new_penalty = nodepool.penalty local new_kern = nodepool.kern local new_rule = nodepool.rule +local new_glue = nodepool.glue local new_gluespec = nodepool.gluespec local nodecodes = nodes.nodecodes @@ -1000,50 +1002,51 @@ end -- -- we could inject a vadjust to force a recalculation .. a mess -- --- so, the next is far from robust and okay but for the moment this overlaying --- has to do +-- So, the next is far from robust and okay but for the moment this overlaying +-- has to do. Always test this with the examples in spec-ver.mkvi! -local function check_experimental_overlay(head,current) -- todo +local function check_experimental_overlay(head,current) local p = nil local c = current local n = nil -- setfield(head,"prev",nil) -- till we have 0.79 ** - local function overlay(p,n,s,mvl) + local function overlay(p,n,mvl) local p_ht = getfield(p,"height") local p_dp = getfield(p,"depth") local n_ht = getfield(n,"height") - local delta = n_ht + s + p_dp - if trace_vspacing then - report_vspacing("overlaying, prev height: %p, prev depth: %p, next height: %p, skips: %p, move up: %p",p_ht,p_dp,n_ht,s,delta) + local skips = 0 + -- + -- We deal with this at the tex end .. we don't see spacing .. enabling this code + -- is probably harmless btu then we need to test it. + -- + local c = getnext(p) + while c and c ~= n do + local id = getid(c) + if id == glue_code then + skips = skips + getfield(getfield(c,"glue_spec"),"width") + elseif id == kern_code then + skips = skips + getfield(c,"kern") + end + c = getnext(c) end + -- + local delta = n_ht + skips + p_dp + texsetdimen("global","d_spac_overlay",-delta) -- for tracing + local k = new_kern(-delta) if n_ht > p_ht then - -- we should adapt pagetotal ! (need a hook for that) + -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak setfield(p,"height",n_ht) end - -- make kern - local k = new_kern(-delta) - if head == current then - head = k -- as it will get appended, else we loose the kern + insert_node_before(head,n,k) + if p == head then + head = k end - -- remove rubish - local c = getnext(p) - while c and c ~= n do - local nc = getnext(c) - if c == head then - head = nc - end - free_node(c) - c = nc + if trace_vspacing then + report_vspacing("overlaying, prev height: %p, prev depth: %p, next height: %p, skips: %p, move up: %p",p_ht,p_dp,n_ht,skips,delta) end - -- insert kern .. brr the kern is somehow not seen unless we also inject a penalty - setfield(p,"next",k) - setfield(k,"prev",p) - setfield(k,"next",n) - setfield(n,"prev",k) - -- done - return head, n + return remove_node(head,current,true) end -- goto next line @@ -1077,38 +1080,23 @@ local function check_experimental_overlay(head,current) -- todo if a_snapmethod == a_snapvbox then -- quit, we're not on the mvl else - -- messy local c = tonut(texlists.page_head) - local s = 0 - while c do + while c and c ~= n do local id = getid(c) - if id == glue_code then - if p then - s = s + getfield(getfield(c,"glue_spec"),"width") - end - elseif id == kern_code then - if p then - s = s + getfield(c,"kern") - end - elseif id == penalty_code then - -- skip (actually, remove) - elseif id == hlist_code then + if id == hlist_code then p = c - s = 0 - else - p = nil - s = 0 end c = getnext(c) end if p and p ~= n then - return overlay(p,n,s,true) + return overlay(p,n,true) end end elseif p ~= n then - return overlay(p,n,0,false) + return overlay(p,n,false) end end + -- in fact, we could try again later ... so then no remove (a few tries) return remove_node(head, current, true) end diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv index 0289a0419..d61c7651b 100644 --- a/tex/context/base/spac-ver.mkiv +++ b/tex/context/base/spac-ver.mkiv @@ -1915,13 +1915,21 @@ \fi\fi \relax} -% \startitemize[n] -% \item \input zapf -% \item \startitemize[a] -% \item \input knuth -% \stopitemize -% \stopitemize +% used in itemize ... always test this + +\newdimen\d_spac_overlay + +\def\spac_overlay_lines + {\blank[\v!back,\v!overlay]% + \nointerlineskip} +% \startitemize[n] +% \item \input zapf +% \item \startitemize[a] +% \item \input knuth +% \stopitemize +% \stopitemize +% % \strut \hfill first line \blank[overlay] second line \hfill \strut % % \ruledvbox { @@ -1929,6 +1937,9 @@ % line 2 \hfill \strut \blank[overlay] % \strut \hfill line 3 \hfill \strut % } +% +% \dorecurse{50} +% {\startitemize[n] \startitem \startitemize[a] \item #1 \stopitemize \stopitem \stopitemize} \definevspacing[\v!preference][penalty:-500] % goodbreak \definevspacing[\v!samepage] [penalty:10000] % nobreak diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex 327d429ed..af2f651d4 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf Binary files differindex eb13c54a9..6df64a555 100644 --- a/tex/context/base/status-lua.pdf +++ b/tex/context/base/status-lua.pdf diff --git a/tex/context/base/strc-itm.mkvi b/tex/context/base/strc-itm.mkvi index af03d13e1..2edcedfff 100644 --- a/tex/context/base/strc-itm.mkvi +++ b/tex/context/base/strc-itm.mkvi @@ -1036,23 +1036,7 @@ \strc_itemgroups_start_item_next \fi \ifconditional\c_strc_itemgroups_concat - % % not good enough: - % - % \vskip-\lastskip % we cannot use a \dimexpr here because - % \vskip-\lineheight % then we loose the stretch and shrink - % \nobreak - % - % % new per 2014-11-16 - % - % \blank[\v!overlay]% new per 2014-03-27 - % - % % changed per 2014-11-16 as somehow we need a penalty to prevent the kern from disappearing - % % .. .kind of fight with default tex append-to-mvl behaviour .. so still not good enough - % - %\blank[\v!back]% - \nobreak - \blank[\v!overlay]% - % + \spac_overlay_lines % see spac-ver.mkvi ... a typical potential problem \setfalse\c_strc_itemgroups_concat \fi \dostarttagged\t!item\empty diff --git a/tex/context/base/tabl-ntb.mkii b/tex/context/base/tabl-ntb.mkii index 465ed44b2..fbf43eb1e 100644 --- a/tex/context/base/tabl-ntb.mkii +++ b/tex/context/base/tabl-ntb.mkii @@ -423,7 +423,9 @@ \ifcsname\@@tblprefix\c!x\positivecol\c!y\positiverow\endcsname\csname\@@tblprefix\c!x\positivecol\c!y\positiverow\endcsname\fi \ifcsname\@@tblprefix\c!x\negativecol\c!y\negativerow\endcsname\csname\@@tblprefix\c!x\negativecol\c!y\negativerow\endcsname\fi % done - \global\letcscsname\@@tblsplitafter\csname\@@tbl\@@tbl\c!after\endcsname + \global\letcscsname\@@tblsplitafter \csname\@@tbl\@@tbl\c!after \endcsname + \global\letcscsname\@@tblsplitbefore \csname\@@tbl\@@tbl\c!before \endcsname + \global\letcscsname\@@tblsplitsamepage\csname\@@tbl\@@tbl\c!samepage\endcsname \relax} % we cannot use +n (checking on number/last/first would slow down too much) @@ -439,7 +441,9 @@ % \dorecurse{10}{\bTR \dorecurse{6}{\bTD xxx \eTD} \eTR} % \eTABLE -\globallet\@@tblsplitafter\relax +\globallet\@@tblsplitafter \relax +\globallet\@@tblsplitbefore \relax +\globallet\@@tblsplitsamepage\relax % split + page: % @@ -851,7 +855,17 @@ {\noalign {\global\advance\tblrow\plusone \global\tblcol\zerocount - \global\tblspn\zerocount}% + \global\tblspn\zerocount + \bgroup % protect local vars + \@@tblsplitbefore + \egroup + \ifx\@@tblsplitsamepage\v!before + \unpenalty + \nobreak + \else\ifx\@@tblsplitsamepage\v!both + \unpenalty + \nobreak + \fi\fi}% \nexttblcol \kern\dimexpr\tbltblleftmargindistance-\tbltblcolumndistance\relax} @@ -862,7 +876,14 @@ {\nointerlineskip \ifnum\tblrow>\noftblheadlines \ifnum\gettblnob\tblrow=\zerocount - \allowbreak + \unpenalty + \ifx\@@tblsplitsamepage\v!after + \nobreak + \else\ifx\@@tblsplitsamepage\v!both + \nobreak + \else + \allowbreak + \fi\fi \fi \else \allowbreak % else no proper head split off diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv index eba1527de..04d4cadbd 100644 --- a/tex/context/base/tabl-ntb.mkiv +++ b/tex/context/base/tabl-ntb.mkiv @@ -231,6 +231,13 @@ \installcorenamespace{naturaltableref} \installcorenamespace{naturaltableset} \installcorenamespace{naturaltablecell} +\installcorenamespace{naturaltablesqueeze} + +\letvalue{\??naturaltablesqueeze }\donefalse +\letvalue{\??naturaltablesqueeze\v!fit }\donetrue +\letvalue{\??naturaltablesqueeze\v!fixed}\donetrue +\letvalue{\??naturaltablesqueeze\v!broad}\donetrue +\letvalue{\??naturaltablesqueeze\v!local}\donetrue \def\tabl_ntb_let_gal{\global\expandafter\let\csname\??naturaltablegal\m_tabl_tbl_level\endcsname} \def\tabl_ntb_get_gal{\csname\??naturaltablegal\m_tabl_tbl_level\endcsname} @@ -294,15 +301,22 @@ % \def\tabl_ntb_row_state#1#2{\ifcsname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname\zerocount\else\plusone\fi} % \def\tabl_ntb_col_state#1#2{\ifcsname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname\zerocount\else\plusone\fi} -\def\tabl_ntb_set_spn #1{\expandafter\let\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname \!!plusone} -\def\tabl_ntb_spn_doifelse#1{\doifelse {\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname}\!!plusone} +%def\tabl_ntb_set_spn #1{\expandafter\let\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname \!!plusone} +%def\tabl_ntb_spn_doifelse#1{\doifelse {\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname}\!!plusone} -\def\tabl_ntb_set_spn #1{\setvalue {\??naturaltablespn\m_tabl_tbl_level:\number#1}{1}} -\def\tabl_ntb_spn_doifelse#1{\doifelsevalue{\??naturaltablespn\m_tabl_tbl_level:\number#1}{1}} +%def\tabl_ntb_set_spn #1{\setvalue {\??naturaltablespn\m_tabl_tbl_level:\number#1}{1}} +%def\tabl_ntb_spn_doifelse#1{\doifelsevalue{\??naturaltablespn\m_tabl_tbl_level:\number#1}{1}} -\def\tabl_ntb_let_ref#1#2{\expandafter\glet\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname} -\def\tabl_ntb_set_ref#1#2{\expandafter\xdef\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname} -\def\tabl_ntb_get_ref#1#2{\ifcsname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname\fi} +\def\tabl_ntb_let_ref #1#2{\expandafter\glet\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname} +\def\tabl_ntb_set_ref #1#2{\expandafter\xdef\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname} +\def\tabl_ntb_get_ref #1#2{\ifcsname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname\fi} + +\def\tabl_ntb_set_spn #1{\expandafter\let\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname \!!plusone} +\def\tabl_ntb_spn_doifelse#1{\ifcase0\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname\relax % could be inlined + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} % keep for a while: % @@ -562,7 +576,9 @@ % local \ifcsname\m_tabl_ntb_prefix\c!y++\m_tabl_ntb_positive_row\endcsname\csname\m_tabl_ntb_prefix\c!y++\m_tabl_ntb_positive_row\endcsname\fi % done - \xdef\m_tabl_ntb_after_split{\naturaltablelocalparameter\c!after}% to be checked + \xdef\m_tabl_ntb_before_split{\naturaltablelocalparameter\c!before}% to be checked + \xdef\m_tabl_ntb_after_split {\naturaltablelocalparameter\c!after }% to be checked + \xdef\m_tabl_ntb_same_page {\naturaltablelocalparameter\c!samepage}% \relax} % we cannot use +n (checking on number/last/first would slow down too much) @@ -578,7 +594,9 @@ % \dorecurse{10}{\bTR \dorecurse{6}{\bTD xxx \eTD} \eTR} % \eTABLE -\let\m_tabl_ntb_after_split\relax +\let\m_tabl_ntb_before_split\empty +\let\m_tabl_ntb_after_split \empty +\let\m_tabl_ntb_same_page \empty % split + page: % @@ -1106,7 +1124,18 @@ \let\m_tabl_ntb_saved_col\!!zerocount \def\tabl_ntb_row_align_start - {\noalign{\tabl_ntb_row_align_reset}% + {\noalign + {\tabl_ntb_row_align_reset + \bgroup % protect local vars + \m_tabl_ntb_before_split + \egroup + \ifx\m_tabl_ntb_same_page\v!before + \unpenalty + \nobreak + \else\ifx\m_tabl_ntb_same_page\v!both + \unpenalty + \nobreak + \fi\fi}% \tabl_ntb_column_next \kern\dimexpr\naturaltablelocalparameter\c!leftmargindistance-\naturaltablelocalparameter\c!columndistance\relax} @@ -1122,7 +1151,14 @@ {\nointerlineskip \ifnum\c_tabl_ntb_row>\c_tabl_ntb_n_of_head_lines \ifnum\tabl_ntb_get_nob\c_tabl_ntb_row=\zerocount - \allowbreak + \unpenalty + \ifx\m_tabl_ntb_same_page\v!after + \nobreak + \else\ifx\m_tabl_ntb_same_page\v!both + \nobreak + \else + \allowbreak + \fi\fi \fi \else \allowbreak % else no proper head split off @@ -1134,8 +1170,10 @@ \scratchcounter\numexpr\c_tabl_ntb_row+\plusone\relax \ifnum\scratchcounter>\c_tabl_ntb_n_of_hdnx_lines\relax \ifnum\scratchcounter<\c_tabl_ntb_maximum_row\relax - \doifsomething{\naturaltablelocalparameter\c!spaceinbetween} - {\blank[\naturaltablelocalparameter\c!spaceinbetween]}% + \edef\p_spaceinbetween{\naturaltablelocalparameter\c!spaceinbetween}% + \ifx\p_spaceinbetween\empty\else + \blank[\p_spaceinbetween]% + \fi \fi \fi \egroup}} @@ -1425,6 +1463,7 @@ \def\tsplitbeforeresult {\beforeTABLEsplitbox}% \def\tsplitafterresult {\afterTABLEsplitbox}% \def\tsplitafter {\m_tabl_ntb_after_split}% + \def\tsplitbefore {\m_tabl_ntb_before_split}% supported ? \setbox\tsplitcontent\vbox{#1}% \ifmultipleTBLheads \dorecurse\c_tabl_ntb_n_of_head_lines @@ -1434,8 +1473,10 @@ {\setbox\scratchbox\vsplit\tsplitcontent to \lineheight \setbox\tsplitnext\vbox{\unvcopy\tsplitnext\unvcopy\scratchbox}}% \fi - \doifsomething{\naturaltablelocalparameter\c!spaceinbetween} - {\def\tsplitinbetween{\blank[\naturaltablelocalparameter\c!spaceinbetween]}}% + \edef\p_spaceinbetween{\naturaltablelocalparameter\c!spaceinbetween}% + \ifx\p_spaceinbetween\empty\else + \blank[\p_spaceinbetween]% + \fi \def\postprocesstsplit{\postprocessTABLEsplitbox{\box\tsplitresult}}% \handletsplit} @@ -1625,8 +1666,8 @@ \ifdim\wd\scratchbox>\scratchdimen \ifsqueezeTBLspan \ifautosqueezeTBLspan - \doifinsetelse{\naturaltablelocalparameter\c!width}{\v!fit,\v!fixed,\v!broad,\v!local} - \donetrue \donefalse + \edef\p_width{\naturaltablelocalparameter\c!width}% + \csname\??naturaltablesqueeze\ifcsname\??naturaltablesqueeze\p_width\endcsname\p_width\fi\endcsname \else \donetrue \fi diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv index 52c452235..f538747a3 100644 --- a/tex/context/base/tabl-tbl.mkiv +++ b/tex/context/base/tabl-tbl.mkiv @@ -1100,20 +1100,20 @@ % {\bgroup % \edef\currenttabulationparent{#1}% % \let\currenttabulation\currenttabulationparent -% \doifnextoptionalcselse\tabl_start_defined_yes\tabl_start_defined_nop} -% -% \def\tabl_start_defined_yes[#1]% -% {\edef\currenttabulation{\currenttabulation:#1}% -% \tabl_tabulate_start_building} -% -% \def\tabl_start_defined_nop -% {\tabl_tabulate_start_building} +% \dodoubleargument\tabl_start_defined_indeed} \unexpanded\def\tabl_start_defined[#1]% {\bgroup \edef\currenttabulationparent{#1}% \let\currenttabulation\currenttabulationparent - \dodoubleargument\tabl_start_defined_indeed} + \edef\p_format{\tabulationparameter\c!format}% + \ifx\p_format\v!none + % this is special case: we need to define the generic english + % \starttabulate in other interfaces as well + \expandafter\dodoubleempty \expandafter\tabl_start_regular + \else + \expandafter\dodoubleargument\expandafter\tabl_start_defined_indeed + \fi} \def\tabl_start_defined_indeed {\iffirstargument @@ -1144,26 +1144,11 @@ \unexpanded\setuvalue{\e!start\v!tabulate}% {\bgroup % whole thing + \let\currenttabulationparent\empty \dodoubleempty\tabl_start_regular} -% \def\tabl_start_regular[#1][#2]% -% {%\let\currenttabulationparent\v!tabulate -% \let\currenttabulationparent\empty -% \let\currenttabulation\currenttabulationparent -% \def\p_format{#1}% -% \ifx\p_format\empty -% \def\p_format{|l|p|}% -% \fi -% \lettabulationparameter\c!format\p_format -% \ifsecondargument -% \setupcurrenttabulation[#2]% -% \fi -% \tabl_tabulate_start_building} - \def\tabl_start_regular - {%\let\currenttabulationparent\v!tabulate - \let\currenttabulationparent\empty - \let\currenttabulation\currenttabulationparent + {\let\currenttabulation\currenttabulationparent \ifsecondargument \expandafter\tabl_start_regular_two \else @@ -2452,4 +2437,10 @@ %D \stopwhatever %D \stoptyping +%D This is needed because we soemtimes use the english command in +%D tracing macros. In fact, most detailed tracing macros that +%D are done with \LUA\ only work in the english interface anyway. + +\definetabulate[tabulate] \setuptabulate[tabulate][\c!format=\v!none] % so no \v! here + \protect \endinput diff --git a/tex/context/base/tabl-xtb.lua b/tex/context/base/tabl-xtb.lua index 89ef21b79..3503d5351 100644 --- a/tex/context/base/tabl-xtb.lua +++ b/tex/context/base/tabl-xtb.lua @@ -41,6 +41,8 @@ local format = string.format local concat = table.concat local points = number.points +local todimen = string.todimen + local context_beginvbox = context.beginvbox local context_endvbox = context.endvbox local context_blank = context.blank @@ -83,6 +85,10 @@ local v_repeat = variables["repeat"] local v_max = variables.max local v_fixed = variables.fixed local v_auto = variables.auto +local v_before = variables.before +local v_after = variables.after +local v_both = variables.both +local v_samepage = variables.samepage local xtables = { } typesetters.xtables = xtables @@ -122,6 +128,7 @@ function xtables.create(settings) local fixedcolumns = { } local frozencolumns = { } local options = { } + local rowproperties = { } data = { rows = rows, widths = widths, @@ -140,6 +147,7 @@ function xtables.create(settings) currentrow = 0, currentcolumn = 0, settings = settings or { }, + rowproperties = rowproperties, } local function add_zero(t,k) t[k] = 0 @@ -200,7 +208,7 @@ function xtables.create(settings) end -function xtables.initialize_reflow_width(option) +function xtables.initialize_reflow_width(option,width) local r = data.currentrow local c = data.currentcolumn + 1 local drc = data.rows[r][c] @@ -365,6 +373,8 @@ function xtables.initialize_reflow_height() elseif data.autowidths[c] then -- width has changed so we need to recalculate the height texsetcount("c_tabl_x_skip_mode",0) + elseif data.fixedcolumns[c] then + texsetcount("c_tabl_x_skip_mode",0) -- new else texsetcount("c_tabl_x_skip_mode",1) end @@ -725,6 +735,7 @@ function xtables.construct() local rowdistance = settings.rowdistance local leftmargindistance = settings.leftmargindistance local rightmargindistance = settings.rightmargindistance + local rowproperties = data.rowproperties -- ranges can be mixes so we collect if trace_xtable then @@ -817,15 +828,30 @@ function xtables.construct() result[nofr][4] = true end nofr = nofr + 1 + local rp = rowproperties[r] result[nofr] = { -- hpack_node_list(list), hpack_node_list(list,0,"exactly","TLT"), -- otherwise weird lap size, i < nofrange and rowdistance > 0 and rowdistance or false, -- might move - false + false, + rp and rp.samepage or false, } end end + if nofr > 0 then + -- the [5] slot gets the after break + result[1] [5] = false + result[nofr][5] = false + for i=2,nofr-1 do + local r = result[i] + if r == v_both or r == v_before then + result[i-1][5] = true + elseif r == v_after then + result[i][5] = true + end + end + end return result end local body = collect_range(ranges[body_mode]) @@ -859,6 +885,12 @@ local function inject(row,copy,package) context_nointerlineskip() -- figure out a better way if row[4] then -- nothing as we have a span + elseif row[5] then + if row[3] then + context_blank { v_samepage, row[3] .. "sp" } + else + context_blank { v_samepage } + end elseif row[3] then context_blank { row[3] .. "sp" } -- why blank ? else @@ -1104,11 +1136,13 @@ function xtables.cleanup() data = table.remove(stack) end -function xtables.next_row() +function xtables.next_row(specification) local r = data.currentrow + 1 data.modes[r] = texgetcount("c_tabl_x_mode") data.currentrow = r data.currentcolumn = 0 + data.rowproperties[r] = specification + end -- eventually we might only have commands diff --git a/tex/context/base/tabl-xtb.mkvi b/tex/context/base/tabl-xtb.mkvi index 05cfef17b..43914137d 100644 --- a/tex/context/base/tabl-xtb.mkvi +++ b/tex/context/base/tabl-xtb.mkvi @@ -259,6 +259,7 @@ \unexpanded\def\tabl_x_process {\begingroup % * + \dontcomplain % for the moment here till we figure out where we get the overflow \doifsomething{\xtableparameter\c!bodyfont} {\setupbodyfont[\xtableparameter\c!bodyfont]}% \setbox\scratchbox\vbox @@ -421,7 +422,9 @@ \unexpanded\def\tabl_x_start_row_construct_yes[#settings]% {\setupcurrentxtable[#settings]% \dostarttagged\t!tablerow\empty - \ctxcommand{x_table_next_row()}} + \ctxcommand{x_table_next_row{ + samepage = "\xtableparameter\c!samepage", + }}} \unexpanded\def\tabl_x_start_row_construct_nop {\dostarttagged\t!tablerow\empty diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index 71d2fec1c..3db0c2d6e 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -48,8 +48,8 @@ appendaction("processors", "fonts", "builders.paragraphs.solutions.split appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo appendaction("processors", "fonts", "nodes.injections.handler") -- maybe todo appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo -appendaction("processors", "fonts", "builders.kernel.ligaturing") -- always on (could be selective: if only node mode) -appendaction("processors", "fonts", "builders.kernel.kerning") -- always on (could be selective: if only node mode) +------------("processors", "fonts", "builders.kernel.ligaturing") -- always on (could be selective: if only node mode) +------------("processors", "fonts", "builders.kernel.kerning") -- always on (could be selective: if only node mode) appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move) ------------("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling) diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua index eb5373ee3..20b89bdf0 100644 --- a/tex/context/base/trac-vis.lua +++ b/tex/context/base/trac-vis.lua @@ -740,7 +740,7 @@ local function ruledpenalty(head,current,vertical) return head, getnext(current) end -local function visualize(head,vertical) +local function visualize(head,vertical,forced) local trace_hbox = false local trace_vbox = false local trace_vtop = false @@ -760,7 +760,7 @@ local function visualize(head,vertical) local prev_trace_fontkern = nil while current do local id = getid(current) - local a = getattr(current,a_visual) or unsetvalue + local a = forced or getattr(current,a_visual) or unsetvalue if a ~= attr then prev_trace_fontkern = trace_fontkern if a == unsetvalue then @@ -801,19 +801,17 @@ local function visualize(head,vertical) head, current = ruledglyph(head,current,previous) end elseif id == disc_code then - if trace_glyph then - local pre = getfield(current,"pre") - if pre then - setfield(current,"pre",ruledglyph(pre,pre)) - end - local post = getfield(current,"post") - if post then - setfield(current,"post",ruledglyph(post,post)) - end - local replace = getfield(current,"replace") - if replace then - setfield(current,"replace",ruledglyph(replace,replace)) - end + local pre = getfield(current,"pre") + if pre then + setfield(current,"pre",visualize(pre,false,a)) + end + local post = getfield(current,"post") + if post then + setfield(current,"post",visualize(post,false,a)) + end + local replace = getfield(current,"replace") + if replace then + setfield(current,"replace",visualize(replace,false,a)) end elseif id == kern_code then local subtype = getsubtype(current) @@ -838,10 +836,6 @@ local function visualize(head,vertical) if trace_penalty then head, current = ruledpenalty(head,current,vertical) end - elseif id == disc_code then - setfield(current,"pre",visualize(getfield(current,"pre"))) - setfield(current,"post",isualize(getfield(current,"post"))) - setfield(current,"replace",visualize(getfield(current,"replace"))) elseif id == hlist_code then local content = getlist(current) if content then diff --git a/tex/context/base/typo-lig.mkiv b/tex/context/base/typo-lig.mkiv new file mode 100644 index 000000000..6171441d6 --- /dev/null +++ b/tex/context/base/typo-lig.mkiv @@ -0,0 +1,31 @@ +%D \module +%D [ file=typo-lig, +%D version=2014.12.01, +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Ligatures, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Typesetting Macros / Ligatures} + +%D This macro is mostly used for testing an attribute that blocks ligatures +%D in the nodemode handler. It is not really used in practice, and mostly +%D there as a plug in the generic font handler. + +\unprotect + +\definesystemattribute[noligature][public] + +\unexpanded\def\noligature#1% + {\dontleavehmode + \begingroup + \attribute\noligatureattribute\plusone + #1% + \endgroup} + +\protect \endinput diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua index 2a93f8492..b0906020e 100644 --- a/tex/context/base/typo-mar.lua +++ b/tex/context/base/typo-mar.lua @@ -753,19 +753,23 @@ local function flushed(scope,parent) -- current is hlist for l=1,#locations do local location = locations[l] local store = displaystore[category][location][scope] - while true do - local candidate = remove(store,1) -- brr, local stores are sparse - if candidate then -- no vpack, as we want to realign - head, room, con = inject(parent,head,candidate) - done = true - continue = continue or con - nofstored = nofstored - 1 - if room then - registertogether(tonode(parent),room) -- !! tonode + if store then + while true do + local candidate = remove(store,1) -- brr, local stores are sparse + if candidate then -- no vpack, as we want to realign + head, room, con = inject(parent,head,candidate) + done = true + continue = continue or con + nofstored = nofstored - 1 + if room then + registertogether(tonode(parent),room) -- !! tonode + end + else + break end - else - break end + else + -- report_margindata("fatal error: invalid category %a",category or "?") end end end @@ -851,15 +855,15 @@ function margins.globalhandler(head,group) -- check group end return head, false elseif group == "hmode_par" then - return handler("global",head,group) + return handler(v_global,head,group) elseif group == "vmode_par" then -- experiment (for alignments) - return handler("global",head,group) + return handler(v_global,head,group) -- this needs checking as we then get quite some one liners to process and -- we cannot look ahead then: elseif group == "box" then -- experiment (for alignments) - return handler("global",head,group) + return handler(v_global,head,group) elseif group == "alignment" then -- experiment (for alignments) - return handler("global",head,group) + return handler(v_global,head,group) else if trace_margingroup then report_margindata("ignored 2, group %a, stored %s, inhibit %a",group,nofstored,inhibit) diff --git a/tex/context/base/typo-txt.mkvi b/tex/context/base/typo-txt.mkvi index fa79a4f6b..7562fe70c 100644 --- a/tex/context/base/typo-txt.mkvi +++ b/tex/context/base/typo-txt.mkvi @@ -194,4 +194,51 @@ %D \HL %D \stoptabulate +%D This is used in the beginners manual. One needs to set the font size to an +%D acceptable value for this to work. + +\unexpanded\def\startnicelyfilledbox + {\vbox\bgroup + \forgetall + \dosingleempty\dostartnicelyfilledbox} + +\def\dostartnicelyfilledbox[#1]% + {\letdummyparameter\c!width \hsize + \letdummyparameter\c!height\vsize + \letdummyparameter\c!offset\exheight % we obey to the outer exheight + \letdummyparameter\c!strut \v!yes % we obey to the inner strut ! + \getdummyparameters[#1]% + \scratchoffset\dummyparameter\c!offset\relax + \setbox\scratchbox\vbox to \dummyparameter\c!height \bgroup + \hsize\dummyparameter\c!width\relax + \emergencystretch10\scratchoffset + \parfillskip\zeropoint + \baselineskip\zeropoint plus \onepoint minus \onepoint + \beginofshapebox + \leftskip \scratchoffset + \rightskip\scratchoffset} + +\unexpanded\def\stopnicelyfilledbox + {\doifelse{\dummyparameter\c!strut}\v!yes + {\xdef\doflushnicelyfilledbox + {\ht\shapebox\the\strutht + \dp\shapebox\the\strutdp + \box\shapebox}}% + {\gdef\doflushnicelyfilledbox + {\box\shapebox}}% + \endofshapebox + \doreshapebox + {\doflushnicelyfilledbox} + {\penalty\shapepenalty} + {\kern\shapekern} + {\vfil}% + \kern\scratchoffset + \vfilneg + \flushshapebox + \vfilneg + \kern\scratchoffset + \egroup + \box\scratchbox + \egroup} + \protect \endinput diff --git a/tex/context/base/x-set-12.mkiv b/tex/context/base/x-set-12.mkiv index 6590bfe9e..c60445313 100644 --- a/tex/context/base/x-set-12.mkiv +++ b/tex/context/base/x-set-12.mkiv @@ -146,8 +146,7 @@ [\c!alternative=\v!doublesided] \setupsetup - [\c!criterium=\v!all, - \c!reference=0] + [\c!criterium=\v!all] \setupframedtexts [setuptext] diff --git a/tex/context/extra/showunic.tex b/tex/context/extra/showunic.tex deleted file mode 100644 index efdbf4d3a..000000000 --- a/tex/context/extra/showunic.tex +++ /dev/null @@ -1,130 +0,0 @@ -% author : Hans Hagen / PRAGMA-ADE -% version : 2005-06-22 - -% todo: take antiqua (has everything) - -% \tracetypescriptstrue - -\usetypescriptfile[type-cbg] - -% \preloadtypescriptstrue (default at pragma) - -% this font does not work ... why -% -% \starttypescript [serif] [hebrew] [default] -% \definefontsynonym [Serif] [hclassic] -% \loadmapline[=][hclassic < hclassic.pfb] -% \stoptypescript - -\setuppapersize - [S6][S6] - -\setupbodyfont - [10pt] - -\setuplayout - [backspace=12pt, - topspace=12pt, - width=middle, - height=middle, - header=0pt, - footer=0pt] - -\setupcolors - [state=start] - -\setupbackgrounds - [page] - [background=color, - backgroundcolor=darkgray] - -\definetypeface [main-latin] [rm] [serif] [latin-modern] [default][encoding=texnansi] -\definetypeface [main-latin] [tt] [mono] [latin-modern] [default][encoding=texnansi] - -\definetypeface [main-math] [rm] [serif] [latin-modern] [default][encoding=texnansi] -\definetypeface [main-math] [tt] [mono] [latin-modern] [default][encoding=texnansi] -\definetypeface [main-math] [mm] [math] [latin-modern] [default][encoding=default] - -\definetypeface [main-eastern] [rm] [serif] [latin-modern] [default][encoding=qx] -\definetypeface [main-eastern] [tt] [mono] [latin-modern] [default][encoding=texnansi] - -\definetypeface [main-greek] [rm] [serif] [cbgreek] [default][encoding=default] -\definetypeface [main-greek] [tt] [mono] [latin-modern] [default][encoding=texnansi] - -\definetypeface [main-cyrillic] [rm] [serif] [computer-modern] [default][encoding=t2a] -\definetypeface [main-cyrillic] [tt] [mono] [latin-modern] [default][encoding=texnansi] - -% \definetypeface [main-hebrew] [rm] [serif] [hebrew] [default][encoding=default] -% \definetypeface [main-hebrew] [tt] [mono] [latin-modern] [default][encoding=texnansi] - -% The \showunicodetable macro is defined in unic-run.tex. - -\starttext - -% latin: western / eastern - -\startstandardmakeup - \setupbodyfont[main-latin] - \centerbox{\scale[factor=max]{\showunicodetable{000}}} -\stopstandardmakeup -\startstandardmakeup - \setupbodyfont[main-eastern] - \centerbox{\scale[factor=max]{\showunicodetable{001}}} -\stopstandardmakeup -\startstandardmakeup - \setupbodyfont[main-latin] - \centerbox{\scale[factor=max]{\showunicodetable{002}}} -\stopstandardmakeup - -% greek - -\startstandardmakeup - \setupbodyfont[main-greek] - \centerbox{\scale[factor=max]{\showunicodetable{003}}} -\stopstandardmakeup - -% cyrillic - -\startstandardmakeup - \setupbodyfont[main-cyrillic] - \centerbox{\scale[factor=max]{\showunicodetable{004}}} -\stopstandardmakeup - -% hebrew - -% \startstandardmakeup -% \setupbodyfont[mainhebrew] -% \centerbox{\scale[factor=max]{\showunicodetable{005}}} -% \stopstandardmakeup - -% misc - -\startstandardmakeup - \setupbodyfont[main-latin] - \centerbox{\scale[factor=max]{\showunicodetable{030}}} -\stopstandardmakeup -\startstandardmakeup - \setupbodyfont[main-latin] - \centerbox{\scale[factor=max]{\showunicodetable{031}}} -\stopstandardmakeup -\startstandardmakeup - \setupbodyfont[main-latin] - \centerbox{\scale[factor=max]{\showunicodetable{032}}} -\stopstandardmakeup - -% math - -\startstandardmakeup - \setupbodyfont[main-math] - \centerbox{\scale[factor=max]{\showunicodetable{033}}} -\stopstandardmakeup -\startstandardmakeup - \setupbodyfont[main-math] - \centerbox{\scale[factor=max]{\showunicodetable{034}}} -\stopstandardmakeup -\startstandardmakeup - \setupbodyfont[main-math] - \centerbox{\scale[factor=max]{\showunicodetable{039}}} -\stopstandardmakeup - -\stoptext diff --git a/tex/context/foxet/fe-bryson.xml b/tex/context/foxet/fe-bryson.xml deleted file mode 100644 index 28646b65f..000000000 --- a/tex/context/foxet/fe-bryson.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version='1.0'?> -<fe:sample xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng' origin='Bill Bryson'> -Imagine trying to live in a world dominated by dihydrogen oxide, a -compound that has no taste or smell and is so viable in its properties -that it is generally benign but at other times swiftly lethal. -Depending on its state, it can scald you or freeze you. In the -presence of certain organic molecules it can form carbonic acids so -nasty that they can strip the leaves from trees and eat the faces off -statuary. In bulk, when agitated, it can strike with a fury that no -human edifice could withstand. Even for those who have learned to live -with it, it is often murderous substance. We call it water. -</fe:sample> diff --git a/tex/context/foxet/fe-ward.xml b/tex/context/foxet/fe-ward.xml deleted file mode 100644 index 05f774265..000000000 --- a/tex/context/foxet/fe-ward.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version='1.0'?> -<fe:sample xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng' origin='Peter Ward'> -The Earth, as a habitat for animal life, is in old age and -has a fatal illness. Several, in fact. It would be happening -whether humans had ever evolved or not. But our presence is -like the effect of an old-age patient who smokes many packs -of cigarettes per day - and we humans are the cigarettes. -</fe:sample> diff --git a/tex/context/foxet/fe-zapf.xml b/tex/context/foxet/fe-zapf.xml deleted file mode 100644 index faf9a0831..000000000 --- a/tex/context/foxet/fe-zapf.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version='1.0'?> -<fe:sample xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng' origin='Hermann Zapf'> -Coming back to the use of typefaces in electronic -publishing: many of the new typographers receive their -knowledge and information about the rules of typography -from books, from computer magazines or the instruction -manuals which they get with the purchase of a PC or -software. There is not so much basic instruction, as of -now, as there was in the old days, showing the differences -between good and bad typographic design. Many people are -just fascinated by their PC's tricks, and think that a -widely<fe:compound/>praised program, called up on the -screen, will make everything automatic from now on. -</fe:sample> diff --git a/tex/context/foxet/fo-0101.fo b/tex/context/foxet/fo-0101.fo deleted file mode 100644 index 197c5834c..000000000 --- a/tex/context/foxet/fo-0101.fo +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='default'> - <fo:region-body/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='default'> - <fo:flow flow-name='xsl-region-body'/> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0102.fo b/tex/context/foxet/fo-0102.fo deleted file mode 100644 index 9adcf917e..000000000 --- a/tex/context/foxet/fo-0102.fo +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='default'> - <fo:region-body/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:declarations> - <fe:definecolor name='red' r='.6'/> - <fe:definecolor name='green' g='.6'/> - <fe:definecolor name='blue' b='.6'/> - <fe:definefontsynonym name='mono' file='lmtt10' encoding='texnansi'/> - </fo:declarations> - - <fo:page-sequence master-reference='default'> - <fo:flow flow-name='xsl-region-body'/> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0103.fo b/tex/context/foxet/fo-0103.fo deleted file mode 100644 index 95d0d4769..000000000 --- a/tex/context/foxet/fo-0103.fo +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='default'> - <fo:region-body/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:declarations> - <fo:color-profile src="url('myprofile.xml')" color-profile-name="myprofile"/> - </fo:declarations> - - <fo:page-sequence master-reference='default'> - <fo:flow flow-name='xsl-region-body'/> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0201.fo b/tex/context/foxet/fo-0201.fo deleted file mode 100644 index f524cfd09..000000000 --- a/tex/context/foxet/fo-0201.fo +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='1cm'> - <fo:region-body/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' line-height='18pt'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0301.fo b/tex/context/foxet/fo-0301.fo deleted file mode 100644 index e0b8a6fc4..000000000 --- a/tex/context/foxet/fo-0301.fo +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='1cm' fe:option='fit'> - <fo:region-body background-color='lightgray'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block-container space-after.optimum='12pt' fe:tracing='true'> - <fo:block> - before<fo:character character='@'/>after - </fo:block> - <fo:block> - before<fo:character character='@' vertical-align='super'/>after - before<fo:character character='@' vertical-align='sub' />after - before<fo:character character='@' vertical-align='-3pt' />after - before<fo:character character='@' vertical-align='+3pt' />after - </fo:block> - <fo:block> - before<fo:character character='@' glyph-orientation-horizontal='0deg' />after - before<fo:character character='@' glyph-orientation-horizontal='90deg' />after - before<fo:character character='@' glyph-orientation-horizontal='180deg'/>after - before<fo:character character='@' glyph-orientation-horizontal='270deg'/>after - </fo:block> - <fo:block> - before<fo:character character='@' glyph-orientation-horizontal='0deg' vertical-align='super'/>after - before<fo:character character='@' glyph-orientation-horizontal='90deg' vertical-align='super'/>after - before<fo:character character='@' glyph-orientation-horizontal='180deg' vertical-align='super'/>after - before<fo:character character='@' glyph-orientation-horizontal='270deg' vertical-align='super'/>after - </fo:block> - <fo:block> - before<fo:character character='@' glyph-orientation-horizontal='0deg' vertical-align='3pt'/>after - before<fo:character character='@' glyph-orientation-horizontal='90deg' vertical-align='3pt'/>after - before<fo:character character='@' glyph-orientation-horizontal='180deg' vertical-align='3pt'/>after - before<fo:character character='@' glyph-orientation-horizontal='270deg' vertical-align='3pt'/>after - </fo:block> - <fo:block> - before<fo:character character='@' vertical-align='super' text-altitude='10pt'/>after - before<fo:character character='@' vertical-align='super' text-altitude='20pt'/>after - before<fo:character character='@' vertical-align='100%' text-altitude='20pt'/>after - before<fo:character character='@' vertical-align='sub' text-depth='10pt' />after - before<fo:character character='@' vertical-align='sub' text-depth='20pt' />after - before<fo:character character='@' vertical-align='-100%' text-depth='20pt' />after - </fo:block> - </fo:block-container> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0601.fo b/tex/context/foxet/fo-0601.fo deleted file mode 100644 index 1e291f278..000000000 --- a/tex/context/foxet/fo-0601.fo +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' - margin-top='1cm' - margin-bottom='2cm' - margin-left='3cm' - margin-right='4cm'> - <fo:region-before extent='1cm' background-color='red' /> - <fo:region-after extent='1cm' background-color='green' /> - <fo:region-start extent='1cm' background-color='blue' /> - <fo:region-end extent='1cm' background-color='yellow'/> - <fo:region-body margin='2cm' background-color='gray' /> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0602.fo b/tex/context/foxet/fo-0602.fo deleted file mode 100644 index 36e864767..000000000 --- a/tex/context/foxet/fo-0602.fo +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' - margin-top='1cm' margin-bottom='2cm' margin-left='3cm' margin-right='4cm'> - <fo:region-body margin='2cm' background-color='gray' /> - <fo:region-before extent='1cm' background-color='red' precedence='true'/> - <fo:region-after extent='1cm' background-color='green' /> - <fo:region-start extent='1cm' background-color='blue' /> - <fo:region-end extent='1cm' background-color='yellow'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0603.fo b/tex/context/foxet/fo-0603.fo deleted file mode 100644 index 268249d3e..000000000 --- a/tex/context/foxet/fo-0603.fo +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' - margin-top='1cm' margin-bottom='2cm' margin-left='3cm' margin-right='4cm'> - <fo:region-body margin='2cm' background-color='gray' /> - <fo:region-before extent='1cm' background-color='red' /> - <fo:region-after extent='1cm' background-color='green' precedence='true'/> - <fo:region-start extent='1cm' background-color='blue' /> - <fo:region-end extent='1cm' background-color='yellow'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0604.fo b/tex/context/foxet/fo-0604.fo deleted file mode 100644 index 891198ee0..000000000 --- a/tex/context/foxet/fo-0604.fo +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' - margin-top='1cm' margin-bottom='2cm' margin-left='3cm' margin-right='4cm'> - <fo:region-body margin='2cm' background-color='gray' /> - <fo:region-before extent='1cm' background-color='red' precedence='true'/> - <fo:region-after extent='1cm' background-color='green' precedence='true'/> - <fo:region-start extent='1cm' background-color='blue' /> - <fo:region-end extent='1cm' background-color='yellow'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0611.fo b/tex/context/foxet/fo-0611.fo deleted file mode 100644 index 70f495fb6..000000000 --- a/tex/context/foxet/fo-0611.fo +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml' n='15'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0612.fo b/tex/context/foxet/fo-0612.fo deleted file mode 100644 index 4b3de6940..000000000 --- a/tex/context/foxet/fo-0612.fo +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm' column-count='2' column-gap='24pt'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml' n='25'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0613.fo b/tex/context/foxet/fo-0613.fo deleted file mode 100644 index f478a571d..000000000 --- a/tex/context/foxet/fo-0613.fo +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='1.25cm'> - <fo:region-body margin='0cm' column-count='3' column-gap='12pt'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml' n='15'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0621.fo b/tex/context/foxet/fo-0621.fo deleted file mode 100644 index 554fcc4a0..000000000 --- a/tex/context/foxet/fo-0621.fo +++ /dev/null @@ -1,106 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root - xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='any' margin='2cm'> - <fe:message>setting up simple page master 'any'</fe:message> - <fo:region-body background-color='darkgray' margin-top='2cm' margin-bottom='2cm' padding='.5cm'/> - <fo:region-before background-color='darkgray' extent='1cm'/> - <fo:region-after background-color='darkgray' extent='1cm'/> - </fo:simple-page-master> - <fo:simple-page-master master-name='first-page' margin='2cm'> - <fe:message>setting up simple page master 'first-page'</fe:message> - <fo:region-body background-color='red' margin='2cm' padding='.5cm'/> - <fo:region-before background-color='red' extent='1cm'/> - <fo:region-after background-color='red' extent='1cm'/> - </fo:simple-page-master> - <fo:simple-page-master master-name='left-page' margin='2cm'> - <fe:message>setting up simple page master 'left-page'</fe:message> - <fo:region-body background-color='green' margin='2cm' padding='.5cm'/> - <fo:region-before background-color='green' extent='1cm'/> - <fo:region-after background-color='green' extent='1cm'/> - </fo:simple-page-master> - <fo:simple-page-master master-name='right-page' margin='2cm'> - <fe:message>setting up simple page master 'right-page'</fe:message> - <fo:region-body background-color='blue' margin='2cm' padding='.5cm'/> - <fo:region-before background-color='blue' extent='1cm'/> - <fo:region-after background-color='blue' extent='1cm'/> - </fo:simple-page-master> - <fo:simple-page-master master-name='blank-page' margin='2cm'> - <fe:message>setting up simple page master 'blank-page'</fe:message> - <fo:region-body background-color='black' margin='2cm' padding='.5cm'/> - <fo:region-before background-color='black' extent='1cm'/> - <fo:region-after background-color='black' extent='1cm'/> - </fo:simple-page-master> - <fo:simple-page-master master-name='odd' margin='2cm'> - <fe:message>setting up simple page master 'odd'</fe:message> - <fo:region-body background-color='cyan' margin='2cm' padding='.5cm' margin-right='2cm'/> - <fo:region-before background-color='cyan' extent='1cm'/> - <fo:region-after background-color='cyan' extent='1cm'/> - </fo:simple-page-master> - <fo:simple-page-master master-name='even' margin='2cm'> - <fe:message>setting up simple page master 'even'</fe:message> - <fo:region-body background-color='magenta' margin='2cm' padding='.5cm' margin-left='2cm'/> - <fo:region-before background-color='magenta' extent='1cm'/> - <fo:region-after background-color='magenta' extent='1cm'/> - </fo:simple-page-master> - <fo:simple-page-master master-name='rest' margin='2cm'> - <fe:message>setting up simple page master 'rest'</fe:message> - <fo:region-body background-color='yellow' margin='2cm' padding='.5cm'/> - <fo:region-before background-color='yellow' extent='1cm'/> - <fo:region-after background-color='yellow' extent='1cm'/> - </fo:simple-page-master> - - <fo:page-sequence-master master-name='demo'> - <fe:message>setting up page sequence master 'demo'</fe:message> - <fo:repeatable-page-master-alternatives> - <fo:conditional-page-master-reference page-position='first' master-reference='first-page'/> - <fo:conditional-page-master-reference page-position='last' master-reference='blank-page'/> - <fo:conditional-page-master-reference page-position='any' master-reference='odd' odd-or-even='odd'/> - <fo:conditional-page-master-reference page-position='any' master-reference='even' odd-or-even='even'/> - </fo:repeatable-page-master-alternatives> - </fo:page-sequence-master> - <fo:page-sequence-master master-name='omed'> - <fe:message>setting up page sequence master 'omed'</fe:message> - <fo:repeatable-page-master-alternatives> - <fo:conditional-page-master-reference page-position='first' master-reference='first-page'/> - <fo:conditional-page-master-reference page-position='last' master-reference='blank-page'/> - <fo:conditional-page-master-reference page-position='any' master-reference='odd' odd-or-even='even'/> - <fo:conditional-page-master-reference page-position='any' master-reference='even' odd-or-even='odd'/> - </fo:repeatable-page-master-alternatives> - </fo:page-sequence-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='any'> - <fe:message>starting page sequence 'any'</fe:message> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml' n='15'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - - <fo:page-sequence master-reference='demo' force-page-count='end-on-odd'> - <fe:message>starting page sequence 'demo'</fe:message> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-bryson.xml' n='30'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - - <fo:page-sequence master-reference='omed' force-page-count='end-on-odd'> - <fe:message>starting page sequence 'omed'</fe:message> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-ward.xml' n='30'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0641.fo b/tex/context/foxet/fo-0641.fo deleted file mode 100644 index 9dbb90870..000000000 --- a/tex/context/foxet/fo-0641.fo +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm' background-color='gray' fe:background-height='1cm' background-image="url('hacker.jpg')" clip='rect(1cm,1cm,1cm,1cm)' /> - <fo:region-before extent='2cm' background-color='red' fe:background-height='1cm' background-image="url('hacker.jpg')" background-repeat='repeat-x' /> - <fo:region-after extent='2cm' background-color='green' fe:background-height='2cm' background-image="url('hacker.jpg')" background-repeat='repeat-y' /> - <fo:region-start extent='2cm' background-color='blue' fe:background-height='1cm' background-image="url('hacker.jpg')" background-repeat='no-repeat'/> - <fo:region-end extent='2cm' background-color='yellow' fe:background-height='2cm' background-image="url('hacker.jpg')" background-repeat='repeat' /> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0642.fo b/tex/context/foxet/fo-0642.fo deleted file mode 100644 index 8f646509c..000000000 --- a/tex/context/foxet/fo-0642.fo +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm' - background-color='gray' - background-image="url('hacker.jpg')" - background-position-horizontal='10%' - background-position-vertical='20%' - background-repeat='no-repeat'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0643.fo b/tex/context/foxet/fo-0643.fo deleted file mode 100644 index 9595d4438..000000000 --- a/tex/context/foxet/fo-0643.fo +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm' - background-color='gray' - background-image="url('hacker.jpg')" - background-position-horizontal='center' - background-position-vertical='center' - background-repeat='no-repeat'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0644.fo b/tex/context/foxet/fo-0644.fo deleted file mode 100644 index a408661e0..000000000 --- a/tex/context/foxet/fo-0644.fo +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' - xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm' - background-color='gray' - background-image="url('hacker.jpg')" - background-position-horizontal='3cm' - background-position-vertical='5cm' - background-repeat='no-repeat'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0650.fo b/tex/context/foxet/fo-0650.fo deleted file mode 100644 index 54fd7c128..000000000 --- a/tex/context/foxet/fo-0650.fo +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' - margin-top='1cm' margin-bottom='2cm' margin-left='3cm' margin-right='4cm'> - <fo:region-body margin='.5cm' background-color='gray' fe:z-order='above' /> - <fo:region-before extent='1cm' background-color='red' /> - <fo:region-after extent='1cm' background-color='green' /> - <fo:region-start extent='1cm' background-color='blue' /> - <fo:region-end extent='1cm' background-color='yellow'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0651.fo b/tex/context/foxet/fo-0651.fo deleted file mode 100644 index 319592ba8..000000000 --- a/tex/context/foxet/fo-0651.fo +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' - margin-top='1cm' margin-bottom='2cm' margin-left='3cm' margin-right='4cm'> - <fo:region-body margin='.5cm' background-color='gray' fe:z-order='below' /> - <fo:region-before extent='1cm' background-color='red' /> - <fo:region-after extent='1cm' background-color='green' /> - <fo:region-start extent='1cm' background-color='blue' /> - <fo:region-end extent='1cm' background-color='yellow'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0701.fo b/tex/context/foxet/fo-0701.fo deleted file mode 100644 index fabbe0722..000000000 --- a/tex/context/foxet/fo-0701.fo +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master margin='2cm' master-name='default'> - <fo:region-body background-color='darkgray'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='default' fe:tracing='true'> - <fo:flow flow-name='xsl-region-body'> - <fo:block-container absolute-position='absolute' height='2cm' width='3cm' left='1cm' top='1cm'> - <fo:block>Test 1</fo:block> - </fo:block-container> - <fo:block-container absolute-position='absolute' height='2cm' left='1cm' top='6cm'> - <fo:block>Test 2</fo:block> - </fo:block-container> - <fo:block-container absolute-position='absolute' height='2cm' left='1cm' top='11cm' right='4cm'> - <fo:block>Test 3</fo:block> - </fo:block-container> - <fo:block-container absolute-position='absolute' height='2cm' width='3cm' right='1cm' bottom='1cm'> - <fo:block>Test 4</fo:block> - </fo:block-container> - <fo:block-container absolute-position='absolute' width='3cm' right='1cm' bottom='6cm'> - <fo:block>Test 5</fo:block> - </fo:block-container> - <fo:block-container absolute-position='absolute' width='3cm' right='1cm' bottom='11cm' top='7cm'> - <fo:block>Test 6</fo:block> - </fo:block-container> - <fo:block-container absolute-position='absolute' left='20%' right='20%' top='20%' bottom='20%'> - <fo:block>Test 7</fo:block> - </fo:block-container> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0801.fo b/tex/context/foxet/fo-0801.fo deleted file mode 100644 index b18c4282f..000000000 --- a/tex/context/foxet/fo-0801.fo +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' initial-page-number='123' format='n'> - <fo:flow flow-name='xsl-region-body'> - <fo:block id='format n'>digits: <fo:page-number/></fo:block> - </fo:flow> - </fo:page-sequence> - - <fo:page-sequence master-reference='test' initial-page-number='123' format='a'> - <fo:flow flow-name='xsl-region-body'> - <fo:block id='format a'>characters: <fo:page-number/></fo:block> - </fo:flow> - </fo:page-sequence> - - <fo:page-sequence master-reference='test' initial-page-number='123' format='i'> - <fo:flow flow-name='xsl-region-body'> - <fo:block id='format i'>romannumerals: <fo:page-number/></fo:block> - </fo:flow> - </fo:page-sequence> - - <fo:page-sequence master-reference='test' initial-page-number='123' format='-[(n)]-'> - <fo:flow flow-name='xsl-region-body'> - <fo:block id='complex format'>complex format: <fo:page-number/></fo:block> - </fo:flow> - </fo:page-sequence> - - <fo:page-sequence master-reference='test' initial-page-number='123'> - <fo:flow flow-name='xsl-region-body'> - <fo:block id='no format'>no format: <fo:page-number/></fo:block> - </fo:flow> - </fo:page-sequence> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:block-container space-after='12pt' id='y'> - <fo:block>digits: <fo:page-number-citation ref-id='format n'/> </fo:block> - <fo:block>characters: <fo:page-number-citation ref-id='format a'/> </fo:block> - <fo:block>romannumerals: <fo:page-number-citation ref-id='format i'/> </fo:block> - <fo:block>complex format: <fo:page-number-citation ref-id='complex format'/> </fo:block> - <fo:block>no format: <fo:page-number-citation ref-id='no format'/> </fo:block> - </fo:block-container> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0901.fo b/tex/context/foxet/fo-0901.fo deleted file mode 100644 index 05011269b..000000000 --- a/tex/context/foxet/fo-0901.fo +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='.5cm'> - <fo:region-body margin='.5cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' initial-page-number='123'> - <fo:flow flow-name='xsl-region-body'> - <fo:block-container font-style='italic'> - <fo:block font-family='Times'>times</fo:block> - <fo:block font-family='Helvetica'>helvetica</fo:block> - <fo:block font-family='Courier'>courier</fo:block> - </fo:block-container> - <fo:block-container font-style='italic'> - <fo:block font-family='Times'>times</fo:block> - <fo:block font-family='Helvetica'>helvetica</fo:block> - <fo:block font-family='Courier'>courier</fo:block> - </fo:block-container> - <fo:block-container font-weight='bold'> - <fo:block font-family='Times'>times</fo:block> - <fo:block font-family='Helvetica'>helvetica</fo:block> - <fo:block font-family='Courier'>courier</fo:block> - </fo:block-container> - <fo:block-container font-style='italic'> - <fo:block font-family='Times'>times</fo:block> - <fo:block font-family='Helvetica'>helvetica</fo:block> - <fo:block font-family='Courier'>courier</fo:block> - </fo:block-container> - <fo:block-container font-style='italic' font-weight='bold' font-size='large'> - <fo:block font-family='Times'>large</fo:block> - <fo:block font-family='Helvetica'>large</fo:block> - <fo:block font-family='Courier'>large</fo:block> - </fo:block-container> - <fo:block-container font-style='italic' font-weight='bold' font-size='x-large'> - <fo:block font-family='Times'>x-large</fo:block> - <fo:block font-family='Helvetica'>x-large</fo:block> - <fo:block font-family='Courier'>x-large</fo:block> - </fo:block-container> - <fo:block-container font-style='italic' font-weight='bold' font-size='xx-large'> - <fo:block font-family='Times'>xx-large</fo:block> - <fo:block font-family='Helvetica'>xx-large</fo:block> - <fo:block font-family='Courier'>xx-large</fo:block> - </fo:block-container> - <fo:block-container font-style='italic' font-weight='bold' font-size='350%'> - <fo:block font-family='Times'>times</fo:block> - <fo:block font-family='Helvetica'>helvetica</fo:block> - <fo:block font-family='Courier'>courier</fo:block> - </fo:block-container> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-0902.fo b/tex/context/foxet/fo-0902.fo deleted file mode 100644 index ebaa06651..000000000 --- a/tex/context/foxet/fo-0902.fo +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='.5cm'> - <fo:region-body margin='.5cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' initial-page-number='123'> - <fo:flow flow-name='xsl-region-body'> - <fo:block-container> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:block-container> - <fo:block-container line-height='40pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:block-container> - <fo:block-container line-height='180%'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:block-container> - <fo:block-container line-height='1.2'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:block-container> - <fo:block-container line-height='normal'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:block-container> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1001.fo b/tex/context/foxet/fo-1001.fo deleted file mode 100644 index 3733265fd..000000000 --- a/tex/context/foxet/fo-1001.fo +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' initial-page-number='123'> - <fo:flow flow-name='xsl-region-body'> - <fo:block-container fe:tracing='true'> - <fo:block>a test line d 10pt</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='discard'/> - <fo:block>a test line d 5pt</fo:block> - <fo:block space-before.optimum='5pt' space-before.conditionality='discard'/> - <fo:block>a test line d 4pt</fo:block> - <fo:block space-before.optimum='4pt' space-before.conditionality='discard'/> - <fo:block>a test line d d d</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='4pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='5pt' space-before.conditionality='discard'/> - <fo:block>a test line r d d</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='4pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='5pt' space-before.conditionality='discard'/> - <fo:block>a test line d r d</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='4pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='5pt' space-before.conditionality='discard'/> - <fo:block>a test line r r d</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='4pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='5pt' space-before.conditionality='discard'/> - <fo:block>a test line d d r</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='4pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='5pt' space-before.conditionality='retain' /> - <fo:block>a test line r d r</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='4pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='5pt' space-before.conditionality='retain' /> - <fo:block>a test line d r r</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='discard'/> - <fo:block space-before.optimum='4pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='5pt' space-before.conditionality='retain' /> - <fo:block>a test line r r r</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='4pt' space-before.conditionality='retain' /> - <fo:block space-before.optimum='5pt' space-before.conditionality='retain' /> - <fo:block>a test line d r r force</fo:block> - <fo:block space-before.optimum='10pt' space-before.conditionality='discard' space-before.precedence='force'/> - <fo:block space-before.optimum='4pt' space-before.conditionality='retain' space-before.precedence='force'/> - <fo:block space-before.optimum='5pt' space-before.conditionality='retain' space-before.precedence='force'/> - <fo:block>a test line</fo:block> - </fo:block-container> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1002.fo b/tex/context/foxet/fo-1002.fo deleted file mode 100644 index cc0ea8100..000000000 --- a/tex/context/foxet/fo-1002.fo +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' initial-page-number='123'> - <fo:flow flow-name='xsl-region-body'> - <fo:block start-indent='1cm'> - <fe:include url='fe-zapf.xml'/> - </fo:block> - <fo:block start-indent='1cm' end-indent='1cm'> - <fe:include url='fe-zapf.xml'/> - <fo:block start-indent='1cm' end-indent='1cm'> - <fe:include url='fe-zapf.xml'/> - </fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - <fo:block end-indent='1cm'> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1003.fo b/tex/context/foxet/fo-1003.fo deleted file mode 100644 index 4c416e02d..000000000 --- a/tex/context/foxet/fo-1003.fo +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' initial-page-number='123'> - <fo:flow flow-name='xsl-region-body'> - <fo:block start-indent='1cm' text-indent='3cm'> - <fe:include url='fe-zapf.xml'/> - </fo:block> - <fo:block start-indent='1cm' end-indent='1cm' text-indent='1cm'> - <fe:include url='fe-zapf.xml'/> - <fo:block start-indent='1cm' end-indent='1cm' text-indent='1cm'> - <fe:include url='fe-zapf.xml'/> - </fo:block> - <fe:include url='fe-zapf.xml'/> - </fo:block> - <fo:block end-indent='1cm' text-indent='3cm'> - <fe:include url='fe-zapf.xml'/> - </fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1004.fo b/tex/context/foxet/fo-1004.fo deleted file mode 100644 index 1c057edd7..000000000 --- a/tex/context/foxet/fo-1004.fo +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='2cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' initial-page-number='123'> - <fo:flow flow-name='xsl-region-body'> - <fo:block-container space-before.optimum='12pt'> - <fo:block> - before<fo:inline space-start='10pt' >inbetween</fo:inline>after - </fo:block> - <fo:block> - before<fo:inline space-end='10pt'>inbetween</fo:inline>after - </fo:block> - <fo:block> - before<fo:inline space-start='10pt' space-end='10pt'>inbetween</fo:inline>after - </fo:block> - <fo:block> - before<fo:inline space-start='-10pt' space-end='-10pt'>inbetween</fo:inline>after - </fo:block> - <fo:block> - before<fo:inline space-start='250%' space-end='250%'>inbetween</fo:inline>after - </fo:block> - </fo:block-container> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1101.fo b/tex/context/foxet/fo-1101.fo deleted file mode 100644 index f6953d522..000000000 --- a/tex/context/foxet/fo-1101.fo +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='1cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' fe:tracing='true'> - <fo:flow flow-name='xsl-region-body'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - <fo:list-block - space-before.optimum='12pt' - space-after.optimum='12pt'> - <fo:list-item> - <fo:list-item-label start-indent='10pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='10pt'> - <fo:block>[b]</fo:block> - </fo:list-item-label> - <fo:list-item-body end-indent='0pt'> - <fo:list-block> - <fo:list-item> - <fo:list-item-label start-indent='40pt'> - <fo:block>[bb]</fo:block> - </fo:list-item-label> - <fo:list-item-body end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - </fo:list-block> - </fo:list-item-body> - </fo:list-item> - </fo:list-block> - <fo:list-block - start-indent='1cm' - end-indent='1cm' - space-before.optimum='12pt' - space-after.optimum='12pt'> - <fo:list-item> - <fo:list-item-label start-indent='10pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - </fo:list-block> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1102.fo b/tex/context/foxet/fo-1102.fo deleted file mode 100644 index f8d5a9df3..000000000 --- a/tex/context/foxet/fo-1102.fo +++ /dev/null @@ -1,128 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='1cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' fe:tracing='true' fe:testgrid='true'> - <fo:flow flow-name='xsl-region-body'> - <fo:list-block - space-before.optimum='12pt' - space-after.optimum='12pt' - provisional-distance-between-starts='2cm' - provisional-label-separation='.5cm'> - <!-- fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='50pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='50pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='50pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='50pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='50pt' end-indent='50pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='50pt' end-indent='50pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='50pt' end-indent='50pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='50pt' end-indent='50pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='10%' end-indent='75%'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='35%' end-indent='10%'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item --> - <fo:list-item> - <fo:list-item-label start-indent='1cm' end-indent='10cm'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='4cm' end-indent='1cm'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='1cm' end-indent='label-end()'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='5cm' end-indent='1cm'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='1cm' end-indent='10cm'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='body-start()' end-indent='2cm'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='1cm' end-indent='label-end()'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='body-start()' end-indent='3cm'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - </fo:list-block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1103.fo b/tex/context/foxet/fo-1103.fo deleted file mode 100644 index 245f3ff0e..000000000 --- a/tex/context/foxet/fo-1103.fo +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='1cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' fe:tracing='true'> - <fo:flow flow-name='xsl-region-body'> - <fo:list-block space-before.optimum='12pt' space-after.optimum='12pt' - start-indent='10pt' end-indent='10pt'> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='10pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='10pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='10pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='10pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='10pt' end-indent='10pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='0pt' end-indent='0pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='0pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='10pt' end-indent='10pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - <fo:list-item> - <fo:list-item-label start-indent='10pt' end-indent='0pt'> - <fo:block>[a]</fo:block> - </fo:list-item-label> - <fo:list-item-body start-indent='10pt' end-indent='10pt'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - </fo:list-block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1104.fo b/tex/context/foxet/fo-1104.fo deleted file mode 100644 index 6867e772f..000000000 --- a/tex/context/foxet/fo-1104.fo +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='1cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test'> - <fo:flow flow-name='xsl-region-body'> - <fo:list-block> - <fo:list-item> - <fo:list-item-label> - <fo:block text-align="center">X</fo:block> - </fo:list-item-label> - <fo:list-item-body> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:list-item-body> - </fo:list-item> - </fo:list-block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/foxet/fo-1201.fo b/tex/context/foxet/fo-1201.fo deleted file mode 100644 index 364dcb214..000000000 --- a/tex/context/foxet/fo-1201.fo +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version='1.0'?> - -<!-- foxet test file - Hans Hagen - PRAGMA ADE - www.pragma-ade.com --> - -<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format' xmlns:fe='http://www.pragma-ade.com/schemas/foxet.rng'> - - <fo:layout-master-set> - <fo:simple-page-master master-name='test' margin='2cm'> - <fo:region-body margin='1cm'/> - </fo:simple-page-master> - </fo:layout-master-set> - - <fo:page-sequence master-reference='test' fe:tracing='true'> - <fo:flow flow-name='xsl-region-body'> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - <fo:block> - test - <fo:inline position='static' font-size='600%'>S</fo:inline> - <fo:inline position='static' font-size='400%'>S</fo:inline> - <fo:inline position='static' font-size='500%'>S</fo:inline> - <fo:inline position='fixed' right='2cm' bottom='2cm' font-size='600%'>F</fo:inline> - <fo:inline position='fixed' right='2cm' top='2cm' font-size='400%'>F</fo:inline> - <fo:inline position='fixed' left='2cm' bottom='2cm' font-size='500%'>F</fo:inline> - <fo:inline position='absolute' right='1cm' bottom='1cm' font-size='600%'>A</fo:inline> - <fo:inline position='absolute' right='1cm' top='1cm' font-size='400%'>A</fo:inline> - <fo:inline position='absolute' left='1cm' bottom='1cm' font-size='500%'>A</fo:inline> - <fo:inline position='relative' right='2mm' bottom='2mm' font-size='600%'>R</fo:inline> - <fo:inline position='relative' right='2mm' top='2mm' font-size='400%'>R</fo:inline> - <fo:inline position='relative' left='2mm' bottom='2mm' font-size='500%'>R</fo:inline> - test - <fo:inline position='static' font-size='600%'>Q</fo:inline> - <fo:inline position='relative' right='2mm' bottom='2mm' font-size='600%'>Q</fo:inline> - <fo:inline position='relative' right='2mm' top='2mm' font-size='400%'>Q</fo:inline> - <fo:inline position='relative' left='2mm' bottom='2mm' font-size='500%'>Q</fo:inline> - </fo:block> - <fo:block><fe:include url='fe-zapf.xml'/></fo:block> - </fo:flow> - </fo:page-sequence> - -</fo:root> diff --git a/tex/context/interface/keys-cs.xml b/tex/context/interface/keys-cs.xml index fca580ed0..b4beb1374 100644 --- a/tex/context/interface/keys-cs.xml +++ b/tex/context/interface/keys-cs.xml @@ -425,7 +425,7 @@ <cd:variable name='september' value='zari'/> <cd:variable name='serif' value='serif'/> <cd:variable name='serried' value='semknuto'/> - <cd:variable name='setups' value='einstellungen'/> + <cd:variable name='setups' value='setups'/> <cd:variable name='sheet' value='sheet'/> <cd:variable name='short' value='short'/> <cd:variable name='simplefonts' value='simplefonts'/> @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='definujsablonutabulky'/> <cd:command name='definetabulate' value='definujtabelaci'/> <cd:command name='definetext' value='definujtext'/> + <cd:command name='definetextbackground' value='definetextbackground'/> <cd:command name='definetextposition' value='definetextposition'/> <cd:command name='definetextvariable' value='definetextvariable'/> <cd:command name='definetype' value='definetype'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='placeheadtext'/> <cd:command name='placelegend' value='umistilegendu'/> <cd:command name='placelist' value='umistiseznam'/> + <cd:command name='placelistofsynonyms' value='placelistofsynonyms'/> <cd:command name='placelocalfootnotes' value='umistilokalnipoznamkypodcarou'/> <cd:command name='placelogos' value='umistiloga'/> <cd:command name='placeongrid' value='umistinamrizku'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='nastavrejstrik'/> <cd:command name='setuprotate' value='nastavotoceni'/> <cd:command name='setuprule' value='setuprule'/> - <cd:command name='setups' value='nastaveni'/> <cd:command name='setupscreens' value='nastavrastr'/> <cd:command name='setupsection' value='nastavsekci'/> <cd:command name='setupsectionblock' value='nastavbloksekce'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='nastavtabulky'/> <cd:command name='setuptabulate' value='nastavtabelaci'/> <cd:command name='setuptext' value='nastavtext'/> + <cd:command name='setuptextbackground' value='setuptextbackground'/> <cd:command name='setuptextposition' value='setuptextposition'/> <cd:command name='setuptextrules' value='nastavtextovelinky'/> <cd:command name='setuptexttexts' value='nastavtexttexty'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='startdokument'/> <cd:command name='startenvironment' value='startprostredi'/> <cd:command name='startfigure' value='startobraz'/> + <cd:command name='startframed' value='startframed'/> <cd:command name='startglobal' value='startglobalni'/> <cd:command name='startline' value='startradek'/> <cd:command name='startlinecorrection' value='startkorekceradku'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='starttabulka'/> <cd:command name='starttables' value='starttabulky'/> <cd:command name='starttext' value='starttext'/> + <cd:command name='starttextbackground' value='starttextbackground'/> <cd:command name='starttextrule' value='starttextovalinka'/> <cd:command name='startunpacked' value='startnezhustene'/> <cd:command name='startversion' value='startverze'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='stopkomponenta'/> <cd:command name='stopdocument' value='stopdokument'/> <cd:command name='stopenvironment' value='stopprostredi'/> + <cd:command name='stopframed' value='stopframed'/> <cd:command name='stopglobal' value='stopglobalni'/> <cd:command name='stopline' value='stopradek'/> <cd:command name='stoplinecorrection' value='stopkorekceradku'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='stoptabulka'/> <cd:command name='stoptables' value='stoptabulky'/> <cd:command name='stoptext' value='stoptext'/> + <cd:command name='stoptextbackground' value='stoptextbackground'/> <cd:command name='stoptextrule' value='stoptextovalinka'/> <cd:command name='stopunpacked' value='stopnezhustene'/> <cd:command name='stopversion' value='stopverze'/> diff --git a/tex/context/interface/keys-de.xml b/tex/context/interface/keys-de.xml index 87f6c6ee4..43ddfd86f 100644 --- a/tex/context/interface/keys-de.xml +++ b/tex/context/interface/keys-de.xml @@ -425,7 +425,7 @@ <cd:variable name='september' value='september'/> <cd:variable name='serif' value='serif'/> <cd:variable name='serried' value='kleinerabstand'/> - <cd:variable name='setups' value='impostazioni'/> + <cd:variable name='setups' value='setups'/> <cd:variable name='sheet' value='sheet'/> <cd:variable name='short' value='kurz'/> <cd:variable name='simplefonts' value='simplefonts'/> @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='definieretabellenvorlage'/> <cd:command name='definetabulate' value='definieretabulator'/> <cd:command name='definetext' value='definieretext'/> + <cd:command name='definetextbackground' value='definetextbackground'/> <cd:command name='definetextposition' value='definetextposition'/> <cd:command name='definetextvariable' value='definetextvariable'/> <cd:command name='definetype' value='definetype'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='placeheadtext'/> <cd:command name='placelegend' value='platzierelegende'/> <cd:command name='placelist' value='platziereliste'/> + <cd:command name='placelistofsynonyms' value='placelistofsynonyms'/> <cd:command name='placelocalfootnotes' value='platzierelokalefussnoten'/> <cd:command name='placelogos' value='platzierelogo'/> <cd:command name='placeongrid' value='amgitterausrichten'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='stelleregisterein'/> <cd:command name='setuprotate' value='stelledrehenein'/> <cd:command name='setuprule' value='setuprule'/> - <cd:command name='setups' value='einstellungen'/> <cd:command name='setupscreens' value='stellerasterein'/> <cd:command name='setupsection' value='stelleabschnittein'/> <cd:command name='setupsectionblock' value='stelleabschnittsblockein'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='stelletabellenein'/> <cd:command name='setuptabulate' value='stelletabulatorein'/> <cd:command name='setuptext' value='stelletextein'/> + <cd:command name='setuptextbackground' value='setuptextbackground'/> <cd:command name='setuptextposition' value='setuptextposition'/> <cd:command name='setuptextrules' value='stelletextumrissein'/> <cd:command name='setuptexttexts' value='stelletexttexteein'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='startdokument'/> <cd:command name='startenvironment' value='startumgebung'/> <cd:command name='startfigure' value='startabbildung'/> + <cd:command name='startframed' value='startframed'/> <cd:command name='startglobal' value='startglobal'/> <cd:command name='startline' value='startzeile'/> <cd:command name='startlinecorrection' value='startzeilenkorrektur'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='starttabelle'/> <cd:command name='starttables' value='starttabellen'/> <cd:command name='starttext' value='starttext'/> + <cd:command name='starttextbackground' value='starttextbackground'/> <cd:command name='starttextrule' value='starttextlinie'/> <cd:command name='startunpacked' value='startgrosserdurchschuss'/> <cd:command name='startversion' value='startversion'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='stopkomponente'/> <cd:command name='stopdocument' value='stopdokument'/> <cd:command name='stopenvironment' value='stopumgebung'/> + <cd:command name='stopframed' value='stopframed'/> <cd:command name='stopglobal' value='stopglobal'/> <cd:command name='stopline' value='stopzeile'/> <cd:command name='stoplinecorrection' value='stopzeilenkorrektur'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='stoptabelle'/> <cd:command name='stoptables' value='stoptabellen'/> <cd:command name='stoptext' value='stoptext'/> + <cd:command name='stoptextbackground' value='stoptextbackground'/> <cd:command name='stoptextrule' value='stoptextlinie'/> <cd:command name='stopunpacked' value='stopgrosserdurchschuss'/> <cd:command name='stopversion' value='stopversion'/> diff --git a/tex/context/interface/keys-en.xml b/tex/context/interface/keys-en.xml index 36a42c4d4..9f29f1164 100644 --- a/tex/context/interface/keys-en.xml +++ b/tex/context/interface/keys-en.xml @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='definetabletemplate'/> <cd:command name='definetabulate' value='definetabulate'/> <cd:command name='definetext' value='definetext'/> + <cd:command name='definetextbackground' value='definetextbackground'/> <cd:command name='definetextposition' value='definetextposition'/> <cd:command name='definetextvariable' value='definetextvariable'/> <cd:command name='definetype' value='definetype'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='placeheadtext'/> <cd:command name='placelegend' value='placelegend'/> <cd:command name='placelist' value='placelist'/> + <cd:command name='placelistofsynonyms' value='placelistofsynonyms'/> <cd:command name='placelocalfootnotes' value='placelocalfootnotes'/> <cd:command name='placelogos' value='placelogos'/> <cd:command name='placeongrid' value='placeongrid'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='setupregister'/> <cd:command name='setuprotate' value='setuprotate'/> <cd:command name='setuprule' value='setuprule'/> - <cd:command name='setups' value='setups'/> <cd:command name='setupscreens' value='setupscreens'/> <cd:command name='setupsection' value='setupsection'/> <cd:command name='setupsectionblock' value='setupsectionblock'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='setuptables'/> <cd:command name='setuptabulate' value='setuptabulate'/> <cd:command name='setuptext' value='setuptext'/> + <cd:command name='setuptextbackground' value='setuptextbackground'/> <cd:command name='setuptextposition' value='setuptextposition'/> <cd:command name='setuptextrules' value='setuptextrules'/> <cd:command name='setuptexttexts' value='setuptexttexts'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='startdocument'/> <cd:command name='startenvironment' value='startenvironment'/> <cd:command name='startfigure' value='startfigure'/> + <cd:command name='startframed' value='startframed'/> <cd:command name='startglobal' value='startglobal'/> <cd:command name='startline' value='startline'/> <cd:command name='startlinecorrection' value='startlinecorrection'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='starttable'/> <cd:command name='starttables' value='starttables'/> <cd:command name='starttext' value='starttext'/> + <cd:command name='starttextbackground' value='starttextbackground'/> <cd:command name='starttextrule' value='starttextrule'/> <cd:command name='startunpacked' value='startunpacked'/> <cd:command name='startversion' value='startversion'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='stopcomponent'/> <cd:command name='stopdocument' value='stopdocument'/> <cd:command name='stopenvironment' value='stopenvironment'/> + <cd:command name='stopframed' value='stopframed'/> <cd:command name='stopglobal' value='stopglobal'/> <cd:command name='stopline' value='stopline'/> <cd:command name='stoplinecorrection' value='stoplinecorrection'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='stoptable'/> <cd:command name='stoptables' value='stoptables'/> <cd:command name='stoptext' value='stoptext'/> + <cd:command name='stoptextbackground' value='stoptextbackground'/> <cd:command name='stoptextrule' value='stoptextrule'/> <cd:command name='stopunpacked' value='stopunpacked'/> <cd:command name='stopversion' value='stopversion'/> diff --git a/tex/context/interface/keys-fr.xml b/tex/context/interface/keys-fr.xml index 637291f18..427881a07 100644 --- a/tex/context/interface/keys-fr.xml +++ b/tex/context/interface/keys-fr.xml @@ -425,7 +425,7 @@ <cd:variable name='september' value='septembre'/> <cd:variable name='serif' value='serif'/> <cd:variable name='serried' value='serried'/> - <cd:variable name='setups' value='reglages'/> + <cd:variable name='setups' value='setups'/> <cd:variable name='sheet' value='sheet'/> <cd:variable name='short' value='short'/> <cd:variable name='simplefonts' value='simplefonts'/> @@ -1012,7 +1012,7 @@ <cd:constant name='separatorcolor' value='separatorcolor'/> <cd:constant name='separatorstyle' value='separatorstyle'/> <cd:constant name='set' value='set'/> - <cd:constant name='setups' value='reglages'/> + <cd:constant name='setups' value='setups'/> <cd:constant name='shrink' value='shrink'/> <cd:constant name='side' value='cote'/> <cd:constant name='sidealign' value='sidealign'/> @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='definittrametableau'/> <cd:command name='definetabulate' value='definittabulation'/> <cd:command name='definetext' value='definittexte'/> + <cd:command name='definetextbackground' value='definetextbackground'/> <cd:command name='definetextposition' value='definitpositiontexte'/> <cd:command name='definetextvariable' value='definitvariabletexte'/> <cd:command name='definetype' value='definittype'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='placetextetete'/> <cd:command name='placelegend' value='placelegende'/> <cd:command name='placelist' value='placeliste'/> + <cd:command name='placelistofsynonyms' value='placelistofsynonyms'/> <cd:command name='placelocalfootnotes' value='placenotespdplocales'/> <cd:command name='placelogos' value='placelogos'/> <cd:command name='placeongrid' value='placesurgrille'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='regleregistre'/> <cd:command name='setuprotate' value='regleoriente'/> <cd:command name='setuprule' value='regleregle'/> - <cd:command name='setups' value='reglages'/> <cd:command name='setupscreens' value='regleecrans'/> <cd:command name='setupsection' value='reglesection'/> <cd:command name='setupsectionblock' value='regleblocsection'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='regletableaux'/> <cd:command name='setuptabulate' value='regletabulation'/> <cd:command name='setuptext' value='regletexte'/> + <cd:command name='setuptextbackground' value='setuptextbackground'/> <cd:command name='setuptextposition' value='reglepositiontexte'/> <cd:command name='setuptextrules' value='reglelignesreglestexte'/> <cd:command name='setuptexttexts' value='regletextestexte'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='demarredocument'/> <cd:command name='startenvironment' value='demarreenvironement'/> <cd:command name='startfigure' value='demarrefigure'/> + <cd:command name='startframed' value='startframed'/> <cd:command name='startglobal' value='demarreglobal'/> <cd:command name='startline' value='demarreligne'/> <cd:command name='startlinecorrection' value='demarrecorrectionligne'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='demarretableau'/> <cd:command name='starttables' value='demarretableaux'/> <cd:command name='starttext' value='demarretexte'/> + <cd:command name='starttextbackground' value='starttextbackground'/> <cd:command name='starttextrule' value='demarreligneregleetexte'/> <cd:command name='startunpacked' value='demarredegroupe'/> <cd:command name='startversion' value='demarreversion'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='stoppecomposant'/> <cd:command name='stopdocument' value='stoppedocument'/> <cd:command name='stopenvironment' value='stoppeenvironement'/> + <cd:command name='stopframed' value='stopframed'/> <cd:command name='stopglobal' value='stoppeglobal'/> <cd:command name='stopline' value='stoppeligne'/> <cd:command name='stoplinecorrection' value='stoppecorrectionligne'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='stoppetableau'/> <cd:command name='stoptables' value='stoppetableaux'/> <cd:command name='stoptext' value='stoppetexte'/> + <cd:command name='stoptextbackground' value='stoptextbackground'/> <cd:command name='stoptextrule' value='stoppeligneregleetexte'/> <cd:command name='stopunpacked' value='stoppedegroupe'/> <cd:command name='stopversion' value='stoppeversion'/> diff --git a/tex/context/interface/keys-it.xml b/tex/context/interface/keys-it.xml index 8bd6256f7..073aabe4d 100644 --- a/tex/context/interface/keys-it.xml +++ b/tex/context/interface/keys-it.xml @@ -425,7 +425,7 @@ <cd:variable name='september' value='settembre'/> <cd:variable name='serif' value='serif'/> <cd:variable name='serried' value='vicino'/> - <cd:variable name='setups' value='nastaveni'/> + <cd:variable name='setups' value='setups'/> <cd:variable name='sheet' value='sheet'/> <cd:variable name='short' value='short'/> <cd:variable name='simplefonts' value='simplefonts'/> @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='definiscimodellotabella'/> <cd:command name='definetabulate' value='definiscitabulato'/> <cd:command name='definetext' value='definiscitesto'/> + <cd:command name='definetextbackground' value='definetextbackground'/> <cd:command name='definetextposition' value='definisciposizionetesto'/> <cd:command name='definetextvariable' value='definiscivariabiletesto'/> <cd:command name='definetype' value='definiscitype'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='posizionatestotesta'/> <cd:command name='placelegend' value='mettilegenda'/> <cd:command name='placelist' value='mettielenco'/> + <cd:command name='placelistofsynonyms' value='placelistofsynonyms'/> <cd:command name='placelocalfootnotes' value='mettinotepdplocali'/> <cd:command name='placelogos' value='mettiloghi'/> <cd:command name='placeongrid' value='mettiingriglia'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='impostaregistro'/> <cd:command name='setuprotate' value='impostarotazione'/> <cd:command name='setuprule' value='impostalinea'/> - <cd:command name='setups' value='impostazioni'/> <cd:command name='setupscreens' value='impostaschermi'/> <cd:command name='setupsection' value='impostasezione'/> <cd:command name='setupsectionblock' value='impostabloccosezione'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='impostatabelle'/> <cd:command name='setuptabulate' value='impostatabulato'/> <cd:command name='setuptext' value='impostatesto'/> + <cd:command name='setuptextbackground' value='setuptextbackground'/> <cd:command name='setuptextposition' value='impostaposizionetesto'/> <cd:command name='setuptextrules' value='impostalineetesto'/> <cd:command name='setuptexttexts' value='impostatestotesti'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='iniziadocumento'/> <cd:command name='startenvironment' value='iniziaambiente'/> <cd:command name='startfigure' value='iniziafigura'/> + <cd:command name='startframed' value='startframed'/> <cd:command name='startglobal' value='iniziaglobale'/> <cd:command name='startline' value='iniziariga'/> <cd:command name='startlinecorrection' value='iniziacorrezioneriga'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='iniziatabella'/> <cd:command name='starttables' value='iniziatabelle'/> <cd:command name='starttext' value='iniziatesto'/> + <cd:command name='starttextbackground' value='starttextbackground'/> <cd:command name='starttextrule' value='inizialineatesto'/> <cd:command name='startunpacked' value='iniziaunpacked'/> <cd:command name='startversion' value='iniziaversione'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='terminacomponente'/> <cd:command name='stopdocument' value='terminadocumento'/> <cd:command name='stopenvironment' value='terminaambiente'/> + <cd:command name='stopframed' value='stopframed'/> <cd:command name='stopglobal' value='terminaglobale'/> <cd:command name='stopline' value='terminariga'/> <cd:command name='stoplinecorrection' value='terminacorrezioneriga'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='terminatabella'/> <cd:command name='stoptables' value='terminatabelle'/> <cd:command name='stoptext' value='terminatesto'/> + <cd:command name='stoptextbackground' value='stoptextbackground'/> <cd:command name='stoptextrule' value='terminalineatesto'/> <cd:command name='stopunpacked' value='terminaunpacked'/> <cd:command name='stopversion' value='terminaversioni'/> diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml index 6d392763b..32c44e62b 100644 --- a/tex/context/interface/keys-nl.xml +++ b/tex/context/interface/keys-nl.xml @@ -425,7 +425,7 @@ <cd:variable name='september' value='september'/> <cd:variable name='serif' value='serif'/> <cd:variable name='serried' value='aanelkaar'/> - <cd:variable name='setups' value='instellingen'/> + <cd:variable name='setups' value='setups'/> <cd:variable name='sheet' value='sheet'/> <cd:variable name='short' value='kort'/> <cd:variable name='simplefonts' value='simplefonts'/> @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='definieertabelvorm'/> <cd:command name='definetabulate' value='definieertabulatie'/> <cd:command name='definetext' value='definieertekst'/> + <cd:command name='definetextbackground' value='definieertekstachtergrond'/> <cd:command name='definetextposition' value='definieertekstpositie'/> <cd:command name='definetextvariable' value='definieertekstvariabele'/> <cd:command name='definetype' value='definieertype'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='plaatskoptekst'/> <cd:command name='placelegend' value='plaatslegenda'/> <cd:command name='placelist' value='plaatslijst'/> + <cd:command name='placelistofsynonyms' value='plaatslijstmetsynoniemen'/> <cd:command name='placelocalfootnotes' value='plaatslokalevoetnoten'/> <cd:command name='placelogos' value='plaatsbeeldmerken'/> <cd:command name='placeongrid' value='plaatsopgrid'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='stelregisterin'/> <cd:command name='setuprotate' value='stelroterenin'/> <cd:command name='setuprule' value='stellijnin'/> - <cd:command name='setups' value='instellingen'/> <cd:command name='setupscreens' value='stelrastersin'/> <cd:command name='setupsection' value='stelsectiein'/> <cd:command name='setupsectionblock' value='stelsectieblokin'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='steltabellenin'/> <cd:command name='setuptabulate' value='steltabulatiein'/> <cd:command name='setuptext' value='steltekstin'/> + <cd:command name='setuptextbackground' value='steltekstachtergrondin'/> <cd:command name='setuptextposition' value='steltekstpositiein'/> <cd:command name='setuptextrules' value='steltekstlijnenin'/> <cd:command name='setuptexttexts' value='stelteksttekstenin'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='startdocument'/> <cd:command name='startenvironment' value='startomgeving'/> <cd:command name='startfigure' value='startfiguur'/> + <cd:command name='startframed' value='startomlijnd'/> <cd:command name='startglobal' value='startglobaal'/> <cd:command name='startline' value='startregel'/> <cd:command name='startlinecorrection' value='startregelcorrectie'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='starttabel'/> <cd:command name='starttables' value='starttabellen'/> <cd:command name='starttext' value='starttekst'/> + <cd:command name='starttextbackground' value='starttekstachtergrond'/> <cd:command name='starttextrule' value='starttekstlijn'/> <cd:command name='startunpacked' value='startvanelkaar'/> <cd:command name='startversion' value='startversie'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='stoponderdeel'/> <cd:command name='stopdocument' value='stopdocument'/> <cd:command name='stopenvironment' value='stopomgeving'/> + <cd:command name='stopframed' value='stopomlijnd'/> <cd:command name='stopglobal' value='stopglobaal'/> <cd:command name='stopline' value='stopregel'/> <cd:command name='stoplinecorrection' value='stopregelcorrectie'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='stoptabel'/> <cd:command name='stoptables' value='stoptabellen'/> <cd:command name='stoptext' value='stoptekst'/> + <cd:command name='stoptextbackground' value='stoptekstachtergrond'/> <cd:command name='stoptextrule' value='stoptekstlijn'/> <cd:command name='stopunpacked' value='stopvanelkaar'/> <cd:command name='stopversion' value='stopversie'/> diff --git a/tex/context/interface/keys-pe.xml b/tex/context/interface/keys-pe.xml index d9609d3d7..ace31d289 100644 --- a/tex/context/interface/keys-pe.xml +++ b/tex/context/interface/keys-pe.xml @@ -425,7 +425,7 @@ <cd:variable name='september' value='سپتامبر'/> <cd:variable name='serif' value='سریف'/> <cd:variable name='serried' value='تنگهم'/> - <cd:variable name='setups' value='بارگذاریها'/> + <cd:variable name='setups' value='setups'/> <cd:variable name='sheet' value='ورقه'/> <cd:variable name='short' value='short'/> <cd:variable name='simplefonts' value='simplefonts'/> @@ -1012,7 +1012,7 @@ <cd:constant name='separatorcolor' value='separatorcolor'/> <cd:constant name='separatorstyle' value='separatorstyle'/> <cd:constant name='set' value='قراربده'/> - <cd:constant name='setups' value='بارگذاریها'/> + <cd:constant name='setups' value='setups'/> <cd:constant name='shrink' value='shrink'/> <cd:constant name='side' value='کنار'/> <cd:constant name='sidealign' value='تنظیمکنار'/> @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='تعریفالگویجدول'/> <cd:command name='definetabulate' value='تعریفجدولبندی'/> <cd:command name='definetext' value='تعریفمتن'/> + <cd:command name='definetextbackground' value='definetextbackground'/> <cd:command name='definetextposition' value='تعریفمکانمتن'/> <cd:command name='definetextvariable' value='تعریفمتغیرمتن'/> <cd:command name='definetype' value='تعریفتایپ'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='درجمتنسر'/> <cd:command name='placelegend' value='درجراهنما'/> <cd:command name='placelist' value='درجلیست'/> + <cd:command name='placelistofsynonyms' value='placelistofsynonyms'/> <cd:command name='placelocalfootnotes' value='درجپانوشتهایموضعی'/> <cd:command name='placelogos' value='درجآرمها'/> <cd:command name='placeongrid' value='درجدرتوری'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='بارگذاریثبت'/> <cd:command name='setuprotate' value='بارگذاریدوران'/> <cd:command name='setuprule' value='بارگذاریخط'/> - <cd:command name='setups' value='بارگذاریها'/> <cd:command name='setupscreens' value='بارگذاریپردهها'/> <cd:command name='setupsection' value='بارگذاریبخش'/> <cd:command name='setupsectionblock' value='بارگذاریبلوکبخش'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='بارگذاریجدولها'/> <cd:command name='setuptabulate' value='بارگذاریجدولبندی'/> <cd:command name='setuptext' value='بارگذاریمتن'/> + <cd:command name='setuptextbackground' value='setuptextbackground'/> <cd:command name='setuptextposition' value='بارگذاریمکانمتن'/> <cd:command name='setuptextrules' value='بارگذاریخطهایمتن'/> <cd:command name='setuptexttexts' value='بارگذاریمتنمتنها'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='شروعنوشتار'/> <cd:command name='startenvironment' value='شروعمحیط'/> <cd:command name='startfigure' value='شروعشکل'/> + <cd:command name='startframed' value='startframed'/> <cd:command name='startglobal' value='شروعسراسری'/> <cd:command name='startline' value='شروعخط'/> <cd:command name='startlinecorrection' value='شروعتصحیحخط'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='شروعجدول'/> <cd:command name='starttables' value='شروعجدولها'/> <cd:command name='starttext' value='شروعمتن'/> + <cd:command name='starttextbackground' value='starttextbackground'/> <cd:command name='starttextrule' value='شروعخطمتن'/> <cd:command name='startunpacked' value='شروعغیرفشرده'/> <cd:command name='startversion' value='شروعنسخه'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='پایانمولفه'/> <cd:command name='stopdocument' value='پایاننوشتار'/> <cd:command name='stopenvironment' value='پایانمحیط'/> + <cd:command name='stopframed' value='stopframed'/> <cd:command name='stopglobal' value='پایانسراسری'/> <cd:command name='stopline' value='پایانخط'/> <cd:command name='stoplinecorrection' value='پایانتصحیحخط'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='پایانجدول'/> <cd:command name='stoptables' value='پایانجدولها'/> <cd:command name='stoptext' value='پایانمتن'/> + <cd:command name='stoptextbackground' value='stoptextbackground'/> <cd:command name='stoptextrule' value='پایانخطمتن'/> <cd:command name='stopunpacked' value='پایانغیرفشرده'/> <cd:command name='stopversion' value='پایاننسخه'/> diff --git a/tex/context/interface/keys-ro.xml b/tex/context/interface/keys-ro.xml index 1de8bc867..af4cc856e 100644 --- a/tex/context/interface/keys-ro.xml +++ b/tex/context/interface/keys-ro.xml @@ -425,7 +425,7 @@ <cd:variable name='september' value='septembrie'/> <cd:variable name='serif' value='serif'/> <cd:variable name='serried' value='serried'/> - <cd:variable name='setups' value='setari'/> + <cd:variable name='setups' value='setups'/> <cd:variable name='sheet' value='sheet'/> <cd:variable name='short' value='short'/> <cd:variable name='simplefonts' value='simplefonts'/> @@ -1297,6 +1297,7 @@ <cd:command name='definetabletemplate' value='definestesablontabel'/> <cd:command name='definetabulate' value='definestetabulatori'/> <cd:command name='definetext' value='definestetext'/> + <cd:command name='definetextbackground' value='definetextbackground'/> <cd:command name='definetextposition' value='definestepozitietext'/> <cd:command name='definetextvariable' value='definestevariabilatext'/> <cd:command name='definetype' value='definetype'/> @@ -1466,6 +1467,7 @@ <cd:command name='placeheadtext' value='placeheadtext'/> <cd:command name='placelegend' value='punelegenda'/> <cd:command name='placelist' value='punelista'/> + <cd:command name='placelistofsynonyms' value='placelistofsynonyms'/> <cd:command name='placelocalfootnotes' value='punenotesubsollocale'/> <cd:command name='placelogos' value='punelogouri'/> <cd:command name='placeongrid' value='plaseazapegrid'/> @@ -1618,7 +1620,6 @@ <cd:command name='setupregister' value='seteazaregistru'/> <cd:command name='setuprotate' value='seteazarotare'/> <cd:command name='setuprule' value='seteazarigla'/> - <cd:command name='setups' value='setari'/> <cd:command name='setupscreens' value='seteazaecrane'/> <cd:command name='setupsection' value='seteazasectiune'/> <cd:command name='setupsectionblock' value='seteazablocsectiune'/> @@ -1636,6 +1637,7 @@ <cd:command name='setuptables' value='seteazatabele'/> <cd:command name='setuptabulate' value='seteazatabulatori'/> <cd:command name='setuptext' value='seteazatext'/> + <cd:command name='setuptextbackground' value='setuptextbackground'/> <cd:command name='setuptextposition' value='seteazapozitietext'/> <cd:command name='setuptextrules' value='seteazarigletext'/> <cd:command name='setuptexttexts' value='seteazatextetext'/> @@ -1682,6 +1684,7 @@ <cd:command name='startdocument' value='startdocument'/> <cd:command name='startenvironment' value='startmediu'/> <cd:command name='startfigure' value='startfigura'/> + <cd:command name='startframed' value='startframed'/> <cd:command name='startglobal' value='startglobal'/> <cd:command name='startline' value='startlinie'/> <cd:command name='startlinecorrection' value='startcorectielinie'/> @@ -1708,6 +1711,7 @@ <cd:command name='starttable' value='starttabel'/> <cd:command name='starttables' value='starttabele'/> <cd:command name='starttext' value='starttext'/> + <cd:command name='starttextbackground' value='starttextbackground'/> <cd:command name='starttextrule' value='startriglatext'/> <cd:command name='startunpacked' value='startneimpachetat'/> <cd:command name='startversion' value='startversiune'/> @@ -1722,6 +1726,7 @@ <cd:command name='stopcomponent' value='stopcomponenta'/> <cd:command name='stopdocument' value='stopdocument'/> <cd:command name='stopenvironment' value='stopmediu'/> + <cd:command name='stopframed' value='stopframed'/> <cd:command name='stopglobal' value='stopblobal'/> <cd:command name='stopline' value='stoplinie'/> <cd:command name='stoplinecorrection' value='stopcorectielinie'/> @@ -1747,6 +1752,7 @@ <cd:command name='stoptable' value='stoptabel'/> <cd:command name='stoptables' value='stoptabele'/> <cd:command name='stoptext' value='stoptext'/> + <cd:command name='stoptextbackground' value='stoptextbackground'/> <cd:command name='stoptextrule' value='stopriglatext'/> <cd:command name='stopunpacked' value='stopneimpachetat'/> <cd:command name='stopversion' value='stopversiune'/> diff --git a/tex/generic/context/luatex/luatex-basics-nod.lua b/tex/generic/context/luatex/luatex-basics-nod.lua index 373dab5a8..ea539f3f6 100644 --- a/tex/generic/context/luatex/luatex-basics-nod.lua +++ b/tex/generic/context/luatex/luatex-basics-nod.lua @@ -45,7 +45,7 @@ attributes.private = attributes.private or function(name) return number end --- Nodes: +-- Nodes (a subset of context so that we don't get too much unused code): nodes = { } nodes.pool = { } @@ -105,10 +105,8 @@ function nodes.pool.kern(k) return n end --- experimental - -local getfield = node.getfield or function(n,tag) return n[tag] end -local setfield = node.setfield or function(n,tag,value) n[tag] = value end +local getfield = node.getfield +local setfield = node.setfield nodes.getfield = getfield nodes.setfield = setfield @@ -116,17 +114,6 @@ nodes.setfield = setfield nodes.getattr = getfield nodes.setattr = setfield -if node.getid then nodes.getid = node.getid else function nodes.getid (n) return getfield(n,"id") end end -if node.getsubtype then nodes.getsubtype = node.getsubtype else function nodes.getsubtype(n) return getfield(n,"subtype") end end -if node.getnext then nodes.getnext = node.getnext else function nodes.getnext (n) return getfield(n,"next") end end -if node.getprev then nodes.getprev = node.getprev else function nodes.getprev (n) return getfield(n,"prev") end end -if node.getchar then nodes.getchar = node.getchar else function nodes.getchar (n) return getfield(n,"char") end end -if node.getfont then nodes.getfont = node.getfont else function nodes.getfont (n) return getfield(n,"font") end end -if node.getlist then nodes.getlist = node.getlist else function nodes.getlist (n) return getfield(n,"list") end end - -function nodes.tonut (n) return n end -function nodes.tonode(n) return n end - -- being lazy ... just copy a bunch ... not all needed in generic but we assume -- nodes to be kind of private anyway @@ -175,4 +162,83 @@ nodes.mlist_to_hlist = node.mlist_to_hlist -- we can go nuts (e.g. experimental); this split permits us us keep code -- used elsewhere stable but at the same time play around in context -nodes.nuts = nodes +local direct = node.direct +local nuts = { } +nodes.nuts = nuts + +local tonode = direct.tonode +local tonut = direct.todirect + +nodes.tonode = tonode +nodes.tonut = tonut + +nuts.tonode = tonode +nuts.tonut = tonut + + +local getfield = direct.getfield +local setfield = direct.setfield + +nuts.getfield = getfield +nuts.setfield = setfield +nuts.getnext = direct.getnext +nuts.getprev = direct.getprev +nuts.getid = direct.getid +nuts.getattr = getfield +nuts.setattr = setfield +nuts.getfont = direct.getfont +nuts.getsubtype = direct.getsubtype +nuts.getchar = direct.getchar + +nuts.insert_before = direct.insert_before +nuts.insert_after = direct.insert_after +nuts.delete = direct.delete +nuts.copy = direct.copy +nuts.tail = direct.tail +nuts.flush_list = direct.flush_list +nuts.end_of_math = direct.end_of_math +nuts.traverse = direct.traverse +nuts.traverse_id = direct.traverse_id + +nuts.getprop = nuts.getattr +nuts.setprop = nuts.setattr + +local new_nut = direct.new +nuts.new = new_nut +nuts.pool = { } + +function nuts.pool.kern(k) + local n = new_nut("kern",1) + setfield(n,"kern",k) + return n +end + +-- properties as used in the (new) injector: + +local propertydata = direct.get_properties_table() +nodes.properties = { data = propertydata } + +direct.set_properties_mode(true,true) -- needed for injection + +function direct.set_properties_mode() end -- we really need the set modes + +nuts.getprop = function(n,k) + local p = propertydata[n] + if p then + return p[k] + end +end + +nuts.setprop = function(n,k,v) + if v then + local p = propertydata[n] + if p then + p[k] = v + else + propertydata[n] = { [k] = v } + end + end +end + +nodes.setprop = nodes.setproperty +nodes.getprop = nodes.getproperty diff --git a/tex/generic/context/luatex/luatex-fonts-cbk.lua b/tex/generic/context/luatex/luatex-fonts-cbk.lua index 9db94f65e..8632701d8 100644 --- a/tex/generic/context/luatex/luatex-fonts-cbk.lua +++ b/tex/generic/context/luatex/luatex-fonts-cbk.lua @@ -19,13 +19,26 @@ local nodes = nodes local traverse_id = node.traverse_id local glyph_code = nodes.nodecodes.glyph +-- from now on we apply ligaturing and kerning here because it might interfere with complex +-- opentype discretionary handling where the base ligature pass expect some weird extra +-- pointers (which then confuse the tail slider that has some checking built in) + +local ligaturing = node.ligaturing +local kerning = node.kerning + +function node.ligaturing() texio.write_nl("warning: node.ligaturing is already applied") end +function node.kerning () texio.write_nl("warning: node.kerning is already applied") end + function nodes.handlers.characters(head) local fontdata = fonts.hashes.identifiers if fontdata then - local usedfonts, done, prevfont = { }, false, nil + local usedfonts, basefonts, prevfont, basefont = { }, { }, nil, nil for n in traverse_id(glyph_code,head) do local font = n.font if font ~= prevfont then + if basefont then + basefont[2] = n.prev + end prevfont = font local used = usedfonts[font] if not used then @@ -36,18 +49,32 @@ function nodes.handlers.characters(head) local processors = shared.processes if processors and #processors > 0 then usedfonts[font] = processors - done = true + else + basefont = { n, nil } + basefonts[#basefonts+1] = basefont end end end end end end - if done then + if next(usedfonts) then for font, processors in next, usedfonts do for i=1,#processors do - local h, d = processors[i](head,font,0) - head, done = h or head, done or d + head = processors[i](head,font,0) or head + end + end + end + if #basefonts > 0 then + for i=1,#basefonts do + local range = basefonts[i] + local start, stop = range[1], range[2] + if stop then + ligaturing(start,stop) + kerning(start,stop) + else + ligaturing(start) + kerning(start) end end end @@ -62,7 +89,7 @@ function nodes.simple_font_handler(head) head = nodes.handlers.characters(head) nodes.injections.handler(head) nodes.handlers.protectglyphs(head) - head = node.ligaturing(head) - head = node.kerning(head) + -- head = node.ligaturing(head) + -- head = node.kerning(head) return head end diff --git a/tex/generic/context/luatex/luatex-fonts-inj.lua b/tex/generic/context/luatex/luatex-fonts-inj.lua index 5e6c07070..402403529 100644 --- a/tex/generic/context/luatex/luatex-fonts-inj.lua +++ b/tex/generic/context/luatex/luatex-fonts-inj.lua @@ -8,8 +8,9 @@ if not modules then modules = { } end modules ['node-inj'] = { -- This is very experimental (this will change when we have luatex > .50 and -- a few pending thingies are available. Also, Idris needs to make a few more --- test fonts. Btw, future versions of luatex will have extended glyph properties --- that can be of help. Some optimizations can go away when we have faster machines. +-- test fonts. Some optimizations can go away when we have faster machines. + +-- todo: ignore kerns between disc and glyph local next = next local utfchar = utf.char @@ -29,12 +30,30 @@ local injections = nodes.injections local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph local kern_code = nodecodes.kern -local nodepool = nodes.pool + +local nuts = nodes.nuts +local nodepool = nuts.pool + local newkern = nodepool.kern -local traverse_id = node.traverse_id -local insert_node_before = node.insert_before -local insert_node_after = node.insert_after +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfield = nuts.getfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getattr = nuts.getattr +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar + +local setfield = nuts.setfield +local setattr = nuts.setattr + +local traverse_id = nuts.traverse_id +local insert_node_before = nuts.insert_before +local insert_node_after = nuts.insert_after local a_kernpair = attributes.private('kernpair') local a_ligacomp = attributes.private('ligacomp') @@ -45,6 +64,8 @@ local a_cursbase = attributes.private('cursbase') local a_curscurs = attributes.private('curscurs') local a_cursdone = attributes.private('cursdone') +local unsetvalue = attributes.unsetvalue + -- This injector has been tested by Idris Samawi Hamid (several arabic fonts as well as -- the rather demanding Husayni font), Khaled Hosny (latin and arabic) and Kaj Eigner -- (arabic, hebrew and thai) and myself (whatever font I come across). I'm pretty sure @@ -65,12 +86,39 @@ local kerns = { } -- For the moment we pass the r2l key ... volt/arabtype tests .. idris: this needs -- checking with husayni (volt and fontforge). +function injections.reset(n) +-- if getattr(n,a_kernpair) then +-- setattr(n,a_kernpair,unsetvalue) +-- end +-- if getattr(n,a_markdone) then +-- setattr(n,a_markbase,unsetvalue) +-- setattr(n,a_markmark,unsetvalue) +-- setattr(n,a_markdone,unsetvalue) +-- end +-- if getattr(n,a_cursdone) then +-- setattr(n,a_cursbase,unsetvalue) +-- setattr(n,a_curscurs,unsetvalue) +-- setattr(n,a_cursdone,unsetvalue) +-- end +-- if getattr(n,a_ligacomp) then +-- setattr(n,a_ligacomp,unsetvalue) +-- end +end + +function injections.setligaindex(n,index) + setattr(n,a_ligacomp,index) +end + +function injections.getligaindex(n,default) + return getattr(n,a_ligacomp) or default +end + function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2]) local ws, wn = tfmstart.width, tfmnext.width local bound = #cursives + 1 - start[a_cursbase] = bound - nxt[a_curscurs] = bound + setattr(start,a_cursbase,bound) + setattr(nxt,a_curscurs,bound) cursives[bound] = { rlmode, dx, dy, ws, wn } return dx, dy, bound end @@ -79,14 +127,14 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr) local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4] -- dy = y - h if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then - local bound = current[a_kernpair] + local bound = getattr(current,a_kernpair) if bound then local kb = kerns[bound] -- inefficient but singles have less, but weird anyway, needs checking kb[2], kb[3], kb[4], kb[5] = (kb[2] or 0) + x, (kb[3] or 0) + y, (kb[4] or 0)+ w, (kb[5] or 0) + h else bound = #kerns + 1 - current[a_kernpair] = bound + setattr(current,a_kernpair,bound) kerns[bound] = { rlmode, x, y, w, h, r2lflag, tfmchr.width } end return x, y, w, h, bound @@ -98,7 +146,7 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) local dx = factor*x if dx ~= 0 then local bound = #kerns + 1 - current[a_kernpair] = bound + setattr(current,a_kernpair,bound) kerns[bound] = { rlmode, dx } return dx, bound else @@ -108,7 +156,7 @@ end function injections.setmark(start,base,factor,rlmode,ba,ma) -- ba=baseanchor, ma=markanchor local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) - local bound = base[a_markbase] + local bound = getattr(base,a_markbase) local index = 1 if bound then local mb = marks[bound] @@ -116,18 +164,18 @@ function injections.setmark(start,base,factor,rlmode,ba,ma) -- ba=baseanchor, ma -- if not index then index = #mb + 1 end index = #mb + 1 mb[index] = { dx, dy, rlmode } - start[a_markmark] = bound - start[a_markdone] = index + setattr(start,a_markmark,bound) + setattr(start,a_markdone,index) return dx, dy, bound else - report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound) + report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound) end end index = index or 1 bound = #marks + 1 - base[a_markbase] = bound - start[a_markmark] = bound - start[a_markdone] = index + setattr(base,a_markbase,bound) + setattr(start,a_markmark,bound) + setattr(start,a_markdone,index) marks[bound] = { [index] = { dx, dy, rlmode } } return dx, dy, bound end @@ -139,15 +187,15 @@ end local function trace(head) report_injections("begin run") for n in traverse_id(glyph_code,head) do - if n.subtype < 256 then - local kp = n[a_kernpair] - local mb = n[a_markbase] - local mm = n[a_markmark] - local md = n[a_markdone] - local cb = n[a_cursbase] - local cc = n[a_curscurs] - local char = n.char - report_injections("font %s, char %U, glyph %c",n.font,char,char) + if getsubtype(n) < 256 then + local kp = getattr(n,a_kernpair) + local mb = getattr(n,a_markbase) + local mm = getattr(n,a_markmark) + local md = getattr(n,a_markdone) + local cb = getattr(n,a_cursbase) + local cc = getattr(n,a_curscurs) + local char = getchar(n) + report_injections("font %s, char %U, glyph %c",getfont(n),char,char) if kp then local k = kerns[kp] if k[3] then @@ -195,22 +243,24 @@ local function show_result(head) local current = head local skipping = false while current do - local id = current.id + local id = getid(current) if id == glyph_code then - report_injections("char: %C, width %p, xoffset %p, yoffset %p",current.char,current.width,current.xoffset,current.yoffset) + report_injections("char: %C, width %p, xoffset %p, yoffset %p", + getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) skipping = false elseif id == kern_code then - report_injections("kern: %p",current.kern) + report_injections("kern: %p",getfield(current,"kern")) skipping = false elseif not skipping then report_injections() skipping = true end - current = current.next + current = getnext(current) end end function injections.handler(head,where,keep) + head = tonut(head) local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns) if has_marks or has_cursives then if trace_injections then @@ -221,17 +271,18 @@ function injections.handler(head,where,keep) if has_kerns then -- move outside loop local nf, tm = nil, nil for n in traverse_id(glyph_code,head) do -- only needed for relevant fonts - if n.subtype < 256 then + if getsubtype(n) < 256 then nofvalid = nofvalid + 1 valid[nofvalid] = n - if n.font ~= nf then - nf = n.font - tm = fontdata[nf].resources.marks + local f = getfont(n) + if f ~= nf then + nf = f + tm = fontdata[nf].resources.marks -- other hash in ctx end if tm then - mk[n] = tm[n.char] + mk[n] = tm[getchar(n)] end - local k = n[a_kernpair] + local k = getattr(n,a_kernpair) if k then local kk = kerns[k] if kk then @@ -251,15 +302,16 @@ function injections.handler(head,where,keep) else local nf, tm = nil, nil for n in traverse_id(glyph_code,head) do - if n.subtype < 256 then + if getsubtype(n) < 256 then nofvalid = nofvalid + 1 valid[nofvalid] = n - if n.font ~= nf then - nf = n.font - tm = fontdata[nf].resources.marks + local f = getfont(n) + if f ~= nf then + nf = f + tm = fontdata[nf].resources.marks -- other hash in ctx end if tm then - mk[n] = tm[n.char] + mk[n] = tm[getchar(n)] end end end @@ -269,7 +321,7 @@ function injections.handler(head,where,keep) local cx = { } if has_kerns and next(ky) then for n, k in next, ky do - n.yoffset = k + setfield(n,"yoffset",k) end end -- todo: reuse t and use maxt @@ -280,9 +332,9 @@ function injections.handler(head,where,keep) for i=1,nofvalid do -- valid == glyphs local n = valid[i] if not mk[n] then - local n_cursbase = n[a_cursbase] + local n_cursbase = getattr(n,a_cursbase) if p_cursbase then - local n_curscurs = n[a_curscurs] + local n_curscurs = getattr(n,a_curscurs) if p_cursbase == n_curscurs then local c = cursives[n_curscurs] if c then @@ -307,20 +359,20 @@ function injections.handler(head,where,keep) end end elseif maxt > 0 then - local ny = n.yoffset + local ny = getfield(n,"yoffset") for i=maxt,1,-1 do ny = ny + d[i] local ti = t[i] - ti.yoffset = ti.yoffset + ny + setfield(ti,"yoffset",getfield(ti,"yoffset") + ny) end maxt = 0 end if not n_cursbase and maxt > 0 then - local ny = n.yoffset + local ny = getfield(n,"yoffset") for i=maxt,1,-1 do ny = ny + d[i] local ti = t[i] - ti.yoffset = ny + setfield(ti,"yoffset",ny) -- maybe add to current yoffset end maxt = 0 end @@ -328,11 +380,11 @@ function injections.handler(head,where,keep) end end if maxt > 0 then - local ny = n.yoffset + local ny = getfield(n,"yoffset") -- hm, n unset ? for i=maxt,1,-1 do ny = ny + d[i] local ti = t[i] - ti.yoffset = ny + setfield(ti,"yoffset",ny) end maxt = 0 end @@ -343,57 +395,83 @@ function injections.handler(head,where,keep) if has_marks then for i=1,nofvalid do local p = valid[i] - local p_markbase = p[a_markbase] + local p_markbase = getattr(p,a_markbase) if p_markbase then - local mrks = marks[p_markbase] - local nofmarks = #mrks - for n in traverse_id(glyph_code,p.next) do - local n_markmark = n[a_markmark] + local mrks = marks[p_markbase] + local nofmarks = #mrks + for n in traverse_id(glyph_code,getnext(p)) do + local n_markmark = getattr(n,a_markmark) if p_markbase == n_markmark then - local index = n[a_markdone] or 1 + local index = getattr(n,a_markdone) or 1 local d = mrks[index] if d then local rlmode = d[3] -- local k = wx[p] + local px = getfield(p,"xoffset") + local ox = 0 if k then local x = k[2] local w = k[4] if w then if rlmode and rlmode >= 0 then -- kern(x) glyph(p) kern(w-x) mark(n) - n.xoffset = p.xoffset - p.width + d[1] - (w-x) + ox = px - getfield(p,"width") + d[1] - (w-x) + -- report_injections("l2r case 1: %p",ox) else -- kern(w-x) glyph(p) kern(x) mark(n) - n.xoffset = p.xoffset - d[1] - x + ox = px - d[1] - x + -- report_injections("r2l case 1: %p",ox) end else if rlmode and rlmode >= 0 then -- okay for husayni - n.xoffset = p.xoffset - p.width + d[1] + ox = px - getfield(p,"width") + d[1] + -- report_injections("r2l case 2: %p",ox) else -- needs checking: is x ok here? - n.xoffset = p.xoffset - d[1] - x + ox = px - d[1] - x + -- report_injections("r2l case 2: %p",ox) end end else + -- if rlmode and rlmode >= 0 then + -- ox = px - getfield(p,"width") + d[1] + -- -- report_injections("l2r case 3: %p",ox) + -- else + -- ox = px - d[1] + -- -- report_injections("r2l case 3: %p",ox) + -- end + -- + -- we need to deal with fonts that have marks with width + -- + local wp = getfield(p,"width") + local wn = getfield(n,"width") -- in arial marks have widths if rlmode and rlmode >= 0 then - n.xoffset = p.xoffset - p.width + d[1] + ox = px - wp + d[1] + -- report_injections("l2r case 3: %p",ox) else - n.xoffset = p.xoffset - d[1] + ox = px - d[1] + -- report_injections("r2l case 3: %p",ox) end - local w = n.width - if w ~= 0 then - insert_node_before(head,n,newkern(-w/2)) - insert_node_after(head,n,newkern(-w/2)) + if wn ~= 0 then + -- bad: we should center + insert_node_before(head,n,newkern(-wn/2)) + insert_node_after(head,n,newkern(-wn/2)) + -- wx[n] = { 0, -wn/2, 0, -wn } end + -- so far end - -- -- + setfield(n,"xoffset",ox) + -- + local py = getfield(p,"yoffset") + local oy = 0 if mk[p] then - n.yoffset = p.yoffset + d[2] + oy = py + d[2] else - n.yoffset = n.yoffset + p.yoffset + d[2] + oy = getfield(n,"yoffset") + py + d[2] end + setfield(n,"yoffset",oy) -- if nofmarks == 1 then break @@ -401,6 +479,8 @@ function injections.handler(head,where,keep) nofmarks = nofmarks - 1 end end + elseif not n_markmark then + break -- HH: added 2013-09-12: no need to deal with non marks else -- KE: there can be <mark> <mkmk> <mark> sequences in ligatures end @@ -462,7 +542,7 @@ function injections.handler(head,where,keep) -- if trace_injections then -- show_result(head) -- end - return head, true + return tonode(head), true elseif not keep then kerns, cursives, marks = { }, { }, { } end @@ -471,14 +551,14 @@ function injections.handler(head,where,keep) trace(head) end for n in traverse_id(glyph_code,head) do - if n.subtype < 256 then - local k = n[a_kernpair] + if getsubtype(n) < 256 then + local k = getattr(n,a_kernpair) if k then local kk = kerns[k] if kk then local rl, x, y, w = kk[1], kk[2] or 0, kk[3], kk[4] if y and y ~= 0 then - n.yoffset = y -- todo: h ? + setfield(n,"yoffset",y) -- todo: h ? end if w then -- copied from above @@ -515,9 +595,9 @@ function injections.handler(head,where,keep) -- if trace_injections then -- show_result(head) -- end - return head, true + return tonode(head), true else -- no tracing needed end - return head, false + return tonode(head), false end diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index db3512e7e..031320402 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 : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 11/26/14 21:43:54 +-- merge date : 12/03/14 18:26:33 do -- begin closure to overcome local limits and interference @@ -3849,21 +3849,12 @@ function nodes.pool.kern(k) n.kern=k return n end -local getfield=node.getfield or function(n,tag) return n[tag] end -local setfield=node.setfield or function(n,tag,value) n[tag]=value end +local getfield=node.getfield +local setfield=node.setfield nodes.getfield=getfield nodes.setfield=setfield nodes.getattr=getfield nodes.setattr=setfield -if node.getid then nodes.getid=node.getid else function nodes.getid (n) return getfield(n,"id") end end -if node.getsubtype then nodes.getsubtype=node.getsubtype else function nodes.getsubtype(n) return getfield(n,"subtype") end end -if node.getnext then nodes.getnext=node.getnext else function nodes.getnext (n) return getfield(n,"next") end end -if node.getprev then nodes.getprev=node.getprev else function nodes.getprev (n) return getfield(n,"prev") end end -if node.getchar then nodes.getchar=node.getchar else function nodes.getchar (n) return getfield(n,"char") end end -if node.getfont then nodes.getfont=node.getfont else function nodes.getfont (n) return getfield(n,"font") end end -if node.getlist then nodes.getlist=node.getlist else function nodes.getlist (n) return getfield(n,"list") end end -function nodes.tonut (n) return n end -function nodes.tonode(n) return n end nodes.tostring=node.tostring or tostring nodes.copy=node.copy nodes.copy_list=node.copy_list @@ -3900,7 +3891,68 @@ nodes.unprotect_glyphs=node.unprotect_glyphs nodes.kerning=node.kerning nodes.ligaturing=node.ligaturing nodes.mlist_to_hlist=node.mlist_to_hlist -nodes.nuts=nodes +local direct=node.direct +local nuts={} +nodes.nuts=nuts +local tonode=direct.tonode +local tonut=direct.todirect +nodes.tonode=tonode +nodes.tonut=tonut +nuts.tonode=tonode +nuts.tonut=tonut +local getfield=direct.getfield +local setfield=direct.setfield +nuts.getfield=getfield +nuts.setfield=setfield +nuts.getnext=direct.getnext +nuts.getprev=direct.getprev +nuts.getid=direct.getid +nuts.getattr=getfield +nuts.setattr=setfield +nuts.getfont=direct.getfont +nuts.getsubtype=direct.getsubtype +nuts.getchar=direct.getchar +nuts.insert_before=direct.insert_before +nuts.insert_after=direct.insert_after +nuts.delete=direct.delete +nuts.copy=direct.copy +nuts.tail=direct.tail +nuts.flush_list=direct.flush_list +nuts.end_of_math=direct.end_of_math +nuts.traverse=direct.traverse +nuts.traverse_id=direct.traverse_id +nuts.getprop=nuts.getattr +nuts.setprop=nuts.setattr +local new_nut=direct.new +nuts.new=new_nut +nuts.pool={} +function nuts.pool.kern(k) + local n=new_nut("kern",1) + setfield(n,"kern",k) + return n +end +local propertydata=direct.get_properties_table() +nodes.properties={ data=propertydata } +direct.set_properties_mode(true,true) +function direct.set_properties_mode() end +nuts.getprop=function(n,k) + local p=propertydata[n] + if p then + return p[k] + end +end +nuts.setprop=function(n,k,v) + if v then + local p=propertydata[n] + if p then + p[k]=v + else + propertydata[n]={ [k]=v } + end + end +end +nodes.setprop=nodes.setproperty +nodes.getprop=nodes.getproperty end -- closure @@ -9785,11 +9837,24 @@ local injections=nodes.injections local nodecodes=nodes.nodecodes local glyph_code=nodecodes.glyph local kern_code=nodecodes.kern -local nodepool=nodes.pool +local nuts=nodes.nuts +local nodepool=nuts.pool local newkern=nodepool.kern -local traverse_id=node.traverse_id -local insert_node_before=node.insert_before -local insert_node_after=node.insert_after +local tonode=nuts.tonode +local tonut=nuts.tonut +local getfield=nuts.getfield +local getnext=nuts.getnext +local getprev=nuts.getprev +local getid=nuts.getid +local getattr=nuts.getattr +local getfont=nuts.getfont +local getsubtype=nuts.getsubtype +local getchar=nuts.getchar +local setfield=nuts.setfield +local setattr=nuts.setattr +local traverse_id=nuts.traverse_id +local insert_node_before=nuts.insert_before +local insert_node_after=nuts.insert_after local a_kernpair=attributes.private('kernpair') local a_ligacomp=attributes.private('ligacomp') local a_markbase=attributes.private('markbase') @@ -9798,31 +9863,40 @@ local a_markdone=attributes.private('markdone') local a_cursbase=attributes.private('cursbase') local a_curscurs=attributes.private('curscurs') local a_cursdone=attributes.private('cursdone') +local unsetvalue=attributes.unsetvalue function injections.installnewkern(nk) newkern=nk or newkern end local cursives={} local marks={} local kerns={} +function injections.reset(n) +end +function injections.setligaindex(n,index) + setattr(n,a_ligacomp,index) +end +function injections.getligaindex(n,default) + return getattr(n,a_ligacomp) or default +end function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) local dx,dy=factor*(exit[1]-entry[1]),factor*(exit[2]-entry[2]) local ws,wn=tfmstart.width,tfmnext.width local bound=#cursives+1 - start[a_cursbase]=bound - nxt[a_curscurs]=bound + setattr(start,a_cursbase,bound) + setattr(nxt,a_curscurs,bound) cursives[bound]={ rlmode,dx,dy,ws,wn } return dx,dy,bound end function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr) local x,y,w,h=factor*spec[1],factor*spec[2],factor*spec[3],factor*spec[4] if x~=0 or w~=0 or y~=0 or h~=0 then - local bound=current[a_kernpair] + local bound=getattr(current,a_kernpair) if bound then local kb=kerns[bound] kb[2],kb[3],kb[4],kb[5]=(kb[2] or 0)+x,(kb[3] or 0)+y,(kb[4] or 0)+w,(kb[5] or 0)+h else bound=#kerns+1 - current[a_kernpair]=bound + setattr(current,a_kernpair,bound) kerns[bound]={ rlmode,x,y,w,h,r2lflag,tfmchr.width } end return x,y,w,h,bound @@ -9833,7 +9907,7 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) local dx=factor*x if dx~=0 then local bound=#kerns+1 - current[a_kernpair]=bound + setattr(current,a_kernpair,bound) kerns[bound]={ rlmode,dx } return dx,bound else @@ -9842,25 +9916,25 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) end function injections.setmark(start,base,factor,rlmode,ba,ma) local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) - local bound=base[a_markbase] + local bound=getattr(base,a_markbase) local index=1 if bound then local mb=marks[bound] if mb then index=#mb+1 mb[index]={ dx,dy,rlmode } - start[a_markmark]=bound - start[a_markdone]=index + setattr(start,a_markmark,bound) + setattr(start,a_markdone,index) return dx,dy,bound else - report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound) + report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound) end end index=index or 1 bound=#marks+1 - base[a_markbase]=bound - start[a_markmark]=bound - start[a_markdone]=index + setattr(base,a_markbase,bound) + setattr(start,a_markmark,bound) + setattr(start,a_markdone,index) marks[bound]={ [index]={ dx,dy,rlmode } } return dx,dy,bound end @@ -9870,15 +9944,15 @@ end local function trace(head) report_injections("begin run") for n in traverse_id(glyph_code,head) do - if n.subtype<256 then - local kp=n[a_kernpair] - local mb=n[a_markbase] - local mm=n[a_markmark] - local md=n[a_markdone] - local cb=n[a_cursbase] - local cc=n[a_curscurs] - local char=n.char - report_injections("font %s, char %U, glyph %c",n.font,char,char) + if getsubtype(n)<256 then + local kp=getattr(n,a_kernpair) + local mb=getattr(n,a_markbase) + local mm=getattr(n,a_markmark) + local md=getattr(n,a_markdone) + local cb=getattr(n,a_cursbase) + local cc=getattr(n,a_curscurs) + local char=getchar(n) + report_injections("font %s, char %U, glyph %c",getfont(n),char,char) if kp then local k=kerns[kp] if k[3] then @@ -9919,21 +9993,23 @@ local function show_result(head) local current=head local skipping=false while current do - local id=current.id + local id=getid(current) if id==glyph_code then - report_injections("char: %C, width %p, xoffset %p, yoffset %p",current.char,current.width,current.xoffset,current.yoffset) + report_injections("char: %C, width %p, xoffset %p, yoffset %p", + getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) skipping=false elseif id==kern_code then - report_injections("kern: %p",current.kern) + report_injections("kern: %p",getfield(current,"kern")) skipping=false elseif not skipping then report_injections() skipping=true end - current=current.next + current=getnext(current) end end function injections.handler(head,where,keep) + head=tonut(head) local has_marks,has_cursives,has_kerns=next(marks),next(cursives),next(kerns) if has_marks or has_cursives then if trace_injections then @@ -9943,17 +10019,18 @@ function injections.handler(head,where,keep) if has_kerns then local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if n.subtype<256 then + if getsubtype(n)<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - if n.font~=nf then - nf=n.font - tm=fontdata[nf].resources.marks + local f=getfont(n) + if f~=nf then + nf=f + tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[n.char] + mk[n]=tm[getchar(n)] end - local k=n[a_kernpair] + local k=getattr(n,a_kernpair) if k then local kk=kerns[k] if kk then @@ -9973,15 +10050,16 @@ function injections.handler(head,where,keep) else local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if n.subtype<256 then + if getsubtype(n)<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - if n.font~=nf then - nf=n.font - tm=fontdata[nf].resources.marks + local f=getfont(n) + if f~=nf then + nf=f + tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[n.char] + mk[n]=tm[getchar(n)] end end end @@ -9990,7 +10068,7 @@ function injections.handler(head,where,keep) local cx={} if has_kerns and next(ky) then for n,k in next,ky do - n.yoffset=k + setfield(n,"yoffset",k) end end if has_cursives then @@ -9999,9 +10077,9 @@ function injections.handler(head,where,keep) for i=1,nofvalid do local n=valid[i] if not mk[n] then - local n_cursbase=n[a_cursbase] + local n_cursbase=getattr(n,a_cursbase) if p_cursbase then - local n_curscurs=n[a_curscurs] + local n_curscurs=getattr(n,a_curscurs) if p_cursbase==n_curscurs then local c=cursives[n_curscurs] if c then @@ -10024,20 +10102,20 @@ function injections.handler(head,where,keep) end end elseif maxt>0 then - local ny=n.yoffset + local ny=getfield(n,"yoffset") for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - ti.yoffset=ti.yoffset+ny + setfield(ti,"yoffset",getfield(ti,"yoffset")+ny) end maxt=0 end if not n_cursbase and maxt>0 then - local ny=n.yoffset + local ny=getfield(n,"yoffset") for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - ti.yoffset=ny + setfield(ti,"yoffset",ny) end maxt=0 end @@ -10045,11 +10123,11 @@ function injections.handler(head,where,keep) end end if maxt>0 then - local ny=n.yoffset + local ny=getfield(n,"yoffset") for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - ti.yoffset=ny + setfield(ti,"yoffset",ny) end maxt=0 end @@ -10060,57 +10138,66 @@ function injections.handler(head,where,keep) if has_marks then for i=1,nofvalid do local p=valid[i] - local p_markbase=p[a_markbase] + local p_markbase=getattr(p,a_markbase) if p_markbase then local mrks=marks[p_markbase] local nofmarks=#mrks - for n in traverse_id(glyph_code,p.next) do - local n_markmark=n[a_markmark] + for n in traverse_id(glyph_code,getnext(p)) do + local n_markmark=getattr(n,a_markmark) if p_markbase==n_markmark then - local index=n[a_markdone] or 1 + local index=getattr(n,a_markdone) or 1 local d=mrks[index] if d then local rlmode=d[3] local k=wx[p] + local px=getfield(p,"xoffset") + local ox=0 if k then local x=k[2] local w=k[4] if w then if rlmode and rlmode>=0 then - n.xoffset=p.xoffset-p.width+d[1]-(w-x) + ox=px-getfield(p,"width")+d[1]-(w-x) else - n.xoffset=p.xoffset-d[1]-x + ox=px-d[1]-x end else if rlmode and rlmode>=0 then - n.xoffset=p.xoffset-p.width+d[1] + ox=px-getfield(p,"width")+d[1] else - n.xoffset=p.xoffset-d[1]-x + ox=px-d[1]-x end end else + local wp=getfield(p,"width") + local wn=getfield(n,"width") if rlmode and rlmode>=0 then - n.xoffset=p.xoffset-p.width+d[1] + ox=px-wp+d[1] else - n.xoffset=p.xoffset-d[1] + ox=px-d[1] end - local w=n.width - if w~=0 then - insert_node_before(head,n,newkern(-w/2)) - insert_node_after(head,n,newkern(-w/2)) + if wn~=0 then + insert_node_before(head,n,newkern(-wn/2)) + insert_node_after(head,n,newkern(-wn/2)) end end + setfield(n,"xoffset",ox) + local py=getfield(p,"yoffset") + local oy=0 if mk[p] then - n.yoffset=p.yoffset+d[2] + oy=py+d[2] else - n.yoffset=n.yoffset+p.yoffset+d[2] + oy=getfield(n,"yoffset")+py+d[2] end + setfield(n,"yoffset",oy) if nofmarks==1 then break else nofmarks=nofmarks-1 end end + elseif not n_markmark then + break else end end @@ -10162,7 +10249,7 @@ function injections.handler(head,where,keep) if not keep then kerns={} end - return head,true + return tonode(head),true elseif not keep then kerns,cursives,marks={},{},{} end @@ -10171,14 +10258,14 @@ function injections.handler(head,where,keep) trace(head) end for n in traverse_id(glyph_code,head) do - if n.subtype<256 then - local k=n[a_kernpair] + if getsubtype(n)<256 then + local k=getattr(n,a_kernpair) if k then local kk=kerns[k] if kk then local rl,x,y,w=kk[1],kk[2] or 0,kk[3],kk[4] if y and y~=0 then - n.yoffset=y + setfield(n,"yoffset",y) end if w then local wx=w-x @@ -10209,17 +10296,17 @@ function injections.handler(head,where,keep) if not keep then kerns={} end - return head,true + return tonode(head),true else end - return head,false + return tonode(head),false end end -- closure do -- begin closure to overcome local limits and interference -if not modules then modules={} end modules ['font-ota']={ +if not modules then modules={} end modules ['font-otx']={ version=1.001, comment="companion to font-otf.lua (analysing)", author="Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -10238,13 +10325,24 @@ analyzers.initializers=initializers analyzers.methods=methods analyzers.useunicodemarks=false local a_state=attributes.private('state') +local nuts=nodes.nuts +local tonut=nuts.tonut +local getfield=nuts.getfield +local getnext=nuts.getnext +local getprev=nuts.getprev +local getid=nuts.getid +local getprop=nuts.getprop +local setprop=nuts.setprop +local getfont=nuts.getfont +local getsubtype=nuts.getsubtype +local getchar=nuts.getchar +local traverse_id=nuts.traverse_id +local traverse_node_list=nuts.traverse +local end_of_math=nuts.end_of_math local nodecodes=nodes.nodecodes local glyph_code=nodecodes.glyph local disc_code=nodecodes.disc local math_code=nodecodes.math -local traverse_id=node.traverse_id -local traverse_node_list=node.traverse -local end_of_math=node.end_of_math local fontdata=fonts.hashes.identifiers local categories=characters and characters.categories or {} local otffeatures=fonts.constructors.newfeatures("otf") @@ -10286,51 +10384,52 @@ function analyzers.setstate(head,font) local tfmdata=fontdata[font] local descriptions=tfmdata.descriptions local first,last,current,n,done=nil,nil,head,0,false + current=tonut(current) while current do - local id=current.id - if id==glyph_code and current.font==font then + local id=getid(current) + if id==glyph_code and getfont(current)==font then done=true - local char=current.char + local char=getchar(current) local d=descriptions[char] if d then if d.class=="mark" or (useunicodemarks and categories[char]=="mn") then done=true - current[a_state]=s_mark + setprop(current,a_state,s_mark) elseif n==0 then first,last,n=current,current,1 - current[a_state]=s_init + setprop(current,a_state,s_init) else last,n=current,n+1 - current[a_state]=s_medi + setprop(current,a_state,s_medi) end else if first and first==last then - last[a_state]=s_isol + setprop(last,a_state,s_isol) elseif last then - last[a_state]=s_fina + setprop(last,a_state,s_fina) end first,last,n=nil,nil,0 end elseif id==disc_code then - current[a_state]=s_medi + setprop(current,a_state,s_medi) last=current else if first and first==last then - last[a_state]=s_isol + setprop(last,a_state,s_isol) elseif last then - last[a_state]=s_fina + setprop(last,a_state,s_fina) end first,last,n=nil,nil,0 if id==math_code then current=end_of_math(current) end end - current=current.next + current=getnext(current) end if first and first==last then - last[a_state]=s_isol + setprop(last,a_state,s_isol) elseif last then - last[a_state]=s_fina + setprop(last,a_state,s_fina) end return head,done end @@ -10478,7 +10577,7 @@ local medial={ } local arab_warned={} local function warning(current,what) - local char=current.char + local char=getchar(current) if not arab_warned[char] then log.report("analyze","arab: character %C has no %a class",char,what) arab_warned[char]=true @@ -10487,30 +10586,30 @@ end local function finish(first,last) if last then if first==last then - local fc=first.char + local fc=getchar(first) if medial[fc] or final[fc] then - first[a_state]=s_isol + setprop(first,a_state,s_isol) else warning(first,"isol") - first[a_state]=s_error + setprop(first,a_state,s_error) end else - local lc=last.char + local lc=getchar(last) if medial[lc] or final[lc] then - last[a_state]=s_fina + setprop(last,a_state,s_fina) else warning(last,"fina") - last[a_state]=s_error + setprop(last,a_state,s_error) end end first,last=nil,nil elseif first then - local fc=first.char + local fc=getchar(first) if medial[fc] or final[fc] then - first[a_state]=s_isol + setprop(first,a_state,s_isol) else warning(first,"isol") - first[a_state]=s_error + setprop(first,a_state,s_error) end first=nil end @@ -10521,38 +10620,39 @@ function methods.arab(head,font,attr) local tfmdata=fontdata[font] local marks=tfmdata.resources.marks local first,last,current,done=nil,nil,head,false + current=tonut(current) while current do - local id=current.id - if id==glyph_code and current.font==font and current.subtype<256 and not current[a_state] then + local id=getid(current) + if id==glyph_code and getfont(current)==font and getsubtype(current)<256 and not getprop(current,a_state) then done=true - local char=current.char + local char=getchar(current) if marks[char] or (useunicodemarks and categories[char]=="mn") then - current[a_state]=s_mark + setprop(current,a_state,s_mark) elseif isolated[char] then first,last=finish(first,last) - current[a_state]=s_isol + setprop(current,a_state,s_isol) first,last=nil,nil elseif not first then if medial[char] then - current[a_state]=s_init + setprop(current,a_state,s_init) first,last=first or current,current elseif final[char] then - current[a_state]=s_isol + setprop(current,a_state,s_isol) first,last=nil,nil else first,last=finish(first,last) end elseif medial[char] then first,last=first or current,current - current[a_state]=s_medi + setprop(current,a_state,s_medi) elseif final[char] then - if not last[a_state]==s_init then - last[a_state]=s_medi + if getprop(last,a_state)~=s_init then + setprop(last,a_state,s_medi) end - current[a_state]=s_fina + setprop(current,a_state,s_fina) first,last=nil,nil elseif char>=0x0600 and char<=0x06FF then - current[a_state]=s_rest + setprop(current,a_state,s_rest) first,last=finish(first,last) else first,last=finish(first,last) @@ -10565,7 +10665,7 @@ function methods.arab(head,font,attr) current=end_of_math(current) end end - current=current.next + current=getnext(current) end if first or last then finish(first,last) @@ -10629,12 +10729,27 @@ registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive") registertracker("otf.actions","otf.replacements,otf.positions") registertracker("otf.injections","nodes.injections") registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") -local insert_node_after=node.insert_after -local delete_node=nodes.delete -local copy_node=node.copy -local find_node_tail=node.tail or node.slide -local flush_node_list=node.flush_list -local end_of_math=node.end_of_math +local nuts=nodes.nuts +local tonode=nuts.tonode +local tonut=nuts.tonut +local getfield=nuts.getfield +local setfield=nuts.setfield +local getnext=nuts.getnext +local getprev=nuts.getprev +local getid=nuts.getid +local getattr=nuts.getattr +local setattr=nuts.setattr +local getprop=nuts.getprop +local setprop=nuts.setprop +local getfont=nuts.getfont +local getsubtype=nuts.getsubtype +local getchar=nuts.getchar +local insert_node_after=nuts.insert_after +local delete_node=nuts.delete +local copy_node=nuts.copy +local find_node_tail=nuts.tail +local flush_node_list=nuts.flush_list +local end_of_math=nuts.end_of_math local setmetatableindex=table.setmetatableindex local zwnj=0x200C local zwj=0x200D @@ -10655,22 +10770,16 @@ local discretionary_code=disccodes.discretionary local ligature_code=glyphcodes.ligature local privateattribute=attributes.private local a_state=privateattribute('state') -local a_markbase=privateattribute('markbase') -local a_markmark=privateattribute('markmark') -local a_markdone=privateattribute('markdone') -local a_cursbase=privateattribute('cursbase') -local a_curscurs=privateattribute('curscurs') -local a_cursdone=privateattribute('cursdone') -local a_kernpair=privateattribute('kernpair') -local a_ligacomp=privateattribute('ligacomp') +local a_cursbase=privateattribute('cursbase') local injections=nodes.injections local setmark=injections.setmark local setcursive=injections.setcursive local setkern=injections.setkern local setpair=injections.setpair -local markonce=true +local resetinjection=injections.reset +local setligaindex=injections.setligaindex +local getligaindex=injections.getligaindex local cursonce=true -local kernonce=true local fonthashes=fonts.hashes local fontdata=fonthashes.identifiers local otffeatures=fonts.constructors.newfeatures("otf") @@ -10746,83 +10855,86 @@ local function pref(kind,lookupname) return formatters["feature %a, lookup %a"](kind,lookuptags[lookupname]) end local function copy_glyph(g) - local components=g.components + local components=getfield(g,"components") if components then - g.components=nil + setfield(g,"components",nil) local n=copy_node(g) - g.components=components + setfield(g,"components",components) return n else return copy_node(g) end end local function markstoligature(kind,lookupname,head,start,stop,char) - if start==stop and start.char==char then + if start==stop and getchar(start)==char then return head,start else - local prev=start.prev - local next=stop.next - start.prev=nil - stop.next=nil + local prev=getprev(start) + local next=getnext(stop) + setfield(start,"prev",nil) + setfield(stop,"next",nil) local base=copy_glyph(start) if head==start then head=base end - base.char=char - base.subtype=ligature_code - base.components=start + resetinjection(base) + setfield(base,"char",char) + setfield(base,"subtype",ligature_code) + setfield(base,"components",start) if prev then - prev.next=base + setfield(prev,"next",base) end if next then - next.prev=base + setfield(next,"prev",base) end - base.next=next - base.prev=prev + setfield(base,"next",next) + setfield(base,"prev",prev) return head,base end end local function getcomponentindex(start) - if start.id~=glyph_code then + if getid(start)~=glyph_code then return 0 - elseif start.subtype==ligature_code then + elseif getsubtype(start)==ligature_code then local i=0 - local components=start.components + local components=getfield(start,"components") while components do i=i+getcomponentindex(components) - components=components.next + components=getnext(components) end return i - elseif not marks[start.char] then + elseif not marks[getchar(start)] then return 1 else return 0 end end local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) - if start==stop and start.char==char then - start.char=char + if start==stop and getchar(start)==char then + resetinjection(start) + setfield(start,"char",char) return head,start end - local prev=start.prev - local next=stop.next - start.prev=nil - stop.next=nil + local prev=getprev(start) + local next=getnext(stop) + setfield(start,"prev",nil) + setfield(stop,"next",nil) local base=copy_glyph(start) if start==head then head=base end - base.char=char - base.subtype=ligature_code - base.components=start + resetinjection(base) + setfield(base,"char",char) + setfield(base,"subtype",ligature_code) + setfield(base,"components",start) if prev then - prev.next=base + setfield(prev,"next",base) end if next then - next.prev=base + setfield(next,"prev",base) end - base.next=next - base.prev=prev + setfield(base,"next",next) + setfield(base,"prev",prev) if not discfound then local deletemarks=markflag~="mark" local components=start @@ -10831,42 +10943,43 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun local head=base local current=base while start do - local char=start.char + local char=getchar(start) if not marks[char] then baseindex=baseindex+componentindex componentindex=getcomponentindex(start) elseif not deletemarks then - start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) + setligaindex(start,baseindex+getligaindex(start,componentindex)) if trace_marks then - logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getligaindex(start)) end head,current=insert_node_after(head,current,copy_node(start)) elseif trace_marks then logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char)) end - start=start.next + start=getnext(start) end - local start=current.next - while start and start.id==glyph_code do - local char=start.char + local start=getnext(current) + while start and getid(start)==glyph_code do + local char=getchar(start) if marks[char] then - start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) + setligaindex(start,baseindex+getligaindex(start,componentindex)) if trace_marks then - logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getligaindex(start)) end else break end - start=start.next + start=getnext(start) end end return head,base end function handlers.gsub_single(head,start,kind,lookupname,replacement) if trace_singles then - logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement)) + logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement)) end - start.char=replacement + resetinjection(start) + setfield(start,"char",replacement) return head,start,true end local function get_alternative_glyph(start,alternatives,value,trace_alternatives) @@ -10892,7 +11005,7 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end elseif value==0 then - return start.char,trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") elseif value<1 then return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) else @@ -10903,25 +11016,27 @@ end local function multiple_glyphs(head,start,multiple,ignoremarks) local nofmultiples=#multiple if nofmultiples>0 then - start.char=multiple[1] + resetinjection(start) + setfield(start,"char",multiple[1]) if nofmultiples>1 then - local sn=start.next + local sn=getnext(start) for k=2,nofmultiples do local n=copy_node(start) - n.char=multiple[k] - n.next=sn - n.prev=start + resetinjection(n) + setfield(n,"char",multiple[k]) + setfield(n,"next",sn) + setfield(n,"prev",start) if sn then - sn.prev=n + setfield(sn,"prev",n) end - start.next=n + setfield(start,"next",n) start=n end end return head,start,true else if trace_multiples then - logprocess("no multiple for %s",gref(start.char)) + logprocess("no multiple for %s",gref(getchar(start))) end return head,start,false end @@ -10931,34 +11046,35 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence local choice,comment=get_alternative_glyph(start,alternative,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment) end - start.char=choice + resetinjection(start) + setfield(start,"char",choice) else if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment) end end return head,start,true end function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence) if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple)) + logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(getchar(start)),gref(multiple)) end return multiple_glyphs(head,start,multiple,sequence.flags[1]) end function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) - local s,stop,discfound=start.next,nil,false - local startchar=start.char + local s,stop,discfound=getnext(start),nil,false + local startchar=getchar(start) if marks[startchar] then while s do - local id=s.id - if id==glyph_code and s.font==currentfont and s.subtype<256 then - local lg=ligature[s.char] + local id=getid(s) + if id==glyph_code and getfont(s)==currentfont and getsubtype(s)<256 then + local lg=ligature[getchar(s)] if lg then stop=s ligature=lg - s=s.next + s=getnext(s) else break end @@ -10970,9 +11086,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) local lig=ligature.ligature if lig then if trace_ligatures then - local stopchar=stop.char + local stopchar=getchar(stop) head,start=markstoligature(kind,lookupname,head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) else head,start=markstoligature(kind,lookupname,head,start,stop,lig) end @@ -10983,18 +11099,18 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) else local skipmark=sequence.flags[1] while s do - local id=s.id - if id==glyph_code and s.subtype<256 then - if s.font==currentfont then - local char=s.char + local id=getid(s) + if id==glyph_code and getsubtype(s)<256 then + if getfont(s)==currentfont then + local char=getchar(s) if skipmark and marks[char] then - s=s.next + s=getnext(s) else local lg=ligature[char] if lg then stop=s ligature=lg - s=s.next + s=getnext(s) else break end @@ -11004,7 +11120,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) end elseif id==disc_code then discfound=true - s=s.next + s=getnext(s) else break end @@ -11013,36 +11129,36 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) if lig then if stop then if trace_ligatures then - local stopchar=stop.char + local stopchar=getchar(stop) head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) else head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) end - return head,start,true else - start.char=lig + resetinjection(start) + setfield(start,"char",lig) if trace_ligatures then logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig)) end - return head,start,true end + return head,start,true else end end return head,start,false end function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -11066,7 +11182,7 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence if al[anchor] then local ma=markanchors[anchor] if ma then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -11091,16 +11207,16 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -11112,7 +11228,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ end end end - local index=start[a_ligacomp] + local index=getligaindex(start) local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -11126,7 +11242,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ if ma then ba=ba[index] if ba then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) @@ -11157,22 +11273,22 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ return head,start,false end function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then - local base=start.prev - local slc=start[a_ligacomp] + local base=getprev(start) + local slc=getligaindex(start) if slc then while base do - local blc=base[a_ligacomp] + local blc=getligaindex(base) if blc and blc~=slc then - base=base.prev + base=getprev(base) else break end end end - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -11184,7 +11300,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence if al[anchor] then local ma=markanchors[anchor] if ma then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -11210,20 +11326,20 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) - local alreadydone=cursonce and start[a_cursbase] + local alreadydone=cursonce and getprop(start,a_cursbase) if not alreadydone then local done=false - local startchar=start.char + local startchar=getchar(start) if marks[startchar] then if trace_cursive then logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=start.next - while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do - local nextchar=nxt.char + local nxt=getnext(start) + while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do + local nextchar=getchar(nxt) if marks[nextchar] then - nxt=nxt.next + nxt=getnext(nxt) else local entryanchors=descriptions[nextchar] if entryanchors then @@ -11257,13 +11373,13 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) end return head,start,false end end function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) - local startchar=start.char + local startchar=getchar(start) local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) @@ -11271,33 +11387,33 @@ function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) return head,start,false end function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) - local snext=start.next + local snext=getnext(start) if not snext then return head,start,false else local prev,done=start,false local factor=tfmdata.parameters.factor local lookuptype=lookuptypes[lookupname] - while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do - local nextchar=snext.char + while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do + local nextchar=getchar(snext) local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=snext.next + snext=getnext(snext) else if not krn then elseif type(krn)=="table" then if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -11310,7 +11426,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) end done=true end @@ -11345,13 +11461,14 @@ function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,looku return head,start,false end function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements) - local char=start.char + local char=getchar(start) local replacement=replacements[char] if replacement then if trace_singles then logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement)) end - start.char=replacement + resetinjection(start) + setfield(start,"char",replacement) return head,start,true else return head,start,false @@ -11364,8 +11481,8 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) end while current do - if current.id==glyph_code then - local currentchar=current.char + if getid(current)==glyph_code then + local currentchar=getchar(current) local lookupname=subtables[1] local replacement=lookuphash[lookupname] if not replacement then @@ -11382,21 +11499,22 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo if trace_singles then logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement)) end - current.char=replacement + resetinjection(current) + setfield(current,"char",replacement) end end return head,start,true elseif current==stop then break else - current=current.next + current=getnext(current) end end return head,start,false end chainmores.gsub_single=chainprocs.gsub_single function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local replacements=lookuphash[lookupname] @@ -11425,8 +11543,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext local subtables=currentlookup.subtables local value=featurevalue==true and tfmdata.shared.features[kind] or featurevalue while current do - if current.id==glyph_code then - local currentchar=current.char + if getid(current)==glyph_code then + local currentchar=getchar(current) local lookupname=subtables[1] local alternatives=lookuphash[lookupname] if not alternatives then @@ -11441,7 +11559,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext if trace_alternatives then logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) end - start.char=choice + resetinjection(start) + setfield(start,"char",choice) else if trace_alternatives then logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) @@ -11455,14 +11574,14 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext elseif current==stop then break else - current=current.next + current=getnext(current) end end return head,start,false end chainmores.gsub_alternate=chainprocs.gsub_alternate function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local ligatures=lookuphash[lookupname] @@ -11477,20 +11596,20 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) end else - local s=start.next + local s=getnext(start) local discfound=false local last=stop local nofreplacements=0 local skipmark=currentlookup.flags[1] while s do - local id=s.id + local id=getid(s) if id==disc_code then - s=s.next + s=getnext(s) discfound=true else - local schar=s.char + local schar=getchar(s) if skipmark and marks[schar] then - s=s.next + s=getnext(s) else local lg=ligatures[schar] if lg then @@ -11498,7 +11617,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if s==stop then break else - s=s.next + s=getnext(s) end else break @@ -11515,7 +11634,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2)) else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2)) + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop)),gref(l2)) end end head,start=toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) @@ -11524,7 +11643,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char)) + logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop))) end end end @@ -11533,7 +11652,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end chainmores.gsub_ligature=chainprocs.gsub_ligature function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -11542,14 +11661,14 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext markanchors=markanchors[markchar] end if markanchors then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -11570,7 +11689,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext if al[anchor] then local ma=markanchors[anchor] if ma then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -11596,7 +11715,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext return head,start,false end function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -11605,14 +11724,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon markanchors=markanchors[markchar] end if markanchors then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -11624,7 +11743,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon end end end - local index=start[a_ligacomp] + local index=getligaindex(start) local baseanchors=descriptions[basechar].anchors if baseanchors then local baseanchors=baseanchors['baselig'] @@ -11636,7 +11755,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon if ma then ba=ba[index] if ba then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) @@ -11663,67 +11782,67 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon return head,start,false end function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then - local subtables=currentlookup.subtables - local lookupname=subtables[1] - local markanchors=lookuphash[lookupname] - if markanchors then - markanchors=markanchors[markchar] - end - if markanchors then - local base=start.prev - local slc=start[a_ligacomp] - if slc then - while base do - local blc=base[a_ligacomp] - if blc and blc~=slc then - base=base.prev - else - break - end + local subtables=currentlookup.subtables + local lookupname=subtables[1] + local markanchors=lookuphash[lookupname] + if markanchors then + markanchors=markanchors[markchar] + end + if markanchors then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break end end - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char - local baseanchors=descriptions[basechar].anchors + end + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) + local baseanchors=descriptions[basechar].anchors + if baseanchors then + baseanchors=baseanchors['basemark'] if baseanchors then - baseanchors=baseanchors['basemark'] - if baseanchors then - local al=anchorlookups[lookupname] - for anchor,ba in next,baseanchors do - if al[anchor] then - local ma=markanchors[anchor] - if ma then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", - cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true + local al=anchorlookups[lookupname] + for anchor,ba in next,baseanchors do + if al[anchor] then + local ma=markanchors[anchor] + if ma then + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", + cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end + return head,start,true end end - if trace_bugs then - logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) - end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) end end - elseif trace_bugs then - logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) end elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end elseif trace_bugs then logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) end return head,start,false end function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local alreadydone=cursonce and start[a_cursbase] + local alreadydone=cursonce and getprop(start,a_cursbase) if not alreadydone then - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local exitanchors=lookuphash[lookupname] @@ -11737,11 +11856,11 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=start.next - while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do - local nextchar=nxt.char + local nxt=getnext(start) + while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do + local nextchar=getchar(nxt) if marks[nextchar] then - nxt=nxt.next + nxt=getnext(nxt) else local entryanchors=descriptions[nextchar] if entryanchors then @@ -11775,7 +11894,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) end return head,start,false end @@ -11783,7 +11902,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,false end function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -11800,9 +11919,9 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo end chainmores.gpos_single=chainprocs.gpos_single function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local snext=start.next + local snext=getnext(start) if snext then - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -11812,26 +11931,26 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local lookuptype=lookuptypes[lookupname] local prev,done=start,false local factor=tfmdata.parameters.factor - while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do - local nextchar=snext.char + while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do + local nextchar=getchar(snext) local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=snext.next + snext=getnext(snext) else if not krn then elseif type(krn)=="table" then if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -11843,7 +11962,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look if a and a~=0 then local k=setkern(snext,factor,rlmode,a) if trace_kerns then - logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) end end if b and b~=0 then @@ -11854,7 +11973,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) end done=true end @@ -11875,6 +11994,10 @@ local function show_skip(kind,chainname,char,ck,class) logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(kind,chainname),gref(char),class,ck[1],ck[2]) end end +local quit_on_no_replacement=true +directives.register("otf.chain.quitonnoreplacement",function(value) + quit_on_no_replacement=value +end) local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash) local flags=sequence.flags local done=false @@ -11892,7 +12015,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq local seq=ck[3] local s=#seq if s==1 then - match=current.id==glyph_code and current.font==currentfont and current.subtype<256 and seq[1][current.char] + match=getid(current)==glyph_code and getfont(current)==currentfont and getsubtype(current)<256 and seq[1][getchar(current)] else local f,l=ck[4],ck[5] if f==1 and f==l then @@ -11900,13 +12023,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if f==l then else local n=f+1 - last=last.next + last=getnext(last) while n<=l do if last then - local id=last.id + local id=getid(last) if id==glyph_code then - if last.font==currentfont and last.subtype<256 then - local char=last.char + if getfont(last)==currentfont and getsubtype(last)<256 then + local char=getchar(last) local ccd=descriptions[char] if ccd then local class=ccd.class @@ -11915,10 +12038,10 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if trace_skips then show_skip(kind,chainname,char,ck,class) end - last=last.next + last=getnext(last) elseif seq[n][char] then if n<l then - last=last.next + last=getnext(last) end n=n+1 else @@ -11934,7 +12057,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq break end elseif id==disc_code then - last=last.next + last=getnext(last) else match=false break @@ -11947,15 +12070,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if match and f>1 then - local prev=start.prev + local prev=getprev(start) if prev then local n=f-1 while n>=1 do if prev then - local id=prev.id + local id=getid(prev) if id==glyph_code then - if prev.font==currentfont and prev.subtype<256 then - local char=prev.char + if getfont(prev)==currentfont and getsubtype(prev)<256 then + local char=getchar(prev) local ccd=descriptions[char] if ccd then local class=ccd.class @@ -11985,7 +12108,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - prev=prev.prev + prev=getprev(prev) elseif seq[n][32] then n=n -1 else @@ -12005,15 +12128,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if match and s>l then - local current=last and last.next + local current=last and getnext(last) if current then local n=l+1 while n<=s do if current then - local id=current.id + local id=getid(current) if id==glyph_code then - if current.font==currentfont and current.subtype<256 then - local char=current.char + if getfont(current)==currentfont and getsubtype(current)<256 then + local char=getchar(current) local ccd=descriptions[char] if ccd then local class=ccd.class @@ -12043,7 +12166,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - current=current.next + current=getnext(current) elseif seq[n][32] then n=n+1 else @@ -12066,7 +12189,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if match then if trace_contexts then local rule,lookuptype,f,l=ck[1],ck[2],ck[4],ck[5] - local char=start.char + local char=getchar(start) if ck[9] then logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a, %a => %a", cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10]) @@ -12100,12 +12223,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq while true do if skipped then while true do - local char=start.char + local char=getchar(start) local ccd=descriptions[char] if ccd then local class=ccd.class if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then - start=start.next + start=getnext(start) else break end @@ -12137,7 +12260,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if i>nofchainlookups then break elseif start then - start=start.next + start=getnext(start) else end end @@ -12147,7 +12270,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if replacements then head,start,done=chainprocs.reversesub(head,start,last,kind,chainname,ck,lookuphash,replacements) else - done=true + done=quit_on_no_replacement if trace_contexts then logprocess("%s: skipping match",cref(kind,chainname)) end @@ -12218,7 +12341,7 @@ local function initialize(sequence,script,language,enabled) if features then local order=sequence.order if order then - for i=1,#order do + for i=1,#order do local kind=order[i] local valid=enabled[kind] if valid then @@ -12270,6 +12393,7 @@ local function featuresprocessor(head,font,attr) if not lookuphash then return head,false end + head=tonut(head) if trace_steps then checkstep(head) end @@ -12303,10 +12427,10 @@ local function featuresprocessor(head,font,attr) local handler=handlers[typ] local start=find_node_tail(head) while start do - local id=start.id + local id=getid(start) if id==glyph_code then - if start.font==font and start.subtype<256 then - local a=start[0] + if getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then a=a==attr else @@ -12317,7 +12441,7 @@ local function featuresprocessor(head,font,attr) local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then head,start,success=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) if success then @@ -12328,15 +12452,15 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start=start.prev end + if start then start=getprev(start) end else - start=start.prev + start=getprev(start) end else - start=start.prev + start=getprev(start) end else - start=start.prev + start=getprev(start) end end else @@ -12354,16 +12478,16 @@ local function featuresprocessor(head,font,attr) local head=start local done=false while start do - local id=start.id - if id==glyph_code and start.font==font and start.subtype<256 then - local a=start[0] + local id=getid(start) + if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then - a=(a==attr) and (not attribute or start[a_state]==attribute) + a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) else - a=not attribute or start[a_state]==attribute + a=not attribute or getprop(start,a_state)==attribute end if a then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -12371,12 +12495,12 @@ local function featuresprocessor(head,font,attr) done=true end end - if start then start=start.next end + if start then start=getnext(start) end else - start=start.next + start=getnext(start) end else - start=start.next + start=getnext(start) end end if done then @@ -12385,18 +12509,18 @@ local function featuresprocessor(head,font,attr) end end local function kerndisc(disc) - local prev=disc.prev - local next=disc.next + local prev=getprev(disc) + local next=getnext(disc) if prev and next then - prev.next=next - local a=prev[0] + setfield(prev,"next",next) + local a=getattr(prev,0) if a then - a=(a==attr) and (not attribute or prev[a_state]==attribute) + a=(a==attr) and (not attribute or getprop(prev,a_state)==attribute) else - a=not attribute or prev[a_state]==attribute + a=not attribute or getprop(prev,a_state)==attribute end if a then - local lookupmatch=lookupcache[prev.char] + local lookupmatch=lookupcache[getchar(prev)] if lookupmatch then local h,d,ok=handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) if ok then @@ -12405,22 +12529,22 @@ local function featuresprocessor(head,font,attr) end end end - prev.next=disc + setfield(prev,"next",disc) end return next end while start do - local id=start.id + local id=getid(start) if id==glyph_code then - if start.font==font and start.subtype<256 then - local a=start[0] + if getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then - a=(a==attr) and (not attribute or start[a_state]==attribute) + a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) else - a=not attribute or start[a_state]==attribute + a=not attribute or getprop(start,a_state)==attribute end if a then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -12428,38 +12552,38 @@ local function featuresprocessor(head,font,attr) success=true end end - if start then start=start.next end + if start then start=getnext(start) end else - start=start.next + start=getnext(start) end else - start=start.next + start=getnext(start) end elseif id==disc_code then - if start.subtype==discretionary_code then - local pre=start.pre + if getsubtype(start)==discretionary_code then + local pre=getfield(start,"pre") if pre then local new=subrun(pre) - if new then start.pre=new end + if new then setfield(start,"pre",new) end end - local post=start.post + local post=getfield(start,"post") if post then local new=subrun(post) - if new then start.post=new end + if new then setfield(start,"post",new) end end - local replace=start.replace + local replace=getfield(start,"replace") if replace then local new=subrun(replace) - if new then start.replace=new end + if new then setfield(start,"replace",new) end end elseif typ=="gpos_single" or typ=="gpos_pair" then kerndisc(start) end - start=start.next + start=getnext(start) elseif id==whatsit_code then - local subtype=start.subtype + local subtype=getsubtype(start) if subtype==dir_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -12478,7 +12602,7 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -12491,11 +12615,11 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=start.next + start=getnext(start) elseif id==math_code then - start=end_of_math(start).next + start=getnext(end_of_math(start)) else - start=start.next + start=getnext(start) end end end @@ -12504,20 +12628,20 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then local head=start local done=false while start do - local id=start.id - if id==glyph_code and start.id==font and start.subtype<256 then - local a=start[0] + local id=getid(start) + if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then - a=(a==attr) and (not attribute or start[a_state]==attribute) + a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) else - a=not attribute or start[a_state]==attribute + a=not attribute or getprop(start,a_state)==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -12532,12 +12656,12 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_missing_cache(typ,lookupname) end end - if start then start=start.next end + if start then start=getnext(start) end else - start=start.next + start=getnext(start) end else - start=start.next + start=getnext(start) end end if done then @@ -12546,22 +12670,22 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then end end local function kerndisc(disc) - local prev=disc.prev - local next=disc.next + local prev=getprev(disc) + local next=getnext(disc) if prev and next then - prev.next=next - local a=prev[0] + setfield(prev,"next",next) + local a=getattr(prev,0) if a then - a=(a==attr) and (not attribute or prev[a_state]==attribute) + a=(a==attr) and (not attribute or getprop(prev,a_state)==attribute) else - a=not attribute or prev[a_state]==attribute + a=not attribute or getprop(prev,a_state)==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[prev.char] + local lookupmatch=lookupcache[getchar(prev)] if lookupmatch then local h,d,ok=handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) if ok then @@ -12574,26 +12698,26 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then end end end - prev.next=disc + setfield(prev,"next",disc) end return next end while start do - local id=start.id + local id=getid(start) if id==glyph_code then - if start.font==font and start.subtype<256 then - local a=start[0] + if getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then - a=(a==attr) and (not attribute or start[a_state]==attribute) + a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) else - a=not attribute or start[a_state]==attribute + a=not attribute or getprop(start,a_state)==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -12608,38 +12732,38 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_missing_cache(typ,lookupname) end end - if start then start=start.next end + if start then start=getnext(start) end else - start=start.next + start=getnext(start) end else - start=start.next + start=getnext(start) end elseif id==disc_code then - if start.subtype==discretionary_code then - local pre=start.pre + if getsubtype(start)==discretionary_code then + local pre=getfield(start,"pre") if pre then local new=subrun(pre) - if new then start.pre=new end + if new then setfield(start,"pre",new) end end - local post=start.post + local post=getfield(start,"post") if post then local new=subrun(post) - if new then start.post=new end + if new then setfield(start,"post",new) end end - local replace=start.replace + local replace=getfield(start,"replace") if replace then local new=subrun(replace) - if new then start.replace=new end + if new then setfield(start,"replace",new) end end elseif typ=="gpos_single" or typ=="gpos_pair" then kerndisc(start) end - start=start.next + start=getnext(start) elseif id==whatsit_code then - local subtype=start.subtype + local subtype=getsubtype(start) if subtype==dir_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -12658,7 +12782,7 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -12671,11 +12795,11 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=start.next + start=getnext(start) elseif id==math_code then - start=end_of_math(start).next + start=getnext(end_of_math(start)) else - start=start.next + start=getnext(start) end end end @@ -12687,6 +12811,7 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then registerstep(head) end end + head=tonode(head) return head,done end local function generic(lookupdata,lookupname,unicode,lookuphash) @@ -14435,13 +14560,20 @@ local fonts=fonts local nodes=nodes local traverse_id=node.traverse_id local glyph_code=nodes.nodecodes.glyph +local ligaturing=node.ligaturing +local kerning=node.kerning +function node.ligaturing() texio.write_nl("warning: node.ligaturing is already applied") end +function node.kerning () texio.write_nl("warning: node.kerning is already applied") end function nodes.handlers.characters(head) local fontdata=fonts.hashes.identifiers if fontdata then - local usedfonts,done,prevfont={},false,nil + local usedfonts,basefonts,prevfont,basefont={},{},nil,nil for n in traverse_id(glyph_code,head) do local font=n.font if font~=prevfont then + if basefont then + basefont[2]=n.prev + end prevfont=font local used=usedfonts[font] if not used then @@ -14452,18 +14584,32 @@ function nodes.handlers.characters(head) local processors=shared.processes if processors and #processors>0 then usedfonts[font]=processors - done=true + else + basefont={ n,nil } + basefonts[#basefonts+1]=basefont end end end end end end - if done then + if next(usedfonts) then for font,processors in next,usedfonts do for i=1,#processors do - local h,d=processors[i](head,font,0) - head,done=h or head,done or d + head=processors[i](head,font,0) or head + end + end + end + if #basefonts>0 then + for i=1,#basefonts do + local range=basefonts[i] + local start,stop=range[1],range[2] + if stop then + ligaturing(start,stop) + kerning(start,stop) + else + ligaturing(start) + kerning(start) end end end @@ -14476,8 +14622,6 @@ function nodes.simple_font_handler(head) head=nodes.handlers.characters(head) nodes.injections.handler(head) nodes.handlers.protectglyphs(head) - head=node.ligaturing(head) - head=node.kerning(head) return head end diff --git a/tex/generic/context/luatex/luatex-fonts-ota.lua b/tex/generic/context/luatex/luatex-fonts-ota.lua new file mode 100644 index 000000000..f083fe09e --- /dev/null +++ b/tex/generic/context/luatex/luatex-fonts-ota.lua @@ -0,0 +1,459 @@ +if not modules then modules = { } end modules ['font-otx'] = { + version = 1.001, + comment = "companion to font-otf.lua (analysing)", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type = type + +if not trackers then trackers = { register = function() end } end + +----- trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end) + +local fonts, nodes, node = fonts, nodes, node + +local allocate = utilities.storage.allocate + +local otf = fonts.handlers.otf + +local analyzers = fonts.analyzers +local initializers = allocate() +local methods = allocate() + +analyzers.initializers = initializers +analyzers.methods = methods +analyzers.useunicodemarks = false + +local a_state = attributes.private('state') + +local nuts = nodes.nuts +local tonut = nuts.tonut + +local getfield = nuts.getfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getprop = nuts.getprop +local setprop = nuts.setprop +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar + +local traverse_id = nuts.traverse_id +local traverse_node_list = nuts.traverse +local end_of_math = nuts.end_of_math + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local math_code = nodecodes.math + +local fontdata = fonts.hashes.identifiers +local categories = characters and characters.categories or { } -- sorry, only in context + +local otffeatures = fonts.constructors.newfeatures("otf") +local registerotffeature = otffeatures.register + +--[[ldx-- +<p>Analyzers run per script and/or language and are needed in order to +process features right.</p> +--ldx]]-- + +-- never use these numbers directly + +local s_init = 1 local s_rphf = 7 +local s_medi = 2 local s_half = 8 +local s_fina = 3 local s_pref = 9 +local s_isol = 4 local s_blwf = 10 +local s_mark = 5 local s_pstf = 11 +local s_rest = 6 + +local states = { + init = s_init, + medi = s_medi, + fina = s_fina, + isol = s_isol, + mark = s_mark, + rest = s_rest, + rphf = s_rphf, + half = s_half, + pref = s_pref, + blwf = s_blwf, + pstf = s_pstf, +} + +local features = { + init = s_init, + medi = s_medi, + fina = s_fina, + isol = s_isol, + -- mark = s_mark, + -- rest = s_rest, + rphf = s_rphf, + half = s_half, + pref = s_pref, + blwf = s_blwf, + pstf = s_pstf, +} + +analyzers.states = states +analyzers.features = features + +-- todo: analyzers per script/lang, cross font, so we need an font id hash -> script +-- e.g. latin -> hyphenate, arab -> 1/2/3 analyze -- its own namespace + +function analyzers.setstate(head,font) + local useunicodemarks = analyzers.useunicodemarks + local tfmdata = fontdata[font] + local descriptions = tfmdata.descriptions + local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean + current = tonut(current) + while current do + local id = getid(current) + if id == glyph_code and getfont(current) == font then + done = true + local char = getchar(current) + local d = descriptions[char] + if d then + if d.class == "mark" or (useunicodemarks and categories[char] == "mn") then + done = true + setprop(current,a_state,s_mark) + elseif n == 0 then + first, last, n = current, current, 1 + setprop(current,a_state,s_init) + else + last, n = current, n+1 + setprop(current,a_state,s_medi) + end + else -- finish + if first and first == last then + setprop(last,a_state,s_isol) + elseif last then + setprop(last,a_state,s_fina) + end + first, last, n = nil, nil, 0 + end + elseif id == disc_code then + -- always in the middle + setprop(current,a_state,s_medi) + last = current + else -- finish + if first and first == last then + setprop(last,a_state,s_isol) + elseif last then + setprop(last,a_state,s_fina) + end + first, last, n = nil, nil, 0 + if id == math_code then + current = end_of_math(current) + end + end + current = getnext(current) + end + if first and first == last then + setprop(last,a_state,s_isol) + elseif last then + setprop(last,a_state,s_fina) + end + return head, done +end + +-- in the future we will use language/script attributes instead of the +-- font related value, but then we also need dynamic features which is +-- somewhat slower; and .. we need a chain of them + +local function analyzeinitializer(tfmdata,value) -- attr + local script, language = otf.scriptandlanguage(tfmdata) -- attr + local action = initializers[script] + if not action then + -- skip + elseif type(action) == "function" then + return action(tfmdata,value) + else + local action = action[language] + if action then + return action(tfmdata,value) + end + end +end + +local function analyzeprocessor(head,font,attr) + local tfmdata = fontdata[font] + local script, language = otf.scriptandlanguage(tfmdata,attr) + local action = methods[script] + if not action then + -- skip + elseif type(action) == "function" then + return action(head,font,attr) + else + action = action[language] + if action then + return action(head,font,attr) + end + end + return head, false +end + +registerotffeature { + name = "analyze", + description = "analysis of character classes", + default = true, + initializers = { + node = analyzeinitializer, + }, + processors = { + position = 1, + node = analyzeprocessor, + } +} + +-- latin + +methods.latn = analyzers.setstate + +-- This info eventually can go into char-def and we will have a state +-- table for generic then (unicode recognized all states but in practice +-- only has only +-- +-- isolated : isol +-- final : isol_fina +-- medial : isol_fina_medi_init +-- +-- so in practice, without analyzer it's rather useless info which is +-- why having it in char-def makes only sense for special purposes (like) +-- like tracing cq. visualizing. + +local tatweel = 0x0640 +local zwnj = 0x200C +local zwj = 0x200D + +local isolated = { -- isol + [0x0600] = true, [0x0601] = true, [0x0602] = true, [0x0603] = true, + [0x0604] = true, + [0x0608] = true, [0x060B] = true, [0x0621] = true, [0x0674] = true, + [0x06DD] = true, + -- mandaic + [0x0856] = true, [0x0858] = true, [0x0857] = true, + -- n'ko + [0x07FA] = true, + -- also here: + [zwnj] = true, + -- 7 + [0x08AD] = true, +} + +local final = { -- isol_fina + [0x0622] = true, [0x0623] = true, [0x0624] = true, [0x0625] = true, + [0x0627] = true, [0x0629] = true, [0x062F] = true, [0x0630] = true, + [0x0631] = true, [0x0632] = true, [0x0648] = true, [0x0671] = true, + [0x0672] = true, [0x0673] = true, [0x0675] = true, [0x0676] = true, + [0x0677] = true, [0x0688] = true, [0x0689] = true, [0x068A] = true, + [0x068B] = true, [0x068C] = true, [0x068D] = true, [0x068E] = true, + [0x068F] = true, [0x0690] = true, [0x0691] = true, [0x0692] = true, + [0x0693] = true, [0x0694] = true, [0x0695] = true, [0x0696] = true, + [0x0697] = true, [0x0698] = true, [0x0699] = true, [0x06C0] = true, + [0x06C3] = true, [0x06C4] = true, [0x06C5] = true, [0x06C6] = true, + [0x06C7] = true, [0x06C8] = true, [0x06C9] = true, [0x06CA] = true, + [0x06CB] = true, [0x06CD] = true, [0x06CF] = true, [0x06D2] = true, + [0x06D3] = true, [0x06D5] = true, [0x06EE] = true, [0x06EF] = true, + [0x0759] = true, [0x075A] = true, [0x075B] = true, [0x076B] = true, + [0x076C] = true, [0x0771] = true, [0x0773] = true, [0x0774] = true, + [0x0778] = true, [0x0779] = true, + [0x08AA] = true, [0x08AB] = true, [0x08AC] = true, + [0xFEF5] = true, [0xFEF7] = true, [0xFEF9] = true, [0xFEFB] = true, + -- syriac + [0x0710] = true, [0x0715] = true, [0x0716] = true, [0x0717] = true, + [0x0718] = true, [0x0719] = true, [0x0728] = true, [0x072A] = true, + [0x072C] = true, [0x071E] = true, + [0x072F] = true, [0x074D] = true, + -- mandaic + [0x0840] = true, [0x0849] = true, [0x0854] = true, [0x0846] = true, + [0x084F] = true, + -- 7 + [0x08AE] = true, [0x08B1] = true, [0x08B2] = true, +} + +local medial = { -- isol_fina_medi_init + [0x0626] = true, [0x0628] = true, [0x062A] = true, [0x062B] = true, + [0x062C] = true, [0x062D] = true, [0x062E] = true, [0x0633] = true, + [0x0634] = true, [0x0635] = true, [0x0636] = true, [0x0637] = true, + [0x0638] = true, [0x0639] = true, [0x063A] = true, [0x063B] = true, + [0x063C] = true, [0x063D] = true, [0x063E] = true, [0x063F] = true, + [0x0641] = true, [0x0642] = true, [0x0643] = true, + [0x0644] = true, [0x0645] = true, [0x0646] = true, [0x0647] = true, + [0x0649] = true, [0x064A] = true, [0x066E] = true, [0x066F] = true, + [0x0678] = true, [0x0679] = true, [0x067A] = true, [0x067B] = true, + [0x067C] = true, [0x067D] = true, [0x067E] = true, [0x067F] = true, + [0x0680] = true, [0x0681] = true, [0x0682] = true, [0x0683] = true, + [0x0684] = true, [0x0685] = true, [0x0686] = true, [0x0687] = true, + [0x069A] = true, [0x069B] = true, [0x069C] = true, [0x069D] = true, + [0x069E] = true, [0x069F] = true, [0x06A0] = true, [0x06A1] = true, + [0x06A2] = true, [0x06A3] = true, [0x06A4] = true, [0x06A5] = true, + [0x06A6] = true, [0x06A7] = true, [0x06A8] = true, [0x06A9] = true, + [0x06AA] = true, [0x06AB] = true, [0x06AC] = true, [0x06AD] = true, + [0x06AE] = true, [0x06AF] = true, [0x06B0] = true, [0x06B1] = true, + [0x06B2] = true, [0x06B3] = true, [0x06B4] = true, [0x06B5] = true, + [0x06B6] = true, [0x06B7] = true, [0x06B8] = true, [0x06B9] = true, + [0x06BA] = true, [0x06BB] = true, [0x06BC] = true, [0x06BD] = true, + [0x06BE] = true, [0x06BF] = true, [0x06C1] = true, [0x06C2] = true, + [0x06CC] = true, [0x06CE] = true, [0x06D0] = true, [0x06D1] = true, + [0x06FA] = true, [0x06FB] = true, [0x06FC] = true, [0x06FF] = true, + [0x0750] = true, [0x0751] = true, [0x0752] = true, [0x0753] = true, + [0x0754] = true, [0x0755] = true, [0x0756] = true, [0x0757] = true, + [0x0758] = true, [0x075C] = true, [0x075D] = true, [0x075E] = true, + [0x075F] = true, [0x0760] = true, [0x0761] = true, [0x0762] = true, + [0x0763] = true, [0x0764] = true, [0x0765] = true, [0x0766] = true, + [0x0767] = true, [0x0768] = true, [0x0769] = true, [0x076A] = true, + [0x076D] = true, [0x076E] = true, [0x076F] = true, [0x0770] = true, + [0x0772] = true, [0x0775] = true, [0x0776] = true, [0x0777] = true, + [0x077A] = true, [0x077B] = true, [0x077C] = true, [0x077D] = true, + [0x077E] = true, [0x077F] = true, + [0x08A0] = true, [0x08A2] = true, [0x08A4] = true, [0x08A5] = true, + [0x08A6] = true, [0x0620] = true, [0x08A8] = true, [0x08A9] = true, + [0x08A7] = true, [0x08A3] = true, + -- syriac + [0x0712] = true, [0x0713] = true, [0x0714] = true, [0x071A] = true, + [0x071B] = true, [0x071C] = true, [0x071D] = true, [0x071F] = true, + [0x0720] = true, [0x0721] = true, [0x0722] = true, [0x0723] = true, + [0x0724] = true, [0x0725] = true, [0x0726] = true, [0x0727] = true, + [0x0729] = true, [0x072B] = true, [0x072D] = true, [0x072E] = true, + [0x074E] = true, [0x074F] = true, + -- mandaic + [0x0841] = true, [0x0842] = true, [0x0843] = true, [0x0844] = true, + [0x0845] = true, [0x0847] = true, [0x0848] = true, [0x0855] = true, + [0x0851] = true, [0x084E] = true, [0x084D] = true, [0x084A] = true, + [0x084B] = true, [0x084C] = true, [0x0850] = true, [0x0852] = true, + [0x0853] = true, + -- n'ko + [0x07D7] = true, [0x07E8] = true, [0x07D9] = true, [0x07EA] = true, + [0x07CA] = true, [0x07DB] = true, [0x07CC] = true, [0x07DD] = true, + [0x07CE] = true, [0x07DF] = true, [0x07D4] = true, [0x07E5] = true, + [0x07E9] = true, [0x07E7] = true, [0x07E3] = true, [0x07E2] = true, + [0x07E0] = true, [0x07E1] = true, [0x07DE] = true, [0x07DC] = true, + [0x07D1] = true, [0x07DA] = true, [0x07D8] = true, [0x07D6] = true, + [0x07D2] = true, [0x07D0] = true, [0x07CF] = true, [0x07CD] = true, + [0x07CB] = true, [0x07D3] = true, [0x07E4] = true, [0x07D5] = true, + [0x07E6] = true, + -- also here: + [tatweel]= true, [zwj] = true, + -- 7 + [0x08A1] = true, [0x08AF] = true, [0x08B0] = true, +} + +local arab_warned = { } + +-- todo: gref + +local function warning(current,what) + local char = getchar(current) + if not arab_warned[char] then + log.report("analyze","arab: character %C has no %a class",char,what) + arab_warned[char] = true + end +end + +-- potential optimization: local medial_final = table.merged(medial,final) + +local function finish(first,last) + if last then + if first == last then + local fc = getchar(first) + if medial[fc] or final[fc] then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + else + local lc = getchar(last) + if medial[lc] or final[lc] then + -- if laststate == 1 or laststate == 2 or laststate == 4 then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + end + first, last = nil, nil + elseif first then + -- first and last are either both set so we never com here + local fc = getchar(first) + if medial[fc] or final[fc] then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first = nil + end + return first, last +end + +function methods.arab(head,font,attr) + local useunicodemarks = analyzers.useunicodemarks + local tfmdata = fontdata[font] + local marks = tfmdata.resources.marks + local first, last, current, done = nil, nil, head, false + current = tonut(current) + while current do + local id = getid(current) + if id == glyph_code and getfont(current) == font and getsubtype(current)<256 and not getprop(current,a_state) then + done = true + local char = getchar(current) + if marks[char] or (useunicodemarks and categories[char] == "mn") then + setprop(current,a_state,s_mark) + elseif isolated[char] then -- can be zwj or zwnj too + first, last = finish(first,last) + setprop(current,a_state,s_isol) + first, last = nil, nil + elseif not first then + if medial[char] then + setprop(current,a_state,s_init) + first, last = first or current, current + elseif final[char] then + setprop(current,a_state,s_isol) + first, last = nil, nil + else -- no arab + first, last = finish(first,last) + end + elseif medial[char] then + first, last = first or current, current + setprop(current,a_state,s_medi) + elseif final[char] then + if getprop(last,a_state) ~= s_init then + -- tricky, we need to check what last may be ! + setprop(last,a_state,s_medi) + end + setprop(current,a_state,s_fina) + first, last = nil, nil + elseif char >= 0x0600 and char <= 0x06FF then -- needs checking + setprop(current,a_state,s_rest) + first, last = finish(first,last) + else -- no + first, last = finish(first,last) + end + else + if first or last then + first, last = finish(first,last) + end + if id == math_code then + current = end_of_math(current) + end + end + current = getnext(current) + end + if first or last then + finish(first,last) + end + return head, done +end + +methods.syrc = methods.arab +methods.mand = methods.arab +methods.nko = methods.arab + +directives.register("otf.analyze.useunicodemarks",function(v) + analyzers.useunicodemarks = v +end) diff --git a/tex/generic/context/luatex/luatex-fonts-otn.lua b/tex/generic/context/luatex/luatex-fonts-otn.lua index 831b23350..32dc820d3 100644 --- a/tex/generic/context/luatex/luatex-fonts-otn.lua +++ b/tex/generic/context/luatex/luatex-fonts-otn.lua @@ -6,8 +6,14 @@ if not modules then modules = { } end modules ['font-otn'] = { license = "see context related readme files", } +-- this is a context version which can contain experimental code, but when we +-- have serious patches we also need to change the other two font-otn files + -- preprocessors = { "nodes" } +-- anchor class : mark, mkmk, curs, mklg (todo) +-- anchor type : mark, basechar, baselig, basemark, centry, cexit, max (todo) + -- this is still somewhat preliminary and it will get better in due time; -- much functionality could only be implemented thanks to the husayni font -- of Idris Samawi Hamid to who we dedicate this module. @@ -171,12 +177,29 @@ registertracker("otf.injections","nodes.injections") registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") -local insert_node_after = node.insert_after -local delete_node = nodes.delete -local copy_node = node.copy -local find_node_tail = node.tail or node.slide -local flush_node_list = node.flush_list -local end_of_math = node.end_of_math +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfield = nuts.getfield +local setfield = nuts.setfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getattr = nuts.getattr +local setattr = nuts.setattr +local getprop = nuts.getprop +local setprop = nuts.setprop +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar + +local insert_node_after = nuts.insert_after +local delete_node = nuts.delete +local copy_node = nuts.copy +local find_node_tail = nuts.tail +local flush_node_list = nuts.flush_list +local end_of_math = nuts.end_of_math local setmetatableindex = table.setmetatableindex @@ -212,24 +235,18 @@ local privateattribute = attributes.private -- of only some. local a_state = privateattribute('state') -local a_markbase = privateattribute('markbase') -local a_markmark = privateattribute('markmark') -local a_markdone = privateattribute('markdone') -- assigned at the injection end -local a_cursbase = privateattribute('cursbase') -local a_curscurs = privateattribute('curscurs') -local a_cursdone = privateattribute('cursdone') -local a_kernpair = privateattribute('kernpair') -local a_ligacomp = privateattribute('ligacomp') -- assigned here (ideally it should be combined) +local a_cursbase = privateattribute('cursbase') -- to be checked, probably can go local injections = nodes.injections local setmark = injections.setmark local setcursive = injections.setcursive local setkern = injections.setkern local setpair = injections.setpair +local resetinjection = injections.reset +local setligaindex = injections.setligaindex +local getligaindex = injections.getligaindex -local markonce = true local cursonce = true -local kernonce = true local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers @@ -333,11 +350,11 @@ end -- and indices. local function copy_glyph(g) -- next and prev are untouched ! - local components = g.components + local components = getfield(g,"components") if components then - g.components = nil + setfield(g,"components",nil) local n = copy_node(g) - g.components = components + setfield(g,"components",components) return n else return copy_node(g) @@ -347,28 +364,29 @@ end -- start is a mark and we need to keep that one local function markstoligature(kind,lookupname,head,start,stop,char) - if start == stop and start.char == char then + if start == stop and getchar(start) == char then return head, start else - local prev = start.prev - local next = stop.next - start.prev = nil - stop.next = nil + local prev = getprev(start) + local next = getnext(stop) + setfield(start,"prev",nil) + setfield(stop,"next",nil) local base = copy_glyph(start) if head == start then head = base end - base.char = char - base.subtype = ligature_code - base.components = start + resetinjection(base) + setfield(base,"char",char) + setfield(base,"subtype",ligature_code) + setfield(base,"components",start) if prev then - prev.next = base + setfield(prev,"next",base) end if next then - next.prev = base + setfield(next,"prev",base) end - base.next = next - base.prev = prev + setfield(base,"next",next) + setfield(base,"prev",prev) return head, base end end @@ -381,17 +399,17 @@ end -- third component. local function getcomponentindex(start) - if start.id ~= glyph_code then + if getid(start) ~= glyph_code then return 0 - elseif start.subtype == ligature_code then + elseif getsubtype(start) == ligature_code then local i = 0 - local components = start.components + local components = getfield(start,"components") while components do i = i + getcomponentindex(components) - components = components.next + components = getnext(components) end return i - elseif not marks[start.char] then + elseif not marks[getchar(start)] then return 1 else return 0 @@ -401,29 +419,31 @@ end -- eventually we will do positioning in an other way (needs addional w/h/d fields) local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) -- brr head - if start == stop and start.char == char then - start.char = char + if start == stop and getchar(start) == char then + resetinjection(start) + setfield(start,"char",char) return head, start end - local prev = start.prev - local next = stop.next - start.prev = nil - stop.next = nil + local prev = getprev(start) + local next = getnext(stop) + setfield(start,"prev",nil) + setfield(stop,"next",nil) local base = copy_glyph(start) if start == head then head = base end - base.char = char - base.subtype = ligature_code - base.components = start -- start can have components + resetinjection(base) + setfield(base,"char",char) + setfield(base,"subtype",ligature_code) + setfield(base,"components",start) -- start can have components if prev then - prev.next = base + setfield(prev,"next",base) end if next then - next.prev = base + setfield(next,"prev",base) end - base.next = next - base.prev = prev + setfield(base,"next",next) + setfield(base,"prev",prev) if not discfound then local deletemarks = markflag ~= "mark" local components = start @@ -433,35 +453,35 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun local current = base -- first we loop over the glyphs in start .. stop while start do - local char = start.char + local char = getchar(start) if not marks[char] then baseindex = baseindex + componentindex componentindex = getcomponentindex(start) elseif not deletemarks then -- quite fishy - start[a_ligacomp] = baseindex + (start[a_ligacomp] or componentindex) + setligaindex(start,baseindex + getligaindex(start,componentindex)) if trace_marks then - logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getligaindex(start)) end head, current = insert_node_after(head,current,copy_node(start)) -- unlikely that mark has components elseif trace_marks then logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char)) end - start = start.next + start = getnext(start) end -- we can have one accent as part of a lookup and another following -- local start = components -- was wrong (component scanning was introduced when more complex ligs in devanagari was added) - local start = current.next - while start and start.id == glyph_code do - local char = start.char + local start = getnext(current) + while start and getid(start) == glyph_code do + local char = getchar(start) if marks[char] then - start[a_ligacomp] = baseindex + (start[a_ligacomp] or componentindex) + setligaindex(start,baseindex + getligaindex(start,componentindex)) if trace_marks then - logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getligaindex(start)) end else break end - start = start.next + start = getnext(start) end end return head, base @@ -469,9 +489,10 @@ end function handlers.gsub_single(head,start,kind,lookupname,replacement) if trace_singles then - logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement)) + logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement)) end - start.char = replacement + resetinjection(start) + setfield(start,"char",replacement) return head, start, true end @@ -498,7 +519,7 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives return false, trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end elseif value == 0 then - return start.char, trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + return getchar(start), trace_alternatives and formatters["invalid value %a, %s"](value,"no change") elseif value < 1 then return alternatives[1], trace_alternatives and formatters["invalid value %a, taking %a"](value,1) else @@ -510,30 +531,32 @@ end local function multiple_glyphs(head,start,multiple,ignoremarks) local nofmultiples = #multiple if nofmultiples > 0 then - start.char = multiple[1] + resetinjection(start) + setfield(start,"char",multiple[1]) if nofmultiples > 1 then - local sn = start.next + local sn = getnext(start) for k=2,nofmultiples do -- todo: use insert_node -- untested: -- --- while ignoremarks and marks[sn.char] then --- local sn = sn.next +-- while ignoremarks and marks[getchar(sn)] then +-- local sn = getnext(sn) -- end local n = copy_node(start) -- ignore components - n.char = multiple[k] - n.next = sn - n.prev = start + resetinjection(n) + setfield(n,"char",multiple[k]) + setfield(n,"next",sn) + setfield(n,"prev",start) if sn then - sn.prev = n + setfield(sn,"prev",n) end - start.next = n + setfield(start,"next",n) start = n end end return head, start, true else if trace_multiples then - logprocess("no multiple for %s",gref(start.char)) + logprocess("no multiple for %s",gref(getchar(start))) end return head, start, false end @@ -544,12 +567,13 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence local choice, comment = get_alternative_glyph(start,alternative,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment) end - start.char = choice + resetinjection(start) + setfield(start,"char",choice) else if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment) end end return head, start, true @@ -557,23 +581,23 @@ end function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence) if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple)) + logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(getchar(start)),gref(multiple)) end return multiple_glyphs(head,start,multiple,sequence.flags[1]) end function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) - local s, stop, discfound = start.next, nil, false - local startchar = start.char + local s, stop, discfound = getnext(start), nil, false + local startchar = getchar(start) if marks[startchar] then while s do - local id = s.id - if id == glyph_code and s.font == currentfont and s.subtype<256 then - local lg = ligature[s.char] + local id = getid(s) + if id == glyph_code and getfont(s) == currentfont and getsubtype(s)<256 then + local lg = ligature[getchar(s)] if lg then stop = s ligature = lg - s = s.next + s = getnext(s) else break end @@ -585,9 +609,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) local lig = ligature.ligature if lig then if trace_ligatures then - local stopchar = stop.char + local stopchar = getchar(stop) head, start = markstoligature(kind,lookupname,head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) else head, start = markstoligature(kind,lookupname,head,start,stop,lig) end @@ -599,18 +623,18 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) else local skipmark = sequence.flags[1] while s do - local id = s.id - if id == glyph_code and s.subtype<256 then - if s.font == currentfont then - local char = s.char + local id = getid(s) + if id == glyph_code and getsubtype(s)<256 then + if getfont(s) == currentfont then + local char = getchar(s) if skipmark and marks[char] then - s = s.next + s = getnext(s) else local lg = ligature[char] if lg then stop = s ligature = lg - s = s.next + s = getnext(s) else break end @@ -620,7 +644,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) end elseif id == disc_code then discfound = true - s = s.next + s = getnext(s) else break end @@ -629,21 +653,21 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) if lig then if stop then if trace_ligatures then - local stopchar = stop.char + local stopchar = getchar(stop) head, start = toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) else head, start = toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) end - return head, start, true else -- weird but happens (in some arabic font) - start.char = lig + resetinjection(start) + setfield(start,"char",lig) if trace_ligatures then logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig)) end - return head, start, true end + return head, start, true else -- weird but happens end @@ -657,16 +681,16 @@ we need to explicitly test for basechar, baselig and basemark entries.</p> --ldx]]-- function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence) - local markchar = start.char + local markchar = getchar(start) if marks[markchar] then - local base = start.prev -- [glyph] [start=mark] - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - local basechar = base.char + local base = getprev(start) -- [glyph] [start=mark] + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + local basechar = getchar(base) if marks[basechar] then while true do - base = base.prev - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - basechar = base.char + base = getprev(base) + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + basechar = getchar(base) if not marks[basechar] then break end @@ -690,7 +714,7 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence if al[anchor] then local ma = markanchors[anchor] if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -718,16 +742,16 @@ end function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence) -- check chainpos variant - local markchar = start.char + local markchar = getchar(start) if marks[markchar] then - local base = start.prev -- [glyph] [optional marks] [start=mark] - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - local basechar = base.char + local base = getprev(start) -- [glyph] [optional marks] [start=mark] + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + local basechar = getchar(base) if marks[basechar] then while true do - base = base.prev - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - basechar = base.char + base = getprev(base) + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + basechar = getchar(base) if not marks[basechar] then break end @@ -739,7 +763,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ end end end - local index = start[a_ligacomp] + local index = getligaindex(start) local baseanchors = descriptions[basechar] if baseanchors then baseanchors = baseanchors.anchors @@ -753,7 +777,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ if ma then ba = ba[index] if ba then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) -- index if trace_marks then logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) @@ -786,22 +810,22 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ end function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence) - local markchar = start.char + local markchar = getchar(start) if marks[markchar] then - local base = start.prev -- [glyph] [basemark] [start=mark] - local slc = start[a_ligacomp] + local base = getprev(start) -- [glyph] [basemark] [start=mark] + local slc = getligaindex(start) if slc then -- a rather messy loop ... needs checking with husayni while base do - local blc = base[a_ligacomp] + local blc = getligaindex(base) if blc and blc ~= slc then - base = base.prev + base = getprev(base) else break end end end - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then -- subtype test can go - local basechar = base.char + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then -- subtype test can go + local basechar = getchar(base) local baseanchors = descriptions[basechar] if baseanchors then baseanchors = baseanchors.anchors @@ -813,7 +837,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence if al[anchor] then local ma = markanchors[anchor] if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -841,21 +865,21 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence end function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) -- to be checked - local alreadydone = cursonce and start[a_cursbase] + local alreadydone = cursonce and getprop(start,a_cursbase) if not alreadydone then local done = false - local startchar = start.char + local startchar = getchar(start) if marks[startchar] then if trace_cursive then logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt = start.next - while not done and nxt and nxt.id == glyph_code and nxt.font == currentfont and nxt.subtype<256 do - local nextchar = nxt.char + local nxt = getnext(start) + while not done and nxt and getid(nxt) == glyph_code and getfont(nxt) == currentfont and getsubtype(nxt)<256 do + local nextchar = getchar(nxt) if marks[nextchar] then -- should not happen (maybe warning) - nxt = nxt.next + nxt = getnext(nxt) else local entryanchors = descriptions[nextchar] if entryanchors then @@ -890,14 +914,14 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) return head, start, done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) end return head, start, false end end function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) - local startchar = start.char + local startchar = getchar(start) local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) @@ -908,19 +932,19 @@ end function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) -- todo: kerns in disc nodes: pre, post, replace -> loop over disc too -- todo: kerns in components of ligatures - local snext = start.next + local snext = getnext(start) if not snext then return head, start, false else local prev, done = start, false local factor = tfmdata.parameters.factor local lookuptype = lookuptypes[lookupname] - while snext and snext.id == glyph_code and snext.font == currentfont and snext.subtype<256 do - local nextchar = snext.char + while snext and getid(snext) == glyph_code and getfont(snext) == currentfont and getsubtype(snext)<256 do + local nextchar = getchar(snext) local krn = kerns[nextchar] if not krn and marks[nextchar] then prev = snext - snext = snext.next + snext = getnext(snext) else if not krn then -- skip @@ -928,14 +952,14 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) if lookuptype == "pair" then -- probably not needed local a, b = krn[2], krn[3] if a and #a > 0 then - local startchar = start.char + local startchar = getchar(start) local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then - local startchar = start.char + local startchar = getchar(start) local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -947,7 +971,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) -- if a and a ~= 0 then -- local k = setkern(snext,factor,rlmode,a) -- if trace_kerns then - -- logprocess("%s: inserting first kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + -- logprocess("%s: inserting first kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) -- end -- end -- if b and b ~= 0 then @@ -958,7 +982,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) elseif krn ~= 0 then local k = setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) end done = true end @@ -1013,13 +1037,14 @@ end -- itself. It is meant mostly for dealing with Urdu. function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements) - local char = start.char + local char = getchar(start) local replacement = replacements[char] if replacement then if trace_singles then logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement)) end - start.char = replacement + resetinjection(start) + setfield(start,"char",replacement) return head, start, true else return head, start, false @@ -1048,9 +1073,9 @@ as less as needed but that would also make the code even more messy.</p> -- -- done -- elseif ignoremarks then -- repeat -- start x x m x x stop => start m --- local next = start.next --- if not marks[next.char] then --- local components = next.components +-- local next = getnext(start) +-- if not marks[getchar(next)] then +-- local components = getfield(next,"components") -- if components then -- probably not needed -- flush_node_list(components) -- end @@ -1060,8 +1085,8 @@ as less as needed but that would also make the code even more messy.</p> -- until next == stop -- else -- start x x x stop => start -- repeat --- local next = start.next --- local components = next.components +-- local next = getnext(start) +-- local components = getfield(next,"components") -- if components then -- probably not needed -- flush_node_list(components) -- end @@ -1085,8 +1110,8 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) end while current do - if current.id == glyph_code then - local currentchar = current.char + if getid(current) == glyph_code then + local currentchar = getchar(current) local lookupname = subtables[1] -- only 1 local replacement = lookuphash[lookupname] if not replacement then @@ -1103,14 +1128,15 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo if trace_singles then logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement)) end - current.char = replacement + resetinjection(current) + setfield(current,"char",replacement) end end return head, start, true elseif current == stop then break else - current = current.next + current = getnext(current) end end return head, start, false @@ -1125,7 +1151,7 @@ the match.</p> function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) -- local head, n = delete_till_stop(head,start,stop) - local startchar = start.char + local startchar = getchar(start) local subtables = currentlookup.subtables local lookupname = subtables[1] local replacements = lookuphash[lookupname] @@ -1168,8 +1194,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext local subtables = currentlookup.subtables local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue while current do - if current.id == glyph_code then -- is this check needed? - local currentchar = current.char + if getid(current) == glyph_code then -- is this check needed? + local currentchar = getchar(current) local lookupname = subtables[1] local alternatives = lookuphash[lookupname] if not alternatives then @@ -1184,7 +1210,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext if trace_alternatives then logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) end - start.char = choice + resetinjection(start) + setfield(start,"char",choice) else if trace_alternatives then logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) @@ -1198,7 +1225,7 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext elseif current == stop then break else - current = current.next + current = getnext(current) end end return head, start, false @@ -1213,7 +1240,7 @@ assume rather stupid ligatures (no complex disc nodes).</p> --ldx]]-- function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) - local startchar = start.char + local startchar = getchar(start) local subtables = currentlookup.subtables local lookupname = subtables[1] local ligatures = lookuphash[lookupname] @@ -1228,20 +1255,20 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) end else - local s = start.next + local s = getnext(start) local discfound = false local last = stop local nofreplacements = 0 local skipmark = currentlookup.flags[1] while s do - local id = s.id + local id = getid(s) if id == disc_code then - s = s.next + s = getnext(s) discfound = true else - local schar = s.char + local schar = getchar(s) if skipmark and marks[schar] then -- marks - s = s.next + s = getnext(s) else local lg = ligatures[schar] if lg then @@ -1249,7 +1276,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if s == stop then break else - s = s.next + s = getnext(s) end else break @@ -1266,7 +1293,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start == stop then logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2)) else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2)) + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop)),gref(l2)) end end head, start = toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) @@ -1275,7 +1302,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start == stop then logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char)) + logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop))) end end end @@ -1286,7 +1313,7 @@ end chainmores.gsub_ligature = chainprocs.gsub_ligature function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar = start.char + local markchar = getchar(start) if marks[markchar] then local subtables = currentlookup.subtables local lookupname = subtables[1] @@ -1295,14 +1322,14 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext markanchors = markanchors[markchar] end if markanchors then - local base = start.prev -- [glyph] [start=mark] - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - local basechar = base.char + local base = getprev(start) -- [glyph] [start=mark] + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + local basechar = getchar(base) if marks[basechar] then while true do - base = base.prev - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - basechar = base.char + base = getprev(base) + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + basechar = getchar(base) if not marks[basechar] then break end @@ -1323,7 +1350,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext if al[anchor] then local ma = markanchors[anchor] if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -1350,7 +1377,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext end function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar = start.char + local markchar = getchar(start) if marks[markchar] then local subtables = currentlookup.subtables local lookupname = subtables[1] @@ -1359,14 +1386,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon markanchors = markanchors[markchar] end if markanchors then - local base = start.prev -- [glyph] [optional marks] [start=mark] - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - local basechar = base.char + local base = getprev(start) -- [glyph] [optional marks] [start=mark] + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + local basechar = getchar(base) if marks[basechar] then while true do - base = base.prev - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then - basechar = base.char + base = getprev(base) + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then + basechar = getchar(base) if not marks[basechar] then break end @@ -1379,7 +1406,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon end end -- todo: like marks a ligatures hash - local index = start[a_ligacomp] + local index = getligaindex(start) local baseanchors = descriptions[basechar].anchors if baseanchors then local baseanchors = baseanchors['baselig'] @@ -1391,7 +1418,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon if ma then ba = ba[index] if ba then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) @@ -1419,64 +1446,59 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon end function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar = start.char + local markchar = getchar(start) if marks[markchar] then - -- local alreadydone = markonce and start[a_markmark] - -- if not alreadydone then - -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark - local subtables = currentlookup.subtables - local lookupname = subtables[1] - local markanchors = lookuphash[lookupname] - if markanchors then - markanchors = markanchors[markchar] - end - if markanchors then - local base = start.prev -- [glyph] [basemark] [start=mark] - local slc = start[a_ligacomp] - if slc then -- a rather messy loop ... needs checking with husayni - while base do - local blc = base[a_ligacomp] - if blc and blc ~= slc then - base = base.prev - else - break - end + -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = lookuphash[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = getprev(start) -- [glyph] [basemark] [start=mark] + local slc = getligaindex(start) + if slc then -- a rather messy loop ... needs checking with husayni + while base do + local blc = getligaindex(base) + if blc and blc ~= slc then + base = getprev(base) + else + break end end - if base and base.id == glyph_code and base.font == currentfont and base.subtype<256 then -- subtype test can go - local basechar = base.char - local baseanchors = descriptions[basechar].anchors + end + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then -- subtype test can go + local basechar = getchar(base) + local baseanchors = descriptions[basechar].anchors + if baseanchors then + baseanchors = baseanchors['basemark'] if baseanchors then - baseanchors = baseanchors['basemark'] - if baseanchors then - local al = anchorlookups[lookupname] - for anchor,ba in next, baseanchors do - if al[anchor] then - local ma = markanchors[anchor] - if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", - cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) - end - return head, start, true + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", + cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end + return head, start, true end end - if trace_bugs then - logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) - end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) end end - elseif trace_bugs then - logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) end elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) end - -- elseif trace_marks and trace_details then - -- logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone) - -- end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end elseif trace_bugs then logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) end @@ -1484,9 +1506,9 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext end function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local alreadydone = cursonce and start[a_cursbase] + local alreadydone = cursonce and getprop(start,a_cursbase) if not alreadydone then - local startchar = start.char + local startchar = getchar(start) local subtables = currentlookup.subtables local lookupname = subtables[1] local exitanchors = lookuphash[lookupname] @@ -1500,12 +1522,12 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt = start.next - while not done and nxt and nxt.id == glyph_code and nxt.font == currentfont and nxt.subtype<256 do - local nextchar = nxt.char + local nxt = getnext(start) + while not done and nxt and getid(nxt) == glyph_code and getfont(nxt) == currentfont and getsubtype(nxt)<256 do + local nextchar = getchar(nxt) if marks[nextchar] then -- should not happen (maybe warning) - nxt = nxt.next + nxt = getnext(nxt) else local entryanchors = descriptions[nextchar] if entryanchors then @@ -1540,7 +1562,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head, start, done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) end return head, start, false end @@ -1550,7 +1572,7 @@ end function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) -- untested .. needs checking for the new model - local startchar = start.char + local startchar = getchar(start) local subtables = currentlookup.subtables local lookupname = subtables[1] local kerns = lookuphash[lookupname] @@ -1571,9 +1593,9 @@ chainmores.gpos_single = chainprocs.gpos_single -- okay? -- when machines become faster i will make a shared function function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local snext = start.next + local snext = getnext(start) if snext then - local startchar = start.char + local startchar = getchar(start) local subtables = currentlookup.subtables local lookupname = subtables[1] local kerns = lookuphash[lookupname] @@ -1583,12 +1605,12 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local lookuptype = lookuptypes[lookupname] local prev, done = start, false local factor = tfmdata.parameters.factor - while snext and snext.id == glyph_code and snext.font == currentfont and snext.subtype<256 do - local nextchar = snext.char + while snext and getid(snext) == glyph_code and getfont(snext) == currentfont and getsubtype(snext)<256 do + local nextchar = getchar(snext) local krn = kerns[nextchar] if not krn and marks[nextchar] then prev = snext - snext = snext.next + snext = getnext(snext) else if not krn then -- skip @@ -1596,14 +1618,14 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look if lookuptype == "pair" then local a, b = krn[2], krn[3] if a and #a > 0 then - local startchar = start.char + local startchar = getchar(start) local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then - local startchar = start.char + local startchar = getchar(start) local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -1615,7 +1637,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look if a and a ~= 0 then local k = setkern(snext,factor,rlmode,a) if trace_kerns then - logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) end end if b and b ~= 0 then @@ -1626,7 +1648,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look elseif krn ~= 0 then local k = setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) end done = true end @@ -1658,6 +1680,12 @@ local function show_skip(kind,chainname,char,ck,class) end end +local quit_on_no_replacement = true + +directives.register("otf.chain.quitonnoreplacement",function(value) -- maybe per font + quit_on_no_replacement = value +end) + local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash) -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6] local flags = sequence.flags @@ -1678,7 +1706,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq -- f..l = mid string if s == 1 then -- never happens - match = current.id == glyph_code and current.font == currentfont and current.subtype<256 and seq[1][current.char] + match = getid(current) == glyph_code and getfont(current) == currentfont and getsubtype(current)<256 and seq[1][getchar(current)] else -- maybe we need a better space check (maybe check for glue or category or combination) -- we cannot optimize for n=2 because there can be disc nodes @@ -1693,13 +1721,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq -- match = true else local n = f + 1 - last = last.next + last = getnext(last) while n <= l do if last then - local id = last.id + local id = getid(last) if id == glyph_code then - if last.font == currentfont and last.subtype<256 then - local char = last.char + if getfont(last) == currentfont and getsubtype(last)<256 then + local char = getchar(last) local ccd = descriptions[char] if ccd then local class = ccd.class @@ -1708,10 +1736,10 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if trace_skips then show_skip(kind,chainname,char,ck,class) end - last = last.next + last = getnext(last) elseif seq[n][char] then if n < l then - last = last.next + last = getnext(last) end n = n + 1 else @@ -1727,7 +1755,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq break end elseif id == disc_code then - last = last.next + last = getnext(last) else match = false break @@ -1741,15 +1769,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end -- before if match and f > 1 then - local prev = start.prev + local prev = getprev(start) if prev then local n = f-1 while n >= 1 do if prev then - local id = prev.id + local id = getid(prev) if id == glyph_code then - if prev.font == currentfont and prev.subtype<256 then -- normal char - local char = prev.char + if getfont(prev) == currentfont and getsubtype(prev)<256 then -- normal char + local char = getchar(prev) local ccd = descriptions[char] if ccd then local class = ccd.class @@ -1780,7 +1808,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match = false break end - prev = prev.prev + prev = getprev(prev) elseif seq[n][32] then -- somewhat special, as zapfino can have many preceding spaces n = n -1 else @@ -1801,16 +1829,16 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end -- after if match and s > l then - local current = last and last.next + local current = last and getnext(last) if current then -- removed optimization for s-l == 1, we have to deal with marks anyway local n = l + 1 while n <= s do if current then - local id = current.id + local id = getid(current) if id == glyph_code then - if current.font == currentfont and current.subtype<256 then -- normal char - local char = current.char + if getfont(current) == currentfont and getsubtype(current)<256 then -- normal char + local char = getchar(current) local ccd = descriptions[char] if ccd then local class = ccd.class @@ -1841,7 +1869,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match = false break end - current = current.next + current = getnext(current) elseif seq[n][32] then n = n + 1 else @@ -1865,7 +1893,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq -- ck == currentcontext if trace_contexts then local rule, lookuptype, f, l = ck[1], ck[2], ck[4], ck[5] - local char = start.char + local char = getchar(start) if ck[9] then logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a, %a => %a", cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10]) @@ -1900,12 +1928,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq while true do if skipped then while true do - local char = start.char + local char = getchar(start) local ccd = descriptions[char] if ccd then local class = ccd.class if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then - start = start.next + start = getnext(start) else break end @@ -1941,7 +1969,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if i > nofchainlookups then break elseif start then - start = start.next + start = getnext(start) else -- weird end @@ -1952,7 +1980,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if replacements then head, start, done = chainprocs.reversesub(head,start,last,kind,chainname,ck,lookuphash,replacements) -- sequence else - done = true -- can be meant to be skipped + done = quit_on_no_replacement -- can be meant to be skipped / quite inconsistent in fonts if trace_contexts then logprocess("%s: skipping match",cref(kind,chainname)) end @@ -2043,7 +2071,7 @@ local function initialize(sequence,script,language,enabled) if features then local order = sequence.order if order then - for i=1,#order do + for i=1,#order do -- local kind = order[i] -- local valid = enabled[kind] if valid then @@ -2102,12 +2130,12 @@ end -- if ok then -- done = true -- end --- if start then start = start.next end +-- if start then start = getnext(start) end -- else --- start = start.next +-- start = getnext(start) -- end -- else --- start = start.next +-- start = getnext(start) -- end -- there will be a new direction parser (pre-parsed etc) @@ -2117,7 +2145,7 @@ end -- attr = attr or false -- -- local a = getattr(start,0) --- if (a == attr and (not attribute or getattr(start,a_state) == attribute)) or (not attribute or getattr(start,a_state) == attribute) then +-- if (a == attr and (not attribute or getprop(start,a_state) == attribute)) or (not attribute or getprop(start,a_state) == attribute) then -- -- the action -- end @@ -2129,6 +2157,8 @@ local function featuresprocessor(head,font,attr) return head, false end + head = tonut(head) + if trace_steps then checkstep(head) end @@ -2161,6 +2191,8 @@ local function featuresprocessor(head,font,attr) -- Keeping track of the headnode is needed for devanagari (I generalized it a bit -- so that multiple cases are also covered.) + -- todo: retain prev + for s=1,#datasets do local dataset = datasets[s] featurevalue = dataset[1] -- todo: pass to function instead of using a global @@ -2179,10 +2211,10 @@ local function featuresprocessor(head,font,attr) -- we need to get rid of this slide! probably no longer needed in latest luatex local start = find_node_tail(head) -- slow (we can store tail because there's always a skip at the end): todo while start do - local id = start.id + local id = getid(start) if id == glyph_code then - if start.font == font and start.subtype<256 then - local a = start[0] + if getfont(start) == font and getsubtype(start) < 256 then + local a = getattr(start,0) if a then a = a == attr else @@ -2193,7 +2225,7 @@ local function featuresprocessor(head,font,attr) local lookupname = subtables[i] local lookupcache = lookuphash[lookupname] if lookupcache then - local lookupmatch = lookupcache[start.char] + local lookupmatch = lookupcache[getchar(start)] if lookupmatch then head, start, success = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) if success then @@ -2204,15 +2236,15 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start = start.prev end + if start then start = getprev(start) end else - start = start.prev + start = getprev(start) end else - start = start.prev + start = getprev(start) end else - start = start.prev + start = getprev(start) end end else @@ -2232,16 +2264,16 @@ local function featuresprocessor(head,font,attr) local head = start local done = false while start do - local id = start.id - if id == glyph_code and start.font == font and start.subtype <256 then - local a = start[0] + local id = getid(start) + if id == glyph_code and getfont(start) == font and getsubtype(start) < 256 then + local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or start[a_state] == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or start[a_state] == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then - local lookupmatch = lookupcache[start.char] + local lookupmatch = lookupcache[getchar(start)] if lookupmatch then -- sequence kan weg local ok @@ -2250,12 +2282,12 @@ local function featuresprocessor(head,font,attr) done = true end end - if start then start = start.next end + if start then start = getnext(start) end else - start = start.next + start = getnext(start) end else - start = start.next + start = getnext(start) end end if done then @@ -2265,19 +2297,19 @@ local function featuresprocessor(head,font,attr) end local function kerndisc(disc) -- we can assume that prev and next are glyphs - local prev = disc.prev - local next = disc.next + local prev = getprev(disc) + local next = getnext(disc) if prev and next then - prev.next = next - -- next.prev = prev - local a = prev[0] + setfield(prev,"next",next) + -- setfield(next,"prev",prev) + local a = getattr(prev,0) if a then - a = (a == attr) and (not attribute or prev[a_state] == attribute) + a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) else - a = not attribute or prev[a_state] == attribute + a = not attribute or getprop(prev,a_state) == attribute end if a then - local lookupmatch = lookupcache[prev.char] + local lookupmatch = lookupcache[getchar(prev)] if lookupmatch then -- sequence kan weg local h, d, ok = handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -2287,24 +2319,24 @@ local function featuresprocessor(head,font,attr) end end end - prev.next = disc - -- next.prev = disc + setfield(prev,"next",disc) + -- setfield(next,"prev",disc) end return next end while start do - local id = start.id + local id = getid(start) if id == glyph_code then - if start.font == font and start.subtype<256 then - local a = start[0] + if getfont(start) == font and getsubtype(start) < 256 then + local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or start[a_state] == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or start[a_state] == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then - local lookupmatch = lookupcache[start.char] + local lookupmatch = lookupcache[getchar(start)] if lookupmatch then -- sequence kan weg local ok @@ -2313,39 +2345,39 @@ local function featuresprocessor(head,font,attr) success = true end end - if start then start = start.next end + if start then start = getnext(start) end else - start = start.next + start = getnext(start) end else - start = start.next + start = getnext(start) end elseif id == disc_code then -- mostly for gsub - if start.subtype == discretionary_code then - local pre = start.pre + if getsubtype(start) == discretionary_code then + local pre = getfield(start,"pre") if pre then local new = subrun(pre) - if new then start.pre = new end + if new then setfield(start,"pre",new) end end - local post = start.post + local post = getfield(start,"post") if post then local new = subrun(post) - if new then start.post = new end + if new then setfield(start,"post",new) end end - local replace = start.replace + local replace = getfield(start,"replace") if replace then local new = subrun(replace) - if new then start.replace = new end + if new then setfield(start,"replace",new) end end elseif typ == "gpos_single" or typ == "gpos_pair" then kerndisc(start) end - start = start.next + start = getnext(start) elseif id == whatsit_code then -- will be function - local subtype = start.subtype + local subtype = getsubtype(start) if subtype == dir_code then - local dir = start.dir + local dir = getfield(start,"dir") if dir == "+TRT" or dir == "+TLT" then topstack = topstack + 1 dirstack[topstack] = dir @@ -2364,7 +2396,7 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype == localpar_code then - local dir = start.dir + local dir = getfield(start,"dir") if dir == "TRT" then rlparmode = -1 elseif dir == "TLT" then @@ -2378,11 +2410,11 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start = start.next + start = getnext(start) elseif id == math_code then - start = end_of_math(start).next + start = getnext(end_of_math(start)) else - start = start.next + start = getnext(start) end end end @@ -2393,20 +2425,20 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then local head = start local done = false while start do - local id = start.id - if id == glyph_code and start.id == font and start.subtype <256 then - local a = start[0] + local id = getid(start) + if id == glyph_code and getfont(start) == font and getsubtype(start) < 256 then + local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or start[a_state] == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or start[a_state] == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then for i=1,ns do local lookupname = subtables[i] local lookupcache = lookuphash[lookupname] if lookupcache then - local lookupmatch = lookupcache[start.char] + local lookupmatch = lookupcache[getchar(start)] if lookupmatch then -- we could move all code inline but that makes things even more unreadable local ok @@ -2423,12 +2455,12 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then report_missing_cache(typ,lookupname) end end - if start then start = start.next end + if start then start = getnext(start) end else - start = start.next + start = getnext(start) end else - start = start.next + start = getnext(start) end end if done then @@ -2438,23 +2470,23 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then end local function kerndisc(disc) -- we can assume that prev and next are glyphs - local prev = disc.prev - local next = disc.next + local prev = getprev(disc) + local next = getnext(disc) if prev and next then - prev.next = next - -- next.prev = prev - local a = prev[0] + setfield(prev,"next",next) + -- setfield(next,"prev",prev) + local a = getattr(prev,0) if a then - a = (a == attr) and (not attribute or prev[a_state] == attribute) + a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) else - a = not attribute or prev[a_state] == attribute + a = not attribute or getprop(prev,a_state) == attribute end if a then for i=1,ns do local lookupname = subtables[i] local lookupcache = lookuphash[lookupname] if lookupcache then - local lookupmatch = lookupcache[prev.char] + local lookupmatch = lookupcache[getchar(prev)] if lookupmatch then -- we could move all code inline but that makes things even more unreadable local h, d, ok = handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -2468,28 +2500,28 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then end end end - prev.next = disc - -- next.prev = disc + setfield(prev,"next",disc) + -- setfield(next,"prev",disc) end return next end while start do - local id = start.id + local id = getid(start) if id == glyph_code then - if start.font == font and start.subtype<256 then - local a = start[0] + if getfont(start) == font and getsubtype(start) < 256 then + local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or start[a_state] == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or start[a_state] == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then for i=1,ns do local lookupname = subtables[i] local lookupcache = lookuphash[lookupname] if lookupcache then - local lookupmatch = lookupcache[start.char] + local lookupmatch = lookupcache[getchar(start)] if lookupmatch then -- we could move all code inline but that makes things even more unreadable local ok @@ -2506,39 +2538,39 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then report_missing_cache(typ,lookupname) end end - if start then start = start.next end + if start then start = getnext(start) end else - start = start.next + start = getnext(start) end else - start = start.next + start = getnext(start) end elseif id == disc_code then -- mostly for gsub - if start.subtype == discretionary_code then - local pre = start.pre + if getsubtype(start) == discretionary_code then + local pre = getfield(start,"pre") if pre then local new = subrun(pre) - if new then start.pre = new end + if new then setfield(start,"pre",new) end end - local post = start.post + local post = getfield(start,"post") if post then local new = subrun(post) - if new then start.post = new end + if new then setfield(start,"post",new) end end - local replace = start.replace + local replace = getfield(start,"replace") if replace then local new = subrun(replace) - if new then start.replace = new end + if new then setfield(start,"replace",new) end end elseif typ == "gpos_single" or typ == "gpos_pair" then kerndisc(start) end - start = start.next + start = getnext(start) elseif id == whatsit_code then - local subtype = start.subtype + local subtype = getsubtype(start) if subtype == dir_code then - local dir = start.dir + local dir = getfield(start,"dir") if dir == "+TRT" or dir == "+TLT" then topstack = topstack + 1 dirstack[topstack] = dir @@ -2557,7 +2589,7 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype == localpar_code then - local dir = start.dir + local dir = getfield(start,"dir") if dir == "TRT" then rlparmode = -1 elseif dir == "TLT" then @@ -2570,11 +2602,11 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start = start.next + start = getnext(start) elseif id == math_code then - start = end_of_math(start).next + start = getnext(end_of_math(start)) else - start = start.next + start = getnext(start) end end end @@ -2586,6 +2618,9 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then registerstep(head) end end + + head = tonode(head) + return head, done end diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua index 5e5c9a4cf..678a28300 100644 --- a/tex/generic/context/luatex/luatex-fonts.lua +++ b/tex/generic/context/luatex/luatex-fonts.lua @@ -27,6 +27,16 @@ if not modules then modules = { } end modules ['luatex-fonts'] = { -- also add more helper code here, but that depends to what extend metatex (sidetrack of context) -- evolves into a low level layer (depends on time, as usual). +texio.write_nl("") +texio.write_nl("--------------------------------------------------------------------------------") +texio.write_nl("The font code has been brought in sync with the context version of 2014.12.01 so") +texio.write_nl("if things don't work out as expected the interfacing needs to be checked. When") +texio.write_nl("this works as expected a second upgrade will happen that gives a more complete") +texio.write_nl("support and another sync with the context code (that new code is currently being") +texio.write_nl("tested. The base pass is now integrated in the main pass.") +texio.write_nl("--------------------------------------------------------------------------------") +texio.write_nl("") + utf = utf or unicode.utf8 -- We have some (global) hooks (for latex): @@ -210,12 +220,12 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule('font-oti.lua') loadmodule('font-otf.lua') loadmodule('font-otb.lua') - loadmodule('luatex-fonts-inj.lua') -- will be replaced (luatex >= .80) - loadmodule('font-ota.lua') + loadmodule('luatex-fonts-inj.lua') + loadmodule('luatex-fonts-ota.lua') loadmodule('luatex-fonts-otn.lua') - loadmodule('font-otp.lua') -- optional + loadmodule('font-otp.lua') loadmodule('luatex-fonts-lua.lua') - loadmodule('font-def.lua') + loadmodule('font-def.lua') -- this code (stripped) might end up in luatex-fonts-def.lua loadmodule('luatex-fonts-def.lua') loadmodule('luatex-fonts-ext.lua') -- some extensions @@ -250,8 +260,8 @@ generic_context.callback_define_font = fonts.definers.read if not generic_context.no_callbacks_yet then - callback.register('ligaturing', generic_context.callback_ligaturing) - callback.register('kerning', generic_context.callback_kerning) + -- callback.register('ligaturing', generic_context.callback_ligaturing) + -- callback.register('kerning', generic_context.callback_kerning) callback.register('pre_linebreak_filter', generic_context.callback_pre_linebreak_filter) callback.register('hpack_filter', generic_context.callback_hpack_filter) callback.register('define_font' , generic_context.callback_define_font) diff --git a/tex/generic/context/luatex/luatex-test.tex b/tex/generic/context/luatex/luatex-test.tex index b822af668..169a260dd 100644 --- a/tex/generic/context/luatex/luatex-test.tex +++ b/tex/generic/context/luatex/luatex-test.tex @@ -64,13 +64,12 @@ \font\test=dejavuserif:+kern at 10pt \test -\hsize 1mm -\noindent Циолковский +\bgroup \hsize 1mm \noindent Циолковский \par \egroup \loadpatterns{ru} -\noindent Циолковский +\bgroup \hsize 1mm \noindent Циолковский \par \egroup a bit of math |