if not modules then modules = { } end modules ['lpdf-rul'] = { version = 1.001, comment = "companion to grph-rul.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } -- todo: split backend and pdf local tonumber, tostring, next, type = tonumber, tostring, next, type local concat, setmetatableindex = table.concat, table.setmetatableindex local attributes = attributes local nodes = nodes local bpfactor = number.dimenfactors.bp local nuts = nodes.nuts local ruleactions = nuts.rules.ruleactions local getwhd = nuts.getwhd local lefttoright_code = tex.directioncodes.lefttoright local mpcolor = attributes.colors.mpcolor local trace_mp = false trackers.register("rules.mp", function(v) trace_mp = v end) local report_mp = logs.reporter("rules","mp") local floor = math.floor local getrandom = utilities.randomizer.get local formatters = string.formatters local setdimen = tex.setdimen local isdimen = tex.isdimen local setmacro = tokens.setters.macro local codeinjections = backends.registered.pdf.codeinjections local d_rule_width = isdimen("d_rule_width") local d_rule_height = isdimen("d_rule_height") local d_rule_depth = isdimen("d_rule_depth") local d_rule_h = isdimen("d_rule_h") local d_rule_v = isdimen("d_rule_v") local d_rule_line = isdimen("d_rule_line") local d_rule_offset = isdimen("d_rule_offset") local d_rule_factor = isdimen("d_rule_factor") -- This is very pdf specific. Maybe move some to lpdf-rul.lua some day. local pdfprint ; pdfprint = function(...) pdfprint = lpdf.print return pdfprint(...) end do local simplemetapost = metapost.simple local cachesize = 0 local maxcachesize = 256*1024 local cachethreshold = 1024 local caching = false -- otherwise random issues so we need a dedicated randomizer first -- local maxcachesize = 8*1024 -- local cachethreshold = 1024/2 local cache = setmetatableindex(function(t,k) local v = simplemetapost("rulefun",k) -- w, h, d cachesize = cachesize + #v if cachesize > maxcachesize then -- print("old",cachesize) for k, v in next, t do local n = #v if n > cachethreshold then t[k] = nil cachesize = cachesize - n end end -- print("new",cachesize) end -- print(cachesize,maxcachesize,cachethreshold,#v) t[k] = v return v end) local replacer = utilities.templates.replacer -- todo: RuleColor -> just string ? -- todo: fetch them instead fo push them -- local predefined = { -- ["fake:word"] = replacer [[ -- FakeWord(%width%,%height%,%depth%,%line%,%color%); -- ]], -- ["fake:rule"] = replacer[[ -- %initializations% -- FakeRule(%width%,%height%,%depth%,%line%,%color%); -- ]], -- ["fake:rest"] = replacer [[ -- RuleDirection := "%direction%" ; -- RuleOption := "%option%" ; -- RuleWidth := %width% ; -- RuleHeight := %height% ; -- RuleDepth := %depth% ; -- RuleH := %h% ; -- RuleV := %v% ; -- RuleThickness := %line% ; -- RuleFactor := %factor% ; -- RuleOffset := %offset% ; -- def RuleColor = %color% enddef ; -- %data%; -- ]] -- } local predefined = { ["fake:word"] = replacer [[ FakeWord(RuleWidth,RuleHeight,RuleDepth,RuleThickness,RuleColor); ]], ["fake:rule"] = replacer[[ %initializations% FakeRule(RuleWidth,RuleHeight,RuleDepth,RuleThickness,RuleColor); ]], ["fake:rest"] = replacer [[ %data%; ]] } local initialized = false ; local function rule_mp(p,h,v,i,n) local name = p.name or "fake:rest" local ht = p.height or 0 local dp = p.depth or 0 local total = ht + dp local code = (predefined[name] or predefined["fake:rest"]) { data = p.data or "", -- -- width = p.width * bpfactor, -- -- height = p.height * bpfactor, -- -- depth = p.depth * bpfactor, -- width = h * bpfactor, -- height = v * bpfactor * ht / total, -- depth = v * bpfactor * dp / total, -- factor = (p.factor or 0) * bpfactor, -- needs checking -- offset = p.offset or 0, -- line = (p.line or 65536) * bpfactor, -- color = mpcolor(p.ma,p.ca,p.ta), -- option = p.option or "", -- direction = p.direction or lefttoright_code, -- h = h * bpfactor, -- v = v * bpfactor, } -- setdimen("d_rule_width", h) setdimen("d_rule_height", v * ht / total) setdimen("d_rule_depth", v * dp / total) setdimen("d_rule_h", h) setdimen("d_rule_v", v) setdimen("d_rule_line", p.line or 65536) setdimen("d_rule_offset", (p.offset or 0) * 65536) setdimen("d_rule_factor", (p.factor or 0)) -- needs checking setmacro("m_rule_option", p.option or "") setmacro("m_rule_direction", p.direction or lefttoright_code) setmacro("m_rule_color", mpcolor(p.ma,p.ca,p.ta)) -- if not initialized then initialized = true simplemetapost("rulefun",formatters["randomseed := %s;"](getrandom("rulefun",0,4095))) end -- we enable extensions but we could also consider to delegate colors -- to the node finalizer local pdf = caching and cache[code] or simplemetapost("rulefun",code,true) if trace_mp then report_mp("code: %s",code) report_mp("pdf : %s",pdf) end if pdf and pdf ~= "" then pdfprint("direct",pdf) end end codeinjections.ruleactionmp = rule_mp end do -- This is the old oval method that we keep it for compatibility reasons. Of course one can use mp -- instead. It could be improved but at the cost of more code than I'm willing to add for something -- hardly used. local linemapping = { [interfaces.variables.round] = "ltrb", [ "0"] = "ltrb", ["ltrb"] = "ltrb", ["trbl"] = "ltrb", ["rblt"] = "ltrb", ["bltr"] = "ltrb", -- ["1"] = "ltrb", ["2"] = "ltrb", ["3"] = "ltrb", ["4"] = "ltrb", ["5"] = "ltrb", ["6"] = "ltrb", ["7"] = "ltrb", ["8"] = "ltrb", -- [ "9"] = "trb", ["trb"] = "trb", ["rtl"] = "trb", ["10"] = "tlb", ["tlb"] = "tlb", ["blt"] = "tlb", ["11"] = "ltr", ["ltr"] = "ltr", ["rtl"] = "lrt", ["12"] = "lbr", ["lbr"] = "lbr", ["rbl"] = "lbr", -- ["13"] = "rt", ["rt"] = "rt", ["tr"] = "rt", ["14"] = "rb", ["rb"] = "rb", ["br"] = "rb", ["15"] = "bl", ["bl"] = "bl", ["lb"] = "bl", ["16"] = "tl", ["tl"] = "tl", ["lt"] = "tl", -- ["32"] = "lr", ["lr"] = "lr", ["rl"] = "lr", ["33"] = "tb", ["tb"] = "tb", ["bt"] = "tb", -- ["28"] = "l", ["l"] = "l", ["29"] = "r", ["r"] = "r", ["30"] = "b", ["b"] = "b", ["31"] = "t", ["t"] = "t", } local roundmapping = { [interfaces.variables.round] = "ltrb", [ "0"] = "ltrb", ["ltrb"] = "ltrb", ["trbl"] = "ltrb", ["rblt"] = "ltrb", ["bltr"] = "ltrb", -- [ "9"] = "trb", ["trb"] = "trb", ["rtl"] = "trb", ["10"] = "tlb", ["tlb"] = "tlb", ["blt"] = "tlb", ["11"] = "ltr", ["ltr"] = "ltr", ["rtl"] = "lrt", ["12"] = "lbr", ["lbr"] = "lbr", ["rbl"] = "lbr", -- ["13"] = "rt", ["rt"] = "rt", ["tr"] = "rt", ["14"] = "rb", ["rb"] = "rb", ["br"] = "rb", ["15"] = "bl", ["bl"] = "bl", ["lb"] = "bl", ["16"] = "tl", ["tl"] = "tl", ["lt"] = "tl", -- ["32"] = "lr", ["lr"] = "lr", ["rl"] = "lr", ["33"] = "tb", ["tb"] = "tb", ["bt"] = "tb", -- ["28"] = "l", ["l"] = "l", ["29"] = "r", ["r"] = "r", ["30"] = "b", ["b"] = "b", ["31"] = "t", ["t"] = "t", } local function register(t,k) local v = tonumber(k) if v then v = tostring(v) end v = v and rawget(t,v) or v if not v then v = "ltrb" end t[k] = v return v end setmetatableindex(linemapping, register) setmetatableindex(roundmapping,register) local function round(p,kind,corner) local width = p.width or 0 local height = p.height or 0 local depth = p.depth or 0 local radius = p.radius or 655360 local line = (p.line or 65536) * bpfactor local half = line / 2 local xxmin = 0 local xxmax = width * bpfactor local yymax = height * bpfactor local yymin = -depth * bpfactor local xmin = xxmin + half local xmax = xxmax - half local ymax = yymax - half local ymin = yymin + half local list = nil local done = kind ~= "fill" and "S" or "f" if radius == 0 then local method = linemapping[corner] if method == "ltrb" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l h %s Q"] (line,xmin,ymin,xmax,ymin,xmax,ymax,xmin,ymax,done) elseif method == "l" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l S Q"] (line,xmin,yymin,xmin,yymax) elseif method == "r" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l S Q"] (line,xmax,yymin,xmax,yymax) elseif method == "b" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l S Q"] (line,xxmin,ymin,xxmax,ymin) elseif method == "t" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l S Q"] (line,xxmin,ymax,xxmax,ymax) elseif method == "lr" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N m %.6N %.6N %.6N l S Q"] (line,xmin,yymin,xmin,yymax,xmax,yymin,xmax,yymax) elseif method == "tb" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N m %.6N %.6N %.6N l S Q"] (line,xxmin,ymin,xxmax,ymin,xxmin,ymax,xxmax,ymax) elseif method == "lbr" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l S Q"] (line,xmin,yymax,xmin,ymin,xmax,ymin,xmax,yymax) elseif method == "tlb" then -- 10 list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l S Q"] (line,xxmax,ymax,xmin,ymax,xmin,ymin,xxmax,ymin) elseif method == "ltr" then -- 11 list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l S Q"] (line,xmin,yymin,xmin,ymax,xmax,ymax,xmax,yymin) elseif method == "trb" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l S Q"] (line,xxmin,ymax,xmax,ymax,xmax,ymin,xxmin,ymin) elseif method == "rt" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l S Q"] (line,xxmin,ymax,xmax,ymax,xmax,yymin) elseif method == "rb" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l S Q"] (line,xmax,yymax,xmax,ymin,xxmin,ymin) elseif method == "bl" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l S Q"] (line,xxmax,ymin,xmin,ymin,xmin,yymax) elseif method == "tl" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l S Q"] (line,xmin,yymin,xmin,ymax,xxmax,ymax) else return end else local method = roundmapping[corner] local full = ( radius + half) local xxxmin = full * bpfactor local xxxmax = ( width - full) * bpfactor local yyymax = ( height - full) * bpfactor local yyymin = (-depth + full) * bpfactor if xxxmin > xxxmax or yyymin > yyymax then return elseif method == "ltrb" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y h %s Q"] (line,xxxmin,ymin,xxxmax,ymin,xmax,ymin,xmax,yyymin,xmax,yyymax,xmax,ymax,xxxmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax,xmin,yyymin,xmin,ymin,xxxmin,ymin,done) elseif method == "1" then -- ll lr list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N l %.6N %.6N l %.6N %.6N %.6N %.6N y h %s Q"] (line,xxxmin,ymin,xxxmax,ymin,xmax,ymin,xmax,yyymin,xmax,ymax,xmin,ymax,xmin,yyymin,xmin,ymin,xxxmin,ymin,done) elseif method == "2" then -- ll ul list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y h %s Q"] (line,xxxmin,ymin,xmax,ymin,xmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax,xmin,yyymin,xmin,ymin,xxxmin,ymin,done) elseif method == "3" then -- ul ur list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l h %s Q"] (line,xmin,ymin,xmax,ymin,xmax,yyymax,xmax,ymax,xxxmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax,xmin,ymin,done) elseif method == "4" then -- ur lr list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N l h %s Q"] (line,xmin,ymin,xxxmax,ymin,xmax,ymin,xmax,yyymin,xmax,yyymax,xmax,ymax,xxxmax,ymax,xmin,ymax,xmin,ymin,done) elseif method == "5" then -- ur list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N l h %s Q"] (line,xmin,ymin,xmax,ymin,xmax,yyymax,xmax,ymax,xxxmax,ymax,xmin,ymax,xmin,ymin,done) elseif method == "6" then -- lr list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N l %.6N %.6N l h %s Q"] (line,xmin,ymin,xxxmax,ymin,xmax,ymin,xmax,yyymin,xmax,ymax,xmin,ymax,xmin,ymin,done) elseif method == "7" then -- ur list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l %.6N %.6N l %.6N %.6N %.6N %.6N y h %s Q"] -- outlier (line,xxxmin,ymin,xmax,ymin,xmax,ymax,xmin, ymax,xmin,yyymin,xmin,ymin,xxxmin,ymin,done) elseif method == "8" then -- ul list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N l %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l h %s Q"] (line,xmin,ymin,xmax,ymin,xmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax,xmin,ymin,done) elseif method == "lbr" then -- 12 list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xmin,yymax,xmin,yyymin,xmin,ymin,xxxmin,ymin,xxxmax,ymin,xmax,ymin,xmax,yyymin,xmax,yymax) elseif method == "tlb" then -- 10 list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xxmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax,xmin,yyymin,xmin,ymin,xxxmin,ymin,xxmax,ymin) elseif method == "ltr" then -- 11 list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xmax,yymin,xmax,yyymax,xmax,ymax,xxxmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax,xmin,yymin) elseif method == "trb" then -- 9 list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xxmin,ymax,xxxmax,ymax,xmax,ymax,xmax,yyymax,xmax,yyymin,xmax,ymin,xxxmax,ymin,xxmin,ymin) elseif method == "lr" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y S Q"] (line,xxxmin,ymin,xmin,ymin,xmin,yyymin,xmin,yyymax,xmin,ymax,xxxmin,ymax,xxxmax,ymax,xmax,ymax,xmax,yyymax,xmax,yyymin,xmax,ymin,xxxmax,ymin) elseif method == "tb" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y S Q"] (line,xmax,yyymin,xmax,ymin,xxxmax,ymin,xxxmin,ymin,xmin,ymin,xmin,yyymin,xmax,yyymax,xmax,ymax,xxxmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax) elseif method == "rt" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xxmin,ymax,xxxmax,ymax,xmax,ymax,xmax,yyymax,xmax,yymin) elseif method == "rb" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xmax,yymax,xmax,yyymin,xmax,ymin,xxxmax,ymin,xxmin,ymin) elseif method == "bl" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xxmax,ymin,xxxmin,ymin,xmin,ymin,xmin,yyymin,xmin,yymax) elseif method == "tl" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l S Q"] (line,xmin,yymin,xmin,yyymax,xmin,ymax,xxxmin,ymax,xxmax,ymax) elseif method == "17" then -- urx list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xxxmax,ymax,xmax,ymax,xmax,yyymax) elseif method == "18" then -- lrt list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xmax,yyymin,xmax,ymin,xxxmax,ymin) elseif method == "19" then -- llx list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xxxmin,ymin,xmin,ymin,xmin,yyymin) elseif method == "20" then -- urx list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xmin,yyymax,xmin,ymax,xxxmin,ymax) elseif method == "21" then -- ulx urx list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xmax,yyymax,xmax,ymax,xxxmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax) elseif method == "22" then -- urt lrt list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xxxmax,ymax,xmax,ymax,xmax,yyymax,xmax,yyymin,xmax,ymin,xxxmax,ymin) elseif method == "23" then -- llx lrx list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xmax,yyymin,xmax,ymin,xxxmax,ymin,xxxmin,ymin,xmin,ymin,xmin,yyymin) elseif method == "24" then -- ulx llx list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xxxmin,ymin,xmin,ymin,xmin,yyymin,xmin,yyymax,xmin,ymax,xxxmin,ymax) elseif method == "25" then -- llx lrx urx ulx list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xxxmax,ymax,xmax,ymax,xmax,yyymax,xmax,yyymin,xmax,ymin,xxxmax,ymin,xxxmin,ymin,xmin,ymin,xmin,yyymin,xmin,yyymax,xmin,ymax,xxxmin,ymax) elseif method == "26" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xmax,yyymin,xmax,ymin,xxxmax,ymin,xmin,yyymax,xmin,ymax,xxxmin,ymax) elseif method == "27" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N m %.6N %.6N %.6N %.6N y S Q"] (line,xxxmax,ymax,xmax,ymax,xmax,yyymax,xxxmin,ymin,xmin,ymin,xmin,yyymin) elseif method == "l" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y S Q"] (line,xxxmin,ymin,xmin,ymin,xmin,yyymin,xmin,yyymax,xmin,ymax,xxxmin,ymax) elseif method == "r" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y S Q"] (line,xxxmax,ymax,xmax,ymax,xmax,yyymax,xmax,yyymin,xmax,ymin,xxxmax,ymin) elseif method == "b" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y S Q"] (line,xmax,yyymin,xmax,ymin,xxxmax,ymin,xxxmin,ymin,xmin,ymin,xmin,yyymin) elseif method == "t" then list = formatters ["q %.6N w %.6N %.6N m %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y S Q"] (line,xmax,yyymax,xmax,ymax,xxxmax,ymax,xxxmin,ymax,xmin,ymax,xmin,yyymax) else return end end -- print(list) pdfprint("direct",list) end local f_rectangle = formatters["q %.6N w %.6N %.6N %.6N %.6N re %s Q"] local f_baselined = formatters["q %.6N w %.6N %.6N %.6N %.6N re s %.6N %.6N m %.6N %.6N l s Q"] local f_dashlined = formatters["q %.6N w %.6N %.6N %.6N %.6N re s [%.6N %.6N] 2 d %.6N %.6N m %.6N %.6N l s Q"] local f_dashtwice = formatters["q %.6N w %.6N %.6N %.6N %.6N re s [%.6N %.6N] 2 d %.6N %.6N m %.6N %.6N l s %.6N %.6N m %.6N %.6N l s Q"] local f_radtangle = formatters["q %.6N w %.6N %.6N m %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y %.6N %.6N l %.6N %.6N %.6N %.6N y h %s Q"] local rule_any = function(p,h,v,i,n) local corner = p.corner if corner then return round(p,i,corner) else local l = (p.line or 65536)*bpfactor local r = p and (p.radius or 0)*bpfactor or 0 local w = h * bpfactor local h = v * bpfactor local m = nil local t = i == "fill" and "f" or "s" local o = l / 2 if r > 0 then w = w - o h = h - o m = f_radtangle(l, r,o, w-r,o, w,o,w,r, w,h-r, w,h,w-r,h, r,h, o,h,o,h-r, o,r, o,o,r,o, t) else w = w - l h = h - l m = f_rectangle(l,o,o,w,h,t) end pdfprint("direct",m) end end local function rule_box(p,h,v,i,n) local w, h, d = getwhd(n) local line = p.line or 65536 local l = line *bpfactor local w = w * bpfactor local h = h * bpfactor local d = d * bpfactor local o = l / 2 local u = p.double if p.baseline ~= false and ((d >= 0 and h >= 0) or (d <= 0 and h <= 0)) then local dashed = tonumber(p.dashed) if dashed and dashed > 5*line then dashed = dashed * bpfactor local delta = (w - 2*dashed*floor(w/(2*dashed)))/2 if u then u = u * bpfactor pdfprint("direct",f_dashtwice(l,o,o,w-l,h+d-l,dashed,dashed,delta,d,w-delta,d,delta,d+u,w-delta,d+u)) else pdfprint("direct",f_dashlined(l,o,o,w-l,h+d-l,dashed,dashed,delta,d,w-delta,d)) end else pdfprint("direct",f_baselined(l,o,o,w-l,h+d-l,0,d,w,d)) end else pdfprint("direct",f_rectangle(l,o,o,w-l,h+d-l,"s")) end end codeinjections.ruleactionfill = rule_any codeinjections.ruleactiondraw = rule_any codeinjections.ruleactionstroke = rule_any codeinjections.ruleactionbox = rule_box end