summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkxl/lpdf-rul.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/lpdf-rul.lmt')
-rw-r--r--Master/texmf-dist/tex/context/base/mkxl/lpdf-rul.lmt388
1 files changed, 388 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/lpdf-rul.lmt b/Master/texmf-dist/tex/context/base/mkxl/lpdf-rul.lmt
new file mode 100644
index 00000000000..efcc6207372
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkxl/lpdf-rul.lmt
@@ -0,0 +1,388 @@
+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"
+}
+
+local tonumber, next, type = tonumber, next, type
+local concat = table.concat
+
+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 = nodes.dirvalues.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
+
+-- This is very pdf specific. Maybe move some to lpdf-rul.lua some day.
+
+local pdfprint ; pdfprint = function(...) pdfprint = lpdf.print return pdfprint(...) end
+
+-- updaters.register("backend.update",function() pdfprint = lpdf.print 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 = table.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 ?
+
+ 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 initialized = false ;
+
+ local rule_mp = function(p,h,v,i,n)
+ local name = p.name or "fake:rest"
+ local code = (predefined[name] or predefined["fake:rest"]) {
+ data = p.data or "",
+ width = p.width * bpfactor,
+ height = p.height * bpfactor,
+ depth = p.depth * bpfactor,
+ 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,
+ }
+ 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
+
+ updaters.register("backend.update.lpdf",function()
+ ruleactions.mp = rule_mp
+ end)
+
+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 function round(p,kind)
+ local method = tonumber(p.corner) or 0
+ if method < 0 or method > 27 then
+ method = 0
+ end
+ local width = p.width or 0
+ local height = p.height or 0
+ local depth = p.depth or 0
+ local total = height + depth
+ local radius = p.radius or 655360
+ local line = p.line or 65536
+ local how = (method > 8 or kind ~= "fill") and "S" or "f"
+ local half = line / 2
+ local xmin = half * bpfactor
+ local xmax = ( width - half) * bpfactor
+ local ymax = ( height - half) * bpfactor
+ local ymin = (-depth + half) * bpfactor
+ local full = ( radius + half)
+ local xxmin = full * bpfactor
+ local xxmax = ( width - full) * bpfactor
+ local yymax = ( height - full) * bpfactor
+ local yymin = (-depth + full) * bpfactor
+ line = line * bpfactor
+ if xxmin <= xxmax and yymin <= yymax then
+ local list = nil
+ if method == 0 then
+ list = {
+ "q", line, "w", xxmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y",
+ xmax, yymax, "l", xmax, ymax, xxmax, ymax, "y", xxmin, ymax, "l", xmin, ymax,
+ xmin, yymax, "y", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", "h", how, "Q",
+ }
+ elseif method == 1 then
+ list = {
+ "q", line, "w", xxmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y",
+ xmax, ymax, "l", xmin, ymax, "l", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y",
+ "h", how, "Q",
+ }
+ elseif method == 2 then
+ list = {
+ "q", line, "w", xxmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xxmin, ymax,
+ "l", xmin, ymax, xmin, yymax, "y", xmin, yymin, "l", xmin, ymin, xxmin, ymin,
+ "y", "h", how, "Q",
+ }
+ elseif method == 3 then
+ list = {
+ "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, yymax, "l", xmax, ymax,
+ xxmax, ymax, "y", xxmin, ymax, "l", xmin, ymax, xmin, yymax, "y", xmin, ymin,
+ "l", "h", how, "Q",
+ }
+
+ elseif method == 4 then
+ list = {
+ "q", line, "w", xmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y",
+ xmax, yymax, "l", xmax, ymax, xxmax, ymax, "y", xmin, ymax, "l", xmin, ymin, "l",
+ "h", how, "Q",
+ }
+ elseif method == 5 then
+ list = {
+ "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, yymax, "l", xmax, ymax,
+ xxmax, ymax, "y", xmin, ymax, "l", xmin, ymin, "l", "h", how, "Q",
+ }
+ elseif method == 6 then
+ list = {
+ "q", line, "w", xmin, ymin, "m", xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y",
+ xmax, ymax, "l", xmin, ymax, "l", xmin, ymin, "l", "h", how, "Q",
+ }
+ elseif method == 7 then
+ list = {
+ "q", line, "w", xxmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xmin, ymax,
+ "l", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", "h", how, "Q",
+ }
+ elseif method == 8 then
+ list = {
+ "q", line, "w", xmin, ymin, "m", xmax, ymin, "l", xmax, ymax, "l", xxmin, ymax,
+ "l", xmin, ymax, xmin, yymax, "y", xmin, ymin, "l", "h", how, "Q",
+ }
+ elseif method == 9 then
+ list = {
+ "q", line, "w", xmin, ymax, "m", xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y",
+ xxmax, ymin, "l", xmax, ymin, xmax, yymin, "y", xmax, ymax, "l", how, "Q",
+ }
+ elseif method == 10 then
+ list = {
+ "q", line, "w", xmax, ymax, "m", xxmin, ymax, "l", xmin, ymax, xmin, yymax, "y",
+ xmin, yymin, "l", xmin, ymin, xxmin, ymin, "y", xmax, ymin, "l", how, "Q",
+ }
+ elseif method == 11 then
+ list = {
+ "q", line, "w", xmax, ymin, "m", xmax, yymax, "l", xmax, ymax, xxmax, ymax, "y",
+ xxmin, ymax, "l", xmin, ymax, xmin, yymax, "y", xmin, ymin, "l", how, "Q",
+ }
+ elseif method == 12 then
+ list = {
+ "q", line, "w", xmin, ymax, "m", xxmax, ymax, "l", xmax, ymax, xmax, yymax, "y",
+ xmax, yymin, "l", xmax, ymin, xxmax, ymin, "y", xmin, ymin, "l", how, "Q",
+ }
+ elseif method == 13 then
+ list = {
+ "q", line, "w", xmin, ymax, "m", xxmax, ymax, "l", xmax, ymax, xmax, yymax, "y",
+ xmax, ymin, "l", how, "Q",
+ }
+ elseif method == 14 then
+ list = {
+ "q", line, "w", xmax, ymax, "m", xmax, yymin, "l", xmax, ymin, xxmax, ymin, "y",
+ xmin, ymin, "l", how, "Q",
+ }
+ elseif method == 15 then
+ list = {
+ "q", line, "w", xmax, ymin, "m", xxmin, ymin, "l", xmin, ymin, xmin, yymin, "y",
+ xmin, ymax, "l", how, "Q",
+ }
+ elseif method == 16 then
+ list = {
+ "q", line, "w", xmin, ymin, "m", xmin, yymax, "l", xmin, ymax, xxmin, ymax, "y",
+ xmax, ymax, "l", how, "Q",
+ }
+ elseif method == 17 then
+ list = {
+ "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", how, "Q",
+ }
+ elseif method == 18 then
+ list = {
+ "q", line, "w", xmax, yymin, "m", xmax, ymin, xxmax, ymin, "y", how, "Q",
+ }
+ elseif method == 19 then
+ list = {
+ "q", line, "w", xxmin, ymin, "m", xmin, ymin, xmin, yymin, "y", how, "Q",
+ }
+ elseif method == 20 then
+ list = {
+ "q", line, "w", xmin, yymax, "m", xmin, ymax, xxmin, ymax, "y", how, "Q",
+ }
+ elseif method == 21 then
+ list = {
+ "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xmin, yymax, "m",
+ xmin, ymax, xxmin, ymax, "y", how, "Q",
+ }
+ elseif method == 22 then
+ list = {
+ "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xmax, yymin, "m",
+ xmax, ymin, xxmax, ymin, "y", how, "Q",
+ }
+ elseif method == 23 then
+ list = {
+ "q", line, "w", xmax, yymin, "m", xmax, ymin, xxmax, ymin, "y", xxmin, ymin, "m",
+ xmin, ymin, xmin, yymin, "y", how, "Q",
+ }
+ elseif method == 24 then
+ list = {
+ "q", line, "w", xxmin, ymin, "m", xmin, ymin, xmin, yymin, "y", xmin, yymax, "m",
+ xmin, ymax, xxmin, ymax, "y", how, "Q",
+ }
+ elseif method == 25 then
+ list = {
+ "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xmax, yymin, "m",
+ xmax, ymin, xxmax, ymin, "y", xxmin, ymin, "m", xmin, ymin, xmin, yymin, "y",
+ xmin, yymax, "m", xmin, ymax, xxmin, ymax, "y", how, "Q",
+ }
+ elseif method == 26 then
+ list = {
+ "q", line, "w", xmax, yymin, "m", xmax, ymin, xxmax, ymin, "y", xmin, yymax, "m",
+ xmin, ymax, xxmin, ymax, "y", how, "Q",
+ }
+
+ elseif method == 27 then
+ list = {
+ "q", line, "w", xxmax, ymax, "m", xmax, ymax, xmax, yymax, "y", xxmin, ymin, "m",
+ xmin, ymin, xmin, yymin, "y", how, "Q",
+ }
+ end
+ pdfprint("direct",concat(list," "))
+ end
+ end
+
+ local f_rectangle = formatters["%.6N w %.6N %.6N %.6N %.6N re %s"]
+ local f_baselined = formatters["%.6N w %.6N %.6N %.6N %.6N re s %.6N %.6N m %.6N %.6N l s"]
+ local f_dashlined = formatters["%.6N w %.6N %.6N %.6N %.6N re s [%.6N %.6N] 2 d %.6N %.6N m %.6N %.6N l s"]
+ local f_radtangle = formatters[
+[[%.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]]
+ ]
+
+ local rule_any = function(p,h,v,i,n)
+ if p.corner then
+ return round(p,i)
+ 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
+ if (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
+ pdfprint("direct",f_dashlined(l,o,o,w-l,h+d-l,dashed,dashed,delta,d,w-delta,d))
+ 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))
+ end
+ end
+
+ updaters.register("backend.update.lpdf",function()
+ ruleactions.fill = rule_any
+ ruleactions.draw = rule_any
+ ruleactions.stroke = rule_any
+ ruleactions.box = rule_box
+ end)
+
+end
+
+
+ ruleactions.mp = unsupported
+
+