From dbde719e7593a47d67acd0fdc0aa48a0ea55c6e5 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 17 Apr 2014 12:39:00 +0200 Subject: beta 2014.04.17 12:39 --- metapost/context/base/mp-mlib.mpiv | 2 + tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4064 -> 4066 bytes tex/context/base/context.mkiv | 2 +- tex/context/base/font-chk.lua | 49 +++ tex/context/base/font-chk.mkiv | 9 + tex/context/base/lpdf-col.lua | 7 +- tex/context/base/mlib-run.lua | 22 +- tex/context/base/node-ini.mkiv | 1 + tex/context/base/node-ppt.lua | 476 +++++++++++++++++++++ tex/context/base/spac-ver.mkiv | 8 + tex/context/base/status-files.pdf | Bin 24615 -> 24604 bytes tex/context/base/status-lua.pdf | Bin 241438 -> 241622 bytes tex/context/base/status-mkiv.lua | 11 + tex/context/base/task-ini.lua | 4 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 16 files changed, 584 insertions(+), 11 deletions(-) create mode 100644 tex/context/base/node-ppt.lua diff --git a/metapost/context/base/mp-mlib.mpiv b/metapost/context/base/mp-mlib.mpiv index 12840b28e..252cd5fd0 100644 --- a/metapost/context/base/mp-mlib.mpiv +++ b/metapost/context/base/mp-mlib.mpiv @@ -366,6 +366,8 @@ vardef thetextext@#(expr p,z) = % interim labeloffset := textextoffset ; if string p : thetextext@#(rawtextext(p),z) + elseif numeric p : + thetextext@#(rawtextext(decimal p),z) else : p if (mfun_labtype@# >= 10) : diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 845147ccf..049fffa20 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.04.15 09:51} +\newcontextversion{2014.04.17 12:39} %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 index cce0f4d2c..81f2ce10a 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/context.mkiv b/tex/context/base/context.mkiv index f75fc118c..d1591005c 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.04.15 09:51} +\edef\contextversion{2014.04.17 12:39} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua index 178ca71be..9d612adc1 100644 --- a/tex/context/base/font-chk.lua +++ b/tex/context/base/font-chk.lua @@ -9,6 +9,8 @@ if not modules then modules = { } end modules ['font-chk'] = { -- possible optimization: delayed initialization of vectors -- move to the nodes namespace +local next = next + local formatters = string.formatters local bpfactor = number.dimenfactors.bp local fastcopy = table.fastcopy @@ -32,6 +34,8 @@ local getprivatenode = helpers.getprivatenode local otffeatures = fonts.constructors.newfeatures("otf") local registerotffeature = otffeatures.register +local afmfeatures = fonts.constructors.newfeatures("afm") +local registerafmfeature = afmfeatures.register local is_character = characters.is_character local chardata = characters.data @@ -403,3 +407,48 @@ local function expandglyph(characters,index,done) end helpers.expandglyph = expandglyph + +-- should not be needed as we add .notdef in the engine + +local dummyzero = { + -- width = 0, + -- height = 0, + -- depth = 0, + -- commands = { { "special", "pdf: q Q" } }, + commands = { { "special", "" } }, +} + +local function adddummysymbols(tfmdata,...) + local characters = tfmdata.characters + if not characters[0] then + characters[0] = dummyzero + end + -- temp test: + if not characters[1] then + characters[1] = dummyzero + end +end + +registerotffeature { + name = "dummies", + description = "dummy symbols", + default = true, + manipulators = { + base = adddummysymbols, + node = adddummysymbols, + } +} + +registerafmfeature { + name = "dummies", + description = "dummy symbols", + default = true, + manipulators = { + base = adddummysymbols, + node = adddummysymbols, + } +} + +-- callback.register("char_exists",function(f,c) -- to slow anyway as called often so we should flag in tfmdata +-- return true +-- end) diff --git a/tex/context/base/font-chk.mkiv b/tex/context/base/font-chk.mkiv index d436388de..4572041c2 100644 --- a/tex/context/base/font-chk.mkiv +++ b/tex/context/base/font-chk.mkiv @@ -15,6 +15,15 @@ \registerctxluafile{font-chk}{1.001} +\tracinglostchars\zerocount + +% Use this instead: +% +% \definefontfeature[default][default][missing=yes] +% \enabletrackers[fonts.missing=replace] +% +% or better: + \unexpanded\def\checkcharactersinfont {\ctxcommand{checkcharactersinfont()}} \unexpanded\def\removemissingcharacters {\ctxcommand{removemissingcharacters()}} \unexpanded\def\replacemissingcharacters{\ctxcommand{replacemissingcharacters()}} diff --git a/tex/context/base/lpdf-col.lua b/tex/context/base/lpdf-col.lua index b2d508611..9e483f9b5 100644 --- a/tex/context/base/lpdf-col.lua +++ b/tex/context/base/lpdf-col.lua @@ -32,6 +32,7 @@ local pdfarray = lpdf.array local pdfreference = lpdf.reference local pdfverbose = lpdf.verbose local pdfflushobject = lpdf.flushobject +local pdfdelayedobject = lpdf.delayedobject local pdfflushstreamobject = lpdf.flushstreamobject local pdfshareobjectreference = lpdf.shareobjectreference @@ -82,11 +83,13 @@ lpdf.transparencygroups = transparencygroups table.setmetatableindex(transparencygroups, function(transparencygroups,colormodel) local cs = colorspaceconstants[colormodel] if cs then - local g = pdfreference(pdfflushobject(pdfdictionary { + local d = pdfdictionary { S = c_transparency, CS = cs, I = true, - })) + } + -- local g = pdfreference(pdfflushobject(tostring(d))) + local g = pdfreference(pdfdelayedobject(tostring(d))) transparencygroups[colormodel] = g return g else diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua index 19af4fbdd..2a34f44d5 100644 --- a/tex/context/base/mlib-run.lua +++ b/tex/context/base/mlib-run.lua @@ -300,14 +300,23 @@ else default = "scaled", } + function metapost.runscript(code) + return code + end + + function metapost.scripterror(str) + report_metapost("script error: %s",str) + end + function metapost.load(name,method) starttiming(mplib) method = method and methods[method] or "scaled" local mpx = mplib.new { - ini_version = true, - find_file = finder, - math_mode = method, - + ini_version = true, + find_file = finder, + math_mode = method, + run_script = metapost.runscript, + script_error = metapost.scripterror, } report_metapost("initializing number mode %a",method) local result @@ -404,6 +413,10 @@ local mp_inp, mp_log, mp_tag = { }, { }, 0 -- key/values +if not metapost.initializescriptrunner then + function metapost.initializescriptrunner() end +end + function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) local converted, result = false, { } if type(mpx) == "string" then @@ -411,6 +424,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, end if mpx and data then starttiming(metapost) + metapost.initializescriptrunner(mpx,trialrun) if trace_graphics then if not mp_inp[mpx] then mp_tag = mp_tag + 1 diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv index 142f0d7ba..5fc519069 100644 --- a/tex/context/base/node-ini.mkiv +++ b/tex/context/base/node-ini.mkiv @@ -21,6 +21,7 @@ \registerctxluafile{node-met}{1.001} \registerctxluafile{node-nut}{1.001} \registerctxluafile{node-res}{1.001} +\registerctxluafile{node-ppt}{1.001} % experimental \registerctxluafile{node-dir}{1.001} \registerctxluafile{node-aux}{1.001} \registerctxluafile{node-tst}{1.001} diff --git a/tex/context/base/node-ppt.lua b/tex/context/base/node-ppt.lua new file mode 100644 index 000000000..c8cba8566 --- /dev/null +++ b/tex/context/base/node-ppt.lua @@ -0,0 +1,476 @@ +if not modules then modules = { } end modules ['node-ppt'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is all very exeperimental and likely to change. + +local next, type, unpack, load = next, type, table.unpack, load + +local serialize = table.serialize +local formatters = string.formatters + +local report = logs.reporter("properties") +local report_setting = logs.reporter("properties","setting") +local trace_setting = false trackers.register("properties.setting", function(v) trace_setting = v end) + +-- report("using experimental properties") + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode +local getid = nuts.getid +local getnext = nuts.getnext +local getprev = nuts.getprev +local getsubtype = nuts.getsubtype +local getfield = nuts.getfield +local setfield = nuts.setfield +local getlist = nuts.getlist +local flushnode = nuts.flush +local removenode = nuts.remove +local traverse = nuts.traverse +local traverse_id = nuts.traverse_id + +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes + +local whatsit_code = nodecodes.whatsit +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local userdefined_code = whatsitcodes.userdefined +local localpar_code = whatsitcodes.localpar + +local nodepool = nodes.pool +local new_usernumber = nodepool.usernumber + +local nutpool = nuts.pool +local nut_usernumber = nutpool.usernumber + +local variables = interfaces.variables +local v_before = variables.before +local v_after = variables.after +local v_here = variables.here + +local cache = { } +local nofslots = 0 +local property_id = nodepool.userids["property"] + +local properties = nodes.properties if not properties then return end -- temp +local propertydata = properties.data + +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming + +if not propertydata then + return +end + +-- management + +local function register(where,data,...) + if not data then + data = where + where = v_after + end + if data then + local data = { where, data, ... } + nofslots = nofslots + 1 + if nofslots > 1 then + cache[nofslots] = data + else + -- report("restarting attacher") + cache = { data } -- also forces collection + end + return new_usernumber(property_id,nofslots) + end +end + +local writenode = node.write +local flushnode = context.flushnode + +function commands.deferredproperty(...) +-- context(register(...)) + flushnode(register(...)) +end + + +function commands.immediateproperty(...) + writenode(register(...)) +end + +commands.attachproperty = commands.deferredproperty + +local actions = { } properties.actions = actions + +table.setmetatableindex(actions,function(t,k) + report("unknown property action %a",k) + local v = function() end + return v +end) + +local f_delayed = formatters["return function(target,head,where,propdata,parent) %s end"] +local f_immediate = formatters["return function(target,head,where,propdata) %s end"] + +local nofdelayed = 0 -- better is to keep track of it per page ... we can have deleted nodes with properties + +function actions.delayed(target,head,where,propdata,code,...) -- this one is used at the tex end +-- local kind = type(code) +-- if kind == "string" then +-- code, err = load(f_delayed(code)) +-- if code then +-- code = code() +-- end +-- elseif kind ~= "function" then +-- code = nil +-- end + if code then + local delayed = propdata.delayed + if delayed then + delayed[#delayed+1] = { where, code, ... } + else + propdata.delayed = { { where, code, ... } } + nofdelayed = nofdelayed + 1 + end + end +end + +function actions.fdelayed(target,head,where,propdata,code,...) -- this one is used at the tex end +-- local kind = type(code) +-- if kind == "string" then +-- code, err = load(f_delayed(code)) +-- if code then +-- code = code() +-- end +-- elseif kind ~= "function" then +-- code = nil +-- end + if code then + local delayed = propdata.delayed + if delayed then + delayed[#delayed+1] = { false, code, ... } + else + propdata.delayed = { { false, code, ... } } + nofdelayed = nofdelayed + 1 + end + end +end + +function actions.immediate(target,head,where,propdata,code,...) -- this one is used at the tex end + local kind = type(code) + if kind == "string" then + local f = f_immediate(code) + local okay, err = load(f) + if okay then + local h = okay()(target,head,where,propdata,...) + if h and h ~= head then + return h + end + end + elseif kind == "function" then + local h = code()(target,head,where,propdata,...) + if h and h ~= head then + return h + end + end +end + +-- another experiment (a table or function closure are equally efficient); a function +-- is easier when we want to experiment with different (compatible) implementations + +-- function nodes.nuts.pool.deferredfunction(...) +-- nofdelayed = nofdelayed + 1 +-- local n = nut_usernumber(property_id,0) +-- propertydata[n] = { deferred = { ... } } +-- return n +-- end + +-- function nodes.nuts.pool.deferredfunction(f) +-- nofdelayed = nofdelayed + 1 +-- local n = nut_usernumber(property_id,0) +-- propertydata[n] = { deferred = f } +-- return n +-- end + +-- maybe actions will get parent too + +local function delayed(head,parent) -- direct based + for target in traverse(head) do + local p = propertydata[target] + if p then + -- local deferred = p.deferred -- kind of late lua (but too soon as we have no access to pdf.h/v) + -- if deferred then + -- -- if #deferred > 0 then + -- -- deferred[1](unpack(deferred,2)) + -- -- else + -- -- deferred[1]() + -- -- end + -- deferred() + -- p.deferred = false + -- if nofdelayed == 1 then + -- nofdelayed = 0 + -- return head + -- else + -- nofdelayed = nofdelayed - 1 + -- end + -- else + local delayed = p.delayed + if delayed then + for i=1,#delayed do + local d = delayed[i] + local code = d[2] + local kind = type(code) + if kind == "string" then + code, err = load(f_delayed(code)) + if code then + code = code() + end + end + local where = d[1] + if where then + local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent + if h and h ~= head then + head = h + end + else + code(unpack(d,3)) + end + end + p.delayed = nil + if nofdelayed == 1 then + nofdelayed = 0 + return head + else + nofdelayed = nofdelayed - 1 + end + end + -- end + end + local id = getid(target) + if id == hlist_code or id == vlist_code then + local list = getlist(target) + if list then + local done = delayed(list,parent) + if done then + setfield(target,"list",done) + end + if nofdelayed == 0 then + return head + end + end + else + -- maybe also some more lists? but we will only use this for some + -- special cases .. who knows + end + end + return head +end + +function properties.delayed(head) -- + if nofdelayed > 0 then + -- if next(propertydata) then + starttiming(properties) + head = delayed(tonut(head)) + stoptiming(properties) + return tonode(head), true -- done in shipout anyway + -- else + -- delayed = 0 + -- end + end + return head, false +end + +-- more explicit ones too + +local anchored = { + [v_before] = function(n) + while n do + n = getprev(n) + if getid(n) == whatsit_code and getsubtype(n) == user_code and getfield(n,"user_id") == property_id then + -- continue + else + return n + end + end + end, + [v_after] = function(n) + while n do + n = getnext(n) + if getid(n) == whatsit_code then + local subtype = getsubtype(n) + if (subtype == userdefined_code and getfield(n,"user_id") == property_id) then + -- continue + elseif subtype == localpar_code then + -- continue .. can't happen anyway as we cannot write + else + return n + end + else + return n + end + end + end, + [v_here] = function(n) + -- todo + end, +} + +table.setmetatableindex(anchored,function(t,k) + v = anchored[v_after] + t[k] = v + return v +end) + +function properties.attach(head) + + if nofslots <= 0 then + return head, false + end + + local done = false + local last = nil + local head = tonut(head) + + starttiming(properties) + + for source in traverse_id(whatsit_code,head) do + if getsubtype(source) == userdefined_code then + if last then + removenode(head,last,true) + last = nil + end + if getfield(source,"user_id") == property_id then + local slot = getfield(source,"value") + local data = cache[slot] + if data then + cache[slot] = nil + local where = data[1] + local target = anchored[where](source) + if target then + local first = data[2] + local method = type(first) + local p_target = propertydata[target] + local p_source = propertydata[source] + if p_target then + if p_source then + for k, v in next, p_source do + p_target[k] = v + end + end + if method == "table" then + for k, v in next, first do + p_target[k] = v + end + elseif method == "function" then + first(target,head,where,p_target,unpack(data,3)) + elseif method == "string" then + actions[first](target,head,where,p_target,unpack(data,3)) + end + elseif p_source then + if method == "table" then + propertydata[target] = p_source + for k, v in next, first do + p_source[k] = v + end + elseif method == "function" then + propertydata[target] = p_source + first(target,head,where,p_source,unpack(data,3)) + elseif method == "string" then + propertydata[target] = p_source + actions[first](target,head,where,p_source,unpack(data,3)) + end + else + if method == "table" then + propertydata[target] = first + elseif method == "function" then + local t = { } + propertydata[target] = t + first(target,head,where,t,unpack(data,3)) + elseif method == "string" then + local t = { } + propertydata[target] = t + actions[first](target,head,where,t,unpack(data,3)) + end + end + if trace_setting then + report_setting("node %i, id %s, data %s", + target,nodecodes[getid(target)],serialize(propertydata[target],false)) + end + end + if nofslots == 1 then + nofslots = 0 + last = source + break + else + nofslots = nofslots - 1 + end + end + last = source + end + end + end + + if last then + removenode(head,last,true) + end + + stoptiming(properties) + + return head, done + +end + +local tasks = nodes.tasks + +-- maybe better hard coded in-place + +-- tasks.prependaction("processors","before","nodes.properties.attach") +-- tasks.appendaction("shipouts","normalizers","nodes.properties.delayed") + +statistics.register("properties processing time", function() + return statistics.elapsedseconds(properties) +end) + +-- only for development + +-- local function show(head,level,report) +-- for target in traverse(head) do +-- local p = propertydata[target] +-- if p then +-- report("level %i, node %i, id %s, data %s", +-- level,target,nodecodes[getid(target)],serialize(propertydata[target],false)) +-- end +-- local id = getid(target) +-- if id == hlist_code or id == vlist_code then +-- local list = getlist(target) +-- if list then +-- show(list,level+1,report) +-- end +-- else +-- -- maybe more lists +-- end +-- end +-- return head, false +-- end +-- +-- local report_shipout = logs.reporter("properties","shipout") +-- local report_processors = logs.reporter("properties","processors") +-- +-- function properties.showshipout (head) return tonode(show(tonut(head),1,report_shipout )), true end +-- function properties.showprocessors(head) return tonode(show(tonut(head),1,report_processors)), true end +-- +-- tasks.prependaction("shipouts","before","nodes.properties.showshipout") +-- tasks.disableaction("shipouts","nodes.properties.showshipout") +-- +-- trackers.register("properties.shipout",function(v) +-- tasks.setaction("shipouts","nodes.properties.showshipout",v) +-- end) +-- +-- tasks.appendaction ("processors","after","nodes.properties.showprocessors") +-- tasks.disableaction("processors","nodes.properties.showprocessors") +-- +-- trackers.register("properties.processors",function(v) +-- tasks.setaction("processors","nodes.properties.showprocessors",v) +-- end) diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv index 0133a6c40..0c84958be 100644 --- a/tex/context/base/spac-ver.mkiv +++ b/tex/context/base/spac-ver.mkiv @@ -546,6 +546,8 @@ \ignorespaces \let\spac_lines_stop_correction\spac_lines_stop_correction_yes} +% still not ok ... will move to the lua end ... needs a final solution + \unexpanded\def\spac_lines_stop_correction_yes {\removeunwantedspaces \egroup @@ -553,6 +555,11 @@ \blank[\v!white]% \snaptogrid\hbox{\box\scratchbox}% \else +\blank[\v!nowhite]% +\ifdim\parskip>\zeropoint + % too fuzzy otherwise +\else + % doesn't like whitespace \ifdim\d_spac_prevdepth<\maxdimen \unless\ifdim\d_spac_prevdepth<\zeropoint \ifdim\d_spac_prevdepth<\strutdp \relax @@ -566,6 +573,7 @@ \fi \fi \fi +\fi \ifdim\pagegoal<\maxdimen \blank[\v!white,\the\d_spac_lines_correction_before]% \blank[\v!white]\dotopbaselinecorrection \fi diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 2fa0a20ca..820368c2f 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 60b31aff2..bfdb99fc1 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/status-mkiv.lua b/tex/context/base/status-mkiv.lua index 339bc24f6..07e912a88 100644 --- a/tex/context/base/status-mkiv.lua +++ b/tex/context/base/status-mkiv.lua @@ -3205,6 +3205,12 @@ return { loading = "font-lib", status = "okay", }, + { + category = "lua", + filename = "font-inj", + loading = "font-lib", + status = "okay", + }, { category = "lua", filename = "font-ldr", @@ -4087,6 +4093,11 @@ return { filename = "node-pag", status = "todo", }, + { + category = "lua", + filename = "node-ppt", + status = "todo", + }, { category = "lua", filename = "node-pro", diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index ff1d36486..75ce08232 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -124,8 +124,8 @@ appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler") -- rather special (this might get hardcoded): --- prependaction("processors", "before", "nodes.properties.attach") --- appendaction ("shipouts", "normalizers", "nodes.properties.delayed") +prependaction("processors", "before", "nodes.properties.attach") -- enabled but optimized for quick abort +appendaction ("shipouts", "normalizers", "nodes.properties.delayed") -- enabled but optimized for quick abort -- speedup: only kick in when used diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index d4311b238..9608066dd 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 : 04/15/14 09:51:32 +-- merge date : 04/17/14 12:39:52 do -- begin closure to overcome local limits and interference -- cgit v1.2.3