From b061ca19f9a8721105957f51448400425adaf7e8 Mon Sep 17 00:00:00 2001 From: Marius Date: Sat, 9 Nov 2013 21:40:13 +0200 Subject: beta 2013.11.09 20:21 --- tex/context/base/buff-ini.lua | 114 +++- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4112 -> 4108 bytes tex/context/base/context.mkiv | 2 +- tex/context/base/core-uti.lua | 34 +- tex/context/base/font-syn.lua | 64 +- tex/context/base/luat-run.lua | 14 +- tex/context/base/math-ali.mkiv | 10 +- tex/context/base/node-ltp.lua | 443 ++++++------- tex/context/base/status-files.pdf | Bin 25448 -> 24551 bytes tex/context/base/status-lua.pdf | Bin 253261 -> 222470 bytes tex/context/base/strc-mat.mkiv | 57 +- tex/context/base/trac-par.lua | 125 ++++ tex/context/base/typo-tal.lua | 4 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 732 ++++++++++----------- 15 files changed, 912 insertions(+), 689 deletions(-) create mode 100644 tex/context/base/trac-par.lua (limited to 'tex') diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua index a8c101b61..08416c9ad 100644 --- a/tex/context/base/buff-ini.lua +++ b/tex/context/base/buff-ini.lua @@ -12,9 +12,9 @@ local sub, format = string.sub, string.format local splitlines, validstring = string.splitlines, string.valid local P, Cs, patterns, lpegmatch = lpeg.P, lpeg.Cs, lpeg.patterns, lpeg.match -local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end) -local trace_grab = false trackers.register("buffers.grab", function(v) trace_grab = v end) -local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end) +local trace_run = false trackers .register("buffers.run", function(v) trace_run = v end) +local trace_grab = false trackers .register("buffers.grab", function(v) trace_grab = v end) +local trace_visualize = false trackers .register("buffers.visualize", function(v) trace_visualize = v end) local report_buffers = logs.reporter("buffers","usage") local report_typeset = logs.reporter("buffers","typeset") @@ -29,6 +29,8 @@ local formatters = string.formatters local addsuffix = file.addsuffix local replacesuffix = file.replacesuffix +local registertempfile = luatex.registertempfile + local v_yes = variables.yes local catcodenumbers = catcodes.numbers @@ -97,7 +99,7 @@ local function getnames(name) end local function istypeset(name) - local names = getnames(name) + local names = getnames(name) if #names == 0 then return false end @@ -339,39 +341,93 @@ function commands.savebuffer(list,name,prefix) -- name is optional io.savedata(name,content) end -local files = { } -local last = 0 - -function commands.runbuffer(name,encapsulate) -- we used to compare the saved file with content - local names = getnames(name) - local filename = files[name] - local tobedone = not istypeset(names) - if tobedone or not filename then - last = last + 1 - filename = formatters["%s-typeset-buffer-%03i"](tex.jobname,last) - files[name] = filename +-- local files = { } +-- local last = 0 +-- +-- function commands.runbuffer(name,encapsulate) -- we used to compare the saved file with content +-- local names = getnames(name) +-- local filename = files[name] +-- local tobedone = not istypeset(names) +-- if tobedone or not filename then +-- last = last + 1 +-- filename = formatters["%s-typeset-buffer-%03i"](tex.jobname,last) +-- files[name] = filename +-- end +-- if tobedone then +-- if trace_run then +-- report_typeset("changes in %a, processing forced",name) +-- end +-- local filename = addsuffix(filename,"tmp") +-- local content = collectcontent(names,nil) or "" +-- if content == "" then +-- content = "empty buffer" +-- end +-- if encapsulate then +-- content = formatters["\\starttext\n%s\n\\stoptext\n"](content) +-- end +-- io.savedata(filename,content) +-- local command = formatters["context %s %s"](jit and "--jit" or "",filename) +-- report_typeset("running: %s\n",command) +-- os.execute(command) +-- markastypeset(names) +-- elseif trace_run then +-- report_typeset("no changes in %a, not processed",name) +-- end +-- context(replacesuffix(filename,"pdf")) +-- end + +-- we can consider adding a size to avoid unlikely clashes + +local oldhashes = nil +local newhashes = nil + +function commands.runbuffer(name,encapsulate) + if not oldhashes then + oldhashes = job.datasets.getdata("typeset buffers","hashes") or { } + for hash, n in next, oldhashes do + local tag = formatters["%s-t-b-%s"](tex.jobname,hash) + registertempfile(addsuffix(tag,"tmp")) -- to be sure + registertempfile(addsuffix(tag,"pdf")) + end + newhashes = { } + job.datasets.setdata { + name = "typeset buffers", + tag = "hashes", + data = newhashes, + } + end + local names = getnames(name) + local content = collectcontent(names,nil) or "" + if content == "" then + content = "empty buffer" + end + if encapsulate then + content = formatters["\\starttext\n%s\n\\stoptext\n"](content) end - if tobedone then + -- + local hash = md5.hex(content) + local tag = formatters["%s-t-b-%s"](tex.jobname,hash) + -- + local filename = addsuffix(tag,"tmp") + local resultname = addsuffix(tag,"pdf") + -- + if newhashes[hash] then + -- done + elseif not oldhashes[hash] or not lfs.isfile(resultname) then if trace_run then report_typeset("changes in %a, processing forced",name) end - local filename = addsuffix(filename,"tmp") - local content = collectcontent(names,nil) or "" - if content == "" then - content = "empty buffer" - end - if encapsulate then - content = formatters["\\starttext\n%s\n\\stoptext\n"](content) - end io.savedata(filename,content) - local command = formatters["context %s %s"](jit and "--jit" or "",filename) + local command = formatters["context --purgeall %s %s"](jit and "--jit" or "",filename) report_typeset("running: %s\n",command) os.execute(command) - markastypeset(names) - elseif trace_run then - report_typeset("no changes in %a, not processed",name) end - context(replacesuffix(filename,"pdf")) + newhashes[hash] = (newhashes[hash] or 0) + 1 + report_typeset("no changes in %a, processing skipped",name) + registertempfile(filename) + registertempfile(resultname,nil,true) + -- + context(resultname) end function commands.getbuffer(name) diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 36c173d60..d23a87ebc 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.11.08 11:50} +\newcontextversion{2013.11.09 20:21} %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/context-version.pdf b/tex/context/base/context-version.pdf index c4c7d70d0..462dc5b36 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index a0250d234..4537e32ea 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2013.11.08 11:50} +\edef\contextversion{2013.11.09 20:21} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index cbbdeff23..d626fa67b 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -36,8 +36,8 @@ local report_passes = logs.reporter("job","passes") job = job or { } local job = job -job.version = 1.22 -- make sure we don't have old lua 5.1 hash leftovers -job.packversion = 1.02 -- make sure we don't have old lua 5.1 hash leftovers +job.version = 1.23 +job.packversion = 1.02 -- some day we will implement loading of other jobs and then we need -- job.jobs @@ -87,12 +87,16 @@ local jobvariables = { checksums = checksums, } +-- if not checksums.old then checksums.old = md5.HEX("old") end -- used in experiment +-- if not checksums.new then checksums.new = md5.HEX("new") end -- used in experiment + job.variables = jobvariables -if not checksums.old then checksums.old = md5.HEX("old") end -- used in experiment -if not checksums.new then checksums.new = md5.HEX("new") end -- used in experiment +local function initializer() + checksums = jobvariables.checksums +end -job.register('job.variables.checksums', checksums) +job.register('job.variables.checksums', 'job.variables.checksums', initializer) local rmethod, rvalue @@ -101,7 +105,6 @@ local setxvalue = context.setxvalue local function initializer() tobesaved = jobvariables.tobesaved collected = jobvariables.collected - checksums = jobvariables.checksums rvalue = collected.randomseed if not rvalue then rvalue = math.random() @@ -123,6 +126,22 @@ function jobvariables.save(cs,value) tobesaved[cs] = value end +-- checksums + +function jobvariables.getchecksum(tag) + return checksums[tag] -- no default +end + +function jobvariables.makechecksum(data) + return data and md5.HEX(data) -- no default +end + +function jobvariables.setchecksum(tag,checksum) + checksums[tag] = checksum +end + +-- + local packlist = { "numbers", "metadata", @@ -156,6 +175,9 @@ function job.save(filename) -- we could return a table but it can get pretty lar local target = format("utilitydata.%s",list[1]) local data = list[2] local finalizer = list[4] + if type(data) == "string" then + data = utilities.tables.accesstable(data) + end if type(finalizer) == "function" then finalizer() end diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index 8af31f222..5b50ac75f 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -263,12 +263,63 @@ filters.ttf = fontloader.info filters.ttc = fontloader.info filters.dfont = fontloader.info -function fontloader.fullinfo(...) -- check with taco what we get / could get +-- We had this as temporary solution because we needed a bit more info but in the +-- meantime it got an interesting side effect: currently luatex delays loading of e.g. +-- glyphs so here we first load and then discard which is a waste. In the past it did +-- free memory because a full load was done. One of these things that goes unnoticed. +-- +-- function fontloader.fullinfo(...) -- check with taco what we get / could get +-- local ff = fontloader.open(...) +-- if ff then +-- local d = ff -- and fontloader.to_table(ff) +-- d.glyphs, d.subfonts, d.gpos, d.gsub, d.lookups = nil, nil, nil, nil, nil +-- fontloader.close(ff) +-- return d +-- else +-- return nil, "error in loading font" +-- end +-- end + +-- Phillip suggested this faster variant but it's still a hack as fontloader.info should +-- return these keys/values (and maybe some more) but at least we close the loader which +-- might save some memory in the end. +-- +-- function fontloader.fullinfo(name) +-- local ff = fontloader.open(name) +-- if ff then +-- local fields = table.tohash(fontloader.fields(ff),true) +-- local d = { +-- names = fields.names and ff.names, +-- familyname = fields.familyname and ff.familyname, +-- fullname = fields.fullname and ff.fullname, +-- fontname = fields.fontname and ff.fontname, +-- weight = fields.weight and ff.weight, +-- italicangle = fields.italicangle and ff.italicangle, +-- units_per_em = fields.units_per_em and ff.units_per_em, +-- design_range_bottom = fields.design_range_bottom and ff.design_range_bottom, +-- design_range_top = fields.design_range_top and ff.design_range_top, +-- design_size = fields.design_size and ff.design_size, +-- italicangle = fields.italicangle and ff.italicangle, +-- pfminfo = fields.pfminfo and ff.pfminfo, +-- } +-- table.setmetatableindex(d,function(t,k) +-- report_names("warning, trying to access field %a in font table of %a",k,name) +-- end) +-- fontloader.close(ff) +-- return d +-- else +-- return nil, "error in loading font" +-- end +-- end + +-- As we have lazy loading anyway, this one still is full and with less code than +-- the previous one. + +function fontloader.fullinfo(...) local ff = fontloader.open(...) if ff then - local d = ff and fontloader.to_table(ff) - d.glyphs, d.subfonts, d.gpos, d.gsub, d.lookups = nil, nil, nil, nil, nil - fontloader.close(ff) + local d = { } -- ff is userdata so [1] or # fails on it + table.setmetatableindex(d,ff) return d else return nil, "error in loading font" @@ -909,9 +960,10 @@ local function analyzefiles(olddata) end end if result == nil then - local result, message = filters[lower(suffix)](completename) + local lsuffix = lower(suffix) + local result, message = filters[lsuffix](completename) if result then - if result[1] then + if #result > 0 then for r=1,#result do local ok = check_name(data,result[r],storedname,modification,suffix,r-1) -- subfonts start at zero -- if not ok then diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua index eaede1030..719a6f7c9 100644 --- a/tex/context/base/luat-run.lua +++ b/tex/context/base/luat-run.lua @@ -103,23 +103,25 @@ callbacks.register("pre_dump", pre_dump_actions, "lua related fi local tempfiles = { } -function luatex.registertempfile(name,extrasuffix) +function luatex.registertempfile(name,extrasuffix,keep) -- namespace might change if extrasuffix then name = name .. ".mkiv-tmp" -- maybe just .tmp end if trace_temp_files and not tempfiles[name] then report_tempfiles("registering temporary file %a",name) end - tempfiles[name] = true + tempfiles[name] = keep or false return name end function luatex.cleanuptempfiles() - for name, _ in next, tempfiles do - if trace_temp_files then - report_tempfiles("removing temporary file %a",name) + for name, keep in next, tempfiles do + if not keep then + if trace_temp_files then + report_tempfiles("removing temporary file %a",name) + end + os.remove(name) end - os.remove(name) end tempfiles = { } end diff --git a/tex/context/base/math-ali.mkiv b/tex/context/base/math-ali.mkiv index 911a0d430..6bfde57b6 100644 --- a/tex/context/base/math-ali.mkiv +++ b/tex/context/base/math-ali.mkiv @@ -980,8 +980,11 @@ \installcorenamespace{mathinnerstart} \installcorenamespace{mathinnerstop} -\unexpanded\def\startinnermath{\csname\??mathinnerstart\formulaparameter\c!align\endcsname} -\unexpanded\def\stopinnermath {\csname\??mathinnerstop \formulaparameter\c!align\endcsname} +% \unexpanded\def\startinnermath{\csname\??mathinnerstart\formulaparameter\c!align\endcsname} +% \unexpanded\def\stopinnermath {\csname\??mathinnerstop \formulaparameter\c!align\endcsname} + +\unexpanded\def\startinnermath{\expandnamespaceparameter\??mathinnerstart\formulaparameter\c!align\v!normal} +\unexpanded\def\stopinnermath {\expandnamespaceparameter\??mathinnerstop \formulaparameter\c!align\v!normal} \unexpanded\def\mathinnerstrut {\doif{\formulaparameter\c!strut}\v!yes\strut} @@ -1090,6 +1093,9 @@ \defineinnermathhandler\v!flushleft {\startmathbox\plusthree}{\stopmathbox} \defineinnermathhandler\v!center {\startmathbox\plustwo }{\stopmathbox} \defineinnermathhandler\v!flushright{\startmathbox\plusone }{\stopmathbox} +\defineinnermathhandler\v!normal {} {} + +%defineinnermathhandler\v!normal {\startmathbox\plustwo }{\stopmathbox} %D [The examples below are in english and don't process in the %D documentation style, which will be english some day.] diff --git a/tex/context/base/node-ltp.lua b/tex/context/base/node-ltp.lua index 97e61cf18..62f922c2a 100644 --- a/tex/context/base/node-ltp.lua +++ b/tex/context/base/node-ltp.lua @@ -13,6 +13,7 @@ if not modules then modules = { } end modules ['node-par'] = { -- todo: permit global steps i.e. using an attribute that sets min/max/step and overloads the font parameters -- todo: split the three passes into three functions -- todo: simplify the direction stack, no copy needed +-- todo: see if we can do without delta nodes (needs thinking) -- todo: add more mkiv like tracing -- todo: add a couple of plugin hooks -- todo: maybe split expansion code paths @@ -90,10 +91,32 @@ if not modules then modules = { } end modules ['node-par'] = { tex vbox 9.84 10.16 0.20 linebreak / 0.52 with hz -> 0.32 hz overhead (150pct more) lua vbox 17.28 18.43 7.64 linebreak / 8.79 with hz -> 1.33 hz overhead ( 20pct more) + new laptop | no nuts + 3.42 baseline + 3.63 0.21 linebreak + 7.38 3.96 linebreak + + new laptop | most nuts + 2.45 baseline + 2.53 0.08 linebreak + 6.16 3.71 linebreak + ltp nuts 5.45 3.00 linebreak + luajittex tex hbox 6.33 6.33 baseline font feature processing, hyphenation etc: 6.33 tex vbox 6.53 6.81 0.20 linebreak / 0.48 with hz -> 0.28 hz overhead (expected 0.32) lua vbox 11.06 11.81 4.53 linebreak / 5.28 with hz -> 0.75 hz overhead + new laptop | no nuts + 2.06 baseline + 2.27 0.21 linebreak + 3.95 1.89 linebreak + + new laptop | most nuts + 1.25 baseline + 1.30 0.05 linebreak + 3.03 1.78 linebreak + ltp nuts 2.47 1.22 linebreak + Interesting is that the runtime for the built-in parbuilder indeed increases much when expansion is enabled, but in the Lua variant the extra overhead is way less significant. This means that when we retrofit the same approach into the core, the overhead of expansion can be sort of nilled. @@ -103,7 +126,7 @@ if not modules then modules = { } end modules ['node-par'] = { local utfchar = utf.char local write, write_nl = texio.write, texio.write_nl local sub, format = string.sub, string.format -local round = math.round +local round, floor = math.round, math.floor local insert, remove = table.insert, table.remove local fonts, nodes, node = fonts, nodes, node @@ -265,6 +288,7 @@ local glyphdir_is_equal = nodes.glyphdir_is_equal local dir_pops = nodes.dir_is_pop local dir_negations = nodes.dir_negation local is_skipable = node.protrusion_skippable +local a_fontkern = attributes.private('fontkern') -- helpers -- @@ -389,7 +413,7 @@ local function calculate_fraction(x,n,d,max_answer) end local function check_shrinkage(par,n) - -- called often, so maybe move inline + -- called often, so maybe move inline -- use NORMAL if n.shrink_order ~= 0 and n.shrink ~= 0 then if par.no_shrink_error_yet then par.no_shrink_error_yet = false @@ -407,7 +431,7 @@ end local expansions = { } local nothing = { stretch = 0, shrink = 0 } -setmetatableindex(expansions,function(t,font) +setmetatableindex(expansions,function(t,font) -- we can store this in tfmdata if needed local expansion = parameters[font].expansion -- can be an extra hash if expansion and expansion.auto then local factors = { } @@ -426,7 +450,7 @@ setmetatableindex(expansions,function(t,font) glyphshrink = shrink * ef_quad, factor = factor, stretch = stretch, - shrink = shrink , + shrink = shrink, } t[char] = v return v @@ -503,6 +527,8 @@ local function kern_stretch_shrink(p,d) end local function kern_stretch_shrink(p,d) + -- maybe make it an option in luatex where we also need to check for attribute fontkern but in general + -- it makes no sense to scale kerns return 0, 0 end @@ -514,6 +540,7 @@ local function check_expand_pars(checked_expansion,f) checked_expansion[f] = false return false end +expansion.step = 1 local step = expansion.step or 0 local stretch = expansion.stretch or 0 local shrink = expansion.shrink or 0 @@ -561,6 +588,7 @@ local function check_expand_lines(checked_expansion,f) checked_expansion[f] = false return false end +expansion.step = 1 local step = expansion.step or 0 local stretch = expansion.stretch or 0 local shrink = expansion.shrink or 0 @@ -796,7 +824,8 @@ local function append_to_vlist(par, b) local head_field = par.head_field if head_field then local n = slide_nodes(head_field) - n.next, s.prev = s, n + n.next = s + s.prev = n else par.head_field = s end @@ -805,7 +834,8 @@ local function append_to_vlist(par, b) local head_field = par.head_field if head_field then local n = slide_nodes(head_field) - n.next, b.prev = b, n + n.next = b + b.prev = n else par.head_field = b end @@ -820,7 +850,8 @@ local function append_list(par, b) local head_field = par.head_field if head_field then local n = slide_nodes(head_field) - n.next, b.prev = b, n + n.next = b + b.prev = n else par.head_field = b end @@ -829,6 +860,9 @@ end -- We can actually make par local to this module as we never break inside a break call and that way the -- array is reused. At some point the information will be part of the paragraph spec as passed. +local hztolerance = 2500 +local hzwarned = false + local function initialize_line_break(head,display) local hang_indent = tex.hangindent or 0 @@ -903,7 +937,7 @@ local function initialize_line_break(head,display) double_hyphen_demerits = tex.doublehyphendemerits or 0, final_hyphen_demerits = tex.finalhyphendemerits or 0, - first_line = 0, -- tex.nest.modeline, -- 0, -- cur_list.pg_field + first_line = 0, -- tex.nest[tex.nest.ptr].modeline, -- 0, -- cur_list.pg_field each_line_height = tex.pdfeachlineheight or 0, -- this will go away each_line_depth = tex.pdfeachlinedepth or 0, -- this will go away @@ -964,15 +998,24 @@ local function initialize_line_break(head,display) prev_char_p = nil, - font_steps = { }, -- mine - statistics = { noflines = 0, nofprotrudedlines = 0, nofadjustedlines = 0, - } + }, + + -- -- just a thought ... parshape functions ... it would be nice to + -- -- also store the height so far (probably not too hard) although + -- -- in most cases we work on grids in such cases + -- + -- adapt_width = function(par,line) + -- -- carry attribute, so that we can accumulate + -- local left = 655360 * (line - 1) + -- local right = 655360 * (line - 1) + -- return left, right + -- end } @@ -980,6 +1023,15 @@ local function initialize_line_break(head,display) local checked_expansion = { par = par } setmetatableindex(checked_expansion,check_expand_pars) par.checked_expansion = checked_expansion + + if par.tolerance < hztolerance then + if not hzwarned then + report_parbuilders("setting tolerance to %a for hz",hztolerance) + hzwarned = true + end + par.tolerance = hztolerance + end + end -- we need par for the error message @@ -1029,9 +1081,9 @@ local function initialize_line_break(head,display) else local last_special_line = #par_shape_ptr par.last_special_line = last_special_line - local ptr = par_shape_ptr[last_special_line] - par.second_width = ptr[2] - par.second_indent = ptr[1] + local parshape = par_shape_ptr[last_special_line] + par.second_width = parshape[2] + par.second_indent = parshape[1] end if par.looseness == 0 then @@ -1281,6 +1333,8 @@ local function post_line_break(par) statistics.noflines = statistics.noflines + 1 if adjust_spacing > 0 then statistics.nofadjustedlines = statistics.nofadjustedlines + 1 + -- in the built-in hpack cal_expand_ratio will later on call subst_ext_font + -- in the alternative approach we can do both in one run just_box = xpack_nodes(q,cur_width,"cal_expand_ratio",par.par_break_dir) -- ,cur_p.analysis) else just_box = xpack_nodes(q,cur_width,"exactly",par.par_break_dir) -- ,cur_p.analysis) @@ -1850,7 +1904,7 @@ end local total = cur_active_width.adjust_stretch + margin_kern_stretch if shortfall > 0 and total > 0 then if total > shortfall then - shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2 + shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2 -- to be adapted else shortfall = shortfall - total end @@ -1858,15 +1912,12 @@ end total = cur_active_width.adjust_shrink + margin_kern_shrink if shortfall < 0 and total > 0 then if total > - shortfall then - shortfall = - total / (par.max_shrink_ratio / par.cur_font_step) / 2 + shortfall = - total / (par.max_shrink_ratio / par.cur_font_step) / 2 -- to be adapted else shortfall = shortfall + total end end end - par.font_steps[line_number] = par.cur_font_step -- mine - else - par.font_steps[line_number] = 0 -- mine end local b = 0 local g = 0 @@ -2334,7 +2385,7 @@ function constructors.methods.basic(head,d) return wrap_up(par) end --- standard tex logging .. will be adapted .. missing font names and to many [] +-- standard tex logging .. will be adapted .. local function write_esc(cs) local esc = tex.escapechar @@ -2654,8 +2705,6 @@ end -- return hlist, 0 -- end --- local expansion_stack = { } -- no dealloc - local function hpack(head,width,method,direction) -- fast version when head = nil -- we can pass the adjust_width and adjust_height so that we don't need to recalculate them but @@ -2667,11 +2716,10 @@ local function hpack(head,width,method,direction) -- fast version when head = ni return hlist, 0 end - local cal_expand_ratio = method == "cal_expand_ratio" -- "subst_ex_font" -- is gone + local cal_expand_ratio = method == "cal_expand_ratio" or method == "subst_ex_font" direction = direction or tex.textdir - local pack_begin_line = 0 local line = 0 local height = 0 @@ -2761,7 +2809,7 @@ local function hpack(head,width,method,direction) -- fast version when head = ni current = current.next elseif id == disc_code then if current.subtype ~= second_disc_code then - -- todo : local stretch, shrink = char_stretch_shrink(s) + -- we follow the end of line disc chain local replace = current.replace if replace then disc_level = disc_level + 1 @@ -2771,14 +2819,6 @@ local function hpack(head,width,method,direction) -- fast version when head = ni current = current.next end else - -- -- pre post replace - -- - -- local stretch, shrink = char_stretch_shrink(current.pre) - -- font_stretch = font_stretch + stretch - -- font_shrink = font_shrink + shrink - -- expansion_index = expansion_index + 1 - -- expansion_stack[expansion_index] = current.pre - -- current = current.next end elseif id == glue_code then @@ -2919,89 +2959,32 @@ local function hpack(head,width,method,direction) -- fast version when head = ni if mode == "additional" then width = width + natural end + hlist.width = width hlist.height = height hlist.depth = depth + local delta = width - natural if delta == 0 then hlist.glue_sign = 0 hlist.glue_order = 0 hlist.glue_set = 0 elseif delta > 0 then + -- natural width smaller than requested width local order = (total_stretch[4] ~= 0 and 4 or total_stretch[3] ~= 0 and 3) or (total_stretch[2] ~= 0 and 2 or total_stretch[1] ~= 0 and 1) or 0 - if cal_expand_ratio and order == 0 and font_stretch > 0 then - font_expand_ratio = (delta/font_stretch) * 1000 -- round(delta/font_stretch * 1000) - else - local tso = total_stretch[order] - if tso ~= 0 then - hlist.glue_sign = 1 - hlist.glue_order = order - hlist.glue_set = delta/tso - else - hlist.glue_sign = 0 - hlist.glue_order = order - hlist.glue_set = 0 - end --- print("stretch",hlist.glue_sign,hlist.glue_order,hlist.glue_set) - if order == 0 and hlist.list then - last_badness = calculate_badness(delta,total_stretch[0]) - if last_badness > tex.hbadness then - if last_badness > 100 then - diagnostics.underfull_hbox(hlist,pack_begin_line,line,last_badness) - else - diagnostics.loose_hbox(hlist,pack_begin_line,line,last_badness) - end - end - end - end - else - local order = total_shrink[4] ~= 0 and 4 or total_shrink[3] ~= 0 and 3 - or total_shrink[2] ~= 0 and 2 or total_shrink[1] ~= 0 and 1 or 0 - if cal_expand_ratio and order == 0 and font_shrink > 0 then - font_expand_ratio = (delta/font_shrink) * 1000 -- round(delta/font_shrink * 1000) - else -- why was this else commented - local tso = total_shrink[order] - if tso ~= 0 then - hlist.glue_sign = 2 - hlist.glue_order = order - hlist.glue_set = -delta/tso - else - hlist.glue_sign = 0 - hlist.glue_order = order - hlist.glue_set = 0 - end --- print("shrink",hlist.glue_sign,hlist.glue_order,hlist.glue_set) - if total_shrink[order] < -delta and order == 0 and hlist.list then - last_badness = 1000000 - hlist.glue_set = 1 - local fuzz = - delta - total_shrink[0] - local hfuzz = tex.hfuzz - if fuzz > hfuzz or tex.hbadness < 100 then - local overfullrule = tex.overfullrule - if fuzz > hfuzz and overfullrule > 0 then - -- weird, is always called and no rules shows up - slide_nodes(list).next = new_rule(overfullrule,nil,nil,hlist.dir) - end - diagnostics.overfull_hbox(hlist,pack_begin_line,line,-delta) -- - added - end - elseif order == 0 and hlist.list and last_badness > tex.hbadness then - diagnostics.bad_hbox(hlist,pack_begin_line,line,last_badness) - end - end - end - if cal_expand_ratio and font_expand_ratio ~= 0 then - -- if font_expand_ratio > 1000 then - -- font_expand_ratio = 1000 - -- elseif font_expand_ratio < -1000 then - -- font_expand_ratio = -1000 - -- end + local correction = 0 + if cal_expand_ratio and order == 0 and font_stretch > 0 then -- check sign of font_stretch + font_expand_ratio = delta/font_stretch - local fontexps, lastfont + if font_expand_ratio > 1 then + font_expand_ratio = 1 + end - if font_expand_ratio > 0 then + local fontexps, lastfont for i=1,expansion_index do local g = expansion_stack[i] + local e if g.id == glyph_code then local currentfont = g.font if currentfont ~= lastfont then @@ -3012,15 +2995,56 @@ local function hpack(head,width,method,direction) -- fast version when head = ni if trace_expansion then setnodecolor(g,"hz:positive") end - g.expansion_factor = font_expand_ratio * data.glyphstretch + e = font_expand_ratio * data.glyphstretch / 1000 + correction = correction + (e / 1000) * g.width else - local stretch, shrink = kern_stretch_shrink(g,g.kern) - g.expansion_factor = font_expand_ratio * stretch + local kern = g.kern + local stretch, shrink = kern_stretch_shrink(g,kern) + e = font_expand_ratio * stretch / 1000 + correction = correction + (e / 1000) * kern end + g.expansion_factor = e end + end + delta = delta - correction + local tso = total_stretch[order] + if tso ~= 0 then + hlist.glue_sign = 1 + hlist.glue_order = order + hlist.glue_set = delta/tso else + hlist.glue_sign = 0 + hlist.glue_order = order + hlist.glue_set = 0 + end + if font_expand_ratio ~= 0 then + -- todo + elseif order == 0 then -- and hlist.list then + last_badness = calculate_badness(delta,total_stretch[0]) + if last_badness > tex.hbadness then + if last_badness > 100 then + diagnostics.underfull_hbox(hlist,line,last_badness) + else + diagnostics.loose_hbox(hlist,line,last_badness) + end + end + end + else + -- natural width larger than requested width + local order = total_shrink[4] ~= 0 and 4 or total_shrink[3] ~= 0 and 3 + or total_shrink[2] ~= 0 and 2 or total_shrink[1] ~= 0 and 1 or 0 + local correction = 0 + if cal_expand_ratio and order == 0 and font_shrink > 0 then -- check sign of font_shrink + font_expand_ratio = delta/font_shrink + + if font_expand_ratio < 1 then + font_expand_ratio = -1 + end + + local fontexps, lastfont for i=1,expansion_index do local g = expansion_stack[i] + local e if g.id == glyph_code then local currentfont = g.font if currentfont ~= lastfont then @@ -3031,33 +3055,68 @@ local function hpack(head,width,method,direction) -- fast version when head = ni if trace_expansion then setnodecolor(g,"hz:negative") end - g.expansion_factor = font_expand_ratio * data.glyphshrink + e = font_expand_ratio * data.glyphshrink / 1000 + -- local d = (e / 1000) * 1000 + -- local eps = g.width - (1 + d / 1000000) * g.width + -- correction = correction + eps + -- e = d + correction = correction + (e / 1000) * g.width else - local stretch, shrink = kern_stretch_shrink(g,g.kern) - g.expansion_factor = font_expand_ratio * shrink + local kern = g.kern + local stretch, shrink = kern_stretch_shrink(g,kern) + e = font_expand_ratio * shrink / 1000 + correction = correction + (e / 1000) * kern end + g.expansion_factor = e end end - + delta = delta - correction + local tso = total_shrink[order] + if tso ~= 0 then + hlist.glue_sign = 2 + hlist.glue_order = order + hlist.glue_set = -delta/tso + else + hlist.glue_sign = 0 + hlist.glue_order = order + hlist.glue_set = 0 + end + if font_expand_ratio ~= 0 then + -- todo + elseif tso < -delta and order == 0 then -- and hlist.list then + last_badness = 1000000 + hlist.glue_set = 1 + local fuzz = - delta - total_shrink[0] + local hfuzz = tex.hfuzz + if fuzz > hfuzz or tex.hbadness < 100 then + local overfullrule = tex.overfullrule + if fuzz > hfuzz and overfullrule > 0 then + -- weird, is always called and no rules shows up + slide_nodes(list).next = new_rule(overfullrule,nil,nil,hlist.dir) + end + diagnostics.overfull_hbox(hlist,line,-delta) + end + elseif order == 0 and hlist.list and last_badness > tex.hbadness then + diagnostics.bad_hbox(hlist,line,last_badness) + end end return hlist, last_badness end -nodes.hpack = hpack -hpack_nodes = hpack -- comment this for old fashioned expansion xpack_nodes = hpack -- comment this for old fashioned expansion -local function common_message(hlist,pack_begin_line,line,str) +local function common_message(hlist,line,str) write_nl("") if status.output_active then -- unset write(str," has occurred while \\output is active") end - if pack_begin_line > 0 then - write(str," in paragraph at lines ",pack_begin_line,"--",line) - elseif pack_begin_line < 0 then - write(str," in alignment at lines ",-pack_begin_line,"--",line) + local fileline = status.linenumber + if line > 0 then + write(str," in paragraph at lines ",fileline,"--",fileline+line-1) + elseif line < 0 then + write(str," in alignment at lines ",fileline,"--",fileline-line-1) else - write(str," detected at line ",line) + write(str," detected at line ",fileline) end write_nl("") diagnostics.short_display(hlist.list,false) @@ -3067,141 +3126,35 @@ local function common_message(hlist,pack_begin_line,line,str) -- diagnostics.stop() end -function diagnostics.overfull_hbox(hlist,pack_begin_line,line,d) - common_message(hlist,pack_begin_line,line,format("Overfull \\hbox (%spt too wide)",number.toscaled(d))) +function diagnostics.overfull_hbox(hlist,line,d) + common_message(hlist,line,format("Overfull \\hbox (%spt too wide)",number.toscaled(d))) end -function diagnostics.bad_hbox(hlist,pack_begin_line,line,b) - common_message(hlist,pack_begin_line,line,format("Tight \\hbox (badness %i)",b)) +function diagnostics.bad_hbox(hlist,line,b) + common_message(hlist,line,format("Tight \\hbox (badness %i)",b)) end -function diagnostics.underfull_hbox(hlist,pack_begin_line,line,b) - common_message(hlist,pack_begin_line,line,format("Underfull \\hbox (badness %i)",b)) -end - -function diagnostics.loose_hbox(hlist,pack_begin_line,line,b) - common_message(hlist,pack_begin_line,line,format("Loose \\hbox (badness %i)",b)) -end - --- for the moment here: - -local utfchar = utf.char -local concat = table.concat - -local nodecodes = nodes.nodecodes -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glyph_code = nodecodes.glyph -local kern_code = nodecodes.kern -local setnodecolor = nodes.tracers.colors.set -local parameters = fonts.hashes.parameters -local basepoints = number.basepoints - --- definecolor[hz:positive] [r=0.6] --- definecolor[hz:negative] [g=0.6] --- definecolor[hz:zero] [b=0.6] - --- scale = multiplier + ef/multiplier - -local trace_verbose = false trackers.register("builders.paragraphs.expansion.verbose", function(v) trace_verbose = v end) - -local report_verbose = logs.reporter("fonts","expansion") - -local function colorize(n) - local size, font, ef, width, scale, list, flush, length - if trace_verbose then - width = 0 - length = 0 - list = { } - flush = function() - if length > 0 then - report_verbose("%0.3f : %10s %10s %s",scale,basepoints(width),basepoints(width*scale),concat(list,"",1,length)) - width = 0 - length = 0 - end - end - else - length = 0 - end - -- tricky: the built-in method creates dummy fonts and the last line normally has the - -- original font and that one then has ex.auto set - while n do - local id = n.id - if id == glyph_code then - local ne = n.expansion_factor - if ne == 0 then - if length > 0 then flush() end - else - local f = n.font - if f ~= font then - if length > 0 then - flush() - end - local pf = parameters[f] - local ex = pf.expansion - if ex and ex.auto then - size = pf.size - font = f -- save lookups - else - size = false - end - end - if size then - if ne ~= ef then - if length > 0 then - flush() - end - ef = ne - end - -- scale = 1.0 + ef / 1000 / 1000 / 1000 - scale = 1.0 + ef / 1000000000 - if scale > 1 then - setnodecolor(n,"hz:positive") - elseif scale < 1 then - setnodecolor(n,"hz:negative") - else - setnodecolor(n,"hz:zero") - end - if report_verbose then - length = length + 1 - list[length] = utfchar(n.char) - width = width + n.width -- no kerning yet - end - end - end - elseif id == hlist_code or id == vlist_code then - if length > 0 then - flush() - end - colorize(n.list,flush) - else -- nothing to show on kerns - if length > 0 then - flush() - end - end - n = n.next - end - if length > 0 then - flush() - end +function diagnostics.underfull_hbox(hlist,line,b) + common_message(hlist,line,format("Underfull \\hbox (badness %i)",b)) end -builders.paragraphs.expansion = builders.paragraphs.expansion or { } - -function builders.paragraphs.expansion.trace(head) - colorize(head,true) - return head +function diagnostics.loose_hbox(hlist,line,b) + common_message(hlist,line,format("Loose \\hbox (badness %i)",b)) end -local tasks = nodes.tasks - -tasks.prependaction("shipouts","normalizers","builders.paragraphs.expansion.trace") -tasks.disableaction("shipouts","builders.paragraphs.expansion.trace") +-- e = font_expand_ratio * data.glyphstretch / 1000 +-- local stretch = data.stretch +-- if e >= stretch then +-- e = stretch +-- else +-- local step = 5 +-- e = math.round(e/step) * step +-- end -trackers.register("builders.paragraphs.expansion.verbose", function(v) - if v then - tasks.enableaction("shipouts","builders.paragraphs.expansion.trace") - else - tasks.disableaction("shipouts","builders.paragraphs.expansion.trace") - end -end) +-- local shrink = - data.shrink +-- if e <= shrink then +-- e = shrink +-- else +-- local step = 5 +-- e = math.round(e/step) * step +-- end diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 180a0971f..b240ea843 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 66a3aa417..31fd9f678 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv index 20fa078a2..b9263cdb0 100644 --- a/tex/context/base/strc-mat.mkiv +++ b/tex/context/base/strc-mat.mkiv @@ -171,10 +171,20 @@ \global\setfalse\c_strc_formulas_inside_place_sub \to \everyresetformulas +% \def\strc_formulas_place_numbering % place formula +% {\settrue\c_strc_formulas_handle_number +% \strc_formulas_check_reference\c_strc_formulas_place_number_mode\currentplaceformulareference +% \glet\strc_formulas_place_number\strc_formulas_place_number_indeed +% \glet\strc_formulas_place_number_nested\strc_formulas_place_number_nested_indeed} + \def\strc_formulas_place_numbering % place formula {\settrue\c_strc_formulas_handle_number \strc_formulas_check_reference\c_strc_formulas_place_number_mode\currentplaceformulareference - \glet\strc_formulas_place_number\strc_formulas_place_number_indeed + \ifnum\c_strc_formulas_place_number_mode=\plustwo + \glet\strc_formulas_place_number\relax + \else + \glet\strc_formulas_place_number\strc_formulas_place_number_indeed + \fi \glet\strc_formulas_place_number_nested\strc_formulas_place_number_nested_indeed} \def\strc_formulas_handle_number % formulas @@ -610,6 +620,33 @@ %D \startformula x \stopformula % now has \noindent (in mkii we messed with baselineskip) %D \stoptyping +% \unexpanded\def\startdisplaymath +% {\bgroup +% \par +% \informulatrue +% \beforedisplayspace +% \par +% \ifvmode +% \prevdepth-\maxdimen % texbook pagina 79-80 +% \fi +% \noindent % else funny hlist with funny baselineskip +% $$% \Ustartdisplaymath +% \setdisplaydimensions +% \startinnermath} +% +% \unexpanded\def\stopdisplaymath +% {\stopinnermath +% $$% \Ustopdisplaymath +% \par +% \afterdisplayspace +% \par +% \egroup} + +\newconstant\c_strc_formulas_space_model + +\c_strc_formulas_space_model\plusone +%c_strc_formulas_space_model\plustwo % needs chdcking with spac-ver + \unexpanded\def\startdisplaymath {\bgroup \par @@ -617,18 +654,32 @@ \beforedisplayspace \par \ifvmode - \prevdepth-\maxdimen % texbook pagina 79-80 + \ifcase\c_strc_formulas_space_model + % nothing + \or + % nothing yet + \or + \prevdepth-\maxdimen % texbook pagina 79-80 + \fi \fi \noindent % else funny hlist with funny baselineskip $$% \Ustartdisplaymath \setdisplaydimensions - %\setpredisplaysize \startinnermath} \unexpanded\def\stopdisplaymath {\stopinnermath $$% \Ustopdisplaymath \par + \ifvmode + \ifcase\c_strc_formulas_space_model + % nothing + \or + \prevdepth .5\strutdp + \or + \prevdepth\lineheight + \fi + \fi \afterdisplayspace \par \egroup} diff --git a/tex/context/base/trac-par.lua b/tex/context/base/trac-par.lua new file mode 100644 index 000000000..262a9cc33 --- /dev/null +++ b/tex/context/base/trac-par.lua @@ -0,0 +1,125 @@ +-- for the moment here: + +local utfchar = utf.char +local concat = table.concat + +local nodecodes = nodes.nodecodes +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern +local setnodecolor = nodes.tracers.colors.set +local parameters = fonts.hashes.parameters +local basepoints = number.basepoints + +-- definecolor[hz:positive] [r=0.6] +-- definecolor[hz:negative] [g=0.6] +-- definecolor[hz:zero] [b=0.6] + +-- scale = multiplier + ef/multiplier + +local trace_both = false trackers.register("builders.paragraphs.expansion.both", function(v) trace_verbose = false trace_both = v end) +local trace_verbose = false trackers.register("builders.paragraphs.expansion.verbose", function(v) trace_verbose = v trace_color = v end) + +local report_verbose = logs.reporter("fonts","expansion") + +local function colorize(n) + local size, font, ef, width, list, flush, length + if trace_verbose then + width = 0 + length = 0 + list = { } + flush = function() + if length > 0 then + report_verbose("%0.3f : %10s %10s %s",ef/1000,basepoints(width),basepoints(width*ef/1000000),concat(list,"",1,length)) + width = 0 + length = 0 + end + end + else + length = 0 + end + -- tricky: the built-in method creates dummy fonts and the last line normally has the + -- original font and that one then has ex.auto set + while n do + local id = n.id + if id == glyph_code then + local ne = n.expansion_factor + if ne == 0 then + if length > 0 then flush() end + setnodecolor(n,"hz:zero") + else + local f = n.font + if f ~= font then + if length > 0 then + flush() + end + local pf = parameters[f] + local ex = pf.expansion + if ex and ex.auto then + size = pf.size + font = f -- save lookups + else + size = false + end + end + if size then + if ne ~= ef then + if length > 0 then + flush() + end + ef = ne + end + if ef > 1 then + setnodecolor(n,"hz:plus") + elseif ef < 1 then + setnodecolor(n,"hz:minus") + else + setnodecolor(n,"hz:zero") + end + if trace_verbose then + length = length + 1 + list[length] = utfchar(n.char) + width = width + n.width -- no kerning yet + end + end + end + elseif id == hlist_code or id == vlist_code then + if length > 0 then + flush() + end + colorize(n.list,flush) + else -- nothing to show on kerns + if length > 0 then + flush() + end + end + n = n.next + end + if length > 0 then + flush() + end +end + +builders.paragraphs.expansion = builders.paragraphs.expansion or { } + +function builders.paragraphs.expansion.trace(head) + colorize(head,true) + return head +end + +local tasks = nodes.tasks + +tasks.prependaction("shipouts","normalizers","builders.paragraphs.expansion.trace") +tasks.disableaction("shipouts","builders.paragraphs.expansion.trace") + +local function set(v) + if v then + tasks.enableaction("shipouts","builders.paragraphs.expansion.trace") + else + tasks.disableaction("shipouts","builders.paragraphs.expansion.trace") + end +end + +trackers.register("builders.paragraphs.expansion.verbose",set) +trackers.register("builders.paragraphs.expansion.both",set) diff --git a/tex/context/base/typo-tal.lua b/tex/context/base/typo-tal.lua index becf2d401..63a66d037 100644 --- a/tex/context/base/typo-tal.lua +++ b/tex/context/base/typo-tal.lua @@ -142,7 +142,9 @@ function characteralign.handler(head,where) else b_start = current b_stop = current - setcolor(current,validseparators[unicode] and "darkcyan" or "darkblue") + if trace_split then + setcolor(current,validseparators[unicode] and "darkcyan" or "darkblue") + end end else b_stop = current diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 705c1146f..2bfa77514 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 : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 11/08/13 11:50:45 +-- merge date : 11/09/13 20:21:53 do -- begin closure to overcome local limits and interference @@ -8814,24 +8814,11 @@ local injections=nodes.injections local nodecodes=nodes.nodecodes local glyph_code=nodecodes.glyph local kern_code=nodecodes.kern -local nuts=nodes.nuts -local nodepool=nuts.pool +local nodepool=nodes.pool local newkern=nodepool.kern -local tonode=nuts.tonode -local tonut=nuts.tonut -local getfield=nuts.getfield -local getnext=nuts.getnext -local getprev=nuts.getprev -local getid=nuts.getid -local getattr=nuts.getattr -local getfont=nuts.getfont -local getsubtype=nuts.getsubtype -local getchar=nuts.getchar -local setfield=nuts.setfield -local setattr=nuts.setattr -local traverse_id=nuts.traverse_id -local insert_node_before=nuts.insert_before -local insert_node_after=nuts.insert_after +local traverse_id=node.traverse_id +local insert_node_before=node.insert_before +local insert_node_after=node.insert_after local a_kernpair=attributes.private('kernpair') local a_ligacomp=attributes.private('ligacomp') local a_markbase=attributes.private('markbase') @@ -8850,21 +8837,21 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne local dx,dy=factor*(exit[1]-entry[1]),factor*(exit[2]-entry[2]) local ws,wn=tfmstart.width,tfmnext.width local bound=#cursives+1 - setattr(start,a_cursbase,bound) - setattr(nxt,a_curscurs,bound) + start[a_cursbase]=bound + nxt[a_curscurs]=bound cursives[bound]={ rlmode,dx,dy,ws,wn } return dx,dy,bound end function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr) local x,y,w,h=factor*spec[1],factor*spec[2],factor*spec[3],factor*spec[4] if x~=0 or w~=0 or y~=0 or h~=0 then - local bound=getattr(current,a_kernpair) + local bound=current[a_kernpair] if bound then local kb=kerns[bound] kb[2],kb[3],kb[4],kb[5]=(kb[2] or 0)+x,(kb[3] or 0)+y,(kb[4] or 0)+w,(kb[5] or 0)+h else bound=#kerns+1 - setattr(current,a_kernpair,bound) + current[a_kernpair]=bound kerns[bound]={ rlmode,x,y,w,h,r2lflag,tfmchr.width } end return x,y,w,h,bound @@ -8875,7 +8862,7 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) local dx=factor*x if dx~=0 then local bound=#kerns+1 - setattr(current,a_kernpair,bound) + current[a_kernpair]=bound kerns[bound]={ rlmode,dx } return dx,bound else @@ -8884,25 +8871,25 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) end function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) - local bound=getattr(base,a_markbase) + local bound=base[a_markbase] local index=1 if bound then local mb=marks[bound] if mb then index=#mb+1 mb[index]={ dx,dy,rlmode } - setattr(start,a_markmark,bound) - setattr(start,a_markdone,index) + start[a_markmark]=bound + start[a_markdone]=index return dx,dy,bound else - report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound) + report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound) end end index=index or 1 bound=#marks+1 - setattr(base,a_markbase,bound) - setattr(start,a_markmark,bound) - setattr(start,a_markdone,index) + base[a_markbase]=bound + start[a_markmark]=bound + start[a_markdone]=index marks[bound]={ [index]={ dx,dy,rlmode,baseismark } } return dx,dy,bound end @@ -8912,15 +8899,15 @@ end local function trace(head) report_injections("begin run") for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then - local kp=getattr(n,a_kernpair) - local mb=getattr(n,a_markbase) - local mm=getattr(n,a_markmark) - local md=getattr(n,a_markdone) - local cb=getattr(n,a_cursbase) - local cc=getattr(n,a_curscurs) - local char=getchar(n) - report_injections("font %s, char %U, glyph %c",getfont(n),char,char) + if n.subtype<256 then + local kp=n[a_kernpair] + local mb=n[a_markbase] + local mm=n[a_markmark] + local md=n[a_markdone] + local cb=n[a_cursbase] + local cc=n[a_curscurs] + local char=n.char + report_injections("font %s, char %U, glyph %c",n.font,char,char) if kp then local k=kerns[kp] if k[3] then @@ -8961,23 +8948,21 @@ local function show_result(head) local current=head local skipping=false while current do - local id=getid(current) + local id=current.id if id==glyph_code then - report_injections("char: %C, width %p, xoffset %p, yoffset %p", - getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) + report_injections("char: %C, width %p, xoffset %p, yoffset %p",current.char,current.width,current.xoffset,current.yoffset) skipping=false elseif id==kern_code then - report_injections("kern: %p",getfield(current,"kern")) + report_injections("kern: %p",current.kern) skipping=false elseif not skipping then report_injections() skipping=true end - current=getnext(current) + current=current.next end end function injections.handler(head,where,keep) - head=tonut(head) local has_marks,has_cursives,has_kerns=next(marks),next(cursives),next(kerns) if has_marks or has_cursives then if trace_injections then @@ -8987,18 +8972,17 @@ function injections.handler(head,where,keep) if has_kerns then local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then + if n.subtype<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - local f=getfont(n) - if f~=nf then - nf=f - tm=fontdata[nf].resources.marks + if n.font~=nf then + nf=n.font + tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[getchar(n)] + mk[n]=tm[n.char] end - local k=getattr(n,a_kernpair) + local k=n[a_kernpair] if k then local kk=kerns[k] if kk then @@ -9018,16 +9002,15 @@ function injections.handler(head,where,keep) else local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then + if n.subtype<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - local f=getfont(n) - if f~=nf then - nf=f - tm=fontdata[nf].resources.marks + if n.font~=nf then + nf=n.font + tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[getchar(n)] + mk[n]=tm[n.char] end end end @@ -9036,7 +9019,7 @@ function injections.handler(head,where,keep) local cx={} if has_kerns and next(ky) then for n,k in next,ky do - setfield(n,"yoffset",k) + n.yoffset=k end end if has_cursives then @@ -9045,9 +9028,9 @@ function injections.handler(head,where,keep) for i=1,nofvalid do local n=valid[i] if not mk[n] then - local n_cursbase=getattr(n,a_cursbase) + local n_cursbase=n[a_cursbase] if p_cursbase then - local n_curscurs=getattr(n,a_curscurs) + local n_curscurs=n[a_curscurs] if p_cursbase==n_curscurs then local c=cursives[n_curscurs] if c then @@ -9070,20 +9053,20 @@ function injections.handler(head,where,keep) end end elseif maxt>0 then - local ny=getfield(n,"yoffset") + local ny=n.yoffset for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - setfield(ti,"yoffset",getfield(ti,"yoffset")+ny) + ti.yoffset=ti.yoffset+ny end maxt=0 end if not n_cursbase and maxt>0 then - local ny=getfield(n,"yoffset") + local ny=n.yoffset for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - setfield(ti,"yoffset",ny) + ti.yoffset=ny end maxt=0 end @@ -9091,11 +9074,11 @@ function injections.handler(head,where,keep) end end if maxt>0 then - local ny=getfield(n,"yoffset") + local ny=n.yoffset for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - setfield(ti,"yoffset",ny) + ti.yoffset=ny end maxt=0 end @@ -9106,66 +9089,57 @@ function injections.handler(head,where,keep) if has_marks then for i=1,nofvalid do local p=valid[i] - local p_markbase=getattr(p,a_markbase) + local p_markbase=p[a_markbase] if p_markbase then local mrks=marks[p_markbase] local nofmarks=#mrks - for n in traverse_id(glyph_code,getnext(p)) do - local n_markmark=getattr(n,a_markmark) + for n in traverse_id(glyph_code,p.next) do + local n_markmark=n[a_markmark] if p_markbase==n_markmark then - local index=getattr(n,a_markdone) or 1 + local index=n[a_markdone] or 1 local d=mrks[index] if d then local rlmode=d[3] local k=wx[p] - local px=getfield(p,"xoffset") - local ox=0 if k then local x=k[2] local w=k[4] if w then if rlmode and rlmode>=0 then - ox=px-getfield(p,"width")+d[1]-(w-x) + n.xoffset=p.xoffset-p.width+d[1]-(w-x) else - ox=px-d[1]-x + n.xoffset=p.xoffset-d[1]-x end else if rlmode and rlmode>=0 then - ox=px-getfield(p,"width")+d[1] + n.xoffset=p.xoffset-p.width+d[1] else - ox=px-d[1]-x + n.xoffset=p.xoffset-d[1]-x end end else - local wp=getfield(p,"width") - local wn=getfield(n,"width") if rlmode and rlmode>=0 then - ox=px-wp+d[1] + n.xoffset=p.xoffset-p.width+d[1] else - ox=px-d[1] + n.xoffset=p.xoffset-d[1] end - if wn~=0 then - insert_node_before(head,n,newkern(-wn/2)) - insert_node_after(head,n,newkern(-wn/2)) + local w=n.width + if w~=0 then + insert_node_before(head,n,newkern(-w/2)) + insert_node_after(head,n,newkern(-w/2)) end end - setfield(n,"xoffset",ox) - local py=getfield(p,"yoffset") - local oy=0 if mk[p] then - oy=py+d[2] + n.yoffset=p.yoffset+d[2] else - oy=getfield(n,"yoffset")+py+d[2] + n.yoffset=n.yoffset+p.yoffset+d[2] end - setfield(n,"yoffset",oy) if nofmarks==1 then break else nofmarks=nofmarks-1 end end - elseif not n_markmark then - break else end end @@ -9217,7 +9191,6 @@ function injections.handler(head,where,keep) if not keep then kerns={} end -head=tonode(head) return head,true elseif not keep then kerns,cursives,marks={},{},{} @@ -9227,14 +9200,14 @@ head=tonode(head) trace(head) end for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then - local k=getattr(n,a_kernpair) + if n.subtype<256 then + local k=n[a_kernpair] if k then local kk=kerns[k] if kk then local rl,x,y,w=kk[1],kk[2] or 0,kk[3],kk[4] if y and y~=0 then - setfield(n,"yoffset",y) + n.yoffset=y end if w then local wx=w-x @@ -9265,10 +9238,10 @@ head=tonode(head) if not keep then kerns={} end - return tonode(head),true + return head,true else end - return tonode(head),false + return head,false end end -- closure @@ -9683,25 +9656,12 @@ registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive") registertracker("otf.actions","otf.replacements,otf.positions") registertracker("otf.injections","nodes.injections") registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") -local nuts=nodes.nuts -local tonode=nuts.tonode -local tonut=nuts.tonut -local getfield=nuts.getfield -local getnext=nuts.getnext -local getprev=nuts.getprev -local getid=nuts.getid -local getattr=nuts.getattr -local getfont=nuts.getfont -local getsubtype=nuts.getsubtype -local getchar=nuts.getchar -local setfield=nuts.setfield -local setattr=nuts.setattr -local insert_node_after=nuts.insert_after -local delete_node=nuts.delete -local copy_node=nuts.copy -local find_node_tail=nuts.tail -local flush_node_list=nuts.flush_list -local end_of_math=nuts.end_of_math +local insert_node_after=node.insert_after +local delete_node=nodes.delete +local copy_node=node.copy +local find_node_tail=node.tail or node.slide +local flush_node_list=node.flush_list +local end_of_math=node.end_of_math local setmetatableindex=table.setmetatableindex local zwnj=0x200C local zwj=0x200D @@ -9812,83 +9772,83 @@ local function pref(kind,lookupname) return formatters["feature %a, lookup %a"](kind,lookupname) end local function copy_glyph(g) - local components=getfield(g,"components") + local components=g.components if components then - setfield(g,"components",nil) + g.components=nil local n=copy_node(g) - setfield(g,"components",components) + g.components=components return n else return copy_node(g) end end local function markstoligature(kind,lookupname,head,start,stop,char) - if start==stop and getchar(start)==char then + if start==stop and start.char==char then return head,start else - local prev=getprev(start) - local next=getnext(stop) - setfield(start,"prev",nil) - setfield(stop,"next",nil) + local prev=start.prev + local next=stop.next + start.prev=nil + stop.next=nil local base=copy_glyph(start) if head==start then head=base end - setfield(base,"char",char) - setfield(base,"subtype",ligature_code) - setfield(base,"components",start) + base.char=char + base.subtype=ligature_code + base.components=start if prev then - setfield(prev,"next",base) + prev.next=base end if next then - setfield(next,"prev",base) + next.prev=base end - setfield(base,"next",next) - setfield(base,"prev",prev) + base.next=next + base.prev=prev return head,base end end local function getcomponentindex(start) - if getid(start)~=glyph_code then + if start.id~=glyph_code then return 0 - elseif getsubtype(start)==ligature_code then + elseif start.subtype==ligature_code then local i=0 - local components=getfield(start,"components") + local components=start.components while components do i=i+getcomponentindex(components) - components=getnext(components) + components=components.next end return i - elseif not marks[getchar(start)] then + elseif not marks[start.char] then return 1 else return 0 end end local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) - if start==stop and getchar(start)==char then - setfield(start,"char",char) + if start==stop and start.char==char then + start.char=char return head,start end - local prev=getprev(start) - local next=getnext(stop) - setfield(start,"prev",nil) - setfield(stop,"next",nil) + local prev=start.prev + local next=stop.next + start.prev=nil + stop.next=nil local base=copy_glyph(start) if start==head then head=base end - setfield(base,"char",char) - setfield(base,"subtype",ligature_code) - setfield(base,"components",start) + base.char=char + base.subtype=ligature_code + base.components=start if prev then - setfield(prev,"next",base) + prev.next=base end if next then - setfield(next,"prev",base) + next.prev=base end - setfield(base,"next",next) - setfield(base,"prev",prev) + base.next=next + base.prev=prev if not discfound then local deletemarks=markflag~="mark" local components=start @@ -9897,42 +9857,42 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun local head=base local current=base while start do - local char=getchar(start) + local char=start.char if not marks[char] then baseindex=baseindex+componentindex componentindex=getcomponentindex(start) elseif not deletemarks then - setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex)) + start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) if trace_marks then - logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) + logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) end head,current=insert_node_after(head,current,copy_node(start)) elseif trace_marks then logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char)) end - start=getnext(start) + start=start.next end - local start=getnext(current) - while start and getid(start)==glyph_code do - local char=getchar(start) + local start=current.next + while start and start.id==glyph_code do + local char=start.char if marks[char] then - setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex)) + start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) if trace_marks then - logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) + logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) end else break end - start=getnext(start) + start=start.next end end return head,base end function handlers.gsub_single(head,start,kind,lookupname,replacement) if trace_singles then - logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement)) + logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement)) end - setfield(start,"char",replacement) + start.char=replacement return head,start,true end local function get_alternative_glyph(start,alternatives,value,trace_alternatives) @@ -9958,7 +9918,7 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end elseif value==0 then - return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + return start.char,trace_alternatives and formatters["invalid value %a, %s"](value,"no change") elseif value<1 then return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) else @@ -9969,25 +9929,25 @@ end local function multiple_glyphs(head,start,multiple,ignoremarks) local nofmultiples=#multiple if nofmultiples>0 then - setfield(start,"char",multiple[1]) + start.char=multiple[1] if nofmultiples>1 then - local sn=getnext(start) + local sn=start.next for k=2,nofmultiples do local n=copy_node(start) - setfield(n,"char",multiple[k]) - setfield(n,"next",sn) - setfield(n,"prev",start) + n.char=multiple[k] + n.next=sn + n.prev=start if sn then - setfield(sn,"prev",n) + sn.prev=n end - setfield(start,"next",n) + start.next=n start=n end end return head,start,true else if trace_multiples then - logprocess("no multiple for %s",gref(getchar(start))) + logprocess("no multiple for %s",gref(start.char)) end return head,start,false end @@ -9997,34 +9957,34 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence local choice,comment=get_alternative_glyph(start,alternative,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment) + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) end - setfield(start,"char",choice) + start.char=choice else if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment) + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) end end return head,start,true end function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence) if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(getchar(start)),gref(multiple)) + logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple)) end return multiple_glyphs(head,start,multiple,sequence.flags[1]) end function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) - local s,stop,discfound=getnext(start),nil,false - local startchar=getchar(start) + local s,stop,discfound=start.next,nil,false + local startchar=start.char if marks[startchar] then while s do - local id=getid(s) - if id==glyph_code and getfont(s)==currentfont and getsubtype(s)<256 then - local lg=ligature[getchar(s)] + local id=s.id + if id==glyph_code and s.font==currentfont and s.subtype<256 then + local lg=ligature[s.char] if lg then stop=s ligature=lg - s=getnext(s) + s=s.next else break end @@ -10036,9 +9996,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) local lig=ligature.ligature if lig then if trace_ligatures then - local stopchar=getchar(stop) + local stopchar=stop.char head,start=markstoligature(kind,lookupname,head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) else head,start=markstoligature(kind,lookupname,head,start,stop,lig) end @@ -10049,18 +10009,18 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) else local skipmark=sequence.flags[1] while s do - local id=getid(s) - if id==glyph_code and getsubtype(s)<256 then - if getfont(s)==currentfont then - local char=getchar(s) + local id=s.id + if id==glyph_code and s.subtype<256 then + if s.font==currentfont then + local char=s.char if skipmark and marks[char] then - s=getnext(s) + s=s.next else local lg=ligature[char] if lg then stop=s ligature=lg - s=getnext(s) + s=s.next else break end @@ -10070,7 +10030,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) end elseif id==disc_code then discfound=true - s=getnext(s) + s=s.next else break end @@ -10079,9 +10039,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) local lig=ligature.ligature if lig then if trace_ligatures then - local stopchar=getchar(stop) + local stopchar=stop.char head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) else head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) end @@ -10093,16 +10053,16 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) return head,start,false end function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10151,16 +10111,16 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10172,7 +10132,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ end end end - local index=getattr(start,a_ligacomp) + local index=start[a_ligacomp] local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -10217,22 +10177,22 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ return head,start,false end function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then - local base=getprev(start) - local slc=getattr(start,a_ligacomp) + local base=start.prev + local slc=start[a_ligacomp] if slc then while base do - local blc=getattr(base,a_ligacomp) + local blc=base[a_ligacomp] if blc and blc~=slc then - base=getprev(base) + base=base.prev else break end end end - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -10270,20 +10230,20 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) - local alreadydone=cursonce and getattr(start,a_cursbase) + local alreadydone=cursonce and start[a_cursbase] if not alreadydone then local done=false - local startchar=getchar(start) + local startchar=start.char if marks[startchar] then if trace_cursive then logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=getnext(start) - while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do - local nextchar=getchar(nxt) + local nxt=start.next + while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do + local nextchar=nxt.char if marks[nextchar] then - nxt=getnext(nxt) + nxt=nxt.next else local entryanchors=descriptions[nextchar] if entryanchors then @@ -10317,13 +10277,13 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) end return head,start,false end end function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) - local startchar=getchar(start) + local startchar=start.char local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) @@ -10331,33 +10291,33 @@ function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) return head,start,false end function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) - local snext=getnext(start) + local snext=start.next if not snext then return head,start,false else local prev,done=start,false local factor=tfmdata.parameters.factor local lookuptype=lookuptypes[lookupname] - while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do - local nextchar=getchar(snext) + while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do + local nextchar=snext.char local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=getnext(snext) + snext=snext.next else if not krn then elseif type(krn)=="table" then if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -10370,7 +10330,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) end done=true end @@ -10405,13 +10365,13 @@ function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,looku return head,start,false end function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements) - local char=getchar(start) + local char=start.char local replacement=replacements[char] if replacement then if trace_singles then logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement)) end - setfield(start,"char",replacement) + start.char=replacement return head,start,true else return head,start,false @@ -10424,8 +10384,8 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) end while current do - if getid(current)==glyph_code then - local currentchar=getchar(current) + if current.id==glyph_code then + local currentchar=current.char local lookupname=subtables[1] local replacement=lookuphash[lookupname] if not replacement then @@ -10442,21 +10402,21 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo if trace_singles then logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement)) end - setfield(current,"char",replacement) + current.char=replacement end end return head,start,true elseif current==stop then break else - current=getnext(current) + current=current.next end end return head,start,false end chainmores.gsub_single=chainprocs.gsub_single function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local replacements=lookuphash[lookupname] @@ -10485,8 +10445,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext local subtables=currentlookup.subtables local value=featurevalue==true and tfmdata.shared.features[kind] or featurevalue while current do - if getid(current)==glyph_code then - local currentchar=getchar(current) + if current.id==glyph_code then + local currentchar=current.char local lookupname=subtables[1] local alternatives=lookuphash[lookupname] if not alternatives then @@ -10501,7 +10461,7 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext if trace_alternatives then logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) end - setfield(start,"char",choice) + start.char=choice else if trace_alternatives then logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) @@ -10515,14 +10475,14 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext elseif current==stop then break else - current=getnext(current) + current=current.next end end return head,start,false end chainmores.gsub_alternate=chainprocs.gsub_alternate function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local ligatures=lookuphash[lookupname] @@ -10537,20 +10497,20 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) end else - local s=getnext(start) + local s=start.next local discfound=false local last=stop local nofreplacements=0 local skipmark=currentlookup.flags[1] while s do - local id=getid(s) + local id=s.id if id==disc_code then - s=getnext(s) + s=s.next discfound=true else - local schar=getchar(s) + local schar=s.char if skipmark and marks[schar] then - s=getnext(s) + s=s.next else local lg=ligatures[schar] if lg then @@ -10558,7 +10518,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if s==stop then break else - s=getnext(s) + s=s.next end else break @@ -10575,7 +10535,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2)) else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop)),gref(l2)) + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2)) end end head,start=toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) @@ -10584,7 +10544,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop))) + logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char)) end end end @@ -10593,7 +10553,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end chainmores.gsub_ligature=chainprocs.gsub_ligature function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -10602,14 +10562,14 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext markanchors=markanchors[markchar] end if markanchors then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10656,7 +10616,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext return head,start,false end function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -10665,14 +10625,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon markanchors=markanchors[markchar] end if markanchors then - local base=getprev(start) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + local base=start.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char if marks[basechar] then while true do - base=getprev(base) - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - basechar=getchar(base) + base=base.prev + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + basechar=base.char if not marks[basechar] then break end @@ -10684,7 +10644,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon end end end - local index=getattr(start,a_ligacomp) + local index=start[a_ligacomp] local baseanchors=descriptions[basechar].anchors if baseanchors then local baseanchors=baseanchors['baselig'] @@ -10723,7 +10683,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon return head,start,false end function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=getchar(start) + local markchar=start.char if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -10732,20 +10692,20 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext markanchors=markanchors[markchar] end if markanchors then - local base=getprev(start) - local slc=getattr(start,a_ligacomp) + local base=start.prev + local slc=start[a_ligacomp] if slc then while base do - local blc=getattr(base,a_ligacomp) + local blc=base[a_ligacomp] if blc and blc~=slc then - base=getprev(base) + base=base.prev else break end end end - if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then - local basechar=getchar(base) + if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then + local basechar=base.char local baseanchors=descriptions[basechar].anchors if baseanchors then baseanchors=baseanchors['basemark'] @@ -10781,9 +10741,9 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext return head,start,false end function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local alreadydone=cursonce and getattr(start,a_cursbase) + local alreadydone=cursonce and start[a_cursbase] if not alreadydone then - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local exitanchors=lookuphash[lookupname] @@ -10797,11 +10757,11 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=getnext(start) - while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do - local nextchar=getchar(nxt) + local nxt=start.next + while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do + local nextchar=nxt.char if marks[nextchar] then - nxt=getnext(nxt) + nxt=nxt.next else local entryanchors=descriptions[nextchar] if entryanchors then @@ -10835,7 +10795,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) end return head,start,false end @@ -10843,7 +10803,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,false end function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -10860,9 +10820,9 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo end chainmores.gpos_single=chainprocs.gpos_single function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local snext=getnext(start) + local snext=start.next if snext then - local startchar=getchar(start) + local startchar=start.char local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -10872,26 +10832,26 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local lookuptype=lookuptypes[lookupname] local prev,done=start,false local factor=tfmdata.parameters.factor - while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do - local nextchar=getchar(snext) + while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do + local nextchar=snext.char local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=getnext(snext) + snext=snext.next else if not krn then elseif type(krn)=="table" then if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=getchar(start) + local startchar=start.char local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -10903,7 +10863,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look if a and a~=0 then local k=setkern(snext,factor,rlmode,a) if trace_kerns then - logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) + logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) end end if b and b~=0 then @@ -10914,7 +10874,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) end done=true end @@ -10935,10 +10895,6 @@ local function show_skip(kind,chainname,char,ck,class) logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(kind,chainname),gref(char),class,ck[1],ck[2]) end end -local quit_on_no_replacement=true -directives.register("otf.chain.quitonnoreplacement",function(value) - quit_on_no_replacement=value -end) local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash) local flags=sequence.flags local done=false @@ -10956,7 +10912,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq local seq=ck[3] local s=#seq if s==1 then - match=getid(current)==glyph_code and getfont(current)==currentfont and getsubtype(current)<256 and seq[1][getchar(current)] + match=current.id==glyph_code and current.font==currentfont and current.subtype<256 and seq[1][current.char] else local f,l=ck[4],ck[5] if f==1 and f==l then @@ -10964,13 +10920,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if f==l then else local n=f+1 - last=getnext(last) + last=last.next while n<=l do if last then - local id=getid(last) + local id=last.id if id==glyph_code then - if getfont(last)==currentfont and getsubtype(last)<256 then - local char=getchar(last) + if last.font==currentfont and last.subtype<256 then + local char=last.char local ccd=descriptions[char] if ccd then local class=ccd.class @@ -10979,10 +10935,10 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if trace_skips then show_skip(kind,chainname,char,ck,class) end - last=getnext(last) + last=last.next elseif seq[n][char] then if n1 then - local prev=getprev(start) + local prev=start.prev if prev then local n=f-1 while n>=1 do if prev then - local id=getid(prev) + local id=prev.id if id==glyph_code then - if getfont(prev)==currentfont and getsubtype(prev)<256 then - local char=getchar(prev) + if prev.font==currentfont and prev.subtype<256 then + local char=prev.char local ccd=descriptions[char] if ccd then local class=ccd.class @@ -11049,7 +11005,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - prev=getprev(prev) + prev=prev.prev elseif seq[n][32] then n=n -1 else @@ -11069,15 +11025,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if match and s>l then - local current=last and getnext(last) + local current=last and last.next if current then local n=l+1 while n<=s do if current then - local id=getid(current) + local id=current.id if id==glyph_code then - if getfont(current)==currentfont and getsubtype(current)<256 then - local char=getchar(current) + if current.font==currentfont and current.subtype<256 then + local char=current.char local ccd=descriptions[char] if ccd then local class=ccd.class @@ -11107,7 +11063,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - current=getnext(current) + current=current.next elseif seq[n][32] then n=n+1 else @@ -11130,7 +11086,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if match then if trace_contexts then local rule,lookuptype,f,l=ck[1],ck[2],ck[4],ck[5] - local char=getchar(start) + local char=start.char if ck[9] then logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a, %a => %a", cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10]) @@ -11164,12 +11120,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq repeat if skipped then while true do - local char=getchar(start) + local char=start.char local ccd=descriptions[char] if ccd then local class=ccd.class if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then - start=getnext(start) + start=start.next else break end @@ -11199,7 +11155,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if start then - start=getnext(start) + start=start.next else end until i>nofchainlookups @@ -11209,7 +11165,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if replacements then head,start,done=chainprocs.reversesub(head,start,last,kind,chainname,ck,lookuphash,replacements) else - done=quit_on_no_replacement + done=true if trace_contexts then logprocess("%s: skipping match",cref(kind,chainname)) end @@ -11326,7 +11282,6 @@ local function featuresprocessor(head,font,attr) if not lookuphash then return head,false end - head=tonut(head) if trace_steps then checkstep(head) end @@ -11359,10 +11314,10 @@ local function featuresprocessor(head,font,attr) local handler=handlers[typ] local start=find_node_tail(head) while start do - local id=getid(start) + local id=start.id if id==glyph_code then - if getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + if start.font==font and start.subtype<256 then + local a=start[0] if a then a=a==attr else @@ -11373,7 +11328,7 @@ local function featuresprocessor(head,font,attr) local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then head,start,success=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) if success then @@ -11384,15 +11339,15 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start=getprev(start) end + if start then start=start.prev end else - start=getprev(start) + start=start.prev end else - start=getprev(start) + start=start.prev end else - start=getprev(start) + start=start.prev end end else @@ -11410,16 +11365,16 @@ local function featuresprocessor(head,font,attr) local head=start local done=false while start do - local id=getid(start) - if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + local id=start.id + if id==glyph_code and start.font==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -11427,12 +11382,12 @@ local function featuresprocessor(head,font,attr) done=true end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end end if done then @@ -11441,17 +11396,17 @@ local function featuresprocessor(head,font,attr) end end while start do - local id=getid(start) + local id=start.id if id==glyph_code then - if getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + if start.font==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -11459,36 +11414,36 @@ local function featuresprocessor(head,font,attr) success=true end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end elseif id==disc_code then - if getsubtype(start)==discretionary_code then - local pre=getfield(start,"pre") + if start.subtype==discretionary_code then + local pre=start.pre if pre then local new=subrun(pre) - if new then setfield(start,"pre",new) end + if new then start.pre=new end end - local post=getfield(start,"post") + local post=start.post if post then local new=subrun(post) - if new then setfield(start,"post",new) end + if new then start.post=new end end - local replace=getfield(start,"replace") + local replace=start.replace if replace then local new=subrun(replace) - if new then setfield(start,"replace",new) end + if new then start.replace=new end end end - start=getnext(start) + start=start.next elseif id==whatsit_code then - local subtype=getsubtype(start) + local subtype=start.subtype if subtype==dir_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -11507,7 +11462,7 @@ local function featuresprocessor(head,font,attr) report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -11520,11 +11475,11 @@ local function featuresprocessor(head,font,attr) report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=getnext(start) + start=start.next elseif id==math_code then - start=getnext(end_of_math(start)) + start=end_of_math(start).next else - start=getnext(start) + start=start.next end end end @@ -11533,20 +11488,20 @@ local function featuresprocessor(head,font,attr) local head=start local done=false while start do - local id=getid(start) - if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + local id=start.id + if id==glyph_code and start.id==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -11561,12 +11516,12 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end end if done then @@ -11575,21 +11530,21 @@ local function featuresprocessor(head,font,attr) end end while start do - local id=getid(start) + local id=start.id if id==glyph_code then - if getfont(start)==font and getsubtype(start)<256 then - local a=getattr(start,0) + if start.font==font and start.subtype<256 then + local a=start[0] if a then - a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) + a=(a==attr) and (not attribute or start[a_state]==attribute) else - a=not attribute or getattr(start,a_state)==attribute + a=not attribute or start[a_state]==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[start.char] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -11604,36 +11559,36 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start=getnext(start) end + if start then start=start.next end else - start=getnext(start) + start=start.next end else - start=getnext(start) + start=start.next end elseif id==disc_code then - if getsubtype(start)==discretionary_code then - local pre=getfield(start,"pre") + if start.subtype==discretionary_code then + local pre=start.pre if pre then local new=subrun(pre) - if new then setfield(start,"pre",new) end + if new then start.pre=new end end - local post=getfield(start,"post") + local post=start.post if post then local new=subrun(post) - if new then setfield(start,"post",new) end + if new then start.post=new end end - local replace=getfield(start,"replace") + local replace=start.replace if replace then local new=subrun(replace) - if new then setfield(start,"replace",new) end + if new then start.replace=new end end end - start=getnext(start) + start=start.next elseif id==whatsit_code then - local subtype=getsubtype(start) + local subtype=start.subtype if subtype==dir_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -11652,7 +11607,7 @@ local function featuresprocessor(head,font,attr) report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=getfield(start,"dir") + local dir=start.dir if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -11665,11 +11620,11 @@ local function featuresprocessor(head,font,attr) report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=getnext(start) + start=start.next elseif id==math_code then - start=getnext(end_of_math(start)) + start=end_of_math(start).next else - start=getnext(start) + start=start.next end end end @@ -11681,7 +11636,6 @@ local function featuresprocessor(head,font,attr) registerstep(head) end end - head=tonode(head) return head,done end local function generic(lookupdata,lookupname,unicode,lookuphash) -- cgit v1.2.3