diff options
author | Karl Berry <karl@freefriends.org> | 2024-07-08 20:15:15 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-07-08 20:15:15 +0000 |
commit | 157f4b8ca0dfcec0e44b6e4d93a29d93870a8860 (patch) | |
tree | 29df4a8a93652e8d296009afc531a5f070dcd8f7 /Master/texmf-dist/tex/luatex/luamplib/luamplib.lua | |
parent | 4d2e984c25f3d1250d4df0d7be6649f405e3af0a (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.lua | 176 |
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 |