diff options
Diffstat (limited to 'tex/context/base')
36 files changed, 490 insertions, 2334 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 4d04ebdb2..b5e91c7d6 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.12.07 19:37} +\newcontextversion{2018.12.17 16:39} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index d5b74dd8d..547af354c 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2018.12.07 19:37} +\edef\contextversion{2018.12.17 16:39} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-cs.mkii b/tex/context/base/mkii/mult-cs.mkii index b2cbdb517..b10fb84fa 100644 --- a/tex/context/base/mkii/mult-cs.mkii +++ b/tex/context/base/mkii/mult-cs.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{barevne} \setinterfacevariable{column}{column} \setinterfacevariable{columns}{sloupce} diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index 0958b3464..0a15a4f30 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{farbe} \setinterfacevariable{column}{column} \setinterfacevariable{columns}{spalten} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positiv} \setinterfacevariable{postponing}{verschieben} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{einstellung} \setinterfacevariable{preview}{vorschau} \setinterfacevariable{previous}{vorig} diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index 7b32b022c..0b5ab2382 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{colore} \setinterfacevariable{column}{colonna} \setinterfacevariable{columns}{colonne} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positivo} \setinterfacevariable{postponing}{posporre} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{preferenza} \setinterfacevariable{preview}{anteprima} \setinterfacevariable{previous}{precedente} diff --git a/tex/context/base/mkiv/back-pdf.mkiv b/tex/context/base/mkiv/back-pdf.mkiv index 6c663bf0f..a9a74cae4 100644 --- a/tex/context/base/mkiv/back-pdf.mkiv +++ b/tex/context/base/mkiv/back-pdf.mkiv @@ -33,7 +33,13 @@ \registerctxluafile{lpdf-tag}{} \registerctxluafile{lpdf-fmt}{} \registerctxluafile{lpdf-pde}{} -\registerctxluafile{lpdf-img}{optimize} + +\doifelsefileexists {lpdf-emb.lua} { + \registerctxluafile{lpdf-img}{optimize} +} { + % nothing +} + \registerctxluafile{lpdf-epa}{} \doifelsefileexists {lpdf-emb.lua} { diff --git a/tex/context/base/mkiv/char-ini.lua b/tex/context/base/mkiv/char-ini.lua index 1e8c1f7d3..62e509151 100644 --- a/tex/context/base/mkiv/char-ini.lua +++ b/tex/context/base/mkiv/char-ini.lua @@ -1287,6 +1287,8 @@ function characters.lower (str) return str and lpegmatch(utf8lower,str) or "" en function characters.upper (str) return str and lpegmatch(utf8upper,str) or "" end function characters.shaped(str) return str and lpegmatch(utf8shape,str) or "" end +lpeg.setutfcasers(characters.lower,characters.upper) + -- local str = [[ -- ÀÁÂÃÄÅàáâãäå àáâãäåàáâãäå ÀÁÂÃÄÅÀÁÂÃÄÅ AAAAAAaaaaaa -- ÆÇæç æçæç ÆÇÆÇ AECaec diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index a31442367..a6c862c7e 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.12.07 19:37} +\newcontextversion{2018.12.17 16:39} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 0bc464b70..0b61408de 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -42,7 +42,7 @@ %D has to match \type {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2018.12.07 19:37} +\edef\contextversion{2018.12.17 16:39} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-imp-dimensions.lua b/tex/context/base/mkiv/font-imp-dimensions.lua index e658ef7bb..a7125625d 100644 --- a/tex/context/base/mkiv/font-imp-dimensions.lua +++ b/tex/context/base/mkiv/font-imp-dimensions.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-imp-dimensions'] = { license = "see context related readme files" } +if not context then return end + local next, type, tonumber = next, type, tonumber local fonts = fonts diff --git a/tex/context/base/mkiv/font-imp-math.lua b/tex/context/base/mkiv/font-imp-math.lua index 3a82c2a9e..d93ece405 100644 --- a/tex/context/base/mkiv/font-imp-math.lua +++ b/tex/context/base/mkiv/font-imp-math.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-imp-math'] = { license = "see context related readme files" } +if not context then return end + local next, type, tonumber = next, type, tonumber local fonts = fonts diff --git a/tex/context/base/mkiv/font-imp-notused.lua b/tex/context/base/mkiv/font-imp-notused.lua index 1c78db7aa..be36c9898 100644 --- a/tex/context/base/mkiv/font-imp-notused.lua +++ b/tex/context/base/mkiv/font-imp-notused.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-imp-notused'] = { license = "see context related readme files" } +if not context then return end + -- local next = next -- local utfbyte = utf.byte -- diff --git a/tex/context/base/mkiv/font-imp-properties.lua b/tex/context/base/mkiv/font-imp-properties.lua index 8cd22af69..5805235b7 100644 --- a/tex/context/base/mkiv/font-imp-properties.lua +++ b/tex/context/base/mkiv/font-imp-properties.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-imp-properties'] = { license = "see context related readme files" } +if not context then return end + local next, type, tonumber, select = next, type, tonumber, select local byte, find, formatters = string.byte, string.find, string.formatters local utfchar = utf.char diff --git a/tex/context/base/mkiv/font-imp-quality.lua b/tex/context/base/mkiv/font-imp-quality.lua index 930d036e1..224d8dc27 100644 --- a/tex/context/base/mkiv/font-imp-quality.lua +++ b/tex/context/base/mkiv/font-imp-quality.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-imp-quality'] = { license = "see context related readme files" } +if not context then return end + local next, type, tonumber = next, type, tonumber local byte = string.byte local insert = table.insert diff --git a/tex/context/base/mkiv/font-imp-reorder.lua b/tex/context/base/mkiv/font-imp-reorder.lua index 250aa47c6..b2dec781c 100644 --- a/tex/context/base/mkiv/font-imp-reorder.lua +++ b/tex/context/base/mkiv/font-imp-reorder.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-imp-reorder'] = { license = "see context related readme files" } +if not context then return end + local next = next local find = string.find local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort diff --git a/tex/context/base/mkiv/font-imp-tracing.lua b/tex/context/base/mkiv/font-imp-tracing.lua index e6de494df..6ce445143 100644 --- a/tex/context/base/mkiv/font-imp-tracing.lua +++ b/tex/context/base/mkiv/font-imp-tracing.lua @@ -6,7 +6,10 @@ if not modules then modules = { } end modules ['font-imp-tracing'] = { license = "see context related readme files" } +if not context then return end + local next, type = next, type +local concat = table.concat local formatters = string.formatters local fonts = fonts @@ -19,6 +22,7 @@ local settings_to_array = utilities.parsers.settings_to_array local setmetatableindex = table.setmetatableindex local helpers = fonts.helpers +local appendcommandtable = helpers.appendcommandtable local prependcommands = helpers.prependcommands local charcommand = helpers.commands.char @@ -48,6 +52,8 @@ local r = 16384 * bp -- 65536 // 4 local f_1 = formatters["%.6F w 0 %.6F %.6F %.6F re f"] local f_2 = formatters["[] 0 d 0 J %.6F w %.6F %.6F %.6F %.6F re S"] +-- change this into w h d instead of h d w + local backcache = setmetatableindex(function(t,h) local h = h * bp local v = setmetatableindex(function(t,d) @@ -169,3 +175,107 @@ local specification = { registerotffeature(specification) registerafmfeature(specification) + +local f_m = formatters["%F %F m"] +local f_l = formatters["%F %F l"] +local f_b = formatters["[] 0 d 0 J %.6F w"] +local f_e = formatters["s"] + +local function ladder(list,docolor,nocolor,lst,offset,sign,default) + local l = lst[1] + local x1 = bp * (offset + l.kern) * sign + local y1 = bp * l.height + local t = { f_b(r,r/2), f_m(x1,y1) } + local n = 2 + local m = #lst + if default > 0 then + default = default * bp + r + else + default = default * bp - r + end + if m == 1 then + n = n + 1 t[n] = f_l(x1,default) + else + for i=1,m do + local l = lst[i] + local x2 = bp * (offset + l.kern) * sign + local y2 = bp * l.height + if i > 1 and y2 == 0 then + y2 = default + end + n = n + 1 t[n] = f_l(x2,y1) + n = n + 1 t[n] = f_l(x2,y2) + x1, y1 = x2, y2 + end + end + n = n + 1 t[n] = f_e() + list[#list+1] = docolor + list[#list+1] = { "pdf", "origin", concat(t," ") } + list[#list+1] = nocolor +end + +local function initialize(tfmdata,key,value) + if value then + if not backcolors then + local vfspecials = backends.pdf.tables.vfspecials + startcolor = vfspecials.startcolor + stopcolor = vfspecials.stopcolor + end + local characters = tfmdata.characters + local brcolor = startcolor("darkred") + local trcolor = startcolor("darkgreen") + local blcolor = startcolor("darkblue") + local tlcolor = startcolor("darkyellow") + local black = stopcolor + for unicode, character in next, characters do + local mathkern = character.mathkern + if mathkern then + -- more efficient would be co collect more in one pdf + -- directive but this is hardly used so not worth the + -- effort + local width = character.width or 0 + local height = character.height or 0 + local depth = character.depth or 0 + local list = { } + local br = mathkern.bottom_right + local tr = mathkern.top_right + local bl = mathkern.bottom_left + local tl = mathkern.top_left + if br then + ladder(list,brcolor,black,br,width,1,height) + end + if tr then + ladder(list,trcolor,black,tr,width,1,-depth) + end + if bl then + ladder(list,blcolor,black,bl,0,-1,height) + end + if tl then + ladder(list,tlcolor,black,tl,0,-1,-depth) + end + if #list > 0 then + local commands = character.commands + if commands then + character.commands = appendcommandtable(commands,list) + else + list[#list+1] = charcommand[unicode] + character.commands = list + end + end + end + end + end +end + +local specification = { + name = "staircase", + description = "show staircase kerns", + position=1, + manipulators = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) diff --git a/tex/context/base/mkiv/font-imp-unicode.lua b/tex/context/base/mkiv/font-imp-unicode.lua index 9e1e3465e..ddb965ec9 100644 --- a/tex/context/base/mkiv/font-imp-unicode.lua +++ b/tex/context/base/mkiv/font-imp-unicode.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-imp-unicode'] = { license = "see context related readme files" } +if not context then return end + local next = next local fonts = fonts diff --git a/tex/context/base/mkiv/font-vfc.lua b/tex/context/base/mkiv/font-vfc.lua index 3e48422d6..dfe6b3afc 100644 --- a/tex/context/base/mkiv/font-vfc.lua +++ b/tex/context/base/mkiv/font-vfc.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['font-vfc'] = { license = "see context related readme files" } -local select = select +local select, type = select, type local insert = table.insert local fonts = fonts @@ -25,7 +25,7 @@ local dummy = { "comment" } function helpers.prependcommands(commands,...) insert(commands,1,push) for i=select("#",...),1,-1 do - local s = select(i,...) + local s = (select(i,...)) if s then insert(commands,1,s) end @@ -38,7 +38,31 @@ function helpers.appendcommands(commands,...) insert(commands,1,push) insert(commands,pop) for i=1,select("#",...) do - local s = select(i,...) + local s = (select(i,...)) + if s then + insert(commands,s) + end + end + return commands +end + +function helpers.prependcommandtable(commands,t) + insert(commands,1,push) + for i=#t,1,-1 do + local s = t[i] + if s then + insert(commands,1,s) + end + end + insert(commands,pop) + return commands +end + +function helpers.appendcommandtable(commands,t) + insert(commands,1,push) + insert(commands,pop) + for i=1,#t do + local s = t[i] if s then insert(commands,s) end diff --git a/tex/context/base/mkiv/grph-img.lua b/tex/context/base/mkiv/grph-img.lua deleted file mode 100644 index c76733cbf..000000000 --- a/tex/context/base/mkiv/grph-img.lua +++ /dev/null @@ -1,746 +0,0 @@ -if not modules then modules = { } end modules ['grph-img'] = { - version = 1.001, - comment = "companion to grph-inc.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- The jpg identification and inclusion code is based on the code in \LUATEX\ but as we --- use \LUA\ we can do it a bit cleaner. We can also use some helpers for reading from --- file. We could make it even more lean and mean. When all works out ok I will clean --- up this code a bit as we can divert more from luatex. - -local lower, strip = string.lower, string.strip -local round = math.round -local concat = table.concat -local suffixonly = file.suffix - -local files = utilities.files -local getsize = files.getsize -local readbyte = files.readbyte -local readstring = files.readstring -local readcardinal = files.readcardinal -local readcardinal2 = files.readcardinal2 -local readcardinal4 = files.readcardinal4 -local readcardinal2le = files.readcardinal2le -local readcardinal4le = files.readcardinal4le -local skipbytes = files.skip -local setposition = files.setposition -local getposition = files.getposition - -local setmetatableindex = table.setmetatableindex -local setmetatablecall = table.setmetatablecall - -local lpdf = lpdf or { } -local pdfmajorversion = lpdf.majorversion -local pdfminorversion = lpdf.minorversion - -local graphics = graphics or { } -local identifiers = { } -graphics.identifiers = identifiers - -do - - local colorspaces = { - [1] = 1, -- gray - [3] = 2, -- rgb - [4] = 3, -- cmyk - } - - local tags = { - [0xC0] = { name = "SOF0", }, -- baseline DCT - [0xC1] = { name = "SOF1", }, -- extended sequential DCT - [0xC2] = { name = "SOF2", }, -- progressive DCT - [0xC3] = { name = "SOF3", supported = false }, -- lossless (sequential) - - [0xC5] = { name = "SOF5", supported = false }, -- differential sequential DCT - [0xC6] = { name = "SOF6", supported = false }, -- differential progressive DCT - [0xC7] = { name = "SOF7", supported = false }, -- differential lossless (sequential) - - [0xC8] = { name = "JPG", }, -- reserved for JPEG extensions - [0xC9] = { name = "SOF9", }, -- extended sequential DCT - [0xCA] = { name = "SOF10", supported = false }, -- progressive DCT - [0xCB] = { name = "SOF11", supported = false }, -- lossless (sequential) - - [0xCD] = { name = "SOF13", supported = false }, -- differential sequential DCT - [0xCE] = { name = "SOF14", supported = false }, -- differential progressive DCT - [0xCF] = { name = "SOF15", supported = false }, -- differential lossless (sequential) - - [0xC4] = { name = "DHT" }, -- define Huffman table(s) - - [0xCC] = { name = "DAC" }, -- define arithmetic conditioning table - - [0xD0] = { name = "RST0", zerolength = true }, -- restart - [0xD1] = { name = "RST1", zerolength = true }, -- restart - [0xD2] = { name = "RST2", zerolength = true }, -- restart - [0xD3] = { name = "RST3", zerolength = true }, -- restart - [0xD4] = { name = "RST4", zerolength = true }, -- restart - [0xD5] = { name = "RST5", zerolength = true }, -- restart - [0xD6] = { name = "RST6", zerolength = true }, -- restart - [0xD7] = { name = "RST7", zerolength = true }, -- restart - - [0xD8] = { name = "SOI", zerolength = true }, -- start of image - [0xD9] = { name = "EOI", zerolength = true }, -- end of image - [0xDA] = { name = "SOS" }, -- start of scan - [0xDB] = { name = "DQT" }, -- define quantization tables - [0xDC] = { name = "DNL" }, -- define number of lines - [0xDD] = { name = "DRI" }, -- define restart interval - [0xDE] = { name = "DHP" }, -- define hierarchical progression - [0xDF] = { name = "EXP" }, -- expand reference image(s) - - [0xE0] = { name = "APP0" }, -- application marker, used for JFIF - [0xE1] = { name = "APP1" }, -- application marker - [0xE2] = { name = "APP2" }, -- application marker - [0xE3] = { name = "APP3" }, -- application marker - [0xE4] = { name = "APP4" }, -- application marker - [0xE5] = { name = "APP5" }, -- application marker - [0xE6] = { name = "APP6" }, -- application marker - [0xE7] = { name = "APP7" }, -- application marker - [0xE8] = { name = "APP8" }, -- application marker - [0xE9] = { name = "APP9" }, -- application marker - [0xEA] = { name = "APP10" }, -- application marker - [0xEB] = { name = "APP11" }, -- application marker - [0xEC] = { name = "APP12" }, -- application marker - [0xED] = { name = "APP13" }, -- application marker - [0xEE] = { name = "APP14" }, -- application marker, used by Adobe - [0xEF] = { name = "APP15" }, -- application marker - - [0xF0] = { name = "JPG0" }, -- reserved for JPEG extensions - [0xFD] = { name = "JPG13" }, -- reserved for JPEG extensions - [0xFE] = { name = "COM" }, -- comment - - [0x01] = { name = "TEM", zerolength = true }, -- temporary use - } - - -- More can be found in http://www.exif.org/Exif2-2.PDF but basically we have - -- good old tiff tags here. - - local function read_APP1_Exif(f, xres, yres, orientation) -- untested - local position = false - local readcardinal2 = readcardinal2 - local readcardinal4 = readcardinal4 - -- endian II|MM - while true do - position = getposition(f) - local b = readbyte(f) - if b == 0 then - -- next one - elseif b == 0x4D and readbyte(f) == 0x4D then -- M - -- big endian - break - elseif b == 0x49 and readbyte(f) == 0x49 then -- I - -- little endian - readcardinal2 = readcardinal2le - readcardinal4 = readcardinal4le - break - else - -- warning "bad exif data" - return xres, yres, orientation - end - end - -- version - local version = readcardinal2(f) - if version ~= 42 then - return xres, yres, orientation - end - -- offset to records - local offset = readcardinal4(f) - if not offset then - return xres, yres, orientation - end - setposition(f,position + offset) - local entries = readcardinal2(f) - if not entries or entries == 0 then - return xres, yres, orientation - end - local x_res, y_res, x_res_ms, y_res_ms, x_temp, y_temp - local res_unit, res_unit_ms - for i=1,entries do - local tag = readcardinal2(f) - local kind = readcardinal2(f) - local size = readcardinal4(f) - local value = 0 - local num = 0 - local den = 0 - if kind == 1 or kind == 7 then -- byte | undefined - value = readbyte(f) - skipbytes(f,3) - elseif kind == 3 or kind == 8 then -- (un)signed short - value = readcardinal2(f) - skipbytes(f,2) - elseif kind == 4 or kind == 9 then -- (un)signed long - value = readcardinal4(f) - elseif kind == 5 or kind == 10 then -- (s)rational - local offset = readcardinal4(f) - local saved = getposition(f) - setposition(f,position+offset) - num = readcardinal4(f) - den = readcardinal4(f) - setposition(f,saved) - else -- 2 -- ascii - skipbytes(f,4) - end - if tag == 274 then -- orientation - orientation = value - elseif tag == 282 then -- x resolution - if den ~= 0 then - x_res = num/den - end - elseif tag == 283 then -- y resolution - if den ~= 0 then - y_res = num/den - end - elseif tag == 296 then -- resolution unit - if value == 2 then - res_unit = 1 - elseif value == 3 then - res_unit = 2.54 - end - elseif tag == 0x5110 then -- pixel unit - res_unit_ms = value == 1 - elseif tag == 0x5111 then -- x pixels per unit - x_res_ms = value - elseif tag == 0x5112 then -- y pixels per unit - y_res_ms = value - end - end - if x_res and y_res and res_unit and res_unit > 0 then - x_temp = round(x_res * res_unit) - y_temp = round(y_res * res_unit) - elseif x_res_ms and y_res_ms and res_unit_ms then - x_temp = round(x_res_ms * 0.0254) -- in meters - y_temp = round(y_res_ms * 0.0254) -- in meters - end - if x_temp and a_temp and x_temp > 0 and y_temp > 0 then - if (x_temp ~= x_res or y_temp ~= y_res) and x_res ~= 0 and y_res ~= 0 then - -- exif resolution differs from already found resolution - elseif x_temp == 1 or y_temp == 1 then - -- exif resolution is kind of weird - else - return x_temp, y_temp, orientation - end - end - return round(xres), round(yres), orientation - end - - function identifiers.jpg(filename) - local specification = { - filename = filename, - filetype = "jpg", - } - if not filename or filename == "" then - specification.error = "invalid filename" - return specification -- error - end - local f = io.open(filename,"rb") - if not f then - specification.error = "unable to open file" - return specification -- error - end - specification.xres = 0 - specification.yres = 0 - specification.orientation = 1 - specification.totalpages = 1 - specification.pagenum = 1 - specification.length = 0 - local banner = readcardinal2(f) - if banner ~= 0xFFD8 then - specification.error = "no jpeg file" - return specification -- error - end - local xres = 0 - local yres = 0 - local orientation = 1 - local okay = false - local filesize = getsize(f) -- seek end - local majorversion = pdfmajorversion and pdfmajorversion() or 2 - local minorversion = pdfminorversion and pdfminorversion() or 2 - while getposition(f) < filesize do - local b = readbyte(f) - if not b then - break - elseif b ~= 0xFF then - if not okay then - -- or check for size - specification.error = "incomplete file" - end - break - end - local category = readbyte(f) - local position = getposition(f) - local length = 0 - local tagdata = tags[category] - if not tagdata then - specification.error = "invalid tag" - break - elseif tagdata.supported == false then - specification.error = "unsupported " .. tagdata.comment - break - end - local name = tagdata.name - if name == "SOF2" then - if majorversion < 2 or minorversion <= 2 then - specification.error = "no progressive DCT in PDF <= 1.2" - break - end - elseif name == "SOF0" or name == "SOF1" then - length = readcardinal2(f) - specification.colordepth = readcardinal(f) - specification.ysize = readcardinal2(f) - specification.xsize = readcardinal2(f) - specification.colorspace = colorspaces[readcardinal(f)] - if not specification.colorspace then - specification.error = "unsupported color space" - break - end - okay = true - elseif name == "APP0" then - length = readcardinal2(f) - if length > 6 then - local format = readstring(f,5) - if format == "JFIF\000" then - skipbytes(f,2) - units = readcardinal(f) - xres = readcardinal2(f) - yres = readcardinal2(f) - if units == 1 then - -- pixels per inch - if xres == 1 or yres == 1 then - -- warning - end - elseif units == 2 then - -- pixels per cm */ - xres = xres * 2.54 - yres = yres * 2.54 - else - xres = 0 - yres = 0 - end - end - end - elseif name == "APP1" then - length = readcardinal2(f) - if length > 7 then - local format = readstring(f,5) - if format == "Exif\000" then - xres, yres, orientation = read_APP1_Exif(f,xres,yres,orientation) - end - end - elseif not tagdata.zerolength then - length = readcardinal2(f) - end - if length > 0 then - setposition(f,position+length) - end - end - f:close() - if not okay then - specification.error = "invalid file" - elseif not specification.error then - if xres == 0 and yres ~= 0 then - xres = yres - end - if yres == 0 and xres ~= 0 then - yres = xres - end - end - specification.xres = xres - specification.yres = yres - specification.orientation = orientation - specification.length = filesize - return specification - end - -end - -do - - local function read_boxhdr(specification,f) - local size = readcardinal4(f) - local kind = readstring(f,4) - if kind then - kind = strip(lower(kind)) - else - kind = "" - end - if size == 1 then - size = readcardinal4(f) * 0xFFFF0000 + readcardinal4(f) - end - if size == 0 and kind ~= "jp2c" then -- move this - specification.error = "invalid size" - end - return kind, size - end - - local function scan_ihdr(specification,f) - specification.ysize = readcardinal4(f) - specification.xsize = readcardinal4(f) - skipbytes(f,2) -- nc - specification.colordepth = readcardinal(f) + 1 - skipbytes(f,3) -- c unkc ipr - end - - local function scan_resc_resd(specification,f) - local vr_n = readcardinal2(f) - local vr_d = readcardinal2(f) - local hr_n = readcardinal2(f) - local hr_d = readcardinal2(f) - local vr_e = readcardinal(f) - local hr_e = readcardinal(f) - specification.xres = math.round((hr_n / hr_d) * math.exp(hr_e * math.log(10.0)) * 0.0254) - specification.yres = math.round((vr_n / vr_d) * math.exp(vr_e * math.log(10.0)) * 0.0254) - end - - local function scan_res(specification,f,last) - local pos = getposition(f) - while true do - local kind, size = read_boxhdr(specification,f) - pos = pos + size - if kind == "resc" then - if specification.xres == 0 and specification.yres == 0 then - scan_resc_resd(specification,f) - if getposition(f) ~= pos then - specification.error = "invalid resc" - return - end - end - elseif tpos == "resd" then - scan_resc_resd(specification,f) - if getposition(f) ~= pos then - specification.error = "invalid resd" - return - end - elseif pos > last then - specification.error = "invalid res" - return - elseif pos == last then - break - end - if specification.error then - break - end - setposition(f,pos) - end - end - - local function scan_jp2h(specification,f,last) - local okay = false - local pos = getposition(f) - while true do - local kind, size = read_boxhdr(specification,f) - pos = pos + size - if kind == "ihdr" then - scan_ihdr(specification,f) - if getposition(f) ~= pos then - specification.error = "invalid ihdr" - return false - end - okay = true - elseif kind == "res" then - scan_res(specification,f,pos) - elseif pos > last then - specification.error = "invalid jp2h" - return false - elseif pos == last then - break - end - if specification.error then - break - end - setposition(f,pos) - end - return okay - end - - function identifiers.jp2(filename) - local specification = { - filename = filename, - filetype = "jp2", - } - if not filename or filename == "" then - specification.error = "invalid filename" - return specification -- error - end - local f = io.open(filename,"rb") - if not f then - specification.error = "unable to open file" - return specification -- error - end - specification.xres = 0 - specification.yres = 0 - specification.orientation = 1 - specification.totalpages = 1 - specification.pagenum = 1 - specification.length = 0 - local xres = 0 - local yres = 0 - local orientation = 1 - local okay = false - local filesize = getsize(f) -- seek end - local majorversion = pdfmajorversion and pdfmajorversion() or 2 - local minorversion = pdfminorversion and pdfminorversion() or 2 - -- - local pos = 0 - -- signature - local kind, size = read_boxhdr(specification,f) - pos = pos + size - setposition(f,pos) - -- filetype - local kind, size = read_boxhdr(specification,f) - if kind ~= "ftyp" then - specification.error = "missing ftyp box" - return specification - end - pos = pos + size - setposition(f,pos) - while not okay do - local kind, size = read_boxhdr(specification,f) - pos = pos + size - if kind == "jp2h" then - okay = scan_jp2h(specification,f,pos) - elseif kind == "jp2c" and not okay then - specification.error = "no ihdr box found" - return specification - end - setposition(f,pos) - end - -- - f:close() - if not okay then - specification.error = "invalid file" - elseif not specification.error then - if xres == 0 and yres ~= 0 then - xres = yres - end - if yres == 0 and xres ~= 0 then - yres = xres - end - end - specification.xres = xres - specification.yres = yres - specification.orientation = orientation - specification.length = filesize - return specification - end - -end - -do - - -- 0 = gray "image b" - -- 2 = rgb "image c" - -- 3 = palette "image c" + "image i" - -- 4 = gray + alpha "image b" - -- 6 = rgb + alpha "image c" - - -- for i=1,length/3 do - -- palette[i] = readstring(f,3) - -- end - - local function grab(t,f,once) - if once then - for i=1,#t do - local l = t[i] - setposition(f,l.offset) - t[i] = readstring(f,l.length) - end - local data = concat(t) - return data - else - local data = { } - for i=1,#t do - local l = t[i] - setposition(f,l.offset) - data[i] = readstring(f,l.length) - end - return concat(data) - end - end - - function identifiers.png(filename) - local specification = { - filename = filename, - filetype = "png", - } - if not filename or filename == "" then - specification.error = "invalid filename" - return specification -- error - end - local f = io.open(filename,"rb") - if not f then - specification.error = "unable to open file" - return specification -- error - end - specification.xres = 0 - specification.yres = 0 - specification.orientation = 1 - specification.totalpages = 1 - specification.pagenum = 1 - specification.offset = 0 - specification.length = 0 - local filesize = getsize(f) -- seek end - local tables = { } - local banner = readstring(f,8) - if banner ~= "\137PNG\013\010\026\010" then - specification.error = "no png file" - return specification -- error - end - while true do - local position = getposition(f) - if position >= filesize then - break - end - local length = readcardinal4(f) - if not length then - break - end - local kind = readstring(f,4) - if kind then - kind = lower(kind) - else - break - end - if kind == "ihdr" then -- metadata - specification.xsize = readcardinal4(f) - specification.ysize = readcardinal4(f) - specification.colordepth = readcardinal(f) - specification.colorspace = readcardinal(f) - specification.compression = readcardinal(f) - specification.filter = readcardinal(f) - specification.interlace = readcardinal(f) - tables[kind] = true - elseif kind == "iend" then - tables[kind] = true - break - elseif kind == "phys" then - local x = readcardinal4(f) - local y = readcardinal4(f) - local u = readcardinal(f) - if u == 1 then -- meters - -- x = round(0.0254 * x) - -- y = round(0.0254 * y) - end - specification.xres = x - specification.yres = y - tables[kind] = true - elseif kind == "idat" or kind == "plte" or kind == "gama" or kind == "trns" then - local t = tables[kind] - if not t then - t = setmetatablecall(grab) - tables[kind] = t - end - t[#t+1] = { - offset = getposition(f), - length = length, - } - else - tables[kind] = true - end - setposition(f,position+length+12) -- #size #kind #crc - end - specification.tables = tables - return specification - end - -end - -do - - local function gray(t,k) - local v = 0 - t[k] = v - return v - end - - local function rgb(t,k) - local v = { 0, 0, 0 } - t[k] = v - return v - end - - local function cmyk(t,k) - local v = { 0, 0, 0, 0 } - t[k] = v - return v - end - - function identifiers.bitmap(specification) - local xsize = specification.xsize or 0 - local ysize = specification.ysize or 0 - local width = specification.width or xsize * 65536 - local height = specification.height or ysize * 65536 - local colordepth = specification.colordepth or 1 -- 1 .. 2 - local colorspace = specification.colorspace or 1 -- 1 .. 3 - local pixel = false - local data = specification.data - local mask = specification.mask - if colorspace == 1 or colorspace == "gray" then - pixel = gray - colorspace = 1 - elseif colorspace == 2 or colorspace == "rgb" then - pixel = rgb - colorspace = 2 - elseif colorspace == 3 or colorspace == "cmyk" then - pixel = cmyk - colorspace = 3 - else - return - end - if colordepth == 8 then - colordepth = 1 - elseif colordepth == 16 then - colordepth = 2 - end - if colordepth > 1 then - -- not yet - return - end - if data then - -- assume correct data - else - data = { } - for i=1,ysize do - data[i] = setmetatableindex(pixel) - end - end - if mask == true then - mask = { } - for i=1,ysize do - mask[i] = setmetatableindex(gray) - end - end - local specification = { - xsize = xsize, - ysize = ysize, - width = width, - height = height, - colordepth = colordepth, - colorspace = colorspace, - data = data, - mask = mask, - } - return specification - end - -end - -function graphics.identify(filename,filetype) - local identify = filetype and identifiers[filetype] - if identify then - return identify(filename) - end - local identify = identifiers[suffixonly(filename)] - if identify then - return identify(filename) - end - -- auto - return { - filename = filename, - filetype = filetype, - error = "identification failed", - } -end - --- inspect(identifiers.jpg("t:/sources/hacker.jpg")) --- inspect(identifiers.png("t:/sources/mill.png")) diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua index 334a0b536..ee4ed2a28 100644 --- a/tex/context/base/mkiv/grph-inc.lua +++ b/tex/context/base/mkiv/grph-inc.lua @@ -54,8 +54,7 @@ local concat, insert, remove = table.concat, table.insert, table.remove local todimen = string.todimen local collapsepath = file.collapsepath local formatters = string.formatters -local formatcolumns = utilities.formatters.formatcolumns -local max, odd = math.max, math.odd +local odd = math.odd local P, R, S, Cc, C, Cs, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.Cc, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.match @@ -2164,315 +2163,3 @@ implement { end end } - --- This is an experiment. The following method uses Lua to handle the embedding --- using the epdf library. This feature will be used when we make the transition --- from the pre 1.10 epdf library (using an unsuported low level poppler api) to a --- new (lightweight, small and statically compiled) library. More on that later. --- --- The method implemented below has the same performance as the hard coded inclusion --- but opens up some possibilities (like merging fonts) that I will look into some --- day. - -local function pdf_checker(data) - local request = data.request - local used = data.used - if request and used and not request.scanimage then - local image = lpdf.epdf.image - local openpdf = image.open - local closepdf = image.close - local querypdf = image.query - local copypage = image.copy - local pdfdoc = nil - request.scanimage = function(t) - pdfdoc = openpdf(t.filename,request.userpassword,request.ownerpassword) - if pdfdoc then - -- - pdfdoc.nofcopiedpages = 0 - -- - local info = querypdf(pdfdoc,request.page) - if info then - local bbox = info and info.boundingbox or { 0, 0, 0, 0 } - local height = bbox[4] - bbox[2] - local width = bbox[3] - bbox[1] - local rotation = info.rotation or 0 - if rotation == 90 then - rotation, height, width = 3, width, height - elseif rotation == 180 then - rotation = 2 - elseif rotation == 270 then - rotation, height, width = 1, width, height - elseif rotation == 1 or rotation == 3 then - height, width = width, height - else - rotation = 0 - end - return { - filename = filename, - -- page = 1, - pages = pdfdoc.nofpages, - width = width, - height = height, - depth = 0, - colordepth = 0, - xres = 0, - yres = 0, - xsize = width, - ysize = height, - rotation = rotation, - pdfdoc = pdfdoc, - } - end - end - end - request.copyimage = function(t) - if not pdfdoc then - pdfdoc = t.pdfdoc - end - if pdfdoc then - local result = copypage(pdfdoc,request.page,nil,request.compact,request.width,request.height,request.attr) - pdfdoc.nofcopiedpages = pdfdoc.nofcopiedpages + 1 - if pdfdoc.nofcopiedpages >= pdfdoc.nofpages then - closepdf(pdfdoc) - pdfdoc = nil - t.pdfdoc = nil - end - return result - else - -- message, should not happen as we always first scan so that reopens - end - end - end - return checkers.generic(data) -end - -local function wrappedidentify(identify,filename) - local wrapup = function() report_inclusion("fatal error reading %a",filename) end - local _, result = xpcall(identify,wrapup,filename) - if result then - local xsize = result.xsize or 0 - local ysize = result.ysize or 0 - local xres = result.xres or 0 - local yres = result.yres or 0 - if xres == 0 or yres == 0 then - xres = 300 - yres = 300 - end - result.xsize = xsize - result.ysize = ysize - result.xres = xres - result.yres = yres - result.width = result.width or ((72/xres) * xsize / bpfactor) - result.height = result.height or ((72/yres) * ysize / bpfactor) - result.depth = result.depth or 0 - result.filename = filename - result.colordepth = result.colordepth or 0 - result.rotation = result.rotation or 0 - result.colorspace = result.colorspace or 0 - return result - else - return { error = "fatal error" } - end -end - -local function jpg_checker(data) - local request = data.request - local used = data.used - if request and used and not request.scanimage then - local identify = graphics.identify - local inject = lpdf.injectors.jpg - local found = false - request.scanimage = function(t) - local result = wrappedidentify(identify,t.filename) - found = not result.error - return { - filename = result.filename, - width = result.width, - height = result.height, - depth = result.depth, - colordepth = result.colordepth, - xres = result.xres, - yres = result.yres, - xsize = result.xsize, - ysize = result.ysize, - rotation = result.rotation, - colorspace = result.colorspace, - } - end - request.copyimage = function(t) - if found then - found = false - return inject(t) - end - end - end - return checkers.generic(data) -end - -local function jp2_checker(data) -- idem as jpg - local request = data.request - local used = data.used - if request and used and not request.scanimage then - local identify = graphics.identify - local inject = lpdf.injectors.jp2 - local found = false - request.scanimage = function(t) - local result = wrappedidentify(identify,t.filename) - found = not result.error - return { - filename = result.filename, - width = result.width, - height = result.height, - depth = result.depth, - colordepth = result.colordepth, - xres = result.xres, - yres = result.yres, - xsize = result.xsize, - ysize = result.ysize, - rotation = result.rotation, - colorspace = result.colorspace, - } - end - request.copyimage = function(t) - if found then - found = false - return inject(t) - end - end - end - return checkers.generic(data) -end - -local function png_checker(data) -- same as jpg (for now) - local request = data.request - local used = data.used - if request and used and not request.scanimage then - local identify = graphics.identify - local inject = lpdf.injectors.png - local found = false - request.scanimage = function(t) - local result = wrappedidentify(identify,t.filename) - found = not result.error - return { - filename = result.filename, - width = result.width, - height = result.height, - depth = result.depth, - colordepth = result.colordepth, - xres = result.xres, - yres = result.yres, - xsize = result.xsize, - ysize = result.ysize, - rotation = result.rotation, - colorspace = result.colorspace, - tables = result.tables, - interlace = result.interlace, - filter = result.filter, - } - end - request.copyimage = function(t) - if found then - found = false - return inject(t) - end - end - end - return checkers.generic(data) -end - -directives.register("graphics.pdf.uselua",function(v) - checkers.pdf = v and pdf_checker or nil - report("%s Lua based PDF inclusion",v and "enabling" or "disabling") -end) - -directives.register("graphics.jpg.uselua",function(v) - checkers.jpg = v and jpg_checker or nil - report("%s Lua based JPG inclusion",v and "enabling" or "disabling") -end) - -directives.register("graphics.jp2.uselua",function(v) - checkers.jp2 = v and jp2_checker or nil - report("%s Lua based JP2 inclusion",v and "enabling" or "disabling") -end) - -directives.register("graphics.png.uselua",function(v) - checkers.png = v and png_checker or nil - report("%s Lua based PNG inclusion",v and "enabling" or "disabling") -end) - -directives.register("graphics.uselua",function(v) - checkers.pdf = v and pdf_checker or nil - checkers.jpg = v and jpg_checker or nil - checkers.jp2 = v and jp2_checker or nil - checkers.png = v and png_checker or nil - -- report("%s Lua based PDF, PNG, JPG and JP2 inclusion",v and "enabling" or "disabling") -end) - --- directives.enable("graphics.pdf.uselua") --- --- local filename = "luatex.pdf" --- --- for i=1,240 do --- context(function() --- context.startTEXpage() --- context.externalfigure( { filename }, { page = i } ) --- context.stopTEXpage() --- end) --- end - --- This is experimental, for the moment here: - -local bitmaps = { } -graphics.bitmaps = bitmaps - -local report_bitmap = logs.reporter("graphics","bitmap") - -function bitmaps.new(xsize,ysize,colorspace,colordepth,mask) - if not xsize or not ysize or xsize == 0 or ysize == 0 then - report_bitmap("provide 'xsize' and 'ysize' larger than zero") - return - end - if not colorspace then - report_bitmap("provide 'colorspace' (1, 2, 3, 'gray', 'rgb', 'cmyk'") - return - end - if not colordepth then - report_bitmap("provide 'colordepth' (1, 2)") - return - end - return graphics.identifiers.bitmap { - colorspace = colorspace, - colordepth = colordepth, - xsize = xsize, - ysize = ysize, - mask = mask and true or nil, - } -end - -local function flush(bitmap) - return wrapimage(lpdf.injectors.bitmap(bitmap)) -end - -bitmaps.flush = flush - -function bitmaps.tocontext(bitmap,width,height) - if type(width) == "number" then - width = width .. "sp" - end - if type(height) == "number" then - height = height .. "sp" - end - if width or height then - context.scale ( - { - width = width, - height = height, - }, - flush(bitmap) - ) - else - context(flush(bitmap)) - end -end - - diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv index 4668b6f48..87ea14ae9 100644 --- a/tex/context/base/mkiv/grph-inc.mkiv +++ b/tex/context/base/mkiv/grph-inc.mkiv @@ -22,6 +22,11 @@ \registerctxluafile{grph-img}{} \registerctxluafile{grph-inc}{} + +\doifelsefileexists {grph-chk.lua} { + \registerctxluafile{grph-chk}{} +} {} + \registerctxluafile{grph-con}{} \registerctxluafile{grph-fil}{} \registerctxluafile{grph-mem}{} diff --git a/tex/context/base/mkiv/l-lpeg.lua b/tex/context/base/mkiv/l-lpeg.lua index eb55a55a0..51bc1d3df 100644 --- a/tex/context/base/mkiv/l-lpeg.lua +++ b/tex/context/base/mkiv/l-lpeg.lua @@ -657,83 +657,6 @@ function lpeg.counter(pattern,action) end end --- utf extensies - --- utf = utf or (unicode and unicode.utf8) or { } -utf = utf or { } - -local utfcharacters = utf and utf.characters or string.utfcharacters -local utfgmatch = utf and utf.gmatch -local utfchar = utf and utf.char - -lpeg.UP = lpeg.P - -if utfcharacters then - - function lpeg.US(str) - local p = P(false) - for uc in utfcharacters(str) do - p = p + P(uc) - end - return p - end - - -elseif utfgmatch then - - function lpeg.US(str) - local p = P(false) - for uc in utfgmatch(str,".") do - p = p + P(uc) - end - return p - end - -else - - function lpeg.US(str) - local p = P(false) - local f = function(uc) - p = p + P(uc) - end - lpegmatch((utf8char/f)^0,str) - return p - end - -end - -local range = utf8byte * utf8byte + Cc(false) -- utf8byte is already a capture - -function lpeg.UR(str,more) - local first, last - if type(str) == "number" then - first = str - last = more or first - else - first, last = lpegmatch(range,str) - if not last then - return P(str) - end - end - if first == last then - return P(str) - elseif utfchar and (last - first < 8) then -- a somewhat arbitrary criterium - local p = P(false) - for i=first,last do - p = p + P(utfchar(i)) - end - return p -- nil when invalid range - else - local f = function(b) - return b >= first and b <= last - end - -- tricky, these nested captures - return utf8byte / f -- nil when invalid range - end -end - --- print(lpeg.match(lpeg.Cs((C(lpeg.UR("αω"))/{ ["χ"] = "OEPS" })^0),"αωχαω")) - -- lpeg.print(lpeg.R("ab","cd","gh")) -- lpeg.print(lpeg.P("a","b","c")) -- lpeg.print(lpeg.S("a","b","c")) @@ -1052,7 +975,6 @@ function lpeg.utfreplacer(list,insensitive) end end - -- local t = { "start", "stoep", "staart", "paard" } -- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) diff --git a/tex/context/base/mkiv/l-macro-imp-optimize.lua b/tex/context/base/mkiv/l-macro-imp-optimize.lua index 982548785..7d7fafefd 100644 --- a/tex/context/base/mkiv/l-macro-imp-optimize.lua +++ b/tex/context/base/mkiv/l-macro-imp-optimize.lua @@ -47,17 +47,21 @@ if LUAVERSION >= 5.3 and lua.macros then -- ]] lua.macros.resolvestring [[ -#define band(a,b) (a&b) -#define bnot(a) (~a&0xFFFFFFFF) -#define bor(a,b) ((a|b)&0xFFFFFFFF) -#define btest(a,b) ((a&b)~=0) -#define bxor(a,b) ((a~b)&0xFFFFFFFF) -#define rshift(a,b) ((a&b)~=0) -#define extract(a,b,c) ((a>>b)&~(-1<<c)) -#define extract(a,b) ((a>>b)&0x1) -#define lshift(a,b) ((a<<b)&0xFFFFFFFF) -#define rshift(a,b) ((a>>b)&0xFFFFFFFF) -#define intdiv(a,b) (a//b) +#define band(a,b) ((a)&(b)) +#define bnot(a) (~(a)&0xFFFFFFFF) +#define bor(a,b) (((a)|(b))&0xFFFFFFFF) +#define btest(a,b) (((a)&(b))~=0) +#define bxor(a,b) (((a)~(b))&0xFFFFFFFF) +#define rshift(a,b) (((a)&(b))~=0) +#define extract(a,b,c) (((a)>>(b))&~(-1<<(c))) +#define extract(a,b) (((a)>>(b))&0x1) +#define extract1(a,b) ((a >> b) & 0x01) +#define extract2(a,b) ((a >> b) & 0x03) +#define extract4(a,b) ((a >> b) & 0x0F) +#define lshift(a,b) (((a)<<(b))&0xFFFFFFFF) +#define rshift(a,b) (((a)>>(b))&0xFFFFFFFF) +#define intdiv(a,b) ((a)//(b)) +#define idiv(a,b) ((a)//(b)) ]] end diff --git a/tex/context/base/mkiv/l-os.lua b/tex/context/base/mkiv/l-os.lua index c2a903f5c..cf469f79d 100644 --- a/tex/context/base/mkiv/l-os.lua +++ b/tex/context/base/mkiv/l-os.lua @@ -32,6 +32,72 @@ local concat = table.concat local random, ceil, randomseed = math.random, math.ceil, math.randomseed local rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring = rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring +-- This check needs to happen real early on. Todo: we can pick it up from the commandline +-- if we pass --binpath= (which is useful anyway) + +do + local selfdir = os.selfdir + if selfdir == "" then + selfdir = nil + end + if not selfdir then + -- We need a fallback plan so let's see what we get. + if arg then + -- passed by mtx-context ... saves network access + for i=1,#arg do + local a = arg[i] + if find(a,"^%-%-[c:]*texmfbinpath=") then + selfdir = gsub(a,"^.-=","") + break + end + end + end + if not selfdir then + selfdir = os.selfbin or "luatex" + if find(selfdir,"[/\\]") then + selfdir = gsub(selfdir,"[/\\][^/\\]*$","") + elseif os.getenv then + local path = os.getenv("PATH") + local name = gsub(selfdir,"^.*[/\\][^/\\]","") + local patt = "[^:]+" + if os.type == "windows" then + patt = "[^;]+" + name = name .. ".exe" + end + local isfile + if lfs then + -- we're okay as lfs is assumed present + local attributes = lfs.attributes + isfile = function(name) + local a = attributes(name,"mode") + return a == "file" or a == "link" or nil + end + else + -- we're not okay and much will not work as we miss lfs + local open = io.open + isfile = function(name) + local f = open(name) + if f then + f:close() + return true + end + end + end + for p in gmatch(path,patt) do + -- possible speedup: there must be tex in 'p' + if isfile(p .. "/" .. name) then + selfdir = p + break + end + end + end + end + -- let's hope we're okay now + os.selfdir = selfdir or "." + end +end +-- print(os.selfdir) os.exit() + -- The following code permits traversing the environment table, at least in luatex. Internally all -- environment names are uppercase. diff --git a/tex/context/base/mkiv/l-unicode.lua b/tex/context/base/mkiv/l-unicode.lua index 433736602..13e0a3fa1 100644 --- a/tex/context/base/mkiv/l-unicode.lua +++ b/tex/context/base/mkiv/l-unicode.lua @@ -21,8 +21,8 @@ if not modules then modules = { } end modules ['l-unicode'] = { -- todo: utf.sub replacement (used in syst-aux) -- we put these in the utf namespace: --- used : byte char gmatch len lower sub upper --- not used : dump find format gfind gsub match rep reverse +-- used : byte char len lower sub upper +-- not used : dump find format gmatch gfind gsub match rep reverse -- utf = utf or (unicode and unicode.utf8) or { } @@ -33,8 +33,21 @@ if not modules then modules = { } end modules ['l-unicode'] = { utf = utf or { } unicode = nil -utf.characters = utf.characters or string.utfcharacters -utf.values = utf.values or string.utfvalues +if not string.utfcharacters then + + -- New: this gmatch hack is taken from the Lua 5.2 book. It's about two times slower + -- than the built-in string.utfcharacters. + + local gmatch = string.gmatch + + function string.characters(str) + return gmatch(str,".[\128-\191]*") + end + + +end + +utf.characters = string.utfcharacters -- string.utfvalues -- string.utfcharacters @@ -60,13 +73,11 @@ local bytepairs = string.bytepairs local finder = lpeg.finder local replacer = lpeg.replacer -local utfvalues = utf.values -local utfgmatch = utf.gmatch -- not always present - local p_utftype = patterns.utftype local p_utfstricttype = patterns.utfstricttype local p_utfoffset = patterns.utfoffset -local p_utf8char = patterns.utf8character +local p_utf8character = patterns.utf8character +local p_utf8char = patterns.utf8char local p_utf8byte = patterns.utf8byte local p_utfbom = patterns.utfbom local p_newline = patterns.newline @@ -169,10 +180,8 @@ if not utf.byte then if not utf.byte then - local utf8byte = patterns.utf8byte - function utf.byte(c) - return lpegmatch(utf8byte,c) + return lpegmatch(p_utf8byte,c) end end @@ -286,7 +295,7 @@ if not utf.len then -- -- alternative 1: 0.77 -- - -- local utfcharcounter = utfbom^-1 * Cs((p_utf8char/'!')^0) + -- local utfcharcounter = utfbom^-1 * Cs((p_utf8character/'!')^0) -- -- function utf.len(str) -- return #lpegmatch(utfcharcounter,str or "") @@ -296,7 +305,7 @@ if not utf.len then -- -- local n = 0 -- - -- local utfcharcounter = utfbom^-1 * (p_utf8char/function() n = n + 1 end)^0 -- slow + -- local utfcharcounter = utfbom^-1 * (p_utf8character/function() n = n + 1 end)^0 -- slow -- -- function utf.length(str) -- n = 0 @@ -373,7 +382,7 @@ if not utf.sub then -- inefficient as lpeg just copies ^n -- local function sub(str,start,stop) - -- local pattern = p_utf8char^-(start-1) * C(p_utf8char^-(stop-start+1)) + -- local pattern = p_utf8character^-(start-1) * C(p_utf8character^-(stop-start+1)) -- inspect(pattern) -- return lpegmatch(pattern,str) or "" -- end @@ -396,7 +405,7 @@ if not utf.sub then -- end -- end -- - -- local pattern = Cmt(p_utf8char,slide)^0 + -- local pattern = Cmt(p_utf8character,slide)^0 -- -- function utf.sub(str,start,stop) -- todo: from the end -- if not start then @@ -451,11 +460,11 @@ if not utf.sub then end end - local pattern_zero = Cmt(p_utf8char,slide_zero)^0 - local pattern_one = Cmt(p_utf8char,slide_one )^0 - local pattern_two = Cmt(p_utf8char,slide_two )^0 + local pattern_zero = Cmt(p_utf8character,slide_zero)^0 + local pattern_one = Cmt(p_utf8character,slide_one )^0 + local pattern_two = Cmt(p_utf8character,slide_two )^0 - local pattern_first = C(patterns.utf8character) + local pattern_first = C(p_utf8character) function utf.sub(str,start,stop) if not start then @@ -551,7 +560,7 @@ end -- a replacement for simple gsubs: -- function utf.remapper(mapping) --- local pattern = Cs((p_utf8char/mapping)^0) +-- local pattern = Cs((p_utf8character/mapping)^0) -- return function(str) -- if not str or str == "" then -- return "" @@ -573,16 +582,16 @@ function utf.remapper(mapping,option,action) -- static also returns a pattern return "" else if not pattern then - pattern = Cs((tabletopattern(mapping)/action + p_utf8char)^0) + pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0) end return lpegmatch(pattern,str) end end elseif option == "pattern" then - return Cs((tabletopattern(mapping)/action + p_utf8char)^0) + return Cs((tabletopattern(mapping)/action + p_utf8character)^0) -- elseif option == "static" then else - local pattern = Cs((tabletopattern(mapping)/action + p_utf8char)^0) + local pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0) return function(str) if not str or str == "" then return "" @@ -593,9 +602,9 @@ function utf.remapper(mapping,option,action) -- static also returns a pattern end elseif variant == "function" then if option == "pattern" then - return Cs((p_utf8char/mapping + p_utf8char)^0) + return Cs((p_utf8character/mapping + p_utf8character)^0) else - local pattern = Cs((p_utf8char/mapping + p_utf8char)^0) + local pattern = Cs((p_utf8character/mapping + p_utf8character)^0) return function(str) if not str or str == "" then return "" @@ -642,9 +651,9 @@ end -- inspect(utf.split("a b c d",true)) local utflinesplitter = p_utfbom^-1 * lpeg.tsplitat(p_newline) -local utfcharsplitter_ows = p_utfbom^-1 * Ct(C(p_utf8char)^0) -local utfcharsplitter_iws = p_utfbom^-1 * Ct((p_whitespace^1 + C(p_utf8char))^0) -local utfcharsplitter_raw = Ct(C(p_utf8char)^0) +local utfcharsplitter_ows = p_utfbom^-1 * Ct(C(p_utf8character)^0) +local utfcharsplitter_iws = p_utfbom^-1 * Ct((p_whitespace^1 + C(p_utf8character))^0) +local utfcharsplitter_raw = Ct(C(p_utf8character)^0) patterns.utflinesplitter = utflinesplitter @@ -780,7 +789,7 @@ local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_ -- if right then -- local now = 256*left + right -- if more > 0 then --- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong +-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- more = 0 -- r = r + 1 -- result[r] = utfchar(now) @@ -809,7 +818,7 @@ local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_ -- if right then -- local now = 256*right + left -- if more > 0 then --- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong +-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- more = 0 -- r = r + 1 -- result[r] = utfchar(now) @@ -839,7 +848,7 @@ local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_ -- if right then -- local now = 256*right + left -- if more > 0 then --- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong +-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- more = 0 -- r = r + 1 -- result[r] = utfchar(now) @@ -916,7 +925,7 @@ local more = 0 local p_utf16_to_utf8_be = C(1) * C(1) /function(left,right) local now = 256*byte(left) + byte(right) if more > 0 then - now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 more = 0 return utfchar(now) elseif now >= 0xD800 and now <= 0xDBFF then @@ -930,7 +939,7 @@ end local p_utf16_to_utf8_le = C(1) * C(1) /function(right,left) local now = 256*byte(left) + byte(right) if more > 0 then - now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 more = 0 return utfchar(now) elseif now >= 0xD800 and now <= 0xDBFF then @@ -1124,15 +1133,6 @@ function utf.utf8_to_utf16(str,littleendian,nobom) end end --- function utf.tocodes(str,separator) -- can be sped up with an lpeg --- local t, n = { }, 0 --- for u in utfvalues(str) do --- n = n + 1 --- t[n] = format("0x%04X",u) --- end --- return concat(t,separator or " ") --- end - local pattern = Cs ( (p_utf8byte / function(unicode ) return format( "0x%04X", unicode) end) * (p_utf8byte * Carg(1) / function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0 @@ -1168,25 +1168,10 @@ end -- -local p_nany = p_utf8char / "" +do -if utfgmatch then - - function utf.count(str,what) - if type(what) == "string" then - local n = 0 - for _ in utfgmatch(str,what) do - n = n + 1 - end - return n - else -- 4 times slower but still faster than / function - return #lpegmatch(Cs((P(what)/" " + p_nany)^0),str) - end - end - -else - - local cache = { } + local p_nany = p_utf8character / "" + local cache = { } function utf.count(str,what) if type(what) == "string" then @@ -1203,23 +1188,7 @@ else end --- maybe also register as string.utf* - - -if not utf.characters then - - -- New: this gmatch hack is taken from the Lua 5.2 book. It's about two times slower - -- than the built-in string.utfcharacters. - - function utf.characters(str) - return gmatch(str,".[\128-\191]*") - end - - string.utfcharacters = utf.characters - -end - -if not utf.values then +if not string.utfvalues then -- So, a logical next step is to check for the values variant. It over five times -- slower than the built-in string.utfvalues. I optimized it a bit for n=0,1. @@ -1231,7 +1200,7 @@ if not utf.values then -- we share this one end - -- function utf.values(str) + -- function string.utfvalues(str) -- local n = #str -- if n == 0 then -- return wrap(dummy) @@ -1246,7 +1215,7 @@ if not utf.values then -- -- faster: - function utf.values(str) + function string.utfvalues(str) local n = #str if n == 0 then return dummy @@ -1269,11 +1238,11 @@ if not utf.values then -- slower: -- - -- local pattern = C(patterns.utf8character) * Cp() - -- ----- pattern = patterns.utf8character/utfbyte * Cp() - -- ----- pattern = patterns.utf8byte * Cp() + -- local pattern = C(p_utf8character) * Cp() + -- ----- pattern = p_utf8character/utfbyte * Cp() + -- ----- pattern = p_utf8byte * Cp() -- - -- function utf.values(str) -- one of the cases where a find is faster than an lpeg + -- function string.utfvalues(str) -- one of the cases where a find is faster than an lpeg -- local n = #str -- if n == 0 then -- return dummy @@ -1292,10 +1261,10 @@ if not utf.values then -- end -- end - string.utfvalues = utf.values - end +utf.values = string.utfvalues + function utf.chrlen(u) -- u is number return (u < 0x80 and 1) or @@ -1364,3 +1333,73 @@ function string.utfpadd(s,n) end return s end + +-- goodies + +do + + local utfcharacters = utf.characters or string.utfcharacters + local utfchar = utf.char or string.utfcharacter + + lpeg.UP = P + + if utfcharacters then + + function lpeg.US(str) + local p = P(false) + for uc in utfcharacters(str) do + p = p + P(uc) + end + return p + end + + else + + function lpeg.US(str) + local p = P(false) + local f = function(uc) + p = p + P(uc) + end + lpegmatch((p_utf8char/f)^0,str) + return p + end + + end + + local range = p_utf8byte * p_utf8byte + Cc(false) -- utf8byte is already a capture + + function lpeg.UR(str,more) + local first, last + if type(str) == "number" then + first = str + last = more or first + else + first, last = lpegmatch(range,str) + if not last then + return P(str) + end + end + if first == last then + return P(str) + end + if not utfchar then + utfchar = utf.char -- maybe delayed + end + if utfchar and (last - first < 8) then -- a somewhat arbitrary criterium + local p = P(false) + for i=first,last do + p = p + P(utfchar(i)) + end + return p -- nil when invalid range + else + local f = function(b) + return b >= first and b <= last + end + -- tricky, these nested captures + return p_utf8byte / f -- nil when invalid range + end + end + + -- print(lpeg.match(lpeg.Cs((C(lpeg.UR("αω"))/{ ["χ"] = "OEPS" })^0),"αωχαω")) + +end diff --git a/tex/context/base/mkiv/lpdf-epd.lua b/tex/context/base/mkiv/lpdf-epd.lua index a5eab016f..fe94a430b 100644 --- a/tex/context/base/mkiv/lpdf-epd.lua +++ b/tex/context/base/mkiv/lpdf-epd.lua @@ -1280,7 +1280,7 @@ if img then do -- image attributes FormType = 1, BBox = pageinfo.cropbox, - -- MetaData = copy(xref,copied,root,"MetaData"), + -- Metadata = copy(xref,copied,root,"Metadata"), -- Group = copy(xref,copied,page,"Group"), -- LastModified = copy(xref,copied,page,"LastModified"), -- Metadata = copy(xref,copied,page,"Metadata"), diff --git a/tex/context/base/mkiv/lpdf-img.lua b/tex/context/base/mkiv/lpdf-img.lua deleted file mode 100644 index ba4d4ff8e..000000000 --- a/tex/context/base/mkiv/lpdf-img.lua +++ /dev/null @@ -1,1052 +0,0 @@ -if not modules then modules = { } end modules ['lpdf-img'] = { - version = 1.001, - comment = "companion to lpdf-ini.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - -local concat, remove, insert = table.concat, table.remove, table.insert -local ceil = math.ceil -local char, find = string.char, string.find -local idiv = number.idiv -local band, rshift = bit32.band, bit32.rshift - -local loaddata = io.loaddata -local setmetatableindex = table.setmetatableindex - -local streams = utilities.streams -local openstring = streams.openstring -local readstring = streams.readstring -local readbytetable = streams.readbytetable - -local lpdf = lpdf or { } -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfconstant = lpdf.constant -local pdfstring = lpdf.string -local pdfflushstreamobject = lpdf.flushstreamobject -local pdfreference = lpdf.reference - -local pdfmajorversion = lpdf.majorversion -local pdfminorversion = lpdf.minorversion - -local createimage = images.create - -local trace = false - -local report_jpg = logs.reporter("graphics","jpg") -local report_jp2 = logs.reporter("graphics","jp2") -local report_png = logs.reporter("graphics","png") - -trackers.register("graphics.backend", function(v) trace = v end) - -local injectors = { } -lpdf.injectors = injectors - -local chars = setmetatableindex(function(t,k) -- share this one - local v = (k <= 0 and "\000") or (k >= 255 and "\255") or char(k) - t[k] = v - return v -end) - -do - - function injectors.jpg(specification) - if specification.error then - return - end - local filename = specification.filename - if not filename then - return - end - local colorspace = specification.colorspace or jpg_gray - local decodearray = nil - ----- procset = colorspace == 0 and "image b" or "image c" - if colorspace == 1 then - colorspace = "DeviceGray" - elseif colorspace == 2 then - colorspace = "DeviceRGB" - elseif colorspace == 3 then - colorspace = "DeviceCMYK" - decodearray = pdfarray { 1, 0, 1, 0, 1, 0, 1, 0 } - end - -- todo: set filename - local xsize = specification.xsize - local ysize = specification.ysize - local colordepth = specification.colordepth - local content = loaddata(filename) - local xobject = pdfdictionary { - Type = pdfconstant("XObject"), - Subtype = pdfconstant("Image"), - -- BBox = pdfarray { 0, 0, xsize, ysize }, - Width = xsize, - Height = ysize, - BitsPerComponent = colordepth, - Filter = pdfconstant("DCTDecode"), - ColorSpace = pdfconstant(colorspace), - Decode = decodearray, - Length = #content, -- specification.length - } + specification.attr - if trace then - report_jpg("%s: width %i, height %i, colordepth %i, size %i",filename,xsize,ysize,colordepth,#content) - end - return createimage { - bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate - nolength = true, - nobbox = true, - notype = true, - stream = content, - attr = xobject(), - } - end - -end - -do - - function injectors.jp2(specification) - if specification.error then - return - end - local filename = specification.filename - if not filename then - return - end - -- todo: set filename - local xsize = specification.xsize - local ysize = specification.ysize - local content = loaddata(filename) - local xobject = pdfdictionary { - Type = pdfconstant("XObject"), - Subtype = pdfconstant("Image"), - BBox = pdfarray { 0, 0, xsize, ysize }, - Width = xsize, - Height = ysize, - Filter = pdfconstant("JPXDecode"), - Length = #content, -- specification.length - } + specification.attr - if trace then - report_jp2("%s: width %i, height %i, size %i",filename,xsize,ysize,#content) - end - return createimage { - bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate - nolength = true, - nobbox = true, - notype = true, - stream = content, - attr = xobject(), - } - end - -end - -do - - -- We don't like interlaced files. You can deinterlace them beforehand because otherwise - -- each run you add runtime. Actually, even masked images can best be converted to PDF - -- beforehand. - - -- The amount of code is larger that I like and looks somewhat redundant but we sort of - -- optimize a few combinations that happen often. - - local function convert(t,len) - if len then -local n = 0 - for i=1,#t,len do - t[i] = "" -n = n + 1 - end - end - for i=1,#t do - local ti = t[i] - if ti ~= "" then - t[i] = chars[ti] - end - end - return concat(t) - end - - local function zero(t,k) - return 0 - end - - local function bump(txt,t,xsize,ysize,bpp) - local l = xsize * bpp + 1 - print(txt,">",xsize,ysize,bpp,l) - for i=1,ysize do - local f = (i-1) * l + 1 - print(txt,i,":",concat(t," ",f,f+l-1)) - end - end - - local function decodeall(t,xsize,ysize,bpp) - local len = xsize * bpp + 1 - local n = 1 - local m = len - 1 - for i=1,ysize do - local filter = t[n] -t[n] = 0 -- not needed - if filter == 0 then - elseif filter == 1 then - for j=n+bpp+1,n+m do - t[j] = (t[j] + t[j-bpp]) % 256 - end - elseif filter == 2 then - for j=n+1,n+m do - t[j] = (t[j] + t[j-len]) % 256 - end - elseif filter == 3 then - for j=n+1,n+bpp do - t[j] = (t[j] + idiv(t[j-len],2)) % 256 - end - for j=n+bpp+1,n+m do - t[j] = (t[j] + idiv(t[j-bpp] + t[j-len],2)) % 256 - end - elseif filter == 4 then - for j=n+1,n+bpp do - local p = j - len - local b = t[p] - if b < 0 then - b = - b - end - if b > 0 then - t[j] = (t[j] + b) % 256 - end - end - for j=n+bpp+1,n+m do - local p = j - len - local a = t[j-bpp] - local b = t[p] - local c = t[p-bpp] - local pa = b - c - local pb = a - c - local pc = pa + pb - if pa < 0 then pa = - pa end - if pb < 0 then pb = - pb end - if pc < 0 then pc = - pc end - t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256 - end - end - n = n + len - end - end - - local xstart = { 0, 4, 0, 2, 0, 1, 0 } - local xstep = { 8, 8, 4, 4, 2, 2, 1 } - local ystart = { 0, 0, 4, 0, 2, 0, 1 } - local ystep = { 8, 8, 8, 4, 4, 2, 2 } - ----- xmax = { 8, 4, 4, 2, 2, 1, 1 } -- for block fill - ----- ymax = { 8, 8, 4, 4, 2, 2, 1 } -- for block fill - - local function newoutput(width,height) - local t = { } - for i=1,height*width do - t[i] = 0 - end - return t - end - - local function expand(t,xsize,ysize,parts,factor) -- we don't compact - local o = { } - local k = 0 - local l = ceil(xsize*parts/8) + 1 - local n = 1 - if factor then - if parts == 4 then - for i=1,ysize do - k = k + 1 ; o[k] = t[n] - for j=n+1,n+l do - local v = t[j] - k = k + 1 ; o[k] = band(rshift(v,4),0x0F) * 0x11 ; k = k + 1 ; o[k] = band(rshift(v,0),0x0F) * 0x11 - end - k = i * (xsize + 1) - n = n + l - end - elseif parts == 2 then - for i=1,ysize do - k = k + 1 ; o[k] = t[n] - for j=n+1,n+l do - local v = t[j] - k = k + 1 ; o[k] = band(rshift(v,6),0x03) * 0x55 ; k = k + 1 ; o[k] = band(rshift(v,4),0x03) * 0x55 - k = k + 1 ; o[k] = band(rshift(v,2),0x03) * 0x55 ; k = k + 1 ; o[k] = band(rshift(v,0),0x03) * 0x55 - end - k = i * (xsize + 1) - n = n + l - end - else - for i=1,ysize do - k = k + 1 ; o[k] = t[n] - for j=n+1,n+l do - local v = t[j] - k = k + 1 ; o[k] = band(rshift(v,7),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,6),0x01) * 0xFF - k = k + 1 ; o[k] = band(rshift(v,5),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,4),0x01) * 0xFF - k = k + 1 ; o[k] = band(rshift(v,3),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,2),0x01) * 0xFF - k = k + 1 ; o[k] = band(rshift(v,1),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,0),0x01) * 0xFF - end - k = i * (xsize + 1) - n = n + l - end - end - else - if parts == 4 then - for i=1,ysize do - k = k + 1 ; o[k] = t[n] - for j=n+1,n+l do - local v = t[j] - k = k + 1 ; o[k] = band(rshift(v,4),0x0F) ; k = k + 1 ; o[k] = band(rshift(v,0),0x0F) - end - k = i * (xsize + 1) - n = n + l - end - elseif parts == 2 then - for i=1,ysize do - k = k + 1 ; o[k] = t[n] - for j=n+1,n+l do - local v = t[j] - k = k + 1 ; o[k] = band(rshift(v,6),0x03) ; k = k + 1 ; o[k] = band(rshift(v,4),0x03) - k = k + 1 ; o[k] = band(rshift(v,2),0x03) ; k = k + 1 ; o[k] = band(rshift(v,0),0x03) - end - k = i * (xsize + 1) - n = n + l - end - else - for i=1,ysize do - k = k + 1 ; o[k] = t[n] - for j=n+1,n+l do - local v = t[j] - k = k + 1 ; o[k] = band(rshift(v,7),0x01) ; k = k + 1 ; o[k] = band(rshift(v,6),0x01) - k = k + 1 ; o[k] = band(rshift(v,5),0x01) ; k = k + 1 ; o[k] = band(rshift(v,4),0x01) - k = k + 1 ; o[k] = band(rshift(v,3),0x01) ; k = k + 1 ; o[k] = band(rshift(v,2),0x01) - k = k + 1 ; o[k] = band(rshift(v,1),0x01) ; k = k + 1 ; o[k] = band(rshift(v,0),0x01) - end - k = i * (xsize + 1) - n = n + l - end - end - end - for i=#o,k+1,-1 do - o[i] = nil - end - return o - end - - local function deinterlaceXX(s,xsize,ysize,bytes,parts,factor) - local output = newoutput(xsize*bytes,ysize) - for pass=1,7 do - local ystart = ystart[pass] - local ystep = ystep[pass] - local xstart = xstart[pass] - local xstep = xstep[pass] - local nx = idiv(xsize + xstep - xstart - 1,xstep) - local ny = idiv(ysize + ystep - ystart - 1,ystep) - if nx > 0 and ny > 0 then - local input - if parts then - local nxx = ceil(nx*parts/8) - input = readbytetable(s,ny*(nxx+1)) - setmetatableindex(input,zero) - decodeall(input,nxx,ny,bytes) - input = expand(input,nx,ny,parts,factor) - else - input = readbytetable(s,ny*(nx*bytes+1)) - setmetatableindex(input,zero) - decodeall(input,nx,ny,bytes) - end - local l = nx*bytes + 1 - for i=ny,1,-1 do - remove(input,(i-1)*l+1) - end - local xstep = xstep * bytes - local xstart = xstart * bytes - local xsize = xsize * bytes - local target = ystart * xsize + xstart + 1 - local ystep = ystep * xsize - local start = 1 - local blobs = bytes - 1 - for j=0,ny-1 do - local target = target + j * ystep - for i=1,nx do - for i=0,blobs do - output[target+i] = input[start] - start= start + 1 - end - target = target + xstep - end - end - end - end - return output - end - - local function deinterlaceYY(s,xsize,ysize,bytes,parts,factor) - local input - if parts then - local nxx = ceil(xsize*parts/8) - input = readbytetable(s,ysize*(nxx+1)) - setmetatableindex(input,zero) - decodeall(input,nxx,ysize,bytes) - input = expand(input,xsize,ysize,parts,factor) - else - input = readbytetable(s,ysize*(xsize*bytes+1)) - setmetatableindex(input,zero) - decodeall(input,xsize,ysize,bytes) - end - local l = xsize*bytes + 1 - local n = 1 - for i=1,ysize do - input[n] = "" - n = n + l - end - return input - end - - local function analyze(colordepth,colorspace,palette,mask) - local bytes, parts, factor - if palette then - if colordepth == 16 then - return 2, false, false - elseif colordepth == 8 then - return 1, false, false - elseif colordepth == 4 then - return 1, 4, false - elseif colordepth == 2 then - return 1, 2, false - elseif colordepth == 1 then - return 1, 1, false - end - elseif colorspace == "DeviceGray" then - if colordepth == 16 then - return mask and 4 or 2, false, false - elseif colordepth == 8 then - return mask and 2 or 1, false, false - elseif colordepth == 4 then - return 1, 4, true - elseif colordepth == 2 then - return 1, 2, true - elseif colordepth == 1 then - return 1, 1, true - end - else - if colordepth == 16 then - return mask and 8 or 6, false, false - elseif colordepth == 8 then - return mask and 4 or 3, false, false - elseif colordepth == 4 then - return 3, 4, true - elseif colordepth == 2 then - return 3, 2, true - elseif colordepth == 1 then - return 3, 1, true - end - end - return false, false, false - end - - local function deinterlace(content,xsize,ysize,colordepth,colorspace,palette,mask) - local bytes, parts, factor = analyze(colordepth,colorspace,palette,mask) - if bytes then - content = zlib.decompress(content) - local s = openstring(content) - local r = deinterlaceXX(s,xsize,ysize,bytes,parts,factor) - return r, parts and 8 or false - end - end - - local function decompose(content,xsize,ysize,colordepth,colorspace,palette,mask) - local bytes, parts, factor = analyze(colordepth,colorspace,palette,mask) - if bytes then - content = zlib.decompress(content) - local s = openstring(content) - local r = deinterlaceYY(s,xsize,ysize,bytes,parts,factor) - return r, parts and 8 or false - end - end - - -- 1 (palette used), 2 (color used), and 4 (alpha channel used) - - -- paeth: - -- - -- p = a + b - c - -- pa = abs(p - a) => a + b - c - a => b - c - -- pb = abs(p - b) => a + b - c - b => a - c - -- pc = abs(p - c) => a + b - c - c => a + b - c - c => a - c + b - c => pa + pb - - local function prepareimage(content,xsize,ysize,depth,colorspace,mask) - local bpp = (depth == 16 and 2 or 1) * ((colorspace == "DeviceRGB" and 3 or 1) + mask) local len = bpp * xsize + 1 - local s = openstring(content) - local t = readbytetable(s,#content) - setmetatableindex(t,zero) - return t, bpp, len - end - - local function filtermask08(xsize,ysize,t,bpp,len,n) - local mask = { } - local l = 0 - local m = len - n - for i=1,ysize do - for j=n+bpp,n+m,bpp do - l = l + 1 ; mask[l] = chars[t[j]] ; t[j] = "" - end - n = n + len - end - return concat(mask) - end - - local function filtermask16(xsize,ysize,t,bpp,len,n) - local mask = { } - local l = 0 - local m = len - n - for i=1,ysize do - for j=n+bpp-1,n+m-1,bpp do - l = l + 1 ; mask[l] = chars[t[j]] ; t[j] = "" - j = j + 1 - l = l + 1 ; mask[l] = chars[t[j]] ; t[j] = "" - end - n = n + len - end - return concat(mask) - end - - local function decodemask08(content,xsize,ysize,depth,colorspace) - local t, bpp, len = prepareimage(content,xsize,ysize,depth,colorspace,1) - local bpp2 = mask and (bpp + bpp) or bpp - local n = 1 - local m = len - 1 - for i=1,ysize do - local filter = t[n] - if filter == 0 then - elseif filter == 1 then - for j=n+bpp2,n+m,bpp do - t[j] = (t[j] + t[j-bpp]) % 256 - end - elseif filter == 2 then - for j=n+bpp,n+m,bpp do - t[j] = (t[j] + t[j-len]) % 256 - end - elseif filter == 3 then - local j = n + bpp - t[j] = (t[j] + idiv(t[j-len],2)) % 256 - for j=n+bpp2,n+m,bpp do - t[j] = (t[j] + idiv(t[j-bpp] + t[j-len],2)) % 256 - end - elseif filter == 4 then - local j = n + bpp - local p = j - len - local b = t[p] - if b < 0 then - b = - b - end - if b > 0 then - t[j] = (t[j] + b) % 256 - end - for j=n+bpp2,n+m,bpp do - local p = j - len - local a = t[j-bpp] - local b = t[p] - local c = t[p-bpp] - local pa = b - c - local pb = a - c - local pc = pa + pb - if pa < 0 then pa = - pa end - if pb < 0 then pb = - pb end - if pc < 0 then pc = - pc end - t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256 - end - end - n = n + len - end - local mask = filtermask08(xsize,ysize,t,bpp,len,1) - return convert(t), mask - end - - local function decodemask16(content,xsize,ysize,depth,colorspace) - local t, bpp, len = prepareimage(content,xsize,ysize,depth,colorspace,1) - local bpp2 = bpp + bpp - local n = 1 - local m = len - 1 - for i=1,ysize do - local filter = t[n] - if filter == 0 then - elseif filter == 1 then - for j=n+bpp2,n+m,bpp do - local k = j - 1 - t[j] = (t[j] + t[j-bpp]) % 256 - t[k] = (t[k] + t[k-bpp]) % 256 - end - elseif filter == 2 then - for j=n+bpp,n+m,bpp do - local k = j - 1 - t[j] = (t[j] + t[j-len]) % 256 - t[k] = (t[k] + t[k-len]) % 256 - end - elseif filter == 3 then - local j = n + bpp - local k = j - 1 - t[j] = (t[j] + idiv(t[j-len],2)) % 256 - t[k] = (t[k] + idiv(t[k-len],2)) % 256 - for j=n+bpp2,n+m,bpp do - local k = j - 1 - t[j] = (t[j] + idiv(t[j-bpp] + t[j-len],2)) % 256 - t[k] = (t[k] + idiv(t[k-bpp] + t[k-len],2)) % 256 - end - elseif filter == 4 then - for i=-1,0 do - local j = n + bpp + i - local p = j - len - local b = t[p] - if b < 0 then - b = - b - end - if b > 0 then - t[j] = (t[j] + b) % 256 - end - for j=n+i+bpp2,n+i+m,bpp do - local p = j - len - local a = t[j-bpp] - local b = t[p] - local c = t[p-bpp] - local pa = b - c - local pb = a - c - local pc = pa + pb - if pa < 0 then pa = - pa end - if pb < 0 then pb = - pb end - if pc < 0 then pc = - pc end - t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256 - end - end - end - n = n + len - end - local mask = filtermask16(xsize,ysize,t,bpp,len,1) - return convert(t), mask - end - - local function full(t,k) local v = "\xFF" t[k] = v return v end - - local function create(content,palette,transparent,xsize,ysize,colordepth,colorspace) - if palette then - -- - local s = openstring(transparent) - local n = #transparent - local r = { } - for i=0,n-1 do - r[i] = readstring(s,1) - end - setmetatableindex(r,full) - -- - local c = zlib.decompress(content) - local s = openstring(c) - -- - local o = { } - local len = ceil(xsize*colordepth/8) + 1 - local m = len - 1 - local u = setmetatableindex(zero) - -- - for i=1,ysize do - local t = readbytetable(s,len) - local k = (i-1) * xsize - local filter = t[1] - if filter == 0 then - elseif filter == 1 then - for j=3,len do - t[j] = (t[j] + t[j-1]) % 256 - end - elseif filter == 2 then - for j=2,len do - t[j] = (t[j] + u[j]) % 256 - end - elseif filter == 3 then - local j = 2 - t[j] = (t[j] + idiv(u[j],2)) % 256 - for j=3,len do - t[j] = (t[j] + idiv(t[j-1] + u[j],2)) % 256 - end - elseif filter == 4 then - local j = 2 - local p = j - len - local b = t[p] - if b < 0 then - b = - b - end - if b > 0 then - t[j] = (t[j] + b) % 256 - end - for j=3,len do - local p = j - len - local a = t[j-1] - local b = t[p] - local c = t[p-1] - local pa = b - c - local pb = a - c - local pc = pa + pb - if pa < 0 then pa = - pa end - if pb < 0 then pb = - pb end - if pc < 0 then pc = - pc end - t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256 - end - end - if colordepth == 8 then - for j=2,len do - local v = t[j] - k = k + 1 ; o[k] = r[v] or "\xFF" - end - elseif colordepth == 4 then - for j=2,len do - local v = t[j] - k = k + 1 ; o[k] = r[band(rshift(v,4),0x0F)] - k = k + 1 ; o[k] = r[band(rshift(v,0),0x0F)] - end - elseif colordepth == 2 then - for j=2,len do - local v = t[j] - k = k + 1 ; o[k] = r[band(rshift(v,6),0x03)] - k = k + 1 ; o[k] = r[band(rshift(v,4),0x03)] - k = k + 1 ; o[k] = r[band(rshift(v,2),0x03)] - k = k + 1 ; o[k] = r[band(rshift(v,0),0x03)] - end - else - for j=2,len do - local v = t[j] - k = k + 1 ; o[k] = r[band(rshift(v,7),0x01)] - k = k + 1 ; o[k] = r[band(rshift(v,6),0x01)] - k = k + 1 ; o[k] = r[band(rshift(v,5),0x01)] - k = k + 1 ; o[k] = r[band(rshift(v,4),0x01)] - k = k + 1 ; o[k] = r[band(rshift(v,3),0x01)] - k = k + 1 ; o[k] = r[band(rshift(v,2),0x01)] - k = k + 1 ; o[k] = r[band(rshift(v,2),0x01)] - k = k + 1 ; o[k] = r[band(rshift(v,1),0x01)] - end - end - u = t - end - return concat(o,"",1,ysize * xsize) - end - end - - local alwaysdecode = false - - directives.register("graphics.png.decode", function(v) - alwaysdecode = v - end) - - function injectors.png(specification) - if specification.error then - return - end - local filename = specification.filename - if not filename then - return - end - local colorspace = specification.colorspace - if not colorspace then - return - end - local interlace = specification.interlace or 0 - if interlace == 1 then - interlace = true - elseif interlace == 0 then - interlace = false - else - report_png("unknown interlacing %i",interlace) - return - end - local tables = specification.tables - if not tables then - return - end - local idat = tables.idat - if not idat then - return - end - local pngfile = io.open(filename,"rb") -- todo: in-mem too - if not pngfile then - return - end - local content = idat(pngfile,true) - tables.idat = false - -- - -- if tables.gama then - -- report_png("ignoring gamma correction") - -- end - -- - local xsize = specification.xsize - local ysize = specification.ysize - local colordepth = specification.colordepth or 8 - local mask = false - local transparent = false - local palette = false - local colors = 1 - if colorspace == 0 then -- gray | image b - colorspace = "DeviceGray" - transparent = true - elseif colorspace == 2 then -- rgb | image c - colorspace = "DeviceRGB" - colors = 3 - transparent = true - elseif colorspace == 3 then -- palette | image c+i - colorspace = "DeviceRGB" - palette = true - transparent = true - elseif colorspace == 4 then -- gray | alpha | image b - colorspace = "DeviceGray" - mask = true - elseif colorspace == 6 then -- rgb | alpha | image c - colorspace = "DeviceRGB" - colors = 3 - mask = true - else - report_png("unknown colorspace %i",colorspace) - return - end - -- - if transparent then - local trns = tables.trns - if trns then - transparent = trns(pngfile,true) - if transparent == "" then - transparent = false - end - tables.trns = false - else - transparent = false - end - end - -- - local decode = alwaysdecode - local major = pdfmajorversion() - local minor = pdfminorversion() - if major > 1 then - -- we're okay - elseif minor < 5 and colordepth == 16 then - report_png("16 bit colordepth not supported in pdf < 1.5") - return - elseif minor < 4 and (mask or transparent) then - report_png("alpha channels not supported in pdf < 1.4") - return - elseif minor < 2 then - decode = true - end - -- - -- todo: compresslevel (or delegate) - -- - if palette then - local plte = tables.plte - if plte then - palette = plte(pngfile,true) - if palette == "" then - palette = false - end - tables.plte = false - else - palette = false - end - end - -- - if interlace then - local r, p = deinterlace(content,xsize,ysize,colordepth,colorspace,palette,mask) - if not r then - return - end - if p then - colordepth = p - end - if mask then - local bpp = (colordepth == 16 and 2 or 1) * ((colorspace == "DeviceRGB" and 3 or 1) + 1) - local len = bpp * xsize -- + 1 - if colordepth == 8 then -- bpp == 1 - mask = filtermask08(xsize,ysize,r,bpp,len,0) - elseif colordepth == 16 then -- bpp == 2 - mask = filtermask16(xsize,ysize,r,bpp,len,0) - else - report_png("mask can't be split from the image") - return - end - end - decode = true - content = convert(r) - content = zlib.compress(content) - elseif mask then - local decoder - if colordepth == 8 then - decoder = decodemask08 - elseif colordepth == 16 then - decoder = decodemask16 - end - if not decoder then - report_png("mask can't be split from the image") - return - end - content = zlib.decompress(content) - content, mask = decoder(content,xsize,ysize,colordepth,colorspace) - content = zlib.compress(content) - decode = false - elseif transparent then - if palette then - mask = create(content,palette,transparent,xsize,ysize,colordepth,colorspace) - else - pallette = false - end - elseif decode then - local r, p = decompose(content,xsize,ysize,colordepth,colorspace,palette) - if not r then - return - end - if p then - colordepth = p - end - content = convert(r) - content = zlib.compress(content) - end - if palette then - palette = pdfarray { - pdfconstant("Indexed"), - pdfconstant("DeviceRGB"), - idiv(#palette,3), - pdfreference(pdfflushstreamobject(palette)), - } - end - pngfile:close() - local xobject = pdfdictionary { - Type = pdfconstant("XObject"), - Subtype = pdfconstant("Image"), - -- BBox = pdfarray { 0, 0, xsize, ysize }, - Width = xsize, - Height = ysize, - BitsPerComponent = colordepth, - Filter = pdfconstant("FlateDecode"), - ColorSpace = palette or pdfconstant(colorspace), - Length = #content, - } + specification.attr - if mask then - local d = pdfdictionary { - Type = pdfconstant("XObject"), - Subtype = pdfconstant("Image"), - Width = xsize, - Height = ysize, - BitsPerComponent = palette and 8 or colordepth, - ColorSpace = pdfconstant("DeviceGray"), - } - xobject.SMask = pdfreference(pdfflushstreamobject(mask,d())) - end - if not decode then - xobject.DecodeParms = pdfdictionary { - Colors = colors, - Columns = xsize, - BitsPerComponent = colordepth, - Predictor = 15, - } - end - if trace then - report_png("%s: width %i, height %i, colordepth: %i, size: %i, palette %l, mask: %l, transparent %l, decode %l",filename,xsize,ysize,colordepth,#content,palette,mask,transparent,decode) - end - return createimage { - bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate - nolength = true, - nobbox = true, - notype = true, - stream = content, - attr = xobject(), - } - end - -end - -do - - local function pack(specification,what) - local t = { } - local n = 0 - local s = specification.colorspace - local d = specification.data - local x = specification.xsize - local y = specification.ysize - if what == "mask" then - d = specification.mask - s = 1 - end - if s == 1 then - for i=1,y do - local r = d[i] - for j=1,x do - n = n + 1 ; t[n] = chars[r[j]] - end - end - elseif s == 2 then - for i=1,y do - local r = d[i] - for j=1,x do - local c = r[j] - n = n + 1 ; t[n] = chars[c[1]] - n = n + 1 ; t[n] = chars[c[2]] - n = n + 1 ; t[n] = chars[c[3]] - end - end - elseif s == 3 then - for i=1,y do - local r = d[i] - for j=1,x do - local c = r[j] - n = n + 1 ; t[n] = chars[c[1]] - n = n + 1 ; t[n] = chars[c[2]] - n = n + 1 ; t[n] = chars[c[3]] - n = n + 1 ; t[n] = chars[c[4]] - end - end - end - return concat(t) - end - - function injectors.bitmap(specification) - local data = specification.data - if not data then - return - end - local xsize = specification.xsize or 0 - local ysize = specification.ysize or 0 - if xsize == 0 or ysize == 0 then - return - end - local colorspace = specification.colorspace or 1 - if colorspace == 1 then - colorspace = "DeviceGray" - elseif colorspace == 2 then - colorspace = "DeviceRGB" - elseif colorspace == 3 then - colorspace = "DeviceCMYK" - end - local colordepth = (specification.colordepth or 2) == 16 or 8 - local content = pack(specification,"data") - local mask = specification.mask - local xobject = pdfdictionary { - Type = pdfconstant("XObject"), - Subtype = pdfconstant("Image"), - BBox = pdfarray { 0, 0, xsize, ysize }, - Width = xsize, - Height = ysize, - BitsPerComponent = colordepth, - ColorSpace = pdfconstant(colorspace), - Length = #content, -- specification.length - } - if mask then - local d = pdfdictionary { - Type = pdfconstant("XObject"), - Subtype = pdfconstant("Image"), - Width = xsize, - Height = ysize, - BitsPerComponent = colordepth, - ColorSpace = pdfconstant("DeviceGray"), - } - xobject.SMask = pdfreference(pdfflushstreamobject(pack(specification,"mask"),d())) - end - return createimage { - bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate - -- nolength = true, - nobbox = true, - notype = true, - stream = content, - attr = xobject(), - } - end - -end diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index 769b54b6c..09a4678a1 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -1208,6 +1208,7 @@ do function lpdf.getcatalog() if checkcatalog() then + catalog.Type = pdfconstant("Catalog") return pdfreference(pdfimmediateobject(tostring(catalog))) end end diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua index 8bd5429cf..ae3edba56 100644 --- a/tex/context/base/mkiv/lxml-tex.lua +++ b/tex/context/base/mkiv/lxml-tex.lua @@ -2460,52 +2460,56 @@ end -- parameters -local function setatt(id,name,value) - local e = getid(id) - if e then - local a = e.at - if a then - a[name] = value - else - e.at = { [name] = value } +do + + local function setatt(id,name,value) + local e = getid(id) + if e then + local a = e.at + if a then + a[name] = value + else + e.at = { [name] = value } + end end end -end -local function setpar(id,name,value) - local e = getid(id) - if e then - local p = e.pa - if p then - p[name] = value - else - e.pa = { [name] = value } + local function setpar(id,name,value) + local e = getid(id) + if e then + local p = e.pa + if p then + p[name] = value + else + e.pa = { [name] = value } + end end end -end -lxml.setatt = setatt -lxml.setpar = setpar + lxml.setatt = setatt + lxml.setpar = setpar -function lxml.setattribute(id,pattern,name,value) - local collected = xmlapplylpath(getid(id),pattern) - if collected then - for i=1,#collected do - setatt(collected[i],name,value) + function lxml.setattribute(id,pattern,name,value) + local collected = xmlapplylpath(getid(id),pattern) + if collected then + for i=1,#collected do + setatt(collected[i],name,value) + end end end -end -function lxml.setparameter(id,pattern,name,value) - local collected = xmlapplylpath(getid(id),pattern) - if collected then - for i=1,#collected do - setpar(collected[i],name,value) + function lxml.setparameter(id,pattern,name,value) + local collected = xmlapplylpath(getid(id),pattern) + if collected then + for i=1,#collected do + setpar(collected[i],name,value) + end end end -end -lxml.setparam = lxml.setparameter + lxml.setparam = lxml.setparameter + +end -- relatively new: @@ -2735,3 +2739,59 @@ function texfinalizers.xml(collected,name,setup) buffers.assign(name,strip(xmltostring(root))) context.xmlprocessbuffer(name,name,setup or (name..":setup")) end + +-- experiment + +do + + local xmltoelement = xml.toelement + local xmlreindex = xml.reindex + + function lxml.replace(root,pattern,whatever) + if type(root) == "string" then + root = lxml.getid(root) + end + local collected = xmlapplylpath(root,pattern) + if collected then + local isstring = type(whatever) == "string" + for c=1,#collected do + local e = collected[c] + local p = e.__p__ + if p then + local d = p.dt + local n = e.ni + local w = isstring and whatever or whatever(e) + if w then + local t = xmltoelement(w,root).dt + if t then + t.__p__ = p + if type(t) == "table" then + local t1 = t[1] + d[n] = t1 + t1.at.type = e.at.type or t1.at.type + for i=2,#t do + n = n + 1 + insert(d,n,t[i]) + end + else + d[n] = t + end + xmlreindex(d) -- probably not needed + end + end + end + end + end + end + + -- function document.mess_around(root) + -- lxml.replace( + -- root, + -- "p[@variant='foo']", + -- function(c) + -- return (string.gsub(tostring(c),"foo","<bar>%1</bar>")) + -- end + -- ) + -- end + +end diff --git a/tex/context/base/mkiv/pack-rul.mkiv b/tex/context/base/mkiv/pack-rul.mkiv index f3ac8f6e8..3cbb731fe 100644 --- a/tex/context/base/mkiv/pack-rul.mkiv +++ b/tex/context/base/mkiv/pack-rul.mkiv @@ -141,6 +141,7 @@ \setupframed [\c!width=\v!fit, \c!height=\v!broad, + %\c!minheight=\zeropoint, %\c!lines=, \c!offset=.25\exheight, % \defaultframeoffset \c!empty=\v!no, @@ -1637,6 +1638,13 @@ \fi \ifconditional\c_framed_has_height \ht\b_framed_normal\d_framed_height + \else + \edef\p_framed_minheight{\framedparameter\c!minheight}% + \ifx\p_framed_minheight\empty \else + \ifdim\ht\b_framed_normal<\p_framed_minheight + \ht\b_framed_normal\p_framed_minheight + \fi + \fi \fi \edef\p_framed_empty{\framedparameter\c!empty}% \ifx\p_framed_empty\v!yes diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi index f36b27474..a27ba5736 100644 --- a/tex/context/base/mkiv/page-lin.mkvi +++ b/tex/context/base/mkiv/page-lin.mkvi @@ -46,6 +46,10 @@ \attribute\linenumberattribute\attributeunsetvalue \to \everyforgetall +\appendtoks + \attribute\linenumberattribute \attributeunsetvalue +\to \everyinsidefloat + \newcount \linenumber % not used \newbox \b_page_lines_scratch \newcount \c_page_lines_reference diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 5315cf23b..9f745ce85 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 338fd01eb..6a170110a 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/trac-deb.lua b/tex/context/base/mkiv/trac-deb.lua index c9a05f238..9f5445a7f 100644 --- a/tex/context/base/mkiv/trac-deb.lua +++ b/tex/context/base/mkiv/trac-deb.lua @@ -347,6 +347,8 @@ directives.register("system.showerror", lmx.overloaderror) -- trace_calls(n) -- end) -- indirect is needed for nilling +-- I'll make this obsolete soon. + local editor = [[scite "-open:%filename%" -goto:%linenumber%]] directives.register("system.editor",function(v) diff --git a/tex/context/base/mkiv/trac-log.lua b/tex/context/base/mkiv/trac-log.lua index 83b81c9b0..206af5668 100644 --- a/tex/context/base/mkiv/trac-log.lua +++ b/tex/context/base/mkiv/trac-log.lua @@ -1028,7 +1028,7 @@ end if tex and tex.error then function logs.texerrormessage(...) -- for the moment we put this function here - tex.error(format(...), { }) + tex.error(format(...)) end else function logs.texerrormessage(...) diff --git a/tex/context/base/mkiv/typo-krn.lua b/tex/context/base/mkiv/typo-krn.lua index 5e4792f62..a099163db 100644 --- a/tex/context/base/mkiv/typo-krn.lua +++ b/tex/context/base/mkiv/typo-krn.lua @@ -129,9 +129,6 @@ local factors = kerns.factors local gluefactor = 4 -- assumes quad = .5 enspace -kerns.keepligature = false -- just for fun (todo: control setting with key/value) -kerns.keeptogether = false -- just for fun (todo: control setting with key/value) - -- red : kept by dynamic feature -- green : kept by static feature -- blue : keep by goodie |