summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2024-05-10 21:15:13 +0000
committerKarl Berry <karl@freefriends.org>2024-05-10 21:15:13 +0000
commitd6f9d4fa306a12d02ed079390ada9b5e4164b1c6 (patch)
tree04ae5add78553df29bddee161a714dd5ff8a21a2 /Master/texmf-dist/tex/luatex
parent4509574ed056cb5935f4a8c0c43d746ae1922161 (diff)
luamplib (10may24)
git-svn-id: svn://tug.org/texlive/trunk@71225 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
-rw-r--r--Master/texmf-dist/tex/luatex/luamplib/luamplib.lua734
-rw-r--r--Master/texmf-dist/tex/luatex/luamplib/luamplib.sty2
2 files changed, 438 insertions, 298 deletions
diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua b/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
index f9286a0d08d..5d5870deb9e 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.29.0",
- date = "2024/05/01",
+ version = "2.30.0",
+ date = "2024/05/10",
description = "Lua package to typeset Metapost with LuaTeX's MPLib.",
}
@@ -59,6 +59,7 @@ end
luamplib.showlog = luamplib.showlog or false
local tableconcat = table.concat
+local tableinsert = table.insert
local texsprint = tex.sprint
local texgettoks = tex.gettoks
local texgetbox = tex.getbox
@@ -109,7 +110,7 @@ luamplibtime = luamplibtime and lfsattributes(luamplibtime,"modification")
local currenttime = os.time()
-local outputdir
+local outputdir, cachedir
if lfstouch then
for i,v in ipairs{'TEXMFVAR','TEXMF_OUTPUT_DIRECTORY','.','TEXMFOUTPUT'} do
local var = i == 3 and v or kpse.var_value(v)
@@ -129,7 +130,6 @@ if lfstouch then
end
end
outputdir = outputdir or '.'
-
function luamplib.getcachedir(dir)
dir = dir:gsub("##","#")
dir = dir:gsub("^~",
@@ -137,7 +137,7 @@ function luamplib.getcachedir(dir)
if lfstouch and dir then
if lfsisdir(dir) then
if is_writable(dir) then
- luamplib.cachedir = dir
+ cachedir = dir
else
warn("Directory '%s' is not writable!", dir)
end
@@ -191,9 +191,8 @@ local verbatimtex_etex = name_b.."verbatimtex"..name_e.."%s*(.-)%s*"..name_b.."e
local function replaceinputmpfile (name,file)
local ofmodify = lfsattributes(file,"modification")
if not ofmodify then return file end
- local cachedir = luamplib.cachedir or outputdir
local newfile = name:gsub("%W","_")
- newfile = cachedir .."/luamplib_input_"..newfile
+ newfile = format("%s/luamplib_input_%s", cachedir or outputdir, newfile)
if newfile and luamplibtime then
local nf = lfsattributes(newfile)
if nf and nf.mode == "file" and
@@ -245,7 +244,7 @@ local special_ftype = {
enc = "enc files",
}
-local function finder(name, mode, ftype)
+function luamplib.finder (name, mode, ftype)
if mode == "w" then
if name and name ~= "mpout.log" then
kpse.record_output_file(name) -- recorder
@@ -267,7 +266,6 @@ local function finder(name, mode, ftype)
return file
end
end
-luamplib.finder = finder
local preamble = [[
boolean mplib ; mplib := true ;
@@ -277,10 +275,9 @@ local preamble = [[
]]
local currentformat = "plain"
-local function setformat (name)
+function luamplib.setformat (name)
currentformat = name
end
-luamplib.setformat = setformat
luamplib.codeinherit = false
local mplibinstances = {}
@@ -331,9 +328,9 @@ local function luamplibload (name)
}
local preamble = tableconcat{
format(preamble, replacesuffix(name,"mp")),
- luamplib.mplibcodepreamble,
- luamplib.legacy_verbatimtex and luamplib.legacyverbatimtexpreamble or "",
- luamplib.textextlabel and luamplib.textextlabelpreamble or "",
+ luamplib.preambles.mplibcode,
+ luamplib.legacy_verbatimtex and luamplib.preambles.legacyverbatimtex or "",
+ luamplib.textextlabel and luamplib.preambles.textextlabel or "",
}
local result, log
if not mpx then
@@ -454,7 +451,7 @@ if colfmt == "l3color" then
end
local ccexplat = luatexbase.registernumber"luamplibcctabexplat"
-local function process_color (str, kind)
+local function process_color (str)
if str then
if not str:find("%b{}") then
str = format("{%s}",str)
@@ -475,94 +472,16 @@ local function process_color (str, kind)
end
end
end
- if myfmt == mplibcolorfmt.l3color and (kind == "fill" or kind == "draw") then return str end
run_tex_code(myfmt:format(str), ccexplat or catat11)
local t = texgettoks"mplibtmptoks"
if not pdfmode and not t:find"^pdf" then
t = t:gsub("%a+ (.+)","pdf:bc [%1]")
end
- if kind then return t end
- return format('1 withprescript "MPlibOverrideColor=%s"', t)
+ return format('1 withprescript "mpliboverridecolor=%s"', t)
end
return ""
end
-local function colorsplit (res)
- local t, tt = { }, res:gsub("[%[%]]",""):explode()
- local be = tt[1]:find"^%d" and 1 or 2
- for i=be, #tt do
- if tt[i]:find"^%a" then break end
- t[#t+1] = tt[i]
- end
- return t
-end
-
-luamplib.outlinecolor = function (str, filldraw)
- local nn = filldraw == "fill" and 'fn:=' or 'dn:='
- local cc = filldraw == "fill" and 'fc:=' or 'dc:='
- local res = process_color(str, filldraw)
- if res:match"{(.+)}" == str then
- return format('%s"n"; %s"%s";', nn,cc,str)
- end
- local t = colorsplit(res)
- local md = #t == 1 and 'gray' or #t == 3 and 'rgb' or #t == 4 and 'cmyk'
- return format('%s"nn"; %s"%s}{%s";', nn, cc, md, tableconcat(t,','))
-end
-
-luamplib.gettexcolor = function (str, rgb)
- local res = process_color(str, "metapost")
- if res:find" cs " or res:find"@pdf.obj" then
- if not rgb then
- warn("%s is a spot color. Forced to CMYK", str)
- end
- run_tex_code({
- "\\color_export:nnN{",
- str,
- "}{",
- rgb and "space-sep-rgb" or "space-sep-cmyk",
- "}\\mplib_@tempa",
- },ccexplat)
- return get_macro"mplib_@tempa":explode()
- end
- local t = colorsplit(res)
- if #t == 3 or not rgb then return t end
- run_tex_code({ -- force to rgb
- "\\color_export:nnnN{",
- #t == 4 and "cmyk" or "gray",
- "}{",
- tableconcat(t,","),
- "}{space-sep-rgb}\\mplib_@tempa",
- },ccexplat)
- return get_macro"mplib_@tempa":explode()
-end
-
-luamplib.shadecolor = function (str)
- local res = process_color(str, "shade")
- if res:find" cs " or res:find"@pdf.obj" then -- spot color shade: l3 only
- run_tex_code({
- [[\color_export:nnN{]], str, [[}{backend}\mplib_@tempa]],
- },ccexplat)
- local name = get_macro'mplib_@tempa':match'{(.-)}{.+}'
- local t, obj = res:explode()
- if pdfmode then
- obj = t[1]:match"^/(.+)"
- if ltx.pdf and ltx.pdf.object_id then
- obj = format("%s 0 R", ltx.pdf.object_id(obj))
- else
- run_tex_code({
- [[\edef\mplib_@tempa{\pdf_object_ref:n{]], obj, "}}",
- },ccexplat)
- obj = get_macro'mplib_@tempa'
- end
- else
- obj = t[2]
- end
- local value = t[3]:match"%[(.-)%]" or t[3]
- return format('(%s) withprescript"mplib_spotcolor=%s:%s"', value,obj,name)
- end
- return colorsplit(res)
-end
-
local function process_dimen (str)
if str then
str = str:gsub("{(.+)}","%1")
@@ -703,15 +622,295 @@ function luamplib.maketext (str, what)
return ""
end
-local mplibcodepreamble = [[
+local function colorsplit (res)
+ local t, tt = { }, res:gsub("[%[%]]",""):explode()
+ local be = tt[1]:find"^%d" and 1 or 2
+ for i=be, #tt do
+ if tt[i]:find"^%a" then break end
+ t[#t+1] = tt[i]
+ end
+ return t
+end
+
+local min = math.min
+luamplib.gettexcolor = function (str, rgb)
+ local res = process_color(str):match'"mpliboverridecolor=(.+)"'
+ if res:find" cs " or res:find"@pdf.obj" then
+ if not rgb then
+ warn("%s is a spot color. Forced to CMYK", str)
+ end
+ run_tex_code({
+ "\\color_export:nnN{",
+ str,
+ "}{",
+ rgb and "space-sep-rgb" or "space-sep-cmyk",
+ "}\\mplib_@tempa",
+ },ccexplat)
+ return get_macro"mplib_@tempa":explode()
+ end
+ local t = colorsplit(res)
+ if #t == 3 or not rgb then return t end
+ if #t == 4 then
+ return { 1 - min(1,t[1]+t[4]), 1 - min(1,t[2]+t[4]), 1 - min(1,t[3]+t[4]) }
+ end
+ return { t[1], t[1], t[1] }
+end
+
+luamplib.shadecolor = function (str)
+ local res = process_color(str):match'"mpliboverridecolor=(.+)"'
+ if res:find" cs " or res:find"@pdf.obj" then -- spot color shade: l3 only
+ run_tex_code({
+ [[\color_export:nnN{]], str, [[}{backend}\mplib_@tempa]],
+ },ccexplat)
+ local name = get_macro'mplib_@tempa':match'{(.-)}{.+}'
+ local t, obj = res:explode()
+ if pdfmode then
+ obj = t[1]:match"^/(.+)"
+ if ltx.pdf and ltx.pdf.object_id then
+ obj = format("%s 0 R", ltx.pdf.object_id(obj))
+ else
+ run_tex_code({
+ [[\edef\mplib_@tempa{\pdf_object_ref:n{]], obj, "}}",
+ },ccexplat)
+ obj = get_macro'mplib_@tempa'
+ end
+ else
+ obj = t[2]
+ end
+ local value = t[3]:match"%[(.-)%]" or t[3]
+ return format('(%s) withprescript"mplib_spotcolor=%s:%s"', value,obj,name)
+ end
+ return colorsplit(res)
+end
+
+local emboldenfonts = { }
+local function embolden (head, fakebold)
+ local curr = head
+ while curr do
+ if curr.head then
+ embolden(curr.head, fakebold)
+ elseif curr.leader and curr.leader.head then
+ embolden(curr.leader.head, fakebold)
+ elseif curr.id == node.id"glyph" and curr.font > 0 then
+ local f = curr.font
+ local i = emboldenfonts[f]
+ if not i then
+ if pdfmode then
+ local ft = font.getcopy(f)
+ ft.mode = 2
+ ft.width = ft.size * fakebold / 6578.176
+ i = font.define(ft)
+ else
+ local ft = font.getfont(f) or font.getcopy(f)
+ if ft.format ~= "opentype" and ft.format ~= "truetype" then
+ goto skip_type1
+ end
+ local name = ft.name:gsub('"',''):gsub(';$','')
+ name = format('%s;embolden=%s',name,fakebold)
+ _, i = fonts.constructors.readanddefine(name,ft.size)
+ end
+ emboldenfonts[f] = i
+ end
+ curr.font = i
+ end
+ ::skip_type1::
+ curr = node.getnext(curr)
+ end
+end
+local function graphictextcolor (col, filldraw)
+ if col:find"^[%d%.:]+$" then
+ col = col:explode":"
+ if pdfmode then
+ local op = #col == 4 and "k" or #col == 3 and "rg" or "g"
+ col[#col+1] = filldraw == "fill" and op or op:upper()
+ return tableconcat(col," ")
+ end
+ return format("[%s]", tableconcat(col," "))
+ end
+ col = process_color(col):match'"mpliboverridecolor=(.+)"'
+ if pdfmode then
+ local t, tt = col:explode(), { }
+ local b = filldraw == "fill" and 1 or #t/2+1
+ local e = b == 1 and #t/2 or #t
+ for i=b,e do
+ tt[#tt+1] = t[i]
+ end
+ return tableconcat(tt," ")
+ end
+ return col:gsub("^.- ","")
+end
+luamplib.graphictext = function (text, fakebold, fc, dc)
+ local fmt = process_tex_text(text):sub(1,-2)
+ local id = tonumber(fmt:match"mplibtexboxid=(%d+):")
+ embolden(texgetbox(id).head, fakebold)
+ local fill = graphictextcolor(fc,"fill")
+ local draw = graphictextcolor(dc,"draw")
+ local bc = pdfmode and "" or "pdf:bc "
+ return format('%s withprescript "mpliboverridecolor=%s%s %s")', fmt, bc, fill, draw)
+end
+
+local function mperr (str)
+ return format("hide(errmessage %q)", str)
+end
+local function getangle (a,b,c)
+ local r = math.deg(math.atan(c.y-b.y, c.x-b.x) - math.atan(b.y-a.y, b.x-a.x))
+ if r > 180 then
+ r = r - 360
+ elseif r < -180 then
+ r = r + 360
+ end
+ return r
+end
+local function turning (t)
+ local r, n = 0, #t
+ for i=1,2 do
+ tableinsert(t, t[i])
+ end
+ for i=1,n do
+ r = r + getangle(t[i], t[i+1], t[i+2])
+ end
+ return r/360
+end
+local function glyphimage(t, fmt)
+ local q,p,r = {{},{}}
+ for i,v in ipairs(t) do
+ local cmd = v[#v]
+ if cmd == "m" then
+ p = {format('(%s,%s)',v[1],v[2])}
+ r = {{x=v[1],y=v[2]}}
+ else
+ local nt = t[i+1]
+ local last = not nt or nt[#nt] == "m"
+ if cmd == "l" then
+ local pt = t[i-1]
+ local seco = pt[#pt] == "m"
+ if (last or seco) and r[1].x == v[1] and r[1].y == v[2] then
+ else
+ tableinsert(p, format('--(%s,%s)',v[1],v[2]))
+ tableinsert(r, {x=v[1],y=v[2]})
+ end
+ if last then
+ tableinsert(p, '--cycle')
+ end
+ elseif cmd == "c" then
+ tableinsert(p, format('..controls(%s,%s)and(%s,%s)',v[1],v[2],v[3],v[4]))
+ if last and r[1].x == v[5] and r[1].y == v[6] then
+ tableinsert(p, '..cycle')
+ else
+ tableinsert(p, format('..(%s,%s)',v[5],v[6]))
+ if last then
+ tableinsert(p, '--cycle')
+ end
+ tableinsert(r, {x=v[5],y=v[6]})
+ end
+ else
+ return mperr"unknown operator"
+ end
+ if last then
+ tableinsert(q[ turning(r) > 0 and 1 or 2 ], tableconcat(p))
+ end
+ end
+ end
+ r = { }
+ if fmt == "opentype" then
+ for _,v in ipairs(q[1]) do
+ tableinsert(r, format('addto currentpicture contour %s;',v))
+ end
+ for _,v in ipairs(q[2]) do
+ tableinsert(r, format('addto currentpicture contour %s withcolor background;',v))
+ end
+ else
+ for _,v in ipairs(q[2]) do
+ tableinsert(r, format('addto currentpicture contour %s;',v))
+ end
+ for _,v in ipairs(q[1]) do
+ tableinsert(r, format('addto currentpicture contour %s withcolor background;',v))
+ end
+ end
+ return format('image(%s)', tableconcat(r))
+end
+if not table.tofile then require"lualibs-lpeg"; require"lualibs-table"; end
+function luamplib.glyph (f, c)
+ local filename, subfont, instance, kind, shapedata
+ local fid = tonumber(f) or font.id(f) -- string: fontname
+ if fid > 0 then
+ local fontdata = font.getfont(fid) or font.getcopy(fid)
+ filename, subfont, kind = fontdata.filename, fontdata.subfont, fontdata.format
+ instance = fontdata.specification and fontdata.specification.instance
+ else
+ local name
+ f = f:match"^%s*(.+)%s*$"
+ name, subfont, instance = f:match"(.+)%((%d+)%)%[(.-)%]$"
+ if not name then
+ name, instance = f:match"(.+)%[(.-)%]$" -- SourceHanSansK-VF.otf[Heavy]
+ end
+ if not name then
+ name, subfont = f:match"(.+)%((%d+)%)$" -- Times.ttc(2)
+ end
+ name = name or f
+ subfont = (subfont or 0)+1
+ instance = instance and instance:lower()
+ for _,ftype in ipairs{"opentype", "truetype"} do
+ filename = kpse.find_file(name, ftype.." fonts")
+ if filename then
+ kind = ftype; break
+ end
+ end
+ end
+ if kind ~= "opentype" and kind ~= "truetype" then
+ f = fid and fid > 0 and tex.fontname(fid) or f
+ if kpse.find_file(f, "tfm") then
+ return format("glyph %s of %q", tonumber(c) or format("%q",c), f)
+ else
+ return mperr"font not found"
+ end
+ end
+ local time = lfsattributes(filename,"modification")
+ local k = format("shapes_%s(%s)[%s]", filename, subfont or "", instance or "")
+ local h = format(string.rep('%02x', 256/8), string.byte(sha2.digest256(k), 1, -1))
+ local newname = format("%s/%s.lua", cachedir or outputdir, h)
+ local newtime = lfsattributes(newname,"modification") or 0
+ if time == newtime then
+ shapedata = require(newname)
+ end
+ if not shapedata then
+ shapedata = fonts and fonts.handlers.otf.readers.loadshapes(filename,subfont,instance)
+ if not shapedata then return mperr"loadshapes() failed. luaotfload not loaded?" end
+ table.tofile(newname, shapedata, "return")
+ lfstouch(newname, time, time)
+ end
+ local gid = tonumber(c)
+ if not gid then
+ local uni = utf8.codepoint(c)
+ for i,v in pairs(shapedata.glyphs) do
+ if c == v.name or uni == v.unicode then
+ gid = i; break
+ end
+ end
+ end
+ if not gid then return mperr"cannot get GID (glyph id)" end
+ local fac = 1000 / (shapedata.units or 1000)
+ local t = shapedata.glyphs[gid].segments
+ if not t then return mperr"glyph has no contour. Maybe blank space" end
+ for i,v in ipairs(t) do
+ if type(v) == "table" then
+ for ii,vv in ipairs(v) do
+ if type(vv) == "number" then
+ t[i][ii] = format("%.0f", vv * fac)
+ end
+ end
+ end
+ end
+ return glyphimage(t, kind)
+end
+
+luamplib.preambles = {
+ mplibcode = [[
texscriptmode := 2;
def rawtextext (expr t) = runscript("luamplibtext{"&t&"}") enddef;
def mplibcolor (expr t) = runscript("luamplibcolor{"&t&"}") enddef;
def mplibdimen (expr t) = runscript("luamplibdimen{"&t&"}") enddef;
def VerbatimTeX (expr t) = runscript("luamplibverbtex{"&t&"}") enddef;
-def message expr t =
- if string t: runscript("mp.report[=["&t&"]=]") else: errmessage "Not a string" fi
-enddef;
if known context_mlib:
defaultfont := "cmtt10";
let infont = normalinfont;
@@ -725,23 +924,27 @@ if known context_mlib:
(1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
fi
enddef;
- def colordecimals primary c =
- if cmykcolor c:
- decimal cyanpart c & ":" & decimal magentapart c & ":" & decimal yellowpart c & ":" & decimal blackpart c
- elseif rgbcolor c:
- decimal redpart c & ":" & decimal greenpart c & ":" & decimal bluepart c
- elseif string c:
- colordecimals resolvedcolor(c)
- else:
- decimal c
- fi
- enddef;
- def resolvedcolor(expr s) =
- runscript("return luamplib.shadecolor('"& s &"')")
- enddef;
else:
vardef textext@# (text t) = rawtextext (t) enddef;
+ def message expr t =
+ if string t: runscript("mp.report[=["&t&"]=]") else: errmessage "Not a string" fi
+ enddef;
fi
+def resolvedcolor(expr s) =
+ runscript("return luamplib.shadecolor('"& s &"')")
+enddef;
+def colordecimals primary c =
+ if cmykcolor c:
+ decimal cyanpart c & ":" & decimal magentapart c & ":" &
+ decimal yellowpart c & ":" & decimal blackpart c
+ elseif rgbcolor c:
+ decimal redpart c & ":" & decimal greenpart c & ":" & decimal bluepart c
+ elseif string c:
+ if known graphictextpic: c else: colordecimals resolvedcolor(c) fi
+ else:
+ decimal c
+ fi
+enddef;
def externalfigure primary filename =
draw rawtextext("\includegraphics{"& filename &"}")
enddef;
@@ -758,55 +961,43 @@ def mplibgraphictext primary t =
enddef;
def mplibgraphictext_ (expr t) text rest =
save fakebold, scale, fillcolor, drawcolor, withfillcolor, withdrawcolor,
- fb, sc, fc, dc, fn, dn, tpic;
- picture tpic; tpic := nullpicture;
- numeric fb, sc; string fc, dc, fn, dn;
- fb:=2; sc:=1; fc:="white"; dc:="black"; fn:=dn:="n";
+ fb, fc, dc, graphictextpic;
+ picture graphictextpic; graphictextpic := nullpicture;
+ numeric fb; string fc, dc; fb:=2; fc:="white"; dc:="black";
+ let scale = scaled;
def fakebold primary c = hide(fb:=c;) enddef;
- def scale primary c = hide(sc:=c;) enddef;
- def fillcolor primary c = hide(
- if string c:
- runscript("return luamplib.outlinecolor('"& c &"','fill')")
- else:
- fn:="nn"; fc:=mpliboutlinecolor_(c);
- fi
- ) enddef;
- def drawcolor primary c = hide(
- if string c:
- runscript("return luamplib.outlinecolor('"& c &"','draw')")
- else:
- dn:="nn"; dc:=mpliboutlinecolor_(c);
- fi
- ) enddef;
+ def fillcolor primary c = hide(fc:=colordecimals c;) enddef;
+ def drawcolor primary c = hide(dc:=colordecimals c;) enddef;
let withfillcolor = fillcolor; let withdrawcolor = drawcolor;
- addto tpic doublepath origin rest; tpic:=nullpicture;
+ addto graphictextpic doublepath origin rest; graphictextpic:=nullpicture;
def fakebold primary c = enddef;
- def scale primary c = enddef;
- def fillcolor primary c = enddef;
- def drawcolor primary c = enddef;
+ let fillcolor = fakebold; let drawcolor = fakebold;
let withfillcolor = fillcolor; let withdrawcolor = drawcolor;
- image(draw rawtextext(
- "{\addfontfeature{FakeBold="& decimal fb &",Scale="& decimal sc &
- "}\csname color_fill:"& fn &"\endcsname{"& fc &
- "}\csname color_stroke:"& dn &"\endcsname{"& dc &
- "}"& t &"}") rest;)
+ image(draw runscript("return luamplib.graphictext([===["&t&"]===],"
+ & decimal fb &",'"& fc &"','"& dc &"')") rest;)
endgroup;
enddef;
-def mpliboutlinecolor_ (expr c) =
- if color c:
- "rgb}{" & decimal redpart c & "," & decimal greenpart c
- & "," & decimal bluepart c
- elseif cmykcolor c:
- "cmyk}{" & decimal cyanpart c & "," & decimal magentapart c
- & "," & decimal yellowpart c & "," & decimal blackpart c
- else:
- "gray}{" & decimal c
- fi
+def mplibglyph expr c of f =
+ runscript (
+ "return luamplib.glyph('"
+ & if numeric f: decimal fi f
+ & "','"
+ & if numeric c: decimal fi c
+ & "')"
+ )
enddef;
-]]
-luamplib.mplibcodepreamble = mplibcodepreamble
-
-local legacyverbatimtexpreamble = [[
+def mplibdrawglyph expr g =
+ draw image(
+ save i; numeric i; i:=0;
+ for item within g:
+ i := i+1;
+ fill pathpart item
+ if i < length g: withpostscript "collect" fi;
+ endfor
+ )
+enddef;
+]],
+ legacyverbatimtex = [[
def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
def normalVerbatimTeX (text t) = runscript("luamplibinfig{"&t&"}") enddef;
let VerbatimTeX = specialVerbatimTeX;
@@ -816,10 +1007,8 @@ extra_endfig := extra_endfig & " let VerbatimTeX = specialVerbatimTeX;"&
"runscript(" &ditto&
"if luamplib.in_the_fig then luamplib.figid=luamplib.figid+1 end "&
"luamplib.in_the_fig=false" &ditto& ");";
-]]
-luamplib.legacyverbatimtexpreamble = legacyverbatimtexpreamble
-
-local textextlabelpreamble = [[
+]],
+ textextlabel = [[
primarydef s infont f = rawtextext(s) enddef;
def fontsize expr f =
begingroup
@@ -828,8 +1017,8 @@ def fontsize expr f =
if size = 0: 10pt else: size fi
endgroup
enddef;
-]]
-luamplib.textextlabelpreamble = textextlabelpreamble
+]],
+}
luamplib.verbatiminput = false
@@ -857,7 +1046,7 @@ end
luamplib.everymplib = setmetatable({ [""] = "" },{ __index = function(t) return t[""] end })
luamplib.everyendmplib = setmetatable({ [""] = "" },{ __index = function(t) return t[""] end })
-local function process_mplibcode (data, instancename)
+function luamplib.process_mplibcode (data, instancename)
texboxes.localid = 4096
if luamplib.legacy_verbatimtex then
@@ -900,7 +1089,6 @@ local function process_mplibcode (data, instancename)
process(data, instancename)
end
-luamplib.process_mplibcode = process_mplibcode
local further_split_keys = {
mplibtexboxid = true,
@@ -926,11 +1114,10 @@ local function getobjects(result,figure,f)
return figure:objects()
end
-local function convert(result, flusher)
+function luamplib.convert (result, flusher)
luamplib.flush(result, flusher)
return true -- done
end
-luamplib.convert = convert
local figcontents = { post = { } }
local function put2output(a,...)
@@ -1081,7 +1268,7 @@ end
local prev_override_color
local function do_preobj_CR(object,prescript)
- local override = prescript and prescript.MPlibOverrideColor
+ local override = prescript and prescript.mpliboverridecolor
if override then
if pdfmode then
pdf_literalcode(override)
@@ -1109,13 +1296,6 @@ local pdfmanagement = is_defined'pdfmanagement_add:nnn'
local pdfobjs, pdfetcs = {}, {}
pdfetcs.pgfextgs = "pgf@sys@addpdfresource@extgs@plain"
-if pdfmode then
- pdfetcs.getpageres = pdf.getpageresources or function() return pdf.pageresources end
- pdfetcs.setpageres = pdf.setpageresources or function(s) pdf.pageresources = s end
-else
- texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}")
-end
-
local function update_pdfobjs (os)
local on = pdfobjs[os]
if on then
@@ -1132,6 +1312,38 @@ local function update_pdfobjs (os)
return on,true
end
+if pdfmode then
+ pdfetcs.getpageres = pdf.getpageresources or function() return pdf.pageresources end
+ pdfetcs.setpageres = pdf.setpageresources or function(s) pdf.pageresources = s end
+ pdfetcs.initialize_resources = function (name)
+ local tabname = format("%s_res",name)
+ pdfetcs[tabname] = { }
+ if luatexbase.callbacktypes.finish_pdffile then -- ltluatex
+ local obj = pdf.reserveobj()
+ pdfetcs.setpageres(format("%s/%s %i 0 R", pdfetcs.getpageres() or "", name, obj))
+ luatexbase.add_to_callback("finish_pdffile", function()
+ pdf.immediateobj(obj, format("<<%s>>", tableconcat(pdfetcs[tabname])))
+ end,
+ format("luamplib.%s.finish_pdffile",name))
+ end
+ end
+ pdfetcs.fallback_update_resources = function (name, res)
+ if luatexbase.callbacktypes.finish_pdffile then
+ local t = pdfetcs[format("%s_res",name)]
+ t[#t+1] = res
+ else
+ local tpr, n = pdfetcs.getpageres() or "", 0
+ tpr, n = tpr:gsub(format("/%s<<",name), "%1"..res)
+ if n == 0 then
+ tpr = format("%s/%s<<%s>>", tpr, name, res)
+ end
+ pdfetcs.setpageres(tpr)
+ end
+ end
+else
+ texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}")
+end
+
local transparancy_modes = { [0] = "Normal",
"Normal", "Multiply", "Screen", "Overlay",
"SoftLight", "HardLight", "ColorDodge", "ColorBurn",
@@ -1140,75 +1352,42 @@ local transparancy_modes = { [0] = "Normal",
"Compatible",
}
-local function opacity_initialize ()
- pdfetcs.opacity_res = {}
- if pdfmode and luatexbase.callbacktypes.finish_pdffile then -- ltluatex
- local extgstate_obj = pdf.reserveobj()
- pdfetcs.setpageres(format("%s/ExtGState %i 0 R",pdfetcs.getpageres() or "",extgstate_obj))
- luatexbase.add_to_callback("finish_pdffile", function()
- pdf.immediateobj(extgstate_obj, format("<<%s>>",tableconcat(pdfetcs.opacity_res)))
- end, "luamplib.opacity.finish_pdffile")
- end
-end
-
local function update_tr_res(mode,opaq)
if pdfetcs.pgfloaded == nil then
pdfetcs.pgfloaded = is_defined(pdfetcs.pgfextgs)
- if not pdfmanagement and not pdfetcs.pgfloaded and not is_defined"TRP@list" then
- opacity_initialize()
+ if pdfmode and not pdfmanagement and not pdfetcs.pgfloaded and not is_defined"TRP@list" then
+ pdfetcs.initialize_resources"ExtGState"
end
end
local os = format("<</BM /%s/ca %.3f/CA %.3f/AIS false>>",mode,opaq,opaq)
local on, new = update_pdfobjs(os)
- if new then
- if pdfmode then
- if pdfmanagement then
- texsprint(ccexplat,{
- [[\pdfmanagement_add:nnn{Page/Resources/ExtGState}]],
- format("{MPlibTr%s}{%s 0 R}", on, on),
+ if not new then return on end
+ local key = format("MPlibTr%s", on)
+ local val = format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on)
+ if pdfmanagement then
+ texsprint(ccexplat,
+ format("\\pdfmanagement_add:nnn{Page/Resources/ExtGState}{%s}{%s}", key, val))
+ else
+ local tr = format("/%s %s", key, val)
+ if pdfetcs.pgfloaded then
+ texsprint(format("\\csname %s\\endcsname{%s}", pdfetcs.pgfextgs,tr))
+ elseif pdfmode then
+ if is_defined"TRP@list" then
+ texsprint(catat11,{
+ [[\if@filesw\immediate\write\@auxout{]],
+ [[\string\g@addto@macro\string\TRP@list{]],
+ tr,
+ [[}}\fi]],
})
- else
- local tr = format("/MPlibTr%s %s 0 R",on,on)
- if pdfetcs.pgfloaded then
- texsprint(format("\\csname %s\\endcsname{%s}", pdfetcs.pgfextgs,tr))
- elseif is_defined"TRP@list" then
- texsprint(catat11,{
- [[\if@filesw\immediate\write\@auxout{]],
- [[\string\g@addto@macro\string\TRP@list{]],
- tr,
- [[}}\fi]],
- })
- if not get_macro"TRP@list":find(tr) then
- texsprint(catat11,[[\global\TRP@reruntrue]])
- end
- else
- if luatexbase.callbacktypes.finish_pdffile then
- pdfetcs.opacity_res[#pdfetcs.opacity_res+1] = tr
- else
- local tpr, n = pdfetcs.getpageres() or "", 0
- tpr, n = tpr:gsub("/ExtGState<<", "%1"..tr)
- if n == 0 then
- tpr = format("%s/ExtGState<<%s>>", tpr, tr)
- end
- pdfetcs.setpageres(tpr)
- end
+ if not get_macro"TRP@list":find(tr) then
+ texsprint(catat11,[[\global\TRP@reruntrue]])
end
- end
- else
- if pdfmanagement then
- texsprint(ccexplat,{
- [[\pdfmanagement_add:nnn{Page/Resources/ExtGState}]],
- format("{MPlibTr%s}{@mplibpdfobj%s}", on, on),
- })
else
- local tr = format("/MPlibTr%s @mplibpdfobj%s",on,on)
- if pdfetcs.pgfloaded then
- texsprint(format("\\csname %s\\endcsname{%s}", pdfetcs.pgfextgs,tr))
- else
- texsprint(format("\\special{pdf:put @MPlibTr<<%s>>}",tr))
- texsprint"\\special{pdf:put @resources<</ExtGState @MPlibTr>>}"
- end
+ pdfetcs.fallback_update_resources("ExtGState", tr)
end
+ else
+ texsprint(format("\\special{pdf:put @MPlibTr<<%s>>}",tr))
+ texsprint"\\special{pdf:put @resources<</ExtGState @MPlibTr>>}"
end
end
return on
@@ -1227,20 +1406,9 @@ local function do_preobj_TR(prescript)
return tron_no
end
-local function shading_initialize ()
- pdfetcs.shading_res = {}
- if pdfmode and luatexbase.callbacktypes.finish_pdffile then -- ltluatex
- local shading_obj = pdf.reserveobj()
- pdfetcs.setpageres(format("%s/Shading %i 0 R",pdfetcs.getpageres() or "",shading_obj))
- luatexbase.add_to_callback("finish_pdffile", function()
- pdf.immediateobj(shading_obj,format("<<%s>>",tableconcat(pdfetcs.shading_res)))
- end, "luamplib.shading.finish_pdffile")
- end
-end
-
local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,steps,fractions)
- if not pdfmanagement and not pdfetcs.shading_res then
- shading_initialize()
+ if pdfmode and not pdfmanagement and not pdfetcs.Shading_res then
+ pdfetcs.initialize_resources"Shading"
end
local fun2fmt,os = "<</FunctionType 2/Domain [%s]/C0 [%s]/C1 [%s]/N 1>>"
if steps > 1 then
@@ -1273,42 +1441,18 @@ local function sh_pdfpageresources(shtype,domain,colorspace,ca,cb,coordinates,st
"/Extend [true true]/AntiAlias true>>",
}
local on, new = update_pdfobjs(os)
- if pdfmode then
- if new then
- if pdfmanagement then
- texsprint(ccexplat,{
- [[\pdfmanagement_add:nnn{Page/Resources/Shading}]],
- format("{MPlibSh%s}{%s 0 R}", on, on),
- })
- else
- local res = format("/MPlibSh%s %s 0 R", on, on)
- if luatexbase.callbacktypes.finish_pdffile then
- pdfetcs.shading_res[#pdfetcs.shading_res+1] = res
- else
- local pageres = pdfetcs.getpageres() or ""
- if not pageres:find("/Shading<<.*>>") then
- pageres = pageres.."/Shading<<>>"
- end
- pageres = pageres:gsub("/Shading<<","%1"..res)
- pdfetcs.setpageres(pageres)
- end
- end
- end
+ if not new then return on end
+ local key = format("MPlibSh%s", on)
+ local val = format(pdfmode and "%s 0 R" or "@mplibpdfobj%s", on)
+ if pdfmanagement then
+ texsprint(ccexplat,
+ format("\\pdfmanagement_add:nnn{Page/Resources/Shading}{%s}{%s}", key, val))
else
- if pdfmanagement then
- if new then
- texsprint(ccexplat,{
- [[\pdfmanagement_add:nnn{Page/Resources/Shading}]],
- format("{MPlibSh%s}{@mplibpdfobj%s}", on, on),
- })
- end
+ local res = format("/%s %s", key, val)
+ if pdfmode then
+ pdfetcs.fallback_update_resources("Shading", res)
else
- if new then
- texsprint{
- "\\special{pdf:put @MPlibSh",
- format("<</MPlibSh%s @mplibpdfobj%s>>}",on, on),
- }
- end
+ texsprint(format("\\special{pdf:put @MPlibSh<<%s>>}", res))
texsprint"\\special{pdf:put @resources<</Shading @MPlibSh>>}"
end
end
@@ -1327,7 +1471,18 @@ local function color_normalize(ca,cb)
end
end
-pdfetcs.clrspcs = { }
+pdfetcs.clrspcs = setmetatable({ }, { __index = function(t,names)
+ run_tex_code({
+ [[\color_model_new:nnn]],
+ format("{mplibcolorspace_%s}", names:gsub(",","_")),
+ format("{DeviceN}{names={%s}}", names),
+ [[\edef\mplib_@tempa{\pdf_object_ref_last:}]],
+ }, ccexplat)
+ local colorspace = get_macro'mplib_@tempa'
+ t[names] = colorspace
+ return colorspace
+end })
+
local function do_preobj_SH(object,prescript)
local shade_no
local sh_type = prescript and prescript.sh_type
@@ -1390,7 +1545,7 @@ local function do_preobj_SH(object,prescript)
local t = { }
for j=1,names[name] do t[#t+1] = 0 end
t[#t+1] = value
- table.insert(#ca == #cb and ca or cb, t)
+ tableinsert(#ca == #cb and ca or cb, t)
end
end
for _,t in ipairs{ca,cb} do
@@ -1401,20 +1556,7 @@ local function do_preobj_SH(object,prescript)
if #names == 1 then
colorspace = objref
else
- local name = tableconcat(names,"-")
- local obj = pdfetcs.clrspcs[name]
- if obj then
- colorspace = obj
- else
- run_tex_code({
- [[\color_model_new:nnn]],
- format("{mplibcolorspace_%s}", name),
- format("{DeviceN}{names={%s}}", tableconcat(names,",")),
- [[\edef\mplib_@tempa{\pdf_object_ref_last:}]],
- }, ccexplat)
- colorspace = get_macro'mplib_@tempa'
- pdfetcs.clrspcs[name] = colorspace
- end
+ colorspace = pdfetcs.clrspcs[ tableconcat(names,",") ]
end
else
local model = 0
@@ -1456,7 +1598,7 @@ local function do_preobj_SH(object,prescript)
return shade_no
end
-local function flush(result,flusher)
+function luamplib.flush (result,flusher)
if result then
local figures = result.fig
if figures then
@@ -1671,9 +1813,8 @@ local function flush(result,flusher)
end
end
end
-luamplib.flush = flush
-local function colorconverter(cr)
+function luamplib.colorconverter (cr)
local n = #cr
if n == 4 then
local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
@@ -1686,6 +1827,5 @@ local function colorconverter(cr)
return format("%.3f g %.3f G",s,s), "0 g 0 G"
end
end
-luamplib.colorconverter = colorconverter
--
-- End of File `luamplib.lua'.
diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty b/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty
index 41a91d020c0..24d0fdabee2 100644
--- a/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty
+++ b/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty
@@ -14,7 +14,7 @@
\else
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{luamplib}
- [2024/05/01 v2.29.0 mplib package for LuaTeX]
+ [2024/05/10 v2.30.0 mplib package for LuaTeX]
\ifx\newluafunction\@undefined
\input ltluatex
\fi