From 9bd28a3039a458b054459fe1ef80161b107b798f Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 29 Nov 2018 20:53:37 +0100 Subject: 2018-11-29 19:54:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-pe.mkii | 1 + tex/context/base/mkiv/anch-pgr.lua | 6 +- tex/context/base/mkiv/anch-pos.lua | 20 +- tex/context/base/mkiv/attr-col.lua | 9 +- tex/context/base/mkiv/back-pdf.lua | 2 +- tex/context/base/mkiv/back-pdf.mkiv | 7 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/cont-run.lua | 3 +- tex/context/base/mkiv/context.mkiv | 3 +- tex/context/base/mkiv/core-env.mkiv | 2 +- tex/context/base/mkiv/font-chk.lua | 4 +- tex/context/base/mkiv/font-dsp.lua | 468 +++++++++++++------- tex/context/base/mkiv/font-imp-quality.lua | 6 +- tex/context/base/mkiv/font-ini.mkvi | 21 +- tex/context/base/mkiv/font-lib.mkvi | 5 +- tex/context/base/mkiv/font-mis.lua | 14 +- tex/context/base/mkiv/font-ocl.lua | 154 ++++--- tex/context/base/mkiv/font-otl.lua | 36 +- tex/context/base/mkiv/font-otr.lua | 4 +- tex/context/base/mkiv/font-oup.lua | 2 +- tex/context/base/mkiv/font-tfm.lua | 54 ++- tex/context/base/mkiv/grph-inc.lua | 118 ++--- tex/context/base/mkiv/l-lpeg.lua | 3 +- tex/context/base/mkiv/l-unicode.lua | 19 +- tex/context/base/mkiv/lpdf-fmt.lua | 5 +- tex/context/base/mkiv/lpdf-fnt.lua | 2 +- tex/context/base/mkiv/lpdf-img.lua | 2 +- tex/context/base/mkiv/lpdf-ini.lua | 178 +++++--- tex/context/base/mkiv/lpdf-nod.lua | 115 ++--- tex/context/base/mkiv/lpdf-pde.lua | 2 +- tex/context/base/mkiv/lpdf-tag.lua | 17 +- tex/context/base/mkiv/lpdf-xmp.lua | 2 +- tex/context/base/mkiv/luat-cod.lua | 11 +- tex/context/base/mkiv/luat-fio.lua | 2 + tex/context/base/mkiv/luat-lib.mkiv | 13 + tex/context/base/mkiv/luat-run.lua | 4 + tex/context/base/mkiv/luat-soc.mkiv | 26 +- tex/context/base/mkiv/math-vfu.lua | 6 +- tex/context/base/mkiv/mult-low.lua | 2 +- tex/context/base/mkiv/node-fin.lua | 231 ++-------- tex/context/base/mkiv/node-ini.lua | 35 +- tex/context/base/mkiv/node-res.lua | 8 - tex/context/base/mkiv/node-shp.lua | 2 +- tex/context/base/mkiv/node-syn.lua | 1 + tex/context/base/mkiv/spac-ali.mkiv | 6 +- tex/context/base/mkiv/spac-hor.mkiv | 5 +- tex/context/base/mkiv/status-files.pdf | Bin 26048 -> 26119 bytes tex/context/base/mkiv/status-lua.pdf | Bin 272222 -> 269735 bytes tex/context/base/mkiv/syst-aux.lua | 44 +- tex/context/base/mkiv/syst-ini.mkiv | 21 +- tex/context/base/mkiv/toks-aux.mkiv | 51 +++ tex/context/base/mkiv/typo-fln.lua | 28 +- tex/context/base/mkiv/typo-lin.lua | 56 ++- tex/context/interface/mkii/keys-pe.xml | 1 + tex/context/interface/mkiv/i-context.pdf | Bin 857326 -> 857449 bytes tex/context/interface/mkiv/i-readme.pdf | Bin 60754 -> 60754 bytes tex/context/modules/mkiv/x-setups-basics.mkiv | 6 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 486 ++++++++++++++++----- tex/generic/context/luatex/luatex-fonts.lua | 2 +- 61 files changed, 1437 insertions(+), 900 deletions(-) create mode 100644 tex/context/base/mkiv/toks-aux.mkiv (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 541ed647d..b82efa527 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.11.18 14:07} +\newcontextversion{2018.11.29 19:46} %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 6da22d53c..a7b296fe6 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.11.18 14:07} +\edef\contextversion{2018.11.29 19:46} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index 5493c3308..d406f3a95 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -1241,6 +1241,7 @@ \setinterfaceconstant{textstyle}{سبک‌متن} \setinterfaceconstant{textwidth}{عرض‌متن} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{عنوان} \setinterfaceconstant{titlecolor}{رنگ‌عنوان} \setinterfaceconstant{titlecommand}{فرمان‌عنوان} diff --git a/tex/context/base/mkiv/anch-pgr.lua b/tex/context/base/mkiv/anch-pgr.lua index e0b9132ff..4014c5222 100644 --- a/tex/context/base/mkiv/anch-pgr.lua +++ b/tex/context/base/mkiv/anch-pgr.lua @@ -231,6 +231,8 @@ interfaces.implement { -- optimized already but we can assume a cycle i.e. prune the last point and then -- even less code .. we could merge some loops but his is more robust +-- use idiv here + local function topairs(t,n) local r = { } for i=1,n do @@ -240,7 +242,7 @@ local function topairs(t,n) return concat(r," ") end -local eps = 65536 / 4 -- 2 +local eps = 65536 / 4 local pps = eps local nps = - pps @@ -743,7 +745,7 @@ local function calculatemultipar(tag) local bp = b.p -- page if trace_shapes then report_shapes("tag %a, left %p, right %p, par %s, page %s, column %s", - left,right,bn or "-",bp or "-",bc or "-") + tag,left,right,bn or "-",bp or "-",bc or "-") end -- if bindex == eindex then diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua index 4767aa259..b8a5f92c2 100644 --- a/tex/context/base/mkiv/anch-pos.lua +++ b/tex/context/base/mkiv/anch-pos.lua @@ -516,19 +516,20 @@ local function b_region(tag) last.x = x ~= 0 and x or nil last.y = y ~= 0 and y or nil last.p = texgetcount("realpageno") - insert(regions,tag) + insert(regions,tag) -- todo: fast stack region = tag end local function e_region(correct) local last = tobesaved[region] local y = getvpos() + local x, y = getpos() if correct then local h = (last.y or 0) - y last.h = h ~= 0 and h or nil end last.y = y ~= 0 and y or nil - remove(regions) + remove(regions) -- todo: fast stack region = regions[#regions] end @@ -544,15 +545,14 @@ local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind end local box = getbox(n) local w, h, d = getwhd(box) - local x, y = getpos() -- hm, makes no sense here as not in shipout tobesaved[tag] = { - -- p = texgetcount("realpageno"), -- we copy them - x = x ~= 0 and x or nil, -- was true - y = y ~= 0 and y or nil, - w = w ~= 0 and w or nil, - h = h ~= 0 and h or nil, - d = d ~= 0 and d or nil, - k = k ~= 0 and k or nil, + -- p = texgetcount("realpageno"), -- we copy them + x = 0, + y = 0, + w = w ~= 0 and w or nil, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, + k = k ~= 0 and k or nil, lo = lo ~= 0 and lo or nil, ro = ro ~= 0 and ro or nil, to = to ~= 0 and to or nil, diff --git a/tex/context/base/mkiv/attr-col.lua b/tex/context/base/mkiv/attr-col.lua index 4e5f59fb1..2d4b65181 100644 --- a/tex/context/base/mkiv/attr-col.lua +++ b/tex/context/base/mkiv/attr-col.lua @@ -114,12 +114,16 @@ local data = colors.data local values = colors.values local registered = colors.registered +local cmykrgbmode = 0 -- only for testing, already defined colors are not affected + local numbers = attributes.numbers local list = attributes.list registerstorage("attributes/colors/values", values, "attributes.colors.values") registerstorage("attributes/colors/registered", registered, "attributes.colors.registered") +directives.register("colors.cmykrgbmode", function(v) cmykrgbmode = tonumber(v) or 0 end) + local f_colors = { rgb = formatters["r:%s:%s:%s"], cmyk = formatters["c:%s:%s:%s:%s"], @@ -148,8 +152,11 @@ end local function cmyktorgb(c,m,y,k) if not c then return 0, 0, 0, 1 + elseif cmykrgbmode == 1 then + local d = 1.0 - k + return 1.0 - min(1.0,c*d+k), 1.0 - min(1.0,m*d+k), 1.0 - min(1.0,y*d+k) else - return 1.0 - min(1.0,c+k), 1.0 - min(1.0,m+k), 1.0 - min(1.0,y+k) + return 1.0 - min(1.0,c +k), 1.0 - min(1.0,m +k), 1.0 - min(1.0,y +k) end end diff --git a/tex/context/base/mkiv/back-pdf.lua b/tex/context/base/mkiv/back-pdf.lua index 27e9cb69c..32c364bba 100644 --- a/tex/context/base/mkiv/back-pdf.lua +++ b/tex/context/base/mkiv/back-pdf.lua @@ -153,7 +153,7 @@ local function pdfstartmirroring() end implement { name = "pdfstartmirroring", actions = pdfstartmirroring } -implement { name = "pdfstopmirroring", actions = pdfstopsomething } +implement { name = "pdfstopmirroring", actions = pdfstartmirroring } -- not: pdfstopsomething if environment.arguments.nocompression then lpdf.setcompression(0,0,true) diff --git a/tex/context/base/mkiv/back-pdf.mkiv b/tex/context/base/mkiv/back-pdf.mkiv index c3cb7657f..6c663bf0f 100644 --- a/tex/context/base/mkiv/back-pdf.mkiv +++ b/tex/context/base/mkiv/back-pdf.mkiv @@ -130,9 +130,10 @@ %D But we still provide: -\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} -\unexpanded\def\maximumpdfcompression {\clf_setpdfcompression\plusnine \plusnine } -\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} +\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} +\unexpanded\def\onlypdfobjectcompression{\clf_setpdfcompression\zerocount\plusthree} +\unexpanded\def\maximumpdfcompression {\clf_setpdfcompression\plusnine \plusnine } +\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} %D These might even become no-ops as we don't need them in \CONTEXT: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index f9bf51f32..7d318e0b9 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.11.18 14:07} +\newcontextversion{2018.11.29 19:46} %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/cont-run.lua b/tex/context/base/mkiv/cont-run.lua index 6d789fe1d..aed2178d8 100644 --- a/tex/context/base/mkiv/cont-run.lua +++ b/tex/context/base/mkiv/cont-run.lua @@ -197,7 +197,8 @@ local function processjob() local suffix = environment.suffix local filename = environment.filename -- hm, not inputfilename ! - if arguments.lmtx then + if arguments.lmtx or not status.obj_ptr then + report("enabling lmtx mode") context.enablelmtx() environment.lmtxmode = true end diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 62aeae740..76fd66b65 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.11.18 14:07} +\edef\contextversion{2018.11.29 19:46} \edef\contextkind {beta} %D For those who want to use this: @@ -155,6 +155,7 @@ % \loadmarkfile{luat-ini} \loadmarkfile{toks-tra} +\loadmarkfile{toks-aux} %loadmarkfile{toks-map} % obsolete, never used \loadmarkfile{attr-ini} diff --git a/tex/context/base/mkiv/core-env.mkiv b/tex/context/base/mkiv/core-env.mkiv index f30f2b5bd..758ee126d 100644 --- a/tex/context/base/mkiv/core-env.mkiv +++ b/tex/context/base/mkiv/core-env.mkiv @@ -813,7 +813,7 @@ %{\edef\m_syst_string_one{\csname\??variables\ifcsname\??variables#1:#2\endcsname#1:#2\else:\fi\endcsname}% {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}% \ifx\m_syst_string_one\empty - \expandafter\firstoffourarguments + \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} diff --git a/tex/context/base/mkiv/font-chk.lua b/tex/context/base/mkiv/font-chk.lua index b1da56747..a79e25e4d 100644 --- a/tex/context/base/mkiv/font-chk.lua +++ b/tex/context/base/mkiv/font-chk.lua @@ -296,9 +296,7 @@ checkers.placeholder = placeholder function checkers.missing(head) local lastfont, characters, found = nil, nil, nil - for n in nextglyph, head do -- faster than while loop so we delay removal - local font = getfont(n) - local char = getchar(n) + for n, font, char in nextglyph, head do -- faster than while loop so we delay removal if font ~= lastfont then characters = fontcharacters[font] lastfont = font diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index 4a0fc71bc..c5fb14d46 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -86,10 +86,11 @@ local streamreader = readers.streamreader local setposition = streamreader.setposition local getposition = streamreader.getposition -local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer -local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer +local readuinteger = streamreader.readcardinal1 +local readushort = streamreader.readcardinal2 +local readulong = streamreader.readcardinal4 local readinteger = streamreader.readinteger1 -local readshort = streamreader.readinteger2 -- 16-bit signed integer +local readshort = streamreader.readinteger2 local readstring = streamreader.readstring local readtag = streamreader.readtag local readbytes = streamreader.readbytes @@ -113,6 +114,7 @@ directives.register("fonts.streamreader",function() setposition = streamreader.setposition getposition = streamreader.getposition + readuinteger = streamreader.readcardinal1 readushort = streamreader.readcardinal2 readulong = streamreader.readcardinal4 readinteger = streamreader.readinteger1 @@ -3070,182 +3072,324 @@ function readers.sbix(f,fontdata,specification) for i=1,nofstrikes do strikes[i] = readulong(f) end - -- if true then - local shapes = { } - local done = 0 - for i=1,nofstrikes do - local strikeoffset = strikes[i] + tableoffset - setposition(f,strikeoffset) - strikes[i] = { - ppem = readushort(f), - ppi = readushort(f), - offset = strikeoffset + local shapes = { } + local done = 0 + for i=1,nofstrikes do + local strikeoffset = strikes[i] + tableoffset + setposition(f,strikeoffset) + strikes[i] = { + ppem = readushort(f), + ppi = readushort(f), + offset = strikeoffset + } + end + -- highest first + sort(strikes,function(a,b) + if b.ppem == a.ppem then + return b.ppi < a.ppi + else + return b.ppem < a.ppem + end + end) + local glyphs = { } + for i=1,nofstrikes do + local strike = strikes[i] + local strikeppem = strike.ppem + local strikeppi = strike.ppi + local strikeoffset = strike.offset + setposition(f,strikeoffset) + for i=0,nofglyphs do + glyphs[i] = readulong(f) + end + local glyphoffset = glyphs[0] + for i=0,nofglyphs-1 do + local nextoffset = glyphs[i+1] + if not shapes[i] then + local datasize = nextoffset - glyphoffset + if datasize > 0 then + setposition(f,strikeoffset + glyphoffset) + shapes[i] = { + x = readshort(f), + y = readshort(f), + tag = readtag(f), -- maybe for tracing + data = readstring(f,datasize-8), + ppem = strikeppem, -- not used, for tracing + ppi = strikeppi, -- not used, for tracing + } + done = done + 1 + if done == nofglyphs then + break + end + end + end + glyphoffset = nextoffset + end + end + fontdata.pngshapes = shapes + end +end + +-- Another bitmap (so not that useful) format. But Luigi found a font that +-- has them , so ... + +do + + local function getmetrics(f) + return { + ascender = readinteger(f), + descender = readinteger(f), + widthmax = readuinteger(f), + caretslopedumerator = readinteger(f), + caretslopedenominator = readinteger(f), + caretoffset = readinteger(f), + minorigin = readinteger(f), + minadvance = readinteger(f), + maxbefore = readinteger(f), + minafter = readinteger(f), + pad1 = readinteger(f), + pad2 = readinteger(f), + } + end + + -- bad names + + local function getbigmetrics(f) + -- bigmetrics, maybe just skip 9 bytes + return { + height = readuinteger(f), + width = readuinteger(f), + horiBearingX = readinteger(f), + horiBearingY = readinteger(f), + horiAdvance = readuinteger(f), + vertBearingX = readinteger(f), + vertBearingY = readinteger(f), + vertAdvance = readuinteger(f), + } + end + + local function getsmallmetrics(f) + -- smallmetrics, maybe just skip 5 bytes + return { + height = readuinteger(f), + width = readuinteger(f), + bearingX = readinteger(f), + bearingY = readinteger(f), + advance = readuinteger(f), + } + end + + function readers.cblc(f,fontdata,specification) + -- should we delay this ? + local ctdttableoffset = gotodatatable(f,fontdata,"cbdt",specification.glyphs) + if not ctdttableoffset then + return + end + local cblctableoffset = gotodatatable(f,fontdata,"cblc",specification.glyphs) + if cblctableoffset then + local majorversion = readushort(f) + local minorversion = readushort(f) + local nofsizetables = readulong(f) + local sizetables = { } + local shapes = { } + local subtables = { } + for i=1,nofsizetables do + sizetables[i] = { + subtables = readulong(f), + indexsize = readulong(f), + nofsubtables = readulong(f), + colorref = readulong(f), + hormetrics = getmetrics(f), + vermetrics = getmetrics(f), + firstindex = readushort(f), + lastindex = readushort(f), + ppemx = readbyte(f), + ppemy = readbyte(f), + bitdepth = readbyte(f), + flags = readbyte(f), } end - -- highest first - sort(strikes,function(a,b) - if b.ppem == a.ppem then - return b.ppi < a.ppi + sort(sizetables,function(a,b) + if b.ppemx == a.ppemx then + return b.bitdepth < a.bitdepth else - return b.ppem < a.ppem + return b.ppemx < a.ppemx end end) - local glyphs = { } - for i=1,nofstrikes do - local strike = strikes[i] - local strikeppem = strike.ppem - local strikeppi = strike.ppi - local strikeoffset = strike.offset - setposition(f,strikeoffset) - for i=0,nofglyphs do - glyphs[i] = readulong(f) + for i=1,nofsizetables do + local s = sizetables[i] + local d = false + for j=s.firstindex,s.lastindex do + if not shapes[j] then + shapes[j] = i + d = true + end end - local glyphoffset = glyphs[0] - for i=0,nofglyphs-1 do - local nextoffset = glyphs[i+1] - if not shapes[i] then - local datasize = nextoffset - glyphoffset - if datasize > 0 then - setposition(f,strikeoffset + glyphoffset) - shapes[i] = { - x = readshort(f), - y = readshort(f), - tag = readtag(f), -- maybe for tracing - data = readstring(f,datasize-8), - ppem = strikeppem, -- not used, for tracing - ppi = strikeppi, -- not used, for tracing - } - done = done + 1 - if done == nofglyphs then - break + if d then + s.used = true + end + end + for i=1,nofsizetables do + local s = sizetables[i] + if s.used then + local offset = s.subtables + setposition(f,cblctableoffset+offset) + for j=1,s.nofsubtables do + local firstindex = readushort(f) + local lastindex = readushort(f) + local tableoffset = readulong(f) + offset + for k=firstindex,lastindex do + if shapes[k] == i then + local s = subtables[tableoffset] + if not s then + s = { + firstindex = firstindex, + lastindex = lastindex, + } + subtables[tableoffset] = s + end + shapes[k] = s end end end - glyphoffset = nextoffset end end - fontdata.sbixshapes = shapes - -- else - -- for i=1,nofstrikes do - -- local strikeoffset = strikes[i] + tableoffset - -- setposition(f,strikeoffset) - -- local glyphs = { } - -- strikes[i] = { - -- ppem = readushort(f), - -- ppi = readushort(f), - -- glyphs = glyphs, - -- } - -- for i=0,nofglyphs do - -- glyphs[i] = readulong(f) - -- end - -- local glyphoffset = glyphs[0] - -- for i=0,nofglyphs-1 do - -- local nextoffset = glyphs[i+1] - -- local datasize = nextoffset - glyphoffset - -- if datasize > 0 then - -- setposition(f,strikeoffset + glyphoffset) - -- glyphs[i] = { - -- x = readshort(f), - -- y = readshort(f), - -- tag = readtag(f), - -- data = readstring(f,datasize-8) - -- } - -- glyphoffset = nextoffset - -- end - -- end - -- end - -- fontdata.sbixshapes = strikes + + -- there is no need to sort in string stream but we have a nicer trace + -- if needed + + for offset, subtable in sortedhash(subtables) do + local tabletype = readushort(f) + subtable.format = readushort(f) + local baseoffset = readulong(f) + ctdttableoffset + local offsets = { } + local metrics = nil + if tabletype == 1 then + -- we have the usual one more to get the size + for i=subtable.firstindex,subtable.lastindex do + offsets[i] = readulong(f) + baseoffset + end + skipbytes(f,4) + elseif tabletype == 2 then + local size = readulong(f) + local done = baseoffset + metrics = getbigmetrics(f) + for i=subtable.firstindex,subtable.lastindex do + offsets[i] = done + done = done + size + end + elseif tabletype == 3 then + -- we have the usual one more to get the size + local n = subtable.lastindex - subtable.firstindex + 2 + for i=subtable.firstindex,subtable.lastindex do + offsets[i] = readushort(f) + baseoffset + end + if math.odd(n) then + skipbytes(f,4) + else + skipbytes(f,2) + end + elseif tabletype == 4 then + for i=1,readulong(f) do + offsets[readushort(f)] = readushort(f) + baseoffset + end + elseif tabletype == 5 then + local size = readulong(f) + local done = baseoffset + metrics = getbigmetrics(f) + local n = readulong(f) + for i=1,n do + offsets[readushort(f)] = done + done = done + size + end + if math.odd(n) then + skipbytes(f,2) + end + else + return -- unsupported format + end + subtable.offsets = offsets + subtable.metrics = metrics + end + + -- we only support a few sensible types ... there are hardly any fonts so + -- why are there so many variants ... not the best spec + + local default = { width = 0, height = 0 } + local glyphs = fontdata.glyphs + + for index, subtable in sortedhash(shapes) do + if type(subtable) == "table" then + local data = nil + local metrics = default + local format = subtable.format + local offset = subtable.offsets[index] + setposition(f,offset) + if format == 17 then + metrics = getsmallmetrics(f) + data = readstring(f,readulong(f)) + elseif format == 18 then + metrics = getbigmetrics(f) + data = readstring(f,readulong(f)) + elseif format == 19 then + metrics = subtable.metrics + data = readstring(f,readulong(f)) + else + -- forget about it + end + local x = metrics.width + local y = metrics.height + shapes[index] = { + -- maybe some metrics + x = x, + y = y, + data = data, + } + -- I'll look into this in more details when needed + -- as we can use the bearings to get better boxes. + local glyph = glyphs[index] + if not glyph.boundingbox then + local width = glyph.width + local height = width * y/x + glyph.boundingbox = { 0, 0, width, height } + end + + else + shapes[index] = { + x = 0, + y = 0, + data = "", + } + end + end + + fontdata.pngshapes = shapes -- we cheat + end + end + + function readers.cbdt(f,fontdata,specification) + -- local tableoffset = gotodatatable(f,fontdata,"ctdt",specification.glyphs) + -- if tableoffset then + -- local majorversion = readushort(f) + -- local minorversion = readushort(f) -- end end -end --- function readers.cblc(f,fontdata,specification) --- local tableoffset = gotodatatable(f,fontdata,"cblc",specification.glyphs) --- if tableoffset then --- end --- end --- --- function readers.cbdt(f,fontdata,specification) --- local tableoffset = gotodatatable(f,fontdata,"ctdt",specification.glyphs) --- if tableoffset then --- --- local function getmetrics(f) --- return { --- ascender = readinteger(f), --- descender = readinteger(f), --- widthmax = readcardinal(f), --- caretslopedumerator = readinteger(f), --- caretslopedenominator = readinteger(f), --- caretoffset = readinteger(f), --- minorigin = readinteger(f), --- minadvance = readinteger(f), --- maxbefore = readinteger(f), --- minafter = readinteger(f), --- pad1 = readinteger(f), --- pad2 = readinteger(f), --- } --- end --- --- local version = readulong(f) --- local nofsizetables = readulong(f) --- local sizetable = { } --- for i=1,nofsizetables do --- sizetable[i] = { --- subtables = readulong(f), --- indexsize = readulong(f), --- nofsubtables = readulong(f), --- colorref = readulong(f), --- hormetrics = getmetrics(f), --- vermetrics = getmetrics(f), --- firstindex = readushort(f), --- lastindex = readushort(f), --- ppemx = readbyte(f), --- ppemy = readbyte(f), --- bitdepth = readbyte(f), --- flags = readbyte(f), --- } --- end --- --- sort(sizetable,function(a,b) --- if b.ppemx == a.ppemx then --- return b.bitdepth < a.bitdepth --- else --- return b.ppemx < a.ppemx --- end --- end) --- --- local shapes = { } --- --- for i=1,nofsizetables do --- local s = sizetables[i] --- for j=firstindex,lastindex do --- if not shapes[j] then --- shapes[j] = { --- i --- } --- end --- end --- end --- --- inspect(shapes) --- --- end --- end + -- function readers.ebdt(f,fontdata,specification) + -- if specification.glyphs then + -- end + -- end --- function readers.ebdt(f,fontdata,specification) --- if specification.glyphs then --- end --- end + -- function readers.ebsc(f,fontdata,specification) + -- if specification.glyphs then + -- end + -- end --- function readers.ebsc(f,fontdata,specification) --- if specification.glyphs then --- end --- end + -- function readers.eblc(f,fontdata,specification) + -- if specification.glyphs then + -- end + -- end --- function readers.eblc(f,fontdata,specification) --- if specification.glyphs then --- end --- end +end -- + AVAR : optional -- + CFF2 : otf outlines diff --git a/tex/context/base/mkiv/font-imp-quality.lua b/tex/context/base/mkiv/font-imp-quality.lua index c0ccfb227..930d036e1 100644 --- a/tex/context/base/mkiv/font-imp-quality.lua +++ b/tex/context/base/mkiv/font-imp-quality.lua @@ -310,12 +310,14 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd) local characters = tfmdata.characters local descriptions = tfmdata.descriptions local properties = tfmdata.properties + local parameters = tfmdata.parameters local resources = tfmdata.resources local rawdata = tfmdata.shared.rawdata local lookuphash = rawdata.lookuphash local lookuptags = resources.lookuptags local script = properties.script local language = properties.language + local units = parameters.units local done, factor, left, right = false, 1, 1, 1 local class = classes[value] if class then @@ -358,7 +360,7 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd) if w == 0 or d == 0 then -- ignored else - local p = lfactor * ((w+d)/d)/100 + local p = lfactor * d/units characters[k].left_protruding = p if trace_protrusion then report_protrusions("lfbd -> %0.3F %C",p,k) @@ -396,7 +398,7 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd) if w == 0 or d == 0 then -- ignored else - local p = rfactor * ((w+d)/d)/100 + local p = rfactor * d/units characters[k].right_protruding = p if trace_protrusion then report_protrusions("rtbd -> %0.3F %C",p,k) diff --git a/tex/context/base/mkiv/font-ini.mkvi b/tex/context/base/mkiv/font-ini.mkvi index e45179906..dd8a5f148 100644 --- a/tex/context/base/mkiv/font-ini.mkvi +++ b/tex/context/base/mkiv/font-ini.mkvi @@ -2757,7 +2757,26 @@ \expandafter\getprivatechar \fi} -% new +%D Some fonts can have color specifiers: +%D +%D \starttyping +%D \definefontfeature[seguiemj-cl][default][colr=yes,ccmp=yes,dist=yes] +%D \definefontsynonym[emoji][seguiemj*seguiemj-cl] +%D +%D \definecolor[emoji-red] [r=.4] +%D \definecolor[emoji-gray][s=1,t=.5,a=1] +%D +%D %definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] % bad +%D \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] % okay +%D +%D \definefontfeature[seguiemj-r][ccmp=yes,dist=yes,colr=emoji-r] +%D +%D \definefont[MyEmojiR][seguiemj*seguiemj-r @ 100pt] +%D +%D \startTEXpage[offset=10pt] +%D \MyEmojiR\resolvedemoji{triangular ruler} +%D \stopTEXpage +%D \stoptyping \unexpanded\def\definefontcolorpalette {\dodoubleargument\font_define_color_palette} diff --git a/tex/context/base/mkiv/font-lib.mkvi b/tex/context/base/mkiv/font-lib.mkvi index 981db9496..f87f2901b 100644 --- a/tex/context/base/mkiv/font-lib.mkvi +++ b/tex/context/base/mkiv/font-lib.mkvi @@ -60,12 +60,11 @@ % tfm -\registerctxluafile{font-tfm}{} - \doifelsefileexists {font-tpk.lua} { \registerctxluafile{font-tpk}{optimize} + \registerctxluafile{font-tfm}{} } { - % nothing + \registerctxluafile{font-tfm}{} } % name database diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua index 66fb19afe..c75b92984 100644 --- a/tex/context/base/mkiv/font-mis.lua +++ b/tex/context/base/mkiv/font-mis.lua @@ -8,20 +8,20 @@ if not modules then modules = { } end modules ['font-mis'] = { fonts = fonts or { } -fonts.helpers = fonts.helpers or { } -local helpers = fonts.helpers +local helpers = fonts.helpers or { } +fonts.helpers = helpers -fonts.handlers = fonts.handlers or { } -local handlers = fonts.handlers +local handlers = fonts.handlers or { } +fonts.handlers = handlers -handlers.otf = handlers.otf or { } -local otf = handlers.otf +local otf = handlers.otf or { } +handlers.otf = otf local readers = otf.readers if readers then - otf.version = otf.version or 3.106 + otf.version = otf.version or 3.107 otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true) function fonts.helpers.getfeatures(name,save) diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua index 866d6dd36..8cb5a12fb 100644 --- a/tex/context/base/mkiv/font-ocl.lua +++ b/tex/context/base/mkiv/font-ocl.lua @@ -63,31 +63,41 @@ end) if context then + -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] -- looks bad + -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] -- looks okay + local colors = attributes.list[attributes.private('color')] or { } local transparencies = attributes.list[attributes.private('transparency')] or { } function otf.registerpalette(name,values) sharedpalettes[name] = values + local color = lpdf.color + local transparency = lpdf.transparency + local register = colors.register for i=1,#values do local v = values[i] - local c = nil - local t = nil - if type(v) == "table" then - c = colors.register(name,"rgb", - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - ) + if v == "textcolor" then + values[i] = false else - c = colors[v] - t = transparencies[v] - end - if c and t then - values[i] = hash[lpdf.color(1,c) .. " " .. lpdf.transparency(t)] - elseif c then - values[i] = hash[lpdf.color(1,c)] - elseif t then - values[i] = hash[lpdf.color(1,t)] + local c = nil + local t = nil + if type(v) == "table" then + c = register(name,"rgb", + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + ) + else + c = colors[v] + t = transparencies[v] + end + if c and t then + values[i] = hash[color(1,c) .. " " .. transparency(t)] + elseif c then + values[i] = hash[color(1,c)] + elseif t then + values[i] = hash[color(1,t)] + end end end end @@ -98,11 +108,13 @@ else -- for generic sharedpalettes[name] = values for i=1,#values do local v = values[i] - values[i] = hash[f_color( - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - )] + if v then + values[i] = hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end end end @@ -217,7 +229,7 @@ end -- -- Here we have no color change in BT .. ET and more q Q pairs but even then acrobat -- -- fails displaying the overlays correctly. Other renderers do it right. -local function initialize(tfmdata,kind,value) -- hm, always value +local function initialize(tfmdata,kind,value) if value then local resources = tfmdata.resources local palettes = resources.colorpalettes @@ -228,8 +240,14 @@ local function initialize(tfmdata,kind,value) -- hm, always value converted = setmetatableindex(convert) resources.converted = converted end - local colorvalues = sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or { } - local classes = #colorvalues + local colorvalues = sharedpalettes[value] + local default = false -- so the text color (bad for icon overloads) + if colorvalues then + default = colorvalues[#colorvalues] + else + colorvalues = converted[palettes[tonumber(value) or 1] or palettes[1]] or { } + end + local classes = #colorvalues if classes == 0 then return end @@ -244,7 +262,6 @@ local function initialize(tfmdata,kind,value) -- hm, always value } -- local getactualtext = otf.getactualtext - local default = colorvalues[#colorvalues] local b, e = getactualtext(tounicode(0xFFFD)) local actualb = { "pdf", "page", b } -- saves tables local actuale = { "pdf", "page", e } -- saves tables @@ -276,6 +293,12 @@ local function initialize(tfmdata,kind,value) -- hm, always value f = true n = n + 1 t[n] = v l = v + else + if f then + n = n + 1 t[n] = pop + end + f = false + l = nil end n = n + 1 t[n] = charcommand[entry.slot] if s > 1 and i < s and goback then @@ -352,7 +375,7 @@ end -- I'll probably make a variant for context as we can do it more efficient there than in -- generic. -local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg +local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg if not tfmdata or not pdfshapes or not kind then return end @@ -553,27 +576,27 @@ fonts.handlers.otf.features.register { -- This can be done differently e.g. with ffi and gm and we can share code anway. Using -- batchmode in gm is not faster and as it accumulates we would need to flush all --- individual shapes. +-- individual shapes. But ... in context lmtx (and maybe the backport) we will use +-- a different and more efficient method anyway. I'm still wondering if I should +-- keep color code in generic. Maybe it should be optional. -local otfsbix = otf.sbix or { } -otf.sbix = otfsbix -otf.sbixenabled = true +local otfpng = otf.png or { } +otf.png = otfpng +otf.pngenabled = true do - -- for now png but also other bitmap formats - - local report_sbix = logs.reporter("fonts","sbix conversion") + local report_png = logs.reporter("fonts","png conversion") local loaddata = io.loaddata local savedata = io.savedata local remove = os.remove local runner = sandbox and sandbox.registerrunner { - name = "otfsbix", + name = "otfpng", program = "gm", - template = "convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log", - -- reporter = report_sbix, + template = "convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", + -- reporter = report_png, } if not runner then @@ -581,29 +604,29 @@ do -- poor mans variant for generic: -- runner = function() - return os.execute("gm convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log") + return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") end end -- Alternatively we can create a single pdf file with -adjoin and then pick up pages from -- that file but creating thousands of small files is no fun either. - function otfsbix.topdf(sbixshapes) + function otfpng.topdf(pngshapes) local pdfshapes = { } - local sbixfile = "temp-otf-sbix-shape.sbix" - local pdffile = "temp-otf-sbix-shape.pdf" + local pngfile = "temp-otf-png-shape.png" + local pdffile = "temp-otf-png-shape.pdf" local nofdone = 0 - local indices = sortedkeys(sbixshapes) -- can be sparse + local indices = sortedkeys(pngshapes) -- can be sparse local nofindices = #indices - report_sbix("processing %i sbix containers",nofindices) + report_png("processing %i png containers",nofindices) statistics.starttiming() for i=1,nofindices do local index = indices[i] - local entry = sbixshapes[index] - local data = entry.data + local entry = pngshapes[index] + local data = entry.data -- or placeholder local x = entry.x local y = entry.y - savedata(sbixfile,data) + savedata(pngfile,data) runner() pdfshapes[index] = { x = x ~= 0 and x or nil, @@ -612,45 +635,44 @@ do } nofdone = nofdone + 1 if nofdone % 100 == 0 then - report_sbix("%i shapes processed",nofdone) + report_png("%i shapes processed",nofdone) end end - report_sbix("processing %i pdf results",nofindices) - remove(sbixfile) + report_png("processing %i pdf results",nofindices) + remove(pngfile) remove(pdffile) statistics.stoptiming() if statistics.elapsedseconds then - report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-") + report_png("png conversion time %s",statistics.elapsedseconds() or "-") end return pdfshapes - -- end end end -- This will change in a future version of context. More direct. -local function initializesbix(tfmdata,kind,value) -- hm, always value - if value and otf.sbixenabled then - local sbix = tfmdata.properties.sbix - local hash = sbix and sbix.hash - local timestamp = sbix and sbix.timestamp +local function initializepng(tfmdata,kind,value) -- hm, always value + if value and otf.pngenabled then + local png = tfmdata.properties.png + local hash = png and png.hash + local timestamp = png and png.timestamp if not hash then return end local pdffile = containers.read(otf.pdfcache,hash) local pdfshapes = pdffile and pdffile.pdfshapes if not pdfshapes or pdffile.timestamp ~= timestamp then - local sbixfile = containers.read(otf.sbixcache,hash) - local sbixshapes = sbixfile and sbixfile.sbixshapes - pdfshapes = sbixshapes and otfsbix.topdf(sbixshapes) or { } + local pngfile = containers.read(otf.pngcache,hash) + local pngshapes = pngfile and pngfile.pngshapes + pdfshapes = pngshapes and otfpng.topdf(pngshapes) or { } containers.write(otf.pdfcache, hash, { pdfshapes = pdfshapes, timestamp = timestamp, }) end -- - pdftovirtual(tfmdata,pdfshapes,"sbix") + pdftovirtual(tfmdata,pdfshapes,"png") end end @@ -658,8 +680,16 @@ fonts.handlers.otf.features.register { name = "sbix", description = "sbix glyphs", manipulators = { - base = initializesbix, - node = initializesbix, + base = initializepng, + node = initializepng, } } +fonts.handlers.otf.features.register { + name = "cblc", + description = "cblc glyphs", + manipulators = { + base = initializepng, + node = initializepng, + } +} diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index 7a8e9b02e..df83dc968 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -52,14 +52,14 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.106 -- beware: also sync font-mis.lua and in mtx-fonts -otf.cache = containers.define("fonts", "otl", otf.version, true) -otf.svgcache = containers.define("fonts", "svg", otf.version, true) -otf.sbixcache = containers.define("fonts", "sbix", otf.version, true) -otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) +otf.version = 3.107 -- beware: also sync font-mis.lua and in mtx-fonts +otf.cache = containers.define("fonts", "otl", otf.version, true) +otf.svgcache = containers.define("fonts", "svg", otf.version, true) +otf.pngcache = containers.define("fonts", "png", otf.version, true) +otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) otf.svgenabled = false -otf.sbixenabled = false +otf.pngenabled = false local otfreaders = otf.readers @@ -152,17 +152,17 @@ function otf.load(filename,sub,instance) report_otf("forced reload of %a due to hard coded flag",filename) reload = true end - if reload then + if reload then report_otf("loading %a, hash %a",filename,hash) -- starttiming(otfreaders,true) data = otfreaders.loadfont(filename,sub or 1,instance) -- we can pass the number instead (if it comes from a name search) if data then -- todo: make this a plugin - local used = checkmemory() - local resources = data.resources - local svgshapes = resources.svgshapes - local sbixshapes = resources.sbixshapes + local used = checkmemory() + local resources = data.resources + local svgshapes = resources.svgshapes + local pngshapes = resources.pngshapes if cleanup == 0 then checkmemory(used,threshold,tracememory) end @@ -186,16 +186,16 @@ function otf.load(filename,sub,instance) checkmemory(used,threshold,tracememory) end end - if sbixshapes then - resources.sbixshapes = nil - if otf.sbixenabled then + if pngshapes then + resources.pngshapes = nil + if otf.pngenabled then local timestamp = os.date() -- work in progress ... a bit boring to do - containers.write(otf.sbixcache,hash, { - sbixshapes = sbixshapes, - timestamp = timestamp, + containers.write(otf.pngcache,hash, { + pngshapes = pngshapes, + timestamp = timestamp, }) - data.properties.sbix = { + data.properties.png = { hash = hash, timestamp = timestamp, } diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index 8ef1295ab..c7ff6b726 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -1008,7 +1008,7 @@ readers["os/2"] = function(f,fontdata) if version >= 1 then windowsmetrics.codepageranges = { readulong(f), readulong(f) } end - if version >= 3 then + if version >= 2 then windowsmetrics.xheight = readshort(f) windowsmetrics.capheight = readshort(f) windowsmetrics.defaultchar = readushort(f) @@ -2447,7 +2447,7 @@ function readers.loadfont(filename,n,instance) mathconstants = fontdata.mathconstants, colorpalettes = fontdata.colorpalettes, svgshapes = fontdata.svgshapes, - sbixshapes = fontdata.sbixshapes, + pngshapes = fontdata.pngshapes, variabledata = fontdata.variabledata, foundtables = fontdata.foundtables, }, diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua index cd44bfef7..e7f483642 100644 --- a/tex/context/base/mkiv/font-oup.lua +++ b/tex/context/base/mkiv/font-oup.lua @@ -740,7 +740,7 @@ local function unifymissing(fontdata) resources.unicodes = nil end -local firstprivate = fonts.privateoffsets.textbase or 0xF0000 +local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 local puafirst = 0xE000 local pualast = 0xF8FF diff --git a/tex/context/base/mkiv/font-tfm.lua b/tex/context/base/mkiv/font-tfm.lua index 12e499216..e757a7b82 100644 --- a/tex/context/base/mkiv/font-tfm.lua +++ b/tex/context/base/mkiv/font-tfm.lua @@ -118,6 +118,15 @@ local depth = { } -- table.setmetatableindex("number") -- -- So "czechdqcheat=yes" is then a valid feature. And yes, it's a cheat. +local loadtfmvf = tfm.readers and tfm.readers.loadtfmvf + +directives.register("fonts.tfm.builtin",function(v) + loadtfmvf = tfm.readers and tfm.readers.loadtfmvf + if v and font.read_tfm then + loadtfmvf = false + end +end) + local function read_from_tfm(specification) local filename = specification.filename local size = specification.size @@ -125,7 +134,12 @@ local function read_from_tfm(specification) if trace_defining then report_defining("loading tfm file %a at size %s",filename,size) end - local tfmdata = font.read_tfm(filename,size) -- not cached, fast enough + local tfmdata + if loadtfmvf then + tfmdata = loadtfmvf(filename,size) + else + tfmdata = font.read_tfm(filename,size) -- not cached, fast enough + end if tfmdata then local features = specification.features and specification.features.normal or { } @@ -133,7 +147,7 @@ local function read_from_tfm(specification) specification.features.normal = features -- If reencode returns a new table, we assume that we're doing something - -- special. An 'auto' reencode pickt up its vector from the pfb file. + -- special. An 'auto' reencode picks up its vector from the pfb file. local newtfmdata = (depth[filename] == 1) and tfm.reencode(tfmdata,specification) if newtfmdata then @@ -234,11 +248,11 @@ local function read_from_tfm(specification) end end -- - shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil + shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil -- -if size < 0 then - size = idiv(65536 * -size,100) -end + if size < 0 then + size = idiv(65536 * -size,100) + end parameters.factor = 1 -- already scaled parameters.size = size parameters.slant = parameters.slant or parameters[1] or 0 @@ -258,6 +272,27 @@ end -- We do nothing as we assume flat tfm files. It would become real messy -- otherwise and I don't have something for testing on my system anyway. -- + elseif loadtfmvf then + -- already loaded + local fonts = tfmdata.fonts + if fonts then + for i=1,#fonts do + local font = fonts[i] + local id = font.id + if not id then + local name = font.name + local size = font.size + if name and size then + local data, id = constructors.readanddefine(name,size) + if id then + font.id = id + font.name = nil + font.size = nil + end + end + end + end + end elseif constructors.resolvevirtualtoo then fonts.loggers.register(tfmdata,file.suffix(filename),specification) -- strange, why here local vfname = findbinfile(specification.name, 'ovf') @@ -285,7 +320,7 @@ end report_defining("virtual font %a exceeds size %s",n,s) fontlist[i] = { id = 0 } else - local t, id = fonts.constructors.readanddefine(n,s) + local t, id = constructors.readanddefine(n,s) fontlist[i] = { id = id } end end @@ -308,6 +343,7 @@ end -- properties.haskerns = true properties.hasligatures = true + properties.hasitalics = true resources.unicodes = { } resources.lookuptags = { } -- @@ -416,7 +452,7 @@ do local vector = false if type(pfbfile) == "string" then - local pfb = fonts.constructors.handlers.pfb + local pfb = constructors.handlers.pfb if pfb and pfb.loadvector then local v, e = pfb.loadvector(pfbfile) if v then @@ -445,7 +481,7 @@ do local originals = tfmdata.characters local indices = { } local parentfont = { "font", 1 } - local private = tfmdata.privateoffset or fonts.constructors.privateoffset + local private = tfmdata.privateoffset or constructors.privateoffset local reported = encdone[tfmfile][encfile] -- create characters table diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua index 909df86bc..3ae54adda 100644 --- a/tex/context/base/mkiv/grph-inc.lua +++ b/tex/context/base/mkiv/grph-inc.lua @@ -65,7 +65,7 @@ local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex local replacetemplate = utilities.templates.replace --- local bpfactor = number.dimenfactors.bp +local bpfactor = number.dimenfactors.bp images = images or { } local images = images @@ -131,8 +131,8 @@ function checkimage(figure) report_inclusion("image %a has bad dimensions (%p,%p), discarding",figure.filename or "?",width,height) return false, "bad dimensions" end - local xres = figure.xres - local yres = figure.yres + -- local xres = figure.xres + -- local yres = figure.yres local changes = false if height > width then if height > maxdimen then @@ -160,14 +160,14 @@ end --- begin of mapping / this will become graphics & code|nodeinjections but not this year -local __img__ = img or setmetatableindex(function() report_inclusion("no img lib present") end) -images.__img__ = img +local __img__ = type(img) == "table" and img or { } +images.__img__ =__img__ -local img_new = img.new -local img_scan = img.scan -local img_copy = img.copy -local img_wrap = img.node -local img_embed = img.immediatewrite +local img_new = __img__.new +local img_scan = __img__.scan +local img_copy = __img__.copy +local img_wrap = __img__.node +local img_embed = __img__.immediatewrite updaters.register("backend.update",function() local img = images.__img__ @@ -1658,7 +1658,7 @@ function checkers.mov(data) nodeinjections.insertmovie { width = width, height = height, - factor = number.dimenfactors.bp, + factor = bpfactor, ["repeat"] = dr["repeat"], controls = dr.controls, preview = dr.preview, @@ -2240,7 +2240,30 @@ end local function wrappedidentify(identify,filename) local wrapup = function() report_inclusion("fatal error reading %a",filename) end local _, result = xpcall(identify,wrapup,filename) - return result or { error = "fatal error" } + 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) @@ -2251,23 +2274,20 @@ local function jpg_checker(data) local inject = lpdf.injectors.jpg local found = false request.scanimage = function(t) - local filename = t.filename - local result = wrappedidentify(identify,filename) - local xsize = result.xsize or 0 - local ysize = result.ysize or 0 + local result = wrappedidentify(identify,t.filename) found = not result.error return { - filename = filename, - width = xsize * 65536, - height = ysize * 65536, - depth = 0, - colordepth = result.colordepth or 0, + filename = result.filename, + width = result.width, + height = result.height, + depth = result.depth, + colordepth = result.colordepth, xres = result.xres, yres = result.yres, - xsize = xsize, - ysize = ysize, - rotation = result.rotation or 0, - colorspace = result.colorspace or 0, + xsize = result.xsize, + ysize = result.ysize, + rotation = result.rotation, + colorspace = result.colorspace, } end request.copyimage = function(t) @@ -2288,23 +2308,20 @@ local function jp2_checker(data) -- idem as jpg local inject = lpdf.injectors.jp2 local found = false request.scanimage = function(t) - local filename = t.filename - local result = wrappedidentify(identify,filename) - local xsize = result.xsize or 0 - local ysize = result.ysize or 0 + local result = wrappedidentify(identify,t.filename) found = not result.error return { - filename = filename, - width = xsize * 65536, - height = ysize * 65536, - depth = 0, - colordepth = result.colordepth or 0, + filename = result.filename, + width = result.width, + height = result.height, + depth = result.depth, + colordepth = result.colordepth, xres = result.xres, yres = result.yres, - xsize = xsize, - ysize = ysize, - rotation = result.rotation or 0, - colorspace = result.colorspace or 0, + xsize = result.xsize, + ysize = result.ysize, + rotation = result.rotation, + colorspace = result.colorspace, } end request.copyimage = function(t) @@ -2325,23 +2342,20 @@ local function png_checker(data) -- same as jpg (for now) local inject = lpdf.injectors.png local found = false request.scanimage = function(t) - local filename = t.filename - local result = wrappedidentify(identify,filename) - local xsize = result.xsize or 0 - local ysize = result.ysize or 0 + local result = wrappedidentify(identify,t.filename) found = not result.error return { - filename = filename, - width = xsize * 65536, - height = ysize * 65536, - depth = 0, - colordepth = result.colordepth or 0, + filename = result.filename, + width = result.width, + height = result.height, + depth = result.depth, + colordepth = result.colordepth, xres = result.xres, yres = result.yres, - xsize = xsize, - ysize = ysize, - rotation = result.rotation or 0, - colorspace = result.colorspace or 0, + xsize = result.xsize, + ysize = result.ysize, + rotation = result.rotation, + colorspace = result.colorspace, tables = result.tables, interlace = result.interlace, filter = result.filter, @@ -2382,7 +2396,7 @@ directives.register("graphics.uselua",function(v) 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") + -- report("%s Lua based PDF, PNG, JPG and JP2 inclusion",v and "enabling" or "disabling") end) -- directives.enable("graphics.pdf.uselua") diff --git a/tex/context/base/mkiv/l-lpeg.lua b/tex/context/base/mkiv/l-lpeg.lua index 589fa2b0b..eb55a55a0 100644 --- a/tex/context/base/mkiv/l-lpeg.lua +++ b/tex/context/base/mkiv/l-lpeg.lua @@ -659,7 +659,8 @@ end -- utf extensies -utf = utf or (unicode and unicode.utf8) or { } +-- 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 diff --git a/tex/context/base/mkiv/l-unicode.lua b/tex/context/base/mkiv/l-unicode.lua index b5f52d312..433736602 100644 --- a/tex/context/base/mkiv/l-unicode.lua +++ b/tex/context/base/mkiv/l-unicode.lua @@ -24,7 +24,14 @@ if not modules then modules = { } end modules ['l-unicode'] = { -- used : byte char gmatch len lower sub upper -- not used : dump find format gfind gsub match rep reverse -utf = utf or (unicode and unicode.utf8) or { } +-- utf = utf or (unicode and unicode.utf8) or { } + +-- not supported: +-- +-- dump, find, format, gfind, gmatch, gsub, lower, match, rep, reverse, upper + +utf = utf or { } +unicode = nil utf.characters = utf.characters or string.utfcharacters utf.values = utf.values or string.utfvalues @@ -65,11 +72,9 @@ local p_utfbom = patterns.utfbom local p_newline = patterns.newline local p_whitespace = patterns.whitespace -if not unicode then - - unicode = { utf = utf } -- for a while - -end +-- if not unicode then +-- unicode = { utf = utf } -- for a while +-- end if not utf.char then @@ -1310,7 +1315,7 @@ if bit32 then local extract = bit32.extract local char = string.char - function unicode.toutf32string(n) + function utf.toutf32string(n) if n <= 0xFF then return char(n) .. diff --git a/tex/context/base/mkiv/lpdf-fmt.lua b/tex/context/base/mkiv/lpdf-fmt.lua index 35c7f46a2..e0ba612c4 100644 --- a/tex/context/base/mkiv/lpdf-fmt.lua +++ b/tex/context/base/mkiv/lpdf-fmt.lua @@ -753,9 +753,10 @@ function codeinjections.setformat(s) majorversion,minorversion) end -- - -- cid sets are always omitted now: + -- cid sets can always omitted now, but those validators still complain so let's + -- for a while keep it (for luigi): -- - -- pdf.setomitcidset(formatspecification.include_cidsets == false and 1 or 0) + lpdf.setomitcidset(formatspecification.include_cidsets == false and 1 or 0) -- -- context.setupcolors { -- not this way -- cmyk = spec.cmyk_colors and variables.yes or variables.no, diff --git a/tex/context/base/mkiv/lpdf-fnt.lua b/tex/context/base/mkiv/lpdf-fnt.lua index b759174a9..1caa2f93c 100644 --- a/tex/context/base/mkiv/lpdf-fnt.lua +++ b/tex/context/base/mkiv/lpdf-fnt.lua @@ -58,7 +58,7 @@ local function finalizefont(v) local n = 0 for i in next, v.indices do local u = indextoslot(id,i) - pdfincludechar(id,u) + -- pdfincludechar(id,u) n = n + 1 end v.n = n diff --git a/tex/context/base/mkiv/lpdf-img.lua b/tex/context/base/mkiv/lpdf-img.lua index 01a995d21..ba4d4ff8e 100644 --- a/tex/context/base/mkiv/lpdf-img.lua +++ b/tex/context/base/mkiv/lpdf-img.lua @@ -759,7 +759,7 @@ t[n] = 0 -- not needed if not idat then return end - local pngfile = io.open(filename,"rb") + local pngfile = io.open(filename,"rb") -- todo: in-mem too if not pngfile then return end diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index a6702cd35..98c121778 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -32,7 +32,7 @@ local context = context -- encoded utf16 string type between <>. We could probably save some bytes by using -- strings between () but then we end up with escaped ()\ too. -local pdf = pdf +pdf = type(pdf) == "table" and pdf or { } local factor = number.dimenfactors.bp local codeinjections = { } @@ -54,42 +54,46 @@ lpdf = lpdf or { } local lpdf = lpdf lpdf.flags = lpdf.flags or { } -- will be filled later -local pdfsetinfo = pdf.setinfo -local pdfsetcatalog = pdf.setcatalog ------ pdfsetnames = pdf.setnames ------ pdfsettrailer = pdf.settrailer -local pdfsettrailerid = pdf.settrailerid ------ pdfsetomitcidset = pdf.setomitcidset - -local pdfsetpageresources = pdf.setpageresources -local pdfsetpageattributes = pdf.setpageattributes -local pdfsetpagesattributes = pdf.setpagesattributes - -local pdfreserveobject = pdf.reserveobj -local pdfimmediateobject = pdf.immediateobj -local pdfdeferredobject = pdf.obj -local pdfreferenceobject = pdf.refobj - -local pdfgetfontname = pdf.getfontname -local pdfgetfontobjnum = pdf.getfontobjnum -local pdfgetxformname = pdf.getxformname -local pdfincludeimage = pdf.includeimage -local pdfincludechar = pdf.includechar -local pdfgetpagereference = pdf.getpageref or pdf.pageref -- tex.pdfpageref is obsolete -local pdfsetfontattributes = pdf.setfontattributes - -local setmajorversion = pdf.setmajorversion -local setminorversion = pdf.setminorversion -local getmajorversion = pdf.getmajorversion -local getminorversion = pdf.getminorversion - -local setcompresslevel = pdf.setcompresslevel -local setobjectcompresslevel = pdf.setobjcompresslevel -local getcompresslevel = pdf.getcompresslevel -local getobjectcompresslevel = pdf.getobjcompresslevel +local pdfsetinfo = pdf.setinfo +local pdfsetcatalog = pdf.setcatalog +----- pdfsetnames = pdf.setnames +----- pdfsettrailer = pdf.settrailer +local pdfsettrailerid = pdf.settrailerid + +local pdfsetpageresources = pdf.setpageresources +local pdfsetpageattributes = pdf.setpageattributes +local pdfsetpagesattributes = pdf.setpagesattributes + +local pdfreserveobject = pdf.reserveobj +local pdfimmediateobject = pdf.immediateobj +local pdfdeferredobject = pdf.obj +local pdfreferenceobject = pdf.refobj + +local pdfgetfontname = pdf.getfontname +local pdfgetfontobjnum = pdf.getfontobjnum +local pdfgetxformname = pdf.getxformname +local pdfincludeimage = pdf.includeimage +local pdfincludechar = pdf.includechar +local pdfgetpagereference = pdf.getpageref or pdf.pageref -- tex.pdfpageref is obsolete +local pdfsetfontattributes = pdf.setfontattributes + +local setmajorversion = pdf.setmajorversion +local setminorversion = pdf.setminorversion +local getmajorversion = pdf.getmajorversion +local getminorversion = pdf.getminorversion + +local setcompresslevel = pdf.setcompresslevel +local setobjectcompresslevel = pdf.setobjcompresslevel +local getcompresslevel = pdf.getcompresslevel +local getobjectcompresslevel = pdf.getobjcompresslevel + +local setsuppressoptionalinfo = pdf.setsuppressoptionalinfo +local setomitcidset = pdf.setomitcidset local function pdfdisablecommand(command) - pdf[command] = function() report_blocked("'pdf.%s' is not supported",command) end + pdf[command] = function() +-- report_blocked("'pdf.%s' is not supported",command) + end end pdfdisablecommand("setinfo") @@ -108,33 +112,39 @@ pdf.disablecommand = pdfdisablecommand updaters.register("backend.update.lpdf",function() - pdfsetinfo = pdf.setinfo - pdfsetcatalog = pdf.setcatalog - pdfsettrailerid = pdf.settrailerid + pdfsetinfo = pdf.setinfo + pdfsetcatalog = pdf.setcatalog + pdfsettrailerid = pdf.settrailerid + + pdfreserveobject = pdf.reserveobj + pdfimmediateobject = pdf.immediateobj + pdfdeferredobject = pdf.obj + pdfreferenceobject = pdf.refobj + pdfsetfontattributes = pdf.setfontattributes - pdfreserveobject = pdf.reserveobj - pdfimmediateobject = pdf.immediateobj - pdfdeferredobject = pdf.obj - pdfreferenceobject = pdf.refobj - pdfsetfontattributes = pdf.setfontattributes + pdfgetfontname = pdf.getfontname + pdfgetfontobjnum = pdf.getfontobjnum + pdfgetxformname = pdf.getxformname + pdfincludeimage = pdf.includeimage + pdfincludechar = pdf.includechar + pdfgetpagereference = pdf.getpageref - pdfgetfontname = pdf.getfontname - pdfgetfontobjnum = pdf.getfontobjnum - pdfgetxformname = pdf.getxformname - pdfincludeimage = pdf.includeimage - pdfincludechar = pdf.includechar - pdfgetpagereference = pdf.getpageref + setmajorversion = pdf.setmajorversion + setminorversion = pdf.setminorversion + getmajorversion = pdf.getmajorversion + getminorversion = pdf.getminorversion + setcompresslevel = pdf.setcompresslevel + setobjectcompresslevel = pdf.setobjcompresslevel + getcompresslevel = pdf.getcompresslevel + getobjectcompresslevel = pdf.getobjcompresslevel - setmajorversion = pdf.setmajorversion - setminorversion = pdf.setminorversion - getmajorversion = pdf.getmajorversion - getminorversion = pdf.getminorversion + pdfsetpageresources = pdf.setpageresources + pdfsetpageattributes = pdf.setpageattributes + pdfsetpagesattributes = pdf.setpagesattributes - setcompresslevel = pdf.setcompresslevel - setobjectcompresslevel = pdf.setobjcompresslevel - getcompresslevel = pdf.getcompresslevel - getobjectcompresslevel = pdf.getobjcompresslevel + setsuppressoptionalinfo = pdf.setsuppressoptionalinfo + setomitcidset = pdf.setomitcidset pdfdisablecommand("setinfo") pdfdisablecommand("setcatalog") @@ -176,21 +186,55 @@ function lpdf.includechar (f,c) pdfincludechar(f,c) end function lpdf.includecharlist(f,c) pdfincludechar(f,c) end -- can be disabled local frozen = false +local clevel = 3 +local olevel = 1 function lpdf.setcompression(level,objectlevel,freeze) if not frozen then - setcompresslevel(level or 3) - setobjectcompresslevel(objectlevel or level or 3) + if setcompresslevel then + setcompresslevel(level or 3) + setobjectcompresslevel(objectlevel or level or 3) + else + clevel = level + olevel = objectlevel + end frozen = freeze end end function lpdf.getcompression() - return getcompresslevel(), getobjectcompresslevel() + if getcompresslevel then + return getcompresslevel(), getobjectcompresslevel() + else + return clevel, olevel + end end -function lpdf.compresslevel () return getcompresslevel () end -function lpdf.objectcompresslevel() return getobjectcompresslevel() end +function lpdf.compresslevel() + if getcompresslevel then + return getcompresslevel() + else + return clevel + end +end + +function lpdf.objectcompresslevel() + if getobjectcompresslevel then + return getobjectcompresslevel() + else + return olevel + end +end + +function lpdf.setsuppressoptionalinfo(n) + if setsuppressoptionalinfo then + setsuppressoptionalinfo(n) -- todo + end +end + +function lpdf.setomitcidset(v) + return pdfsetomitcidset(v) +end do @@ -1653,19 +1697,21 @@ do function lpdf.procset(dict) if not a_procset then - a_procset = pdfreference(pdfimmediateobject(pdfarray { + a_procset = pdfarray { pdfconstant("PDF"), pdfconstant("Text"), pdfconstant("ImageB"), pdfconstant("ImageC"), pdfconstant("ImageI"), - })) + } + a_procset = pdfreference(pdfimmediateobject(tostring(a_procset))) end if dict then if not d_procset then - d_procset = pdfreference(pdfimmediateobject(pdfdictionary { + d_procset = pdfdictionary { ProcSet = a_procset - })) + } + d_procset = pdfreference(pdfimmediateobject(tostring(d_procset))) end return d_procset else diff --git a/tex/context/base/mkiv/lpdf-nod.lua b/tex/context/base/mkiv/lpdf-nod.lua index 29c3765be..289567c5d 100644 --- a/tex/context/base/mkiv/lpdf-nod.lua +++ b/tex/context/base/mkiv/lpdf-nod.lua @@ -12,12 +12,9 @@ local formatters = string.formatters local nodecodes = nodes.nodecodes local whatsit_code = nodecodes.whatsit - local whatsitcodes = nodes.whatsitcodes -local pdfliteralcode = whatsitcodes.pdfliteral -local pdfsavecode = whatsitcodes.pdfsave -local pdfrestorecode = whatsitcodes.pdfrestore -local pdfsetmatrixcode = whatsitcodes.pdfsetmatrix +local latelua_code = whatsitcodes.latelua +local literal_code = whatsitcodes.literal local nodeinjections = backends.nodeinjections @@ -39,26 +36,66 @@ local pageliteral = literalvalues.page local directliteral = literalvalues.direct local rawliteral = literalvalues.raw -local pdforiginliteral = register(new_node(whatsit_code, pdfliteralcode)) setfield(pdforiginliteral,"mode",originliteral) -local pdfpageliteral = register(new_node(whatsit_code, pdfliteralcode)) setfield(pdfpageliteral, "mode",pageliteral) -local pdfdirectliteral = register(new_node(whatsit_code, pdfliteralcode)) setfield(pdfdirectliteral,"mode",directliteral) -local pdfrawliteral = register(new_node(whatsit_code, pdfliteralcode)) setfield(pdfrawliteral, "mode",rawliteral) +local literalcode = whatsitcodes.literal +local savecode = whatsitcodes.save +local restorecode = whatsitcodes.restore +local setmatrixcode = whatsitcodes.setmatrix -local pdfsave = register(new_node(whatsit_code, pdfsavecode)) -local pdfrestore = register(new_node(whatsit_code, pdfrestorecode)) -local pdfsetmatrix = register(new_node(whatsit_code, pdfsetmatrixcode)) +local s_matrix_0 = "1 0 0 1" +local f_matrix_2 = formatters["%.6F 0 0 %.6F"] +local f_matrix_4 = formatters["%.6F %.6F %.6F %.6F"] -local variables = interfaces.variables +directives.register("pdf.stripzeros",function() + f_matrix_2 = formatters["%.6N 0 0 %.6N"] + f_matrix_4 = formatters["%.6N %.6N %.6N %.6N"] +end) + +local function tomatrix(rx,sx,sy,ry,tx,ty) -- todo: tx ty + if type(rx) == "string" then + return rx + else + if not rx then + rx = 1 + elseif rx == 0 then + rx = 0.0001 + end + if not ry then + ry = 1 + elseif ry == 0 then + ry = 0.0001 + end + if not sx then + sx = 0 + end + if not sy then + sy = 0 + end + if sx == 0 and sy == 0 then + if rx == 1 and ry == 1 then + return s_matrix_0 + else + return f_matrix_2(rx,ry) + end + else + return f_matrix_4(rx,sx,sy,ry) + end + end +end + +local pdforiginliteral = register(new_node(whatsit_code, literalcode)) setfield(pdforiginliteral,"mode",originliteral) +local pdfpageliteral = register(new_node(whatsit_code, literalcode)) setfield(pdfpageliteral, "mode",pageliteral) +local pdfdirectliteral = register(new_node(whatsit_code, literalcode)) setfield(pdfdirectliteral,"mode",directliteral) +local pdfrawliteral = register(new_node(whatsit_code, literalcode)) setfield(pdfrawliteral, "mode",rawliteral) + +local pdfsave = register(new_node(whatsit_code, savecode)) +local pdfrestore = register(new_node(whatsit_code, restorecode)) +local pdfsetmatrix = register(new_node(whatsit_code, setmatrixcode)) function nodepool.pdforiginliteral(str) local t = copy_node(pdforiginliteral) setdata(t,str) return t end function nodepool.pdfpageliteral (str) local t = copy_node(pdfpageliteral ) setdata(t,str) return t end function nodepool.pdfdirectliteral(str) local t = copy_node(pdfdirectliteral) setdata(t,str) return t end function nodepool.pdfrawliteral (str) local t = copy_node(pdfrawliteral ) setdata(t,str) return t end --- best is to use a specific one: origin | page | direct | raw - --- nodepool.pdfliteral = nodepool.pdfpageliteral -- or is origin the default ? - local pdfliterals = { -- by number [originliteral] = pdforiginliteral, @@ -92,49 +129,15 @@ function nodepool.pdfrestore() return copy_node(pdfrestore) end -local s_matrix_0 = "1 0 0 1" -local f_matrix_2 = formatters["%.6F 0 0 %.6F"] -local f_matrix_4 = formatters["%.6F %.6F %.6F %.6F"] - -directives.register("pdf.stripzeros",function() - f_matrix_2 = formatters["%.6N 0 0 %.6N"] - f_matrix_4 = formatters["%.6N %.6N %.6N %.6N"] -end) - -function nodepool.pdfsetmatrix(rx,sx,sy,ry,tx,ty) -- todo: tx ty +function nodepool.pdfsetmatrix(rx,sx,sy,ry,tx,ty) local t = copy_node(pdfsetmatrix) - if type(rx) == "string" then - setdata(t,rx) - else - if not rx then - rx = 1 - elseif rx == 0 then - rx = 0.0001 - end - if not ry then - ry = 1 - elseif ry == 0 then - ry = 0.0001 - end - if not sx then - sx = 0 - end - if not sy then - sy = 0 - end - if sx == 0 and sy == 0 then - if rx == 1 and ry == 1 then - setdata(t,s_matrix_0) - else - setdata(t,f_matrix_2(rx,ry)) - end - else - setdata(t,f_matrix_4(rx,sx,sy,ry)) - end - end + setdata(t,tomatrix(rx,sx,sy,ry,tx,ty)) return t end + +-- best is to use a specific one: origin | page | direct | raw + nodeinjections.save = nodepool.pdfsave nodeinjections.restore = nodepool.pdfrestore nodeinjections.transform = nodepool.pdfsetmatrix diff --git a/tex/context/base/mkiv/lpdf-pde.lua b/tex/context/base/mkiv/lpdf-pde.lua index 907db0b13..8d8d8f280 100644 --- a/tex/context/base/mkiv/lpdf-pde.lua +++ b/tex/context/base/mkiv/lpdf-pde.lua @@ -1122,7 +1122,7 @@ if img then do notype = true, stream = content, -- todo: no compress, pass directly also length, filter etc attr = xobject(), - -- type = images.types.stream, + kind = images.types.stream, } end end diff --git a/tex/context/base/mkiv/lpdf-tag.lua b/tex/context/base/mkiv/lpdf-tag.lua index d57da4ccd..70a97c9d0 100644 --- a/tex/context/base/mkiv/lpdf-tag.lua +++ b/tex/context/base/mkiv/lpdf-tag.lua @@ -75,9 +75,9 @@ local structure_kids -- delayed local structure_ref -- delayed local parent_ref -- delayed local root -- delayed +local names -- delayed local tree = { } local elements = { } -local names = false -- delayed local structurestags = structures.tags local taglist = structurestags.taglist @@ -111,7 +111,7 @@ local usedmapping = { } -- end local function finishstructure() - if root and names and #structure_kids > 0 then + if root and #structure_kids > 0 then local nums, n = pdfarray(), 0 for i=1,#tree do n = n + 1 ; nums[n] = i - 1 @@ -257,14 +257,10 @@ local function makeelement(fulltag,parent) AF = af, } local s = pdfreference(pdfflushobject(d)) - if id then - if names then - local size = #names - names[size+1] = id - names[size+2] = s - else - names= { id, s } - end + if id and names then + local size = #names + names[size+1] = id + names[size+2] = s end local kids = parent.kids kids[#kids+1] = s @@ -338,6 +334,7 @@ function nodeinjections.addtags(head) structure_ref = pdfreserveobject() parent_ref = pdfreserveobject() root = { pref = pdfreference(structure_ref), kids = structure_kids } + names = pdfarray() end local function collectranges(head,list) diff --git a/tex/context/base/mkiv/lpdf-xmp.lua b/tex/context/base/mkiv/lpdf-xmp.lua index 3693df2a8..43437962a 100644 --- a/tex/context/base/mkiv/lpdf-xmp.lua +++ b/tex/context/base/mkiv/lpdf-xmp.lua @@ -90,7 +90,7 @@ local mapping = { ["CaptionWriter"] = { "metadata", "rdf:Description/photoshop:CaptionWriter" }, } -pdf.setsuppressoptionalinfo( +lpdf.setsuppressoptionalinfo ( 0 -- + 1 -- pdfnofullbanner + 2 -- pdfnofilename diff --git a/tex/context/base/mkiv/luat-cod.lua b/tex/context/base/mkiv/luat-cod.lua index 790f741c1..1a20908bd 100644 --- a/tex/context/base/mkiv/luat-cod.lua +++ b/tex/context/base/mkiv/luat-cod.lua @@ -151,7 +151,7 @@ end environment.luatexengine = LUATEXENGINE environment.luatexversion = LUATEXVERSION -environment.luatexfuncitonality = LUATEXFUNCTIONALITY +environment.luatexfunctionality = LUATEXFUNCTIONALITY environment.jitsupported = JITSUPPORTED environment.initex = INITEXMODE environment.initexmode = INITEXMODE @@ -254,6 +254,15 @@ local function open_read_file(name) } end +local function find_data_file(name) + return source_file(name) +end + +local open_data_file = open_read_file + callback.register('find_read_file' , find_read_file ) callback.register('open_read_file' , open_read_file ) callback.register('find_write_file', find_write_file) + +callback.register('find_data_file' , find_data_file ) +callback.register('open_data_file' , open_data_file ) diff --git a/tex/context/base/mkiv/luat-fio.lua b/tex/context/base/mkiv/luat-fio.lua index 1a9ebe40b..2996ae66a 100644 --- a/tex/context/base/mkiv/luat-fio.lua +++ b/tex/context/base/mkiv/luat-fio.lua @@ -78,6 +78,8 @@ if not resolvers.initialized() then register('open_read_file' , function( name) return opentexfile(name) end, true) register('find_data_file' , function(name) return findbinfile(name,"tex") end, true) + register('open_data_file' , function(name) return opentexfile(name) end, true) + register('find_enc_file' , function(name) return findbinfile(name,"enc") end, true) register('find_font_file' , function(name) return findbinfile(name,"tfm") end, true) -- register('find_format_file' , function(name) return findbinfile(name,"fmt") end, true) diff --git a/tex/context/base/mkiv/luat-lib.mkiv b/tex/context/base/mkiv/luat-lib.mkiv index 320d68920..d5f6099ca 100644 --- a/tex/context/base/mkiv/luat-lib.mkiv +++ b/tex/context/base/mkiv/luat-lib.mkiv @@ -41,6 +41,19 @@ \registerctxluafile{util-sbx}{} % needs tracker and templates +\registerctxluafile{util-soc-imp-reset} {} +\registerctxluafile{util-soc-imp-socket} {} +%registerctxluafile{util-soc-imp-copas} {} +\registerctxluafile{util-soc-imp-ltn12} {} +%registerctxluafile{util-soc-imp-mbox} {} +\registerctxluafile{util-soc-imp-mime} {} +\registerctxluafile{util-soc-imp-url} {} +\registerctxluafile{util-soc-imp-headers}{} +\registerctxluafile{util-soc-imp-http} {} +\registerctxluafile{util-soc-imp-tp} {} +%registerctxluafile{util-soc-imp-ftp} {} +%registerctxluafile{util-soc-imp-smtp} {} + \registerctxluafile{data-ini}{} \registerctxluafile{data-exp}{} \registerctxluafile{data-env}{} diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua index 4172201c2..5d7026eb7 100644 --- a/tex/context/base/mkiv/luat-run.lua +++ b/tex/context/base/mkiv/luat-run.lua @@ -136,6 +136,8 @@ function luatex.wrapup(action) appendaction(wrapupactions,"user",action) end +appendaction(wrapupactions,"system",synctex.wrapup) + -- this can be done later callbacks.register('start_run', start_run, "actions performed at the beginning of a run") @@ -155,6 +157,8 @@ callbacks.register('process_output_buffer', false, "actions perf callbacks.register("pre_dump", pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump +-- finish_synctex might go away (move to wrapup_run) + callbacks.register("finish_synctex", wrapup_synctex, "rename temporary synctex file") callbacks.register('wrapup_run', wrapup_run, "actions performed after closing files") diff --git a/tex/context/base/mkiv/luat-soc.mkiv b/tex/context/base/mkiv/luat-soc.mkiv index e17ff22d3..b2ce70483 100644 --- a/tex/context/base/mkiv/luat-soc.mkiv +++ b/tex/context/base/mkiv/luat-soc.mkiv @@ -35,18 +35,18 @@ %D Currently we preload the related \LUA\ code in \LUATEX, but that might change at %D some point. We're prepared for that. -\registerctxluafile{util-soc-imp-reset} {} - -\registerctxluafile{util-soc-imp-socket} {} -%registerctxluafile{util-soc-imp-copas} {} -\registerctxluafile{util-soc-imp-ltn12} {} -%registerctxluafile{util-soc-imp-mbox} {} -\registerctxluafile{util-soc-imp-mime} {} -\registerctxluafile{util-soc-imp-url} {} -\registerctxluafile{util-soc-imp-headers}{} -\registerctxluafile{util-soc-imp-http} {} -\registerctxluafile{util-soc-imp-tp} {} -%registerctxluafile{util-soc-imp-ftp} {} -%registerctxluafile{util-soc-imp-smtp} {} +% \registerctxluafile{util-soc-imp-reset} {} +% +% \registerctxluafile{util-soc-imp-socket} {} +% % registerctxluafile{util-soc-imp-copas} {} +% \registerctxluafile{util-soc-imp-ltn12} {} +% % registerctxluafile{util-soc-imp-mbox} {} +% \registerctxluafile{util-soc-imp-mime} {} +% \registerctxluafile{util-soc-imp-url} {} +% \registerctxluafile{util-soc-imp-headers}{} +% \registerctxluafile{util-soc-imp-http} {} +% \registerctxluafile{util-soc-imp-tp} {} +% % registerctxluafile{util-soc-imp-ftp} {} +% % registerctxluafile{util-soc-imp-smtp} {} \endinput diff --git a/tex/context/base/mkiv/math-vfu.lua b/tex/context/base/mkiv/math-vfu.lua index 95f33285e..f19e9d61b 100644 --- a/tex/context/base/mkiv/math-vfu.lua +++ b/tex/context/base/mkiv/math-vfu.lua @@ -160,9 +160,9 @@ local function make(main,characters,id,size,n,m) local dnrule = 0xFF400 + m local xu = main.parameters.x_height + 0.3*size local xd = 0.3*size - local w = c.width - local h = c.height - local d = c.depth + local w = c.width or 0 + local h = c.height or 0 + local d = c.depth or 0 local thickness = h - d local rulewidth = step*size -- we could use an overlap local slot = { "slot", id, old } diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index 1630429b7..13ab1c000 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -348,7 +348,7 @@ return { "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", -- - "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", + "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", -- "modulonumber", "dividenumber", -- diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index ff7ac7598..b8fe389c0 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -38,6 +38,17 @@ local nodecodes = nodes.nodecodes local whatcodes = nodes.whatcodes local rulecodes = nodes.rulecodes +-- local normal_rule_code = rulecodes.normal +local box_rule_code = rulecodes.box +local image_rule_code = rulecodes.image +local empty_rule_code = rulecodes.empty +-- local user_rule_code = rulecodes.user +-- local over_rule_code = rulecodes.over +-- local under_rule_code = rulecodes.under +-- local fraction_rule_code = rulecodes.fraction +-- local radical_rule_code = rulecodes.radical +-- local outline_rule_code = rulecodes.outline + local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc local glue_code = nodecodes.glue @@ -167,103 +178,6 @@ end -- we need to deal with literals too (reset as well as oval) --- local function process(attribute,head,inheritance,default) -- one attribute --- local stack = head --- local check = false --- local leader = nil --- while stack do --- local id = getid(stack) --- if id == glyph_code or id == disc_code then --- check = true -- disc no longer needed as we flatten replace --- elseif id == glue_code then --- leader = getleader(stack) --- if leader then --- check = true --- end --- elseif id == hlist_code or id == vlist_code then --- local content = getlist(stack) --- if content then --- -- begin nested -- --- local list --- if nstrigger and getattr(stack,nstrigger) then --- local outer = getattr(stack,attribute) --- if outer ~= inheritance then --- list = process(attribute,content,inheritance,outer) --- else --- list = process(attribute,content,inheritance,default) --- end --- else --- list = process(attribute,content,inheritance,default) --- end --- if content ~= list then --- setlist(stack,list) --- end --- -- end nested -- --- end --- elseif id == rule_code then --- check = getwidth(stack) ~= 0 --- end --- -- much faster this way than using a check() and nested() function --- if check then --- local c = getattr(stack,attribute) --- if c then --- if default and c == inheritance then --- if current ~= default then --- head = insert_node_before(head,stack,copy_node(nsdata[default])) --- current = default --- end --- elseif current ~= c then --- head = insert_node_before(head,stack,copy_node(nsdata[c])) --- current = c --- end --- if leader then --- local savedcurrent = current --- local ci = getid(leader) --- if ci == hlist_code or ci == vlist_code then --- -- else we reset inside a box unneeded, okay, the downside is --- -- that we trigger color in each repeated box, so there is room --- -- for improvement here --- current = 0 --- end --- -- begin nested -- --- local list --- if nstrigger and getattr(stack,nstrigger) then --- local outer = getattr(stack,attribute) --- if outer ~= inheritance then --- list = process(attribute,leader,inheritance,outer) --- else --- list = process(attribute,leader,inheritance,default) --- end --- else --- list = process(attribute,leader,inheritance,default) --- end --- if leader ~= list then --- setleader(stack,list) --- end --- -- end nested -- --- current = savedcurrent --- leader = false --- end --- elseif default and inheritance then --- if current ~= default then --- head = insert_node_before(head,stack,copy_node(nsdata[default])) --- current = default --- end --- elseif current > 0 then --- head = insert_node_before(head,stack,copy_node(nsnone)) --- current = 0 --- end --- check = false --- end --- stack = getnext(stack) --- end --- return head --- end --- --- states.process = function(namespace,attribute,head,default) --- return process(attribute,head,default) --- end - local function process(attribute,head,inheritance,default) -- one attribute local check = false local leader = nil @@ -296,9 +210,8 @@ local function process(attribute,head,inheritance,default) -- one attribute -- end nested -- end elseif id == rule_code then --- check = getwidth(stack) ~= 0 -local wd, ht, dp = getwhd(stack) -check = wd ~= 0 or (ht+dp) ~= 0 + local wd, ht, dp = getwhd(stack) + check = wd ~= 0 or (ht+dp) ~= 0 end -- much faster this way than using a check() and nested() function if check then @@ -366,106 +279,10 @@ end -- state changes while the main state stays the same (like two glyphs following -- each other with the same color but different color spaces e.g. \showcolor) --- local function selective(attribute,head,inheritance,default) -- two attributes --- local stack = head --- local check = false --- local leader = nil --- while stack do --- local id = getid(stack) --- if id == glyph_code or id == disc_code then --- check = true -- disc no longer needed as we flatten replace --- elseif id == glue_code then --- leader = getleader(stack) --- if leader then --- check = true --- end --- elseif id == hlist_code or id == vlist_code then --- local content = getlist(stack) --- if content then --- -- begin nested --- local list --- if nstrigger and getattr(stack,nstrigger) then --- local outer = getattr(stack,attribute) --- if outer ~= inheritance then --- list = selective(attribute,content,inheritance,outer) --- else --- list = selective(attribute,content,inheritance,default) --- end --- else --- list = selective(attribute,content,inheritance,default) --- end --- if content ~= list then --- setlist(stack,list) --- end --- -- end nested --- end --- elseif id == rule_code then --- check = getwidth(stack) ~= 0 --- end --- --- if check then --- local c = getattr(stack,attribute) --- if c then --- if default and c == inheritance then --- if current ~= default then --- local data = nsdata[default] --- head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector])) --- current = default --- end --- else --- local s = getattr(stack,nsselector) --- -- local s = nsforced or getattr(stack,nsselector) --- if current ~= c or current_selector ~= s then --- local data = nsdata[c] --- head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector])) --- current = c --- current_selector = s --- end --- end --- if leader then --- -- begin nested --- local list --- if nstrigger and getattr(stack,nstrigger) then --- local outer = getattr(stack,attribute) --- if outer ~= inheritance then --- list = selective(attribute,leader,inheritance,outer) --- else --- list = selective(attribute,leader,inheritance,default) --- end --- else --- list = selective(attribute,leader,inheritance,default) --- end --- if leader ~= list then --- setleader(stack,list) --- end --- -- end nested --- leader = false --- end --- elseif default and inheritance then --- if current ~= default then --- local data = nsdata[default] --- head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector])) --- current = default --- end --- elseif current > 0 then --- head = insert_node_before(head,stack,copy_node(nsnone)) --- current, current_selector = 0, 0 --- end --- check = false --- end --- stack = getnext(stack) --- end --- return head --- end --- --- states.selective = function(namespace,attribute,head,default) --- return selective(attribute,head,default) --- end - local function selective(attribute,head,inheritance,default) -- two attributes local check = false local leader = nil - for stack, id in nextnode, head do + for stack, id, subtype in nextnode, head do if id == glyph_code or id == disc_code then check = true -- disc no longer needed as we flatten replace elseif id == glue_code then @@ -494,9 +311,13 @@ local function selective(attribute,head,inheritance,default) -- two attributes -- end nested end elseif id == rule_code then --- check = getwidth(stack) ~= 0 -local wd, ht, dp = getwhd(stack) -check = wd ~= 0 or (ht+dp) ~= 0 +if subtype == box_rule_code or subtype == image_rule_code or subtype == empty_rule_code then + -- so no redundant color stuff (only here, layers for instance should obey) + check = false +else + local wd, ht, dp = getwhd(stack) + check = wd ~= 0 or (ht+dp) ~= 0 +end end if check then @@ -606,9 +427,8 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance, end end elseif id == rule_code then --- check = getwidth(stack) ~= 0 -local wd, ht, dp = getwhd(stack) -check = wd ~= 0 or (ht+dp) ~= 0 + local wd, ht, dp = getwhd(stack) + check = wd ~= 0 or (ht+dp) ~= 0 end if check then local a = getattr(stack,attribute) @@ -693,9 +513,8 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, end end elseif id == rule_code then --- check = getwidth(current) ~= 0 -local wd, ht, dp = getwhd(current) -check = wd ~= 0 or (ht+dp) ~= 0 + local wd, ht, dp = getwhd(current) + check = wd ~= 0 or (ht+dp) ~= 0 end if check then diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua index e4011ef59..4aa18ee48 100644 --- a/tex/context/base/mkiv/node-ini.lua +++ b/tex/context/base/mkiv/node-ini.lua @@ -311,7 +311,7 @@ local noadoptions = allocate { -- local directionvalues = mark(getvalues("dir")) -- local gluevalues = mark(getvalues("glue")) --- local pdfliteralvalues = mark(getvalues("pdf_literal")) +-- local literalvalues = mark(getvalues("literal")) local dirvalues = allocate { [0] = "TLT", @@ -328,7 +328,7 @@ local gluevalues = allocate { [4] = "filll", } -local pdfliteralvalues = allocate { +local literalvalues = allocate { [0] = "origin", [1] = "page", [2] = "always", @@ -361,7 +361,7 @@ usercodes = allocate(swapped(usercodes,usercodes)) noadoptions = allocate(swapped(noadoptions,noadoptions)) dirvalues = allocate(swapped(dirvalues,dirvalues)) gluevalues = allocate(swapped(gluevalues,gluevalues)) -pdfliteralvalues = allocate(swapped(pdfliteralvalues,pdfliteralvalues)) +literalvalues = allocate(swapped(literalvalues,literalvalues)) nodes.gluecodes = gluecodes nodes.dircodes = dircodes @@ -386,7 +386,20 @@ nodes.usercodes = usercodes nodes.noadoptions = noadoptions nodes.dirvalues = dirvalues nodes.gluevalues = gluevalues -nodes.pdfliteralvalues = pdfliteralvalues +nodes.literalvalues = literalvalues + +if whatcodes.literal then + -- temporary hack + whatcodes.pdfliteral = whatcodes.literal + whatcodes.pdfsave = whatcodes.save + whatcodes.pdfrestore = whatcodes.restore + whatcodes.pdfsetmatrix = whatcodes.setmatrix +else + whatcodes.literal = whatcodes.pdfliteral + whatcodes.save = whatcodes.pdfsave + whatcodes.restore = whatcodes.pdfrestore + whatcodes.setmatrix = whatcodes.pdfsetmatrix +end dirvalues.lefttoright = 0 dirvalues.righttoleft = 1 @@ -417,14 +430,14 @@ table.setmetatableindex(nodes.subtypes,function(t,k) return v end) -nodes.skipcodes = gluecodes -- more friendly -nodes.directioncodes = dircodes -- more friendly -nodes.whatsitcodes = whatcodes -- more official +nodes.skipcodes = gluecodes -- more friendly +nodes.directioncodes = dircodes -- more friendly +nodes.whatsitcodes = whatcodes -- more official nodes.marginkerncodes = margincodes nodes.discretionarycodes = disccodes -nodes.directionvalues = dirvalues -- more friendly -nodes.skipvalues = gluevalues -- more friendly -nodes.literalvalues = pdfliteralvalues -- more friendly +nodes.directionvalues = dirvalues -- more friendly +nodes.skipvalues = gluevalues -- more friendly +nodes.literalvalues = literalvalues -- more friendly glyphcodes.glyph = glyphcodes.character @@ -435,7 +448,7 @@ kerncodes.kerning = kerncodes.fontkern kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new -pdfliteralvalues.direct = pdfliteralvalues.always +literalvalues.direct = literalvalues.always nodes.codes = allocate { -- mostly for listing glue = skipcodes, diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index 983899c1b..01cf1d1f0 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -171,7 +171,6 @@ local glyph = register_nut(new_nut(glyphcode,0)) local textdir = register_nut(new_nut(nodecodes.dir)) local latelua = register_nut(new_nut(whatsitcode,whatsitcodes.latelua)) -local special = register_nut(new_nut(whatsitcode,whatsitcodes.special)) local savepos = register_nut(new_nut(whatsitcode,whatsitcodes.savepos)) local user_node = new_nut(whatsitcode,whatsitcodes.userdefined) @@ -608,13 +607,6 @@ function nutpool.userattributes(id,attr) return n end -function nutpool.special(str) - local n = copy_nut(special) - -- setfield(n,"data",str) - setdata(n,str) - return n -end - -- housekeeping local function cleanup(nofboxes) -- todo diff --git a/tex/context/base/mkiv/node-shp.lua b/tex/context/base/mkiv/node-shp.lua index 74f3c4da2..c7f1c9810 100644 --- a/tex/context/base/mkiv/node-shp.lua +++ b/tex/context/base/mkiv/node-shp.lua @@ -58,7 +58,7 @@ local removables = { [whatsitcodes.write] = true, [whatsitcodes.savepos] = true, [whatsitcodes.latelua] = true, - [whatsitcodes.pdfdest] = true, + -- [whatsitcodes.pdfdest] = true, } -- About 10% of the nodes make no sense for the backend. By (at least) diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua index 0d4b1b45d..835a60193 100644 --- a/tex/context/base/mkiv/node-syn.lua +++ b/tex/context/base/mkiv/node-syn.lua @@ -361,6 +361,7 @@ end function synctex.wrapup() if tmpfile then renamefile(tmpfile,logfile) + tmpfile = nil end end diff --git a/tex/context/base/mkiv/spac-ali.mkiv b/tex/context/base/mkiv/spac-ali.mkiv index ee4cfa8bc..b28295cb3 100644 --- a/tex/context/base/mkiv/spac-ali.mkiv +++ b/tex/context/base/mkiv/spac-ali.mkiv @@ -333,7 +333,8 @@ \newconstant\c_spac_align_state_par_fill \def\v_spac_align_fill_amount {\plusone fil} -\def\v_spac_align_fill_amount_hard {\plusone fill} +\def\v_spac_align_fill_amount_hard {\plusone fill} +\def\v_spac_align_fill_amount_extreme {\plustenthousand filll} \def\v_spac_align_fill_amount_negative {\minusone fil} \def\v_spac_align_fill_amount_double {\plustwo fil} \def\v_spac_align_fill_amount_space {\plustwo fil} % can be added to xspace if we have a key @@ -457,7 +458,8 @@ \spaceskip \zeropoint\relax \xspaceskip \zeropoint\relax \parfillskip \zeropoint - \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_hard\relax + \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax + \parfillleftmode\plustwo % \plusone checks for multiple lines \parindent \zeropoint \relax} diff --git a/tex/context/base/mkiv/spac-hor.mkiv b/tex/context/base/mkiv/spac-hor.mkiv index db8d12ae2..8504fdbd3 100644 --- a/tex/context/base/mkiv/spac-hor.mkiv +++ b/tex/context/base/mkiv/spac-hor.mkiv @@ -17,8 +17,9 @@ \registerctxluafile{spac-hor}{} -\let \parfillrightskip \parfillskip -\newskip\parfillleftskip +\let \parfillrightskip \parfillskip +\newskip \parfillleftskip +\newconstant\parfillleftmode \let\v_spac_indentation_current\empty % amount/keyword diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 2c0642736..60ab6f82f 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 6d2294748..863c2d643 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/syst-aux.lua b/tex/context/base/mkiv/syst-aux.lua index 5072879fa..f3ab7ff61 100644 --- a/tex/context/base/mkiv/syst-aux.lua +++ b/tex/context/base/mkiv/syst-aux.lua @@ -323,9 +323,47 @@ end implement { name = "texdefinition_one", actions = texdefinition_one, scope = "private", arguments = "string" } implement { name = "texdefinition_two", actions = texdefinition_two, scope = "private" } -implement { name = "upper", arguments = "string", actions = { utf.upper, context } } -implement { name = "lower", arguments = "string", actions = { utf.lower, context } } -implement { name = "strip", arguments = "string", actions = { string.strip, context } } -- or utf.strip +do + + -- Quite probably we don't yet have characters loaded so we delay some + -- aliases. + + local _lower_, _upper_, _strip_ + + _lower_ = function(s) + if characters and characters.lower then + _lower_ = characters.lower + return _lower_(s) + end + return string.lower(s) + end + + _upper_ = function(s) + if characters and characters.upper then + _upper_ = characters.upper + return _upper_(s) + end + return string.upper(s) + end + + _strip_ = function(s) + -- or utf.strip + if string.strip then + _strip_ = string.strip + return _strip_(s) + end + return s + end + + local function lower() context(_lower_(s)) end + local function upper() context(_upper_(s)) end + local function strip() context(_strip_(s)) end + + implement { name = "upper", arguments = "string", actions = upper } + implement { name = "lower", arguments = "string", actions = lower } + implement { name = "strip", arguments = "string", actions = strip } + +end implement { name = "converteddimen", diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv index f7b73a30e..f9f685f76 100644 --- a/tex/context/base/mkiv/syst-ini.mkiv +++ b/tex/context/base/mkiv/syst-ini.mkiv @@ -1042,6 +1042,8 @@ % module after which the official interfaces have to be used. This is needed for % modules not made by ctx developers. +\ifdefined\pdfextension + \normalprotected\def\pdfliteral {\pdfextension literal } \normalprotected\def\pdfcolorstack {\pdfextension colorstack } \normalprotected\def\pdfsetmatrix {\pdfextension setmatrix } @@ -1148,8 +1150,18 @@ \normalprotected\def\maximumpdfcompression{\pdfobjcompresslevel\plusnine \pdfcompresslevel\plusnine } \normalprotected\def\normalpdfcompression {\pdfobjcompresslevel\plusthree \pdfcompresslevel\plusthree} +\else + \let\nopdfcompression \relax + \let\maximumpdfcompression\relax + \let\normalpdfcompression \relax +\fi + \normalpdfcompression +\ifdefined\outputmode \else + \newcount\outputmode +\fi + \outputmode \zerocount % we generate the format in this mode %D Basic status stuff. @@ -1191,8 +1203,13 @@ %D We get rid of the funny \TEX\ offset defaults of one inch by setting them to zero. -\voffset\zeropoint \let\voffset\relax \newdimen\voffset % prevent messing up -\hoffset\zeropoint \let\hoffset\relax \newdimen\hoffset % prevent messing up +\voffset\zeropoint \let\voffset\relax \newdimen\voffset +\hoffset\zeropoint \let\hoffset\relax \newdimen\hoffset + +\let\pageleftoffset \hoffset +\let\pagerightoffset \hoffset +\let\pagetopoffset \voffset +\let\pagebottomoffset\voffset %D Handy. diff --git a/tex/context/base/mkiv/toks-aux.mkiv b/tex/context/base/mkiv/toks-aux.mkiv new file mode 100644 index 000000000..5b43de596 --- /dev/null +++ b/tex/context/base/mkiv/toks-aux.mkiv @@ -0,0 +1,51 @@ +%D \module +%D [ file=toks-aux, +%D version=2018.11.29, +%D title=\CONTEXT\ Token Support, +%D subtitle=Helpers, +%D author=Wolfgang Schuster, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Token Support / Helpers} + +\unprotect + +\installcorenamespace {tokenlist} + +\unexpanded\def\definetokenlist[#1]% + {\ifcsname\??tokenlist#1\endcsname + \global\lastnamedcs\emptytoks + \else + \expandafter\newtoks\csname\??tokenlist#1\endcsname + \fi} + +\unexpanded\def\starttokenlist[#1]#2\stoptokenlist + {\ifcsname\??tokenlist#1\endcsname \else + \expandafter\newtoks\csname\??tokenlist#1\endcsname + \fi + \toksapp\lastnamedcs{#2}} + +\let\stoptokenlist\relax + +\def\gettokenlist[#1]% + {\ifcsname\??tokenlist#1\endcsname + \the\lastnamedcs + \fi} + +\def\settokenlist[#1]#2% + {\ifcsname\??tokenlist#1\endcsname \else + \expandafter\newtoks\csname\??tokenlist#1\endcsname + \fi + \toksapp\lastnamedcs{#2}} + +\unexpanded\def\resettokenlist[#1]% + {\ifcsname\??tokenlist#1\endcsname + \lastnamedcs\emptytoks + \fi} + +\protect diff --git a/tex/context/base/mkiv/typo-fln.lua b/tex/context/base/mkiv/typo-fln.lua index e105b5a11..b67086fbe 100644 --- a/tex/context/base/mkiv/typo-fln.lua +++ b/tex/context/base/mkiv/typo-fln.lua @@ -204,7 +204,7 @@ actions[v_line] = function(head,setting) while start do local id = getid(start) if id == glyph_code then - n = n + 1 + -- go on elseif id == disc_code then -- this could be an option n = n + 1 @@ -216,7 +216,8 @@ actions[v_line] = function(head,setting) end elseif id == kern_code then -- todo: fontkern -- this could be an option - elseif n > 0 then + elseif id == glue_code then + n = n + 1 if try() then break end @@ -253,7 +254,6 @@ actions[v_line] = function(head,setting) local id = getid(start) local ok = false if id == glyph_code then - n = n + 1 update(start) elseif id == disc_code then n = n + 1 @@ -297,18 +297,26 @@ actions[v_line] = function(head,setting) setdisc(disc,pre,post,replace) flush_node(disc) elseif id == glue_code then - head = insert_node_before(head,start,newpenalty(10000)) -- nobreak + n = n + 1 + if linebreak ~= n then + head = insert_node_before(head,start,newpenalty(10000)) -- nobreak + end end + local next = getnext(start) if linebreak == n then - if trace_firstlines then - head, start = insert_node_after(head,start,newpenalty(10000)) -- nobreak - head, start = insert_node_after(head,start,newkern(-65536)) - head, start = insert_node_after(head,start,tracerrule(65536,4*65536,2*65536,"darkblue")) + if start ~= head then + local where = id == glue_code and getprev(start) or start + if trace_firstlines then + head, where = insert_node_after(head,where,newpenalty(10000)) -- nobreak + head, where = insert_node_after(head,where,newkern(-65536)) + head, where = insert_node_after(head,where,tracerrule(65536,4*65536,2*65536,"darkblue")) + end + head, where = insert_node_after(head,where,newpenalty(-10000)) -- break end - head, start = insert_node_after(head,start,newpenalty(-10000)) -- break + start = next break end - start = getnext(start) + start = next end end diff --git a/tex/context/base/mkiv/typo-lin.lua b/tex/context/base/mkiv/typo-lin.lua index 862240524..a1c0bb52b 100644 --- a/tex/context/base/mkiv/typo-lin.lua +++ b/tex/context/base/mkiv/typo-lin.lua @@ -248,33 +248,36 @@ function paragraphs.normalize(head,islocal) return head, false end -- this can become a separate handler but it makes sense to integrate it here - local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip") - if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then - local last = nil -- a nut - local done = false - for line, subtype in nexthlist, head do - if subtype == line_code and not getprop(line,"line") then - if done then - last = line - else - done = true + local mode = texgetcount("parfillleftmode") + if mode > 0 then + local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip") + if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then + local last = nil -- a nut + local done = mode == 2 -- false + for line, subtype in nexthlist, head do + if subtype == line_code and not getprop(line,"line") then + if done then + last = line + else + done = true + end end end - end - if last then -- only if we have more than one line - local head = getlist(last) - local current = head - if current then - if getid(current) == glue_code and getsubtype(current,leftskip_code) then - current = getnext(current) - end + if last then -- only if we have more than one line + local head = getlist(last) + local current = head if current then - head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink)) - if head == current then - setlist(last,head) + if getid(current) == glue_code and getsubtype(current,leftskip_code) then + current = getnext(current) + end + if current then + head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink)) + if head == current then + setlist(last,head) + end + -- can be a 'rehpack(h )' + rehpack(last) end - -- can be a 'rehpack(h )' - rehpack(last) end end end @@ -283,14 +286,9 @@ function paragraphs.normalize(head,islocal) for line, subtype in nexthlist, head do if subtype == line_code and not getprop(line,"line") then normalize(line) - if done then - last = line - else - done = true - end end end - return head, true + return head, true -- true is obsolete end -- print(nodes.idstostring(head)) diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index 620b85ea4..eebe9e7a0 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -1247,6 +1247,7 @@ + diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 94584fd03..c2fd61636 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index a06625a9a..9a4afe44d 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/context/modules/mkiv/x-setups-basics.mkiv b/tex/context/modules/mkiv/x-setups-basics.mkiv index 028c9e5a5..51c925397 100644 --- a/tex/context/modules/mkiv/x-setups-basics.mkiv +++ b/tex/context/modules/mkiv/x-setups-basics.mkiv @@ -517,11 +517,7 @@ {\doifelsenextoptionalcs\cmd_show_setup_yes\cmd_show_setup_nop} \def\cmd_show_setup_yes[#1]% - {\iffirstargument - \cmd_show_setup_nop{#1}% - \else - \expandafter\cmd_show_setup_nop - \fi} + {\cmd_show_setup_nop{#1}} \def\cmd_show_setup_nop#1% this will trigger 'used' {\begingroup diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 5499f8f18..493c21a03 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 11/18/18 14:07:44 +-- merge date : 11/29/18 19:46:33 do -- begin closure to overcome local limits and interference @@ -554,7 +554,7 @@ function lpeg.counter(pattern,action) return function(str) n=0;lpegmatch(pattern,str);return n end end end -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 @@ -3097,7 +3097,8 @@ if not modules then modules={} end modules ['l-unicode']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -utf=utf or (unicode and unicode.utf8) or {} +utf=utf or {} +unicode=nil utf.characters=utf.characters or string.utfcharacters utf.values=utf.values or string.utfvalues local type=type @@ -3120,9 +3121,6 @@ local p_utf8byte=patterns.utf8byte local p_utfbom=patterns.utfbom local p_newline=patterns.newline local p_whitespace=patterns.whitespace -if not unicode then - unicode={ utf=utf } -end if not utf.char then utf.char=string.utfcharacter or (utf8 and utf8.char) if not utf.char then @@ -3743,7 +3741,7 @@ end if bit32 then local extract=bit32.extract local char=string.char - function unicode.toutf32string(n) + function utf.toutf32string(n) if n<=0xFF then return char(n).."\000\000\000" @@ -11757,7 +11755,7 @@ readers["os/2"]=function(f,fontdata) if version>=1 then windowsmetrics.codepageranges={ readulong(f),readulong(f) } end - if version>=3 then + if version>=2 then windowsmetrics.xheight=readshort(f) windowsmetrics.capheight=readshort(f) windowsmetrics.defaultchar=readushort(f) @@ -12980,7 +12978,7 @@ function readers.loadfont(filename,n,instance) mathconstants=fontdata.mathconstants, colorpalettes=fontdata.colorpalettes, svgshapes=fontdata.svgshapes, - sbixshapes=fontdata.sbixshapes, + pngshapes=fontdata.pngshapes, variabledata=fontdata.variabledata, foundtables=fontdata.foundtables, }, @@ -17465,10 +17463,11 @@ local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader local setposition=streamreader.setposition local getposition=streamreader.getposition -local readushort=streamreader.readcardinal2 -local readulong=streamreader.readcardinal4 +local readuinteger=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readulong=streamreader.readcardinal4 local readinteger=streamreader.readinteger1 -local readshort=streamreader.readinteger2 +local readshort=streamreader.readinteger2 local readstring=streamreader.readstring local readtag=streamreader.readtag local readbytes=streamreader.readbytes @@ -17488,6 +17487,7 @@ directives.register("fonts.streamreader",function() streamreader=utilities.streams setposition=streamreader.setposition getposition=streamreader.getposition + readuinteger=streamreader.readcardinal1 readushort=streamreader.readcardinal2 readulong=streamreader.readcardinal4 readinteger=streamreader.readinteger1 @@ -20084,59 +20084,269 @@ function readers.sbix(f,fontdata,specification) for i=1,nofstrikes do strikes[i]=readulong(f) end + local shapes={} + local done=0 + for i=1,nofstrikes do + local strikeoffset=strikes[i]+tableoffset + setposition(f,strikeoffset) + strikes[i]={ + ppem=readushort(f), + ppi=readushort(f), + offset=strikeoffset + } + end + sort(strikes,function(a,b) + if b.ppem==a.ppem then + return b.ppi0 then + setposition(f,strikeoffset+glyphoffset) + shapes[i]={ + x=readshort(f), + y=readshort(f), + tag=readtag(f), + data=readstring(f,datasize-8), + ppem=strikeppem, + ppi=strikeppi, + } + done=done+1 + if done==nofglyphs then + break + end + end + end + glyphoffset=nextoffset + end + end + fontdata.pngshapes=shapes + end +end +do + local function getmetrics(f) + return { + ascender=readinteger(f), + descender=readinteger(f), + widthmax=readuinteger(f), + caretslopedumerator=readinteger(f), + caretslopedenominator=readinteger(f), + caretoffset=readinteger(f), + minorigin=readinteger(f), + minadvance=readinteger(f), + maxbefore=readinteger(f), + minafter=readinteger(f), + pad1=readinteger(f), + pad2=readinteger(f), + } + end + local function getbigmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + horiBearingX=readinteger(f), + horiBearingY=readinteger(f), + horiAdvance=readuinteger(f), + vertBearingX=readinteger(f), + vertBearingY=readinteger(f), + vertAdvance=readuinteger(f), + } + end + local function getsmallmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + bearingX=readinteger(f), + bearingY=readinteger(f), + advance=readuinteger(f), + } + end + function readers.cblc(f,fontdata,specification) + local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs) + if not ctdttableoffset then + return + end + local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs) + if cblctableoffset then + local majorversion=readushort(f) + local minorversion=readushort(f) + local nofsizetables=readulong(f) + local sizetables={} local shapes={} - local done=0 - for i=1,nofstrikes do - local strikeoffset=strikes[i]+tableoffset - setposition(f,strikeoffset) - strikes[i]={ - ppem=readushort(f), - ppi=readushort(f), - offset=strikeoffset + local subtables={} + for i=1,nofsizetables do + sizetables[i]={ + subtables=readulong(f), + indexsize=readulong(f), + nofsubtables=readulong(f), + colorref=readulong(f), + hormetrics=getmetrics(f), + vermetrics=getmetrics(f), + firstindex=readushort(f), + lastindex=readushort(f), + ppemx=readbyte(f), + ppemy=readbyte(f), + bitdepth=readbyte(f), + flags=readbyte(f), } end - sort(strikes,function(a,b) - if b.ppem==a.ppem then - return b.ppi0 then - setposition(f,strikeoffset+glyphoffset) - shapes[i]={ - x=readshort(f), - y=readshort(f), - tag=readtag(f), - data=readstring(f,datasize-8), - ppem=strikeppem, - ppi=strikeppi, - } - done=done+1 - if done==nofglyphs then - break + for i=1,nofsizetables do + local s=sizetables[i] + local d=false + for j=s.firstindex,s.lastindex do + if not shapes[j] then + shapes[j]=i + d=true + end + end + if d then + s.used=true + end + end + for i=1,nofsizetables do + local s=sizetables[i] + if s.used then + local offset=s.subtables + setposition(f,cblctableoffset+offset) + for j=1,s.nofsubtables do + local firstindex=readushort(f) + local lastindex=readushort(f) + local tableoffset=readulong(f)+offset + for k=firstindex,lastindex do + if shapes[k]==i then + local s=subtables[tableoffset] + if not s then + s={ + firstindex=firstindex, + lastindex=lastindex, + } + subtables[tableoffset]=s + end + shapes[k]=s end end end - glyphoffset=nextoffset end end - fontdata.sbixshapes=shapes + for offset,subtable in sortedhash(subtables) do + local tabletype=readushort(f) + subtable.format=readushort(f) + local baseoffset=readulong(f)+ctdttableoffset + local offsets={} + local metrics=nil + if tabletype==1 then + for i=subtable.firstindex,subtable.lastindex do + offsets[i]=readulong(f)+baseoffset + end + skipbytes(f,4) + elseif tabletype==2 then + local size=readulong(f) + local done=baseoffset + metrics=getbigmetrics(f) + for i=subtable.firstindex,subtable.lastindex do + offsets[i]=done + done=done+size + end + elseif tabletype==3 then + local n=subtable.lastindex-subtable.firstindex+2 + for i=subtable.firstindex,subtable.lastindex do + offsets[i]=readushort(f)+baseoffset + end + if math.odd(n) then + skipbytes(f,4) + else + skipbytes(f,2) + end + elseif tabletype==4 then + for i=1,readulong(f) do + offsets[readushort(f)]=readushort(f)+baseoffset + end + elseif tabletype==5 then + local size=readulong(f) + local done=baseoffset + metrics=getbigmetrics(f) + local n=readulong(f) + for i=1,n do + offsets[readushort(f)]=done + done=done+size + end + if math.odd(n) then + skipbytes(f,2) + end + else + return + end + subtable.offsets=offsets + subtable.metrics=metrics + end + local default={ width=0,height=0 } + local glyphs=fontdata.glyphs + for index,subtable in sortedhash(shapes) do + if type(subtable)=="table" then + local data=nil + local metrics=default + local format=subtable.format + local offset=subtable.offsets[index] + setposition(f,offset) + if format==17 then + metrics=getsmallmetrics(f) + data=readstring(f,readulong(f)) + elseif format==18 then + metrics=getbigmetrics(f) + data=readstring(f,readulong(f)) + elseif format==19 then + metrics=subtable.metrics + data=readstring(f,readulong(f)) + else + end + local x=metrics.width + local y=metrics.height + shapes[index]={ + x=x, + y=y, + data=data, + } + local glyph=glyphs[index] + if not glyph.boundingbox then + local width=glyph.width + local height=width*y/x + glyph.boundingbox={ 0,0,width,height } + end + else + shapes[index]={ + x=0, + y=0, + data="", + } + end + end + fontdata.pngshapes=shapes + end + end + function readers.cbdt(f,fontdata,specification) end end function readers.stat(f,fontdata,specification) @@ -21136,7 +21346,7 @@ local function unifymissing(fontdata) fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) resources.unicodes=nil end -local firstprivate=fonts.privateoffsets.textbase or 0xF0000 +local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 local puafirst=0xE000 local pualast=0xF8FF local function unifyglyphs(fontdata,usenames) @@ -23091,13 +23301,13 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_de local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.106 +otf.version=3.107 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) -otf.sbixcache=containers.define("fonts","sbix",otf.version,true) +otf.pngcache=containers.define("fonts","png",otf.version,true) otf.pdfcache=containers.define("fonts","pdf",otf.version,true) otf.svgenabled=false -otf.sbixenabled=false +otf.pngenabled=false local otfreaders=otf.readers local hashes=fonts.hashes local definers=fonts.definers @@ -23165,7 +23375,7 @@ function otf.load(filename,sub,instance) report_otf("forced reload of %a due to hard coded flag",filename) reload=true end - if reload then + if reload then report_otf("loading %a, hash %a",filename,hash) starttiming(otfreaders,true) data=otfreaders.loadfont(filename,sub or 1,instance) @@ -23173,7 +23383,7 @@ function otf.load(filename,sub,instance) local used=checkmemory() local resources=data.resources local svgshapes=resources.svgshapes - local sbixshapes=resources.sbixshapes + local pngshapes=resources.pngshapes if cleanup==0 then checkmemory(used,threshold,tracememory) end @@ -23196,15 +23406,15 @@ function otf.load(filename,sub,instance) checkmemory(used,threshold,tracememory) end end - if sbixshapes then - resources.sbixshapes=nil - if otf.sbixenabled then + if pngshapes then + resources.pngshapes=nil + if otf.pngenabled then local timestamp=os.date() - containers.write(otf.sbixcache,hash,{ - sbixshapes=sbixshapes, + containers.write(otf.pngcache,hash,{ + pngshapes=pngshapes, timestamp=timestamp, }) - data.properties.sbix={ + data.properties.png={ hash=hash, timestamp=timestamp, } @@ -31646,11 +31856,13 @@ else sharedpalettes[name]=values for i=1,#values do local v=values[i] - values[i]=hash[f_color( - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - )] + if v then + values[i]=hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end end end end @@ -31674,7 +31886,7 @@ local pop={ "pdf","page","Q" } if not LUATEXFUNCTIONALITY or LUATEXFUNCTIONALITY<6472 then start={ "nop" } end -local function initialize(tfmdata,kind,value) +local function initialize(tfmdata,kind,value) if value then local resources=tfmdata.resources local palettes=resources.colorpalettes @@ -31684,7 +31896,13 @@ local function initialize(tfmdata,kind,value) converted=setmetatableindex(convert) resources.converted=converted end - local colorvalues=sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or {} + local colorvalues=sharedpalettes[value] + local default=false + if colorvalues then + default=colorvalues[#colorvalues] + else + colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {} + end local classes=#colorvalues if classes==0 then return @@ -31697,7 +31915,6 @@ local function initialize(tfmdata,kind,value) { id=0 } } local getactualtext=otf.getactualtext - local default=colorvalues[#colorvalues] local b,e=getactualtext(tounicode(0xFFFD)) local actualb={ "pdf","page",b } local actuale={ "pdf","page",e } @@ -31728,6 +31945,12 @@ local function initialize(tfmdata,kind,value) f=true n=n+1 t[n]=v l=v + else + if f then + n=n+1 t[n]=pop + end + f=false + l=nil end n=n+1 t[n]=charcommand[entry.slot] if s>1 and i temp-otf-svg-shape.log") + return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") end end - function otfsbix.topdf(sbixshapes) + function otfpng.topdf(pngshapes) local pdfshapes={} - local sbixfile="temp-otf-sbix-shape.sbix" - local pdffile="temp-otf-sbix-shape.pdf" + local pngfile="temp-otf-png-shape.png" + local pdffile="temp-otf-png-shape.pdf" local nofdone=0 - local indices=sortedkeys(sbixshapes) + local indices=sortedkeys(pngshapes) local nofindices=#indices - report_sbix("processing %i sbix containers",nofindices) + report_png("processing %i png containers",nofindices) statistics.starttiming() for i=1,nofindices do local index=indices[i] - local entry=sbixshapes[index] - local data=entry.data + local entry=pngshapes[index] + local data=entry.data local x=entry.x local y=entry.y - savedata(sbixfile,data) + savedata(pngfile,data) runner() pdfshapes[index]={ x=x~=0 and x or nil, @@ -31995,47 +32218,55 @@ do } nofdone=nofdone+1 if nofdone%100==0 then - report_sbix("%i shapes processed",nofdone) + report_png("%i shapes processed",nofdone) end end - report_sbix("processing %i pdf results",nofindices) - remove(sbixfile) + report_png("processing %i pdf results",nofindices) + remove(pngfile) remove(pdffile) statistics.stoptiming() if statistics.elapsedseconds then - report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-") + report_png("png conversion time %s",statistics.elapsedseconds() or "-") end return pdfshapes end end -local function initializesbix(tfmdata,kind,value) - if value and otf.sbixenabled then - local sbix=tfmdata.properties.sbix - local hash=sbix and sbix.hash - local timestamp=sbix and sbix.timestamp +local function initializepng(tfmdata,kind,value) + if value and otf.pngenabled then + local png=tfmdata.properties.png + local hash=png and png.hash + local timestamp=png and png.timestamp if not hash then return end local pdffile=containers.read(otf.pdfcache,hash) local pdfshapes=pdffile and pdffile.pdfshapes if not pdfshapes or pdffile.timestamp~=timestamp then - local sbixfile=containers.read(otf.sbixcache,hash) - local sbixshapes=sbixfile and sbixfile.sbixshapes - pdfshapes=sbixshapes and otfsbix.topdf(sbixshapes) or {} + local pngfile=containers.read(otf.pngcache,hash) + local pngshapes=pngfile and pngfile.pngshapes + pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {} containers.write(otf.pdfcache,hash,{ pdfshapes=pdfshapes, timestamp=timestamp, }) end - pdftovirtual(tfmdata,pdfshapes,"sbix") + pdftovirtual(tfmdata,pdfshapes,"png") end end fonts.handlers.otf.features.register { name="sbix", description="sbix glyphs", manipulators={ - base=initializesbix, - node=initializesbix, + base=initializepng, + node=initializepng, + } +} +fonts.handlers.otf.features.register { + name="cblc", + description="cblc glyphs", + manipulators={ + base=initializepng, + node=initializepng, } } @@ -34085,6 +34316,13 @@ function tfm.setfeatures(tfmdata,features) end end local depth={} +local loadtfmvf=tfm.readers and tfm.readers.loadtfmvf +directives.register("fonts.tfm.builtin",function(v) + loadtfmvf=tfm.readers and tfm.readers.loadtfmvf + if v and font.read_tfm then + loadtfmvf=false + end +end) local function read_from_tfm(specification) local filename=specification.filename local size=specification.size @@ -34092,7 +34330,12 @@ local function read_from_tfm(specification) if trace_defining then report_defining("loading tfm file %a at size %s",filename,size) end - local tfmdata=font.read_tfm(filename,size) + local tfmdata + if loadtfmvf then + tfmdata=loadtfmvf(filename,size) + else + tfmdata=font.read_tfm(filename,size) + end if tfmdata then local features=specification.features and specification.features.normal or {} local features=constructors.checkedfeatures("tfm",features) @@ -34157,9 +34400,9 @@ local function read_from_tfm(specification) end end shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil -if size<0 then - size=idiv(65536*-size,100) -end + if size<0 then + size=idiv(65536*-size,100) + end parameters.factor=1 parameters.size=size parameters.slant=parameters.slant or parameters[1] or 0 @@ -34172,6 +34415,26 @@ end constructors.enhanceparameters(parameters) properties.private=properties.private or tfmdata.private or privateoffset if newtfmdata then + elseif loadtfmvf then + local fonts=tfmdata.fonts + if fonts then + for i=1,#fonts do + local font=fonts[i] + local id=font.id + if not id then + local name=font.name + local size=font.size + if name and size then + local data,id=constructors.readanddefine(name,size) + if id then + font.id=id + font.name=nil + font.size=nil + end + end + end + end + end elseif constructors.resolvevirtualtoo then fonts.loggers.register(tfmdata,file.suffix(filename),specification) local vfname=findbinfile(specification.name,'ovf') @@ -34199,7 +34462,7 @@ end report_defining("virtual font %a exceeds size %s",n,s) fontlist[i]={ id=0 } else - local t,id=fonts.constructors.readanddefine(n,s) + local t,id=constructors.readanddefine(n,s) fontlist[i]={ id=id } end end @@ -34208,6 +34471,7 @@ end end properties.haskerns=true properties.hasligatures=true + properties.hasitalics=true resources.unicodes={} resources.lookuptags={} depth[filename]=depth[filename]-1 @@ -34289,7 +34553,7 @@ do local encoding=false local vector=false if type(pfbfile)=="string" then - local pfb=fonts.constructors.handlers.pfb + local pfb=constructors.handlers.pfb if pfb and pfb.loadvector then local v,e=pfb.loadvector(pfbfile) if v then @@ -34317,7 +34581,7 @@ do local originals=tfmdata.characters local indices={} local parentfont={ "font",1 } - local private=tfmdata.privateoffset or fonts.constructors.privateoffset + local private=tfmdata.privateoffset or constructors.privateoffset local reported=encdone[tfmfile][encfile] local backmap=vector and table.swapped(vector) local done={} diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua index 16c85ddc2..b869efc56 100644 --- a/tex/generic/context/luatex/luatex-fonts.lua +++ b/tex/generic/context/luatex/luatex-fonts.lua @@ -44,7 +44,7 @@ if not modules then modules = { } end modules ['luatex-fonts'] = { -- and interferences between mechanisms between macro packages. We use the rendering in context -- and luatex-plain as reference for issues. -utf = utf or unicode.utf8 +utf = utf or (unicode and unicode.utf8) or { } -- We have some (global) hooks (for latex): -- cgit v1.2.3