From 91a47fa6fbfacd23d2802c41d3c908569070bdf2 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 7 Jan 2021 17:18:53 +0100 Subject: 2021-01-07 16:59:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-en.mkii | 1 + tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-cff.lua | 15 +- tex/context/base/mkiv/font-dsp.lua | 4 +- tex/context/base/mkiv/font-mis.lua | 2 +- tex/context/base/mkiv/font-otl.lua | 2 +- tex/context/base/mkiv/font-ots.lua | 3 + tex/context/base/mkiv/mult-low.lua | 3 +- tex/context/base/mkiv/status-files.pdf | Bin 26485 -> 26130 bytes tex/context/base/mkiv/status-lua.pdf | Bin 253534 -> 253886 bytes tex/context/base/mkiv/task-ini.lua | 1 + tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 2 +- tex/context/base/mkxl/driv-shp.lmt | 5 +- tex/context/base/mkxl/font-col.lmt | 54 +- tex/context/base/mkxl/font-ctx.lmt | 10 +- tex/context/base/mkxl/font-ini.mklx | 110 ++-- tex/context/base/mkxl/font-mat.mklx | 71 ++- tex/context/base/mkxl/font-ots.lmt | 688 ++++++++++----------- tex/context/base/mkxl/lang-ini.mkxl | 18 +- tex/context/base/mkxl/node-fnt.lmt | 162 ++--- tex/context/base/mkxl/node-nut.lmt | 2 +- tex/context/base/mkxl/node-tra.lmt | 15 + tex/context/interface/mkii/keys-en.xml | 1 + tex/context/modules/mkiv/s-fonts-variable.mkiv | 6 + tex/generic/context/luatex/luatex-fonts-merged.lua | 14 +- 29 files changed, 621 insertions(+), 578 deletions(-) (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index a466ff87a..d4a5fdb76 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2021.01.05 10:41} +\newcontextversion{2021.01.07 16:56} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 063d2e462..1d1031281 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2021.01.05 10:41} +\edef\contextversion{2021.01.07 16:56} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii index 4c9092f89..d3a073db3 100644 --- a/tex/context/base/mkii/mult-en.mkii +++ b/tex/context/base/mkii/mult-en.mkii @@ -1131,6 +1131,7 @@ \setinterfaceconstant{reference}{reference} \setinterfaceconstant{referencemethod}{referencemethod} \setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencetext}{referencetext} \setinterfaceconstant{referencing}{referencing} \setinterfaceconstant{region}{region} \setinterfaceconstant{regionin}{regionin} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index dff51fd71..cf07d5340 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.01.05 10:41} +\newcontextversion{2021.01.07 16:56} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 8e9dda9c3..10c8b1fdf 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2021.01.05 10:41} +\edef\contextversion{2021.01.07 16:56} %D Kind of special: diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua index b7d45392d..4e2981011 100644 --- a/tex/context/base/mkiv/font-cff.lua +++ b/tex/context/base/mkiv/font-cff.lua @@ -1425,13 +1425,15 @@ do -- to wrap my head around the rather complex variable font specification -- with regions and axis, the following approach kind of works but is more -- some trial and error trick. It's still not clear how much of the complex - -- truetype description applies to cff. + -- truetype description applies to cff. Once there are fonts out there we'll + -- get there. (Marcel and friends did some tests with recent cff2 fonts so + -- the code has been adapted accordingly.) local reginit = false local function updateregions(n) -- n + 1 if regions then - local current = regions[n] or regions[1] + local current = regions[n+1] or regions[1] nofregions = #current if axis and n ~= reginit then factors = { } @@ -2155,7 +2157,14 @@ do popped = 3 seacs = { } if regions then - regions = { regions } -- needs checking + -- this was: + -- regions = { regions } -- needs checking + -- and is now (MFC): + regions = { } + local deltas = data.deltas + for i = 1, #deltas do + regions[i] = deltas[i].regions + end axis = data.factors or false end end diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index 91ee83b19..8d7c3d359 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -503,7 +503,7 @@ local function readvariationdata(f,storeoffset,factors) -- store regions[i] = t end -- deltas - if factors then + -- if factors then for i=1,nofdeltadata do setposition(f,storeoffset+deltadata[i]) local nofdeltasets = readushort(f) @@ -528,7 +528,7 @@ local function readvariationdata(f,storeoffset,factors) -- store scales = factors and getscales(usedregions,factors) or nil, } end - end + -- end setposition(f,position) return regions, deltadata end diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua index da22f3bf9..18120f524 100644 --- a/tex/context/base/mkiv/font-mis.lua +++ b/tex/context/base/mkiv/font-mis.lua @@ -21,7 +21,7 @@ local readers = otf.readers if readers then - otf.version = otf.version or 3.112 + otf.version = otf.version or 3.113 otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true) function fonts.helpers.getfeatures(name,save) diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index b8e13f107..19de2bb77 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.112 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.113 -- beware: also sync font-mis.lua and in mtx-fonts otf.cache = containers.define("fonts", "otl", otf.version, true) otf.svgcache = containers.define("fonts", "svg", otf.version, true) otf.pngcache = containers.define("fonts", "png", otf.version, true) diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 1f4806ee2..880bcb6d5 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -829,6 +829,9 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip -- of{f-}{}{f}e o{f-}{}{f}fe o{-}{}{ff}e (oe and ff ligature) -- we can end up here when we have a start run .. testruns start at a disc but -- so here we have the other case: char + disc + -- + -- Challenge for Kai (latinmodern): \hyphenation{fii-f-f-iif} fiiffiif + -- if discfound then -- don't assume marks in a disc and we don't run over a disc (for now) local pre, post, replace = getdisc(discfound) diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index fb786231e..2b1dffc68 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -541,7 +541,8 @@ return { "prelistbox", "postlistbox", "prelistcopy", "postlistcopy", "setprelistbox", "setpostlistbox", -- "noligaturing", "nokerning", "noexpansion", "noprotrusion", - -- + "noleftkerning", "noleftligaturing", "norightkerning", "norightligaturing", + -- "futureletnexttoken", "defbackslashbreak", "letbackslashbreak", -- "pushoverloadmode", "popoverloadmode", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 6f1f7acfe..154b18975 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 2e51acc39..9434bf9cd 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua index 323ad4dc9..c06e32df3 100644 --- a/tex/context/base/mkiv/task-ini.lua +++ b/tex/context/base/mkiv/task-ini.lua @@ -53,6 +53,7 @@ appendaction("processors", "fonts", "typesetters.fontkerns.handler", appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nonut", "enabled" ) appendaction("processors", "fonts", "builders.kernel.ligaturing", nil, "nut", "disabled" ) appendaction("processors", "fonts", "builders.kernel.kerning", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.show", nil, "nut", "disabled" ) appendaction("processors", "fonts", "nodes.handlers.stripping", nil, "nut", "disabled" ) appendaction("processors", "fonts", "nodes.handlers.flatten", nil, "nut", "disabled" ) appendaction("processors", "fonts", "fonts.goodies.colorschemes.coloring", nil, "nut", "disabled" ) diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index 0fae7c684..700283051 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.01.05 10:41} +\newcontextversion{2021.01.07 16:56} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index 8c6701d81..1a20d3a85 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.01.05 10:41} +\immutable\edef\contextversion{2021.01.07 16:56} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt index 7a0ccf25b..57ac9e294 100644 --- a/tex/context/base/mkxl/driv-shp.lmt +++ b/tex/context/base/mkxl/driv-shp.lmt @@ -925,8 +925,9 @@ local hlist_out, vlist_out do end elseif id == disc_code then local replace, tail = getreplace(current) - if replace and subtype ~= select_disc then - -- we could flatten .. no gain + -- actually, we no longer have these select discs in the packaged list ... it's about + -- time to clean up the disc code a bit further + if replace then -- and subtype ~= select_disc_code then setlink(tail,getnext(current)) setlink(current,replace) setreplace(current) diff --git a/tex/context/base/mkxl/font-col.lmt b/tex/context/base/mkxl/font-col.lmt index a0e40d0ba..200551099 100644 --- a/tex/context/base/mkxl/font-col.lmt +++ b/tex/context/base/mkxl/font-col.lmt @@ -24,6 +24,8 @@ local setfont = nuts.setfont ----- traverse_char = nuts.traverse_char local nextchar = nuts.traversers.char +local getscales = nuts.getscales +local setscales = nuts.setscales local settings_to_hash = utilities.parsers.settings_to_hash @@ -230,9 +232,15 @@ function collections.clonevector(name) local oldchars = fontdata[current].characters local newchars = fontdata[cloneid].characters local factor = definition.factor + local rscale = definition.rscale if factor then vector.factor = factor end +if tex.conditionals["c_font_compact"] then + if rscale then + vector.rscale = rscale + end +end if trace_collecting then if target then report_fonts("remapping font %a to %a for range %U - %U, offset %X, target %U",current,cloneid,start,stop,offset,target) @@ -334,6 +342,9 @@ function collections.prepare(name) -- we can do this in lua now .. todo local f = d[i] local name = f.font local scale = f.rscale or 1 +if tex.conditionals["c_font_compact"] then + scale = 1 +end if fontpatternhassize(name) then context.font_fallbacks_clone_unique(name,scale) else @@ -393,26 +404,33 @@ function collections.process(head) -- this way we keep feature processing local vect = vector[char] if not vect then -- keep it - elseif type(vect) == "table" then - local newfont = vect[1] - local newchar = vect[2] - if trace_collecting then - report_fonts("remapping character %C in font %a to character %C in font %a%s", - char,font,newchar,newfont,not chardata[newfont][newchar] and " (missing)" or "" - ) - end - setfont(n,newfont,newchar) else - local fakemono = vector.factor - if trace_collecting then - report_fonts("remapping font %a to %a for character %C%s", - font,vect,char,not chardata[vect][char] and " (missing)" or "" - ) - end - if fakemono then - setfont(n,vect,monoslot(vect,char,font,fakemono)) + if type(vect) == "table" then + local newfont = vect[1] + local newchar = vect[2] + if trace_collecting then + report_fonts("remapping character %C in font %a to character %C in font %a%s", + char,font,newchar,newfont,not chardata[newfont][newchar] and " (missing)" or "" + ) + end + setfont(n,newfont,newchar) else - setfont(n,vect) + local fakemono = vector.factor + if trace_collecting then + report_fonts("remapping font %a to %a for character %C%s", + font,vect,char,not chardata[vect][char] and " (missing)" or "" + ) + end + if fakemono then + setfont(n,vect,monoslot(vect,char,font,fakemono)) + else + setfont(n,vect) + end + end + local rscale = vector.rscale + if rscale and rscale ~= 1 then + local s, x, y = getscales(n) + setscales(n,s*rscale,x*rscale,y*rscale) end end end diff --git a/tex/context/base/mkxl/font-ctx.lmt b/tex/context/base/mkxl/font-ctx.lmt index b316bcc0a..c59f4c9e7 100644 --- a/tex/context/base/mkxl/font-ctx.lmt +++ b/tex/context/base/mkxl/font-ctx.lmt @@ -1166,8 +1166,13 @@ do -- else too many locals implement { name = "definefont_two", arguments = { - "boolean", "string", "string", "integer", "integer", "string", "string", "string", "string", - "integer", "integer", "integer", "string", "string", "string", "string", "integer", + -- "boolean", "string", "string", "dimension", "integer", "string", + -- "string", "string", "string", "integer", "dimension", "string", + -- "string", "string", "string", "integer", + "boolean", "argument", "argument", "dimension", "integer", + "argument", "argument", "argument", "argument", "integer", + "dimension", "argument", "argument", "argument", "argument", + "integer", }, actions = function ( global, -- \ifx\fontclass\empty\s!false\else\s!true\fi @@ -1181,7 +1186,6 @@ do -- else too many locals fontfallbacks, -- \m_font_fallbacks mathsize, -- \fontface textsize, -- \d_font_scaled_text_face - relativeid, -- \relativefontid classgoodies, -- \m_font_class_goodies goodies, -- \m_font_goodies classdesignsize, -- \m_font_class_designsize diff --git a/tex/context/base/mkxl/font-ini.mklx b/tex/context/base/mkxl/font-ini.mklx index bb5050527..ea049bc38 100644 --- a/tex/context/base/mkxl/font-ini.mklx +++ b/tex/context/base/mkxl/font-ini.mklx @@ -495,8 +495,6 @@ \ifx\p_font_rscale\v!auto \let\p_font_rscale\plusone \font_helpers_check_relative_font_id - \else - \let\relativefontid\minusone \fi} \def\font_rscale_xx#style% @@ -668,8 +666,6 @@ \newcount\lastfontid % also used at the lua end / tex end \newtoks \everydefinefont -\mutable\let\relativefontid\minusone - \aliased\let\c_font_feature_inheritance_fontnone \zerocount % none \aliased\let\c_font_feature_inheritance_fontonly \plusone % fontonly \aliased\let\c_font_feature_inheritance_classonly \plustwo % classonly @@ -771,23 +767,39 @@ \font_helpers_update_font_parameters \font_helpers_update_font_class_parameters %\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}% +% \clf_definefont_two +% \ifempty\fontclass\s!false\else\s!true\fi +% {#csname}% +% {\somefontfile}% +% \d_font_scaled_font_size +% \c_font_feature_inheritance_mode +% {\m_font_class_features}% +% {\m_font_features}% +% {\m_font_class_fallbacks}% +% {\m_font_fallbacks}% +% \fontface +% \d_font_scaled_text_face +% {\m_font_class_goodies}% +% {\m_font_goodies}% +% {\m_font_class_designsize}% +% {\m_font_designsize}% +% \scaledfontmode \clf_definefont_two \ifempty\fontclass\s!false\else\s!true\fi {#csname}% - {\somefontfile}% + \somefontfile \d_font_scaled_font_size \c_font_feature_inheritance_mode - {\m_font_class_features}% - {\m_font_features}% - {\m_font_class_fallbacks}% - {\m_font_fallbacks}% + \m_font_class_features + \m_font_features + \m_font_class_fallbacks + \m_font_fallbacks \fontface \d_font_scaled_text_face - \relativefontid - {\m_font_class_goodies}% - {\m_font_goodies}% - {\m_font_class_designsize}% - {\m_font_designsize}% + \m_font_class_goodies + \m_font_goodies + \m_font_class_designsize + \m_font_designsize \scaledfontmode \relax \ifcase\scaledfontsize @@ -880,23 +892,39 @@ \font_helpers_update_font_class_parameters % ... till here %\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}% +% \clf_definefont_two +% \ifempty\fontclass\s!false\else\s!true\fi +% {#csname}% +% {\somefontfile}% +% \d_font_scaled_font_size +% \c_font_feature_inheritance_mode +% {\m_font_class_features}% +% {\m_font_features}% +% {\m_font_class_fallbacks}% +% {\m_font_fallbacks}% +% \fontface +% \d_font_scaled_text_face +% {\m_font_class_goodies}% +% {\m_font_goodies}% +% {\m_font_class_designsize}% +% {\m_font_designsize}% +% \scaledfontmode \clf_definefont_two \ifempty\fontclass\s!false\else\s!true\fi {#csname}% - {\somefontfile}% + \somefontfile \d_font_scaled_font_size \c_font_feature_inheritance_mode - {\m_font_class_features}% - {\m_font_features}% - {\m_font_class_fallbacks}% - {\m_font_fallbacks}% + \m_font_class_features + \m_font_features + \m_font_class_fallbacks + \m_font_fallbacks \fontface \d_font_scaled_text_face - \relativefontid - {\m_font_class_goodies}% - {\m_font_goodies}% - {\m_font_class_designsize}% - {\m_font_designsize}% + \m_font_class_goodies + \m_font_goodies + \m_font_class_designsize + \m_font_designsize \scaledfontmode \relax \ifcase\scaledfontsize @@ -907,15 +935,15 @@ \else \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks) % - \ifnum\c_font_scaled_font_mode_saved>\plusfour - \glyphscale\numexpr\plusthousand*\dimexpr\d_font_scaled_font_size\relax/\c_font_scaled_points\relax - \else - \glyphscale\c_font_future_glyph_scale - \fi - % actually this has to happen elsewhere .. temp hack (do we know here if we are global?) - \gletcsname\??frozenfont#csname\expandafter\endcsname\csname#csname\endcsname - \protected\xdefcsname#csname\endcsname - {\csname\??frozenfont#csname\endcsname + \glyphscale + \ifnum\c_font_scaled_font_mode_saved>\plusfour + \numexpr\plusthousand*\dimexpr\d_font_scaled_font_size\relax/\c_font_scaled_points\relax + \else + \c_font_future_glyph_scale + \fi + \ifempty\fontclass\else\global\fi + \protected\edefcsname#csname\endcsname + {\setfontid\the\fontid\csname#csname\endcsname\relax \glyphscale\the\glyphscale\relax}% % \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname @@ -1051,28 +1079,14 @@ %D Beware, in the frozen variants no settings are supported yet, but that might happen %D some day. -\installcorenamespace{frozenfont} -%installcorenamespace{frozensize} - -\newcount\c_last_global_glyph_scale - \permanent\tolerant\protected\def\definefrozenfont[#name]#spacer[#specification]#spacer[#settings]% {\ifparameter#name\or \begingroup \definefont[#name][#specification][#settings]% \csname#name\endcsname \glet\lastglobalrawfontcall\lastrawfontcall - \global\c_last_global_glyph_scale\glyphscale \endgroup - \ifconditional\c_font_compact - % temp hack - \letcsname\??frozenfont#name\endcsname\lastglobalrawfontcall - \protected\edefcsname#name\endcsname - {\csname\??frozenfont#name\endcsname - \glyphscale\the\c_last_global_glyph_scale\relax}% - \else - \letcsname#name\endcsname\lastglobalrawfontcall - \fi + \letcsname#name\endcsname\lastglobalrawfontcall \fi} %D The instance namespace protection makes the switch local so that we can redefine a diff --git a/tex/context/base/mkxl/font-mat.mklx b/tex/context/base/mkxl/font-mat.mklx index 0e3b3fbad..561effd58 100644 --- a/tex/context/base/mkxl/font-mat.mklx +++ b/tex/context/base/mkxl/font-mat.mklx @@ -253,34 +253,67 @@ %D little in restoring global states and, what's more important, we get rid of large %D math parameter push/pop in tracingall when not needed. -\def\font_helpers_preset_math_family_indeed#fam#familytag% - {\expandafter\let\expandafter\v_font_math_one\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname - \ifrelax\v_font_math_one - \font_helpers_preset_math_family_warning - \orelse\ifnum\fontid\textfont#fam=\fontid\v_font_math_one\else - \font_helpers_preset_math_family_indeed_changed#fam#familytag% +% \def\font_helpers_preset_math_family_indeed#fam#familytag% +% {\expandafter\let\expandafter\v_font_math_one\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname +% \ifrelax\v_font_math_one +% \font_helpers_preset_math_family_warning +% \orelse\ifnum\fontid\textfont#fam=\fontid\v_font_math_one\else +% \font_helpers_preset_math_family_indeed_changed#fam#familytag% +% \fi} + +% \def\font_helpers_preset_math_family_warning +% {\writestatus{fonts}{math: unset for global bodyfont \fontclass\space at \fontbody}} + +% \def\font_helpers_preset_math_family_indeed_changed_normal#fam#familytag% +% {\font_helpers_set_math_family_set_scales_normal +% \scriptscriptfont#fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname +% \scriptfont #fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname +% \textfont #fam\v_font_math_one} + +% \def\font_helpers_preset_math_family_indeed_changed_compact#fam#familytag% +% {\font_helpers_set_math_family_set_scales_compact +% \scriptscriptfont#fam\v_font_math_one +% \scriptfont #fam\v_font_math_one +% \textfont #fam\v_font_math_one} + +% \def\font_helpers_preset_math_family_indeed_changed +% {\ifconditional\c_font_compact +% \expandafter\font_helpers_preset_math_family_indeed_changed_compact +% \else +% \expandafter\font_helpers_preset_math_family_indeed_changed_normal +% \fi} + +\def\font_helpers_preset_math_family_indeed_normal#fam#familytag% + {\expandafter\let\expandafter\font_math_last_font\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname + \font_math_last_font + \ifnum\fontid\textfont#fam=\fontid\font\else + \font_helpers_preset_math_family_indeed_changed_normal#fam#familytag% \fi} -\def\font_helpers_preset_math_family_warning - {\writestatus{fonts}{math: unset for global bodyfont \fontclass\space at \fontbody}} - \def\font_helpers_preset_math_family_indeed_changed_normal#fam#familytag% {\font_helpers_set_math_family_set_scales_normal - \scriptscriptfont#fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname - \scriptfont #fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname - \textfont #fam\v_font_math_one} + \csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname\scriptscriptfont#fam\font + \csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname\scriptfont #fam\font + % \csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname\textfont #fam\font} + \font_math_last_font \textfont #fam\font} + +\def\font_helpers_preset_math_family_indeed_compact#fam#familytag% + {\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-1\endcsname + \ifnum\fontid\textfont#fam=\fontid\font\else + \font_helpers_preset_math_family_indeed_changed_compact#fam% + \fi} -\def\font_helpers_preset_math_family_indeed_changed_compact#fam#familytag% +\def\font_helpers_preset_math_family_indeed_changed_compact#fam% {\font_helpers_set_math_family_set_scales_compact - \scriptscriptfont#fam\v_font_math_one - \scriptfont #fam\v_font_math_one - \textfont #fam\v_font_math_one} + \scriptscriptfont#fam\font + \scriptfont #fam\font + \textfont #fam\font} -\def\font_helpers_preset_math_family_indeed_changed +\def\font_helpers_preset_math_family_indeed {\ifconditional\c_font_compact - \expandafter\font_helpers_preset_math_family_indeed_changed_compact + \expandafter\font_helpers_preset_math_family_indeed_compact \else - \expandafter\font_helpers_preset_math_family_indeed_changed_normal + \expandafter\font_helpers_preset_math_family_indeed_normal \fi} \let\font_helpers_reset_fontclass_math_families\gobbleoneargument diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt index 03e0f47fa..578e661eb 100644 --- a/tex/context/base/mkxl/font-ots.lmt +++ b/tex/context/base/mkxl/font-ots.lmt @@ -133,7 +133,6 @@ local registertracker = trackers.register local logs = logs local trackers = trackers local nodes = nodes -local attributes = attributes local fonts = fonts local otf = fonts.handlers.otf @@ -194,7 +193,6 @@ local getboth = nuts.getboth local setboth = nuts.setboth local getid = nuts.getid local getstate = nuts.getstate -local getsubtype = nuts.getsubtype local setsubtype = nuts.setsubtype local getchar = nuts.getchar local setchar = nuts.setchar @@ -203,9 +201,11 @@ local setdisc = nuts.setdisc local getreplace = nuts.getreplace local setlink = nuts.setlink local getwidth = nuts.getwidth +local getoptions = nuts.getoptions +local setoptions = nuts.setoptions local getglyphdata = nuts.getglyphdata -local getwhatever = nuts.getwhatever +local getscales = nuts.getscales --------------------------------------------------------------------------------------- @@ -247,7 +247,6 @@ local nextnode = nuts.traversers.node local nodecodes = nodes.nodecodes local glyphcodes = nodes.glyphcodes -local disccodes = nodes.disccodes local glyph_code = nodecodes.glyph local glue_code = nodecodes.glue @@ -259,7 +258,7 @@ local par_code = nodecodes.par local lefttoright_code = nodes.dirvalues.lefttoright local righttoleft_code = nodes.dirvalues.righttoleft -local discretionarydisc_code = disccodes.discretionary +local discretionarydisc_code = nodes.disccodes.discretionary local ligatureglyph_code = glyphcodes.ligature local injections = nodes.injections @@ -294,7 +293,7 @@ local descriptions = false local marks = false local classes = false local currentfont = false -local currentattr = false +local currentdynamic = false local currentscale = false local currentxscale = false local currentyscale = false @@ -517,15 +516,37 @@ local has_glyph_option = nuts.has_glyph_option -- in lmtx we need to check the components and can be slightly more clever -local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head - if has_glyph_option(start,no_right_ligature_code) then - return head, start +local function inhibited(start,stop) + for n in nextnode, start do + -- we asume glyph nodes + if n == start then + if has_glyph_option(n,no_right_ligature_code) then + return true + end + elseif n == stop then + if has_glyph_option(n,no_left_ligature_code) then + return true + else + return false + end + elseif has_glyph_option(n,no_left_ligature_code) then + return true + elseif has_glyph_option(n,no_right_ligature_code) then + return true + end end + return false +end + +local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head if start == stop and getchar(start) == char then resetinjection(start) setchar(start,char) return head, start end + if inhibited(start,stop) then + return head, start + end local prev = getprev(start) local next = getnext(stop) local comp = start @@ -537,6 +558,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou end resetinjection(base) setchar(base,char) + setoptions(base,getoptions(start) | getoptions(stop)) -- maybe only lig options setsubtype(base,ligatureglyph_code) set_components(base,comp) setlink(prev,base,next) @@ -572,7 +594,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou -- we can have one accent as part of a lookup and another following local start = getnext(current) while start do - local char = ischar(start) + local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then -- also something skiphash here? if marks[char] then @@ -580,7 +602,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou if trace_marks then logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) end - start = getnext(start) + start = nxt else break end @@ -756,7 +778,7 @@ end -- marks that are kept. function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash) - local current = getnext(start) + local current = getnext(start) if not current then return head, start, false, nil end @@ -764,7 +786,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip local startchar = getchar(start) if skiphash and skiphash[startchar] then while current do - local nxt, char = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then local lg = ligature[char] if lg then @@ -798,7 +820,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip local discfound = false local hasmarks = marks[startchar] while current do - local nxt, char, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then current = nxt @@ -828,25 +850,27 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip -- of{f-}{}{f}e o{f-}{}{f}fe o{-}{}{ff}e (oe and ff ligature) -- we can end up here when we have a start run .. testruns start at a disc but -- so here we have the other case: char + disc + -- + -- Challenge for Kai (latinmodern): \hyphenation{fii-f-f-iif} fiiffiif + -- if discfound then -- don't assume marks in a disc and we don't run over a disc (for now) local pre, post, replace = getdisc(discfound) local match if replace then - local char = ischar(replace,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char = isnextchar(replace,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char and ligature[char] then match = true end end if not match and pre then - local char = ischar(pre,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char = isnextchar(pre,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char and ligature[char] then match = true end end - if not match and not pre or not replace then - local n = getnext(discfound) - local char = ischar(n,currentfont,currentscale,currentxscale,currentyscale) + if not match and (not pre or not replace) then + local nxt, char = isnextchar(getnext(discfound),currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char and ligature[char] then match = true end @@ -899,6 +923,8 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) + -- we can have a rare case of multiple disc in a lig but that makes no sense language wise but if really + -- needed we could backtrack if we're in a disc node else -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) @@ -950,11 +976,11 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,st else local prev = start while snext do - local nextchar = ischar(snext,currentfont,currentscale,currentxscale,currentyscale) + local nxt, nextchar = isnextchar(snext,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if nextchar then if skiphash and skiphash[nextchar] then -- includes marks too when flag prev = snext - snext = getnext(snext) + snext = nxt else local krn = kerns[nextchar] if not krn then @@ -1016,13 +1042,14 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode, if marks[markchar] then local base = getprev(start) -- [glyph] [start=mark] if base then - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then + -- todo: use prv while base do base = getprev(base) if base then - basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1071,13 +1098,14 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm if marks[markchar] then local base = getprev(start) -- [glyph] [optional marks] [start=mark] if base then - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then + -- todo: use prv while base do base = getprev(base) if base then - basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1147,7 +1175,7 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode, end end if base then - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local nxt, basechar = isnextchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then -- subtype test can go local ba = markanchors[1][basechar] -- slot 1 has been made copy of the class hash if ba then @@ -1176,11 +1204,11 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,sk else local nxt = getnext(start) while nxt do - local nextchar = ischar(nxt,currentfont,currentscale,currentxscale,currentyscale) + local n, nextchar = isnextchar(nxt,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if not nextchar then break elseif marks[nextchar] then -- always sequence.flags[1] - nxt = getnext(nxt) + nxt = n else local exit = exitanchors[3] if exit then @@ -1330,7 +1358,7 @@ function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,r if mapping then local current = start while current do - local currentchar = ischar(current) + local nxt, currentchar = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if currentchar then local replacement = mapping[currentchar] if not replacement or replacement == "" then @@ -1351,7 +1379,7 @@ function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,r elseif current == stop then break else - current = getnext(current) + current = nxt end end end @@ -1381,7 +1409,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku local value = what == true and tfmdata.shared.features[kind] or what -- todo: optimize in ctx local current = start while current do - local currentchar = ischar(current) + local nxt, currentchar = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if currentchar then local alternatives = mapping[currentchar] if alternatives then @@ -1405,7 +1433,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku elseif current == stop then break else - current = getnext(current) + current = nxt end end end @@ -1504,7 +1532,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup -- end -- end -- - local nxt, schar, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) + local nxt, schar, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if schar then if skiphash and skiphash[schar] then -- marks -- if current == stop then -- maybe add this @@ -1615,13 +1643,12 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm if kerns then local prev = start while snext do - local nextchar = ischar(snext,currentfont,currentscale,currentxscale,currentyscale) + local nxt, nextchar = isnextchar(snext,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if not nextchar then break - end - if skiphash and skiphash[nextchar] then + elseif skiphash and skiphash[nextchar] then prev = snext - snext = getnext(snext) + snext = nxt else local krn = kerns[nextchar] if not krn then @@ -1684,13 +1711,14 @@ function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlooku if markanchors then local base = getprev(start) -- [glyph] [start=mark] if base then - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then + -- todo: use prv while base do base = getprev(base) if base then - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1749,13 +1777,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentl if markanchors then local base = getprev(start) -- [glyph] [optional marks] [start=mark] if base then - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then + -- todo: use prv while base do base = getprev(base) if base then - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local prv, basechar = isprevchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1829,7 +1858,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlooku end end if base then -- subtype test can go - local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) + local nxt, basechar = isnextchar(base,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if basechar then local ba = markanchors[1][basechar] if ba then @@ -1875,12 +1904,12 @@ function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup, else local nxt = getnext(start) while nxt do - local nextchar = ischar(nxt,currentfont,currentscale,currentxscale,currentyscale) + local n, nextchar = isnextchar(nxt,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if not nextchar then break elseif marks[nextchar] then -- should not happen (maybe warning) - nxt = getnext(nxt) + nxt = n else local exit = exitanchors[3] if exit then @@ -2050,10 +2079,10 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) while start do if skiphash then -- hm, so we know we skip some while start do - local char = ischar(start,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then - start = getnext(start) + start = nxt else break end @@ -2311,7 +2340,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) local insertedmarks = 0 while cprev do - local char = ischar(cf,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char = isnextchar(cf,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char and marks[char] then insertedmarks = insertedmarks + 1 cf = cprev @@ -2377,11 +2406,11 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) local insertedmarks = 0 while cnext do - local char = ischar(cnext,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char = isnextchar(cnext,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char and marks[char] then insertedmarks = insertedmarks + 1 cl = cnext - cnext = getnext(cnext) + cnext = nxt else break end @@ -2508,8 +2537,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s local nofcontexts = contexts.n -- #contexts - local startchar = nofcontext == 1 or ischar(start,currentfont,currentscale,currentxscale,currentyscale) -- only needed in a chain - + local startchar = nofcontext == 1 or ischar(start,currentfont) -- already checked for k=1,nofcontexts do -- does this disc mess work well with n > 1 local ck = contexts[k] @@ -2541,8 +2569,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s sweeptype = nil end if last then - -- local char, id = ischar(last,currentfont) - local nxt, char, id = isnextchar(last,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char, id = isnextchar(last,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then skipped = true @@ -2654,8 +2681,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s local n = f - 1 while n >= 1 do if prev then - -- local char, id = ischar(prev,currentfont) - local prv, char, id = isprevchar(prev,currentfont,currentscale,currentxscale,currentyscale) + local prv, char, id = isprevchar(prev,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then skipped = true @@ -2792,8 +2818,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s local n = l + 1 while n <= s do if current then - -- local char, id = ischar(current,currentfont) - local nxt, char, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) + local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then skipped = true @@ -3104,7 +3129,7 @@ local function report_disc(what,n) report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) end -local function kernrun(disc,k_run,font,attr,...) +local function kernrun(disc,k_run,...) -- -- we catch -- @@ -3125,30 +3150,30 @@ local function kernrun(disc,k_run,font,attr,...) -- has happened but then it should be in the disc so basically this test indicates an error) -- while prevmarks do - local char = ischar(prevmarks,font) + local prv, char = isprevchar(prevmarks,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char and marks[char] then - prevmarks = getprev(prevmarks) + prevmarks = prv else break end end -- - if prev and not ischar(prev,font) then -- and (pre or replace) + if prev and not ischar(prev,currentfont) then -- and (pre or replace) -- weak test prev = false end - if next and not ischar(next,font) then -- and (post or replace) + if next and not ischar(next,currentfont) then -- and (post or replace) -- weak test next = false end -- -- we need to get rid of this nest mess some day .. has to be done otherwise -- if pre then - if k_run(pre,"injections",nil,font,attr,...) then + if k_run(pre,"injections",nil,...) then done = true end if prev then setlink(prev,pre) - if k_run(prevmarks,"preinjections",pre,font,attr,...) then -- or prev? + if k_run(prevmarks,"preinjections",pre,...) then -- or prev? done = true end setprev(pre) @@ -3157,12 +3182,12 @@ local function kernrun(disc,k_run,font,attr,...) end -- if post then - if k_run(post,"injections",nil,font,attr,...) then + if k_run(post,"injections",nil,...) then done = true end if next then setlink(posttail,next) - if k_run(posttail,"postinjections",next,font,attr,...) then + if k_run(posttail,"postinjections",next,...) then done = true end setnext(posttail) @@ -3171,12 +3196,12 @@ local function kernrun(disc,k_run,font,attr,...) end -- if replace then - if k_run(replace,"injections",nil,font,attr,...) then + if k_run(replace,"injections",nil,...) then done = true end if prev then setlink(prev,replace) - if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then -- getnext(replace)) + if k_run(prevmarks,"replaceinjections",replace,...) then -- getnext(replace)) done = true end setprev(replace) @@ -3184,7 +3209,7 @@ local function kernrun(disc,k_run,font,attr,...) end if next then setlink(replacetail,next) - if k_run(replacetail,"replaceinjections",next,font,attr,...) then + if k_run(replacetail,"replaceinjections",next,...) then done = true end setnext(replacetail) @@ -3192,7 +3217,7 @@ local function kernrun(disc,k_run,font,attr,...) end elseif prev and next then setlink(prev,next) - if k_run(prevmarks,"emptyinjections",next,font,attr,...) then + if k_run(prevmarks,"emptyinjections",next,...) then done = true end setlink(prev,disc,next) @@ -3259,6 +3284,12 @@ end -- if we can hyphenate in a lig then unlikely a lig so we -- could have a option here to ignore lig +local test_flatten_start = 2 -- must start at 2 according to Kai + +directives.register("otf.testrun.forceflatten", function(v) + test_flatten_start = v and 1 or 2 +end) + local function testrun(disc,t_run,c_run,...) if trace_testruns then report_disc("test",disc) @@ -3287,7 +3318,7 @@ local function testrun(disc,t_run,c_run,...) local d = d_replace > d_post and d_replace or d_post local head = getnext(disc) -- is: next local tail = head - for i=2,d do -- must start at 2 according to Kai + for i=test_flatten_start,d do local nx = getnext(tail) local id = getid(nx) if id == disc_code then @@ -3383,7 +3414,7 @@ end local nesting = 0 -local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) +local function c_run_single(head,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) local done = false local sweep = sweephead[head] local start @@ -3395,26 +3426,17 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm start = head end while start do - local char, id = ischar(start,font) + local nxt, char, id = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then - local a -- happens often so no assignment is faster - if attr then - a = getglyphdata(start) - end - if not a or (a == attr) then - local lookupmatch = lookupcache[char] - if lookupmatch then - local ok - head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done = true - end + local lookupmatch = lookupcache[char] + if lookupmatch then + local ok + head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + done = true end - if start then - start = getnext(start) - end - else - -- go on can be a mixed one + end + if start then start = getnext(start) end elseif char == false then @@ -3424,94 +3446,81 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm return head, done else -- in disc component - start = getnext(start) + start = nxt end end return head, done end -local function t_run_single(start,stop,font,attr,lookupcache) +local function t_run_single(start,stop,lookupcache) local lastd = nil while start ~= stop do - local char = ischar(start,font) + local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then - local a -- happens often so no assignment is faster - if attr then - a = getglyphdata(start) - end - local startnext = getnext(start) - if not a or (a == attr) then - local lookupmatch = lookupcache[char] - if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check - -- if we need more than ligatures we can outline the code and use functions - local s = startnext - local ss = nil - local sstop = s == stop + local lookupmatch = lookupcache[char] + if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check + -- if we need more than ligatures we can outline the code and use functions + local s = startnext + local ss = nil + local sstop = s == stop + if not s then + s = ss + ss = nil + end + -- a bit weird: why multiple ... anyway we can't have a disc in a disc + -- how about post ... we can probably merge this into the while + while getid(s) == disc_code do + ss = getnext(s) + s = getreplace(s) if not s then s = ss ss = nil end - -- a bit weird: why multiple ... anyway we can't have a disc in a disc - -- how about post ... we can probably merge this into the while - while getid(s) == disc_code do - ss = getnext(s) - s = getreplace(s) - if not s then - s = ss - ss = nil - end - end - local l = nil - local d = 0 - while s do - local char = ischar(s,font) - if char then - local lg = lookupmatch[char] - if lg then - if sstop then - d = 1 - elseif d > 0 then - d = d + 1 - end - l = lg - s = getnext(s) - sstop = s == stop + end + local l = nil + local d = 0 + while s do + local nxt, char = isnextchar(s,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) + if char then + local lg = lookupmatch[char] + if lg then + if sstop then + d = 1 + elseif d > 0 then + d = d + 1 + end + l = lg + s = nxt + sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getreplace(s) if not s then s = ss ss = nil end - while getid(s) == disc_code do - ss = getnext(s) - s = getreplace(s) - if not s then - s = ss - ss = nil - end - end - lookupmatch = lg - else - break end + lookupmatch = lg else break end + else + break end - if l and l.ligature then -- so we test for ligature - lastd = d - end - -- why not: if not l then break elseif l.ligature then return d end - else - -- why not: break - -- no match (yet) end - else - -- go on can be a mixed one - -- why not: break + if l and l.ligature then -- so we test for ligature + lastd = d + end end if lastd then return lastd + else + start = startnext end - start = startnext else break end @@ -3519,17 +3528,12 @@ local function t_run_single(start,stop,font,attr,lookupcache) return 0 end -local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - local a -- happens often so no assignment is faster - if attr then - a = getglyphdata(sub) - end - if not a or (a == attr) then - for n in nextnode, sub do -- only gpos - if n == last then - break - end - local char = ischar(n,font) +local function k_run_single(sub,injection,last,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + for n in nextnode, sub do -- only gpos + if n == last then + break + else + local nxt, char = isnextchar(n,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then local lookupmatch = lookupcache[char] if lookupmatch then @@ -3543,25 +3547,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase end end --- local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) --- for n in nextnode, sub do -- only gpos --- if n == last then --- break --- end --- local char = ischar(n,font,attr) --- if char then --- local lookupmatch = lookupcache[char] --- if lookupmatch then --- local h, d, ok = handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) --- if ok then --- return true --- end --- end --- end --- end --- end - -local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) +local function c_run_multiple(head,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) local done = false local sweep = sweephead[head] local start @@ -3573,35 +3559,26 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm start = head end while start do - local char = ischar(start,font) + local nxt, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then - local a -- happens often so no assignment is faster - if attr then - a = getglyphdata(start) - end - if not a or (a == attr) then - for i=1,nofsteps do - local step = steps[i] - local lookupcache = step.coverage - local lookupmatch = lookupcache[char] - if lookupmatch then - -- we could move all code inline but that makes things even more unreadable - local ok - head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done = true - break - elseif not start then - -- don't ask why ... shouldn't happen - break - end + for i=1,nofsteps do + local step = steps[i] + local lookupcache = step.coverage + local lookupmatch = lookupcache[char] + if lookupmatch then + -- we could move all code inline but that makes things even more unreadable + local ok + head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + done = true + break + elseif not start then + -- don't ask why ... shouldn't happen + break end end - if start then - start = getnext(start) - end - else - -- go on can be a mixed one + end + if start then start = getnext(start) end elseif char == false then @@ -3612,91 +3589,83 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm return head, done else -- in disc component - start = getnext(start) + start = nxt end end return head, done end -local function t_run_multiple(start,stop,font,attr,steps,nofsteps) +local function t_run_multiple(start,stop,steps,nofsteps) local lastd = nil while start ~= stop do - local char = ischar(start,font) + local startnext, char = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then - local a -- happens often so no assignment is faster - if attr then - a = getglyphdata(start) - end - local startnext = getnext(start) - if not a or (a == attr) then - for i=1,nofsteps do - local step = steps[i] - local lookupcache = step.coverage - local lookupmatch = lookupcache[char] - if lookupmatch then - -- if we need more than ligatures we can outline the code and use functions - local s = startnext - local ss = nil - local sstop = s == stop + for i=1,nofsteps do + local step = steps[i] + local lookupcache = step.coverage + local lookupmatch = lookupcache[char] + if lookupmatch then + -- if we need more than ligatures we can outline the code and use functions + local s = startnext + local ss = nil + local sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getreplace(s) if not s then s = ss ss = nil end - while getid(s) == disc_code do - ss = getnext(s) - s = getreplace(s) - if not s then - s = ss - ss = nil - end - end - local l = nil - local d = 0 - while s do - local char = ischar(s) - if char then - local lg = lookupmatch[char] - if lg then - if sstop then - d = 1 - elseif d > 0 then - d = d + 1 - end - l = lg - s = getnext(s) - sstop = s == stop + end + local l = nil + local d = 0 + while s do + local nxt, char = isnextchar(s,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) + if char then + local lg = lookupmatch[char] + if lg then + if sstop then + d = 1 + elseif d > 0 then + d = d + 1 + end + l = lg + s = nxt + sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getreplace(s) if not s then s = ss ss = nil end - while getid(s) == disc_code do - ss = getnext(s) - s = getreplace(s) - if not s then - s = ss - ss = nil - end - end - lookupmatch = lg - else - break end + lookupmatch = lg else break end + else + break end - if l and l.ligature then - lastd = d - end + end + if l and l.ligature then + lastd = d end end - else - -- go on can be a mixed one end if lastd then return lastd + else + start = startnext end - start = startnext else break end @@ -3704,17 +3673,12 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) return 0 end -local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - local a -- happens often so no assignment is faster - if attr then - a = getglyphdata(sub) - end - if not a or (a == attr) then - for n in nextnode, sub do -- only gpos - if n == last then - break - end - local char = ischar(n) +local function k_run_multiple(sub,injection,last,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + for n in nextnode, sub do -- only gpos + if n == last then + break + else + local nxt, char = isnextchar(n,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then for i=1,nofsteps do local step = steps[i] @@ -3782,7 +3746,7 @@ otf.helpers.txtdirstate = txtdirstate otf.helpers.pardirstate = pardirstate -- This is the main loop. We run over the node list dealing with a specific font. The --- attribute is a context specific thing. We could work on sub start-stop ranges instead +-- dynamic is a context specific thing. We could work on sub start-stop ranges instead -- but I wonder if there is that much speed gain (experiments showed that it made not -- much sense) and we need to keep track of directions anyway. Also at some point I -- want to play with font interactions and then we do need the full sweeps. Apart from @@ -3818,27 +3782,27 @@ do return v end } - function otf.featuresprocessor(head,font,attr,direction,n) + function otf.featuresprocessor(head,font,dynamic,direction,n) local sequences = sequencelists[font] -- temp hack nesting = nesting + 1 if nesting == 1 then - currentfont = font - currentattr = attr - currentscale = false - currentxscale = false - currentyscale = false - tfmdata = fontdata[font] - descriptions = tfmdata.descriptions -- only needed in gref so we could pass node there instead - characters = tfmdata.characters -- but this branch is not entered that often anyway - local resources = tfmdata.resources - marks = resources.marks - classes = resources.classes + currentfont = font + currentdynamic = dynamic + currentscale = false + currentxscale = false + currentyscale = false + tfmdata = fontdata[font] + descriptions = tfmdata.descriptions -- only needed in gref so we could pass node there instead + characters = tfmdata.characters -- but this branch is not entered that often anyway + local resources = tfmdata.resources + marks = resources.marks + classes = resources.classes threshold, - factor = getthreshold(font) - checkmarks = tfmdata.properties.checkmarks + factor = getthreshold(font) + checkmarks = tfmdata.properties.checkmarks if not otfdataset then otfdataset = otf.dataset @@ -3867,7 +3831,7 @@ do initialrl = -1 end - local datasets = otfdataset(tfmdata,font,attr) + local datasets = otfdataset(tfmdata,font,dynamic) local dirstack = { nil } -- could move outside function but we can have local runs sweephead = { } -- sweephead = { a = 1, b = 1 } sweephead.a = nil sweephead.b = nil @@ -3880,7 +3844,7 @@ do for s=1,#datasets do local dataset = datasets[s] - local attribute = dataset[2] + local state = dataset[2] local sequence = dataset[3] -- sequences[s] -- also dataset[5] local rlparmode = initialrl local topstack = 0 @@ -3896,7 +3860,7 @@ do -- This permits injection, watch the different arguments. Watch out, the arguments passed -- are not frozen as we might extend or change this. Is this used at all apart from some -- experiments? - local h, ok = handler(head,dataset,sequence,initialrl,font,attr) -- less arguments now + local h, ok = handler(head,dataset,sequence,initialrl,font,dynamic) -- less arguments now if h and h ~= head then head = h end @@ -3910,31 +3874,26 @@ do local rlmode = 0 -- how important is this .. do we need to check for dir? local merged = steps.merged while start do - local prv, char, id = isprevchar(start,font) + local prv, char, id = isprevchar(start,font,dynamic,state) if char then local m = merged[char] if m then - local a - a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute) - if a then - for i=m[1],m[2] do - local step = steps[i] - local lookupcache = step.coverage - local lookupmatch = lookupcache[char] - if lookupmatch then - local ok - head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - -- done = true - break - end + currentscale, currentxscale, currentyscale = getscales(start) + for i=m[1],m[2] do + local step = steps[i] + local lookupcache = step.coverage + local lookupmatch = lookupcache[char] + if lookupmatch then + local ok + head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + -- done = true + break end end - if start then - start = getprev(start) - end - else - start = prv + end + if start then + start = getprev(start) end else start = prv @@ -3950,30 +3909,24 @@ do local step = steps[1] local lookupcache = step.coverage while start do - local nxt, char, id = isnextchar(start,font) -- we can move the data/state checks here + local nxt, char, id = isnextchar(start,font,dynamic,state) -- we can move the data/state checks here if char then if skiphash and skiphash[char] then -- we never needed it here but let's try start = nxt else local lookupmatch = lookupcache[char] if lookupmatch then - local a - a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute) - if a then - local ok, df - head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if df then - -- print("restart 1",typ) - elseif start then - start = getnext(start) -- can be a new start - end - else - start = nxt + currentscale, currentxscale, currentyscale = getscales(start) + local ok, df + head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + -- print("restart 1",typ) + elseif start then + start = getnext(start) -- can be a new start end else start = nxt end - end elseif char == false or id == glue_code then -- a different font|state or glue (happens often) @@ -3982,11 +3935,11 @@ do if not discs or discs[start] == true then local ok if gpossing then - start, ok = kernrun(start,k_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + start, ok = kernrun(start,k_run_single, lookupcache,step,dataset,sequence,rlmode,skiphash,handler) elseif forcetestrun then - start, ok = testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + start, ok = testrun(start,t_run_single,c_run_single,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) else - start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + start, ok = comprun(start,c_run_single, lookupcache,step,dataset,sequence,rlmode,skiphash,handler) end -- if ok then -- done = true @@ -4009,42 +3962,37 @@ do else local merged = steps.merged while start do - local nxt, char, id = isnextchar(start,font) + local nxt, char, id = isnextchar(start,font,dynamic,state) if char then if skiphash and skiphash[char] then -- we never needed it here but let's try start = nxt else local m = merged[char] if m then - local a - a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute) - if a then - local ok, df - for i=m[1],m[2] do - local step = steps[i] - local lookupcache = step.coverage - local lookupmatch = lookupcache[char] - if lookupmatch then - -- we could move all code inline but that makes things even more unreadable + currentscale, currentxscale, currentyscale = getscales(start) + local ok, df + for i=m[1],m[2] do + local step = steps[i] + local lookupcache = step.coverage + local lookupmatch = lookupcache[char] + if lookupmatch then + -- we could move all code inline but that makes things even more unreadable -- local ok, df - head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if df then - break - elseif ok then - break - elseif not start then - -- don't ask why ... shouldn't happen - break - end + head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + break + elseif ok then + break + elseif not start then + -- don't ask why ... shouldn't happen + break end end - if df then - -- print("restart 2",typ) - elseif start then - start = getnext(start) -- can be a new next - end - else - start = nxt + end + if df then + -- print("restart 2",typ) + elseif start then + start = getnext(start) -- can be a new next end else start = nxt @@ -4057,11 +4005,11 @@ do if not discs or discs[start] == true then local ok if gpossing then - start, ok = kernrun(start,k_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + start, ok = kernrun(start,k_run_multiple, steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) elseif forcetestrun then - start, ok = testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + start, ok = testrun(start,t_run_multiple,c_run_multiple,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) else - start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + start, ok = comprun(start,c_run_multiple, steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) end else start = nxt @@ -4098,6 +4046,7 @@ do function otf.datasetpositionprocessor(head,font,direction,dataset) currentfont = font + currentdynamic = false currentscale = false currentxscale = false currentyscale = false @@ -4142,8 +4091,7 @@ do local position = 0 while start do - -- local char, id = ischar(start,font) - local nxt, char, id = isnextchar(start,font) + local nxt, char, id = isnextchar(start,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then position = position + 1 local m = merged[char] @@ -4240,14 +4188,14 @@ function otf.plugininitializer(tfmdata,value) end end -function otf.pluginprocessor(head,font,attr,direction) -- n +function otf.pluginprocessor(head,font,dynamic,direction) -- n local s = fontdata[font].shared local p = s and s.plugin if p then if trace_plugins then report_process("applying plugin %a",p[1]) end - return p[2](head,font,attr,direction) + return p[2](head,font,dynamic,direction) else return head, false end @@ -4294,7 +4242,7 @@ registerotffeature { -- when a handler has steps, it is called as the other ones, but when we have no steps, -- we use a different call: -- --- function(head,dataset,sequence,initialrl,font,attr) +-- function(head,dataset,sequence,initialrl,font,dynamic) -- return head, done -- end -- @@ -4314,7 +4262,7 @@ local tag = "kern" -- if fontfeatures then --- function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) +-- function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,dynamic) -- local features = fontfeatures[font] -- local enabled = features and features.spacekern and features[tag] -- if enabled then @@ -4325,7 +4273,7 @@ local tag = "kern" -- else -- generic (no hashes) - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) + function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,dynamic) local shared = fontdata[font].shared local features = shared and shared.features local enabled = features and features.spacekern and features[tag] @@ -4409,7 +4357,7 @@ otf.readers.registerextender { end } -local function spaceinitializer(tfmdata,value) -- attr +local function spaceinitializer(tfmdata,value) -- dynamic local resources = tfmdata.resources local spacekerns = resources and resources.spacekerns if value and spacekerns == nil then diff --git a/tex/context/base/mkxl/lang-ini.mkxl b/tex/context/base/mkxl/lang-ini.mkxl index e115ce9f8..2644d1d76 100644 --- a/tex/context/base/mkxl/lang-ini.mkxl +++ b/tex/context/base/mkxl/lang-ini.mkxl @@ -756,7 +756,18 @@ {\clf_currentposthyphenchar post}% {replace}} -%D Also new: +%D A typical \LMTX\ feature: +%D +%D \starttyping +%D whatever\par +%D {\nokerning whatever}\par +%D efficient ff fi\par +%D {\noligaturing efficient ff fi}\par +%D {\nokerning\noligaturing efficient ff fi}\par +%D {e{\noligaturing ffi}cient}\par +%D {ef{\noleftligaturing f}icient ff fi}\par +%D {ef{\norightligaturing f}icient ff fi}\par +%D \stoptyping \immutable\chardef\nokerningcode \numexpr\noleftkerncode +\norightkerncode \relax \immutable\chardef\noligaturingcode\numexpr\noleftligaturecode+\norightligaturecode\relax @@ -764,4 +775,9 @@ \permanent\protected\def\nokerning {\bitwiseflip\glyphoptions\nokerningcode} \permanent\protected\def\noligaturing{\bitwiseflip\glyphoptions\noligaturingcode} +\permanent\protected\def\noleftkerning {\bitwiseflip\glyphoptions\noleftkerncode} +\permanent\protected\def\noleftligaturing {\bitwiseflip\glyphoptions\noleftligaturecode} +\permanent\protected\def\norightkerning {\bitwiseflip\glyphoptions\norightkerncode} +\permanent\protected\def\norightligaturing{\bitwiseflip\glyphoptions\norightligaturecode} + \protect \endinput diff --git a/tex/context/base/mkxl/node-fnt.lmt b/tex/context/base/mkxl/node-fnt.lmt index 658ea46bb..c96bdde3d 100644 --- a/tex/context/base/mkxl/node-fnt.lmt +++ b/tex/context/base/mkxl/node-fnt.lmt @@ -60,8 +60,6 @@ local setprev = nuts.setprev local isglyph = nuts.isglyph -- unchecked local ischar = nuts.ischar -- checked ------ traverse_id = nuts.traverse_id ------ traverse_char = nuts.traverse_char local nextboundary = nuts.traversers.boundary local nextdisc = nuts.traversers.disc local nextchar = nuts.traversers.char @@ -88,14 +86,6 @@ local run = 0 local setfontdynamics = { } local fontprocesses = { } --- setmetatableindex(setfontdynamics, function(t,font) --- local tfmdata = fontdata[font] --- local shared = tfmdata.shared --- local v = shared and shared.dynamics and otf.setdynamics or false --- t[font] = v --- return v --- end) - setmetatableindex(setfontdynamics, function(t,font) local tfmdata = fontdata[font] local shared = tfmdata.shared @@ -156,8 +146,8 @@ local function start_trace(head) local char, id = isglyph(n) if char then local font = id - local attr = getglyphdata(n) or 0 - report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,char) + local dynamic = getglyphdata(n) or 0 + report_fonts("font %03i, dynamic %03i, glyph %C",font,dynamic,char) elseif id == disc_code then report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n)) elseif id == boundary_code then @@ -169,10 +159,10 @@ local function start_trace(head) end end -local function stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant) +local function stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant) report_fonts() report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") - report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none") + report_fonts("dynamics: %s",d > 0 and concat(keys(dynamicfonts)," ") or "none") report_fonts("built-in: %s",b > 0 and b or "none") report_fonts("removed : %s",r > 0 and r or "none") report_fonts() @@ -181,11 +171,11 @@ end do local usedfonts - local attrfonts + local dynamicfonts local basefonts -- could be reused local basefont local prevfont - local prevattr + local prevdynamic local variants local redundant -- could be reused local firstnone @@ -193,7 +183,7 @@ do local lastproc local lastnone - local a, u, b, r + local d, u, b, r local function protectnone() protect_glyphs(firstnone,lastnone) @@ -228,7 +218,7 @@ do end end - local function setnode(n,font,attr) -- we could use prevfont and prevattr when we set then first + local function setnode(n,font,dynamic) -- we could use prevfont and prevdynamic when we set then first if firstnone then protectnone() end @@ -236,17 +226,17 @@ do basefont[2] = getprev(n) basefont = false end - if attr > 0 then - local used = attrfonts[font] + if dynamic > 0 then + local used = dynamicfonts[font] if not used then used = { } - attrfonts[font] = used + dynamicfonts[font] = used end - if not used[attr] then + if not used[dynamic] then local fd = setfontdynamics[font] if fd then - used[attr] = fd[attr] - a = a + 1 + used[dynamic] = fd[dynamic] + d = d + 1 end end else @@ -266,22 +256,22 @@ do -- either next or not, but definitely no already processed list starttiming(nodes) - usedfonts = { } - attrfonts = { } - basefonts = { } - basefont = nil - prevfont = nil - prevattr = 0 - variants = nil - redundant = nil - firstnone = nil - lastfont = nil - lastproc = nil - lastnone = nil + usedfonts = { } + dynamicfonts = { } + basefonts = { } + basefont = nil + prevfont = nil + prevdynamic = 0 + variants = nil + redundant = nil + firstnone = nil + lastfont = nil + lastproc = nil + lastnone = nil -local fontmode = nil + local fontmode = nil -- base none or other - a, u, b, r = 0, 0, 0, 0 + d, u, b, r = 0, 0, 0, 0 if trace_fontrun then start_trace(head) @@ -290,48 +280,31 @@ local fontmode = nil -- There is no gain in checking for a single glyph and then having a fast path. On the -- metafun manual (with some 2500 single char lists) the difference is just noise. - for n, char, font in nextchar, head do - --- local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context --- if font ~= prevfont or attr ~= prevattr then --- prevfont = font --- prevattr = attr --- variants = fontvariants[font] --- local fontmode = fontmodes[font] --- if fontmode == "none" then --- setnone(n) --- elseif fontmode == "base" then --- setbase(n) --- else --- setnode(n,font,attr) --- end --- elseif firstnone then --- lastnone = n --- end + for n, char, font, dynamic in nextchar, head do if font ~= prevfont then prevfont = font fontmode = fontmodes[font] if fontmode == "none" then - prevattr = 0 - variants = false + prevdynamic = 0 + variants = false setnone(n) elseif fontmode == "base" then - prevattr = 0 - variants = false + prevdynamic = 0 + variants = false setbase(n) else - local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context - prevattr = attr - variants = fontvariants[font] - setnode(n,font,attr) + -- local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context + prevdynamic = dynamic + variants = fontvariants[font] + setnode(n,font,dynamic) end elseif fontmode == "node" then - local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context - if attr ~= prevattr then - prevattr = attr - variants = fontvariants[font] - setnode(n,font,attr) + local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context + if dynamic ~= prevdynamic then + prevdynamic = dynamic + variants = fontvariants[font] + setnode(n,font,dynamic) end elseif firstnone then lastnone = n @@ -434,21 +407,21 @@ local fontmode = nil -- basefont is not supported in disc only runs ... it would mean a lot of -- ranges .. we could try to run basemode as a separate processor run but not -- for now (we can consider it when the new node code is tested - for d in nextdisc, head do + for disc in nextdisc, head do -- doing only replace is good enough because pre and post are normally used -- for hyphens and these come from fonts that part of the hyphenated word - local r = getreplace(d) + local r = getreplace(disc) if r then - local prevfont = nil - local prevattr = nil - local none = false - firstnone = nil - basefont = nil - for n, char, font in nextchar, r do - local attr = getglyphdata(n) or 0 -- zero attribute is reserved for fonts in context - if font ~= prevfont or attr ~= prevattr then - prevfont = font - prevattr = attr + local prevfont = nil + local prevdynamic = nil + local none = false + firstnone = nil + basefont = nil + for n, char, font, dynamic in nextchar, r do + -- local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context + if font ~= prevfont or dynamic ~= prevdynamic then + prevfont = font + prevdynamic = dynamic local fontmode = fontmodes[font] if fontmode == "none" then setnone(n) @@ -456,7 +429,7 @@ local fontmode = nil -- so the replace gets an extra treatment ... so be it setbase(n) else - setnode(n,font,attr) + setnode(n,font,dynamic) end elseif firstnone then -- lastnone = n @@ -475,40 +448,37 @@ local fontmode = nil end if trace_fontrun then - stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant) + stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant) end -- in context we always have at least 2 processors if u == 0 then -- skip elseif u == 1 then - local attr = a > 0 and 0 or false -- 0 is the savest way for i=1,#lastproc do - head = lastproc[i](head,lastfont,attr,direction) + head = lastproc[i](head,lastfont,0,direction) end else - -- local attr = a == 0 and false or 0 -- 0 is the savest way - local attr = a > 0 and 0 or false -- 0 is the savest way for font, processors in next, usedfonts do -- unordered for i=1,#processors do - head = processors[i](head,font,attr,direction,u) + head = processors[i](head,font,0,direction,u) -- u triggers disc optimizer end end end - if a == 0 then + if d == 0 then -- skip - elseif a == 1 then - local font, dynamics = next(attrfonts) - for attribute, processors in next, dynamics do -- unordered, attr can switch in between + elseif d == 1 then + local font, dynamics = next(dynamicfonts) + for dynamic, processors in next, dynamics do -- unordered, dynamic can switch in between for i=1,#processors do - head = processors[i](head,font,attribute,direction) + head = processors[i](head,font,dynamic,direction) end end else - for font, dynamics in next, attrfonts do - for attribute, processors in next, dynamics do -- unordered, attr can switch in between + for font, dynamics in next, dynamicfonts do + for dynamic, processors in next, dynamics do -- unordered, dynamic can switch in between for i=1,#processors do - head = processors[i](head,font,attribute,direction,a) + head = processors[i](head,font,dynamic,direction,d) -- d triggers disc optimizer end end end diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt index 7b36d1752..dbd5c7ef2 100644 --- a/tex/context/base/mkxl/node-nut.lmt +++ b/tex/context/base/mkxl/node-nut.lmt @@ -102,7 +102,6 @@ local nuts = { getyscale = direct.getyscale, getxyscales = direct.getxyscales, getorientation = direct.getorientation, - getwhatever = direct.getwhatever, -- experimental hook getoptions = direct.getoptions, getpenalty = direct.getpenalty, getpost = direct.getpost, @@ -236,6 +235,7 @@ local nuts = { write = direct.write, append = direct.append, has_glyph_option = direct.has_glyph_option, + show = direct.show, } nodes.nuts = nuts diff --git a/tex/context/base/mkxl/node-tra.lmt b/tex/context/base/mkxl/node-tra.lmt index f985652c5..da3cb1d33 100644 --- a/tex/context/base/mkxl/node-tra.lmt +++ b/tex/context/base/mkxl/node-tra.lmt @@ -59,6 +59,8 @@ local used_nodes = nuts.usedlist local nextnode = nuts.traversers.node local nextglyph = nuts.traversers.glyph +local shownodes = nuts.show + local d_tostring = nuts.tostring local nutpool = nuts.pool @@ -722,3 +724,16 @@ tracers.rule = nodestracerpool.rule -- for a while -- end -- print("STOP", message or "") -- end + +function nodes.handlers.show(n) + if n then + shownodes(tonut(n)) + else + -- maybe a message + end + return n +end + +trackers.register("fonts.result.show", function(v) + nodes.tasks.setaction("processors","nodes.handlers.show",v) +end) diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml index c7cdcfa74..dc2cc49c3 100644 --- a/tex/context/interface/mkii/keys-en.xml +++ b/tex/context/interface/mkii/keys-en.xml @@ -1137,6 +1137,7 @@ + diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv index 7a9d82c5a..6e4b1773f 100644 --- a/tex/context/modules/mkiv/s-fonts-variable.mkiv +++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv @@ -103,6 +103,12 @@ % \showfontvariations % [font=file:sourcecode-regular.otf] +% \showfontvariations +% [font=file:sourcecodevariable-roman.otf] + +% \showfontvariations +% [font=file:sourcecodevariable-italic.otf] + % \showfontvariations % [font=file:AmstelvarAlpha-VF.ttf] diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 1b6212597..dde25ac75 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2021-01-05 10:41 +-- merge date : 2021-01-07 16:56 do -- begin closure to overcome local limits and interference @@ -14019,7 +14019,7 @@ do local reginit=false local function updateregions(n) if regions then - local current=regions[n] or regions[1] + local current=regions[n+1] or regions[1] nofregions=#current if axis and n~=reginit then factors={} @@ -14588,7 +14588,11 @@ do popped=3 seacs={} if regions then - regions={ regions } + regions={} + local deltas=data.deltas + for i=1,#deltas do + regions[i]=deltas[i].regions + end axis=data.factors or false end end @@ -16573,7 +16577,6 @@ local function readvariationdata(f,storeoffset,factors) end regions[i]=t end - if factors then for i=1,nofdeltadata do setposition(f,storeoffset+deltadata[i]) local nofdeltasets=readushort(f) @@ -16597,7 +16600,6 @@ local function readvariationdata(f,storeoffset,factors) scales=factors and getscales(usedregions,factors) or nil, } end - end setposition(f,position) return regions,deltadata end @@ -20782,7 +20784,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.112 +otf.version=3.113 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) otf.pngcache=containers.define("fonts","png",otf.version,true) -- cgit v1.2.3