diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mlib-pdf.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mlib-pdf.lua | 656 |
1 files changed, 329 insertions, 327 deletions
diff --git a/Master/texmf-dist/tex/context/base/mlib-pdf.lua b/Master/texmf-dist/tex/context/base/mlib-pdf.lua index 344052607a3..38b61b0ba97 100644 --- a/Master/texmf-dist/tex/context/base/mlib-pdf.lua +++ b/Master/texmf-dist/tex/context/base/mlib-pdf.lua @@ -6,172 +6,148 @@ if not modules then modules = { } end modules ['mlib-pdf'] = { license = "see context related readme files", } -local format, join = string.format, table.concat -local sprint = tex.sprint +local format, concat = string.format, table.concat +local texsprint = tex.sprint local abs, sqrt, round = math.abs, math.sqrt, math.round +local copy_node, write_node = node.copy, node.write + +local ctxcatcodes = tex.ctxcatcodes + metapost = metapost or { } metapost.multipass = false metapost.n = 0 +metapost.optimize = true -- false + +--~ Because in MKiV we always have two passes, we save the objects. When an extra +--~ mp run is done (due to for instance texts identifier in the parse pass), we +--~ get a new result table and the stored objects are forgotten. Otherwise they +--~ are reused. + +local function getobjects(result,figure,f) + if metapost.optimize then + local objects = result.objects + if not objects then + result.objects = { } + end + objects = result.objects[f] + if not objects then + objects = figure:objects() + result.objects[f] = objects + end + return objects + else + return figure:objects() + end +end -function metapost.convert(result, trialrun, flusher, multipass) +function metapost.convert(result, trialrun, flusher, multipass, askedfig) if trialrun then metapost.multipass = false - metapost.parse(result, flusher) - if multipass and not metapost.multipass then - metapost.flush(result, flusher) -- saves a run + metapost.parse(result, askedfig) + if multipass and not metapost.multipass and metapost.optimize then + metapost.flush(result, flusher, askedfig) -- saves a run else return false end else - metapost.flush(result, flusher) + metapost.flush(result, flusher, askedfig) end return true -- done end -function metapost.comment(message) - if message then - sprint(tex.ctxcatcodes,format("\\MPLIBtoPDF{\\letterpercent\\space mps graphic %s: %s}", metapost.n, message)) +metapost.flushers = { } +metapost.flushers.pdf = { } + +local savedliterals = nil + +local mpsliteral = nodes.register(node.new("whatsit",8)) + +function metapost.flush_literal(d) -- \def\MPLIBtoPDF#1{\ctxlua{metapost.flush_literal(#1)}} + if savedliterals then + local literal = copy_node(mpsliteral) + literal.data = savedliterals[d] + write_node(literal) + else + logs.report("metapost","problem flushing literal %s",d) end end -metapost.flushers = { } -metapost.flushers.pdf = { } +function metapost.flush_reset() + savedliterals = nil +end + +function metapost.flushers.pdf.comment(message) + if message then + message = format("%% mps graphic %s: %s", metapost.n, message) + if savedliterals then + local last = #savedliterals + 1 + savedliterals[last] = message + texsprint(ctxcatcodes,"\\MPLIBtoPDF{",last,"}") + else + savedliterals = { message } + texsprint(ctxcatcodes,"\\MPLIBtoPDF{1}") + end + end +end function metapost.flushers.pdf.startfigure(n,llx,lly,urx,ury,message) + savedliterals = nil metapost.n = metapost.n + 1 - sprint(tex.ctxcatcodes,format("\\startMPLIBtoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury)) - if message then metapost.comment(message) end + texsprint(ctxcatcodes,format("\\startMPLIBtoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury)) + if message then metapost.flushers.pdf.comment(message) end end function metapost.flushers.pdf.stopfigure(message) - if message then metapost.comment(message) end - sprint(tex.ctxcatcodes,"\\stopMPLIBtoPDF") + if message then metapost.flushers.pdf.comment(message) end + texsprint(ctxcatcodes,"\\stopMPLIBtoPDF") + texsprint(ctxcatcodes,"\\ctxlua{metapost.flush_reset()}") -- maybe just at the beginning end function metapost.flushers.pdf.flushfigure(pdfliterals) -- table if #pdfliterals > 0 then - sprint(tex.ctxcatcodes,"\\MPLIBtoPDF{",join(pdfliterals,"\n"),"}") + pdfliterals = concat(pdfliterals,"\n") + if savedliterals then + local last = #savedliterals + 1 + savedliterals[last] = pdfliterals + texsprint(ctxcatcodes,"\\MPLIBtoPDF{",last,"}") + else + savedliterals = { pdfliterals } + texsprint(ctxcatcodes,"\\MPLIBtoPDF{1}") + end end end function metapost.flushers.pdf.textfigure(font,size,text,width,height,depth) -- we could save the factor text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost (i have to check if this is true for mplib) - sprint(tex.ctxcatcodes,format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-number.dimenfactors.bp*depth)) + texsprint(ctxcatcodes,format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-number.dimenfactors.bp*depth)) end --- the pen calculations are taken from metapost, first converted by --- taco from c to lua, and then optimized by hans, so all errors are his - -local function pyth(a,b) - return sqrt(a*a + b*b) -- much faster than sqrt(a^2 + b^2) -end - -local aspect_bound = 10/65536 -local aspect_default = 1/65536 local bend_tolerance = 131/65536 -local eps = 0.0001 - -local function coord_range_x(h, dz) -- direction x - local zlo, zhi = 0, 0 - for i=1, #h do - local p = h[i] - local z = p.x_coord - if z < zlo then zlo = z elseif z > zhi then zhi = z end - z = p.right_x - if z < zlo then zlo = z elseif z > zhi then zhi = z end - z = p.left_x - if z < zlo then zlo = z elseif z > zhi then zhi = z end - end - return (zhi - zlo <= dz and aspect_bound) or aspect_default -end - -local function coord_range_y(h, dz) -- direction y - local zlo, zhi = 0, 0 - for i=1, #h do - local p = h[i] - local z = p.y_coord - if z < zlo then zlo = z elseif z > zhi then zhi = z end - z = p.right_y - if z < zlo then zlo = z elseif z > zhi then zhi = z end - z = p.left_y - if z < zlo then zlo = z elseif z > zhi then zhi = z end - end - return (zhi - zlo <= dz and aspect_bound) or aspect_default -end local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 local function pen_characteristics(object) - local p = object.pen[1] - local x_coord, y_coord, left_x, left_y, right_x, right_y = p.x_coord, p.y_coord, p.left_x, p.left_y, p.right_x, p.right_y - local wx, wy, width - if right_x == x_coord and left_y == y_coord then - wx = abs(left_x - x_coord) - wy = abs(right_y - y_coord) - else - wx = pyth(left_x - x_coord, right_x - x_coord) - wy = pyth(left_y - y_coord, right_y - y_coord) - end - if wy/coord_range_x(object.path, wx) >= wx/coord_range_y(object.path, wy) then - width = wy - else - width = wx - end - sx, rx, ry, sy, tx, ty = left_x, left_y, right_x, right_y, x_coord, y_coord - sx, rx, ry, sy = (sx-tx), (rx-ty), (ry-tx), (sy-ty) -- combine with previous - if width ~= 1 then - if width == 0 then - sx, sy = 1, 1 - else - rx, ry, sx, sy = rx/width, ry/width, sx/width, sy/width - end - end - -- sx rx ry sy tx ty -> 1 0 0 1 0 0 is ok, but 0 0 0 0 0 0 not - if true then - if abs(sx) < eps then sx = eps end - if abs(sy) < eps then sy = eps end + if mplib.pen_info then + local t = mplib.pen_info(object) + rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty + divider = sx*sy - rx*ry + return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width else - -- this block looks complicated but it only captures invalid transforms - -- to be checked rx vs sx and so - local det = sx/sy - ry/rx - local aspect = 4*aspect_bound + aspect_default - if abs(det) < aspect then - local s - if det >= 0 then - s, aspect = 1, aspect - det - else - s, aspect = -1, -aspect - det -- - ? - end - local absrx, absry, abssy, abssx = abs(rx), abs(ry), abs(sy), abs(sx) - if abssx + abssy >= absry + absrx then -- was yy - if abssx > abssy then - sy = sy + (aspect + s*abssx) / sx - else - sx = sx + (aspect + s*abssy) / sy - end - else - if absry > absrx then - rx = rx + (aspect + s*absry) / ry - else - ry = ry + (aspect + s*absrx) / rx - end - end - end + rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 + return false, 1 end - divider = sx*sy - rx*ry - return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), width end -local function concat(px, py) -- no tx, ty here +local function mpconcat(px, py) -- no tx, ty here / we can move this one inline if needed return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider end local function curved(ith,pth) local d = pth.left_x - ith.right_x - if abs(ith.right_x-ith.x_coord-d) <= bend_tolerance and abs(pth.x_coord-pth.left_x-d) <= bend_tolerance then + if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then d = pth.left_y - ith.right_y - if abs(ith.right_y-ith.y_coord-d) <= bend_tolerance and abs(pth.y_coord-pth.left_y-d) <= bend_tolerance then + if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then return false end end @@ -196,8 +172,12 @@ local function flushnormalpath(path, t, open) if curved(pth,one) then t[#t+1] = format("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord ) else - t[#t+1] = format("%f %f l",one.x_coord,one.y_coord) + t[#t+1] = format("%f %f l",one.x_coord,one.y_coord) end + elseif #path == 1 then + -- special case .. draw point + local one = path[1] + t[#t+1] = format("%f %f l",one.x_coord,one.y_coord) end return t end @@ -208,29 +188,35 @@ local function flushconcatpath(path, t, open) for i=1,#path do pth = path[i] if not ith then - t[#t+1] = format("%f %f m",concat(pth.x_coord,pth.y_coord)) + t[#t+1] = format("%f %f m",mpconcat(pth.x_coord,pth.y_coord)) elseif curved(ith,pth) then - local a, b = concat(ith.right_x,ith.right_y) - local c, d = concat(pth.left_x,pth.left_y) - t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord)) + local a, b = mpconcat(ith.right_x,ith.right_y) + local c, d = mpconcat(pth.left_x,pth.left_y) + t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,mpconcat(pth.x_coord,pth.y_coord)) else - t[#t+1] = format("%f %f l",concat(pth.x_coord, pth.y_coord)) + t[#t+1] = format("%f %f l",mpconcat(pth.x_coord, pth.y_coord)) end ith = pth end if not open then local one = path[1] if curved(pth,one) then - local a, b = concat(pth.right_x,pth.right_y) - local c, d = concat(one.left_x,one.left_y) - t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord)) + local a, b = mpconcat(pth.right_x,pth.right_y) + local c, d = mpconcat(one.left_x,one.left_y) + t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,mpconcat(one.x_coord, one.y_coord)) else - t[#t+1] = format("%f %f l",concat(one.x_coord,one.y_coord)) + t[#t+1] = format("%f %f l",mpconcat(one.x_coord,one.y_coord)) end + elseif #path == 1 then + -- special case .. draw point + local one = path[1] + t[#t+1] = format("%f %f l",mpconcat(one.x_coord,one.y_coord)) end return t end +metapost.flushnormalpath = flushnormalpath + metapost.specials = metapost.specials or { } -- we have two extension handlers, one for pre and postscripts, and one for colors @@ -238,7 +224,7 @@ metapost.specials = metapost.specials or { } -- the flusher is pdf based, if another backend is used, we need to overload the -- flusher; this is beta code, the organization will change -function metapost.flush(result,flusher) -- pdf flusher, table en dan concat is sneller, 1 literal +function metapost.flush(result,flusher,askedfig) -- pdf flusher, table en dan concat is sneller, 1 literal if result then local figures = result.fig if figures then @@ -247,254 +233,268 @@ function metapost.flush(result,flusher) -- pdf flusher, table en dan concat is s local colorhandler = metapost.colorhandler for f=1, #figures do local figure = figures[f] ---~ local objects = figure:objects() -local objects = result.objects -if not objects then - objects = figure:objects() - result.objects = objects -end - local fignum = tonumber((figure:filename()):match("([%d]+)$") or 0) - local t = { } - local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false - local bbox = figure:boundingbox() - local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack - if urx < llx then - -- invalid - flusher.startfigure(fignum,0,0,0,0,"invalid") - flusher.stopfigure() - else - flusher.startfigure(fignum,llx,lly,urx,ury,"begin") - t[#t+1] = "q" - if objects then - for o=1,#objects do - local object = objects[o] - local objecttype = object.type - if objecttype == "start_bounds" or objecttype == "stop_bounds" then - -- skip - elseif objecttype == "start_clip" then - t[#t+1] = "q" - flushnormalpath(object.path,t,false) - t[#t+1] = "W n" - elseif objecttype == "stop_clip" then - t[#t+1] = "Q" - miterlimit, linecap, linejoin, dashed = -1, -1, -1, false - elseif objecttype == "special" then - metapost.specials.register(object.prescript) - elseif objecttype == "text" then - t[#t+1] = "q" - local ot = object.transform -- 3,4,5,6,1,2 - t[#t+1] = format("%f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: format("%f %f m %f %f %f %f 0 0 cm",unpack(ot)) - flusher.flushfigure(t) - t = { } - flusher.textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) - t[#t+1] = "Q" - else - -- alternatively we can pass on the stack, could be a helper - local currentobject = { -- not needed when no extensions - type = object.type, - miterlimit = object.miterlimit, - linejoin = object.linejoin, - linecap = object.linecap, - color = object.color, - dash = object.dash, - path = object.path, - htap = object.htap, - pen = object.pen, - prescript = object.prescript, - postscript = object.postscript, - } - -- - local before, inbetween, after = nil, nil, nil - -- - local cs, cr = currentobject.color, nil - -- todo document why ... - if cs and colorhandler and #cs > 0 and round(cs[1]*10000) == 123 then -- test in function - currentobject, cr = colorhandler(cs,currentobject,t,colorconverter) - objecttype = currentobject.type - end - -- - local prescript = currentobject.prescript - if prescript then - -- move test to function - local special = metapost.specials[prescript] - if special then - currentobject, before, inbetween, after = special(currentobject.postscript,currentobject,t,flusher) + local objects = getobjects(result,figure,f) + local fignum = figure:charcode() or 0 + if not askedfig or (askedfig == fignum) then + local t = { } + local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false + local bbox = figure:boundingbox() + local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack + metapost.llx = llx + metapost.lly = lly + metapost.urx = urx + metapost.ury = ury + if urx < llx then + -- invalid + flusher.startfigure(fignum,0,0,0,0,"invalid",figure) + flusher.stopfigure() + else + flusher.startfigure(fignum,llx,lly,urx,ury,"begin",figure) + t[#t+1] = "q" + if objects then + t[#t+1] = metapost.colorinitializer() + -- once we have multiple prescripts we can do more tricky things like + -- text and special colors at the same time + for o=1,#objects do + local object = objects[o] + local objecttype = object.type + if objecttype == "start_bounds" or objecttype == "stop_bounds" then + -- skip + elseif objecttype == "start_clip" then + t[#t+1] = "q" + flushnormalpath(object.path,t,false) + t[#t+1] = "W n" + elseif objecttype == "stop_clip" then + t[#t+1] = "Q" + miterlimit, linecap, linejoin, dashed = -1, -1, -1, false + elseif objecttype == "special" then + metapost.specials.register(object.prescript) + elseif objecttype == "text" then + t[#t+1] = "q" + local ot = object.transform -- 3,4,5,6,1,2 + t[#t+1] = format("%f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: format("%f %f m %f %f %f %f 0 0 cm",unpack(ot)) + flusher.flushfigure(t) -- flush accumulated literals + t = { } + flusher.textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) + t[#t+1] = "Q" + else + -- alternatively we can pass on the stack, could be a helper + -- can be optimized with locals + local currentobject = { -- not needed when no extensions + type = object.type, + miterlimit = object.miterlimit, + linejoin = object.linejoin, + linecap = object.linecap, + color = object.color, + dash = object.dash, + path = object.path, + htap = object.htap, + pen = object.pen, + prescript = object.prescript, + postscript = object.postscript, + } + -- + local before, inbetween, after = nil, nil, nil + -- + local cs, cr = currentobject.color, nil + -- todo document why ... + if cs and colorhandler and #cs > 0 and round(cs[1]*10000) == 123 then -- test in function + currentobject, cr = colorhandler(cs,currentobject,t,colorconverter) objecttype = currentobject.type end - end - -- - cs = currentobject.color - if cs and #cs > 0 then - t[#t+1], cr = colorconverter(cs) - end - -- - if before then object, t = before() end - local ml = currentobject.miterlimit - if ml and ml ~= miterlimit then - miterlimit = ml - t[#t+1] = format("%f M",ml) - end - local lj = currentobject.linejoin - if lj and lj ~= linejoin then - linejoin = lj - t[#t+1] = format("%i j",lj) - end - local lc = currentobject.linecap - if lc and lc ~= linecap then - linecap = lc - t[#t+1] = format("%i J",lc) - end - local dl = currentobject.dash - if dl then - local d = format("[%s] %i d",join(dl.dashes or {}," "),dl.offset) - if d ~= dashed then - dashed = d - t[#t+1] = dashed + -- + local prescript = currentobject.prescript + if prescript and prescript ~= "" then + -- move test to function + local special = metapost.specials[prescript] + if special then + currentobject, before, inbetween, after = special(currentobject.postscript,currentobject,t,flusher) + objecttype = currentobject.type + end end - elseif dashed then - t[#t+1] = "[] 0 d" - dashed = false - end - if inbetween then object, t = inbetween() end - local path = currentobject.path - local transformed, penwidth = false, 1 - local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point" - local pen = currentobject.pen - if pen then - if pen.type=='elliptical' then - transformed, penwidth = pen_characteristics(object) -- boolean, value - t[#t+1] = format("%f w",penwidth) -- todo: only if changed - if objecttype == 'fill' then - objecttype = 'both' + -- + cs = currentobject.color + if cs and #cs > 0 then + t[#t+1], cr = colorconverter(cs) + end + -- + if before then currentobject, t = before() end + local ml = currentobject.miterlimit + if ml and ml ~= miterlimit then + miterlimit = ml + t[#t+1] = format("%f M",ml) + end + local lj = currentobject.linejoin + if lj and lj ~= linejoin then + linejoin = lj + t[#t+1] = format("%i j",lj) + end + local lc = currentobject.linecap + if lc and lc ~= linecap then + linecap = lc + t[#t+1] = format("%i J",lc) + end + local dl = currentobject.dash + if dl then + local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset) + if d ~= dashed then + dashed = d + t[#t+1] = dashed end - else -- calculated by mplib itself - objecttype = 'fill' - end - end - if transformed then - t[#t+1] = "q" - end - if path then - if transformed then - flushconcatpath(path,t,open) - else - flushnormalpath(path,t,open) + elseif dashed then + t[#t+1] = "[] 0 d" + dashed = false end - if objecttype == "fill" then - t[#t+1] = "h f" - elseif objecttype == "outline" then - t[#t+1] = (open and "S") or "h S" - elseif objecttype == "both" then - t[#t+1] = "h B" + if inbetween then currentobject, t = inbetween() end + local path = currentobject.path + local transformed, penwidth = false, 1 + local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point" + local pen = currentobject.pen + if pen then + if pen.type == 'elliptical' then + transformed, penwidth = pen_characteristics(object) -- boolean, value + t[#t+1] = format("%f w",penwidth) -- todo: only if changed + if objecttype == 'fill' then + objecttype = 'both' + end + else -- calculated by mplib itself + objecttype = 'fill' + end end - end - if transformed then - t[#t+1] = "Q" - end - local path = currentobject.htap - if path then if transformed then t[#t+1] = "q" end - if transformed then - flushconcatpath(path,t,open) - else - flushnormalpath(path,t,open) - end - if objecttype == "fill" then - t[#t+1] = "h f" - elseif objecttype == "outline" then - t[#t+1] = (open and "S") or "h S" - elseif objecttype == "both" then - t[#t+1] = "h B" + if path then + if transformed then + flushconcatpath(path,t,open) + else + flushnormalpath(path,t,open) + end + if objecttype == "fill" then + t[#t+1] = "h f" + elseif objecttype == "outline" then + t[#t+1] = (open and "S") or "h S" + elseif objecttype == "both" then + t[#t+1] = "h B" + end end if transformed then t[#t+1] = "Q" end + local path = currentobject.htap + if path then + if transformed then + t[#t+1] = "q" + end + if transformed then + flushconcatpath(path,t,open) + else + flushnormalpath(path,t,open) + end + if objecttype == "fill" then + t[#t+1] = "h f" + elseif objecttype == "outline" then + t[#t+1] = (open and "S") or "h S" + elseif objecttype == "both" then + t[#t+1] = "h B" + end + if transformed then + t[#t+1] = "Q" + end + end + if cr then + t[#t+1] = cr + end + if after then currentobject, t = after() end end - if cr then - t[#t+1] = cr - end - if after then object, t = after() end - end - end + end + end + t[#t+1] = "Q" + flusher.flushfigure(t) + flusher.stopfigure("end") + end + if askedfig then + break end - t[#t+1] = "Q" - flusher.flushfigure(t) - flusher.stopfigure("end") end end end end end -function metapost.parse(result) +function metapost.parse(result,askedfig) if result then local figures = result.fig if figures then for f=1, #figures do local figure = figures[f] ---~ local objects = figure:objects() -local objects = result.objects -if not objects then - objects = figure:objects() - result.objects = objects -end - if objects then - for o=1,#objects do - local object = objects[o] - if object.type == "outline" then - local prescript = object.prescript - if prescript then - local special = metapost.specials[prescript] - if special then - special(object.postscript,object) + local fignum = figure:charcode() or 0 + if not askedfig or (askedfig == fignum) then + local bbox = figure:boundingbox() + local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack + metapost.llx = llx + metapost.lly = lly + metapost.urx = urx + metapost.ury = ury + local objects = getobjects(result,figure,f) + if objects then + for o=1,#objects do + local object = objects[o] + if object.type == "outline" then + local prescript = object.prescript + if prescript then + local special = metapost.specials[prescript] + if special then + special(object.postscript,object) + end end - end - end + end + end end + break end end end end end -do - - -- just tracing +-- tracing: - local t = { } +local t = { } - local flusher = { - startfigure = function() - t = { } - sprint(tex.ctxcatcodes,"\\startnointerference") - end, - flushfigure = function(literals) - for i=1, #literals do - t[#t+1] = literals[i] - end - end, - stopfigure = function() - sprint(tex.ctxcatcodes,"\\stopnointerference") +local flusher = { + startfigure = function() + t = { } + texsprint(ctxcatcodes,"\\startnointerference") + end, + flushfigure = function(literals) + for i=1, #literals do + t[#t+1] = literals[i] end - } - - function metapost.pdfliterals(result) - metapost.flush(result,flusher) - return t + end, + stopfigure = function() + texsprint(ctxcatcodes,"\\stopnointerference") end +} +function metapost.pdfliterals(result) + metapost.flush(result,flusher) + return t end +-- so far + function metapost.totable(result) local figure = result and result.fig and result.fig[1] if figure then local t = { } local objects = figure:objects() - for _, object in ipairs(objects) do + for o=1,#objects do + local object = objects[o] local tt = { } - for _, field in ipairs(mplib.fields(object)) do + local fields = mplib.fields(object) + for f=1,#fields do + local field = fields[f] tt[field] = object[field] end t[#t+1] = tt @@ -509,6 +509,8 @@ function metapost.totable(result) end end +-- will be overloaded later + function metapost.colorconverter() return function(cr) local n = #cr |