From 86659b2416b5513b448fa70329d135e3a8ce165c Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Fri, 8 Jul 2016 00:54:11 +0200 Subject: 2016-07-08 00:03:00 --- tex/context/base/context-version.pdf | Bin 4254 -> 4256 bytes tex/context/base/mkiv/back-pdf.mkiv | 6 +- tex/context/base/mkiv/colo-imp-rgb.mkiv | 10 +- tex/context/base/mkiv/colo-ini.lua | 47 ++++- tex/context/base/mkiv/colo-ini.mkiv | 35 ++-- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 3 +- tex/context/base/mkiv/font-otc.lua | 141 ++++++++++---- tex/context/base/mkiv/font-otj.lua | 60 ++++-- tex/context/base/mkiv/font-ots.lua | 88 ++++----- tex/context/base/mkiv/grph-pat.lua | 74 ++++++++ tex/context/base/mkiv/grph-pat.mkiv | 125 ++++++++++++ tex/context/base/mkiv/lpdf-grp.lua | 37 +++- tex/context/base/mkiv/lpdf-ini.lua | 11 +- tex/context/base/mkiv/lpdf-nod.lua | 30 +-- tex/context/base/mkiv/math-ali.mkiv | 209 ++++++++++++++++----- tex/context/base/mkiv/node-res.lua | 15 +- tex/context/base/mkiv/status-files.pdf | Bin 9083 -> 9213 bytes tex/context/base/mkiv/status-lua.pdf | Bin 366661 -> 367168 bytes tex/context/base/mkiv/strc-mat.mkiv | 2 +- tex/context/interface/mkiv/i-context.pdf | Bin 821334 -> 821499 bytes tex/context/interface/mkiv/i-readme.pdf | Bin 60784 -> 60787 bytes tex/generic/context/luatex/luatex-fonts-merged.lua | 106 ++++++----- 23 files changed, 770 insertions(+), 231 deletions(-) create mode 100644 tex/context/base/mkiv/grph-pat.lua create mode 100644 tex/context/base/mkiv/grph-pat.mkiv (limited to 'tex') diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 1540c94a5..21a5808f0 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/mkiv/back-pdf.mkiv b/tex/context/base/mkiv/back-pdf.mkiv index 3e055ea83..8c4061f2e 100644 --- a/tex/context/base/mkiv/back-pdf.mkiv +++ b/tex/context/base/mkiv/back-pdf.mkiv @@ -86,9 +86,9 @@ %D But we still provide: -\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} -\unexpanded\def\maximumpdfcompression{\clf_setpdfcompression\plusnine \plusnine } -\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} +\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} +\unexpanded\def\maximumpdfcompression {\clf_setpdfcompression\plusnine \plusnine } +\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} %D These might even become no-ops as we don't need them in \CONTEXT: diff --git a/tex/context/base/mkiv/colo-imp-rgb.mkiv b/tex/context/base/mkiv/colo-imp-rgb.mkiv index 58b2ca42c..934071ed9 100644 --- a/tex/context/base/mkiv/colo-imp-rgb.mkiv +++ b/tex/context/base/mkiv/colo-imp-rgb.mkiv @@ -112,8 +112,8 @@ \definecolor [gruen] [green] \definecolor [blau] [blue] - \definecolor [cyan] [cyan] - \definecolor [magenta] [magenta] + %definecolor [cyan] [cyan] + %definecolor [magenta] [magenta] \definecolor [gelb] [yellow] \definecolor [weiss] [white] @@ -245,8 +245,8 @@ \definecolor [vert] [green] \definecolor [bleu] [blue] - \definecolor [cyan] [cyan] - \definecolor [magenta] [magenta] + %\definecolor [cyan] [cyan] + %\definecolor [magenta] [magenta] \definecolor [jaune] [yellow] \definecolor [blanche] [white] @@ -290,7 +290,7 @@ \definecolor [albastru] [blue] \definecolor [cian] [cyan] - \definecolor [magenta] [magenta] + %\definecolor [magenta] [magenta] \definecolor [galben] [yellow] \definecolor [alb] [white] diff --git a/tex/context/base/mkiv/colo-ini.lua b/tex/context/base/mkiv/colo-ini.lua index 32f095a3d..b1d9c2f9a 100644 --- a/tex/context/base/mkiv/colo-ini.lua +++ b/tex/context/base/mkiv/colo-ini.lua @@ -229,6 +229,8 @@ local transparent = { luminosity = 16, } +transparencies.names = transparent + local gray_okay = true local rgb_okay = true local cmyk_okay = true @@ -377,6 +379,21 @@ end) local defineintermediatecolor +local function resolvedname(name) + local color + if valid[name] then + color = counts[name] + if color then + color = texgetcount(color) + else + color = l_color[name] -- fall back on old method + end + else + color = l_color[name] -- fall back on old method + end + return color, l_transparency[name] +end + local function defineprocesscolor(name,str,global,freeze) -- still inconsistent color vs transparent local what, one, two, three = lpegmatch(specialcolor,str) if what == "H" then @@ -384,10 +401,16 @@ local function defineprocesscolor(name,str,global,freeze) -- still inconsistent definecolor(name, register_color(name,'rgb',one,two,three),global) elseif what == "M" then -- intermediate - return defineintermediatecolor(name,one,l_color[two],l_color[three],l_transparency[two],l_transparency[three],"",global,freeze) + -- return defineintermediatecolor(name,one,l_color[two],l_color[three],l_transparency[two],l_transparency[three],"",global,freeze) + local c1, t1 = resolvedname(two) + local c2, t2 = resolvedname(three) + return defineintermediatecolor(name,one,c1,c2,t1,t2,"",global,freeze) elseif what == "P" then -- pgf for tikz - return defineintermediatecolor(name,two,l_color[one],l_color[three],l_transparency[one],l_transparency[three],"",global,freeze) + -- return defineintermediatecolor(name,two,l_color[one],l_color[three],l_transparency[one],l_transparency[three],"",global,freeze) + local c1, t1 = resolvedname(one) + local c2, t2 = resolvedname(three) + return defineintermediatecolor(name,two,c1,c1,t1,t2,"",global,freeze) else local settings = settings_to_hash_strict(str) if settings then @@ -470,7 +493,7 @@ local function definespotcolor(name,parent,str,global) if ta and tt then definetransparent(name, transparencies.register(name,transparent[ta] or tonumber(ta) or 1,tonumber(tt) or 1), global) elseif colors.couple then - --~ definetransparent(name, transparencies.register(nil, 1, 1), global) -- can be sped up + -- definetransparent(name, transparencies.register(nil, 1, 1), global) -- can be sped up definetransparent(name, 0, global) -- can be sped up end end @@ -547,7 +570,11 @@ local function definemultitonecolor(name,multispec,colorspec,selfspec) nn = concat(nn,'_') local parent = gsub(lower(nn),"[^%d%a%.]+","_") if not colorspec or colorspec == "" then - local cc = { } for i=1,max do cc[i] = l_color[dd[i]] end + local cc = { } + for i=1,max do +-- cc[i] = l_color[dd[i]] + cc[i] = resolvedname(dd[i]) + end definemixcolor(name,parent,pp,cc,global,freeze) -- can become local else if selfspec ~= "" then @@ -823,11 +850,19 @@ local min = math.min local function inbetween(one,two,i,fraction) local o, t = one[i], two[i] + local c = fraction < 0 + if c then + fraction = - fraction + end local otf = o + fraction * (t - o) if otf > 1 then otf = 1 end - return otf + if c then + return 1 - otf + else + return otf + end end local function justone(one,fraction,i) @@ -848,7 +883,7 @@ end defineintermediatecolor = function(name,fraction,c_one,c_two,a_one,a_two,specs,global,freeze) fraction = tonumber(fraction) or 1 - local one, two = colorvalues[c_one], colorvalues[c_two] + local one, two = colorvalues[c_one], colorvalues[c_two] -- beware, it uses the globals if one then if two then local csone, cstwo = one[1], two[1] diff --git a/tex/context/base/mkiv/colo-ini.mkiv b/tex/context/base/mkiv/colo-ini.mkiv index e984128d9..c5705643f 100644 --- a/tex/context/base/mkiv/colo-ini.mkiv +++ b/tex/context/base/mkiv/colo-ini.mkiv @@ -774,25 +774,32 @@ {\advance\c_colo_protection\minusone} \def\colo_basics_define[#1][#2]% - {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax - \colo_basics_synchronize{#1}% - \ifcase\c_colo_protection - \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% + {\edef\m_colo_old{#1}% + \edef\m_colo_new{#2}% + \ifx\m_colo_old\m_colo_new + % maybe a warning + \else + \clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax + \colo_basics_synchronize{#1}% + \ifcase\c_colo_protection + \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% + \fi \fi} \def\colo_basics_define_global[#1][#2]% - {\clf_defineprocesscolorglobal{#1}{#2}\v_colo_freeze_state\relax - \colo_basics_synchronize{#1}% - \ifcase\c_colo_protection - \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% + {\edef\m_colo_old{#1}% + \edef\m_colo_new{#2}% + \ifx\m_colo_old\m_colo_new + % maybe a warning + \else + \clf_defineprocesscolorglobal{#1}{#2}\v_colo_freeze_state\relax + \colo_basics_synchronize{#1}% + \ifcase\c_colo_protection + \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% + \fi \fi} -\def\colo_basics_define_named[#1][#2]% currently same as define - {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax - \colo_basics_synchronize{#1}% - \ifcase\c_colo_protection - \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% - \fi} +\let\colo_basics_define_named\colo_basics_define \def\dodefinefastcolor[#1][#2]% still not fast but ok (might change) {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 638d92a01..fe4ee0e69 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.07.06 10:01} +\newcontextversion{2016.07.07 23:58} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 3e54ba8c7..3bf751cc5 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.07.06 10:01} +\edef\contextversion{2016.07.07 23:58} \edef\contextkind {beta} %D For those who want to use this: @@ -510,6 +510,7 @@ \loadmarkfile{grph-fig} \loadmarkfile{grph-raw} \loadmarkfile{grph-rul} +\loadmarkfile{grph-pat} \loadmarkfile{pack-box} \loadmarkfile{pack-bar} diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua index 14afc5c50..a55320903 100644 --- a/tex/context/base/mkiv/font-otc.lua +++ b/tex/context/base/mkiv/font-otc.lua @@ -44,6 +44,24 @@ local types = { chainposition = "gpos_contextchain", } +local names = { + gsub_single = "gsub", + gsub_multiple = "gsub", + gsub_alternate = "gsub", + gsub_ligature = "gsub", + gsub_context = "gsub", + gsub_contextchain = "gsub", + gsub_reversecontextchain = "gsub", + gpos_single = "gpos", + gpos_pair = "gpos", + gpos_cursive = "gpos", + gpos_mark2base = "gpos", + gpos_mark2ligature = "gpos", + gpos_mark2mark = "gpos", + gpos_context = "gpos", + gpos_contextchain = "gpos", +} + setmetatableindex(types, function(t,k) t[k] = k return k end) -- "key" local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } @@ -51,6 +69,22 @@ local noflags = { false, false, false, false } -- beware: shared, maybe we should copy the sequence +local function getrange(sequences,category) + local count = #sequences + local first = nil + local last = nil + for i=1,count do + local t = sequences[i].type + if t and names[t] == category then + if not first then + first = i + end + last = i + end + end + return first or 1, last or count +end + local function validspecification(specification,name) local dataset = specification.dataset if dataset then @@ -434,6 +468,74 @@ local function addfeature(data,feature,specifications) local dataset = specifications.dataset + local function report(name,category,position,first,last,sequences) + report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", + name,category,position,first,last,1,#sequences) + end + + local function inject(specification,sequences,sequence,first,last,category,name) + local position = specification.position or false + if not position then + position = specification.prepend + if position == true then + if trace_loading then + report(name,category,first,first,last,sequences) + end + insert(sequences,first,sequence) + return + end + end + if not position then + position = specification.append + if position == true then + if trace_loading then + report(name,category,last+1,first,last,sequences) + end + insert(sequences,last+1,sequence) + return + end + end + local kind = type(position) + if kind == "string" then + local index = false + for i=first,last do + local s = sequences[i] + local f = s.features + if f then + for k in next, f do + if k == position then + index = i + break + end + end + if index then + break + end + end + end + if index then + position = index + else + position = last + 1 + end + elseif kind == "number" then + if position < 0 then + position = last - position + 1 + end + if position > last then + position = last + 1 + elseif position < first then + position = first + end + else + position = last + 1 + end + if trace_loading then + report(name,category,position,first,last,sequences) + end + insert(sequences,position,sequence) + end + for s=1,#dataset do local specification = dataset[s] local valid = specification.valid -- nowhere used @@ -546,6 +648,7 @@ local function addfeature(data,feature,specifications) if featureflags[1] then featureflags[1] = "mark" end if featureflags[2] then featureflags[2] = "ligature" end if featureflags[3] then featureflags[3] = "base" end + local steptype = types[featuretype] local sequence = { chain = featurechain, features = { [feature] = askedfeatures }, @@ -554,41 +657,11 @@ local function addfeature(data,feature,specifications) order = featureorder, [stepkey] = steps, nofsteps = nofsteps, - type = types[featuretype], + type = steptype, } - -- todo : before|after|index - local prepend = specification.prepend - if prepend == true then - prepend = 1 - end - if type(prepend) == "number" then - -- okay - elseif type(prepend) == "string" then - local index = false - for i=1,#sequences do - local s = sequences[i] - local f = s.features - if f then - for k in next, f do - if k == prepend then - index = i - break - end - end - if index then - break - end - end - end - prepend = index - elseif prepend == true then - prepend = 1 - end - if not prepend or prepend <= 0 or prepend > #sequences then - insert(sequences,sequence) - else - insert(sequences,prepend,sequence) - end + -- position | prepend | append + local first, last = getrange(sequences,category) + inject(specification,sequences,sequence,first,last,category,feature) -- register in metadata (merge as there can be a few) local features = fontfeatures[category] if not features then diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua index 3bbed0918..27422c2a1 100644 --- a/tex/context/base/mkiv/font-otj.lua +++ b/tex/context/base/mkiv/font-otj.lua @@ -30,7 +30,6 @@ if not nodes.properties then return end local next, rawget = next, rawget local fastcopy = table.fastcopy -local floor = math.floor local registertracker = trackers.register @@ -1423,6 +1422,48 @@ function nodes.injections.setspacekerns(font,sequence) end end +local getthreshold + +if context then + + local threshold = 1 -- todo: add a few methods for context + local parameters = fonts.hashes.parameters + + directives.register("otf.threshold", function(v) threshold = tonumber(v) or 1 end) + + getthreshold = function(font) + local p = parameters[font] + local f = p.factor + local s = p.spacing + local t = threshold * (s and s.width or p.space or 0) - 2 + return t > 0 and t or 0, f + end + +else + + injections.threshold = 0 + + getthreshold = function(font) + local p = fontdata[font].parameters + local f = p.factor + local s = p.spacing + local t = injections.threshold * (s and s.width or p.space or 0) - 2 + return t > 0 and t or 0, f + end + +end + +injections.getthreshold = getthreshold + +function injections.isspace(n,threshold) + if getid(n) == glue_code then + local w = getfield(n,"width") + if threshold and w > threshold then -- was >= + return 32 + end + end +end + local function injectspaces(head) if not triggers then @@ -1439,18 +1480,11 @@ local function injectspaces(head) local rightkern = false local function updatefont(font,trig) - -- local resources = resources[font] - -- local spacekerns = resources.spacekerns - -- if spacekerns then - -- leftkerns = spacekerns.left - -- rightkerns = spacekerns.right - -- end leftkerns = trig.left rightkerns = trig.right - local par = fontdata[font].parameters -- fallback for generic - factor = par.factor - threshold = floor(par.spacing.width - 2) -- get rid of rounding errors lastfont = font + threshold, + factor = getthreshold(font) end for n in traverse_id(glue_code,tonut(head)) do @@ -1470,7 +1504,7 @@ local function injectspaces(head) end end if prevchar then - local font = getfont(next) + local font = getfont(prev) local trig = triggers[font] if trig then if lastfont ~= font then @@ -1483,7 +1517,7 @@ local function injectspaces(head) end if leftkern then local old = getfield(n,"width") - if old >= threshold then + if old > threshold then if rightkern then local new = old + (leftkern + rightkern) * factor if trace_spaces then @@ -1502,7 +1536,7 @@ local function injectspaces(head) leftkern = false elseif rightkern then local old = getfield(n,"width") - if old >= threshold then + if old > threshold then local new = old + rightkern * factor if trace_spaces then report_spaces("[%p -> %p] %C",nextchar,old,new) diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 2c84b0c49..0f385088a 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -134,12 +134,8 @@ local trace_discruns = false registertracker("otf.discruns", function(v local trace_compruns = false registertracker("otf.compruns", function(v) trace_compruns = v end) local trace_testruns = false registertracker("otf.testruns", function(v) trace_testruns = v end) -local quit_on_no_replacement = true -- maybe per font -local zwnjruns = true -local optimizekerns = true - -registerdirective("otf.zwnjruns", function(v) zwnjruns = v end) -registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement = value end) +----- zwnjruns = true registerdirective("otf.zwnjruns", function(v) zwnjruns = v end) +local optimizekerns = true local report_direct = logs.reporter("fonts","otf direct") local report_subchain = logs.reporter("fonts","otf subchain") @@ -270,16 +266,8 @@ local notmatchreplace = { } local handlers = { } --- helper - -local function isspace(n) - if getid(n) == glue_code then - local w = getfield(n,"width") - if w >= threshold then - return 32 - end - end -end +local isspace = injections.isspace +local getthreshold = injections.getthreshold -- we use this for special testing and documentation @@ -606,7 +594,7 @@ end return head, base end -local function multiple_glyphs(head,start,multiple,ignoremarks) +local function multiple_glyphs(head,start,multiple,ignoremarks,what) local nofmultiples = #multiple if nofmultiples > 0 then resetinjection(start) @@ -614,17 +602,29 @@ local function multiple_glyphs(head,start,multiple,ignoremarks) if nofmultiples > 1 then local sn = getnext(start) for k=2,nofmultiples do --- untested: --- --- while ignoremarks and marks[getchar(sn)] then --- local sn = getnext(sn) --- end + -- untested: + -- + -- while ignoremarks and marks[getchar(sn)] then + -- local sn = getnext(sn) + -- end local n = copy_node(start) -- ignore components resetinjection(n) setchar(n,multiple[k]) insert_node_after(head,start,n) start = n end + if what == true then + -- we're ok + elseif what > 1 then + local m = multiple[nofmultiples] + for i=2,what do + local n = copy_node(start) -- ignore components + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start = n + end + end end return head, start, true else @@ -706,7 +706,7 @@ function handlers.gsub_multiple(head,start,dataset,sequence,multiple) if trace_multiples then logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) end - return multiple_glyphs(head,start,multiple,sequence.flags[1]) + return multiple_glyphs(head,start,multiple,sequence.flags[1],dataset[1]) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) @@ -1238,7 +1238,7 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup if trace_multiples then logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) end - return multiple_glyphs(head,start,replacement,sequence.flags[1]) + return multiple_glyphs(head,start,replacement,sequence.flags[1],dataset[1]) end return head, start, false end @@ -1263,7 +1263,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku end local kind = dataset[4] local what = dataset[1] - local value = what == true and tfmdata.shared.features[kind] or what + local value = what == true and tfmdata.shared.features[kind] or what -- todo: optimize in ctx local current = start while current do local currentchar = ischar(current) @@ -2296,16 +2296,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end -- maybe only if match prev = getprev(prev) - elseif seq[n][32] then + elseif seq[n][32] and isspace(prev,threshold) then n = n - 1 prev = getprev(prev) else match = false break end - elseif seq[n][32] then -- somewhat special, as zapfino can have many preceding spaces - n = n - 1 - prev = getprev(prev) -- was absent else match = false break @@ -2425,15 +2422,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end -- maybe only if match current = getnext(current) - elseif seq[n][32] then -- brrr + elseif seq[n][32] and isspace(current,threshold) then n = n + 1 + current = getnext(current) else match = false break end - elseif seq[n][32] then - n = n + 1 - current = getnext(current) else match = false break @@ -2546,7 +2541,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if replacements then head, start, done = reversesub(head,start,last,dataset,sequence,replacements,rlmode) else - done = quit_on_no_replacement -- can be meant to be skipped / quite inconsistent in fonts + done = true if trace_contexts then logprocess("%s: skipping match",cref(dataset,sequence)) end @@ -2729,10 +2724,10 @@ local function kernrun(disc,k_run,font,attr,...) end end -- - if prev and (pre or replace) and not ischar(prev,font) then + if prev and not ischar(prev,font) then -- and (pre or replace) prev = false end - if next and (post or replace) and not ischar(next,font) then + if next and not ischar(next,font) then -- and (post or replace) next = false end -- @@ -3307,13 +3302,13 @@ local function featuresprocessor(head,font,attr) if nesting == 1 then - currentfont = font - tfmdata = fontdata[font] - descriptions = tfmdata.descriptions - characters = tfmdata.characters - marks = tfmdata.resources.marks - factor = tfmdata.parameters.factor - threshold = tfmdata.parameters.spacing.width or 65536*10 + currentfont = font + tfmdata = fontdata[font] + descriptions = tfmdata.descriptions + characters = tfmdata.characters + marks = tfmdata.resources.marks + threshold, + factor = getthreshold(font) elseif currentfont ~= font then @@ -3372,15 +3367,12 @@ local function featuresprocessor(head,font,attr) local nofsteps = sequence.nofsteps if not steps then -- this permits injection, watch the different arguments - local h, d, ok = handler(head,start,dataset,sequence,nil,nil,nil,0,font,attr) + local h, d, ok = handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr) if ok then success = true if h then head = h end - if d then - start = d - end end elseif typ == "gsub_reversecontextchain" then -- this is a limited case, no special treatments like 'init' etc @@ -3611,7 +3603,7 @@ if fontfeatures then else -- generic (no hashes) function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) - local shared = identifiers[font].shared + local shared = fontdata[font].shared local features = shared and shared.features local enabled = features and features.spacekern == true and features.kern == true if enabled then diff --git a/tex/context/base/mkiv/grph-pat.lua b/tex/context/base/mkiv/grph-pat.lua new file mode 100644 index 000000000..17bde6dea --- /dev/null +++ b/tex/context/base/mkiv/grph-pat.lua @@ -0,0 +1,74 @@ +if not modules then modules = { } end modules ['grph-pat'] = { + version = 1.001, + comment = "companion to grph-pat.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is just a proof of concept. Viewers behave different (offsets) and Acrobat doesn't +-- show xform based patterns. +-- +-- This module will be cleaned up and use codeinjections and such. + +local texsetbox = tex.setbox +local texgetbox = tex.getbox + +local nodepool = nodes.pool +local new_literal = nodepool.pdfpageliteral +local new_hlist = nodepool.hlist + +local names = { } + +interfaces.implement { + name = "registerpattern", + arguments = { { + { "name" }, + { "number", "integer" }, + { "width", "dimension" }, + { "height", "dimension" }, + { "hoffset", "dimension" }, + { "voffset", "dimension" }, + } }, + actions = function(specification) + local number = specification.number + local name = specification.name + local box = texgetbox(number) + if not name or name == "" then + return + end + nodes.handlers.finalize(box) + names[name] = lpdf.registerpattern { + number = number, + width = specification.width or box.width, + height = specification.height or (box.height + box.depth) , + hoffset = specification.hoffset, + voffset = specification.voffset, + } + end +} + +interfaces.implement { + name = "applypattern", + arguments = { { + { "name" }, + { "number", "integer" }, + { "width", "dimension" }, + { "height", "dimension" }, + } }, + actions = function(specification) + local number = specification.number + local name = specification.name + local width = specification.width + local height = specification.height + if not name or name == "" then + return + end + local p = names[name] + if p then + local l = new_literal(lpdf.patternstream(p,width,height)) + local h = new_hlist(l,width,height) + texsetbox(number,h) + end + end +} diff --git a/tex/context/base/mkiv/grph-pat.mkiv b/tex/context/base/mkiv/grph-pat.mkiv new file mode 100644 index 000000000..0126647cc --- /dev/null +++ b/tex/context/base/mkiv/grph-pat.mkiv @@ -0,0 +1,125 @@ +%D \module +%D [ file=grph-par, +%D version=2016.07.08, +%D title=\CONTEXT\ Graphic Macros, +%D subtitle=Patterns, +%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. + +%D This works ok in Okular and MuPDF but somehow xforms don't work in Acrobat +%D (full nor reader). Also the basic offset is kind of unspecified. So \unknown\ +%D we're dealing with a fragile feature. So, don't rely on where the first (ulr) +%D tile occurs. +%D +%D The two commands introduced here are not documented (yet). + +\writestatus{loading}{ConTeXt Graphic Macros / Patterns} + +\unprotect + +\registerctxluafile{grph-pat}{1.001} + +\unexpanded\def\registerpattern + {\begingroup + \letdummyparameter\c!name \s!dummy + \letdummyparameter\c!width \v!auto + \letdummyparameter\c!height \v!auto + \letdummyparameter\c!hoffset\zeropoint + \letdummyparameter\c!voffset\zeropoint + \dodoubleempty\syst_boxes_registerpattern} + +\def\syst_boxes_registerpattern[#1][#2]% + {\ifsecondargument + \setdummyparameter\c!name{#1}% + \getdummyparameters[#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\getdummyparameters[#1]}% + {\setdummyparameter\c!name{#1}}% + \fi\fi + \dowithnextboxcs\syst_boxes_registerpattern_indeed\hbox} + +\edef\v!auto_m{-\v!auto} + +\def\syst_boxes_registerpattern_indeed + {%\finalizeobjectbox\nextbox + \edef\p_width {\dummyparameter\c!width}% + \edef\p_height {\dummyparameter\c!height}% + \edef\p_hoffset{\dummyparameter\c!hoffset}% + \edef\p_voffset{\dummyparameter\c!voffset}% + \scratchwidth \dimexpr\ifx\p_width \v!auto\wd \nextbox \else\p_width \fi\relax + \scratchheight \dimexpr\ifx\p_height \v!auto\htdp\nextbox \else\p_height \fi\relax + \scratchhoffset\dimexpr\ifx\p_hoffset\v!auto\scratchwidth /2\else\ifx\p_hoffset\v!auto_m-\scratchwidth /2\else\p_hoffset\fi\fi\relax + \scratchvoffset\dimexpr\ifx\p_voffset\v!auto\scratchheight/2\else\ifx\p_voffset\v!auto_m-\scratchheight/2\else\p_voffset\fi\fi\relax + \clf_registerpattern + name {\dummyparameter\c!name} + number \nextbox + width \scratchwidth + height \scratchheight + hoffset \scratchhoffset + voffset \scratchvoffset + \relax + \endgroup} + +\unexpanded\def\applypattern + {\hbox\bgroup + \letdummyparameter\c!name \s!dummy + \letdummyparameter\c!width \zeropoint + \letdummyparameter\c!height\zeropoint + \dodoubleempty\syst_boxes_applypattern} + +\def\syst_boxes_applypattern[#1][#2]% + {\ifsecondargument + \setdummyparameter\c!name{#1}% + \getdummyparameters[#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\getdummyparameters[#1]}% + {\setdummyparameter\c!name{#1}}% + \fi\fi + \clf_applypattern + name {\dummyparameter\c!name} + number \nextbox + width \dimexpr\dummyparameter\c!width\relax + height \dimexpr\dummyparameter\c!height\relax + \relax + \box\nextbox + \egroup} + +\protect + +\continueifinputfile{grph-pat.mkiv} + +\nopdfcompression + +\starttext + + \registerpattern[demo]{It \darkred Works!} + + \framed[offset=overlay]{\applypattern[demo][width=7cm,height=4cm]} + + \blank + + \registerpattern[name=more,hoffset=0bp,voffset=0pt]{\externalfigure[cow.pdf][width=1cm]} + + \framed[offset=overlay]{\applypattern[name=more,width=7cm,height=4cm]} + + \blank + + \registerpattern[name=more,hoffset=auto,voffset=auto]{\externalfigure[cow.pdf][width=1cm]} + + \framed[offset=overlay]{\applypattern[name=more,width=7cm,height=4cm]} + + \blank + + \registerpattern[name=more,hoffset=-auto,voffset=-auto]{\externalfigure[cow.pdf][width=1cm]} + + \framed[offset=overlay]{\applypattern[name=more,width=7cm,height=4cm]} + +\stoptext + diff --git a/tex/context/base/mkiv/lpdf-grp.lua b/tex/context/base/mkiv/lpdf-grp.lua index af9116175..c5d1b1c65 100644 --- a/tex/context/base/mkiv/lpdf-grp.lua +++ b/tex/context/base/mkiv/lpdf-grp.lua @@ -16,7 +16,7 @@ local backends, lpdf = backends, lpdf local nodeinjections = backends.pdf.nodeinjections local colors = attributes.colors -local basepoints = number.dimenfactors["bp"] +local basepoints = number.dimenfactors.bp local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections @@ -266,8 +266,6 @@ end -- temp hack -local factor = number.dimenfactors.bp - function img.package(image) -- see lpdf-u3d ** local boundingbox = image.bbox local imagetag = "Im" .. image.index @@ -287,8 +285,39 @@ function img.package(image) -- see lpdf-u3d ** local xform = img.scan { attr = resources(), stream = formatters["%F 0 0 %F 0 0 cm /%s Do"](width,height,imagetag), - bbox = { 0, 0, width/factor, height/factor }, + bbox = { 0, 0, width/basepoints, height/basepoints }, } img.immediatewrite(xform) return xform end + +-- experimental + +local nofpatterns = 0 +local f_pattern = formatters["q /Pattern cs /%s scn 0 0 %F %F re f Q"] -- q Q is not really needed + +local texsavebox = tex.saveboxresource + +function lpdf.registerpattern(specification) + nofpatterns = nofpatterns + 1 + local d = pdfdictionary { + Type = pdfconstant("Pattern"), + PatternType = 1, + PaintType = 1, + TilingType = 2, + XStep = (specification.width or 10) * basepoints, + YStep = (specification.height or 10) * basepoints, + Matrix = { + 1, 0, 0, 1, + (specification.hoffset or 0) * basepoints, + (specification.voffset or 0) * basepoints, + }, + } + local n = texsavebox(specification.number,d(),lpdf.collectedresources(),true,1) + lpdf.adddocumentpattern("Pt" .. nofpatterns,lpdf.reference(n)) + return nofpatterns +end + +function lpdf.patternstream(n,width,height) + return f_pattern("Pt" .. n,width*basepoints,height*basepoints) +end diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index bd47fda1b..01a045979 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -514,8 +514,15 @@ local mt_v = { __lpdftype = "verbose", __tostring = tostring_v, __call = valu local function pdfstream(t) -- we need to add attributes if t then - for i=1,#t do - t[i] = tostring(t[i]) + local tt = type(t) + if tt == "table" then + for i=1,#t do + t[i] = tostring(t[i]) + end + elseif tt == "string" then + t= { t } + else + t= { tostring(t) } end end return setmetatable(t or { },mt_x) diff --git a/tex/context/base/mkiv/lpdf-nod.lua b/tex/context/base/mkiv/lpdf-nod.lua index 3dd5a6648..34cce9150 100644 --- a/tex/context/base/mkiv/lpdf-nod.lua +++ b/tex/context/base/mkiv/lpdf-nod.lua @@ -24,14 +24,15 @@ local new_node = nuts.new local nodepool = nuts.pool local register = nodepool.register -local pdfliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfliteral,"mode",1) -local pdfsave = register(new_node("whatsit", whatsitcodes.pdfsave)) -local pdfrestore = register(new_node("whatsit", whatsitcodes.pdfrestore)) -local pdfsetmatrix = register(new_node("whatsit", whatsitcodes.pdfsetmatrix)) ------ pdfdest = register(new_node("whatsit", whatsitcodes.pdfdest)) setfield(pdfdest,"named_id",1) -- xyz_zoom untouched ------ pdfannot = register(new_node("whatsit", whatsitcodes.pdfannot)) +local pdfpageliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfpageliteral, "mode",0) +local pdfdirectliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfdirectliteral,"mode",1) +local pdfsave = register(new_node("whatsit", whatsitcodes.pdfsave)) +local pdfrestore = register(new_node("whatsit", whatsitcodes.pdfrestore)) +local pdfsetmatrix = register(new_node("whatsit", whatsitcodes.pdfsetmatrix)) +----- pdfdest = register(new_node("whatsit", whatsitcodes.pdfdest)) setfield(pdfdest,"named_id",1) -- xyz_zoom untouched +----- pdfannot = register(new_node("whatsit", whatsitcodes.pdfannot)) -local variables = interfaces.variables +local variables = interfaces.variables local views = { -- beware, we do support the pdf keys but this is *not* official xyz = 0, [variables.standard] = 0, @@ -44,19 +45,24 @@ local views = { -- beware, we do support the pdf keys but this is *not* official fitr = 7, } -function nodepool.pdfliteral(str) - local t = copy_node(pdfliteral) +local function pdfpage(str) + local t = copy_node(pdfpageliteral) setfield(t,"data",str) return t end -function nodepool.pdfdirect(str) - local t = copy_node(pdfliteral) +local function pdfdirect(str) + local t = copy_node(pdfdirectliteral) setfield(t,"data",str) - setfield(t,"mode",1) return t end +nodepool.pdfpage = pdfpage +nodepool.pdfpageliteral = pdfpage +nodepool.pdfdirect = pdfdirect +nodepool.pdfdirectliteral = pdfdirect +nodepool.pdfliteral = pdfdirect + function nodepool.pdfsave() return copy_node(pdfsave) end diff --git a/tex/context/base/mkiv/math-ali.mkiv b/tex/context/base/mkiv/math-ali.mkiv index cd47b95c0..756939eec 100644 --- a/tex/context/base/mkiv/math-ali.mkiv +++ b/tex/context/base/mkiv/math-ali.mkiv @@ -27,24 +27,24 @@ % n>1 ### needed, strange # interaction in recurse -\newtoks\c_math_align_a -\newtoks\c_math_align_b -\newtoks\c_math_align_c +\newtoks\t_math_align_a +\newtoks\t_math_align_b +\newtoks\t_math_align_c \def\displayopenupvalue{.25\bodyfontsize} \def\math_build_eqalign {\scratchtoks\emptytoks \dorecurse{\mathalignmentparameter\c!m}\math_build_eqalign_step - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_c}}} + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_c}}} \unexpanded\def\math_build_eqalign_step % make sure no expansion in tracing {\ifnum\recurselevel>\plusone \scratchtoks\expandafter{\the\scratchtoks\tabskip\mathalignmentparameter\c!distance\aligntab\tabskip\zeropoint}% \fi - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_a}}% + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_a}}% \dorecurse{\numexpr\mathalignmentparameter\c!n-\plusone\relax} - {\normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_b}}}} + {\normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_b}}}} \def\math_math_in_eqalign#1% {\startforceddisplaymath @@ -83,15 +83,80 @@ % use zeroskipplusfill +% \def\math_prepare_r_eqalign_no +% {\t_math_align_a{\strut\math_first_in_eqalign\hfil\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% +% \t_math_align_b{\aligntab\math_next_in_eqalign\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% +% \ifnum\mathraggedstatus=\plusone +% \t_math_align_c{\hfil\aligntab\span\math_text_in_eqalign{\alignmark\alignmark}\tabskip\zeropoint}% +% \else\ifnum\mathraggedstatus=\plusthree +% \t_math_align_c{\hfil\tabskip\zeropoint\s!plus 1\s!fill\aligntab\span\math_text_in_eqalign{\alignmark\alignmark}\tabskip\zeropoint}% +% \else +% \t_math_align_c{\hfil\tabskip\centering\aligntab\llap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\zeropoint}% +% \fi\fi +% \global\mathnumberstatus\zerocount +% \math_build_eqalign +% \the\mathdisplayaligntweaks +% \tabskip\centering} + +% \def\math_prepare_l_eqalign_no % \checkeddisplaymath +% {\t_math_align_a{\strut\math_first_in_eqalign\hfil\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% +% \t_math_align_b{\aligntab\math_next_in_eqalign\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% +% % problem: number is handled after rest and so ends up in the margin +% \ifnum\mathraggedstatus=\plusone +% \t_math_align_c{\hfil\aligntab\kern-\displaywidth\rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% +% \else\ifnum\mathraggedstatus=\plusthree +% \t_math_align_c{\hfil\tabskip\zeropoint\s!plus 1\s!fill\aligntab\kern-\displaywidth\span\math_rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% +% \else +% \t_math_align_c{\hfil\tabskip\centering\aligntab\kern-\displaywidth\rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% +% \fi\fi +% \global\mathnumberstatus\zerocount +% \math_build_eqalign +% \the\mathdisplayaligntweaks +% \tabskip\centering} + \def\math_prepare_r_eqalign_no - {\c_math_align_a{\strut\math_first_in_eqalign\hfil\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% - \c_math_align_b{\aligntab\math_next_in_eqalign\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% + {\t_math_align_a + {\strut + \tabskip\zeropoint + \alignmark\alignmark % for picking up the number + \aligntab + \math_first_in_eqalign + \hfil + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \t_math_align_b + {\aligntab + \math_next_in_eqalign + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% \ifnum\mathraggedstatus=\plusone - \c_math_align_c{\hfil\aligntab\span\math_text_in_eqalign{\alignmark\alignmark}\tabskip\zeropoint}% + \t_math_align_c + {\hfil + \aligntab + \span + \math_text_in_eqalign{\alignmark\alignmark}% + \tabskip\zeropoint}% \else\ifnum\mathraggedstatus=\plusthree - \c_math_align_c{\hfil\tabskip\zeropoint\s!plus 1\s!fill\aligntab\span\math_text_in_eqalign{\alignmark\alignmark}\tabskip\zeropoint}% + \t_math_align_c + {\hfil + \tabskip\zeropoint\s!plus 1\s!fill + \aligntab + \span + \math_text_in_eqalign{\alignmark\alignmark}% + \tabskip\zeropoint}% \else - \c_math_align_c{\hfil\tabskip\centering\aligntab\llap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\zeropoint}% + \t_math_align_c + {\hfil + \tabskip\centering + \aligntab + \llap{\span\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\zeropoint}% \fi\fi \global\mathnumberstatus\zerocount \math_build_eqalign @@ -99,15 +164,50 @@ \tabskip\centering} \def\math_prepare_l_eqalign_no % \checkeddisplaymath - {\c_math_align_a{\strut\math_first_in_eqalign\hfil\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% - \c_math_align_b{\aligntab\math_next_in_eqalign\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% - % problem: number is handled after rest and so ends up in the margin + {\t_math_align_a + {\strut + \tabskip\zeropoint + \alignmark\alignmark % for picking up the number + \aligntab + \math_first_in_eqalign + \hfil + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \t_math_align_b + {\aligntab + \math_next_in_eqalign + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% \ifnum\mathraggedstatus=\plusone - \c_math_align_c{\hfil\aligntab\kern-\displaywidth\rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% + \t_math_align_c + {\hfil + \aligntab + \kern-\displaywidth + \rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% \else\ifnum\mathraggedstatus=\plusthree - \c_math_align_c{\hfil\tabskip\zeropoint\s!plus 1\s!fill\aligntab\kern-\displaywidth\span\math_rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% + \t_math_align_c + {\hfil + \tabskip\zeropoint\s!plus 1\s!fill + \aligntab + \kern-\displaywidth + \span + \math_rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% \else - \c_math_align_c{\hfil\tabskip\centering\aligntab\kern-\displaywidth\rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% + \t_math_align_c + {\hfil + \tabskip\centering + \aligntab + \kern-\displaywidth + \rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% \fi\fi \global\mathnumberstatus\zerocount \math_build_eqalign @@ -176,26 +276,48 @@ \newtoks \everymathalignment -\def\math_alignment_NR_indeed[#1][#2]% - {\strc_formulas_place_number_nested{#1}{#2}% to be tagged (better an attribute) +% \def\math_alignment_NC_first +% {\glet\math_alignment_NC\math_alignment_NC_rest} +% +% \def\math_alignment_NR +% {\aligntab +% \dostoptagged % finish cell +% \dodoubleempty\math_alignment_NR_indeed} % use xx from tabulate +% +% \def\math_alignment_NR_indeed[#1][#2]% +% {\strc_formulas_place_number_nested{#1}{#2}% to be tagged (better an attribute) +% \crcr +% \dostoptagged % finish row +% \noalign{\glet\math_alignment_NC\math_alignment_NC_first}} % noalign used for change state, conditional does not work here + +% \def\math_alignment_NC_first#1\NR +% {\glet\math_alignment_NC\math_alignment_NC_rest +% \dotripleempty\math_alignment_NC_first_indeed[{#1}]} + +% \def\math_alignment_NC_first_indeed[#1][#2][#3]% +% {\strc_formulas_place_number_nested{#2}{#3}\aligntab#1\NR} + +\def\math_alignment_NC_first#1\NR + {\glet\math_alignment_NC\math_alignment_NC_rest + \scratchtoks{\aligntab#1\NR}% + \dodoubleempty\math_alignment_NC_first_indeed} + +\def\math_alignment_NC_first_indeed[#1][#2]% + {\strc_formulas_place_number_nested{#1}{#2}\the\scratchtoks} + +\def\math_alignment_NR + {\aligntab + \dostoptagged % finish cell \crcr \dostoptagged % finish row \noalign{\glet\math_alignment_NC\math_alignment_NC_first}} % noalign used for change state, conditional does not work here -\def\math_alignment_NC_first - {\glet\math_alignment_NC\math_alignment_NC_rest} - \def\math_alignment_NC_rest {\aligntab} \def\math_alignment_EQ {\NC=} -\def\math_alignment_NR - {\aligntab - \dostoptagged % finish cell - \dodoubleempty\math_alignment_NR_indeed} % use xx from tabulate - \appendtoks \glet\math_alignment_NC\math_alignment_NC_first \unexpanded\def\NC{\math_alignment_NC}% messy, due to lookahead (we cannot use a flag) @@ -316,9 +438,10 @@ \dostarttagged\t!mathtablecell\empty} \def\math_left_of_equalign - {\edef\p_location{\formulaparameter\c!location}% - \ifx\p_location\v!left - \box\b_strc_formulas_number + {\ifcase\wd\b_strc_formulas_number\else + \ifcase\c_strc_math_number_location\or + \box\b_strc_formulas_number + \fi \fi \ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname \ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi @@ -328,9 +451,10 @@ {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname \ifcase\lastnamedcs \or \hfill \or \relax \or \hfill \fi \fi - \edef\p_location{\formulaparameter\c!location}% - \ifx\p_location\v!left\else - \box\b_strc_formulas_number + \ifcase\wd\b_strc_formulas_number\else + \ifcase\c_strc_math_number_location\or\or + \box\b_strc_formulas_number + \fi \fi} \def\math_eqalign_set_column#1% we could just add to the preamble (as with other alignments) @@ -699,19 +823,19 @@ \definemathmatrix[\v!mathmatrix] \def\math_matrix_prepare - {\c_math_align_a{\strut\math_first_in_eqalign\math_left_of_equalign\span + {\t_math_align_a{\strut\math_first_in_eqalign\math_left_of_equalign\span \math_text_in_eqalign{\mathmatrixparameter\c!style\alignmark\alignmark}\math_right_of_eqalign}% - \c_math_align_b{\aligntab\hskip\mathmatrixparameter\c!distance + \t_math_align_b{\aligntab\hskip\mathmatrixparameter\c!distance \math_next_in_eqalign\math_left_of_equalign\span \math_text_in_eqalign{\mathmatrixparameter\c!style\alignmark\alignmark}\math_right_of_eqalign}% - \c_math_align_c{\aligntab\aligntab\hskip\mathmatrixparameter\c!distance + \t_math_align_c{\aligntab\aligntab\hskip\mathmatrixparameter\c!distance \math_left_of_equalign\span \math_text_in_eqalign{\mathmatrixparameter\c!style\alignmark\alignmark}\math_right_of_eqalign}% \scratchtoks\emptytoks - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_a}}% + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_a}}% \dorecurse{\numexpr\scratchcounter-\plusone\relax} - {\normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_b}}}% - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_c}}% + {\normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_b}}}% + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_c}}% \halign \expandafter \bgroup\the\scratchtoks \crcr} \unexpanded\def\math_matrix_NC_indeed @@ -1033,9 +1157,8 @@ %D The following code comes from \type {math-str.mkiv}. %D -%D Here we implement a basic math alignment mechanism. Numbers -%D are also handled. The macros \type {\startinnermath} and -%D \type {\stopinnermath} can be overloaded in specialized +%D Here we implement a basic math alignment mechanism. Numbers are also handled. The macros +%D \type {\startinnermath} and \type {\stopinnermath} can be overloaded in specialized %D modules. \installcorenamespace{mathinnerstart} @@ -1332,7 +1455,7 @@ \useformulacolorparameter\c!color \c_strc_math_number_location\ifx\p_location\v!left\plusone\else\ifx\p_location\v!right\plustwo\else\zerocount\fi\fi % - \strc_formulas_place_number + %\strc_formulas_place_number % not here as we can have inner alignment numbers \dontcomplain \setbox\b_strc_math_display\math_hbox\bgroup % \checkeddisplaymath \mathinnerstrut diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index 89ffd1ff5..4876a862f 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -495,7 +495,7 @@ function nutpool.noad() return copy_nut(noad) end -function nutpool.hlist(list,width,height,depth,shift) +local function new_hlist(list,width,height,depth,shift) local n = copy_nut(hlist) if list then setlist(n,list) @@ -515,7 +515,7 @@ function nutpool.hlist(list,width,height,depth,shift) return n end -function nutpool.vlist(list,width,height,depth,shift) +local function new_vlist(list,width,height,depth,shift) local n = copy_nut(vlist) if list then setlist(n,list) @@ -535,6 +535,17 @@ function nutpool.vlist(list,width,height,depth,shift) return n end +nutpool.hlist = new_hlist +nutpool.vlist = new_vlist + +function nodepool.hlist(list,width,height,depth,shift) + return tonode(new_hlist(list and tonut(list),width,height,depth,shift)) +end + +function nodepool.vlist(list,width,height,depth,shift) + return tonode(new_vlist(list and tonut(list),width,height,depth,shift)) +end + -- local num = userids["my id"] -- local str = userids[num] diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 8c60658b7..dbd30fb33 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 530e006b4..8e6aa3c03 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv index 8bf04e511..dd747c6ea 100644 --- a/tex/context/base/mkiv/strc-mat.mkiv +++ b/tex/context/base/mkiv/strc-mat.mkiv @@ -1035,7 +1035,7 @@ \unexpanded\def\strc_formulas_number_again[#1]% {\def\currentformulareference{#1}% - %\glet\strc_formulas_place_number\relax + \glet\strc_formulas_place_number\relax \strc_formulas_place_number_in_box} \unexpanded\def\placeformula diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 5ba2f6509..25ceec4f1 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index 2f0e5163d..3b9d5b706 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index e33f42574..eacdb1b4e 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 07/06/16 10:01:19 +-- merge date : 07/07/16 23:58:34 do -- begin closure to overcome local limits and interference @@ -16263,7 +16263,6 @@ if not modules then modules={} end modules ['font-otj']={ if not nodes.properties then return end local next,rawget=next,rawget local fastcopy=table.fastcopy -local floor=math.floor local registertracker=trackers.register local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) @@ -17451,6 +17450,37 @@ function nodes.injections.setspacekerns(font,sequence) triggers={ [font]=sequence } end end +local getthreshold +if context then + local threshold=1 + local parameters=fonts.hashes.parameters + directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) + getthreshold=function(font) + local p=parameters[font] + local f=p.factor + local s=p.spacing + local t=threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +else + injections.threshold=0 + getthreshold=function(font) + local p=fontdata[font].parameters + local f=p.factor + local s=p.spacing + local t=injections.threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +end +injections.getthreshold=getthreshold +function injections.isspace(n,threshold) + if getid(n)==glue_code then + local w=getfield(n,"width") + if threshold and w>threshold then + return 32 + end + end +end local function injectspaces(head) if not triggers then return head,false @@ -17466,10 +17496,9 @@ local function injectspaces(head) local function updatefont(font,trig) leftkerns=trig.left rightkerns=trig.right - local par=fontdata[font].parameters - factor=par.factor - threshold=floor(par.spacing.width-2) lastfont=font + threshold, + factor=getthreshold(font) end for n in traverse_id(glue_code,tonut(head)) do local prev,next=getboth(n) @@ -17488,7 +17517,7 @@ local function injectspaces(head) end end if prevchar then - local font=getfont(next) + local font=getfont(prev) local trig=triggers[font] if trig then if lastfont~=font then @@ -17501,7 +17530,7 @@ local function injectspaces(head) end if leftkern then local old=getfield(n,"width") - if old>=threshold then + if old>threshold then if rightkern then local new=old+(leftkern+rightkern)*factor if trace_spaces then @@ -17520,7 +17549,7 @@ local function injectspaces(head) leftkern=false elseif rightkern then local old=getfield(n,"width") - if old>=threshold then + if old>threshold then local new=old+rightkern*factor if trace_spaces then report_spaces("[%p -> %p] %C",nextchar,old,new) @@ -17971,11 +18000,7 @@ local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kern local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end) local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) -local quit_on_no_replacement=true -local zwnjruns=true local optimizekerns=true -registerdirective("otf.zwnjruns",function(v) zwnjruns=v end) -registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement=value 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") @@ -18072,14 +18097,8 @@ local notmatchpre={} local notmatchpost={} local notmatchreplace={} local handlers={} -local function isspace(n) - if getid(n)==glue_code then - local w=getfield(n,"width") - if w>=threshold then - return 32 - end - end -end +local isspace=injections.isspace +local getthreshold=injections.getthreshold local checkstep=(nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end local registerstep=(nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end local registermessage=(nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end @@ -18357,7 +18376,7 @@ end end return head,base end -local function multiple_glyphs(head,start,multiple,ignoremarks) +local function multiple_glyphs(head,start,multiple,ignoremarks,what) local nofmultiples=#multiple if nofmultiples>0 then resetinjection(start) @@ -18371,6 +18390,17 @@ local function multiple_glyphs(head,start,multiple,ignoremarks) insert_node_after(head,start,n) start=n end + if what==true then + elseif what>1 then + local m=multiple[nofmultiples] + for i=2,what do + local n=copy_node(start) + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start=n + end + end end return head,start,true else @@ -18441,7 +18471,7 @@ function handlers.gsub_multiple(head,start,dataset,sequence,multiple) if trace_multiples then logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) end - return multiple_glyphs(head,start,multiple,sequence.flags[1]) + return multiple_glyphs(head,start,multiple,sequence.flags[1],dataset[1]) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) local current=getnext(start) @@ -18896,7 +18926,7 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup if trace_multiples then logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) end - return multiple_glyphs(head,start,replacement,sequence.flags[1]) + return multiple_glyphs(head,start,replacement,sequence.flags[1],dataset[1]) end return head,start,false end @@ -18908,7 +18938,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku end local kind=dataset[4] local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what + local value=what==true and tfmdata.shared.features[kind] or what local current=start while current do local currentchar=ischar(current) @@ -19849,16 +19879,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end end prev=getprev(prev) - elseif seq[n][32] then + elseif seq[n][32] and isspace(prev,threshold) then n=n-1 prev=getprev(prev) else match=false break end - elseif seq[n][32] then - n=n-1 - prev=getprev(prev) else match=false break @@ -19972,15 +19999,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else end current=getnext(current) - elseif seq[n][32] then + elseif seq[n][32] and isspace(current,threshold) then n=n+1 + current=getnext(current) else match=false break end - elseif seq[n][32] then - n=n+1 - current=getnext(current) else match=false break @@ -20075,7 +20100,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if replacements then head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode) else - done=quit_on_no_replacement + done=true if trace_contexts then logprocess("%s: skipping match",cref(dataset,sequence)) end @@ -20224,10 +20249,10 @@ local function kernrun(disc,k_run,font,attr,...) break end end - if prev and (pre or replace) and not ischar(prev,font) then + if prev and not ischar(prev,font) then prev=false end - if next and (post or replace) and not ischar(next,font) then + if next and not ischar(next,font) then next=false end if pre then @@ -20653,8 +20678,8 @@ local function featuresprocessor(head,font,attr) descriptions=tfmdata.descriptions characters=tfmdata.characters marks=tfmdata.resources.marks - factor=tfmdata.parameters.factor - threshold=tfmdata.parameters.spacing.width or 65536*10 + threshold, + factor=getthreshold(font) elseif currentfont~=font then report_warning("nested call with a different font, level %s, quitting",nesting) nesting=nesting-1 @@ -20682,15 +20707,12 @@ local function featuresprocessor(head,font,attr) local steps=sequence.steps local nofsteps=sequence.nofsteps if not steps then - local h,d,ok=handler(head,start,dataset,sequence,nil,nil,nil,0,font,attr) + local h,d,ok=handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr) if ok then success=true if h then head=h end - if d then - start=d - end end elseif typ=="gsub_reversecontextchain" then local start=find_node_tail(head) @@ -20886,7 +20908,7 @@ if fontfeatures then end else function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) - local shared=identifiers[font].shared + local shared=fontdata[font].shared local features=shared and shared.features local enabled=features and features.spacekern==true and features.kern==true if enabled then -- cgit v1.2.3