summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-04-16 13:20:40 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-04-16 13:20:40 +0200
commit218228536ed709be8ab2dde4a00dc27249ceed8a (patch)
tree71b331e3d99ebd89fefcc1cb369d233c5c7fbdc1 /tex
parentea2466fe69bd082d379e95e1567f3de0b76de243 (diff)
downloadcontext-218228536ed709be8ab2dde4a00dc27249ceed8a.tar.gz
2017-04-16 12:47:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/cont-run.lua4
-rw-r--r--tex/context/base/mkiv/cont-run.mkiv1
-rw-r--r--tex/context/base/mkiv/context.mkiv3
-rw-r--r--tex/context/base/mkiv/font-ctx.lua33
-rw-r--r--tex/context/base/mkiv/font-def.lua71
-rw-r--r--tex/context/base/mkiv/font-dsp.lua189
-rw-r--r--tex/context/base/mkiv/font-ocl.lua308
-rw-r--r--tex/context/base/mkiv/font-otc.lua4
-rw-r--r--tex/context/base/mkiv/font-otl.lua30
-rw-r--r--tex/context/base/mkiv/font-otr.lua110
-rw-r--r--tex/context/base/mkiv/l-pdfview.lua4
-rw-r--r--tex/context/base/mkiv/lang-ini.lua5
-rw-r--r--tex/context/base/mkiv/luat-run.lua31
-rw-r--r--tex/context/base/mkiv/lxml-aux.lua2
-rw-r--r--tex/context/base/mkiv/node-nut.lua8
-rw-r--r--tex/context/base/mkiv/node-syn.lua501
-rw-r--r--tex/context/base/mkiv/pack-rul.mkiv4
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25625 -> 25662 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin422657 -> 424483 bytes
-rw-r--r--tex/context/base/mkiv/tabl-frm.mkiv209
-rw-r--r--tex/context/base/mkiv/tabl-ltb.mkiv3
-rw-r--r--tex/context/base/mkiv/typo-bld.lua1
-rw-r--r--tex/context/base/mkiv/util-sci.lua42
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin811962 -> 811963 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60771 -> 60771 bytes
-rw-r--r--tex/context/modules/mkiv/m-scite.mkiv6
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua457
30 files changed, 1703 insertions, 329 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index ede175893..d256c24d9 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{2017.04.08 12:09}
+\newcontextversion{2017.04.16 12:32}
%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 cc11308ef..26595dd56 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{2017.04.08 12:09}
+\edef\contextversion{2017.04.16 12:32}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 3b0c97ff0..0d9ecfdd7 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{2017.04.08 12:09}
+\newcontextversion{2017.04.16 12:32}
%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 d9dad3f2d..2225a0fb2 100644
--- a/tex/context/base/mkiv/cont-run.lua
+++ b/tex/context/base/mkiv/cont-run.lua
@@ -180,6 +180,10 @@ local function processjob()
local suffix = environment.suffix
local filename = environment.filename -- hm, not inputfilename !
+ if arguments.synctex then
+ directives.enable("system.synctex="..tostring(arguments.synctex))
+ end
+
if not filename or filename == "" then
-- skip
elseif suffix == "xml" or arguments.forcexml then
diff --git a/tex/context/base/mkiv/cont-run.mkiv b/tex/context/base/mkiv/cont-run.mkiv
index fcca7b581..490c6bee2 100644
--- a/tex/context/base/mkiv/cont-run.mkiv
+++ b/tex/context/base/mkiv/cont-run.mkiv
@@ -15,6 +15,7 @@
\unprotect
+\registerctxluafile{node-syn}{1.001}
\registerctxluafile{cont-run}{1.001}
\protect \endinput
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 14f619247..c4446b3dd 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.04.08 12:09}
+\edef\contextversion{2017.04.16 12:32}
\edef\contextkind {beta}
%D For those who want to use this:
@@ -403,6 +403,7 @@
\loadmarkfile{tabl-ntb}
\loadmarkfile{tabl-nte}
\loadmarkfile{tabl-ltb}
+\loadmarkfile{tabl-frm}
\loadmarkfile{tabl-tsp}
\loadmkvifile{tabl-xtb}
\loadmarkfile{tabl-mis}
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index 0e64511e2..9e53b2c25 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -156,16 +156,17 @@ end
helpers.name = getfontname
+local addformatter = utilities.strings.formatters.add
+
if _LUAVERSION < 5.2 then
- formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name")
- formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],"local sequenced = table.sequenced")
+ addformatter(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name")
+ addformatter(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],"local sequenced = table.sequenced")
else
- -- somehow can fail:
- formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = helpers.name })
- formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced })
+ addformatter(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = helpers.name })
+ addformatter(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced })
end
@@ -183,12 +184,12 @@ do
local shares = { }
local hashes = { }
-local nofinstances = 0
-local instances = table.setmetatableindex(function(t,k)
- nofinstances = nofinstances + 1
- t[k] = nofinstances
- return nofinstances
-end)
+ local nofinstances = 0
+ local instances = table.setmetatableindex(function(t,k)
+ nofinstances = nofinstances + 1
+ t[k] = nofinstances
+ return nofinstances
+ end)
function constructors.trytosharefont(target,tfmdata)
constructors.noffontsloaded = constructors.noffontsloaded + 1
@@ -347,21 +348,13 @@ otftables.scripts.auto = "automatic fallback to latn when no dflt present"
-- setmetatableindex(otffeatures.descriptions,otftables.features)
-local privatefeatures = { -- this can go away
- tlig = true,
- trep = true,
- anum = true,
-}
-
local function checkedscript(tfmdata,resources,features)
local latn = false
local script = false
if resources.features then
for g, list in next, resources.features do
for f, scripts in next, list do
- if privatefeatures[f] then
- -- skip
- elseif scripts.dflt then
+ if scripts.dflt then
script = "dflt"
break
elseif scripts.latn then
diff --git a/tex/context/base/mkiv/font-def.lua b/tex/context/base/mkiv/font-def.lua
index 6765be9d3..c8394badf 100644
--- a/tex/context/base/mkiv/font-def.lua
+++ b/tex/context/base/mkiv/font-def.lua
@@ -11,8 +11,9 @@ if not modules then modules = { } end modules ['font-def'] = {
local lower, gsub = string.lower, string.gsub
local tostring, next = tostring, next
local lpegmatch = lpeg.match
-local suffixonly, removesuffix = file.suffix, file.removesuffix
+local suffixonly, removesuffix, basename = file.suffix, file.removesuffix, file.basename
local formatters = string.formatters
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
local allocate = utilities.storage.allocate
@@ -203,9 +204,9 @@ function resolvers.name(specification)
features.normal = normal
end
normal.instance = instance
-if not callbacks.supported.glyph_stream_provider then
- normal.variableshapes = true -- for the moment
-end
+ if not callbacks.supported.glyph_stream_provider then
+ normal.variableshapes = true -- for the moment
+ end
end
--
local suffix = lower(suffixonly(resolved))
@@ -313,6 +314,65 @@ local function checkembedding(tfmdata)
tfmdata.embedding = embedding
end
+local function checkfeatures(tfmdata)
+ local resources = tfmdata.resources
+ local shared = tfmdata.shared
+ if resources and shared then
+ local features = resources.features
+ local usedfeatures = shared.features
+ if features and usedfeatures then
+ local usedlanguage = usedfeatures.language or "dflt"
+ local usedscript = usedfeatures.script or "dflt"
+ local function check(what)
+ if what then
+ local foundlanguages = { }
+ for feature, scripts in next, what do
+ if usedscript == "auto" or scripts["*"] then
+ -- ok
+ elseif not scripts[usedscript] then
+ -- report_defining("font %!font:name!, feature %a, no script %a",
+ -- tfmdata,feature,usedscript)
+ else
+ for script, languages in next, scripts do
+ if languages["*"] then
+ -- ok
+ elseif not languages[usedlanguage] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,usedlanguage)
+ end
+ end
+ end
+ for script, languages in next, scripts do
+ for language in next, languages do
+ foundlanguages[language] = true
+ end
+ end
+ end
+ if false then
+ foundlanguages["*"] = nil
+ foundlanguages = sortedkeys(foundlanguages)
+ for feature, scripts in sortedhash(what) do
+ for script, languages in next, scripts do
+ if not languages["*"] then
+ for i=1,#foundlanguages do
+ local language = foundlanguages[i]
+ if not languages[language] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,language)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ check(features.gsub)
+ check(features.gpos)
+ end
+ end
+end
+
function definers.loadfont(specification)
local hash = constructors.hashinstance(specification)
-- todo: also hash by instance / factors
@@ -347,6 +407,7 @@ function definers.loadfont(specification)
checkembedding(tfmdata) -- todo: general postprocessor
loadedfonts[hash] = tfmdata
designsizes[specification.hash] = tfmdata.parameters.designsize
+ checkfeatures(tfmdata)
end
end
if not tfmdata then
@@ -458,7 +519,7 @@ function definers.read(specification,size,id) -- id can be optional, name can al
local parameters = tfmdata.parameters or { }
report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
properties.format or "unknown", id, properties.name, parameters.size, properties.encodingbytes,
- properties.encodingname, properties.fullname, file.basename(properties.filename))
+ properties.encodingname, properties.fullname, basename(properties.filename))
end
statistics.stoptiming(fonts)
return tfmdata
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index 76bc5912d..d2aea7037 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -3024,6 +3024,195 @@ function readers.svg(f,fontdata,specification)
fontdata.hascolor = true
end
+function readers.sbix(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"sbix",specification.glyphs)
+ if tableoffset then
+ local version = readushort(f)
+ local flags = readushort(f)
+ local nofstrikes = readulong(f)
+ local strikes = { }
+ local nofglyphs = fontdata.nofglyphs
+ 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
+ }
+ 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.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
+ -- 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 majorversion = readushort(f)
+-- local minorversion = readushort(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.ebsc(f,fontdata,specification)
+-- if specification.glyphs then
+-- end
+-- end
+
+-- function readers.eblc(f,fontdata,specification)
+-- if specification.glyphs then
+-- end
+-- end
+
-- + AVAR : optional
-- + CFF2 : otf outlines
-- - CVAR : ttf hinting, not needed
diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua
index 68d9ac650..2cb0c1eb7 100644
--- a/tex/context/base/mkiv/font-ocl.lua
+++ b/tex/context/base/mkiv/font-ocl.lua
@@ -10,6 +10,7 @@ if not modules then modules = { } end modules ['font-ocl'] = {
local tostring, next, format = tostring, next, string.format
local round, max = math.round, math.round
+local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash
local formatters = string.formatters
local tounicode = fonts.mappings.tounicode
@@ -175,14 +176,8 @@ fonts.handlers.otf.features.register {
}
}
-local otfsvg = otf.svg or { }
-otf.svg = otfsvg
-otf.svgenabled = true
-
do
- local nofstreams = 0
-
-- local f_setstream = formatters[ [[io.savedata("svg-glyph-%05i",%q)]] ]
-- local f_getstream = formatters[ [[svg-glyph-%05i]] ]
@@ -194,47 +189,125 @@ do
-- end
-- end
- local f_name = formatters[ [[svg-glyph-%05i]] ]
- local f_used = context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
+ local nofstreams = 0
+ local f_name = formatters[ [[pdf-glyph-%05i]] ]
+ local f_used = context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
+ local hashed = { }
+ local cache = { }
+
+ function otf.storepdfdata(pdf)
+ local done = hashed[pdf]
+ if not done then
+ nofstreams = nofstreams + 1
+ local o, n = epdf.openMemStream(pdf,#pdf,f_name(nofstreams))
+ cache[n] = o -- we need to keep in mem
+ done = f_used(n)
+ hashed[pdf] = done
+ end
+ return nil, done, nil
+ end
- local cache = { }
+ -- maybe more efficient but much slower (and we hash already)
+ --
+ -- if context then
+ --
+ -- local storepdfdata = otf.storepdfdata
+ -- local initialized = false
+ --
+ -- function otf.storepdfdata(pdf)
+ -- if not initialized then
+ -- if resolvers.setmemstream then
+ -- local f_setstream = formatters[ [[resolvers.setmemstream("pdf-glyph-%05i",%q,true)]] ]
+ -- local f_getstream = formatters[ [[memstream:///pdf-glyph-%05i]] ]
+ -- local f_nilstream = formatters[ [[resolvers.resetmemstream("pdf-glyph-%05i",true)]] ]
+ -- storepdfdata = function(pdf)
+ -- local done = hashed[pdf]
+ -- local set = nil
+ -- local reset = nil
+ -- if not done then
+ -- nofstreams = nofstreams + 1
+ -- set = f_setstream(nofstreams,pdf)
+ -- done = f_getstream(nofstreams)
+ -- reset = f_nilstream(nofstreams)
+ -- hashed[pdf] = done
+ -- end
+ -- return set, done, reset
+ -- end
+ -- otf.storepdfdata = storepdfdata
+ -- end
+ -- initialized = true
+ -- end
+ -- return storepdfdata(pdf)
+ -- end
+ --
+ -- end
- function otfsvg.storepdfdata(pdf)
- nofstreams = nofstreams + 1
- local o, n = epdf.openMemStream(pdf,#pdf,f_name(nofstreams))
- cache[n] = o -- we need to keep in mem
- return nil, f_used(n), nil
- end
+end
- if context then
-
- local storepdfdata = otfsvg.storepdfdata
- local initialized = false
-
- function otfsvg.storepdfdata(pdf)
- if not initialized then
- if resolvers.setmemstream then
- local f_setstream = formatters[ [[resolvers.setmemstream("svg-glyph-%05i",%q,true)]] ]
- local f_getstream = formatters[ [[memstream:///svg-glyph-%05i]] ]
- local f_nilstream = formatters[ [[resolvers.resetmemstream("svg-glyph-%05i",true)]] ]
- storepdfdata = function(pdf)
- nofstreams = nofstreams + 1
- return
- f_setstream(nofstreams,pdf),
- f_getstream(nofstreams),
- f_nilstream(nofstreams)
- end
- otfsvg.storepdfdata = storepdfdata
+local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg
+ if not tfmdata or not pdfshapes or not kind then
+ return
+ end
+ --
+ local characters = tfmdata.characters
+ local properties = tfmdata.properties
+ local parameters = tfmdata.parameters
+ local hfactor = parameters.hfactor
+ --
+ properties.virtualized = true
+ --
+ tfmdata.fonts = {
+ { id = 0 }
+ }
+ --
+ local getactualtext = otf.getactualtext
+ local storepdfdata = otf.storepdfdata
+ --
+ -- local nop = { "nop" }
+ --
+ for unicode, character in sortedhash(characters) do -- sort is nicer for svg
+ local index = character.index
+ if index then
+ local pdf = pdfshapes[index]
+ local typ = type(pdf)
+ local data = nil
+ local dx = nil
+ local dy = nil
+ if typ == "table" then
+ data = pdf.data
+ dx = pdf.dx or 0
+ dy = pdf.dy or 0
+ elseif typ == "string" then
+ data = pdf
+ dx = 0
+ dy = 0
+ end
+ if data then
+ local setcode, name, nilcode = storepdfdata(data)
+ if name then
+ local bt, et = getactualtext(unicode)
+ local wd = character.width or 0
+ local ht = character.height or 0
+ local dp = character.depth or 0
+ character.commands = {
+ { "special", "pdf:direct:" .. bt },
+ { "down", dp + dy * hfactor },
+ { "right", dx * hfactor },
+ -- setcode and { "lua", setcode } or nop,
+ { "image", { filename = name, width = wd, height = ht, depth = dp } },
+ -- nilcode and { "lua", nilcode } or nop,
+ { "special", "pdf:direct:" .. et },
+ }
+ character[kind] = true
end
- initialized = true
end
- return storepdfdata(pdf)
end
-
end
-
end
+local otfsvg = otf.svg or { }
+otf.svg = otfsvg
+otf.svgenabled = true
do
@@ -323,7 +396,7 @@ do
end
statistics.stoptiming()
if statistics.elapsedseconds then
- report_svg("svg conversion time %s",statistics.elapsedseconds())
+ report_svg("svg conversion time %s",statistics.elapsedseconds() or "-")
end
end
return pdfshapes
@@ -333,17 +406,12 @@ end
local function initializesvg(tfmdata,kind,value) -- hm, always value
if value and otf.svgenabled then
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local properties = tfmdata.properties
- --
- local svg = properties.svg
+ local svg = tfmdata.properties.svg
local hash = svg and svg.hash
local timestamp = svg and svg.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
@@ -355,44 +423,7 @@ local function initializesvg(tfmdata,kind,value) -- hm, always value
timestamp = timestamp,
})
end
- if not pdfshapes or not next(pdfshapes) then
- return
- end
- --
- properties.virtualized = true
- tfmdata.fonts = {
- { id = 0 }
- }
- --
- local getactualtext = otf.getactualtext
- local storepdfdata = otfsvg.storepdfdata
- --
- local nop = { "nop" }
- --
- for unicode, character in next, characters do
- local index = character.index
- if index then
- local pdf = pdfshapes[index]
- if pdf then
- local setcode, name, nilcode = storepdfdata(pdf)
- if name then
- local bt, et = getactualtext(unicode)
- local wd = character.width or 0
- local ht = character.height or 0
- local dp = character.depth or 0
- character.commands = {
- { "special", "pdf:direct:" .. bt },
- { "down", dp },
- setcode and { "lua", setcode } or nop,
- { "image", { filename = name, width = wd, height = ht, depth = dp } },
- nilcode and { "lua", nilcode } or nop,
- { "special", "pdf:direct:" .. et },
- }
- character.svg = true
- end
- end
- end
- end
+ pdftovirtual(tfmdata,pdfshapes,"svg")
end
end
@@ -404,3 +435,114 @@ fonts.handlers.otf.features.register {
node = initializesvg,
}
}
+
+-- 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.
+
+local otfsbix = otf.sbix or { }
+otf.sbix = otfsbix
+otf.sbixenabled = true
+
+do
+
+ -- for now png but also other bitmap formats
+
+ local report_sbix = logs.reporter("fonts","sbix conversion")
+
+ local loaddata = io.loaddata
+ local savedata = io.savedata
+ local remove = os.remove
+
+ local runner = sandbox and sandbox.registerrunner {
+ name = "otfsbix",
+ program = "gm",
+ template = "convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log",
+ -- reporter = report_sbix,
+ }
+
+ if not runner then
+ --
+ -- 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")
+ 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)
+ local pdfshapes = { }
+ local sbixfile = "temp-otf-sbix-shape.sbix"
+ local pdffile = "temp-otf-sbix-shape.pdf"
+ local nofdone = 0
+ local indices = sortedkeys(sbixshapes) -- can be sparse
+ local nofindices = #indices
+ report_sbix("processing %i sbix containers",nofindices)
+ statistics.starttiming()
+ for i=1,nofindices do
+ local index = indices[i]
+ local entry = sbixshapes[index]
+ local data = entry.data
+ local x = entry.x
+ local y = entry.y
+ savedata(sbixfile,data)
+ runner()
+ pdfshapes[index] = {
+ x = x ~= 0 and x or nil,
+ y = y ~= 0 and y or nil,
+ data = loaddata(pdffile),
+ }
+ nofdone = nofdone + 1
+ if nofdone % 100 == 0 then
+ report_sbix("%i shapes processed",nofdone)
+ end
+ end
+ report_sbix("processing %i pdf results",nofindices)
+ remove(sbixfile)
+ remove(pdffile)
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ return pdfshapes
+ -- end
+ end
+
+end
+
+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
+ 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 { }
+ containers.write(otf.pdfcache, hash, {
+ pdfshapes = pdfshapes,
+ timestamp = timestamp,
+ })
+ end
+ --
+ pdftovirtual(tfmdata,pdfshapes,"sbix")
+ end
+end
+
+fonts.handlers.otf.features.register {
+ name = "sbix",
+ description = "sbix glyphs",
+ manipulators = {
+ base = initializesbix,
+ node = initializesbix,
+ }
+}
+
diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua
index bed2adf85..1866591b4 100644
--- a/tex/context/base/mkiv/font-otc.lua
+++ b/tex/context/base/mkiv/font-otc.lua
@@ -10,7 +10,6 @@ local format, insert, sortedkeys, tohash = string.format, table.insert, table.so
local type, next = type, next
local lpegmatch = lpeg.match
local utfbyte, utflen, utfsplit = utf.byte, utf.len, utf.split
-local settings_to_array = utilities.parsers.settings_to_array
-- we assume that the other otf stuff is loaded already
@@ -1040,6 +1039,9 @@ registerotffeature {
description = 'block certain ligatures',
}
+local settings_to_array = utilities.parsers and utilities.parsers.settings_to_array
+ or function(s) return string.split(s,",") end -- for generic
+
local function blockligatures(str)
local t = settings_to_array(str)
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index 9e4e255e3..c0b152a5b 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -53,11 +53,13 @@ local fonts = fonts
local otf = fonts.handlers.otf
otf.version = 3.028 -- 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.pdfcache = containers.define("fonts", "pdf", otf.version, true)
+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.svgenabled = false
+otf.sbixenabled = false
local otfreaders = otf.readers
@@ -127,8 +129,10 @@ function otf.load(filename,sub,instance)
starttiming(otfreaders)
data = otfreaders.loadfont(filename,sub or 1,instance) -- we can pass the number instead (if it comes from a name search)
if data then
- local resources = data.resources
- local svgshapes = resources.svgshapes
+ -- todo: make this a plugin
+ local resources = data.resources
+ local svgshapes = resources.svgshapes
+ local sbixshapes = resources.sbixshapes
if svgshapes then
resources.svgshapes = nil
if otf.svgenabled then
@@ -144,6 +148,22 @@ function otf.load(filename,sub,instance)
}
end
end
+ if sbixshapes then
+ resources.sbixshapes = nil
+ if otf.sbixenabled then
+ local timestamp = os.date()
+ -- work in progress ... a bit boring to do
+ containers.write(otf.sbixcache,hash, {
+ sbixshapes = sbixshapes,
+ timestamp = timestamp,
+ })
+ data.properties.sbix = {
+ hash = hash,
+ timestamp = timestamp,
+ }
+ end
+ end
+ --
otfreaders.compact(data)
otfreaders.rehash(data,"unicodes")
otfreaders.addunicodetable(data)
diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua
index 3935ca735..fcfe6e824 100644
--- a/tex/context/base/mkiv/font-otr.lua
+++ b/tex/context/base/mkiv/font-otr.lua
@@ -133,15 +133,6 @@ end
local tableversion = 0.004
readers.tableversion = tableversion
local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF
-local reportedskipped = { }
-
-
-local function reportskippedtable(tag)
- if not reportedskipped[tag] then
- report("loading of table %a skipped (reported once only)",tag)
- reportedskipped[tag] = true
- end
-end
-- We have quite some data tables. We are somewhat ff compatible with names but as I used
-- the information from the microsoft site there can be differences. Eventually I might end
@@ -720,6 +711,15 @@ local function gotodatatable(f,fontdata,tag,criterium)
end
end
+local function reportskippedtable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local datatable = fontdata.tables[tag]
+ if datatable then
+ report("loading of table %a skipped",tag)
+ end
+ end
+end
+
local function setvariabledata(fontdata,tag,data)
local variabledata = fontdata.variabledata
if variabledata then
@@ -729,8 +729,9 @@ local function setvariabledata(fontdata,tag,data)
end
end
-helpers.gotodatatable = gotodatatable
-helpers.setvariabledata = setvariabledata
+helpers.gotodatatable = gotodatatable
+helpers.setvariabledata = setvariabledata
+helpers.reportskippedtable = reportskippedtable
-- The name table is probably the first one to load. After all this one provides
-- useful information about what we deal with. The complication is that we need
@@ -1181,9 +1182,7 @@ readers.vmtx = function(f,fontdata,specification)
end
readers.vorg = function(f,fontdata,specification)
- if specification.glyphs then
- -- reportskippedtable("vorg")
- end
+ reportskippedtable(f,fontdata,"vorg",specification.glyphs)
end
-- The post table relates to postscript (printing) but has some relevant properties for other
@@ -1254,9 +1253,7 @@ readers.post = function(f,fontdata,specification)
end
readers.cff = function(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("cff")
- end
+ reportskippedtable(f,fontdata,"cff",specification.glyphs)
end
-- Not all cmaps make sense .. e.g. dfont is obsolete and probably more are not relevant. Let's see
@@ -1745,35 +1742,55 @@ end
-- although we not need it in our usage (yet). We can remove the locations table when we're done.
function readers.loca(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("loca")
- end
+ reportskippedtable(f,fontdata,"loca",specification.glyphs)
end
function readers.glyf(f,fontdata,specification) -- part goes to cff module
- if specification.glyphs then
- reportskippedtable("glyf")
- end
+ reportskippedtable(f,fontdata,"glyf",specification.glyphs)
end
--- Experimental (we need fonts).
+-- The MicroSoft variant is pretty clean and is supported (implemented elsewhere)
+-- just because I wanted to see how such a font looks like.
function readers.colr(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("colr")
- end
+ reportskippedtable(f,fontdata,"colr",specification.glyphs)
end
-
function readers.cpal(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("cpal")
- end
+ reportskippedtable(f,fontdata,"cpal",specification.glyphs)
end
+-- This one is also supported, if only because I could locate a proper font for
+-- testing.
+
function readers.svg(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("svg")
- end
+ reportskippedtable(f,fontdata,"svg",specification.glyphs)
+end
+
+-- There is a font from apple to test the next one. Will there be more? Anyhow,
+-- it's relatively easy to support, so I did it.
+
+function readers.sbix(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"sbix",specification.glyphs)
+end
+
+-- I'm only willing to look into the next variant if I see a decent and complete (!)
+-- font and more can show up. It makes no sense to waste time on ideas. Okay, the
+-- apple font also has these tables.
+
+function readers.cbdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
+end
+function readers.cblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cblc",specification.glyphs)
+end
+function readers.ebdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
+end
+function readers.ebsc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
+end
+function readers.eblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"eblc",specification.glyphs)
end
-- Here we have a table that we really need for later processing although a more advanced gpos table
@@ -1819,27 +1836,19 @@ function readers.kern(f,fontdata,specification)
end
function readers.gdef(f,fontdata,specification)
- if specification.details then
- reportskippedtable("gdef")
- end
+ reportskippedtable(f,fontdata,"gdef",specification.details)
end
function readers.gsub(f,fontdata,specification)
- if specification.details then
- reportskippedtable("gsub")
- end
+ reportskippedtable(f,fontdata,"gsub",specification.details)
end
function readers.gpos(f,fontdata,specification)
- if specification.details then
- reportskippedtable("gpos")
- end
+ reportskippedtable(f,fontdata,"gpos",specification.details)
end
function readers.math(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("math")
- end
+ reportskippedtable(f,fontdata,"math",specification.details)
end
-- Now comes the loader. The order of reading these matters as we need to know
@@ -2109,8 +2118,16 @@ local function readdata(f,offset,specification)
readtable("colr",f,fontdata,specification)
readtable("cpal",f,fontdata,specification)
+
readtable("svg" ,f,fontdata,specification)
+ readtable("sbix",f,fontdata,specification)
+
+ readtable("cbdt",f,fontdata,specification)
+ readtable("cblc",f,fontdata,specification)
+ readtable("ebdt",f,fontdata,specification)
+ readtable("eblc",f,fontdata,specification)
+
readtable("kern",f,fontdata,specification)
readtable("gsub",f,fontdata,specification)
readtable("gpos",f,fontdata,specification)
@@ -2321,6 +2338,7 @@ function readers.loadfont(filename,n,instance)
mathconstants = fontdata.mathconstants,
colorpalettes = fontdata.colorpalettes,
svgshapes = fontdata.svgshapes,
+ sbixshapes = fontdata.sbixshapes,
variabledata = fontdata.variabledata,
foundtables = fontdata.foundtables,
},
diff --git a/tex/context/base/mkiv/l-pdfview.lua b/tex/context/base/mkiv/l-pdfview.lua
index 6302fd6f6..d2add9188 100644
--- a/tex/context/base/mkiv/l-pdfview.lua
+++ b/tex/context/base/mkiv/l-pdfview.lua
@@ -44,7 +44,7 @@ if os.type == "windows" then
['okular'] = [[start "test" okular.exe --unique "%filename%"]],
['pdfxcview'] = [[start "test" pdfxcview.exe /A "nolock=yes=OpenParameters" "%filename%"]],
['sumatra'] = [[start "test" sumatrapdf.exe -reuse-instance -bg-color 0xCCCCCC "%filename%"]],
- ['auto'] = [[start "%filename%"]],
+ ['auto'] = [[start "" "%filename%"]],
}
closecalls= {
['default'] = [[pdfclose --file "%filename%"]],
@@ -91,7 +91,7 @@ else
['okular'] = [[okular --unique "%filename%"]],
['sumatra'] = [[wine "sumatrapdf.exe" -reuse-instance -bg-color 0xCCCCCC "%filename%"]],
['pdfxcview'] = [[wine "pdfxcview.exe" /A "nolock=yes=OpenParameters" "%filename%"]],
- ['auto'] = [[open "%filename%"]],
+ ['auto'] = [[open "%filename%"]], -- linux: xdg-open
}
closecalls= {
['default'] = [[pdfclose --file "%filename%"]],
diff --git a/tex/context/base/mkiv/lang-ini.lua b/tex/context/base/mkiv/lang-ini.lua
index 62786d9ab..6de951998 100644
--- a/tex/context/base/mkiv/lang-ini.lua
+++ b/tex/context/base/mkiv/lang-ini.lua
@@ -46,6 +46,7 @@ local postexhyphenchar = lang.postexhyphenchar -- global per language
local sethjcode = lang.sethjcode
local uccodes = characters.uccodes
+local lccodes = characters.lccodes
lang.exceptions = lang.hyphenation
local new_langage = lang.new
@@ -159,7 +160,7 @@ local function sethjcodes(instance,loaded,what,factor)
--
local function setcode(l)
local u = uccodes[l]
- local s = 1
+ local s = l
if hjcounts then
local c = hjcounts[l]
if c then
@@ -182,7 +183,7 @@ local function sethjcodes(instance,loaded,what,factor)
h[l] = s
if u ~= l and type(u) == "number" then
sethjcode(instance,u,s)
- h[u] = s
+ h[u] = lccodes[l]
end
end
--
diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua
index d0f894292..372bbcbfa 100644
--- a/tex/context/base/mkiv/luat-run.lua
+++ b/tex/context/base/mkiv/luat-run.lua
@@ -23,6 +23,10 @@ local report_tempfiles = logs.reporter("resolvers","tempfiles")
luatex = luatex or { }
local luatex = luatex
+if not luatex.synctex then
+ luatex.synctex = table.setmetatableindex(function() return function() end end)
+end
+
local startactions = { }
local stopactions = { }
local dumpactions = { }
@@ -68,6 +72,7 @@ local function stop_shipout_page()
for i=1,#pageactions do
pageactions[i]()
end
+ luatex.synctex.flush()
end
local function report_output_pages()
@@ -142,27 +147,6 @@ end
luatex.registerstopactions(luatex.cleanuptempfiles)
--- for the moment here
-
-local report_system = logs.reporter("system")
-local synctex = 0
-
-directives.register("system.synctex", function(v)
- synctex = tonumber(v) or (toboolean(v,true) and 1) or (v == "zipped" and 1) or (v == "unzipped" and -1) or 0
- if synctex ~= 0 then
- report_system("synctex functionality is enabled (%s), expect runtime overhead!",tostring(synctex))
- else
- report_system("synctex functionality is disabled!")
- end
- tex.normalsynctex = synctex
-end)
-
-statistics.register("synctex tracing",function()
- if synctex ~= 0 then
- return "synctex has been enabled (extra log file generated)"
- end
-end)
-
-- filenames
local types = {
@@ -184,6 +168,10 @@ local total = 0
local stack = { }
local all = false
+function luatex.currentfile()
+ return stack[#stack] or tex.jobname
+end
+
local function report_start(left,name)
if not left then
-- skip
@@ -200,6 +188,7 @@ local function report_start(left,name)
level = level + 1
-- report_open("%i > %i > %s",level,total,name or "?")
report_open("level %i, order %i, name %a",level,total,name or "?")
+ luatex.synctex.setfilename(name)
end
end
diff --git a/tex/context/base/mkiv/lxml-aux.lua b/tex/context/base/mkiv/lxml-aux.lua
index 9a829795d..ee0909cbf 100644
--- a/tex/context/base/mkiv/lxml-aux.lua
+++ b/tex/context/base/mkiv/lxml-aux.lua
@@ -762,7 +762,7 @@ local obsolete = xml.obsolete
xml.strip_whitespace = xml.strip obsolete.strip_whitespace = xml.strip
xml.collect_elements = xml.collect obsolete.collect_elements = xml.collect
xml.delete_element = xml.delete obsolete.delete_element = xml.delete
-xml.replace_element = xml.replace obsolete.replace_element = xml.replacet
+xml.replace_element = xml.replace obsolete.replace_element = xml.replace
xml.each_element = xml.each obsolete.each_element = xml.each
xml.process_elements = xml.process obsolete.process_elements = xml.process
xml.insert_element_after = xml.insertafter obsolete.insert_element_after = xml.insertafter
diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua
index ed3c06c28..b23709ff0 100644
--- a/tex/context/base/mkiv/node-nut.lua
+++ b/tex/context/base/mkiv/node-nut.lua
@@ -853,3 +853,11 @@ function nuts.copy_properties(source,target,what)
end
return newprops -- for checking
end
+
+-- here:
+
+nodes.set_synctex_line = node.set_synctex_line
+nodes.set_synctex_tag = node.set_synctex_tag
+
+nuts.get_synctex_fields = direct.get_synctex_fields
+nuts.set_synctex_fields = direct.set_synctex_fields
diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua
new file mode 100644
index 000000000..31243cd60
--- /dev/null
+++ b/tex/context/base/mkiv/node-syn.lua
@@ -0,0 +1,501 @@
+if not modules then modules = { } end modules ['node-syn'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Because we have these fields in some node that are used by sunctex, I decided (because
+-- some users seem to like that feature) to implement a variant that might work out better
+-- for ConTeXt. This is experimental code. I don't use it myself so it will take a while
+-- to mature. There will be some helpers that one can use in more complex situations like
+-- included xml files.
+--
+-- It is unclear how the output gets interpreted. For instance, we only need to be able to
+-- go back to a place where text is entered, but still we need all that redundant box
+-- wrapping.
+--
+-- Possible optimizations: pack whole lines.
+
+local type, rawset = type, rawset
+local concat = table.concat
+local formatters = string.formatters
+
+local trace = false trackers.register("system.syntex.visualize", function(v) trace = v end)
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+
+local getid = nuts.getid
+local getlist = nuts.getlist
+local setlist = nuts.setlist
+local getnext = nuts.getnext
+local getwhd = nuts.getwhd
+local getwidth = nuts.getwidth
+local getsubtype = nuts.getsubtype
+local getattr = nuts.getattr
+
+local nodecodes = nodes.nodecodes
+local kerncodes = nodes.kerncodes
+
+local glue_code = nodecodes.glue
+local kern_code = nodecodes.kern
+local kern_disc = nodecodes.disc
+local rule_code = nodecodes.rule
+----- math_code = nodecodes.math
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
+local fontkern_code = kerncodes.fontkern
+
+local insert_before = nuts.insert_before
+local insert_after = nuts.insert_after
+
+local nodepool = nuts.pool
+local new_latelua = nodepool.latelua
+local new_rule = nodepool.rule
+local new_hlist = nodepool.hlist
+
+local getdimensions = nuts.dimensions
+local getrangedimensions = nuts.rangedimensions
+
+local a_fontkern = attributes.private("fontkern")
+
+local get_synctex_fields = nuts.get_synctex_fields
+local set_synctex_fields = nuts.set_synctex_fields
+local set_syntex_tag = nodes.set_synctex_tag
+
+local getpos = function()
+ getpos = backends.codeinjections.getpos
+ return getpos()
+ end
+
+local f_glue = formatters["g%i,%i:%i,%i"]
+local f_glyph = formatters["x%i,%i:%i,%i"]
+local f_kern = formatters["k%i,%i:%i,%i:%i"]
+local f_rule = formatters["r%i,%i:%i,%i:%i,%i,%i"]
+local f_hlist = formatters["[%i,%i:%i,%i:%i,%i,%i"]
+local f_vlist = formatters["(%i,%i:%i,%i:%i,%i,%i"]
+local s_hlist = "]"
+local s_vlist = ")"
+local f_hvoid = formatters["h%i,%i:%i,%i:%i,%i,%i"]
+local f_vvoid = formatters["v%i,%i:%i,%i:%i,%i,%i"]
+
+local characters = fonts.hashes.characters
+
+local synctex = { }
+luatex.synctex = synctex
+
+-- the file name stuff
+
+local noftags = 0
+local stnums = { }
+local sttags = table.setmetatableindex(function(t,name)
+ noftags = noftags + 1
+ t[name] = noftags
+ stnums[noftags] = name
+ return noftags
+end)
+
+function synctex.setfilename(name)
+ if set_syntex_tag and name then
+ set_syntex_tag(sttags[name])
+ end
+end
+
+function synctex.resetfilename()
+ if set_syntex_tag then
+ local name = luatex.currentfile()
+ if name then
+ set_syntex_tag(name)
+ end
+ end
+end
+
+-- the node stuff
+
+local result = { }
+local r = 0
+local f = nil
+local nofsheets = 0
+local nofobjects = 0
+local last = 0
+local filesdone = 0
+local enabled = false
+local compact = true
+
+local function writeanchor()
+ local size = f:seek("end")
+ f:write("!" .. (size-last) .. "\n")
+ last = size
+end
+
+local function writefiles()
+ local total = #stnums
+ if filesdone < total then
+ for i=filesdone+1,total do
+ f:write("Input:"..i..":"..stnums[i].."\n")
+ end
+ filesdone = total
+ end
+end
+
+local function flushpreamble()
+ local jobname = tex.jobname
+ stnums[0] = jobname
+ f = io.open(file.replacesuffix(jobname,"syncctx"),"w")
+ f:write("SyncTeX Version:1\n")
+ f:write("Input:0:"..jobname.."\n")
+ writefiles()
+ f:write("Output:pdf\n")
+ f:write("Magnification:1000\n")
+ f:write("Unit:1\n")
+ f:write("X Offset:0\n")
+ f:write("Y Offset:0\n")
+ f:write("Content:\n")
+ flushpreamble = writefiles
+end
+
+local function flushpostamble()
+ writeanchor()
+ f:write("Postamble:\n")
+ f:write("Count:"..nofobjects.."\n")
+ writeanchor()
+ f:write("Post scriptum:\n")
+ f:close()
+ enabled = false
+end
+
+local pageheight = 0 -- todo: set before we do this!
+
+local function b_hlist(head,current,t,l,w,h,d)
+ return insert_before(head,current,new_latelua(function()
+ local x, y = getpos()
+ r = r + 1
+ result[r] = f_hlist(t,l,x,tex.pageheight-y,w,h,d)
+ nofobjects = nofobjects + 1
+ end))
+end
+
+local function b_vlist(head,current,t,l,w,h,d)
+ return insert_before(head,current,new_latelua(function()
+ local x, y = getpos()
+ r = r + 1
+ result[r] = f_vlist(t,l,x,tex.pageheight-y,w,h,d)
+ nofobjects = nofobjects + 1
+ end))
+end
+
+local function e_hlist(head,current)
+ return insert_after(head,current,new_latelua(function()
+ r = r + 1
+ result[r] = s_hlist
+ nofobjects = nofobjects + 1
+ end))
+end
+
+local function e_vlist(head,current)
+ return insert_after(head,current,new_latelua(function()
+ r = r + 1
+ result[r] = s_vlist
+ nofobjects = nofobjects + 1
+ end))
+end
+
+local function x_hlist(head,current,t,l,w,h,d)
+ return insert_before(head,current,new_latelua(function()
+ local x, y = getpos()
+ r = r + 1
+ result[r] = f_hvoid(t,l,x,tex.pageheight-y,w,h,d)
+ nofobjects = nofobjects + 1
+ end))
+end
+
+local function x_vlist(head,current,t,l,w,h,d)
+ return insert_before(head,current,new_latelua(function()
+ local x, y = getpos()
+ r = r + 1
+ result[r] = f_vvoid(t,l,x,tex.pageheight-y,w,h,d)
+ nofobjects = nofobjects + 1
+ end))
+end
+
+-- local function x_glyph(head,current,t,l)
+-- return insert_before(head,current,new_latelua(function()
+-- local x, y = getpos()
+-- r = r + 1
+-- result[r] = f_glyph(t,l,x,tex.pageheight-y)
+-- nofobjects = nofobjects + 1
+-- end))
+-- end
+
+-- local function x_glue(head,current,t,l)
+-- return insert_before(head,current,new_latelua(function()
+-- local x, y = getpos()
+-- r = r + 1
+-- result[r] = f_glue(t,l,x,tex.pageheight-y)
+-- nofobjects = nofobjects + 1
+-- end))
+-- end
+
+-- local function x_kern(head,current,t,l,k)
+-- return insert_before(head,current,new_latelua(function()
+-- local x, y = getpos()
+-- r = r + 1
+-- result[r] = f_kern(t,l,x,tex.pageheight-y,k)
+-- nofobjects = nofobjects + 1
+-- end))
+-- end
+
+-- local function x_rule(head,current,t,l,w,h,d)
+-- return insert_before(head,current,new_latelua(function()
+-- local x, y = getpos()
+-- r = r + 1
+-- result[r] = f_rule(t,l,x,tex.pageheight-y,w,h,d)
+-- nofobjects = nofobjects + 1
+-- end))
+-- end
+
+local function collect(head,t,l)
+ local current = head
+ while current do
+ local id = getid(current)
+ if id == glyph_code then
+ local first = current
+ local last = current
+ while true do
+ id = getid(current)
+ if id == glyph_code or id == disc_code then
+ last = current
+ elseif id == kern_code and (getsubtype(current) == fontkern_code or getattr(current,a_fontkern)) then
+ last = current
+ else
+ if id == glue_code then
+ -- we could go on when we're in the same t/l run
+ local tc, lc = get_synctex_fields(current)
+ if tc > 0 then
+ t, l = tc, lc
+ end
+ id = nil -- so no test later on
+ end
+ local w, h, d = getdimensions(first,getnext(last))
+ -- local w, h, d = getrangedimensions(head,first,getnext(last))
+ if trace then
+ -- color is already handled so no colors
+ head = insert_before(head,first,new_hlist(new_rule(w,32768,32768)))
+ end
+if h < 655360 then
+ h = 655360
+end
+if d < 327680 then
+ d = 327680
+end
+ head = x_hlist(head,first,t,l,w,h,d)
+ break
+ end
+ current = getnext(current)
+ if not current then
+ local w, h, d = getdimensions(first,getnext(last))
+ -- local w, h, d = getrangedimensions(head,first,getnext(last))
+ if trace then
+ -- color is already handled so no colors
+ head = insert_before(head,first,new_hlist(new_rule(w,32768,32768)))
+ end
+if h < 655360 then
+ h = 655360
+end
+if d < 327680 then
+ d = 327680
+end
+ head = x_hlist(head,first,t,l,w,h,d)
+ return head
+ end
+ end
+ end
+ if id == hlist_code then
+ local list = getlist(current)
+ local tc, lc = get_synctex_fields(current)
+ if tc > 0 then
+ t, l = tc, lc
+ end
+ if compact then
+ if list then
+ local l = collect(list,t,l)
+ if l ~= list then
+ setlist(current,l)
+ end
+ end
+ else
+ local w, h, d = getwhd(current)
+ if w == 0 or (h == 0 and d == 0) then
+ if list then
+ local l = collect(list,t,l)
+ if l ~= list then
+ setlist(current,l)
+ end
+ end
+ elseif list then
+ -- head = b_hlist(head,current,t,l,w,h,d)
+ head = b_hlist(head,current,0,0,w,h,d)
+ local l = collect(list,t,l)
+ if l ~= list then
+ setlist(current,l)
+ end
+ head, current = e_hlist(head,current)
+ else
+ -- head = x_hlist(head,current,t,l,w,h,d)
+ head = x_hlist(head,current,0,0,w,h,d)
+ end
+ end
+ elseif id == vlist_code then
+ local list = getlist(current)
+ local tc, lc = get_synctex_fields(current)
+ if tc > 0 then
+ t, l = tc, lc
+ end
+ if compact then
+ if list then
+ local l = collect(list,t,l)
+ if l ~= list then
+ setlist(current,l)
+ end
+ end
+ else
+ local w, h, d = getwhd(current)
+ if w == 0 or (h == 0 and d == 0) then
+ if list then
+ local l = collect(list,t,l)
+ if l ~= list then
+ setlist(current,l)
+ end
+ end
+ elseif list then
+ -- head = b_vlist(head,current,t,l,w,h,d)
+ head = b_vlist(head,current,0,0,w,h,d)
+ local l = collect(list,t,l)
+ if l ~= list then
+ setlist(current,l)
+ end
+ head, current = e_vlist(head,current)
+ else
+ -- head = x_vlist(head,current,t,l,w,h,d)
+ head = x_vlist(head,current,0,0,w,h,d)
+ end
+ end
+ elseif id == glue_code then
+ local tc, lc = get_synctex_fields(current)
+ if tc > 0 then
+ t, l = tc, lc
+ end
+ -- head = x_glue(head,current,t,l)
+ -- elseif id == kern_code then
+ -- local tc, lc = get_synctex_fields(current)
+ -- if tc > 0 then
+ -- t, l = tc, lc
+ -- end
+ -- -- local k = getwidth(current)
+ -- -- if k ~= 0 then
+ -- -- head = x_kern(head,current,t,l,k)
+ -- -- end
+ -- elseif id == rule_code then
+ -- local tc, lc = get_synctex_fields(current)
+ -- if tc > 0 then
+ -- t, l = tc, lc
+ -- end
+ -- -- if t > 0 and l > 0 then
+ -- -- local w, h, d = getwhd(current)
+ -- -- head = x_rule(head,current,t,l,w,h,d)
+ -- -- end
+ end
+ current = getnext(current)
+ end
+ return head
+end
+
+-- range of same numbers
+
+function synctex.collect(head)
+ if enabled then
+ result, r = { }, 0
+ head = collect(tonut(head),0,0)
+ return tonode(head), true
+ else
+ return head, false
+ end
+end
+
+-- also no solution for bad first file resolving in sumatra
+
+function synctex.flush()
+ if enabled then
+ nofsheets = nofsheets + 1 -- could be realpageno
+ flushpreamble()
+ writeanchor()
+ f:write("{"..nofsheets.."\n")
+ if compact then
+ f:write(f_vlist(0,0,0,0,tex.pagewidth,tex.pageheight,0))
+ f:write("\n")
+ end
+ f:write(concat(result,"\n"))
+ if compact then
+ f:write("\n")
+ f:write(s_vlist)
+ end
+ f:write("\n")
+ writeanchor()
+ f:write("}"..nofsheets.."\n")
+ nofobjects = nofobjects + 2
+ result, r = { }, 0
+ end
+end
+
+function synctex.enable()
+ if not enabled and node.set_synctex_mode then
+ enabled = true
+ node.set_synctex_mode(1)
+ tex.normalsynctex = 0
+ nodes.tasks.appendaction("shipouts", "after", "nodes.synctex.collect")
+ end
+end
+
+function synctex.finish()
+ if enabled then
+ flushpostamble()
+ end
+end
+
+-- not the best place
+
+luatex.registerstopactions(synctex.finish)
+
+nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect")
+
+-- moved here
+
+local report_system = logs.reporter("system")
+local synctex = false
+
+directives.register("system.synctex", function(v)
+ if v == "context" then
+ luatex.synctex.enable()
+ tex.normalsynctex = 0
+ synctex = true
+ else
+ v = tonumber(v) or (toboolean(v,true) and 1) or (v == "zipped" and 1) or (v == "unzipped" and -1) or 0
+ tex.normalsynctex = v
+ synctex = v ~= 0
+ end
+ if synctex then
+ report_system("synctex functionality is enabled (%s), expect runtime overhead!",tostring(v))
+ else
+ report_system("synctex functionality is disabled!")
+ end
+end)
+
+statistics.register("synctex tracing",function()
+ if synctex or tex.normalsynctex ~= 0 then
+ return "synctex has been enabled (extra log file generated)"
+ end
+end)
diff --git a/tex/context/base/mkiv/pack-rul.mkiv b/tex/context/base/mkiv/pack-rul.mkiv
index ff39200b8..eec7b8cb3 100644
--- a/tex/context/base/mkiv/pack-rul.mkiv
+++ b/tex/context/base/mkiv/pack-rul.mkiv
@@ -941,7 +941,9 @@
\def\pack_framed_start_framed_nop_indeed[#1]%
{\pack_framed_initialize
\bgroup
- \setupcurrentframed[#1]% here !
+ \iffirstargument
+ \setupcurrentframed[#1]% here !
+ \fi
\pack_framed_process_indeed
\bgroup
\ignorespaces}
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 32aee579a..94d382b63 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index ba8f9d5b7..c66f8765b 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/tabl-frm.mkiv b/tex/context/base/mkiv/tabl-frm.mkiv
new file mode 100644
index 000000000..639d6f06d
--- /dev/null
+++ b/tex/context/base/mkiv/tabl-frm.mkiv
@@ -0,0 +1,209 @@
+%D \module
+%D [ file=tabl-frm,
+%D version=2017.04.11,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Framed Tables,
+%D author=Hans Hagen,
+%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.
+
+%D For Thomas Schmitz who needed 3000 pages long tables.
+
+\unprotect
+
+\writestatus{loading}{ConTeXt Table Macros / Framed Tables}
+
+\installcorenamespace{framedtable}
+\installcorenamespace{framedtablerow}
+\installcorenamespace{framedtablecolumn}
+
+\newcount\c_tabl_framed_c
+\newcount\c_tabl_framed_r
+\newdimen\d_tabl_framed_h
+\newdimen\d_tabl_framed_d
+\newdimen\b_tabl_framed
+
+\initializeboxstack\??framedtable
+
+\defineframed[\??framedtable]
+\defineframed[\??framedtablerow][\??framedtable]
+\defineframed[\??framedtablecolumn][\??framedtable]
+
+\setupframed
+ [\??framedtable]
+ [\c!distance=\zeropoint,
+ \c!before=,
+ \c!after=,
+ \c!inbetween=]
+
+\setupframed
+ [\??framedtablerow]
+ [\c!strut=\v!no,
+ \c!offset=\v!overlay]
+
+% \defineframedtable[foo]
+% \defineframedtable[bar][foo]
+
+\unexpanded\def\defineframedtable
+ {\dodoubleempty\tabl_framed_define}
+
+\def\tabl_framed_define[#1][#2]%
+ {\ifsecondargument
+ \defineframed[\??framedtable#1][\??framedtable#2]%
+ \else\iffirstargument
+ \defineframed[\??framedtable#1][\??framedtable]%
+ \fi\fi}
+
+% \setupframedtable[foo][...]
+
+\unexpanded\def\setupframedtable
+ {\dodoubleempty\tabl_framed_setup}
+
+\def\tabl_framed_setup[#1][#2]%
+ {\ifsecondargument
+ \ifcsname\??framed:\??framedtable#1\endcsname \else
+ \defineframed[\??framedtable#1][\??framedtable]%
+ \fi
+ \setupframed[\??framedtable#1][#2]%
+ \else
+ \setupframed[\??framedtable][#1]%
+ \fi}
+
+% \setupframedtable[1][...]
+% \setupframedtable[foo][1][...]
+
+\unexpanded\def\setupframedtablerow
+ {\dotripleempty\tabl_framed_setup_row}
+
+\def\tabl_framed_setup_row[#1][#2][#3]%
+ {\ifthirdargument
+ \ifcsname\??framed:\??framedtable#1\endcsname \else
+ \defineframed[\??framedtable#1][\??framedtable]%
+ \fi
+ \ifcsname\??framed:\??framedtablerow#1:#2\endcsname \else
+ \defineframed[\??framedtablerow#1:#2][\??framedtable#1]%
+ \fi
+ \setupframed[\??framedtablerow#1:#2][#3]%
+ \else\ifsecondargument
+ \ifcsname\??framed:\??framedtablerow:#1\endcsname \else
+ \defineframed[\??framedtablerow:#1][\??framedtable]%
+ \fi
+ \setupframed[\??framedtablerow:#1][#2]%
+ \fi\fi}
+
+\unexpanded\def\setupframedtablecolumn
+ {\dotripleempty\tabl_framed_setup_column}
+
+\def\tabl_framed_setup_column[#1][#2][#3]%
+ {\ifthirdargument
+ \ifcsname\??framed:\??framedtable#1\endcsname \else
+ \defineframed[\??framedtable#1][\??framedtable]%
+ \fi
+ \ifcsname\??framed:\??framedtablecolumn#1:#2\endcsname \else
+ \defineframed[\??framedtablecolumn#1:#2][\??framedtable#1]%
+ \fi
+ \setupframed[\??framedtablecolumn#1:#2][#3]%
+ \else\ifsecondargument
+ \ifcsname\??framed:\??framedtablecolumn:#1\endcsname \else
+ \defineframed[\??framedtablecolumn:#1][\??framedtable]%
+ \fi
+ \setupframed[\??framedtablecolumn:#1][#2]%
+ \fi\fi}
+
+\unexpanded\def\startframedtable
+ {\dodoubleempty\tabl_framed_start}
+
+\unexpanded\def\tabl_framed_start[#1][#2]%
+ {\begingroup
+ \forgetall
+ \doifelseassignment{#1}%
+ {\let\currentframedtable\empty
+ \setupframed[\??framedtable][#1]}%
+ {\edef\currentframedtable{#1}%
+ \setupframed[\??framedtable][#2]}%
+ \edef\currentframed{\??framedtable\currentframedtable}%
+ \c_tabl_framed_r\zerocount
+ \d_tabl_framed_d\framedparameter\c!distance
+ \framedparameter\c!before}
+
+\unexpanded\def\stopframedtable
+ {\framedparameter\c!after
+ \endgroup}
+
+\unexpanded\def\startframedrow
+ {\advance\c_tabl_framed_r\plusone
+ \c_tabl_framed_c\zerocount
+ \d_tabl_framed_h\zeropoint
+ \bgroup
+ \edef\currentframed{\number\c_tabl_framed_r}%
+ \edef\currentframed
+ {\??framedtablerow\currentframedtable
+ \ifcsname\??framedtablerow\currentframedtable:\currentframed\endcsname
+ :\currentframed
+ \else\ifcsname\??framedtablerow\currentframedtable:\v!each\endcsname
+ :\v!each
+ \fi\fi}%
+ \dosingleempty\pack_framed_start_framed_nop_indeed}
+
+\unexpanded\def\stopframedrow
+ {\dofastloopcs\c_tabl_framed_c\tabl_framed_flush_row
+ \stopframed
+ \nointerlineskip
+ \vskip\zeropoint\relax
+ \framedparameter\c!inbetween}
+
+\unexpanded\def\tabl_framed_flush_row
+ {\vpack to \d_tabl_framed_h{\flushbox\??framedtable{\number\fastloopindex}\vfill}%
+ \ifdim\d_tabl_framed_d=\zeropoint\else\kern\d_tabl_framed_d\fi}
+
+\unexpanded\def\startframedcell
+ {\advance\c_tabl_framed_c\plusone
+ \setbox\b_tabl_framed\hpack\bgroup
+ %\bgroup
+ \edef\currentframed{\number\c_tabl_framed_c}%
+ \edef\currentframed
+ {\??framedtablecolumn\currentframedtable
+ \ifcsname\??framedtablecolumn\currentframedtable:\currentframed\endcsname
+ :\currentframed
+ \else\ifcsname\??framedtablecolumn\currentframedtable:\v!each\endcsname
+ :\v!each
+ \fi\fi}%
+ \dosingleempty\pack_framed_start_framed_nop_indeed}
+
+\unexpanded\def\stopframedcell
+ {\stopframed
+ %\egroup
+ \ifdim\ht\b_tabl_framed>\d_tabl_framed_h
+ \d_tabl_framed_h\ht\b_tabl_framed
+ \fi
+ \savebox\??framedtable{\number\c_tabl_framed_c}{\box\b_tabl_framed}}
+
+\protect \endinput
+
+\starttext
+
+\setupframedtablecolumn [1] [width=3cm,background=color,backgroundcolor=red]
+\setupframedtablecolumn [2] [width=4cm,background=color,backgroundcolor=green,align=normal]
+% \setupframedtablerow [each] [background=color,backgroundcolor=blue,strut=no]
+% \setupframedtablerow [each] [strut=no,offset=overlay]
+
+\startframedtable[inbetween=\kern-0.4pt,distance=-0.4pt]
+
+\testfeatureonce{10000}{
+% \testfeatureonce{10}{
+ \startframedrow
+ \startframedcell%[backgroundcolor=yellow]
+ test
+ \stopframedcell
+ \startframedcell
+ test \par test
+ \stopframedcell
+ \stopframedrow
+}
+\stopframedtable
+
+\stoptext
diff --git a/tex/context/base/mkiv/tabl-ltb.mkiv b/tex/context/base/mkiv/tabl-ltb.mkiv
index b0e3f52e4..3147fa1cc 100644
--- a/tex/context/base/mkiv/tabl-ltb.mkiv
+++ b/tex/context/base/mkiv/tabl-ltb.mkiv
@@ -474,7 +474,8 @@
\ifconditional\c_tabl_lines_preroll \else
\box\b_tabl_lines_cell
% the columncounter is one ahead !
- \dorecurse\c_tabl_lines_step{\strut\hfil}%
+% \dorecurse\c_tabl_lines_step{\strut\hfil}%
+\strut
\hskip\scratchskip
\fi
\fi}
diff --git a/tex/context/base/mkiv/typo-bld.lua b/tex/context/base/mkiv/typo-bld.lua
index 04cc4db8d..153218eef 100644
--- a/tex/context/base/mkiv/typo-bld.lua
+++ b/tex/context/base/mkiv/typo-bld.lua
@@ -37,6 +37,7 @@ local texnest = tex.nest
local texlists = tex.lists
local nodes = nodes
+local nodeidstostring = nodes.idstostring
local nodepool = nodes.pool
local new_baselineskip = nodepool.baselineskip
local new_lineskip = nodepool.lineskip
diff --git a/tex/context/base/mkiv/util-sci.lua b/tex/context/base/mkiv/util-sci.lua
index 33e520719..e028d2f95 100644
--- a/tex/context/base/mkiv/util-sci.lua
+++ b/tex/context/base/mkiv/util-sci.lua
@@ -17,7 +17,20 @@ utilities.scite = scite
local report = logs.reporter("scite")
-local lexerroot = file.dirname(resolvers.find_file("scite-context-lexer.lua"))
+do
+ local lexerroot = "c:/data/system/scite/wscite/context/lexers"
+ if not lexerroot then
+ lexerroot = file.dirname(resolvers.find_file("scite-context-lexer.lua"))
+ end
+ if lfs.isdir(lexerroot) then
+ package.extraluapath(lexerroot)
+ package.extraluapath(lexerroot.."/themes")
+ package.extraluapath(lexerroot.."/data")
+ report("using lexer root %a",lexerroot)
+ else
+ report("no valid lexer root")
+ end
+end
local knownlexers = {
tex = "tex", mkiv = "tex", mkvi = "tex", mkxi = "tex", mkix = "tex", mkii = "tex", cld = "tex",
@@ -35,20 +48,16 @@ lexer = nil -- main lexer, global (for the moment needed for themes)
local function loadscitelexer()
if not lexer then
- dir.push(lexerroot)
- lexer = dofile("scite-context-lexer.lua")
- dofile("themes/scite-context-theme.lua")
- dir.pop()
+ lexer = require("scite-context-lexer")
+ require("scite-context-theme") -- uses lexer
end
return lexer
end
local loadedlexers = setmetatableindex(function(t,k)
local l = knownlexers[k] or k
- dir.push(lexerroot)
loadscitelexer()
local v = lexer.load(formatters["scite-context-lexer-%s"](l))
- dir.pop()
t[l] = v
t[k] = v
return v
@@ -58,8 +67,8 @@ scite.loadedlexers = loadedlexers
scite.knownlexers = knownlexers
scite.loadscitelexer = loadscitelexer
-local f_fore_bold = formatters['.%s { display: inline ; font-weight: bold ; color: #%s%s%s ; }']
-local f_fore_none = formatters['.%s { display: inline ; font-weight: normal ; color: #%s%s%s ; }']
+local f_fore_bold = formatters['.%s { display: inline ; font-weight: bold ; color: #%02X%02X%02X ; }']
+local f_fore_none = formatters['.%s { display: inline ; font-weight: normal ; color: #%02X%02X%02X ; }']
local f_none_bold = formatters['.%s { display: inline ; font-weight: bold ; }']
local f_none_none = formatters['.%s { display: inline ; font-weight: normal ; }']
local f_div_class = formatters['<div class="%s">%s</div>']
@@ -92,7 +101,7 @@ local function exportcsslexing()
if not css then
loadscitelexer()
local function black(f)
- return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00')
+ return (#f == 0 and f[1] == 0) or ((f[1] == f[2]) and (f[2] == f[3]) and (f[3] == 0))
end
local result, r = { }, 0
for k, v in table.sortedhash(lexer.context.styles) do
@@ -100,17 +109,10 @@ local function exportcsslexing()
local fore = v.fore
r = r + 1
if fore and not black(fore) then
- if bold then
- result[r] = f_fore_bold(k,fore[1],fore[2],fore[3])
- else
- result[r] = f_fore_none(k,fore[1],fore[2],fore[3])
- end
+ local cr, cg, cb = fore[1], fore[2], fore[3]
+ result[r] = (bold and f_fore_bold or f_fore_none)(k,cr,cg or cr,cb or cr)
else
- if bold then
- result[r] = f_none_bold(k)
- else
- result[r] = f_none_none(k)
- end
+ result[r] = (bold and f_none_bold or f_none_none)(k)
end
end
css = concat(result,"\n")
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index ff174700c..5716030ad 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 90fa626d6..61f901149 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/mkiv/m-scite.mkiv b/tex/context/modules/mkiv/m-scite.mkiv
index 256a78b39..a7d9f8b5c 100644
--- a/tex/context/modules/mkiv/m-scite.mkiv
+++ b/tex/context/modules/mkiv/m-scite.mkiv
@@ -56,7 +56,7 @@ buffers.scite = scite
-- context output:
-local f_def_color = formatters["\\definecolor[slxc%s][h=%s%s%s]%%"]
+local f_def_color = formatters["\\definecolor[slxc%s][h=%02X%02X%02X]%%"]
local f_fore_none = formatters["\\unexpanded\\def\\slx%s#1{{\\slxc%s#1}}%%"]
local f_fore_bold = formatters["\\unexpanded\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"]
local f_none_bold = formatters["\\unexpanded\\def\\slx%s#1{{\\bf#1}}%%"]
@@ -99,14 +99,14 @@ local function exportcolors()
if not colors then
scite.loadscitelexer()
local function black(f)
- return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00')
+ return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == 0)
end
local result, r = { f_mapping }, 1
for k, v in table.sortedhash(lexer.context.styles) do
local fore = v.fore
if fore and not black(fore) then
r = r + 1
- result[r] = f_def_color(k,fore[1],fore[2],fore[3])
+ result[r] = f_def_color(k,fore[1],fore[2] or fore[1],fore[3] or fore[1])
end
end
r = r + 1
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 68bcd8007..c671651ef 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 : 04/08/17 12:09:31
+-- merge date : 04/16/17 12:32:21
do -- begin closure to overcome local limits and interference
@@ -8171,14 +8171,7 @@ local function readlongdatetime(f)
end
local tableversion=0.004
readers.tableversion=tableversion
-local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
-local reportedskipped={}
-local function reportskippedtable(tag)
- if not reportedskipped[tag] then
- report("loading of table %a skipped (reported once only)",tag)
- reportedskipped[tag]=true
- end
-end
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
local reservednames={ [0]="copyright",
"family",
"subfamily",
@@ -8382,6 +8375,14 @@ local function gotodatatable(f,fontdata,tag,criterium)
end
end
end
+local function reportskippedtable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local datatable=fontdata.tables[tag]
+ if datatable then
+ report("loading of table %a skipped",tag)
+ end
+ end
+end
local function setvariabledata(fontdata,tag,data)
local variabledata=fontdata.variabledata
if variabledata then
@@ -8392,6 +8393,7 @@ local function setvariabledata(fontdata,tag,data)
end
helpers.gotodatatable=gotodatatable
helpers.setvariabledata=setvariabledata
+helpers.reportskippedtable=reportskippedtable
local platformnames={
postscriptname=true,
fullname=true,
@@ -8763,8 +8765,7 @@ readers.vmtx=function(f,fontdata,specification)
end
end
readers.vorg=function(f,fontdata,specification)
- if specification.glyphs then
- end
+ reportskippedtable(f,fontdata,"vorg",specification.glyphs)
end
readers.post=function(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"post",true)
@@ -8825,9 +8826,7 @@ readers.post=function(f,fontdata,specification)
end
end
readers.cff=function(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("cff")
- end
+ reportskippedtable(f,fontdata,"cff",specification.glyphs)
end
local formatreaders={}
local duplicatestoo=true
@@ -9246,29 +9245,37 @@ function readers.cmap(f,fontdata,specification)
end
end
function readers.loca(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("loca")
- end
+ reportskippedtable(f,fontdata,"loca",specification.glyphs)
end
function readers.glyf(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("glyf")
- end
+ reportskippedtable(f,fontdata,"glyf",specification.glyphs)
end
function readers.colr(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("colr")
- end
+ reportskippedtable(f,fontdata,"colr",specification.glyphs)
end
function readers.cpal(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("cpal")
- end
+ reportskippedtable(f,fontdata,"cpal",specification.glyphs)
end
function readers.svg(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("svg")
- end
+ reportskippedtable(f,fontdata,"svg",specification.glyphs)
+end
+function readers.sbix(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"sbix",specification.glyphs)
+end
+function readers.cbdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
+end
+function readers.cblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cblc",specification.glyphs)
+end
+function readers.ebdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
+end
+function readers.ebsc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
+end
+function readers.eblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"eblc",specification.glyphs)
end
function readers.kern(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns)
@@ -9308,24 +9315,16 @@ function readers.kern(f,fontdata,specification)
end
end
function readers.gdef(f,fontdata,specification)
- if specification.details then
- reportskippedtable("gdef")
- end
+ reportskippedtable(f,fontdata,"gdef",specification.details)
end
function readers.gsub(f,fontdata,specification)
- if specification.details then
- reportskippedtable("gsub")
- end
+ reportskippedtable(f,fontdata,"gsub",specification.details)
end
function readers.gpos(f,fontdata,specification)
- if specification.details then
- reportskippedtable("gpos")
- end
+ reportskippedtable(f,fontdata,"gpos",specification.details)
end
function readers.math(f,fontdata,specification)
- if specification.glyphs then
- reportskippedtable("math")
- end
+ reportskippedtable(f,fontdata,"math",specification.details)
end
local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames)
local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
@@ -9560,6 +9559,11 @@ local function readdata(f,offset,specification)
readtable("colr",f,fontdata,specification)
readtable("cpal",f,fontdata,specification)
readtable("svg",f,fontdata,specification)
+ readtable("sbix",f,fontdata,specification)
+ readtable("cbdt",f,fontdata,specification)
+ readtable("cblc",f,fontdata,specification)
+ readtable("ebdt",f,fontdata,specification)
+ readtable("eblc",f,fontdata,specification)
readtable("kern",f,fontdata,specification)
readtable("gsub",f,fontdata,specification)
readtable("gpos",f,fontdata,specification)
@@ -9753,6 +9757,7 @@ function readers.loadfont(filename,n,instance)
mathconstants=fontdata.mathconstants,
colorpalettes=fontdata.colorpalettes,
svgshapes=fontdata.svgshapes,
+ sbixshapes=fontdata.sbixshapes,
variabledata=fontdata.variabledata,
foundtables=fontdata.foundtables,
},
@@ -15269,6 +15274,72 @@ function readers.svg(f,fontdata,specification)
end
fontdata.hascolor=true
end
+function readers.sbix(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local flags=readushort(f)
+ local nofstrikes=readulong(f)
+ local strikes={}
+ local nofglyphs=fontdata.nofglyphs
+ 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.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),
+ 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.sbixshapes=shapes
+ end
+end
function readers.stat(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"stat",true)
if tableoffset then
@@ -17755,8 +17826,10 @@ local otf=fonts.handlers.otf
otf.version=3.028
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.svgenabled=false
+otf.sbixenabled=false
local otfreaders=otf.readers
local hashes=fonts.hashes
local definers=fonts.definers
@@ -17812,6 +17885,7 @@ function otf.load(filename,sub,instance)
if data then
local resources=data.resources
local svgshapes=resources.svgshapes
+ local sbixshapes=resources.sbixshapes
if svgshapes then
resources.svgshapes=nil
if otf.svgenabled then
@@ -17826,6 +17900,20 @@ function otf.load(filename,sub,instance)
}
end
end
+ if sbixshapes then
+ resources.sbixshapes=nil
+ if otf.sbixenabled then
+ local timestamp=os.date()
+ containers.write(otf.sbixcache,hash,{
+ sbixshapes=sbixshapes,
+ timestamp=timestamp,
+ })
+ data.properties.sbix={
+ hash=hash,
+ timestamp=timestamp,
+ }
+ end
+ end
otfreaders.compact(data)
otfreaders.rehash(data,"unicodes")
otfreaders.addunicodetable(data)
@@ -25817,6 +25905,7 @@ if not modules then modules={} end modules ['font-ocl']={
}
local tostring,next,format=tostring,next,string.format
local round,max=math.round,math.round
+local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash
local formatters=string.formatters
local tounicode=fonts.mappings.tounicode
local otf=fonts.handlers.otf
@@ -25944,44 +26033,78 @@ fonts.handlers.otf.features.register {
node=initializecolr,
}
}
-local otfsvg=otf.svg or {}
-otf.svg=otfsvg
-otf.svgenabled=true
do
local nofstreams=0
- local f_name=formatters[ [[svg-glyph-%05i]] ]
+ local f_name=formatters[ [[pdf-glyph-%05i]] ]
local f_used=context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
+ local hashed={}
local cache={}
- function otfsvg.storepdfdata(pdf)
- nofstreams=nofstreams+1
- local o,n=epdf.openMemStream(pdf,#pdf,f_name(nofstreams))
- cache[n]=o
- return nil,f_used(n),nil
+ function otf.storepdfdata(pdf)
+ local done=hashed[pdf]
+ if not done then
+ nofstreams=nofstreams+1
+ local o,n=epdf.openMemStream(pdf,#pdf,f_name(nofstreams))
+ cache[n]=o
+ done=f_used(n)
+ hashed[pdf]=done
+ end
+ return nil,done,nil
end
- if context then
- local storepdfdata=otfsvg.storepdfdata
- local initialized=false
- function otfsvg.storepdfdata(pdf)
- if not initialized then
- if resolvers.setmemstream then
- local f_setstream=formatters[ [[resolvers.setmemstream("svg-glyph-%05i",%q,true)]] ]
- local f_getstream=formatters[ [[memstream:///svg-glyph-%05i]] ]
- local f_nilstream=formatters[ [[resolvers.resetmemstream("svg-glyph-%05i",true)]] ]
- storepdfdata=function(pdf)
- nofstreams=nofstreams+1
- return
- f_setstream(nofstreams,pdf),
- f_getstream(nofstreams),
- f_nilstream(nofstreams)
- end
- otfsvg.storepdfdata=storepdfdata
+end
+local function pdftovirtual(tfmdata,pdfshapes,kind)
+ if not tfmdata or not pdfshapes or not kind then
+ return
+ end
+ local characters=tfmdata.characters
+ local properties=tfmdata.properties
+ local parameters=tfmdata.parameters
+ local hfactor=parameters.hfactor
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local storepdfdata=otf.storepdfdata
+ for unicode,character in sortedhash(characters) do
+ local index=character.index
+ if index then
+ local pdf=pdfshapes[index]
+ local typ=type(pdf)
+ local data=nil
+ local dx=nil
+ local dy=nil
+ if typ=="table" then
+ data=pdf.data
+ dx=pdf.dx or 0
+ dy=pdf.dy or 0
+ elseif typ=="string" then
+ data=pdf
+ dx=0
+ dy=0
+ end
+ if data then
+ local setcode,name,nilcode=storepdfdata(data)
+ if name then
+ local bt,et=getactualtext(unicode)
+ local wd=character.width or 0
+ local ht=character.height or 0
+ local dp=character.depth or 0
+ character.commands={
+ { "special","pdf:direct:"..bt },
+ { "down",dp+dy*hfactor },
+ { "right",dx*hfactor },
+ { "image",{ filename=name,width=wd,height=ht,depth=dp } },
+ { "special","pdf:direct:"..et },
+ }
+ character[kind]=true
end
- initialized=true
end
- return storepdfdata(pdf)
end
end
end
+local otfsvg=otf.svg or {}
+otf.svg=otfsvg
+otf.svgenabled=true
do
local report_svg=logs.reporter("fonts","svg conversion")
local loaddata=io.loaddata
@@ -26054,7 +26177,7 @@ do
end
statistics.stoptiming()
if statistics.elapsedseconds then
- report_svg("svg conversion time %s",statistics.elapsedseconds())
+ report_svg("svg conversion time %s",statistics.elapsedseconds() or "-")
end
end
return pdfshapes
@@ -26062,10 +26185,7 @@ do
end
local function initializesvg(tfmdata,kind,value)
if value and otf.svgenabled then
- local characters=tfmdata.characters
- local descriptions=tfmdata.descriptions
- local properties=tfmdata.properties
- local svg=properties.svg
+ local svg=tfmdata.properties.svg
local hash=svg and svg.hash
local timestamp=svg and svg.timestamp
if not hash then
@@ -26082,40 +26202,7 @@ local function initializesvg(tfmdata,kind,value)
timestamp=timestamp,
})
end
- if not pdfshapes or not next(pdfshapes) then
- return
- end
- properties.virtualized=true
- tfmdata.fonts={
- { id=0 }
- }
- local getactualtext=otf.getactualtext
- local storepdfdata=otfsvg.storepdfdata
- local nop={ "nop" }
- for unicode,character in next,characters do
- local index=character.index
- if index then
- local pdf=pdfshapes[index]
- if pdf then
- local setcode,name,nilcode=storepdfdata(pdf)
- if name then
- local bt,et=getactualtext(unicode)
- local wd=character.width or 0
- local ht=character.height or 0
- local dp=character.depth or 0
- character.commands={
- { "special","pdf:direct:"..bt },
- { "down",dp },
- setcode and { "lua",setcode } or nop,
- { "image",{ filename=name,width=wd,height=ht,depth=dp } },
- nilcode and { "lua",nilcode } or nop,
- { "special","pdf:direct:"..et },
- }
- character.svg=true
- end
- end
- end
- end
+ pdftovirtual(tfmdata,pdfshapes,"svg")
end
end
fonts.handlers.otf.features.register {
@@ -26126,6 +26213,91 @@ fonts.handlers.otf.features.register {
node=initializesvg,
}
}
+local otfsbix=otf.sbix or {}
+otf.sbix=otfsbix
+otf.sbixenabled=true
+do
+ local report_sbix=logs.reporter("fonts","sbix conversion")
+ local loaddata=io.loaddata
+ local savedata=io.savedata
+ local remove=os.remove
+ local runner=sandbox and sandbox.registerrunner {
+ name="otfsbix",
+ program="gm",
+ template="convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log",
+ }
+ if not runner then
+ runner=function()
+ return os.execute("gm convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log")
+ end
+ end
+ function otfsbix.topdf(sbixshapes)
+ local pdfshapes={}
+ local sbixfile="temp-otf-sbix-shape.sbix"
+ local pdffile="temp-otf-sbix-shape.pdf"
+ local nofdone=0
+ local indices=sortedkeys(sbixshapes)
+ local nofindices=#indices
+ report_sbix("processing %i sbix containers",nofindices)
+ statistics.starttiming()
+ for i=1,nofindices do
+ local index=indices[i]
+ local entry=sbixshapes[index]
+ local data=entry.data
+ local x=entry.x
+ local y=entry.y
+ savedata(sbixfile,data)
+ runner()
+ pdfshapes[index]={
+ x=x~=0 and x or nil,
+ y=y~=0 and y or nil,
+ data=loaddata(pdffile),
+ }
+ nofdone=nofdone+1
+ if nofdone%100==0 then
+ report_sbix("%i shapes processed",nofdone)
+ end
+ end
+ report_sbix("processing %i pdf results",nofindices)
+ remove(sbixfile)
+ remove(pdffile)
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_sbix("sbix 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
+ 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 {}
+ containers.write(otf.pdfcache,hash,{
+ pdfshapes=pdfshapes,
+ timestamp=timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"sbix")
+ end
+end
+fonts.handlers.otf.features.register {
+ name="sbix",
+ description="sbix glyphs",
+ manipulators={
+ base=initializesbix,
+ node=initializesbix,
+ }
+}
end -- closure
@@ -26142,7 +26314,6 @@ local format,insert,sortedkeys,tohash=string.format,table.insert,table.sortedkey
local type,next=type,next
local lpegmatch=lpeg.match
local utfbyte,utflen,utfsplit=utf.byte,utf.len,utf.split
-local settings_to_array=utilities.parsers.settings_to_array
local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
@@ -26974,6 +27145,8 @@ registerotffeature {
name='blockligatures',
description='block certain ligatures',
}
+local settings_to_array=utilities.parsers and utilities.parsers.settings_to_array
+ or function(s) return string.split(s,",") end
local function blockligatures(str)
local t=settings_to_array(str)
for i=1,#t do
@@ -28783,8 +28956,9 @@ if not modules then modules={} end modules ['font-def']={
local lower,gsub=string.lower,string.gsub
local tostring,next=tostring,next
local lpegmatch=lpeg.match
-local suffixonly,removesuffix=file.suffix,file.removesuffix
+local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename
local formatters=string.formatters
+local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
local allocate=utilities.storage.allocate
local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end)
local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end)
@@ -28904,9 +29078,9 @@ function resolvers.name(specification)
features.normal=normal
end
normal.instance=instance
-if not callbacks.supported.glyph_stream_provider then
- normal.variableshapes=true
-end
+ if not callbacks.supported.glyph_stream_provider then
+ normal.variableshapes=true
+ end
end
local suffix=lower(suffixonly(resolved))
if fonts.formats[suffix] then
@@ -28985,6 +29159,60 @@ local function checkembedding(tfmdata)
end
tfmdata.embedding=embedding
end
+local function checkfeatures(tfmdata)
+ local resources=tfmdata.resources
+ local shared=tfmdata.shared
+ if resources and shared then
+ local features=resources.features
+ local usedfeatures=shared.features
+ if features and usedfeatures then
+ local usedlanguage=usedfeatures.language or "dflt"
+ local usedscript=usedfeatures.script or "dflt"
+ local function check(what)
+ if what then
+ local foundlanguages={}
+ for feature,scripts in next,what do
+ if usedscript=="auto" or scripts["*"] then
+ elseif not scripts[usedscript] then
+ else
+ for script,languages in next,scripts do
+ if languages["*"] then
+ elseif not languages[usedlanguage] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,usedlanguage)
+ end
+ end
+ end
+ for script,languages in next,scripts do
+ for language in next,languages do
+ foundlanguages[language]=true
+ end
+ end
+ end
+ if false then
+ foundlanguages["*"]=nil
+ foundlanguages=sortedkeys(foundlanguages)
+ for feature,scripts in sortedhash(what) do
+ for script,languages in next,scripts do
+ if not languages["*"] then
+ for i=1,#foundlanguages do
+ local language=foundlanguages[i]
+ if not languages[language] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,language)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ check(features.gsub)
+ check(features.gpos)
+ end
+ end
+end
function definers.loadfont(specification)
local hash=constructors.hashinstance(specification)
local tfmdata=loadedfonts[hash]
@@ -29018,6 +29246,7 @@ function definers.loadfont(specification)
checkembedding(tfmdata)
loadedfonts[hash]=tfmdata
designsizes[specification.hash]=tfmdata.parameters.designsize
+ checkfeatures(tfmdata)
end
end
if not tfmdata then
@@ -29110,7 +29339,7 @@ function definers.read(specification,size,id)
local parameters=tfmdata.parameters or {}
report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
properties.format or "unknown",id,properties.name,parameters.size,properties.encodingbytes,
- properties.encodingname,properties.fullname,file.basename(properties.filename))
+ properties.encodingname,properties.fullname,basename(properties.filename))
end
statistics.stoptiming(fonts)
return tfmdata