diff options
3 files changed, 580 insertions, 3 deletions
diff --git a/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks-plugin-pstcie.lua b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks-plugin-pstcie.lua new file mode 100644 index 00000000000..04d6759716a --- /dev/null +++ b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks-plugin-pstcie.lua @@ -0,0 +1,395 @@ +---- luapstricks-plugin-pstcie.lua +-- Copyright 2021--2023 Marcel Krüger <tex@2krueger.de> +-- Converted from PostScript in pst-cie.pro version 0.03 +-- +-- This work may be distributed and/or modified under the +-- conditions of the LaTeX Project Public License, either version 1.3 +-- of this license or (at your option) any later version. +-- The latest version of this license is in +-- http://www.latex-project.org/lppl.txt +-- and version 1.3 or later is part of all distributions of LaTeX +-- version 2005/12/01 or later. +-- +-- This work has the LPPL maintenance status `maintained'. +-- +-- The Current Maintainer of this work is M. Krüger +-- +-- This work consists of the files luapstricks.lua and luapstricks-plugin-pstmarble.lua + +local loader, version, plugininterface = ... +assert(loader == 'luapstricks' and version == 0) + +local push = plugininterface.push +local pop = plugininterface.pop +local pop_array = plugininterface.pop_array +local pop_num = plugininterface.pop_num +local pop_proc = plugininterface.pop_proc +local pop_string = pop +local exec = plugininterface.exec + +local newtable = lua.newtable +local abs = math.abs +local exp = math.exp +local cos = math.cos +local sin = math.sin +local rad = math.rad +local max = math.max +local deg = math.deg +local atan = math.atan + +-- Using the usual scale +--[[ +local function BLKBOD(temp, table) + local X, Y, Z = 0, 0, 0 + for i = 1, #table do + local WL = (359 + i) * 1e-9 + local DIS = (3.74183e-16 / WL^5) / (exp(1.4388e-2 / (WL * temp)) - 1) + local entry = table[i] + X = X + entry[1] * DIS + Y = Y + entry[2] * DIS + Z = Z + entry[3] * DIS + end + local XYZ = X + Y + Z + return X / XYZ, Y / XYZ, Z / XYZ +end +--]] +-- But we can scale all components with fixed factors, so we get the same result with +local function BLKBOD(temp, table) + assert(#table == 471) -- 471 = 830 - 360 + 1 + local x, y, z = 0, 0, 0 + local scaled_constant = 1.4388e7 / temp + for wavelength = 360, 830 do + local factor = 1 / (wavelength^5 * (exp(scaled_constant / wavelength) - 1)) + local entry = table[wavelength - 359].value + x = x + entry[1] * factor + y = y + entry[2] * factor + z = z + entry[3] * factor + end + local xyz = x + y + z + return x / xyz, y / xyz, z / xyz +end + +local function xy2uv(x, y) + -- local divisor = x + 15*y + 3 + -- return 4*x / divisor --[[u]], 6*y / divisor --[[v]] + local divisor = -2*x + 12*y + 3 + return 4*x / divisor --[[u']], 9*y / divisor --[[v']] +end + +local colorspaces = setmetatable({ + Adobe = { + xy2RGB = function(x, y, z) + return 2.0413690 * x + -0.5649464 * y + -0.3446944 * z, + -0.9692660 * x + 1.8760108 * y + 0.0415560 * z, + 0.0134474 * x + -0.1183897 * y + 1.0154096 * z + end, + --[[ + /primaryIlluminants { + /xR 0.6400 def /yR 0.3300 def + /xG 0.2100 def /yG 0.7150 def + /xB 0.1500 def /yB 0.0600 def + D65 + --]] + }, + CIE = { + xy2RGB = function(x, y, z) + return 2.3706743 * x + -0.9000405 * y + -0.4706338 * z, + -0.5138850 * x + 1.4253036 * y + 0.0885814 * z, + 0.0052982 * x + -0.0146949 * y + 1.0093968 * z + end, + --[[ + /primaryIlluminants { + /xR 0.7355 def /yR 0.2645 def + /xG 0.2658 def /yG 0.7243 def + /xB 0.1669 def /yB 0.0085 def + E_ + --]] + }, + SMPTE = { + xy2RGB = function(x, y, z) + return 3.5053960 * x + -1.7394894 * y + -0.5439640 * z, + -1.0690722 * x + 1.9778245 * y + 0.0351722 * z, + 0.0563200 * x + -0.1970226 * y + 1.0502026 * z + end, + --[[ + /primaryIlluminants { + /xR 0.6300 def /yR 0.3400 def + /xG 0.3100 def /yG 0.5950 def + /xB 0.1550 def /yB 0.0700 def + D65 + --]] + }, + NTSC = { + xy2RGB = function(x, y, z) + return 1.9099961 * x + -0.5324542 * y + -0.2882091 * z, + -0.9846663 * x + 1.9991710 * y + -0.0283082 * z, + 0.0583056 * x + -0.1183781 * y + 0.8975535 * z + end, + --[[ + /primaryIlluminants { + /xR 0.6700 def /yR 0.3300 def + /xG 0.2100 def /yG 0.7100 def + /xB 0.1400 def /yB 0.0800 def + C_ + --]] + }, + sRGB = { + xy2RGB = function(x, y, z) + local r = 3.2404542 * x + -1.5371385 * y + -0.4985314 * z + local g = -0.9692660 * x + 1.8760108 * y + 0.0415560 * z + local b = 0.0556434 * x + -0.2040259 * y + 1.0572252 * z + if r <= 0.00304 then r = r * 12.92 else r = 1.055 * r^(1/2.4) - 0.055 end + if g <= 0.00304 then g = g * 12.92 else g = 1.055 * g^(1/2.4) - 0.055 end + if b <= 0.00304 then b = b * 12.92 else b = 1.055 * b^(1/2.4) - 0.055 end + return r, g, b + end, + GAM = 1, + --[[ + /primaryIlluminants { + return + /xR 0.6400 def /yR 0.3300 def + /xG 0.3000 def /yG 0.6000 def + /xB 0.1500 def /yB 0.0600 def + D65 + } def + ]] + }, + ['Pal-Secam'] = { + xy2RGB = function(x, y, z) + return 3.0628971 * x + -1.3931791 * y + -0.4757517 * z, + -0.9692660 * x + 1.8760108 * y + 0.0415560 * z, + 0.0678775 * x + -0.2288548 * y + 1.0693490 * z + end, + --[[ + /primaryIlluminants { + /xR 0.6400 def /yR 0.3300 def + /xG 0.2900 def /yG 0.6000 def + /xB 0.1500 def /yB 0.0600 def + D65 + } def + --]] + }, + ProPhoto = { + xy2RGB = function(x, y, z) + return 1.3459433 * x + -0.2556075 * y + -0.0511118 * z, + -0.5445989 * x + 1.5081673 * y + 0.0205351 * z, + 0.0000000 * x + 0.0000000 * y + 1.2118128 * z + end, + --[[ + /primaryIlluminants { + /xR 0.7347 def /yR 0.2653 def + /xG 0.1596 def /yG 0.8404 def + /xB 0.0366 def /yB 0.0001 def + D50 + } def + --]] + }, + ColorMatch = { + xy2RGB = function(x, y, z) + return 2.6422874 * x + -1.2234270 * y + -0.3930143 * z, + -1.1119763 * x + 2.0590183 * y + 0.0159614 * z, + 0.0821699 * x + -0.2807254 * y + 1.4559877 * z + end, + --[[ + /primaryIlluminants { + /xR 0.6300 def /yR 0.3400 def + /xG 0.2950 def /yG 0.6050 def + /xB 0.1500 def /yB 0.0750 def + D50 + } def + --]] + }, +}, {__index = function(t, k) + local target = {} + exec{kind = 'dict', value = target} + exec'begin' + exec(k) + exec'end' + table.print({[k] = target}) + local v = { + --[[ + ["Pal-Secam"]={ + ["primaryIlluminants"]={ + ["kind"]="executable", + ["value"]={ + ["kind"]="array", + ["value"]={ + { + ["kind"]="name", + ["value"]="xR", + }, + 0.64, + "def", + { + ["kind"]="name", + ["value"]="yR", + }, + 0.33, + "def", + { + ["kind"]="name", + ["value"]="xG", + }, + 0.29, + "def", + { + ["kind"]="name", + ["value"]="yG", + }, + 0.6, + "def", + { + ["kind"]="name", + ["value"]="xB", + }, + 0.15, + "def", + { + ["kind"]="name", + ["value"]="yB", + }, + 0.06, + "def", + "D65", + }, + }, + }, + --]] + --[[ + ["xy2RGB"]={ + ["kind"]="executable", + ["value"]={ + ["kind"]="array", + ["value"]={ + { + ["kind"]="name", + ["value"]="R", + }, + 3.0628971, + "X", + "mul", + -1.3931791, + "Y", + "mul", + "add", + -0.4757517, + "Z", + "mul", + "add", + "def", + { + ["kind"]="name", + ["value"]="G", + }, + -0.969266, + "X", + "mul", + 1.8760108, + "Y", + "mul", + "add", + 0.041556, + "Z", + "mul", + "add", + "def", + { + ["kind"]="name", + ["value"]="B", + }, + 0.0678775, + "X", + "mul", + -0.2288548, + "Y", + "mul", + "add", + 1.069349, + "Z", + "mul", + "add", + "def", + }, + }, + --]] + xy2RGB = function(x, y, z) + push{kind = 'name', value = 'X'} + push(x) + exec'def' + push{kind = 'name', value = 'Y'} + push(y) + exec'def' + push{kind = 'name', value = 'Z'} + push(z) + exec'def' + exec(target.xy2RGB) + exec'R' + local r = pop_num() + exec'G' + local g = pop_num() + exec'B' + local b = pop_num() + return r, g, b + end, + } + t[k] = v + return v +end}) + +local function normalisation(r, g, b) + local maxRGB = max(r, g, b) + r = r / maxRGB + g = g / maxRGB + b = b / maxRGB + if r < 0 then r = 0 elseif r > 1 then r = 1 end + if g < 0 then g = 0 elseif g > 1 then g = 1 end + if b < 0 then b = 0 elseif b > 1 then b = 1 end + return r, g, b +end + +local function gamut(stepXY, GAM, contrast, chromaticityCoordinates, colorspace) + local space = colorspaces[colorspace] + GAM = space.GAM or GAM + local result = {} + local steps = 1 // stepXY + -- newpath + for xPos = 0, steps do + local x = xPos * stepXY + for yPos = 0, steps do + local y = yPos * stepXY + local z = 1 - x - y + --[[ This block seems weird, I don't thing that it does what it's supposed to. + if chromaticityCoordinates ~= 'xy' then + local u, v = xy2uv(x, y) + xPos = u * cieUnit + yPos = v * cieUnit + end + ]] + local r, g, b = normalisation(space.xy2RGB(x, y, z)) + result[yPos * (steps + 1) + xPos + 1] = {kind = 'array', value = {r^GAM * contrast, g^GAM * contrast, b^GAM * contrast}} + end + end + return result, steps + 1, steps + 1 +end + +return { + ['.BLKBOD'] = function() + local tablename = pop_array().value + local T = pop_num() + local X, Y, Z = BLKBOD(T, tablename) + push(X) + push(Y) + push(Z) + end, + ['.gamut'] = function() + local colorspace = pop_string().value + local chromaticityCoordinates = pop_string().value + local contrast = pop_num() + local GAM = pop_num() + local stepXY = pop_num() + local result, cols, rows = gamut(stepXY, GAM, contrast, chromaticityCoordinates, colorspace) + push{kind = 'array', value = result} + push(cols) + push(rows) + end, +}, 0 diff --git a/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks-plugin-pstsolides3d.lua b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks-plugin-pstsolides3d.lua new file mode 100644 index 00000000000..ccbeafb428c --- /dev/null +++ b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks-plugin-pstsolides3d.lua @@ -0,0 +1,182 @@ +---- luapstricks-plugin-pstsolides3d.lua +-- Copyright 2021--2023 Marcel Krüger <tex@2krueger.de> +-- Converted from PostScript in pst-solides3d.pro +-- +-- This work may be distributed and/or modified under the +-- conditions of the LaTeX Project Public License, either version 1.3 +-- of this license or (at your option) any later version. +-- The latest version of this license is in +-- http://www.latex-project.org/lppl.txt +-- and version 1.3 or later is part of all distributions of LaTeX +-- version 2005/12/01 or later. +-- +-- This work has the LPPL maintenance status `maintained'. +-- +-- The Current Maintainer of this work is M. Krüger +-- +-- This work consists of the files luapstricks.lua and luapstricks-plugin-pstmarble.lua + +local loader, version, plugininterface = ... +assert(loader == 'luapstricks' and version == 0) + +local push = plugininterface.push +local pop = plugininterface.pop +local pop_array = plugininterface.pop_array +local pop_num = plugininterface.pop_num +local pop_proc = plugininterface.pop_proc +local pop_string = pop +local exec = plugininterface.exec + +local newtable = lua.newtable +local abs = math.abs +local exp = math.exp +local cos = math.cos +local sin = math.sin +local rad = math.rad +local max = math.max +local deg = math.deg +local atan = math.atan + +--[[ +-- Solides are represented as four element arrays containing: +-- { +-- Sommets, Faces, Colors_Faces, InOut_Table +-- } +--]] + +local function issolid(candidate) + if type(candidate) ~= 'table' then return false end + local kind = candidate.kind + if kind == 'executable' then return issolid(candidate.value) end + if kind ~= 'array' then return false end + candidate = candidate.value + if #candidate ~= 4 then return false end + + local sommets = candidate[1] + if type(sommets) ~= 'table' then return false end + if sommets.kind == 'executable' then + sommets = sommets.value + if type(sommets) ~= 'table' then return false end + end + if sommets.kind ~= 'array' then return false end + + local faces = candidate[2] + if type(faces) ~= 'table' then return false end + if faces.kind == 'executable' then + faces = faces.value + if type(faces) ~= 'table' then return false end + end + if faces.kind ~= 'array' then return false end + + local faceColors = candidate[3] + if type(faceColors) ~= 'table' then return false end + if faceColors.kind == 'executable' then + faceColors = faceColors.value + if type(faceColors) ~= 'table' then return false end + end + if faceColors.kind ~= 'array' then return false end + + local IO = candidate[4] + if type(IO) ~= 'table' then return false end + if IO.kind == 'executable' then + IO = IO.value + if type(IO) ~= 'table' then return false end + end + if IO.kind ~= 'array' then return false end + IO = IO.value + if #IO ~= 4 then return false end + + return type(IO[1]) == 'number' and type(IO[2]) == 'number' and type(IO[3]) == 'number' and type(IO[4]) == 'number' +end + +local function nullsolid(candidate) + assert(issolid(candidate), 'Error type argument dans "nullsolid"') + return #candidate[1].value == 0 +end + +local function getp3d(sommets, indices) + -- TODO + error'TODO' +end + +local function solidgetsommetsface(solid, i) + assert(issolid(solid), 'Error : mauvais type d argument dans solidgetsommetsface') + local table_sommets = solid.value[1].value + local table_faces = solid.value[2].value + local table_indices = table_faces[i + 1] + local result = {} + for j=1, #table_indices do + result[j] = getp3d(table_sommets, table_indices[j]) + end + return result +end + +local function isobarycentre3d(face) + -- TODO + error'TODO' +end + +local function solidcentreface(solid, i) + return isobarycentre3d(solidgetsommetsface(solid, i)) +end + + +local function drawsolid(solid, order, peintrealgorithme) + if nullsolid(solid) then return end + local sommets = solid[1].value + local n = #sommets // 3 + + local faces = solid[2].value + + if not order then + order = {} + if peintrealgorithme then + for i = 1, #faces do + local face = solidcentreface(solid, i-1) + order[i] = face GetCamPos distance3d + end + order = order doublequicksort pop reverse + else + for i = 1, #faces do + order[i] = i - 1 + end + order = {kind = 'array', value = order} + end + end + + 0 1 faces length 1 sub { + /k exch def + /i order k get def + gsave + solid i solidfacevisible? { + solid i dessinefacevisible + } if + grestore + } for + aretescachees { + 0 1 F length 1 sub { + /k exch def + /i order k get def + gsave + solid i solidfacevisible? not { + solid i dessinefacecachee + } if + grestore + } for + } if +end + +return { + drawsolid = function() + local order + local solid = pop() + if not issolid(solid) then + solid, order = pop(), solid + assert(issolid(solid), 'Error : mauvais type d argument dans drawsolid') + end + return drawsolid(solid, order) + end, + issolid = function() + push(issolid(pop())) + end, +}, 0 diff --git a/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua index 9797073d2d9..1ab25e42929 100644 --- a/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua +++ b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua @@ -18,8 +18,8 @@ if luatexbase then luatexbase.provides_module { name = 'luapstricks', - version = 'v0.9', - date = '2023-04-14', + version = 'v0.10', + date = '2023-05-23', description = 'PSTricks backend for LuaLaTeX', } end @@ -4191,7 +4191,7 @@ local fid = font.define{ ps_pos_x, ps_pos_y = pdf.getpos() n.xoffset = -ps_pos_x n.yoffset = -ps_pos_y - n = node.hpack(n) + n = node.hpack(n, 0, 1, 0) -- Default width, TLT vf.node(node.direct.todirect(n)) node.free(n) end} |