summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2024-07-08 20:15:15 +0000
committerKarl Berry <karl@freefriends.org>2024-07-08 20:15:15 +0000
commit157f4b8ca0dfcec0e44b6e4d93a29d93870a8860 (patch)
tree29df4a8a93652e8d296009afc531a5f070dcd8f7 /Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
parent4d2e984c25f3d1250d4df0d7be6649f405e3af0a (diff)
luamplib (8jul24)
git-svn-id: svn://tug.org/texlive/trunk@71745 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luamplib/luamplib.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luamplib/luamplib.lua176
1 files changed, 150 insertions, 26 deletions
diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua b/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
index ffe7c0e0c41..85e9db1843a 100644
--- a/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
+++ b/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
@@ -11,8 +11,8 @@
luatexbase.provides_module {
name = "luamplib",
- version = "2.32.4",
- date = "2024/07/03",
+ version = "2.33.0",
+ date = "2024/07/08",
description = "Lua package to typeset Metapost with LuaTeX's MPLib.",
}
@@ -60,6 +60,7 @@ luamplib.showlog = luamplib.showlog or false
local tableconcat = table.concat
local tableinsert = table.insert
+local tableunpack = table.unpack
local texsprint = tex.sprint
local texgettoks = tex.gettoks
local texgetbox = tex.getbox
@@ -580,7 +581,7 @@ function luamplib.runscript (code)
return buffer
end
buffer = {}
- mpprint(buffer, table.unpack(res))
+ mpprint(buffer, tableunpack(res))
return tableconcat(buffer)
end
return ""
@@ -660,15 +661,14 @@ luamplib.shadecolor = function (str)
run_tex_code({
[[\color_export:nnN{]], str, [[}{backend}\mplib_@tempa]],
},ccexplat)
- local name = get_macro'mplib_@tempa':match'{(.-)}{.+}'
+ local name, value = get_macro'mplib_@tempa':match'{(.-)}{(.-)}'
local t, obj = res:explode()
if pdfmode then
obj = format("%s 0 R", ltx.pdf.object_id( t[1]:sub(2,-1) ))
else
obj = t[2]
end
- local value = t[3]:match"%[(.-)%]" or t[3]
- return format('(%s) withprescript"mplib_spotcolor=%s:%s"', value,obj,name)
+ return format('(1) withprescript"mplib_spotcolor=%s:%s:%s"', value,obj,name)
end
return colorsplit(res)
end
@@ -1417,6 +1417,39 @@ vardef mplibtransformmatrix (text e) =
& decimal ypart t & ","
& "}");
enddef;
+primarydef p withfademethod s =
+ p withprescript "mplibfadetype=" & s
+ withprescript "mplibfadebbox=" &
+ decimal xpart llcorner p & ":" &
+ decimal ypart llcorner p & ":" &
+ decimal xpart urcorner p & ":" &
+ decimal ypart urcorner p
+enddef;
+def withfadeopacity (expr a,b) =
+ withprescript "mplibfadeopacity=" &
+ decimal a & ":" &
+ decimal b
+enddef;
+def withfadevector (expr a,b) =
+ withprescript "mplibfadevector=" &
+ decimal xpart a & ":" &
+ decimal ypart a & ":" &
+ decimal xpart b & ":" &
+ decimal ypart b
+enddef;
+let withfadecenter = withfadevector;
+def withfaderadius (expr a,b) =
+ withprescript "mplibfaderadius=" &
+ decimal a & ":" &
+ decimal b
+enddef;
+def withfadebbox (expr a,b) =
+ withprescript "mplibfadebbox=" &
+ decimal xpart a & ":" &
+ decimal ypart a & ":" &
+ decimal xpart b & ":" &
+ decimal ypart b
+enddef;
]],
legacyverbatimtex = [[
def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
@@ -1720,19 +1753,29 @@ pdfetcs.pgfextgs = "pgf@sys@addpdfresource@extgs@plain"
pdfetcs.pgfpattern = "pgf@sys@addpdfresource@patterns@plain"
pdfetcs.pgfcolorspace = "pgf@sys@addpdfresource@colorspaces@plain"
-local function update_pdfobjs (os)
- local on = pdfobjs[os]
+local function update_pdfobjs (os, stream)
+ local key = os
+ if stream then key = key..stream end
+ local on = pdfobjs[key]
if on then
return on,false
end
if pdfmode then
- on = pdf.immediateobj(os)
+ if stream then
+ on = pdf.immediateobj("stream",stream,os)
+ else
+ on = pdf.immediateobj(os)
+ end
else
on = pdfetcs.cnt or 1
- texsprint(format("\\special{pdf:obj @mplibpdfobj%s %s}",on,os))
+ if stream then
+ texsprint(format("\\special{pdf:stream @mplibpdfobj%s (%s) <<%s>>}",on,stream,os))
+ else
+ texsprint(format("\\special{pdf:obj @mplibpdfobj%s %s}",on,os))
+ end
pdfetcs.cnt = on + 1
end
- pdfobjs[os] = on
+ pdfobjs[key] = on
return on,true
end
@@ -1785,12 +1828,9 @@ local transparancy_modes = { [0] = "Normal",
"Hue", "Saturation", "Color", "Luminosity",
"Compatible",
}
-
-local function update_tr_res(mode,opaq)
- local os = format("<</BM /%s/ca %.3f/CA %.3f/AIS false>>",mode,opaq,opaq)
- local on, new = update_pdfobjs(os)
+local function add_extgs_resources (on, new)
+ local key = format("MPlibTr%s", on)
if new then
- local key = format("MPlibTr%s", on)
local val = format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on)
if pdfmanagement then
texsprint {
@@ -1822,21 +1862,22 @@ local function update_tr_res(mode,opaq)
if not pdfmode and not pdfmanagement and not is_defined(pdfetcs.pgfextgs) then
texsprint"\\special{pdf:put @resources <</ExtGState @MPlibTr>>}"
end
- return on
+ return key
end
-
local function do_preobj_TR(object,prescript)
if object.postscript == "collect" then return end
local opaq = prescript and prescript.tr_transparency
- local tron_no
+ local on
if opaq then
local mode = prescript.tr_alternative or 1
mode = transparancy_modes[tonumber(mode)]
- tron_no = update_tr_res(mode, opaq)
+ local os, new = format("<</BM /%s/ca %.3f/CA %.3f/AIS false>>",mode,opaq,opaq)
+ on, new = update_pdfobjs(os)
+ local key = add_extgs_resources(on,new)
start_pdf_code()
- pdf_literalcode("/MPlibTr%i gs",tron_no)
+ pdf_literalcode("/%s gs",key)
end
- return tron_no
+ return on
end
local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,steps,fractions)
@@ -1970,15 +2011,14 @@ local function do_preobj_SH(object,prescript)
local script = object.prescript:explode"\13+"
for i=#script,1,-1 do
if script[i]:find"mplib_spotcolor" then
- local name, value
- objref, name = script[i]:match"=(.-):(.+)"
- value = script[i+1]:match"=(.+)"
+ local t, name, value = script[i]:explode"="[2]:explode":"
+ value, objref, name = t[1], t[2], t[3]
if not names[name] then
pos = pos+1
names[name] = pos
names[#names+1] = name
end
- local t = { }
+ t = { }
for j=1,names[name] do t[#t+1] = 0 end
t[#t+1] = value
tableinsert(#ca == #cb and ca or cb, t)
@@ -2215,6 +2255,86 @@ local function do_preobj_PAT(object, prescript)
patt.done = true
end
+local function do_preobj_FADE (object, prescript)
+ if object.postscript == "collect" then return end
+ local fd_type = prescript and prescript.mplibfadetype
+ if not fd_type then return end
+ local dx, dy = 0, 0
+ local bbox = prescript.mplibfadebbox:explode":"
+ if tonumber(bbox[1]) < 0 then
+ dx = -bbox[1]
+ bbox[1], bbox[3] = 0, bbox[3] + dx
+ end
+ if tonumber(bbox[2]) < 0 then
+ dy = -bbox[2]
+ bbox[2], bbox[4] = 0, bbox[4] + dy
+ end
+ local vec, coords = prescript.mplibfadevector, { }
+ if vec then
+ vec = vec:explode":"
+ for i=1,4 do
+ coords[#coords+1] = vec[i] + (i % 2 == 0 and dy or dx)
+ end
+ end
+ if fd_type == "linear" then
+ if not vec then
+ coords = { bbox[1], bbox[2], bbox[3], bbox[2] } -- left to right
+ end
+ coords = format("%f %f %f %f", tableunpack(coords))
+ elseif fd_type == "circular" then
+ local width, height = bbox[3]-bbox[1], bbox[4]-bbox[2]
+ if not vec then
+ coords = { width/2, height/2, width/2, height/2 } -- center for both circle
+ end
+ local radius = prescript.mplibfaderadius or format("0:%f",math.sqrt(width^2+height^2)/2);
+ radius = radius:explode":"
+ tableinsert(coords, 3, radius[1])
+ tableinsert(coords, radius[2])
+ coords = format("%f %f %f %f %f %f", tableunpack(coords))
+ else
+ err("unknown fading method '%s'", fd_type)
+ end
+ fd_type = fd_type == "linear" and 2 or 3
+ bbox = format("%f %f %f %f", tableunpack(bbox))
+ local opaq = (prescript.mplibfadeopacity or "1:0"):explode":"
+ local ca, cb = {{ opaq[1] }}, {{ opaq[2] }}
+ local on, os, new
+ on = sh_pdfpageresources(fd_type, "0 1", "/DeviceGray", ca, cb, coords, 1)
+ if pdfmode then
+ os = format("<</PatternType 2/Shading %s 0 R>>", on)
+ else
+ os = format("<</PatternType 2/Shading @mplibpdfobj%s>>", on)
+ end
+ on = update_pdfobjs(os)
+ local streamtext = format("q /Pattern cs/MPlibFd%s scn %s re f Q", on, bbox)
+ if pdfmode then
+ os = format("<</Pattern<</MPlibFd%s %s 0 R>>>>", on, on)
+ else
+ os = format("<</Pattern<</MPlibFd%s @mplibpdfobj%s>>>>", on, on)
+ end
+ on = update_pdfobjs(os)
+ local resources = "/Resources "..format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on)
+ on = update_pdfobjs"<</S/Transparency/CS/DeviceGray>>"
+ local attr = tableconcat{
+ "/Subtype/Form",
+ format("/BBox[%s]", bbox),
+ format("/Matrix[1 0 0 1 %f %f]", -dx, -dy),
+ resources,
+ "/Group ", format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on),
+ }
+ on = update_pdfobjs(attr, streamtext)
+ os = tableconcat {
+ "<</SMask<</S/Luminosity/G ",
+ format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on),
+ ">>>>",
+ }
+ on, new = update_pdfobjs(os)
+ local key = add_extgs_resources(on,new)
+ start_pdf_code()
+ pdf_literalcode("/%s gs", key)
+ return on
+end
+
function luamplib.flush (result,flusher)
if result then
local figures = result.fig
@@ -2244,6 +2364,7 @@ function luamplib.flush (result,flusher)
prescript = prescript and script2table(prescript) -- prescript is now a table
local cr_over = do_preobj_CR(object,prescript) -- color
local tr_opaq = do_preobj_TR(object,prescript) -- opacity
+ local fading_ = do_preobj_FADE(object,prescript) -- fading
if prescript and prescript.mplibtexboxid then
put_tex_boxes(object,prescript)
elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then --skip
@@ -2407,6 +2528,9 @@ function luamplib.flush (result,flusher)
end
end
end
+ if fading_ then -- fading
+ stop_pdf_code()
+ end
if tr_opaq then -- opacity
stop_pdf_code()
end