diff options
author | Mojca Miklavec <mojca.miklavec@gmail.com> | 2014-05-05 20:29:55 +0000 |
---|---|---|
committer | Mojca Miklavec <mojca.miklavec@gmail.com> | 2014-05-05 20:29:55 +0000 |
commit | ba9a57343987f1c2c72396e7c38f1fa30352c24c (patch) | |
tree | 66a8b12cdf67427ce96770fd0e9e581759aade1c /Master/texmf-dist/tex/context/base/mlib-pdf.lua | |
parent | 15242121b8ddf7d4a041fb3998d295dd8232e1eb (diff) |
ConTeXt 2014.04.28 23:24
git-svn-id: svn://tug.org/texlive/trunk@33856 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mlib-pdf.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mlib-pdf.lua | 189 |
1 files changed, 156 insertions, 33 deletions
diff --git a/Master/texmf-dist/tex/context/base/mlib-pdf.lua b/Master/texmf-dist/tex/context/base/mlib-pdf.lua index 96330995105..d25dde88469 100644 --- a/Master/texmf-dist/tex/context/base/mlib-pdf.lua +++ b/Master/texmf-dist/tex/context/base/mlib-pdf.lua @@ -10,13 +10,16 @@ if not modules then modules = { } end modules ['mlib-pdf'] = { local format, concat, gsub = string.format, table.concat, string.gsub local abs, sqrt, round = math.abs, math.sqrt, math.round -local setmetatable = setmetatable -local Cf, C, Cg, Ct, P, S, lpegmatch = lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.match +local setmetatable, rawset, tostring, tonumber, type = setmetatable, rawset, tostring, tonumber, type +local P, S, C, Ct, Cc, Cg, Cf, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.Carg +local lpegmatch = lpeg.match local formatters = string.formatters local report_metapost = logs.reporter("metapost") -local mplib, context = mplib, context +local trace_variables = false trackers.register("metapost.variables",function(v) trace_variables = v end) + +local mplib, context = mplib, context local allocate = utilities.storage.allocate @@ -30,15 +33,26 @@ metapost.flushers = metapost.flushers or { } local pdfflusher = { } metapost.flushers.pdf = pdfflusher -metapost.multipass = false +metapost.multipass = false -- to be stacked metapost.n = 0 -metapost.optimize = true -- false +metapost.optimize = true -- false local experiment = true -- uses context(node) that already does delayed nodes - -local savedliterals = nil -- needs checking +local savedliterals = nil -- needs checking local mpsliteral = nodes.pool.register(node.new("whatsit",nodes.whatsitcodes.pdfliteral)) -- pdfliteral.mode = 1 +local f_f = formatters["%F"] + +local f_m = formatters["%F %F m"] +local f_c = formatters["%F %F %F %F %F %F c"] +local f_l = formatters["%F %F l"] +local f_cm = formatters["%F %F %F %F %F %F cm"] +local f_M = formatters["%F M"] +local f_j = formatters["%i j"] +local f_J = formatters["%i J"] +local f_d = formatters["[%s] %F d"] +local f_w = formatters["%F w"] + local pdfliteral = function(s) local literal = copy_node(mpsliteral) literal.data = s @@ -117,7 +131,7 @@ end function pdfflusher.startfigure(n,llx,lly,urx,ury,message) savedliterals = nil metapost.n = metapost.n + 1 - context.startMPLIBtoPDF(llx,lly,urx,ury) + context.startMPLIBtoPDF(f_f(llx),f_f(lly),f_f(urx),f_f(ury)) if message then pdfflusher.comment(message) end end @@ -190,11 +204,11 @@ local function flushnormalpath(path, t, open) nt = nt + 1 pth = path[i] if not ith then - t[nt] = formatters["%f %f m"](pth.x_coord,pth.y_coord) + t[nt] = f_m(pth.x_coord,pth.y_coord) elseif curved(ith,pth) then - t[nt] = formatters["%f %f %f %f %f %f c"](ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord) + t[nt] = f_c(ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord) else - t[nt] = formatters["%f %f l"](pth.x_coord,pth.y_coord) + t[nt] = f_l(pth.x_coord,pth.y_coord) end ith = pth end @@ -202,15 +216,15 @@ local function flushnormalpath(path, t, open) nt = nt + 1 local one = path[1] if curved(pth,one) then - t[nt] = formatters["%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 ) + t[nt] = f_c(pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord ) else - t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord) + t[nt] = f_l(one.x_coord,one.y_coord) end elseif #path == 1 then -- special case .. draw point local one = path[1] nt = nt + 1 - t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord) + t[nt] = f_l(one.x_coord,one.y_coord) end return t end @@ -224,18 +238,18 @@ local function flushconcatpath(path, t, open) nt = 0 end nt = nt + 1 - t[nt] = formatters["%f %f %f %f %f %f cm"](sx,rx,ry,sy,tx,ty) + t[nt] = f_cm(sx,rx,ry,sy,tx,ty) for i=1,#path do nt = nt + 1 pth = path[i] if not ith then - t[nt] = formatters["%f %f m"](mpconcat(pth.x_coord,pth.y_coord)) + t[nt] = f_m(mpconcat(pth.x_coord,pth.y_coord)) elseif curved(ith,pth) then local a, b = mpconcat(ith.right_x,ith.right_y) local c, d = mpconcat(pth.left_x,pth.left_y) - t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(pth.x_coord,pth.y_coord)) + t[nt] = f_c(a,b,c,d,mpconcat(pth.x_coord,pth.y_coord)) else - t[nt] = formatters["%f %f l"](mpconcat(pth.x_coord, pth.y_coord)) + t[nt] = f_l(mpconcat(pth.x_coord, pth.y_coord)) end ith = pth end @@ -245,15 +259,15 @@ local function flushconcatpath(path, t, open) if curved(pth,one) then local a, b = mpconcat(pth.right_x,pth.right_y) local c, d = mpconcat(one.left_x,one.left_y) - t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(one.x_coord, one.y_coord)) + t[nt] = f_c(a,b,c,d,mpconcat(one.x_coord, one.y_coord)) else - t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord)) + t[nt] = f_l(mpconcat(one.x_coord,one.y_coord)) end elseif #path == 1 then -- special case .. draw point nt = nt + 1 local one = path[1] - t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord)) + t[nt] = f_l(mpconcat(one.x_coord,one.y_coord)) end return t end @@ -268,7 +282,97 @@ metapost.flushnormalpath = flushnormalpath -- performance penalty, but so is passing extra arguments (result, flusher, after) -- and returning stuff. -local function ignore() end +local ignore = function () end + +local space = P(" ") +local equal = P("=") +local key = C((1-equal)^1) * equal +local newline = S("\n\r")^1 +local number = (((1-space-newline)^1) / tonumber) * (space^0) + +local p_number = number +local p_string = C((1-newline)^0) +local p_boolean = P("false") * Cc(false) + P("true") * Cc(true) +local p_set = Ct(number^1) +local p_path = Ct(Ct(number * number^-5)^1) + +-- local variable = +-- P("1:") * key * p_number +-- + P("2:") * key * p_string +-- + P("3:") * key * p_boolean +-- + S("4568") * P(":") * key * p_set +-- + P("7:") * key * p_path +-- +-- local pattern_key = Cf ( Carg(1) * (Cg(variable * newline^0)^0), rawset) + +local variable = + P("1:") * p_number + + P("2:") * p_string + + P("3:") * p_boolean + + S("4568") * P(":") * p_set + + P("7:") * p_path + +local pattern_tab = Cf ( Carg(1) * (Cg(variable * newline^0)^0), rawset) + +local variable = + P("1:") * p_number + + P("2:") * p_string + + P("3:") * p_boolean + + S("4568") * P(":") * number^1 + + P("7:") * (number * number^-5)^1 + +local pattern_lst = (variable * newline^0)^0 + +metapost.variables = { } -- to be stacked +metapost.llx = 0 -- to be stacked +metapost.lly = 0 -- to be stacked +metapost.urx = 0 -- to be stacked +metapost.ury = 0 -- to be stacked + +function commands.mprunvar(key,n) -- should be defined in another lib + local value = metapost.variables[key] + if value ~= nil then + local tvalue = type(value) + if tvalue == "table" then + local ntype = type(n) + if ntype == "number" then + context(value[n]) + elseif ntype == "string" then + context(concat(value,n)) + else + context(concat(value," ")) + end + elseif tvalue == "number" or tvalue == "boolean" then + context(tostring(value)) + elseif tvalue == "string" then + context(value) + end + end +end + +function metapost.untagvariable(str,variables) -- will be redone + if variables == false then + return lpegmatch(pattern_lst,str) + else + return lpegmatch(pattern_tab,str,1,variables or { }) + end +end + +-- function metapost.processspecial(str) +-- lpegmatch(pattern_key,object.prescript,1,variables) +-- end + +function metapost.processspecial(str) + local code = loadstring(str) + if code then + if trace_variables then + report_metapost("executing special code: %s",str) + end + code() + else + report_metapost("invalid special code: %s",str) + end +end function metapost.flush(result,flusher,askedfig) if result then @@ -283,15 +387,30 @@ function metapost.flush(result,flusher,askedfig) local stopfigure = flusher.stopfigure local flushfigure = flusher.flushfigure local textfigure = flusher.textfigure - for f=1, #figures do + local processspecial = flusher.processspecial or metapost.processspecial + for f=1,#figures do local figure = figures[f] local objects = getobjects(result,figure,f) - local fignum = figure:charcode() or 0 + local fignum = figure:charcode() or 0 if askedfig == "direct" or askedfig == "all" 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] + local variables = { } + metapost.variables = variables + metapost.properties = { + llx = llx, + lly = lly, + urx = urx, + ury = ury, + slot = figure:charcode(), + width = figure:width(), + height = figure:height(), + depth = figure:depth(), + italic = figure:italcorr(), + } + -- replaced by the above metapost.llx = llx metapost.lly = lly metapost.urx = urx @@ -308,8 +427,12 @@ function metapost.flush(result,flusher,askedfig) for o=1,#objects do local object = objects[o] local objecttype = object.type - if objecttype == "start_bounds" or objecttype == "stop_bounds" or objecttype == "special" then + if objecttype == "start_bounds" or objecttype == "stop_bounds" then -- skip + elseif objecttype == "special" then + if processspecial then + processspecial(object.prescript) + end elseif objecttype == "start_clip" then t[#t+1] = "q" flushnormalpath(object.path,t,false) @@ -320,7 +443,7 @@ function metapost.flush(result,flusher,askedfig) elseif objecttype == "text" then t[#t+1] = "q" local ot = object.transform -- 3,4,5,6,1,2 - t[#t+1] = formatters["%f %f %f %f %f %f cm"](ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%f %f m %f %f %f %f 0 0 cm"](unpack(ot)) + t[#t+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%F %F m %F %F %F %F 0 0 cm"](unpack(ot)) flushfigure(t) -- flush accumulated literals t = { } textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) @@ -345,21 +468,21 @@ function metapost.flush(result,flusher,askedfig) local ml = object.miterlimit if ml and ml ~= miterlimit then miterlimit = ml - t[#t+1] = formatters["%f M"](ml) + t[#t+1] = f_M(ml) end local lj = object.linejoin if lj and lj ~= linejoin then linejoin = lj - t[#t+1] = formatters["%i j"](lj) + t[#t+1] = f_j(lj) end local lc = object.linecap if lc and lc ~= linecap then linecap = lc - t[#t+1] = formatters["%i J"](lc) + t[#t+1] = f_J(lc) end local dl = object.dash if dl then - local d = formatters["[%s] %f d"](concat(dl.dashes or {}," "),dl.offset) + local d = f_d(concat(dl.dashes or {}," "),dl.offset) if d ~= dashed then dashed = d t[#t+1] = dashed @@ -375,7 +498,7 @@ function metapost.flush(result,flusher,askedfig) if pen then if pen.type == 'elliptical' then transformed, penwidth = pen_characteristics(original) -- boolean, value - t[#t+1] = formatters["%f w"](penwidth) -- todo: only if changed + t[#t+1] = f_w(penwidth) -- todo: only if changed if objecttype == 'fill' then objecttype = 'both' end @@ -395,7 +518,7 @@ function metapost.flush(result,flusher,askedfig) if objecttype == "fill" then t[#t+1] = "h f" elseif objecttype == "outline" then - t[#t+1] = (open and "S") or "h S" + t[#t+1] = open and "S" or "h S" elseif objecttype == "both" then t[#t+1] = "h B" end @@ -416,7 +539,7 @@ function metapost.flush(result,flusher,askedfig) if objecttype == "fill" then t[#t+1] = "h f" elseif objecttype == "outline" then - t[#t+1] = (open and "S") or "h S" + t[#t+1] = open and "S" or "h S" elseif objecttype == "both" then t[#t+1] = "h B" end |