diff options
Diffstat (limited to 'tex')
32 files changed, 648 insertions, 604 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 7bfcf8614..4e4b70b10 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.06.30 19:45} +\newcontextversion{2017.07.05 23:01} %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 48ef7f4cd..b80487453 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.06.30 19:45} +\edef\contextversion{2017.07.05 23:01} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index ec1fb10f4..f11749025 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -687,6 +687,7 @@ \setinterfaceconstant{bottomoffset}{untenoffset} \setinterfaceconstant{bottomspace}{bottomspace} \setinterfaceconstant{bottomstate}{untenstatus} +\setinterfaceconstant{break}{break} \setinterfaceconstant{buffer}{buffer} \setinterfaceconstant{cache}{cache} \setinterfaceconstant{calculate}{berechnen} diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index 26d0cd9c6..6ae2fe671 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -687,6 +687,7 @@ \setinterfaceconstant{bottomoffset}{offsetjos} \setinterfaceconstant{bottomspace}{spatiujos} \setinterfaceconstant{bottomstate}{starejos} +\setinterfaceconstant{break}{break} \setinterfaceconstant{buffer}{buffer} \setinterfaceconstant{cache}{cache} \setinterfaceconstant{calculate}{calculeaza} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 82888546f..da2b24760 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.06.30 19:45} +\newcontextversion{2017.07.05 23:01} %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.mkiv b/tex/context/base/mkiv/cont-run.mkiv index 07154196f..ef4992c69 100644 --- a/tex/context/base/mkiv/cont-run.mkiv +++ b/tex/context/base/mkiv/cont-run.mkiv @@ -34,8 +34,11 @@ \unexpanded\def\setupsynctex[#1]% {\begingroup - \getdummyparameters[\c!state=,#1]% - \doifelse{\dummyparameter\c!state}\v!start\clf_synctexenable\clf_synctexdisable + \getdummyparameters[\c!state=\v!stop,\c!method=\v!max,#1]% + \clf_setupsynctex + state {\dummyparameter\c!state}% + method {\dummyparameter\c!method}% + \relax \endgroup} \unexpanded\def\blocksynctexfile[#1]% diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 73069d51a..c142bbc64 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -41,7 +41,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2017.06.30 19:45} +\edef\contextversion{2017.07.05 23:01} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index f4f04d87e..2e85c2438 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -2511,12 +2511,12 @@ function readers.gdef(f,fontdata,specification) local tableoffset = datatable.offset setposition(f,tableoffset) local version = readulong(f) - local classoffset = tableoffset + readushort(f) - local attachmentoffset = tableoffset + readushort(f) -- used for bitmaps - local ligaturecarets = tableoffset + readushort(f) -- used in editors (maybe nice for tracing) - local markclassoffset = tableoffset + readushort(f) - local marksetsoffset = version >= 0x00010002 and (tableoffset + readushort(f)) - local varsetsoffset = version >= 0x00010003 and (tableoffset + readulong(f)) + local classoffset = readushort(f) + local attachmentoffset = readushort(f) -- used for bitmaps + local ligaturecarets = readushort(f) -- used in editors (maybe nice for tracing) + local markclassoffset = readushort(f) + local marksetsoffset = version >= 0x00010002 and readushort(f) or 0 + local varsetsoffset = version >= 0x00010003 and readulong(f) or 0 local glyphs = fontdata.glyphs local marks = { } local markclasses = setmetatableindex("table") @@ -2525,56 +2525,61 @@ function readers.gdef(f,fontdata,specification) fontdata.markclasses = markclasses fontdata.marksets = marksets -- class definitions - setposition(f,classoffset) - local classformat = readushort(f) - if classformat == 1 then - local firstindex = readushort(f) - local lastindex = firstindex + readushort(f) - 1 - for index=firstindex,lastindex do - local class = classes[readushort(f)] - if class == "mark" then - marks[index] = true - end - glyphs[index].class = class - end - elseif classformat == 2 then - local nofranges = readushort(f) - for i=1,nofranges do + if classoffset ~= 0 then + setposition(f,tableoffset + classoffset) + local classformat = readushort(f) + if classformat == 1 then local firstindex = readushort(f) - local lastindex = readushort(f) - local class = classes[readushort(f)] - if class then - for index=firstindex,lastindex do - glyphs[index].class = class - if class == "mark" then - marks[index] = true + local lastindex = firstindex + readushort(f) - 1 + for index=firstindex,lastindex do + local class = classes[readushort(f)] + if class == "mark" then + marks[index] = true + end + glyphs[index].class = class + end + elseif classformat == 2 then + local nofranges = readushort(f) + for i=1,nofranges do + local firstindex = readushort(f) + local lastindex = readushort(f) + local class = classes[readushort(f)] + if class then + for index=firstindex,lastindex do + glyphs[index].class = class + if class == "mark" then + marks[index] = true + end end end end end end -- mark classes - setposition(f,markclassoffset) - local classformat = readushort(f) - if classformat == 1 then - local firstindex = readushort(f) - local lastindex = firstindex + readushort(f) - 1 - for index=firstindex,lastindex do - markclasses[readushort(f)][index] = true - end - elseif classformat == 2 then - local nofranges = readushort(f) - for i=1,nofranges do + if markclassoffset ~= 0 then + setposition(f,tableoffset + markclassoffset) + local classformat = readushort(f) + if classformat == 1 then local firstindex = readushort(f) - local lastindex = readushort(f) - local class = markclasses[readushort(f)] + local lastindex = firstindex + readushort(f) - 1 for index=firstindex,lastindex do - class[index] = true + markclasses[readushort(f)][index] = true + end + elseif classformat == 2 then + local nofranges = readushort(f) + for i=1,nofranges do + local firstindex = readushort(f) + local lastindex = readushort(f) + local class = markclasses[readushort(f)] + for index=firstindex,lastindex do + class[index] = true + end end end end -- mark sets : todo: just make the same as class sets above - if marksetsoffset and marksetsoffset > tableoffset then -- zero offset means no table + if marksetsoffset ~= 0 then + marksetsoffset = tableoffset + marksetsoffset setposition(f,marksetsoffset) local format = readushort(f) if format == 1 then @@ -2594,9 +2599,9 @@ function readers.gdef(f,fontdata,specification) local factors = specification.factors - if (specification.variable or factors) and varsetsoffset and varsetsoffset > tableoffset then + if (specification.variable or factors) and varsetsoffset ~= 0 then - local regions, deltas = readvariationdata(f,varsetsoffset,factors) + local regions, deltas = readvariationdata(f,tableoffset+varsetsoffset,factors) -- setvariabledata(fontdata,"gregions",regions) diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua index 85e39e877..cf77ac4eb 100644 --- a/tex/context/base/mkiv/font-ext.lua +++ b/tex/context/base/mkiv/font-ext.lua @@ -749,15 +749,15 @@ registerafmfeature(dimensions_specification) -- -- \definecolor[DummyColor][s=.75,t=.5,a=1] {\DummyColor test} \nopdfcompression -- --- local gray = { "special", "pdf: /Tr1 gs .75 g" } --- local black = { "special", "pdf: /Tr0 gs 0 g" } +-- local gray = { "pdf", "/Tr1 gs .75 g" } +-- local black = { "pdf", "/Tr0 gs 0 g" } -- sort of obsolete as we now have \showglyphs local push = { "push" } local pop = { "pop" } -local gray = { "special", "pdf: .75 g" } -local black = { "special", "pdf: 0 g" } +local gray = { "pdf", ".75 g" } +local black = { "pdf", "0 g" } local downcache = { } -- handy for huge cjk fonts local rulecache = { } -- handy for huge cjk fonts diff --git a/tex/context/base/mkiv/font-fbk.lua b/tex/context/base/mkiv/font-fbk.lua index 60f1a1fdf..8a5c1ebb7 100644 --- a/tex/context/base/mkiv/font-fbk.lua +++ b/tex/context/base/mkiv/font-fbk.lua @@ -300,11 +300,11 @@ end -- vf builder --- {'special', 'pdf: q ' .. s .. ' 0 0 '.. s .. ' 0 0 cm'}, --- {'special', 'pdf: q 1 0 0 1 ' .. -w .. ' ' .. -h .. ' cm'}, --- {'special', 'pdf: /Fm\XX\space Do'}, --- {'special', 'pdf: Q'}, --- {'special', 'pdf: Q'}, +-- { "pdf", "q " .. s .. " 0 0 " .. s .. " 0 0 cm" }, +-- { "pdf", "q 1 0 0 1 " .. -w .. " " .. -h .. " cm" }, +-- { "pdf", "/Fm\XX\space Do" }, +-- { "pdf", "Q" }, +-- { "pdf", "Q" }, -- new and experimental diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua index 5e4da74e3..024e32831 100644 --- a/tex/context/base/mkiv/font-mis.lua +++ b/tex/context/base/mkiv/font-mis.lua @@ -21,7 +21,7 @@ local readers = otf.readers if readers then - otf.version = otf.version or 3.030 + otf.version = otf.version or 3.031 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 b3f368836..aca2c62bb 100644 --- a/tex/context/base/mkiv/font-ocl.lua +++ b/tex/context/base/mkiv/font-ocl.lua @@ -18,8 +18,8 @@ local tounicode = fonts.mappings.tounicode local otf = fonts.handlers.otf -local f_color = formatters["pdf:direct:%f %f %f rg"] -local f_gray = formatters["pdf:direct:%f g"] +local f_color = formatters["%f %f %f rg"] +local f_gray = formatters["%f g"] if context then @@ -49,7 +49,7 @@ end local sharedpalettes = { } local hash = setmetatableindex(function(t,k) - local v = { "special", k } + local v = { "pdf", "direct", k } t[k] = v return v end) @@ -76,11 +76,11 @@ if context then t = transparencies[v] end if c and t then - values[i] = hash["pdf:direct:" .. lpdf.color(1,c) .. " " .. lpdf.transparency(t)] + values[i] = hash[lpdf.color(1,c) .. " " .. lpdf.transparency(t)] elseif c then - values[i] = hash["pdf:direct:" .. lpdf.color(1,c)] + values[i] = hash[lpdf.color(1,c)] elseif t then - values[i] = hash["pdf:direct:" .. lpdf.color(1,t)] + values[i] = hash[lpdf.color(1,t)] end end end @@ -123,6 +123,9 @@ local function convert(t,k) return v end +local start = { "pdf", "page", "q" } +local stop = { "pdf", "raw", "Q" } + local function initializecolr(tfmdata,kind,value) -- hm, always value if value then local resources = tfmdata.resources @@ -157,13 +160,11 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value local getactualtext = otf.getactualtext local default = colorvalues[#colorvalues] local b, e = getactualtext(tounicode(0xFFFD)) - local start = { "special", "pdf:page:q" } - local stop = { "special", "pdf:raw:Q" } - local actualb = { "special", "pdf:page:" .. b } -- saves tables - local actuale = { "special", "pdf:page:" .. e } -- saves tables + local actualb = { "pdf", "page", b } -- saves tables + local actuale = { "pdf", "page", e } -- saves tables -- local cache = setmetatableindex(function(t,k) - local v = { "char", k } + local v = { "char", k } -- could he a weak shared hash t[k] = v return v end) @@ -179,7 +180,7 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same local t = { start, - not u and actualb or { "special", "pdf:raw:" .. getactualtext(tounicode(u)) } + not u and actualb or { "pdf", "raw", getactualtext(tounicode(u)) } } local n = 2 local l = nil @@ -328,13 +329,13 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg local ht = character.height or 0 local dp = character.depth or 0 character.commands = { - { "special", "pdf:direct:" .. bt }, + { "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 }, + { "pdf", "direct", et }, } character[kind] = true end diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index a338f85a8..2661ac5c1 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.030 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.031 -- 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) diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index c5fa13abe..a5a039525 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -114,40 +114,45 @@ local random = math.random local formatters = string.formatters local insert = table.insert -local registertracker = trackers.register - -local logs = logs -local trackers = trackers -local nodes = nodes -local attributes = attributes -local fonts = fonts - -local otf = fonts.handlers.otf -local tracers = nodes.tracers - -local trace_singles = false registertracker("otf.singles", function(v) trace_singles = v end) -local trace_multiples = false registertracker("otf.multiples", function(v) trace_multiples = v end) -local trace_alternatives = false registertracker("otf.alternatives", function(v) trace_alternatives = v end) -local trace_ligatures = false registertracker("otf.ligatures", function(v) trace_ligatures = v end) -local trace_contexts = false registertracker("otf.contexts", function(v) trace_contexts = v end) -local trace_marks = false registertracker("otf.marks", function(v) trace_marks = v end) -local trace_kerns = false registertracker("otf.kerns", function(v) trace_kerns = v end) -local trace_cursive = false registertracker("otf.cursive", function(v) trace_cursive = v end) -local trace_preparing = false registertracker("otf.preparing", function(v) trace_preparing = v end) -local trace_bugs = false registertracker("otf.bugs", function(v) trace_bugs = v end) -local trace_details = false registertracker("otf.details", function(v) trace_details = v end) -local trace_steps = false registertracker("otf.steps", function(v) trace_steps = v end) -local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end) -local trace_directions = false registertracker("otf.directions", function(v) trace_directions = v end) -local trace_plugins = false registertracker("otf.plugins", function(v) trace_plugins = v end) -local trace_chains = false registertracker("otf.chains", function(v) trace_chains = v end) - -local trace_kernruns = false registertracker("otf.kernruns", function(v) trace_kernruns = v end) -local trace_discruns = false registertracker("otf.discruns", function(v) trace_discruns = v end) -local trace_compruns = false registertracker("otf.compruns", function(v) trace_compruns = v end) -local trace_testruns = false registertracker("otf.testruns", function(v) trace_testruns = v end) - -local optimizekerns = true +local registertracker = trackers.register + +local logs = logs +local trackers = trackers +local nodes = nodes +local attributes = attributes +local fonts = fonts + +local otf = fonts.handlers.otf +local tracers = nodes.tracers + +local trace_singles = false registertracker("otf.singles", function(v) trace_singles = v end) +local trace_multiples = false registertracker("otf.multiples", function(v) trace_multiples = v end) +local trace_alternatives = false registertracker("otf.alternatives", function(v) trace_alternatives = v end) +local trace_ligatures = false registertracker("otf.ligatures", function(v) trace_ligatures = v end) +local trace_contexts = false registertracker("otf.contexts", function(v) trace_contexts = v end) +local trace_marks = false registertracker("otf.marks", function(v) trace_marks = v end) +local trace_kerns = false registertracker("otf.kerns", function(v) trace_kerns = v end) +local trace_cursive = false registertracker("otf.cursive", function(v) trace_cursive = v end) +local trace_preparing = false registertracker("otf.preparing", function(v) trace_preparing = v end) +local trace_bugs = false registertracker("otf.bugs", function(v) trace_bugs = v end) +local trace_details = false registertracker("otf.details", function(v) trace_details = v end) +local trace_steps = false registertracker("otf.steps", function(v) trace_steps = v end) +local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end) +local trace_directions = false registertracker("otf.directions", function(v) trace_directions = v end) +local trace_plugins = false registertracker("otf.plugins", function(v) trace_plugins = v end) +local trace_chains = false registertracker("otf.chains", function(v) trace_chains = v end) + +local trace_kernruns = false registertracker("otf.kernruns", function(v) trace_kernruns = v end) +local trace_discruns = false registertracker("otf.discruns", function(v) trace_discruns = v end) +local trace_compruns = false registertracker("otf.compruns", function(v) trace_compruns = v end) +local trace_testruns = false registertracker("otf.testruns", function(v) trace_testruns = v end) + +local forcediscretionaries = false +local optimizekerns = true + +directives.register("otf.forcediscretionaries",function(v) + forcediscretionaries = v +end) local report_direct = logs.reporter("fonts","otf direct") local report_subchain = logs.reporter("fonts","otf subchain") @@ -225,7 +230,7 @@ local math_code = nodecodes.math local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar ------ discretionary_code = disccodes.discretionary +local discretionary_code = disccodes.discretionary local ligature_code = glyphcodes.ligature local a_state = attributes.private('state') @@ -566,7 +571,11 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou -- here components have a pointer so we can't free it! set_components(base,copied) replace = base - setdisc(discfound,pre,post,replace) -- was discretionary_code + if forcediscretionaries then + setdisc(discfound,pre,post,replace,discretionary_code) + else + setdisc(discfound,pre,post,replace) + end base = prev end end diff --git a/tex/context/base/mkiv/font-shp.lua b/tex/context/base/mkiv/font-shp.lua index 6e21848a4..c465ec91b 100644 --- a/tex/context/base/mkiv/font-shp.lua +++ b/tex/context/base/mkiv/font-shp.lua @@ -362,7 +362,7 @@ local function addvariableshapes(tfmdata,key,value) -- we need inline in order to support color local bt, et = getactualtext(char.tounicode or char.unicode or unicode) char.commands = { - { "special", "pdf:" .. segmentstopdf(segments,factor,bt,et) } + { "pdf", segmentstopdf(segments,factor,bt,et) } } end end diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua index e2c0d220e..50150d9e2 100644 --- a/tex/context/base/mkiv/lang-dis.lua +++ b/tex/context/base/mkiv/lang-dis.lua @@ -267,40 +267,58 @@ end local wiped = 0 -local function wipe(head,delayed) - local p, n = getboth(delayed) - local _, _, h, _, _, t = getdisc(delayed,true) - if p or n then - if h then - setlink(p,h) - setlink(t,n) - setfield(delayed,"replace") - else - setlink(p,n) - end +local flatten_discretionaries = node.flatten_discretionaries -- todo in nodes + +if flatten_discretionaries then + + -- This is not that much faster than the lua variant simply because there is + -- seldom a replace list but it fits in the picture. See luatex-todo.w for the + -- code. + + function languages.flatten(head) + local h, n = flatten_discretionaries(head) + wiped = wiped + n + return h, n > 0 end - if head == delayed then - head = h + +else + + local function wipe(head,delayed) + local p, n = getboth(delayed) + local _, _, h, _, _, t = getdisc(delayed,true) + if p or n then + if h then + setlink(p,h) + setlink(t,n) + setfield(delayed,"replace") + else + setlink(p,n) + end + end + if head == delayed then + head = h + end + wiped = wiped + 1 + flush_node(delayed) + return head end - wiped = wiped + 1 - flush_node(delayed) - return head -end -function languages.flatten(head) - local nuthead = tonut(head) - local delayed = nil - for d in traverse_id(disc_code,nuthead) do + function languages.flatten(head) + local nuthead = tonut(head) + local delayed = nil + for d in traverse_id(disc_code,nuthead) do + if delayed then + nuthead = wipe(nuthead,delayed) + end + delayed = d + end if delayed then - nuthead = wipe(nuthead,delayed) + return tonode(wipe(nuthead,delayed)), true + else + return head, false end - delayed = d - end - if delayed then - return tonode(wipe(nuthead,delayed)), true - else - return head, false end + end function languages.nofflattened() diff --git a/tex/context/base/mkiv/lpdf-col.lua b/tex/context/base/mkiv/lpdf-col.lua index b5973ba88..af01c7dd2 100644 --- a/tex/context/base/mkiv/lpdf-col.lua +++ b/tex/context/base/mkiv/lpdf-col.lua @@ -703,29 +703,29 @@ end -- this will move to lpdf-spe.lua -local f_slant = formatters["pdf: q 1 0 %F 1 0 0 cm"] +local f_slant = formatters["q 1 0 %F 1 0 0 cm"] backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color - red = { "special", 'pdf: 1 0 0 rg 1 0 0 RG' }, - green = { "special", 'pdf: 0 1 0 rg 0 1 0 RG' }, - blue = { "special", 'pdf: 0 0 1 rg 0 0 1 RG' }, - gray = { "special", 'pdf: .75 g .75 G' }, - black = { "special", 'pdf: 0 g 0 G' }, + red = { "pdf", "1 0 0 rg 1 0 0 RG" }, + green = { "pdf", "0 1 0 rg 0 1 0 RG" }, + blue = { "pdf", "0 0 1 rg 0 0 1 RG" }, + gray = { "pdf", ".75 g .75 G" }, + black = { "pdf", "0 g 0 G" }, rulecolors = { - red = { "special", 'pdf: 1 0 0 rg' }, - green = { "special", 'pdf: 0 1 0 rg' }, - blue = { "special", 'pdf: 0 0 1 rg' }, - gray = { "special", 'pdf: .5 g' }, - black = { "special", 'pdf: 0 g' }, - palered = { "special", 'pdf: 1 .75 .75 rg' }, - palegreen = { "special", 'pdf: .75 1 .75 rg' }, - paleblue = { "special", 'pdf: .75 .75 1 rg' }, - palegray = { "special", 'pdf: .75 g' }, + red = { "pdf", '1 0 0 rg' }, + green = { "pdf", '0 1 0 rg' }, + blue = { "pdf", '0 0 1 rg' }, + gray = { "pdf", '.5 g' }, + black = { "pdf", '0 g' }, + palered = { "pdf", '1 .75 .75 rg' }, + palegreen = { "pdf", '.75 1 .75 rg' }, + paleblue = { "pdf", '.75 .75 1 rg' }, + palegray = { "pdf", '.75 g' }, }, - startslant = function(a) return { "special", f_slant(a) } end, - stopslant = { "special", "pdf: Q" }, + startslant = function(a) return { "pdf", f_slant(a) } end, + stopslant = { "pdf", "Q" }, } diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua index 0d30ad11b..b194e755e 100644 --- a/tex/context/base/mkiv/luat-run.lua +++ b/tex/context/base/mkiv/luat-run.lua @@ -20,11 +20,13 @@ local report_lua = logs.reporter("system","lua") local report_tex = logs.reporter("system","status") local report_tempfiles = logs.reporter("resolvers","tempfiles") -luatex = luatex or { } -local luatex = luatex +luatex = luatex or { } +local luatex = luatex +local synctex = luatex.synctex -if not luatex.synctex then - luatex.synctex = table.setmetatableindex(function() return function() end end) +if not synctex then + synctex = table.setmetatableindex(function() return function() end end) + luatex.synctex = synctex end local startactions = { } @@ -64,6 +66,7 @@ local function stop_run() end local function start_shipout_page() + synctex.start() logs.start_page_number() end @@ -72,7 +75,7 @@ local function stop_shipout_page() for i=1,#pageactions do pageactions[i]() end - luatex.synctex.flush() + synctex.stop() end local function report_output_pages() @@ -96,7 +99,7 @@ local function pre_dump_actions() end local function wrapup_synctex() - luatex.synctex.wrapup() + synctex.wrapup() end -- this can be done later @@ -193,7 +196,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) + synctex.setfilename(name) end end diff --git a/tex/context/base/mkiv/m-fonts-plugins.mkiv b/tex/context/base/mkiv/m-fonts-plugins.mkiv index ecb311694..7678f820c 100644 --- a/tex/context/base/mkiv/m-fonts-plugins.mkiv +++ b/tex/context/base/mkiv/m-fonts-plugins.mkiv @@ -132,6 +132,8 @@ liga=yes, kern=yes] +% no tlig and no analyze + \definefontfeature [test-node] [mode=node, diff --git a/tex/context/base/mkiv/meta-fnt.lua b/tex/context/base/mkiv/meta-fnt.lua index 95bdfa6d9..ea7f6f2bc 100644 --- a/tex/context/base/mkiv/meta-fnt.lua +++ b/tex/context/base/mkiv/meta-fnt.lua @@ -66,7 +66,7 @@ local flusher = { if inline then characters[slot] = { commands = { - { "special", "pdf:" .. code }, + { "pdf", code }, } } else diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua index 2fdea49c1..bd8cc7964 100644 --- a/tex/context/base/mkiv/node-syn.lua +++ b/tex/context/base/mkiv/node-syn.lua @@ -6,33 +6,51 @@ if not modules then modules = { } end modules ['node-syn'] = { license = "see context related readme files" } --- Because we have these fields in some node that are used by synctex, 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. +-- Because we have these fields in some node that are used by synctex, and because +-- some users seem to like that feature, I decided 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. Currently (somewhere else) we +-- take care of valid files, that is: we prohibit access to files in the tree +-- because we don't want users to mess up styles. -- --- 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. +-- It is unclear how the output gets interpreted but by reverse engineering (and +-- stripping) the file generated by generic synctex, I got there eventually. 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. Anyway, I was able to get a +-- minimal output and cross my fingers that the parser used in editors is not +-- changed in fundamental ways. -- --- Possible optimizations: pack whole lines. - --- InverseSearchCmdLine = mtxrun.exe --script synctex --edit --name="%f" --line="%l" $ - --- Unfortunately syntex always removes the files at the end and not at the start (it --- happens in synctexterminate). This forces us to use an intermediate file, no big deal --- in context (which has a runner) but definitely not nice. +-- I only tested SumatraPDF with SciTE, for which one needs to configure in the +-- viewer: +-- +-- InverseSearchCmdLine = c:\data\system\scite\wscite\scite.exe "%f" "-goto:%l" $ +-- +-- Unfortunately syntex always removes the files at the end and not at the start +-- (this happens in synctexterminate) so we need to work around that by using an +-- intermediate file. This is no big deal in context (which has a runner) but +-- definitely not nice. +-- +-- The visualizer code is only needed for testing so we don't use fancy colors or +-- provide more detail. After all we're only interested in rendered source text +-- anyway. We try to play safe which sometimes means that we'd better no go +-- somewhere than go someplace wrong. +-- +-- A previous version had a mode for exporting boxes and such but I removed that +-- as it made no sense. Also, collecting output in a table was not faster than +-- directly piping to the file, probably because the amount is not that large. We +-- keep some left-overs commented. local type, rawset = type, rawset local concat = table.concat local formatters = string.formatters -local replacesuffix = file.replacesuffix - -local trace = false trackers.register("system.synctex.visualize", function(v) trace = v end) +local replacesuffix, suffixonly, nameonly = file.replacesuffix, file.suffix, file.nameonly +local openfile, renamefile, removefile = io.open, os.rename, os.remove local report_system = logs.reporter("system") +local tex = tex + local nuts = nodes.nuts local tonut = nuts.tonut local tonode = nuts.tonode @@ -48,14 +66,13 @@ local getsubtype = nuts.getsubtype local nodecodes = nodes.nodecodes local kerncodes = nodes.kerncodes +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc local glue_code = nodecodes.glue local kern_code = nodecodes.kern -local kern_disc = nodecodes.disc -local rule_code = nodecodes.rule ------ math_code = nodecodes.math +----- rule_code = nodecodes.rule 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 @@ -77,36 +94,31 @@ local force_synctex_tag = tex.force_synctex_tag local force_synctex_line = tex.force_synctex_line ----- get_synctex_tag = tex.get_synctex_tag ----- get_synctex_line = tex.get_synctex_line - -local getcount = tex.getcount -local setcount = tex.setcount +local set_synctex_mode = tex.set_synctex_mode local getpos = function() getpos = backends.codeinjections.getpos return getpos() end +local foundintree = resolvers.foundintree local eol = "\010" -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 foundintree = resolvers.foundintree -local suffixonly = file.suffix -local nameonly = file.nameonly - -local synctex = { } +----- f_glue = formatters["g%i,%i:%i,%i\010"] +----- f_glyph = formatters["x%i,%i:%i,%i\010"] +----- f_kern = formatters["k%i,%i:%i,%i:%i\010"] +----- f_rule = formatters["r%i,%i:%i,%i:%i,%i,%i\010"] +----- f_hlist = formatters["[%i,%i:%i,%i:%i,%i,%i\010"] +----- f_vlist = formatters["(%i,%i:%i,%i:%i,%i,%i\010"] +local z_hlist = "[0,0:0,0:0,0,0\010" +local z_vlist = "(0,0:0,0:0,0,0\010" +local s_hlist = "]\010" +local s_vlist = ")\010" +local f_hvoid = formatters["h%i,%i:%i,%i:%i,%i,%i\010"] +----- f_vvoid = formatters["v%i,%i:%i,%i:%i,%i,%i\010"] + +local synctex = luatex.synctex or { } luatex.synctex = synctex -- the file name stuff @@ -168,22 +180,19 @@ end -- the node stuff -local result = { } -local r = 0 -local f = nil +local filehandle = nil local nofsheets = 0 local nofobjects = 0 local last = 0 local filesdone = 0 local enabled = false -local compact = true -local fulltrace = false +local tmpfile = false local logfile = false local used = false local function writeanchor() - local size = f:seek("end") - f:write("!" .. (size-last) ..eol) + local size = filehandle:seek("end") + filehandle:write("!",size-last,eol) last = size end @@ -191,310 +200,295 @@ local function writefiles() local total = #stnums if filesdone < total then for i=filesdone+1,total do - f:write("Input:"..i..":"..stnums[i]..eol) + filehandle:write("Input:",i,":",stnums[i],eol) end filesdone = total end end +local function makenames() + logfile = replacesuffix(tex.jobname,"synctex") + tmpfile = replacesuffix(logfile,"syncctx") +end + local function flushpreamble() - logfile = replacesuffix(tex.jobname,"syncctx") - f = io.open(logfile,"wb") - f:write("SyncTeX Version:1"..eol) - writefiles() - f:write("Output:pdf"..eol) - f:write("Magnification:1000"..eol) - f:write("Unit:1"..eol) - f:write("X Offset:0"..eol) - f:write("Y Offset:0"..eol) - f:write("Content:"..eol) - flushpreamble = writefiles + makenames() + filehandle = openfile(tmpfile,"wb") + if filehandle then + filehandle:write("SyncTeX Version:1",eol) + writefiles() + filehandle:write("Output:pdf",eol) + filehandle:write("Magnification:1000",eol) + filehandle:write("Unit:1",eol) + filehandle:write("X Offset:0",eol) + filehandle:write("Y Offset:0",eol) + filehandle:write("Content:",eol) + flushpreamble = function() + writefiles() + return filehandle + end + else + enabled = false + end + return filehandle end function synctex.wrapup() - if logfile then - os.rename(logfile,replacesuffix(logfile,"synctex")) + if tmpfile then + renamefile(tmpfile,logfile) end end local function flushpostamble() - if not f then + if not filehandle then return end writeanchor() - f:write("Postamble:"..eol) - f:write("Count:"..nofobjects..eol) + filehandle:write("Postamble:",eol) + filehandle:write("Count:",nofobjects,eol) writeanchor() - f:write("Post scriptum:"..eol) - f:close() + filehandle:write("Post scriptum:",eol) + filehandle: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)) +-- local function doaction(action,t,l,w,h,d) +-- local x, y = getpos() +-- filehandle:write(action(t,l,x,tex.pageheight-y,w,h,d)) +-- nofobjects = nofobjects + 1 -- 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)) +-- +-- local function noaction(action) +-- filehandle:write(action) +-- nofobjects = nofobjects + 1 -- 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)) +-- +-- local function b_vlist(head,current,t,l,w,h,d) +-- return insert_before(head,current,new_latelua(function() doaction(f_vlist,t,l,w,h,d) 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)) +-- +-- local function b_hlist(head,current,t,l,w,h,d) +-- return insert_before(head,current,new_latelua(function() doaction(f_hlist,t,l,w,h,d) end)) +-- end +-- +-- local function e_vlist(head,current) +-- return insert_after(head,current,new_latelua(noaction(s_vlist))) -- end +-- +-- local function e_hlist(head,current) +-- return insert_after(head,current,new_latelua(noaction(s_hlist))) +-- end +-- +-- local function x_vlist(head,current,t,l,w,h,d) +-- return insert_before(head,current,new_latelua(function() doaction(f_vvoid,t,l,w,h,d) end)) +-- end +-- +-- local function x_hlist(head,current,t,l,w,h,d) +-- return insert_before(head,current,new_latelua(function() doaction(f_hvoid,t,l,w,h,d) end)) +-- end + +local function doaction(t,l,w,h,d) + local x, y = getpos() + filehandle:write(f_hvoid(t,l,x,tex.pageheight-y,w,h,d)) + nofobjects = nofobjects + 1 +end --- todo: why not only lines --- todo: larger ranges +local function x_hlist(head,current,t,l,w,h,d) + return insert_before(head,current,new_latelua(function() doaction(t,l,w,h,d) end)) +end -- color is already handled so no colors --- we can have ranges .. more efficient but a bit more complex to analyze ... some day +local collect = nil +local fulltrace = false +local trace = false +local height = 10 * 65536 +local depth = 5 * 65536 +local traceheight = 32768 +local tracedepth = 32768 + +trackers.register("system.synctex.visualize", function(v) + trace = v + fulltrace = v == "real" +end) + +local function inject(head,first,last,tag,line) + local w, h, d = getdimensions(first,getnext(last)) + if h < height then + h = height + end + if d < depth then + d = depth + end + if trace then + head = insert_before(head,first,new_hlist(new_rule(w,fulltrace and h or traceheight,fulltrace and d or tracedepth))) + end + head = x_hlist(head,first,tag,line,w,h,d) + return head +end -local function collect(head,t,l,dp,ht) +local function collect_min(head) local current = head while current do local id = getid(current) if id == glyph_code then local first = current local last = current + local tag = 0 + local line = 0 while true do - id = getid(current) - -- traditionally glyphs have no synctex code which works sort of ok - -- but not when we don't leave hmode cq. have no par - -- - if id == glyph_code or id == disc_code then + if id == glyph_code then local tc, lc = get_synctex_fields(current) if tc and tc > 0 then - t, l = tc, lc + tag = tc + line = lc end last = current - elseif id == kern_code and getsubtype(current) == fontkern_code then - local tc, lc = get_synctex_fields(current) - if tc and tc > 0 then - t, l = tc, lc - end + elseif id == disc_code or (id == kern_code and getsubtype(current) == fontkern_code) 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 dp and d < dp then d = dp end - if ht and h < ht then h = ht end - if h < 655360 then h = 655360 end - if d < 327680 then d = 327680 end - if trace then - head = insert_before(head,first,new_hlist(new_rule(w,fulltrace and h or 32768,fulltrace and d or 32768))) + if tag > 0 then + head = inject(head,first,last,tag,line) 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 dp and d < dp then d = dp end - if ht and h < ht then h = ht end - if h < 655360 then h = 655360 end - if d < 327680 then d = 327680 end - if trace then - head = insert_before(head,first,new_hlist(new_rule(w,fulltrace and h or 32768,fulltrace and d or 32768))) + if current then + id = getid(current) + else + if tag > 0 then + head = inject(head,first,last,tag,line) end - head = x_hlist(head,first,t,l,w,h,d) return head end end end - if id == hlist_code then + -- pick up (as id can have changed) + if id == hlist_code or 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 + if list then + local l = collect(list) + if l ~= list then + setlist(current,l) 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 + current = getnext(current) + end + return head +end + +collect = collect_max + +local function inject(parent,head,first,last,tag,line) + local w, h, d = getrangedimensions(parent,first,getnext(last)) + if h < height then + h = height + end + if d < depth then + d = depth + end + if trace then + head = insert_before(head,first,new_hlist(new_rule(w,fulltrace and h or traceheight,fulltrace and d or tracedepth))) + end + head = x_hlist(head,first,tag,line,w,h,d) + return head +end + +local function collect_max(head,parent) + local current = head + while current do + local id = getid(current) + if id == glyph_code then + local first = current + local last = current + local tag = 0 + local line = 0 + while true do + if id == glyph_code then + local tc, lc = get_synctex_fields(current) + if tc and tc > 0 then + if tag > 0 and (tag ~= tc or line ~= lc) then + head = inject(parent,head,first,last,tag,line) + first = current end + tag = tc + line = lc + last = current + else + if tag > 0 then + head = inject(parent,head,first,last,tag,line) + tag = 0 + end + first = nil + last = nil end - elseif list then - -- head = b_hlist(head,current,t,l,w,h,d) - head = b_hlist(head,current,0,0,w,h,d) -- todo: only d h when line - local l = collect(list,t,l,d,h) - if l ~= list then - setlist(current,l) + elseif id == disc_code then + if not first then + first = current 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) -- todo: only d h when line - 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) + last = current + elseif id == kern_code and getsubtype(current) == fontkern_code then + if first then + last = current 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) + elseif id == glue_code then + if tag > 0 then + local tc, lc = get_synctex_fields(current) + if tc and tc > 0 then + if tag ~= tc or line ~= lc then + head = inject(parent,head,first,last,tag,line) + tag = 0 + break + end + else + head = inject(parent,head,first,last,tag,line) + tag = 0 + break end + else + tag = 0 + break 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) + id = nil -- so no test later on + else + if tag > 0 then + head = inject(parent,head,first,last,tag,line) + tag = 0 end - head, current = e_vlist(head,current) + break + end + current = getnext(current) + if current then + id = getid(current) else - -- head = x_vlist(head,current,t,l,w,h,d) - head = x_vlist(head,current,0,0,w,h,d) + if tag > 0 then + head = inject(parent,head,first,last,tag,line) + end + return head end end - elseif id == glue_code then - local tc, lc = get_synctex_fields(current) - if tc > 0 then - t, l = tc, lc + end + -- pick up(as id can have changed) + if id == hlist_code or id == vlist_code then + local list = getlist(current) + if list then + local l = collect(list,current) + if l ~= list then + setlist(current,l) + end 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 + local h = tonut(head) + h = collect(h,h) + return tonode(h), true else return head, false end @@ -502,106 +496,73 @@ end -- also no solution for bad first file resolving in sumatra -function synctex.flush() +function synctex.start() if enabled then nofsheets = nofsheets + 1 -- could be realpageno - flushpreamble() - writeanchor() - f:write("{"..nofsheets..eol) - if compact then - -- f:write(f_vlist(0,0,0,0,tex.pagewidth,tex.pageheight,0)) - f:write(f_hlist(0,0,0,0,0,0,0)) - f:write(eol) - f:write(f_vlist(0,0,0,0,0,0,0)) - f:write(eol) + if flushpreamble() then + writeanchor() + filehandle:write("{",nofsheets,eol) + filehandle:write(z_hlist,z_vlist) end - f:write(concat(result,eol)) - if compact then - f:write(eol) - f:write(s_vlist) - f:write(eol) - f:write(s_hlist) - end - f:write(eol) + end +end + +function synctex.stop() + if enabled then + filehandle:write(s_vlist,s_hlist) writeanchor() - f:write("}"..nofsheets..eol) + filehandle:write("}",nofsheets,eol) nofobjects = nofobjects + 2 - result, r = { }, 0 end end -local details = 1 -local state = 0 - -directives.register("system.synctex.details",function(v) - details = tonumber(v) or 1 -end) - -local set_synctex_mode = tex.set_synctex_mode - -if set_synctex_mode then - - function synctex.enable() - if not enabled then - enabled = true - state = details or 1 - set_synctex_mode(state) - if not used then - directives.enable("system.synctex.xml") - nodes.tasks.appendaction("shipouts", "after", "nodes.synctex.collect") - report_system("synctex functionality is enabled, expect runtime overhead!") - used = true - end - elseif state > 0 then - set_synctex_mode(state) +function synctex.enable() + if not enabled then + enabled = true + set_synctex_mode(3) -- we want details + if not used then + directives.enable("system.synctex.xml") + nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect") + report_system("synctex functionality is enabled, expect 5-10 pct runtime overhead!") + used = true end end +end - function synctex.disable() - if enabled then - set_synctex_mode(0) - report_system("synctex functionality is disabled!") - enabled = false - end +function synctex.disable() + if enabled then + set_synctex_mode(0) + report_system("synctex functionality is disabled!") + enabled = false end +end - function synctex.finish() - if enabled then - flushpostamble() - else - os.remove(replacesuffix(tex.jobname,"syncctx")) - os.remove(replacesuffix(tex.jobname,"synctex")) - end +function synctex.finish() + if enabled then + flushpostamble() + else + makenames() + removefile(logfile) + removefile(tmpfile) end +end - function synctex.pause() - if enabled then - set_synctex_mode(0) - end +function synctex.pause() + if enabled then + set_synctex_mode(0) end +end - function synctex.resume() - if enabled then - set_synctex_mode(state) - end +function synctex.resume() + if enabled then + set_synctex_mode(3) end - -else - - function synctex.enable () end - function synctex.disable() end - function synctex.finish () end - function synctex.pause () end - function synctex.resume () end - end -- not the best place luatex.registerstopactions(synctex.finish) -nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect") - directives.register("system.synctex", function(v) if v then synctex.enable() @@ -612,7 +573,8 @@ end) statistics.register("synctex tracing",function() if used then - return string.format("%i referenced files, %i files ignored, logfile: %s",noftags,nofblocked,logfile) + return string.format("%i referenced files, %i files ignored, %i objects flushed, logfile: %s", + noftags,nofblocked,nofobjects,logfile) end end) @@ -634,13 +596,25 @@ interfaces.implement { } interfaces.implement { - name = "synctexenable", - actions = synctex.enable, -} - -interfaces.implement { - name = "synctexdisable", - actions = synctex.disable, + name = "setupsynctex", + arguments = { + { + { "state" }, + { "method" }, + }, + }, + actions = function(t) + if t.method == interfaces.variables.max then + collect = collect_max + else + collect = collect_min + end + if t.state == interfaces.variables.start then + synctex.enable() + else + synctex.disable() + end + end } interfaces.implement { diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 933402892..72baf08cc 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 3334c4ae9..b33293a23 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/trac-inf.lua b/tex/context/base/mkiv/trac-inf.lua index d09fce77a..99fe30a6e 100644 --- a/tex/context/base/mkiv/trac-inf.lua +++ b/tex/context/base/mkiv/trac-inf.lua @@ -84,7 +84,7 @@ local seconds = function(n) return n or 0 end local function starttiming(instance) local timer = timers[instance or "notimer"] - local it = timer.timing or 0 + local it = timer.timing if it == 0 then timer.starttime = ticks() if not timer.loadtime then @@ -116,7 +116,7 @@ end local function elapsed(instance) if type(instance) == "number" then - return instance or 0 + return instance else local timer = timers[instance or "notimer"] return timer and seconds(timer.loadtime) or 0 diff --git a/tex/context/base/mkiv/util-fil.lua b/tex/context/base/mkiv/util-fil.lua index 01bcd571e..6100f36f6 100644 --- a/tex/context/base/mkiv/util-fil.lua +++ b/tex/context/base/mkiv/util-fil.lua @@ -35,7 +35,10 @@ function files.close(f) end function files.size(f) - return f:seek("end") + local current = f:seek() + local size = f:seek("end") + f:seek("set",current) + return size end files.getsize = files.size diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml index 404f8da89..aaf0594b2 100644 --- a/tex/context/interface/mkii/keys-de.xml +++ b/tex/context/interface/mkii/keys-de.xml @@ -693,6 +693,7 @@ <cd:constant name='bottomoffset' value='untenoffset'/> <cd:constant name='bottomspace' value='bottomspace'/> <cd:constant name='bottomstate' value='untenstatus'/> + <cd:constant name='break' value='break'/> <cd:constant name='buffer' value='buffer'/> <cd:constant name='cache' value='cache'/> <cd:constant name='calculate' value='berechnen'/> diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index a4566c4b4..7f7fc14ad 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -693,6 +693,7 @@ <cd:constant name='bottomoffset' value='offsetjos'/> <cd:constant name='bottomspace' value='spatiujos'/> <cd:constant name='bottomstate' value='starejos'/> + <cd:constant name='break' value='break'/> <cd:constant name='buffer' value='buffer'/> <cd:constant name='cache' value='cache'/> <cd:constant name='calculate' value='calculeaza'/> diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 365dc0f01..42aaf874c 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex f656c5953..1ad38df61 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/context/modules/common/s-abr-01.tex b/tex/context/modules/common/s-abr-01.tex index 9a6679066..632c902b1 100644 --- a/tex/context/modules/common/s-abr-01.tex +++ b/tex/context/modules/common/s-abr-01.tex @@ -246,6 +246,7 @@ \logo [SVG] {svg} \logo [STIX] {Stix} \logo [SUMATRAPDF] {SumatraPDF} +\logo [SYNCTEX] {Sync\TeX} \logo [SWIG] {swig} \logo [SWIGLIB] {SwigLib} \logo [TABLE] {\TaBlE} diff --git a/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua b/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua index 793526f7b..1fc1c79f7 100644 --- a/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua +++ b/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua @@ -8,6 +8,14 @@ if not modules then modules = { } end modules ['luatex-fonts-demo-vf-1'] = { local identifiers = fonts.hashes.identifiers +local defaults = { + { "pdf", "0 g" }, + { "pdf", "1 0 0 rg" }, + { "pdf", "0 1 0 rg" }, + { "pdf", "0 0 1 rg" }, + { "pdf", "0 0 1 rg" }, +} + return function(specification) local f1, id1 = fonts.constructors.readanddefine('lmroman10-regular', specification.size) local f2, id2 = fonts.constructors.readanddefine('lmsans10-regular', specification.size) @@ -20,12 +28,8 @@ return function(specification) { id = id2 }, { id = id3 }, } - local color = { [0] = - { "special", "pdf:0 g" }, - { "special", "pdf:1 0 0 rg" }, - { "special", "pdf:0 1 0 rg" }, - { "special", "pdf:0 0 1 rg" }, - { "special", "pdf:0 0 1 rg" }, + local color = { + [0] = defaults, } local chars = { identifiers[id1].characters, diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index ed9c29f78..51e10df43 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 : 06/30/17 19:45:43 +-- merge date : 07/05/17 23:01:18 do -- begin closure to overcome local limits and interference @@ -4306,7 +4306,10 @@ function files.close(f) f:close() end function files.size(f) - return f:seek("end") + local current=f:seek() + local size=f:seek("end") + f:seek("set",current) + return size end files.getsize=files.size function files.setposition(f,n) @@ -16422,12 +16425,12 @@ function readers.gdef(f,fontdata,specification) local tableoffset=datatable.offset setposition(f,tableoffset) local version=readulong(f) - local classoffset=tableoffset+readushort(f) - local attachmentoffset=tableoffset+readushort(f) - local ligaturecarets=tableoffset+readushort(f) - local markclassoffset=tableoffset+readushort(f) - local marksetsoffset=version>=0x00010002 and (tableoffset+readushort(f)) - local varsetsoffset=version>=0x00010003 and (tableoffset+readulong(f)) + local classoffset=readushort(f) + local attachmentoffset=readushort(f) + local ligaturecarets=readushort(f) + local markclassoffset=readushort(f) + local marksetsoffset=version>=0x00010002 and readushort(f) or 0 + local varsetsoffset=version>=0x00010003 and readulong(f) or 0 local glyphs=fontdata.glyphs local marks={} local markclasses=setmetatableindex("table") @@ -16435,54 +16438,59 @@ function readers.gdef(f,fontdata,specification) fontdata.marks=marks fontdata.markclasses=markclasses fontdata.marksets=marksets - setposition(f,classoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - local class=classes[readushort(f)] - if class=="mark" then - marks[index]=true - end - glyphs[index].class=class - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do + if classoffset~=0 then + setposition(f,tableoffset+classoffset) + local classformat=readushort(f) + if classformat==1 then local firstindex=readushort(f) - local lastindex=readushort(f) - local class=classes[readushort(f)] - if class then - for index=firstindex,lastindex do - glyphs[index].class=class - if class=="mark" then - marks[index]=true + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + local class=classes[readushort(f)] + if class=="mark" then + marks[index]=true + end + glyphs[index].class=class + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=classes[readushort(f)] + if class then + for index=firstindex,lastindex do + glyphs[index].class=class + if class=="mark" then + marks[index]=true + end end end end end end - setposition(f,markclassoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - markclasses[readushort(f)][index]=true - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do + if markclassoffset~=0 then + setposition(f,tableoffset+markclassoffset) + local classformat=readushort(f) + if classformat==1 then local firstindex=readushort(f) - local lastindex=readushort(f) - local class=markclasses[readushort(f)] + local lastindex=firstindex+readushort(f)-1 for index=firstindex,lastindex do - class[index]=true + markclasses[readushort(f)][index]=true + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=markclasses[readushort(f)] + for index=firstindex,lastindex do + class[index]=true + end end end end - if marksetsoffset and marksetsoffset>tableoffset then + if marksetsoffset~=0 then + marksetsoffset=tableoffset+marksetsoffset setposition(f,marksetsoffset) local format=readushort(f) if format==1 then @@ -16500,8 +16508,8 @@ function readers.gdef(f,fontdata,specification) end end local factors=specification.factors - if (specification.variable or factors) and varsetsoffset and varsetsoffset>tableoffset then - local regions,deltas=readvariationdata(f,varsetsoffset,factors) + if (specification.variable or factors) and varsetsoffset~=0 then + local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors) if factors then fontdata.temporary.getdelta=function(outer,inner) local delta=deltas[outer+1] @@ -19484,7 +19492,7 @@ 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.030 +otf.version=3.031 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) @@ -22304,7 +22312,11 @@ local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kern local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end) local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) +local forcediscretionaries=false local optimizekerns=true +directives.register("otf.forcediscretionaries",function(v) + forcediscretionaries=v +end) local report_direct=logs.reporter("fonts","otf direct") local report_subchain=logs.reporter("fonts","otf subchain") local report_chain=logs.reporter("fonts","otf chain") @@ -22369,6 +22381,7 @@ local disc_code=nodecodes.disc local math_code=nodecodes.math local dir_code=nodecodes.dir local localpar_code=nodecodes.localpar +local discretionary_code=disccodes.discretionary local ligature_code=glyphcodes.ligature local a_state=attributes.private('state') local a_noligature=attributes.private("noligature") @@ -22645,7 +22658,11 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou setboth(base) set_components(base,copied) replace=base - setdisc(discfound,pre,post,replace) + if forcediscretionaries then + setdisc(discfound,pre,post,replace,discretionary_code) + else + setdisc(discfound,pre,post,replace) + end base=prev end end @@ -27706,8 +27723,8 @@ local setmetatableindex=table.setmetatableindex local formatters=string.formatters local tounicode=fonts.mappings.tounicode local otf=fonts.handlers.otf -local f_color=formatters["pdf:direct:%f %f %f rg"] -local f_gray=formatters["pdf:direct:%f g"] +local f_color=formatters["%f %f %f rg"] +local f_gray=formatters["%f g"] if context then local startactualtext=nil local stopactualtext=nil @@ -27728,7 +27745,7 @@ else end local sharedpalettes={} local hash=setmetatableindex(function(t,k) - local v={ "special",k } + local v={ "pdf","direct",k } t[k]=v return v end) @@ -27752,11 +27769,11 @@ if context then t=transparencies[v] end if c and t then - values[i]=hash["pdf:direct:"..lpdf.color(1,c).." "..lpdf.transparency(t)] + values[i]=hash[lpdf.color(1,c).." "..lpdf.transparency(t)] elseif c then - values[i]=hash["pdf:direct:"..lpdf.color(1,c)] + values[i]=hash[lpdf.color(1,c)] elseif t then - values[i]=hash["pdf:direct:"..lpdf.color(1,t)] + values[i]=hash[lpdf.color(1,t)] end end end @@ -27787,6 +27804,8 @@ local function convert(t,k) t[k]=v return v end +local start={ "pdf","page","q" } +local stop={ "pdf","raw","Q" } local function initializecolr(tfmdata,kind,value) if value then local resources=tfmdata.resources @@ -27817,12 +27836,10 @@ local function initializecolr(tfmdata,kind,value) local getactualtext=otf.getactualtext local default=colorvalues[#colorvalues] local b,e=getactualtext(tounicode(0xFFFD)) - local start={ "special","pdf:page:q" } - local stop={ "special","pdf:raw:Q" } - local actualb={ "special","pdf:page:"..b } - local actuale={ "special","pdf:page:"..e } + local actualb={ "pdf","page",b } + local actuale={ "pdf","page",e } local cache=setmetatableindex(function(t,k) - local v={ "char",k } + local v={ "char",k } t[k]=v return v end) @@ -27837,7 +27854,7 @@ local function initializecolr(tfmdata,kind,value) local goback=w~=0 and widths[w] or nil local t={ start, - not u and actualb or { "special","pdf:raw:"..getactualtext(tounicode(u)) } + not u and actualb or { "pdf","raw",getactualtext(tounicode(u)) } } local n=2 local l=nil @@ -27927,11 +27944,11 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local ht=character.height or 0 local dp=character.depth or 0 character.commands={ - { "special","pdf:direct:"..bt }, + { "pdf","direct",bt }, { "down",dp+dy*hfactor }, { "right",dx*hfactor }, { "image",{ filename=name,width=wd,height=ht,depth=dp } }, - { "special","pdf:direct:"..et }, + { "pdf","direct",et }, } character[kind]=true end |