diff options
Diffstat (limited to 'tex/context/base/mkxl')
41 files changed, 1350 insertions, 571 deletions
diff --git a/tex/context/base/mkxl/char-tex.lmt b/tex/context/base/mkxl/char-tex.lmt index e5ce1c4ab..02d9a6cb6 100644 --- a/tex/context/base/mkxl/char-tex.lmt +++ b/tex/context/base/mkxl/char-tex.lmt @@ -36,7 +36,6 @@ local is_letter = characters.is_letter local is_command = characters.is_command local is_spacing = characters.is_spacing local is_mark = characters.is_mark -local is_punctuation = characters.is_punctuation local data = characters.data if not data then return end local blocks = characters.blocks diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index f890b8877..48532ede6 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{2022.10.22 11:20} +\newcontextversion{2022.11.14 22:54} %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 9c7a785f8..d111761b0 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{2022.10.22 11:20} +\immutable\edef\contextversion{2022.11.14 22:54} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/font-chk.lmt b/tex/context/base/mkxl/font-chk.lmt index 089e68f9f..05a3611cc 100644 --- a/tex/context/base/mkxl/font-chk.lmt +++ b/tex/context/base/mkxl/font-chk.lmt @@ -379,16 +379,11 @@ local function expandglyph(characters,index,done) if n then d.next = expandglyph(characters,n,done) end - local h = d.hparts - if h then - for i=1,#h do - h[i].glyph = expandglyph(characters,h[i].glyph,done) - end - end - local v = d.vparts - if v then - for i=1,#v do - v[i].glyph = expandglyph(characters,v[i].glyph,done) + local p = d.parts + if p then + for i=1,#p do + local pi = p[i] + pi.glyph = expandglyph(characters,pi.glyph,done) end end return d diff --git a/tex/context/base/mkxl/font-con.lmt b/tex/context/base/mkxl/font-con.lmt index 2e32193e9..daf106a8a 100644 --- a/tex/context/base/mkxl/font-con.lmt +++ b/tex/context/base/mkxl/font-con.lmt @@ -276,6 +276,8 @@ local function scaleparts(parts,delta) return t end +-- getcharactertagvalues + function constructors.scale(tfmdata,specification) local target = { } -- the new table -- @@ -320,20 +322,20 @@ function constructors.scale(tfmdata,specification) -- local mathsize = tonumber(specification.mathsize) or 0 local textsize = tonumber(specification.textsize) or scaledpoints - local forcedsize = tonumber(parameters.mathsize ) or 0 -- can be set by the feature "mathsize" + -- local forcedsize = tonumber(parameters.mathsize ) or 0 -- can be set by the feature "mathsize" local extrafactor = tonumber(specification.factor ) or 1 - if (mathsize == 2 or forcedsize == 2) and parameters.scriptpercentage then - scaledpoints = parameters.scriptpercentage * textsize / 100 - elseif (mathsize == 3 or forcedsize == 3) and parameters.scriptscriptpercentage then - scaledpoints = parameters.scriptscriptpercentage * textsize / 100 - elseif forcedsize > 1000 then -- safeguard - scaledpoints = forcedsize - else - -- in context x and xx also use mathsize - end + -- if (mathsize == 2 or forcedsize == 2) and parameters.scriptpercentage then + -- scaledpoints = parameters.scriptpercentage * textsize / 100 + -- elseif (mathsize == 3 or forcedsize == 3) and parameters.scriptscriptpercentage then + -- scaledpoints = parameters.scriptscriptpercentage * textsize / 100 + -- elseif forcedsize > 1000 then -- safeguard + -- scaledpoints = forcedsize + -- else + -- -- in context x and xx also use mathsize + -- end targetparameters.mathsize = mathsize targetparameters.textsize = textsize - targetparameters.forcedsize = forcedsize + -- targetparameters.forcedsize = forcedsize targetparameters.extrafactor = extrafactor -- local defaultwidth = resources.defaultwidth or 0 @@ -356,6 +358,7 @@ function constructors.scale(tfmdata,specification) -- local askedscaledpoints = scaledpoints local scaledpoints, delta = constructors.calculatescale(tfmdata,scaledpoints,nil,specification) -- no shortcut, dan be redefined +-- print("B",mathsize,askedscaledpoints,scaledpoints,delta) -- local hdelta = delta local vdelta = delta @@ -486,7 +489,7 @@ function constructors.scale(tfmdata,specification) -- local ascender = parameters.ascender if ascender then - targetparameters.ascender = delta * ascender + targetparameters.ascender = delta * ascender end local descender = parameters.descender if descender then @@ -671,6 +674,10 @@ function constructors.scale(tfmdata,specification) if ve then chr.expansion = ve*1000 -- expansionfactor, hm, can happen elsewhere end + local vc = character.compression + if vc then + chr.compression = vc*1000 -- expansionfactor, hm, can happen elsewhere + end local vl = character.leftprotrusion if vl then chr.leftprotrusion = width*vl @@ -682,60 +689,42 @@ function constructors.scale(tfmdata,specification) end -- if hasmath then - -- - -- todo, just operate on descriptions.math local nxt = character.next if nxt then chr.next = nxt end - local vparts = character.vparts - if vparts then - chr.vparts = scaleparts(vparts,vdelta) - end - local hparts = character.hparts - if hparts then - chr.hparts = scaleparts(hparts,hdelta) + local parts = character.parts + if parts then + local orientation = character.partsorientation or "vertical" + chr.parts = scaleparts(parts,orientation == "horizontal" and hdelta or vdelta) + chr.partsorientation = orientation end - local vi = character.vitalic + local vi = character.partsitalic if vi and vi ~= 0 then - chr.vitalic = vi*hdelta + chr.partsitalic = vi*hdelta end --- local va = character.accent --- if va and not chr.topanchor then --- chr.topanchor = va --- end local va = character.topanchor - if va then + if va and va ~= 0 then chr.topanchor = va*vdelta end va = character.bottomanchor - if va then + if va and va ~= 0 then chr.bottomanchor = va*vdelta end - local vo = character.topovershoot - if vo then - chr.topovershoot = vo*hdelta - end - -- vo = character.bottomovershoot - -- if vo then - -- chr.bottomovershoot = vo*hdelta - -- end -- - -- if stackmath then -- not ok yet - local mk = character.mathkerns - if mk then - local tr = mk.topright - local tl = mk.topleft - local br = mk.bottomright - local bl = mk.bottomleft - chr.mathkerns = { - topright = tr and mathkerns(tr,vdelta) or nil, - topleft = tl and mathkerns(tl,vdelta) or nil, - bottomright = br and mathkerns(br,vdelta) or nil, - bottomleft = bl and mathkerns(bl,vdelta) or nil, - } - end - -- end + local mk = character.mathkerns + if mk then + local tr = mk.topright + local tl = mk.topleft + local br = mk.bottomright + local bl = mk.bottomleft + chr.mathkerns = { + topright = tr and mathkerns(tr,vdelta) or nil, + topleft = tl and mathkerns(tl,vdelta) or nil, + bottomright = br and mathkerns(br,vdelta) or nil, + bottomleft = bl and mathkerns(bl,vdelta) or nil, + } + end -- if hasitalics then local vi = character.italic @@ -743,42 +732,46 @@ function constructors.scale(tfmdata,specification) chr.italic = vi*hdelta end end - local vk = character.topleft - if vk and vk ~= 0 then - chr.topleft = vk*hdelta - end - local vk = character.topright - if vk and vk ~= 0 then - chr.topright = vk*hdelta - end - local vk = character.bottomleft - if vk and vk ~= 0 then - chr.bottomleft = vk*hdelta - end - local vk = character.bottomright - if vk and vk ~= 0 then - chr.bottomright = vk*hdelta - end - -- local ft = character.options - -- if ft then - -- chr.options = ft + -- + -- These can never happen here as these come from tweaks but I need to check it: + -- + -- local vo = character.topovershoot + -- if vo and vo ~= 0 then + -- chr.topovershoot = vo*hdelta -- end + -- local il = character.innerlocation + -- if il then + -- chr.innerlocation = il + -- chr.innerxoffset = (character.innerxoffset or 0) * hdelta + -- chr.inneryoffset = (character.inneryoffset or 0) * vdelta + -- end + -- + -- if character.extensible then + -- chr.extensible = true -- stretch fixed width accent + -- end + -- -- + -- local k = character.topleft if k and k ~= 0 then chr.topleft = k*hdelta end + -- local k = character.topright if k and k ~= 0 then chr.topright = k*hdelta end + -- local k = character.bottomleft if k and k ~= 0 then chr.bottomleft = k*hdelta end + -- local k = character.bottomright if k and k ~= 0 then chr.bottomright = k*hdelta end + -- -- + -- local m = character.leftmargin if m and m ~= 0 then chr.leftmargin = m*hdelta end + -- local m = character.rightmargin if m and m ~= 0 then chr.rightmargin = m*hdelta end + -- local m = character.topmargin if m and m ~= 0 then chr.topmargin = m*hdelta end + -- local m = character.bottommargin if m and m ~= 0 then chr.bottommargin = m*hdelta end + -- local sm = character.smaller if sm then chr.smaller = sm end - local mi = character.mirror - if mi then - chr.mirror = mi - end - local fa = character.flataccent + -- local mi = character.mirror + -- if mi then + -- chr.mirror = mi + -- end + local fa = character.flataccent -- set here? if fa then chr.flataccent = fa end - local m = character.leftmargin if m and m ~= 0 then chr.leftmargin = m*hdelta end - local m = character.rightmargin if m and m ~= 0 then chr.rightmargin = m*hdelta end - local m = character.topmargin if m and m ~= 0 then chr.topmargin = m*hdelta end - local m = character.bottommargin if m and m ~= 0 then chr.bottommargin = m*hdelta end elseif autoitalicamount then -- itlc feature local vi = description.italic if not vi then diff --git a/tex/context/base/mkxl/font-ctx.lmt b/tex/context/base/mkxl/font-ctx.lmt index 83c0a912b..23c676e4e 100644 --- a/tex/context/base/mkxl/font-ctx.lmt +++ b/tex/context/base/mkxl/font-ctx.lmt @@ -187,6 +187,12 @@ constructors.noffontsloaded = 0 -- font.getcopy = font.getfont -- we always want the table that context uses +local accuratefactors = false +----- compactfontmode = false + +experiments.register("fonts.accurate", function(v) accuratefactors = v end) +experiments.register("fonts.compact", function() accuratefactors = true end) + do -- Does this still make sense? @@ -1635,8 +1641,11 @@ function constructors.calculatescale(tfmdata,scaledpoints,relativeid,specificati scaledpoints = (- scaledpoints/1000) * (tfmdata.designsize or parameters.designsize) -- already in sp end -- a temp hack till we have upgraded all mechanisms - local delta = round(scaledpoints/units) + local delta = scaledpoints/units local size = round(scaledpoints) + if not accuratefactors then + delta = round(delta) + end texsetcount(c_font_scaled_points,size) -- return size, delta @@ -1662,16 +1671,17 @@ function constructors.hashinstance(specification,force) end specification.size = size if fallbacks then - return hash .. ' @ ' .. size .. ' @ ' .. fallbacks + hash = hash .. ' @ ' .. size .. ' @ ' .. fallbacks else local scalemode = specification.scalemode local special = scalemode and specialscale[scalemode] if special then - return hash .. ' @ ' .. size .. ' @ ' .. special + hash = hash .. ' @ ' .. size .. ' @ ' .. special else - return hash .. ' @ ' .. size + hash = hash .. ' @ ' .. size end end + return hash end -- We overload the (generic) resolver: @@ -2356,7 +2366,7 @@ do end implement { - name = "nbfs", + name = "normalizedbodyfontsize", arguments = "dimen", actions = function(d) context(lpegmatch(stripper,f_strip(d/65536))) diff --git a/tex/context/base/mkxl/font-def.lmt b/tex/context/base/mkxl/font-def.lmt index d71132180..6afeeb474 100644 --- a/tex/context/base/mkxl/font-def.lmt +++ b/tex/context/base/mkxl/font-def.lmt @@ -474,6 +474,7 @@ function definers.read(specification,size,id) -- id can be optional, name can al end specification = definers.resolve(specification) local hash = constructors.hashinstance(specification) +-- inspect(hash) local tfmdata = definers.registered(hash) -- id local name = specification.name if tfmdata then diff --git a/tex/context/base/mkxl/font-imp-quality.lmt b/tex/context/base/mkxl/font-imp-quality.lmt index 93ec1b653..9c57613ee 100644 --- a/tex/context/base/mkxl/font-imp-quality.lmt +++ b/tex/context/base/mkxl/font-imp-quality.lmt @@ -124,6 +124,9 @@ vectors['default'] = { vectors['quality'] = vectors['default'] -- metatable ? +-- Compression is new and used for a math experiment. Musical timestamp(s): November +-- 2022, a cluster of live performances: RPWL (5), PT (7, yes!) and xPropaganda (10). + local function initialize(tfmdata,value) if value then local class, vector = get_class_and_vector(tfmdata,value,"expansions") @@ -159,9 +162,23 @@ local function initialize(tfmdata,value) end end end - if v and v ~= 0 then - chr.expansion = v*factor - else -- can be option + -- So, factor influences all shapes but we now obey zero when set! + if v then + if type(v) == "table" then + local e = v[1] + local c = v[2] or 0 + if e ~= 0 then + chr.expansion = e*factor + end + if c ~= 0 then + chr.compression = c*factor + end + elseif v == 0 then + -- chr.expansion = 0 + else + chr.expansion = v*factor + end + elseif factor ~= 1 then -- test is new chr.expansion = factor end end @@ -194,6 +211,82 @@ implement { actions = function(class,settings) getparameters(classes,class,'preset',settings) end } +-- special version for math 7/11/22 + +classes.math = { + stretch = 2, + shrink = 2, + step = .5, + vector = 'math', + factor = 1, +} + +vectors.math = { + [0x002B] = { 4, 0 }, -- + + [0x2212] = { 4, 0 }, -- - + [0x003C] = { 8, 0 }, -- < + [0x003D] = { 8, 0 }, -- = + [0x003E] = { 8, 0 }, -- > + [0x002F] = { 2, 0 }, -- / + [0x0028] = { 2, 0 }, -- ( + [0x0029] = { 2, 0 }, -- ) + [0x005B] = { 2, 0 }, -- [ + [0x005D] = { 2, 0 }, -- ] +} + +local function initialize(tfmdata,value) + if value then + local class, vector = get_class_and_vector(tfmdata,value,"expansions") + if class then + if vector then + local stretch = class.stretch or 0 + local shrink = class.shrink or 0 + local step = class.step or 0 + local factor = class.factor or 1 + if trace_expansion then + report_expansions("setting class %a, vector %a, factor %a, stretch %a, shrink %a, step %a", + value,class.vector,factor,stretch,shrink,step) + end + tfmdata.parameters.expansion = { + stretch = 10 * stretch, + shrink = 10 * shrink, + step = 10 * step, + factor = factor, + } + local characters = tfmdata.characters + for u, v in next, vector do + local chr = characters[u] + if type(v) == "table" then + local e = v[1] + local c = v[2] or 0 + if e ~= 0 then + chr.expansion = e*factor + end + if c ~= 0 then + chr.compression = c*factor + end + elseif v ~= 0 then + chr.expansion = v*factor + end + end + elseif trace_expansion then + report_expansions("unknown vector %a in class %a",class.vector,value) + end + elseif trace_expansion then + report_expansions("unknown class %a",value) + end + end +end + +registerotffeature { + name = "mathexpansion", + description = "apply hz optimization to math", + initializers = { + base = initialize, + node = initialize, + } +} + -- -- -- -- -- -- -- protrusion -- -- -- -- -- -- diff --git a/tex/context/base/mkxl/font-ini.mklx b/tex/context/base/mkxl/font-ini.mklx index 1fab52386..5e521e263 100644 --- a/tex/context/base/mkxl/font-ini.mklx +++ b/tex/context/base/mkxl/font-ini.mklx @@ -419,11 +419,11 @@ \fi} \def\normalizebodyfontsize_indeed#macro#body% - {\edef#macro{\clf_nbfs\dimexpr#body\relax}% + {\edef#macro{\clf_normalizedbodyfontsize\dimexpr#body\relax}% \gletcsname\??fontnormalizedbody\number\dimexpr#body\endcsname#macro} \permanent\def\thenormalizedbodyfontsize#body% - {\clf_nbfs\dimexpr#body\relax} + {\clf_normalizedbodyfontsize\dimexpr#body\relax} \mutable\edef\normalizedglobalbodyfontsize{\thenormalizedbodyfontsize\bodyfontsize} \mutable\edef\normalizedlocalbodyfontsize {\thenormalizedbodyfontsize\bodyfontsize} @@ -458,12 +458,60 @@ \installcorenamespace{mappedfontsize} -\permanent\tolerant\protected\def\mapfontsize[#from]#spacer[#to]% - {\ifarguments\or\or\defcsname\??mappedfontsize\the\dimexpr#from\relax\endcsname{#to}\fi} +% \permanent\tolerant\protected\def\mapfontsize[#from]#spacer[#to]% +% {\ifarguments\or\or\defcsname\??mappedfontsize\the\dimexpr#from\relax\endcsname{#to}\fi} +% +% \def\font_basics_set_mapped_fontsize#from% +% {\ifcsname\??mappedfontsize\the\dimexpr#from\relax\endcsname +% \lastnamedcs\else#from% +% \fi} + +% will become: mapmathfontsize + +%letcsname\??mappedfontsize\s!text \endcsname\!!plusone +\letcsname\??mappedfontsize\s!script \endcsname\!!plustwo +\letcsname\??mappedfontsize\s!scriptscript\endcsname\!!plusthree + +\permanent\tolerant\protected\def\mapfontsize[#class]#spacer[#from]#spacer[#to]% + {\ifarguments + % ignore + \or + % reset + \letcsname\??mappedfontsize#class:1\endcsname\undefined + \letcsname\??mappedfontsize#class:2\endcsname\undefined + \letcsname\??mappedfontsize#class:3\endcsname\undefined + \or + % unsupported + \or + % set + \defcsname + \??mappedfontsize + #class:% + \begincsname\??mappedfontsize#from\endcsname + \endcsname{#to}% + \fi} + +\permanent\tolerant\protected\def\checkedmapfontsize[#class]#spacer[#from]#spacer[#to]% + {\ifcsname\??mappedfontsize#class:\begincsname\??mappedfontsize#from\endcsname\endcsname + % keep (user) value + \else + \mapfontsize[#class][#from][#to]% + \fi} + +\permanent\tolerant\def\mappedfontsize#class#from% + {\begincsname + \??mappedfontsize + #class:% + \begincsname\??mappedfontsize#from\endcsname + \endcsname} \def\font_basics_set_mapped_fontsize#from% - {\ifcsname\??mappedfontsize\the\dimexpr#from\relax\endcsname - \lastnamedcs\else#from% + {\ifcsname\??mappedfontsize\fontclass:\fontface\endcsname + %\the\dimexpr\lastnamedcs\dimexpr#from\relax\relax + %\the\dimexpr\lastnamedcs\dimexpr\bodyfontsize\relax\relax + \the\dimexpr\lastnamedcs\dimexpr\normalizedbodyfontsize\relax\relax + \else % we could use default + #from% \fi} \installcorenamespace{fontbodyknown} @@ -747,7 +795,7 @@ \d_font_scaled_font_size\v_font_size_absolute\relax \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size % uses \somefontsize set by lua \or - % mo + % mo % mapped font size will go away \d_font_scaled_font_size\font_basics_set_mapped_fontsize\v_font_size_absolute \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size \or @@ -1328,13 +1376,14 @@ \ifcsname\??fontenvironments \normalizedbodyfontsize#parameter\endcsname\lastnamedcs\orelse \ifcsname\??fontenvironments\s!default #parameter\endcsname\lastnamedcs\fi} -% \permanent\def\bodyfontsizevariable#size#parameter% -% {\begincsname\??fontenvironments -% \ifcsname\??fontenvironments\fontclass#size#parameter\endcsname\fontclass#size#parameter\orelse -% \ifcsname\??fontenvironments\fontclass #parameter\endcsname\fontclass #parameter\orelse -% \ifcsname\??fontenvironments #size#parameter\endcsname #size#parameter\orelse -% \ifcsname\??fontenvironments\s!default #parameter\endcsname\s!default #parameter\fi -% \endcsname} +\permanent\def\bodyfontsizevariable#size#parameter% used in s-fonts-show + {\begincsname\??fontenvironments + \ifcsname\??fontenvironments\fontclass#size#parameter\endcsname\fontclass#size#parameter\orelse + \ifcsname\??fontenvironments\fontclass #parameter\endcsname\fontclass #parameter\orelse + \ifcsname\??fontenvironments\v!all #size#parameter\endcsname\v!all #size#parameter\orelse + \ifcsname\??fontenvironments #size#parameter\endcsname #size#parameter\orelse + \ifcsname\??fontenvironments\s!default #parameter\endcsname\s!default #parameter\fi + \endcsname} \def\font_bodyfontvariable#parameter% {\ifcsname\??fontenvironments\fontclass\normalizedbodyfontsize#parameter\endcsname\lastnamedcs\orelse @@ -1669,6 +1718,8 @@ %D Here the rest concerns rl or lr so in this case it is not a size specifier but %D a directional one. +%D no need for the: one two rest + \protected\def\font_basics_define_body_font_nop_mm[#one#two#rest=#value]% local {%\ifcsname\s!mm\endcsname\else\font_basics_check_fontname_combination\s!mm{#one#two}{#rest}\fi \letcsname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined @@ -2366,6 +2417,8 @@ %D math families and finally we activate the default typeface and also set the font %D specific parameters assigned to \type {\everybodyfont}. +% todo: per class + \permanent\protected\def\textface {\currentbodyfontdimension\s!text } \permanent\protected\def\scriptface {\currentbodyfontdimension\s!script } \permanent\protected\def\scriptscriptface{\currentbodyfontdimension\s!scriptscript} diff --git a/tex/context/base/mkxl/font-lib.mklx b/tex/context/base/mkxl/font-lib.mklx index 05367dae8..bb0eec7e6 100644 --- a/tex/context/base/mkxl/font-lib.mklx +++ b/tex/context/base/mkxl/font-lib.mklx @@ -97,8 +97,6 @@ \registerctxluafile{node-fnt}{autosuffix} % here -\registerctxluafile{font-mps}{autosuffix} % outline fun - \registerctxluafile{font-lua}{} \registerctxluafile{font-enh}{autosuffix} diff --git a/tex/context/base/mkxl/font-mat.mklx b/tex/context/base/mkxl/font-mat.mklx index 868f44198..d9337d1b0 100644 --- a/tex/context/base/mkxl/font-mat.mklx +++ b/tex/context/base/mkxl/font-mat.mklx @@ -124,23 +124,26 @@ \mutable\let\fontfamily\relax % for now public but it is a helper -\newconditional\c_math_last_family_set +%newconditional\c_math_last_family_set +\newcount \c_math_last_family_used \def\font_helpers_set_math_family_indeed_normal#mrtag#family% \fontface etc are also used later on {\let\savedfontbody\fontbody \let\fontfamily#family% - \settrue\c_math_last_family_set +% \settrue\c_math_last_family_set +\c_math_last_family_used\zerocount % the order is important as we depend on known id's when completing fonts - % enabling is needed when we have fallbacks which spoils the families + % enabling is needed when we have fallbacks which spoils the families; per + % mid 2022 this is no longer true as we do fallbacks differently \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusthree \font_helpers_set_math_family_a\scriptscriptfont#mrtag\font % defines - \font_helpers_set_math_family_a\scriptscriptfont#mrtag\font % enables + \font_helpers_set_math_family_a\scriptscriptfont#mrtag\font % enables / still needed ? \let\mathsizesuffix\mathscriptsuffix \let\fontface\!!plustwo \font_helpers_set_math_family_a\scriptfont #mrtag\font % defines - \font_helpers_set_math_family_a\scriptfont #mrtag\font % enables + \font_helpers_set_math_family_a\scriptfont #mrtag\font % enables / still needed ? \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusone \font_helpers_set_math_family_a\textfont #mrtag\font % defines - \font_helpers_set_math_family_a\textfont #mrtag\font % enables + \font_helpers_set_math_family_a\textfont #mrtag\font % enables / still needed ? \let\mathsizesuffix\empty \let\fontface\!!zerocount \let\fontbody\savedfontbody \setfalse\c_font_auto_size} @@ -160,13 +163,14 @@ \def\font_helpers_set_math_family_indeed_compact#mrtag#family% \fontface etc are also used later on {\let\savedfontbody\fontbody \let\fontfamily#family% - \settrue\c_math_last_family_set +% \settrue\c_math_last_family_set +\c_math_last_family_used\zerocount \font_helpers_set_math_family_set_scales_compact % the order is important as we depend on known id's when completing fonts % enabling is needed when we have fallbacks which spoils the families \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusone \font_helpers_set_math_family_a\textfont #mrtag\font % defines - \font_helpers_set_math_family_a\textfont #mrtag\font % enables + \font_helpers_set_math_family_a\textfont #mrtag\font % enables / still needed ? \scriptfont #mrtag\font % reuses \scriptscriptfont#mrtag\font % reuses \let\mathsizesuffix\empty \let\fontface\!!zerocount @@ -185,17 +189,18 @@ \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one \let\savedfontbody\fontbody \let\fontfamily#familytag% - \settrue\c_math_last_family_set +% \settrue\c_math_last_family_set +\c_math_last_family_used\zerocount \font_helpers_set_math_family_set_scales_normal \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusthree \font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% defines - \font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% enables + \font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% enables / still needed ? \let\mathsizesuffix\mathscriptsuffix \let\fontface\!!plustwo \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam% defines - \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam% enables + \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam% enables / still needed ? \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusone \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% defines - \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% enables + \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% enables / still needed ? \let\mathsizesuffix\empty \let\fontface\!!zerocount \let\fontbody\savedfontbody \let\defaultfontclass\savedfontclass @@ -206,10 +211,11 @@ \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one \let\savedfontbody\fontbody \let\fontfamily#familytag% - \settrue\c_math_last_family_set +% \settrue\c_math_last_family_set +\c_math_last_family_used\zerocount \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusone \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% defines - \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% enables +% \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% enables / still needed ? \scriptfont #mbfam\textfont#mbfam% reuses \scriptscriptfont#mbfam\textfont#mbfam% reuses \let\mathsizesuffix\empty \let\fontface\!!zerocount @@ -474,8 +480,18 @@ \mutable\let\bigmathfontsize\empty +% \permanent\protected\def\synchronizebigmath +% {\ifx\bigmathfontsize\fontsize +% % already in sync +% \else +% \let\bigmathfontsize\fontsize +% \font_helpers_synchronize_math +% \fi} + \permanent\protected\def\synchronizebigmath - {\ifx\bigmathfontsize\fontsize + {\ifconditional\c_font_compact + % no need + \orelse\ifx\bigmathfontsize\fontsize % already in sync \else \let\bigmathfontsize\fontsize @@ -501,14 +517,26 @@ %D This is nasty, as the engine only stores the last set family parameters (per style) which %D in our case can be bold. +% \def\font_helpers_synchronize_math_parameters +% {\textfont \zerocount\textfont \zerocount +% \scriptfont \zerocount\scriptfont \zerocount +% \scriptscriptfont\zerocount\scriptscriptfont\zerocount +% \setfalse\c_math_last_family_set} +% +% \appendtoks +% \ifconditional\c_math_last_family_set +% \font_helpers_synchronize_math_parameters +% \fi +% \to\everybodyfont + \def\font_helpers_synchronize_math_parameters - {\textfont \zerocount\textfont \zerocount + {\c_math_last_family_used\mathstylefontid\textstyle\zerocount + \textfont \zerocount\textfont \zerocount \scriptfont \zerocount\scriptfont \zerocount - \scriptscriptfont\zerocount\scriptscriptfont\zerocount - \setfalse\c_math_last_family_set} + \scriptscriptfont\zerocount\scriptscriptfont\zerocount} \appendtoks - \ifconditional\c_math_last_family_set + \ifnum\c_math_last_family_used=\mathstylefontid\textstyle\zerocount\else \font_helpers_synchronize_math_parameters \fi \to\everybodyfont diff --git a/tex/context/base/mkxl/font-otl.lmt b/tex/context/base/mkxl/font-otl.lmt index b7889fc05..2d0d58a97 100644 --- a/tex/context/base/mkxl/font-otl.lmt +++ b/tex/context/base/mkxl/font-otl.lmt @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.121 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.130 -- 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) @@ -384,46 +384,33 @@ local function copytotfm(data,cache_id) local m = d.math if m then -- - local italic = m.italic - local vitalic = m.vitalic - -- - local variants = m.hvariants - local parts = m.hparts - if variants then - local c = character - for i=1,#variants do - -- local un = variants[i].glyph - local un = variants[i] - c.next = un - c = characters[un] - end -- c is now last in chain - c.hparts = parts - elseif parts then - character.hparts = parts - italic = m.hitalic + local italic = m.italic + if italic and italic ~= 0 then + character.italic = italic end -- - local variants = m.vvariants - local parts = m.vparts + local variants = m.variants + local parts = m.parts + local partsitalic = m.partsitalic + local partsorientation = m.partsorientation if variants then local c = character for i=1,#variants do - -- local un = variants[i].glyph local un = variants[i] c.next = un c = characters[un] end -- c is now last in chain - c.vparts = parts + c.parts = parts + c.partsorientation = partsorientation + if partsitalic and partsitalic ~= 0 then + c.partsitalic = partsitalic + end elseif parts then - character.vparts = parts - end - -- - if italic and italic ~= 0 then - character.italic = italic - end - -- - if vitalic and vitalic ~= 0 then - character.vitalic = vitalic + character.parts = parts + character.partsorientation = partsorientation + if partsitalic and partsitalic ~= 0 then + character.partsitalic = partsitalic + end end -- local topanchor = m.topanchor or m.accent -- for now @@ -678,25 +665,26 @@ local function read_from_otf(specification) return tfmdata end -local function checkmathsize(tfmdata,mathsize) - local mathdata = tfmdata.shared.rawdata.metadata.math - local mathsize = tonumber(mathsize) - if mathdata then -- we cannot use mathparameters as luatex will complain - local parameters = tfmdata.parameters - parameters.scriptpercentage = mathdata.ScriptPercentScaleDown - parameters.scriptscriptpercentage = mathdata.ScriptScriptPercentScaleDown - parameters.mathsize = mathsize -- only when a number ! - end -end - -registerotffeature { - name = "mathsize", - description = "apply mathsize specified in the font", - initializers = { - base = checkmathsize, - node = checkmathsize, - } -} +-- local function checkmathsize(tfmdata,mathsize) +-- local mathdata = tfmdata.shared.rawdata.metadata.math +-- local mathsize = tonumber(mathsize) +-- if mathdata then -- we cannot use mathparameters as luatex will complain +-- local parameters = tfmdata.parameters +-- parameters.scriptpercentage = mathdata.ScriptPercentScaleDown +-- parameters.scriptscriptpercentage = mathdata.ScriptScriptPercentScaleDown +-- parameters.mathsize = mathsize -- only when a number ! +-- -- print(mathdata.ScriptPercentScaleDown,mathdata.ScriptScriptPercentScaleDown) +-- end +-- end +-- +-- registerotffeature { +-- name = "mathsize", +-- description = "apply mathsize specified in the font", +-- initializers = { +-- base = checkmathsize, +-- node = checkmathsize, +-- } +-- } -- readers diff --git a/tex/context/base/mkxl/font-pre.mkxl b/tex/context/base/mkxl/font-pre.mkxl index 4a7442d10..2918a7e8c 100644 --- a/tex/context/base/mkxl/font-pre.mkxl +++ b/tex/context/base/mkxl/font-pre.mkxl @@ -412,6 +412,7 @@ [mode=base, % mode=none, % better, maybe do this last kern=yes, +% kern=force, % flac=yes, % handled differently % liga=yes, % makes no sense % mode=node, @@ -424,6 +425,7 @@ compactmath=yes, flattenaccents=yes, % mathgaps=yes, + mathexpansion=math, language=dflt, script=math] @@ -439,32 +441,32 @@ % \definefontfeature[mathextra][collapseitalics] -\definefontfeature - [mathematics-l2r] - [mathematics] - [] +% \definefontfeature % obsolete +% [mathematics-l2r] +% [mathematics] +% [] -\definefontfeature - [mathematics-r2l] - [mathematics] - [rtlm=yes, - locl=yes] +% \definefontfeature % obsolete +% [mathematics-r2l] +% [mathematics] +% [rtlm=yes, +% locl=yes] -\definefontfeature[virtualmath] [mathematics] -\definefontfeature[virtualmath-l2r] [mathematics-l2r] -\definefontfeature[virtualmath-r2l] [mathematics-r2l] +\definefontfeature[virtualmath] [mathematics] +% \definefontfeature[virtualmath-l2r] [mathematics-l2r] % obsolete +% \definefontfeature[virtualmath-r2l] [mathematics-r2l] % obsolete -\definefontfeature[math-text] [mathematics] [ssty=no] -\definefontfeature[math-script] [mathematics] [ssty=1,mathsize=yes] -\definefontfeature[math-scriptscript] [mathematics] [ssty=2,mathsize=yes] +\definefontfeature[math-text] [mathematics] % [ssty=no] +\definefontfeature[math-script] [mathematics] [ssty=1,mathsize=yes] +\definefontfeature[math-scriptscript] [mathematics] [ssty=2,mathsize=yes] -\definefontfeature[math-text-l2r] [mathematics-l2r] [ssty=no] -\definefontfeature[math-script-l2r] [mathematics-l2r] [ssty=1,mathsize=yes] -\definefontfeature[math-scriptscript-l2r] [mathematics-l2r] [ssty=2,mathsize=yes] +% \definefontfeature[math-text-l2r] [mathematics-l2r] [ssty=no] % obsolete +% \definefontfeature[math-script-l2r] [mathematics-l2r] [ssty=1,mathsize=yes] % obsolete +% \definefontfeature[math-scriptscript-l2r] [mathematics-l2r] [ssty=2,mathsize=yes] % obsolete -\definefontfeature[math-text-r2l] [mathematics-r2l] [ssty=no] -\definefontfeature[math-script-r2l] [mathematics-r2l] [ssty=1,mathsize=yes] -\definefontfeature[math-scriptscript-r2l] [mathematics-r2l] [ssty=2,mathsize=yes] +% \definefontfeature[math-text-r2l] [mathematics-r2l] [ssty=no] % obsolete +% \definefontfeature[math-script-r2l] [mathematics-r2l] [ssty=1,mathsize=yes] % obsolete +% \definefontfeature[math-scriptscript-r2l] [mathematics-r2l] [ssty=2,mathsize=yes] % obsolete % this will go away: could be a mode in the engine % diff --git a/tex/context/base/mkxl/font-set.mklx b/tex/context/base/mkxl/font-set.mklx index 98e2e96e1..631c4af05 100644 --- a/tex/context/base/mkxl/font-set.mklx +++ b/tex/context/base/mkxl/font-set.mklx @@ -43,10 +43,14 @@ % \clf_resetnullfont % in luatex 0.70 this will also do the previous % \glet\font_preloads_reset_nullfont\relax} +% \def\font_preload_check_mode +% {\doifelsemode{lmmath} +% {\def\m_font_fallback_name{modern-designsize-virtual}}% this will stay +% {\def\m_font_fallback_name{modern-designsize}}% % this might become 'modern' +% \glet\font_preload_check_mode\relax} + \def\font_preload_check_mode - {\doifelsemode{lmmath} - {\def\m_font_fallback_name{modern-designsize-virtual}}% this will stay - {\def\m_font_fallback_name{modern-designsize}}% % this might become 'modern' + {\def\m_font_fallback_name{modern}% \glet\font_preload_check_mode\relax} \def\font_preload_default_fonts diff --git a/tex/context/base/mkxl/lang-def.mkxl b/tex/context/base/mkxl/lang-def.mkxl index 2be05104f..cd5fd4ba3 100644 --- a/tex/context/base/mkxl/lang-def.mkxl +++ b/tex/context/base/mkxl/lang-def.mkxl @@ -284,6 +284,23 @@ \c!leftquotation=\rightguillemot, \c!rightquotation=\leftguillemot, \c!date={\v!day,{.},\space,\v!month,\space,\v!year}] + +\installlanguage + [\s!hy] + [\c!spacing=\v!packed, + \c!leftsentence=\endash, % *sentences not confirmed + \c!rightsentence=\endash, + \c!leftsubsentence=\endash, + \c!rightsubsentence=\endash, + \c!leftquote=\guilsingleleft, + \c!rightquote=\guilsingleright, + \c!leftquotation=\leftguillemot + \c!rightquotation=\rightguillemot + \c!date={\v!day,\space,\v!month,\space,\v!year}, % word + % \c!date={\v!day,{.},\v!month,{.},\v!year}, % numbers + \s!patterns=\s!hy, + \s!lefthyphenmin=2, + \s!righthyphenmin=2] \installlanguage [\s!polish] [\s!pl] \installlanguage [\s!czech] [\s!cs] @@ -292,6 +309,10 @@ \installlanguage [\s!slovenian] [\s!sl] \installlanguage [slovene] [\s!sl] % both possible (mojca: still needed?) \installlanguage [\s!albanian] [\s!sq] +\installlanguage [\s!armenian] [\s!hy] + +\installlanguage [\s!hye] [\s!hy] % Eastern Armenian +\installlanguage [\s!hyw] [\s!hy] % Western Armenian % Cyrillic Languages diff --git a/tex/context/base/mkxl/lang-rep.lmt b/tex/context/base/mkxl/lang-rep.lmt index 6139a03f7..fcaff523a 100644 --- a/tex/context/base/mkxl/lang-rep.lmt +++ b/tex/context/base/mkxl/lang-rep.lmt @@ -181,7 +181,7 @@ local function tonodes(list,template) return head end -local is_punctuation = characters.is_punctuation +local ispunctuation = characters.is_punctuation -- We can try to be clever and use the fact that there is no match to skip -- over to the next word but it is gives fuzzy code so for now I removed @@ -326,7 +326,7 @@ function replacements.handler(head) tree = trees[a] if tree then local char = getchar(current) - local punc = is_punctuation[char] + local punc = ispunctuation[char] if mode == "punc" then if not punc then if root then diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt index d937e3dea..57f5b6037 100644 --- a/tex/context/base/mkxl/lpdf-lmt.lmt +++ b/tex/context/base/mkxl/lpdf-lmt.lmt @@ -238,7 +238,7 @@ lpdf.usedindices = usedindices -- [streamhash][index] -> realindex (can local horizontalmode = true local scalefactor = 1 local threshold = 655360 -local thresfactor = 100 +----- thresfactor = 100 local tjfactor = 100 / 65536 function flushers.updatefontstate(font) @@ -690,7 +690,7 @@ do local trace_threshold = false trackers.register("backends.pdf.threshold", function(v) trace_threshold = v end) - -- local f_skip = formatters["%.2N"] + ----- f_skip = formatters["%.2N"] -- I will redo this mess ... we no longer have the mkiv pdf generator that we used in -- luatex (a precursor to lmtx and also for comparison) but only in lmtx now so ... @@ -776,7 +776,7 @@ do move = calc_pdfpos(pos_h,pos_v) end if move then - local d = tj_delta * scalefactor / f_x_scale + local d = tj_delta * scalefactor / (tmef * f_x_scale) if d <= -0.5 or d >= 0.5 then if mode == "char" then end_charmode() @@ -1504,8 +1504,19 @@ local flushimage do local dim_h = size_h * bpfactor local dim_v = size_v * bpfactor local rule - - if dim_v <= one_bp then + -- + -- this fails for showglyphs so and i have no reason to look into it now and rectangles + -- do a better job anyway + -- + if subtype == outlinerule_code then + local linewidth = getdata(current) + pdf_set_pos_temp(pos_h,pos_v) + if linewidth > 0 then + rule = f_w(linewidth * bpfactor,dim_h,dim_v) + else + rule = f_o(dim_h,dim_v) + end + elseif dim_v <= one_bp then pdf_set_pos_temp(pos_h,pos_v + 0.5 * size_v) rule = f_v(dim_v,dim_h) elseif dim_h <= one_bp then @@ -1513,16 +1524,7 @@ local flushimage do rule = f_h(dim_h,dim_v) else pdf_set_pos_temp(pos_h,pos_v) - if subtype == outlinerule_code then - local linewidth = getdata(current) - if linewidth > 0 then - rule = f_w(linewidth * bpfactor,dim_h,dim_v) - else - rule = f_o(dim_h,dim_v) - end - else - rule = f_f(dim_h,dim_v) - end + rule = f_f(dim_h,dim_v) end b = b + 1 ; buffer[b] = rule diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt index 713635583..c18dcda29 100644 --- a/tex/context/base/mkxl/math-act.lmt +++ b/tex/context/base/mkxl/math-act.lmt @@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['math-act'] = { -- have been removed (no longer viable) but can be found in the .lua variant. local type, next, tonumber = type, next, tonumber -local fastcopy, copytable, insert, remove = table.fastcopy, table.copy, table.insert, table.remove +local fastcopy, copytable, insert, remove, concat = table.fastcopy, table.copy, table.insert, table.remove, table.concat local formatters = string.formatters local byte = string.byte local setmetatableindex, sortedkeys, sortedhash = table.setmetatableindex, table.sortedkeys, table.sortedhash @@ -24,6 +24,7 @@ local report_math = logs.reporter("mathematics","initializing") local report_mathtweak = logs.reporter("mathematics","tweak") local getfontoffamily = tex.getfontoffamily +local texget = tex.get local fontcharacters = fonts.hashes.characters local chardata = characters.data local extensibles = mathematics.extensibles @@ -245,8 +246,22 @@ end -- a couple of predefined tweaks: -local mathtweaks = { } -mathematics.tweaks = mathtweaks +local datasets = { } +local mathtweaks = { datasets = datasets } +mathematics.tweaks = mathtweaks + +-- can be a common helper: + +local f_u = formatters["%U"] + +local function unicodecharlist(t) + local r = { } + local n = 0 + for u in sortedhash(t) do + n = n + 1 ; r[n] = f_u(u) + end + return concat(r," ") +end local function report_tweak(fmt,target,original,...) if fmt then @@ -269,6 +284,16 @@ local function report_tweak(fmt,target,original,...) end end +local function feedback_tweak(tweak,target,original,done) + if not done or (type(done) == "table" and not next(done)) then +if trace_tweaking then -- for now + report_tweak("no need for %a",target,original,tweak) +end + elseif trace_tweaking then + report_tweak("tweak %a applied to: %s",target,original,tweak,unicodecharlist(done)) + end +end + mathtweaks.subsets = { acenorsuvxz = { 0x1D44E, 0x1D450, 0x1D452, 0x1D45B, 0x1D45C, 0x1D45F, 0x1D460, 0x1D462, 0x1D463, 0x1D465, 0x1D467 }, bhklt = { 0x1D44F, 0x1D455, 0x1D458, 0x1D459, 0x1D461 }, @@ -341,7 +366,7 @@ local detail do c = characters[nxt] nxt = c.next end - c = c.hparts or c.vparts + c = c.parts if c then local index = t[3] if index == "*" then @@ -414,6 +439,12 @@ do t = type(v) end if t == "table" and next(v) then + + local axis = tonumber(v.axis) + if axis then + axis = target.mathparameters.AxisHeight * axis + end + local factor = v.factor if factor then local m = v @@ -490,6 +521,13 @@ do if yoffsetfactor then character.yoffset = yoffsetfactor * total end + + if axis then + character.height = (character.height or 0) - axis + character.depth = (character.depth or 0) + axis + character.yoffset = (character.yoffset or 0) + axis + end + if italicfactor then if italic then character.italic = italicfactor * italic @@ -533,7 +571,7 @@ do if nxt then adapt(list,target,original,targetcharacters,originalcharacters,nxt,v,compact,n) else - local parts = character.hparts + local parts = character.parts if parts then for i=1,#parts do adapt(list,target,original,targetcharacters,originalcharacters,parts[i],v,compact,n) @@ -621,25 +659,24 @@ do -- local originalcharacters = original.characters local count = 0 -- local also = getalso(target,original) - -- local done = { } + local done = false for k, v in sortedhash(list) do local ori = targetcharacters[k] local nxt = ori.next local cnt = v if nxt then - local hpt, vpt + local prt = nil local lst = { } while nxt do local chr = targetcharacters[nxt] lst[#lst+1] = chr nxt = chr.next if not nxt then - hpt = chr.hparts - vpt = chr.vparts + prt = chr.parts break end end - if hpt or vpt then + if prt then count = count + 1 if cnt ~= "*" then if #lst < cnt then @@ -647,15 +684,18 @@ do end ori = lst[cnt] end - ori.hparts = hpt - ori.vparts = vpt - -- ori.next = nil -- so we keep the chain + ori.parts = prt + end + if not trace_tweaking then + done = true + elseif done then + done[k] = true + else + done = { [k] = true } end end end - if trace_tweaking and count > 0 then - report_tweak("%i variants wiped",target,original,count) - end + feedback_tweak("wipevariants",target,original,done) end end @@ -663,7 +703,7 @@ end do - function mathtweaks.replacements(target,original,parameters) + function mathtweaks.replace(target,original,parameters) local list = parameters.list if list then local targetcharacters = target.characters @@ -687,7 +727,7 @@ do end end - function mathtweaks.substitutes(target,original,parameters) + function mathtweaks.substitute(target,original,parameters) local list = parameters.list if list then local targetcharacters = target.characters @@ -707,9 +747,6 @@ do end end - mathtweaks.replace = mathtweaks.replacements - mathtweaks.substitute = mathtweaks.substitutes - end do @@ -721,7 +758,7 @@ do if list then local targetcharacters = target.characters local originalcharacters = original.characters - local count = 0 + local done = false local function add(v,n) local chardata = targetcharacters[mathgaps[n] or n] @@ -735,7 +772,13 @@ do local t = mathgaps[nn] or nn if t then kerns[t] = vv * width - count = count + 1 + if not trace_tweaking then + done = true + elseif done then + done[t] = true + else + done = { [t] = true } + end end end) end @@ -768,9 +811,7 @@ do -- end -- end - if trace_tweaking and count > 0 then - report_tweak("%i kern pairs",target,original,count) - end + feedback_tweak("kernpairs",target,original,done) end end @@ -1038,65 +1079,67 @@ do end -do - - function mathtweaks.fixanchors(target,original,parameters) - local targetcharacters= target.characters - local factor = tonumber(parameters.factor) or 0 - if factor ~= 0 then - local count = 0 - for k, v in next, targetcharacters do - local a = v.topanchor - if a and a > 0 then - v.topanchor = a * factor - count = count + 1 - end - end - if trace_tweaking and count > 0 then - report_tweak("%i top anchors fixed",target,original,count) - end - end - end - - mathtweaks.fixaccents = mathtweaks.fixanchors - -end - -do - - -- actually this should be a an engine feature driven by category because we don't - -- want this in display mode .. only a test for MS and HH +-- do +-- +-- function mathtweaks.fixanchors(target,original,parameters) +-- local targetcharacters= target.characters +-- local factor = tonumber(parameters.factor) or 0 +-- if factor ~= 0 then +-- local done = false +-- for k, v in next, targetcharacters do +-- local a = v.topanchor +-- if a and a > 0 then +-- v.topanchor = a * factor +-- count = count + 1 +-- if not trace_tweaking then +-- done = true +-- elseif done then +-- done[u] = true +-- else +-- done = { [u] = true } +-- end +-- end +-- end +-- end +-- feedback_tweak("fixanchors",target,original,done) +-- end +-- +-- end +-- do +-- +-- -- actually this should be a an engine feature driven by category because we don't +-- -- want this in display mode .. only a test for MS and HH +-- -- local issymbol = characters.is_symbol -- -- function mathtweaks.oldstylemath(target,original,parameters) --- local chardata = characters.data +-- local chardata = characters.data -- local characters = target.characters -- local axis = target.mathparameters.AxisHeight -- local delta = (parameters.factor or .1) * axis -- target.mathparameters.AxisHeight = (axis - delta) -- for k, v in sortedhash(characters) do -- if issymbol[k] then -- quick hack, engine knows --- print("old style math",k,chardata[k].description) -- v.yoffset = -delta -- v.height = (v.height or 0) - delta -- v.depth = (v.depth or 0) - delta -- end -- end -- end - - function mathtweaks.oldstylemath(target,original,parameters) - -- not relevant - end - -end +-- +-- function mathtweaks.oldstylemath(target,original,parameters) +-- -- not relevant +-- end +-- +-- end do function mathtweaks.simplifykerns(target,original,parameters) local characters = target.characters - local simplified = 0 - for k, v in sortedhash(characters) do + local done = false + for u, v in sortedhash(characters) do local mathkerns = v.mathkerns if mathkerns then local k = mathkerns.topleft @@ -1128,25 +1171,28 @@ do end end v.mathkerns = nil - simplified = simplified + 1 + if not trace_tweaking then + done = true + elseif done then + done[u] = true + else + done = { [u] = true } + end end end - if simplified == 0 then - report_tweak("no need to simplify mathkerns",target,original) - elseif trace_tweaking then - report_tweak("%i mathkerns simplified",target,original,simplified) - end + feedback_tweak("simplifykerns",target,original,done) end end do - local function wipe(target,original,parameters,field,move,integrals) + local function wipe(whatever,target,original,parameters,field,move,integrals) local targetcharacters = target.characters local targetdescriptions = target.descriptions local factor = target.parameters.factor local correct = parameters.correct + local done = false local function getllx(u) local d = targetdescriptions[u] if d then @@ -1172,7 +1218,7 @@ do goto smaller end else - local done = false + local okay = false local italic = c.italic if move and not c.advance then -- advance check prevents double move local width = c.width or 0 @@ -1187,39 +1233,41 @@ do if topanchor then c.topanchor = topanchor + llx end - c.bottomleft = (c.bottomleft or 0) - llx - c.topleft = (c.topleft or 0) - llx - done = true + -- too bad (schola e^x): + -- c.bottomleft = (c.bottomleft or 0) - llx + -- c.topleft = (c.topleft or 0) - llx + okay = true end end if italic and italic ~= 0 then c.width = width + italic c.bottomright = - italic - done = true + okay = true else c.width = width end end if italic then c.italic = nil - done = true + okay = true end - if not done then - goto smaller - end - end - if trace_tweaking then - if l then - report_tweak("%s %a in range %a from %C","removing",target,original,field,l,s) + if okay then + if not trace_tweaking then + done = true + elseif done then + done[u] = true + else + done = { [u] = true } + end else - report_tweak("%s %a from %C","removing",target,original,field,s) + goto smaller end end goto smaller ::smaller:: s = c.smaller ::variants:: - -- no italics here anyway butr we could check them some day + -- no italics here anyway but we could check them some day else break end @@ -1262,22 +1310,21 @@ do end end end + feedback_tweak(whatever,target,original,done) end function mathtweaks.wipeanchors(target,original,parameters) - wipe(target,original,parameters,"topanchor") + wipe("wipeanchors",target,original,parameters,"topanchor") end - mathtweaks.wipeaccents = mathtweaks.wipeanchors - function mathtweaks.wipeitalics(target,original,parameters) if not checkitalics then - wipe(target,original,parameters,"italic") + wipe("wipeitalics",target,original,parameters,"italic") end end function mathtweaks.moveitalics(target,original,parameters) - wipe(target,original,parameters,"italic",true) + wipe("moveitalics",target,original,parameters,"italic",true) end -- function mathtweaks.fixdigits(target,original,parameters) @@ -1292,7 +1339,8 @@ do local characters = target.characters local list = parameters.list if list then - for k, v in sortedhash(list) do + local done = false + for u, v in sortedhash(list) do local c = characters[k] if c then local w = c.width @@ -1301,15 +1349,20 @@ do if trace_tweaking then -- todo end + if not trace_tweaking then + done = true + elseif done then + done[u] = true + else + done = { [u] = true } + end end end end - -- todo: small + feedback_tweak("topanchors",target,original,done) end end - mathtweaks.topaccents = mathtweaks.topanchors - function mathtweaks.movelimits(target,original,parameters) local characters = target.characters local list = parameters.list @@ -1346,6 +1399,27 @@ do if n then relocate(n,factor) end + -- Kind of tricky: we configure the engine to use the vitalic + -- so when we tweak we need to set that to zero. + local parts = c.parts + local italic = c.partsitalic + if parts and italic then + if italic ~= 0 then + local tchar = characters[parts[#parts].glyph] + local bchar = characters[parts[1].glyph] + local width = tchar.width or 0 + local half = (italic/2) * factor + tchar.topanchor = width + half + bchar.bottomanchor = width - half + bchar.bottomright = - italic + if trace_tweaking then + -- todo + end + tchar.italic = nil + bchar.italic = nil + end + c.vitalic = nil + end if also then local a = also[u] if a then @@ -1365,9 +1439,7 @@ do relocate(k,tonumber(v) or factor) end end - if not next(done) then - report_tweak("no need to move limits",target,original) - end + feedback_tweak("movelimits",target,original,done) end end @@ -1544,6 +1616,8 @@ do }, } + datasets.accentdimensions = candidates + local function adapt(c,factor,baseheight,basedepth) -- if not c.tweaked then local height = c.height or 0 @@ -1593,7 +1667,7 @@ do nv = nv + 1 nc = c.next if not nc then - local hv = c.hparts + local hv = c.parts if hv then for i=1,#hv do local c = characters[hv[i].glyph] @@ -1656,7 +1730,7 @@ do -- depth = 0, -- unicode = 0x203E, -- commands = { { "rule", height, width } }, - -- hparts = { + -- parts = { -- { advance = width, ["end"] = step, glyph = 0x203E, start = 0 }, -- { advance = width, ["end"] = 0, glyph = 0x203E, start = step, extender = 1 }, -- } @@ -1668,7 +1742,7 @@ do -- yoffset = -depth, -- unicode = 0x0332, -- commands = { { "rule", height, width } }, - -- hparts = { + -- parts = { -- { advance = width, ["end"] = step, glyph = 0x0332, start = 0 }, -- { advance = width, ["end"] = 0, glyph = 0x0332, start = step, extender = 1 }, -- } @@ -1687,7 +1761,7 @@ do yoffset = - thickness / 2, unicode = 0x203E, commands = { { "rule", thickness, width } }, - hparts = { + parts = { { advance = width, ["end"] = step, glyph = 0x203E, start = 0 }, { advance = width, ["end"] = 0, glyph = 0x203E, start = step, extender = 1 }, } @@ -1714,7 +1788,7 @@ do depth = double, unicode = 0x23B4, commands = { { "rule", thickness, width } }, - hparts = { + parts = { { advance = thickness, glyph = tpiece, ["end"] = 0, start = half }, { advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 }, { advance = thickness, glyph = tpiece, ["end"] = half, start = 0 }, @@ -1735,7 +1809,7 @@ do depth = half, unicode = 0x23B5, commands = { { "rule", thickness, width } }, - hparts = { + parts = { { advance = thickness, glyph = bpiece, ["end"] = 0, start = half }, { advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 }, { advance = thickness, glyph = bpiece, ["end"] = half, start = 0 }, @@ -1776,13 +1850,12 @@ do while chardata.next do chardata = characters[chardata.next] end --- if chardata and (force or not chardata.hparts) then - if chardata and (force or overloads[unicode] == false or not chardata.hparts) then + if chardata and (force or overloads[unicode] == false or not chardata.parts) then if not list then - chardata.hparts = nil -- when we test + chardata.parts = nil -- when we test else local overload = overloads[unicode] - local hparts = { } + local parts = { } for i=1,#list do local part = list[i] local glyph = part.glyph or unicode @@ -1797,7 +1870,7 @@ do local width = characters[glyph].width local step = width/2 if part.extensible then - hparts[#hparts+1] = { + parts[#parts+1] = { advance = width, glyph = glyph, ["end"] = step, @@ -1805,7 +1878,7 @@ do extender = 1, } else - hparts[#hparts+1] = { + parts[#parts+1] = { advance = width, glyph = glyph, ["end"] = 0, @@ -1813,8 +1886,8 @@ do } end end - if #hparts == #list then - chardata.hparts = hparts + if #parts == #list then + chardata.parts = parts end end end @@ -1886,6 +1959,8 @@ do } end + datasets.addarrows = { } + function mathtweaks.addarrows(target,original,parameters) local overloads = parameters.list or { } -- { [unicode] = { left = .1, right = .1 } } local left = parameters.left or 0.05 @@ -1896,6 +1971,10 @@ do for unicode, list in sortedhash(arrows) do create(target,unicode,list,overloads) end + datasets.addarrows = sortedkeys(arrows) + if trace_tweaking then + report_tweak("arrows added",target,original) + end end end @@ -1915,7 +1994,7 @@ do -- this could be combined with the previous local sequence = data.sequence local horizontal = data.horizontal if sequence then - local parts = horizontal and source.hparts or source.vparts + local parts = source.parts if parts then local p = { } for i=1,#sequence do @@ -1943,7 +2022,7 @@ do -- this could be combined with the previous end end if #p > 0 then - target[horizontal and "hparts" or "vparts"] = p + target.parts = p end end end @@ -1982,6 +2061,8 @@ do { 0x205F, "s", 1/2 }, -- math thinspace } + datasets.checkspacing = list + function mathtweaks.checkspacing(target,original,parameters) local characters = target.characters local parameters = target.parameters @@ -2073,6 +2154,32 @@ do end end + local function fix(target,original,characters,u,l) + local data = characters[u] + if data then + data.innerlocation = l.location == "right" and 2 or 1 + data.innerxoffset = (l.hfactor or 1) * (data.width or 0) + data.inneryoffset = (l.vfactor or 1) * ((data.height or 0) + (data.depth or 0)) + end + end + + function mathtweaks.radicaldegreeanchors(target,original,parameters) + local list = parameters.list + if list then + local characters = target.characters + for unicode, l in sortedhash(list) do -- resolve variants + local u = detail(characters,unicode) or unicode + if type(u) == "table" then + for i=1,#u do + fix(target,original,characters,u[i],l) + end + else + fix(target,original,characters,u,l) + end + end + end + end + end do @@ -2137,15 +2244,48 @@ do done = nil end + -- After the next one I rewarded myself by (again) watching Joe Parrish interpretation + -- of Shostakovich 10 Mvmt. II - Metal several times (video on yt, track on bandcamp) + -- ... timestamp: awaiting the new Albion (Official) single; their work comes in parts. + + function mathtweaks.fixintegrals(target,original,parameters) + local characters = target.characters + local integral = characters[0x222B] + if integral and not integral.parts then + local top = characters[0x2320] + local mid = characters[0x23AE] + local bot = characters[0x2321] + if top and mid and bot then + top = top.height + mid = mid.height + bot = bot.height + integral.partsitalic = integral.italic + integral.parts = { + { advance = bot, ["end"] = bot/3, glyph = 0x2321, start = bot/3 }, + { advance = mid, ["end"] = mid/2, glyph = 0x23AE, start = mid/2, extender = 1 }, + { advance = top, ["end"] = top/3, glyph = 0x2320, start = top/3 }, + } + if trace_tweaking then + report_tweak("fixing the integral extensible",target,original) + end + end + else + report_tweak("no need to fix the integral extensible",target,original) + end + end + end do local list = { 0x2061, 0x2062, 0x2063, 0x2064 } + datasets.wipecues = list + function mathtweaks.wipecues(target,original,parameters) local characters = target.characters local tobewiped = parameters.list or list + local done = false for i=1,#tobewiped do local unicode = tobewiped[i] characters[unicode] = { @@ -2154,10 +2294,15 @@ do depth = 0, unicode = unicode, } - if trace_tweaking then - report_tweak("character %U has been wiped",target,original,unicode) + if not trace_tweaking then + done = true + elseif done then + done[unicode] = true + else + done = { [unicode] = true } end end + feedback_tweak("wipecues",target,original,done) end end @@ -2168,48 +2313,62 @@ do [0x002F] = 0x2044, } + datasets.fixslashes = mapping + function mathtweaks.fixslashes(target,original,parameters) local characters = target.characters + -- local done = false for normal, weird in sortedhash(mapping) do local normalone = characters[normal] local weirdone = characters[weird] if normalone and weirdone and not normalone.next then normalone.next = weirdone.next - if trace_tweaking then - report_tweak("extensibles from %U used for %U",target,original,weird,normal) - end + -- if not trace_tweaking then + -- done = true + -- elseif done then + -- done[normal] = true + -- else + -- done = { [normal] = true } + -- end end weirdone = copytable(normalone) characters[weird] = weirdone weirdone.unicode = weird end - end + -- feedback_tweak("fixslashes",target,original,done) + if trace_tweaking then + report_tweak("slashes fixed",target,original) + end + end end do -- see pagella for an extensive example + local nps = fonts.helpers.newprivateslot + local mapping = { - [0x0300] = { 0x0060, false }, -- aliases can be a table - [0x0308] = { 0x00A8, false }, - [0x0304] = { 0x00AF, false }, - [0x0301] = { 0x00B4, false }, - [0x0302] = { 0x02C6, true }, - [0x030C] = { 0x02C7, true }, - [0x0306] = { 0x02D8, false }, - [0x0307] = { 0x02D9, false }, - [0x030A] = { 0x02DA, false }, - [0x0303] = { 0x02DC, true }, - [0x20DB] = { 0x20DB, false }, + [0x0300] = { 0x0060, false, nps("flat 0x0060 1") }, + [0x0308] = { 0x00A8, false, nps("flat 0x00A8 1") }, + [0x0304] = { 0x00AF, false, nps("flat 0x00AF 1") }, + [0x0301] = { 0x00B4, false, nps("flat 0x00B4 1") }, + [0x0302] = { 0x02C6, true, nps("flat 0x02C6 1") }, + [0x030C] = { 0x02C7, true, nps("flat 0x02C7 1") }, + [0x0306] = { 0x02D8, false, nps("flat 0x02D8 1") }, + [0x0307] = { 0x02D9, false, nps("flat 0x02D9 1") }, + [0x030A] = { 0x02DA, false, nps("flat 0x02DA 1") }, + [0x0303] = { 0x02DC, true, nps("flat 0x02DC 1") }, + [0x20DB] = { 0x20DB, false, nps("flat 0x20DB 1") }, } -local hat = fonts.helpers.newprivateslot("hat 0x0302") -- todo other sizes + datasets.fixaccents = mapping + datasets.extendaccents = mapping + datasets.flattenaccents = mapping + datasets.copyaccents = mapping function mathtweaks.fixaccents(target,original,parameters) local characters = target.characters - -characters[hat] = copytable(characters[0x0302]) -- TODO - + local done = false for stretching, entry in sortedhash(mapping) do local alias = entry[1] local stretchingdata = characters[stretching] @@ -2218,23 +2377,43 @@ characters[hat] = copytable(characters[0x0302]) -- TODO local width = -topanchor topanchor = width/2 stretchingdata.width = width + stretchingdata.advance = 0 stretchingdata.topanchor = topanchor stretchingdata.commands = { rightcommand[width + topanchor], charcommand[stretching] } - if trace_tweaking then - report_tweak("width of initial extensible accent %U set",target,original,stretching) + if not trace_tweaking then + done = true + elseif done then + done[stretching] = true + else + done = { [stretching] = true } end end end + feedback_tweak("fixaccents",target,original,done) end + -- all true|number false + function mathtweaks.extendaccents(target,original,parameters) local characters = target.characters + local all = parameters.all + local count = tonumber(all) + local done = false for stretching, entry in sortedhash(mapping) do local extend = entry[2] - local stretchingdata = characters[stretching] if extend then - local last = stretchingdata + local last = characters[stretching] + local cnt = 1 + local okay = false while last do + if all or (count and cnt > count) then + last.extensible = true + local flataccent = last.flataccent + if flataccent then + characters[flataccent].extensible = true + okay = true + end + end local n = last.next if n then last = characters[n] @@ -2243,16 +2422,72 @@ characters[hat] = copytable(characters[0x0302]) -- TODO local flataccent = last.flataccent if flataccent then characters[flataccent].extensible = true + okay = true end break end + cnt = cnt + 1 + end + if okay then + if not trace_tweaking then + done = true + elseif done then + done[stretching] = true + else + done = { [stretching] = true } + end + end + end + end + feedback_tweak("extendaccents",target,original,done) + end + + -- force true false + -- height factor 0.8 + -- offset factor 0.9|calculated + -- squeeze factor 0.1|calculated + + function mathtweaks.flattenaccents(target,original,parameters) + local characters = target.characters + local force = parameters.force + local squeeze = parameters.squeeze or 0.8 + local ofactor = parameters.offset or (squeeze/2) + local hfactor = parameters.height or (1 - ofactor) + local done = false + for stretching, entry in sortedhash(mapping) do + local last = characters[stretching] + while last do + if force or not last.flataccent then + local slot = entry[3] + local data = copytable(last) + local height = data.height or 0 + data.effect = { squeeze = squeeze } + data.height = hfactor * height + data.yoffset = ofactor * height + characters[slot] = data + last.flataccent = slot + if not trace_tweaking then + done = true + elseif done then + done[stretching] = true + else + done = { [stretching] = true } + end + end + local n = last.next + if n then + last = characters[n] + else + break end end end + feedback_tweak("flattenaccents",target,original,done) end function mathtweaks.copyaccents(target,original,parameters) local characters = target.characters + local done = false for stretching, entry in sortedhash(mapping) do local alias = entry[1] if alias ~= stretching then @@ -2266,15 +2501,20 @@ characters[hat] = copytable(characters[0x0302]) -- TODO next = stretchingdata.next, commands = { charcommand[stretching] }, topanchor = stretchingdata.topanchor, - -- unicode = stretching, -- when we aliasize to combiners + -- unicode = stretching, -- when we alias to combiners unicode = alias, -- when we keep the original } - if trace_tweaking then - report_tweak("extensibles accent %U copied to %U",target,original,stretching,alias) + if not trace_tweaking then + done = true + elseif done then + done[stretching] = true + else + done = { [stretching] = true } end end end end + feedback_tweak("copyaccents",target,original,done) end end @@ -2335,8 +2575,8 @@ do local parameters = target.parameters local linewidth = target.MathConstants.RadicalRuleThickness -- make option local basechar = characters[radical] - local baseheight = basechar.height/2 - local basedepth = basechar.depth/2 + local baseheight = (basechar.height or 0)/2 + local basedepth = (basechar.depth or 0)/2 local basetotal = baseheight + basedepth local used = baseheight -- @@ -2364,7 +2604,7 @@ do downcommand[basedepth], { "rule", basetotal, linewidth }, }, - vparts = { + parts = { { advance = basetotal, ["end"] = used, @@ -2408,7 +2648,7 @@ do upcommand[baseheight-4*linewidth], { "rule", 4*linewidth, linewidth }, }, - vparts = { + parts = { { advance = basetotal, ["end"] = used, @@ -2489,7 +2729,7 @@ do commands = { scale == 1 and charcommand[basecode] or { "slot", 0, basecode, scale, scale }, }, - vparts = { + parts = { { advance = used, ["end"] = used, @@ -2553,13 +2793,13 @@ do -- local used = 0.8*height local used = 1.2*height -- large overlap because no smaller pieces local total = height + depth - characters[single].vparts = extensible(single,total,used) + characters[single].parts = extensible(single,total,used) characters[double] = { unicode = double, width = 2*width - 1*advance, height = height, depth = depth, - vparts = extensible(double,total,used), + parts = extensible(double,total,used), callback = "devirtualize", commands = { charcommand[single], @@ -2787,16 +3027,10 @@ do elseif trace_tweaking then report_tweak("skipping mirror %U (%s)",target,original,unicode,what) end - local hparts = data.hparts - if hparts then - for i=1,#hparts do - add(target,original,characters,hparts[i],"hpart") - end - end - local vparts = data.vparts - if vparts then - for i=1,#vparts do - add(target,original,characters,vparts[i],"vpart") + local parts = data.parts + if parts then + for i=1,#parts do + add(target,original,characters,parts[i],"hpart") end end local smaller = data.smaller @@ -2907,7 +3141,7 @@ do if setlist or resetlist then local properties = target.properties local codes = tex.mathcontrolcodes - local oldcontrol = tex.get("mathfontcontrol") + local oldcontrol = texget("mathfontcontrol") local newcontrol = oldcontrol -- todo: reset if resetlist then @@ -2989,15 +3223,13 @@ do local features = target.specification.features.normal local definedfont = fonts.definers.internal local copiedglyph = fonts.handlers.vf.math.copy_glyph --- does a deep copy, including parts and so + -- does a deep copy, including parts and so local getsubstitution = fonts.handlers.otf.getsubstitution local fontdata = fonts.hashes.identifiers -- local fonts = target.fonts local size = target.size local characters = target.characters --- local descriptions = target.descriptions - -- compact: size = 655360 if not fonts then fonts = { } target.fonts = fonts @@ -3019,8 +3251,7 @@ do local firstsource = sourcerange.first local lastsource = sourcerange.last or firstsource if firstsource and firsttarget then - local offset = firsttarget - firstsource - local topovershoot = entry.topovershoot + local offset = firsttarget - firstsource if filename then local rscale = entry.rscale or 1 -- todo size = size * rscale -- maybe use scale in vf command @@ -3047,11 +3278,10 @@ do if feature then sourceunicode = getsubstitution(dropin,sourceunicode,feature,true,"math","dflt") or sourceunicode end - if trace_tweaking then - report_tweak("copying %s %U from file %a to %s %U",target,original,thesource,sourceunicode,filename,thetarget,targetunicode) - end +-- if trace_tweaking then +-- report_tweak("copying %s %U from file %a to %s %U",target,original,thesource,sourceunicode,filename,thetarget,targetunicode) +-- end characters[targetunicode] = copiedglyph(target,characters,chars,sourceunicode,index) --- description end end elseif feature then @@ -3062,11 +3292,10 @@ do local variant = getsubstitution(original,sourceunicode,feature,true,"math","dflt") local data = characters[variant] if data then - if trace_tweaking then - report_tweak("copying %s %U from feature %a to %s %U",target,original,thesource,sourceunicode,feature,thetarget,targetunicode) - end +-- if trace_tweaking then +-- report_tweak("copying %s %U from feature %a to %s %U",target,original,thesource,sourceunicode,feature,thetarget,targetunicode) +-- end characters[targetunicode] = copytable(data) --- description end end else @@ -3075,13 +3304,12 @@ do local sourceunicode = mathgaps[s] or s local targetunicode = mathgaps[t] or t if sourceunicode ~= targetunicode then - local data = characters[sourceunicode] + local data = characters[sourceunicode] if data then - if trace_tweaking then - report_tweak("copying %s %U to %s %U",target,original,thesource,sourceunicode,thetarget,targetunicode) - end +-- if trace_tweaking then +-- report_tweak("copying %s %U to %s %U",target,original,thesource,sourceunicode,thetarget,targetunicode) +-- end characters[targetunicode] = copytable(data) --- description end end end @@ -3184,21 +3412,23 @@ local function applytweaks(when,target,original) end end +local function tweakable(target) + local mathparameters = target.mathparameters +-- local features = target.specification.features +-- local mathscript = features and features.normal and features.normal.script == "math" +-- return mathparameters and mathscript -- and target,properties.hasmath + return mathparameters +end + function mathematics.tweakbeforecopyingfont(target,original) - if use_math_goodies then - local mathparameters = target.mathparameters -- why not hasmath - if mathparameters then - applytweaks("beforecopying",target,original) - end + if use_math_goodies and tweakable(target) then + applytweaks("beforecopying",target,original) end end function mathematics.tweakaftercopyingfont(target,original) - if use_math_goodies then - local mathparameters = target.mathparameters -- why not hasmath - if mathparameters then - applytweaks("aftercopying",target,original) - end + if use_math_goodies and tweakable(target) then + applytweaks("aftercopying",target,original) end end @@ -3232,8 +3462,7 @@ do local reported = table.setmetatableindex("table") function mathematics.checkaftercopyingfont(target,original) - local mathparameters = target.mathparameters -- why not hasmath - if mathparameters then + if tweakable(target) then local chardata = characters.data local characters = target.characters -- @@ -3300,11 +3529,8 @@ do end function mathematics.beforepassingfonttotex(target) - if use_math_goodies then - local mathparameters = target.mathparameters -- why not hasmath - if mathparameters then - applytweaks("beforepassing",target,target) - end + if tweakable(target) then + applytweaks("beforepassing",target,target) end end @@ -3352,15 +3578,7 @@ local function extensiblecode(font,unicode) if not char then return unknown end - if character.hparts then - if character.vparts then - return { e_mixed, code, character } - else - local m = char.mathextensible - local e = m and extensibles[m] - return e and { e, code, character } or unknown - end - elseif character.vparts then + if character.parts then local m = char.mathextensible local e = m and extensibles[m] return e and { e, code, character } or unknown @@ -3402,19 +3620,19 @@ local function horizontalcode(family,unicode) local loffset = 0 local roffset = 0 if kind == e_left then - local charlist = data[3].hparts + local charlist = data[3].parts if charlist then local left = charlist[1] loffset = abs((left["start"] or 0) - (left["end"] or 0)) end elseif kind == e_right then - local charlist = data[3].hparts + local charlist = data[3].parts if charlist then local right = charlist[#charlist] roffset = abs((right["start"] or 0) - (right["end"] or 0)) end elseif kind == e_horizontal then - local charlist = data[3].hparts + local charlist = data[3].parts if charlist then local left = charlist[1] local right = charlist[#charlist] @@ -3444,3 +3662,52 @@ interfaces.implement { -- can be public with two times "integerargument" context(kind) end } + +function mathematics.variantcode(unicode,variant) + local data = fontcharacters[getfontoffamily(texget("fam"))] + local char = data and data[unicode] + if char then + for i=1,variant do + local next = char.next + if next then + unicode = next + char = data[next] + else + break + end + end + end + return unicode +end + +function mathematics.variantcount(unicode) + local data = fontcharacters[getfontoffamily(texget("fam"))] + local char = data and data[unicode] + local count = 0 + if char then + while true do + local next = char.next + if next then + count = count + 1 + char = data[next] + else + break + end + end + end + return count +end + +interfaces.implement { + name = "mathvariantcode", + public = true, + arguments = { "integer", "integer" }, + actions = { mathematics.variantcode, context }, +} + +interfaces.implement { + name = "mathvariantcount", + public = true, + arguments = "integer", + actions = { mathematics.variantcount, context }, +} diff --git a/tex/context/base/mkxl/math-ali.mkxl b/tex/context/base/mkxl/math-ali.mkxl index af6b48cee..8a29f4f9d 100644 --- a/tex/context/base/mkxl/math-ali.mkxl +++ b/tex/context/base/mkxl/math-ali.mkxl @@ -2871,11 +2871,11 @@ %D Usage \type {\sum _ {\mstack {i \in V_{0}, i \neq j}}}, documented by Mikael: -\permanent\protected\def\mstack#1% +\permanent\protected\def\mstack#1% todo: make it configurable {\begingroup \scratchtoks\emptytoks \setcharstrut(\relax - \processcommalist[#1]{\iftok\scratchtoks\emptytoks\else\toksapp\scratchtoks{\strut\NR}\fi\toksapp\scratchtoks}% - \expandafter\startsubstack\the\scratchtoks\strut\stopsubstack + \processcommalist[#1]{\iftok\scratchtoks\emptytoks\else\toksapp\scratchtoks{\mathstrut\NR}\fi\toksapp\scratchtoks}% + \expandafter\startsubstack\the\scratchtoks\mathstrut\stopsubstack \endgroup} %D Similar to simplecases: diff --git a/tex/context/base/mkxl/math-fen.mkxl b/tex/context/base/mkxl/math-fen.mkxl index b3c85070f..d8cbf4e76 100644 --- a/tex/context/base/mkxl/math-fen.mkxl +++ b/tex/context/base/mkxl/math-fen.mkxl @@ -54,6 +54,8 @@ \c!height=\zeropoint, \c!depth=\zeropoint, \c!distance=\zerocount, + \c!topspace=\zeropoint, + \c!bottomspace=\zeropoint, \c!factor=\v!auto] \appendtoks @@ -83,6 +85,17 @@ %D $ a + \fenced[bar] {\frac {b} {c}} + d $ %D \stoptyping +% \startbuffer +% $ \left( \frac{1}{x}^{2} \right)$ +% $ \left( x \right)$ +% $ \left( x^2 \right)$ +% $ \left( \frac{1}{x} \right)$ +% $ \left( \frac{1}{x}^2 \right)$ +% \stopbuffer +% +% \getbuffer\blank +% {\setupmathfence[topspace=-2pt,bottomspace=-1pt]\getbuffer\blank} + % todo : class -> number \newconditional\c_math_fenced_mirror \settrue \c_math_fenced_mirror @@ -205,6 +218,10 @@ \fi \s!source \numexpr\namedboxanchor{\mathfenceparameter#4}\relax + % + \s!top \mathfenceparameter\c!topspace + \s!bottom \mathfenceparameter\c!bottomspace + % \math_fenced_trace \ifx\p_fence\v!none \Udelimiter\mathghostcode\fam\zerocount diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl index c1beb071c..259fd360e 100644 --- a/tex/context/base/mkxl/math-ini.mkxl +++ b/tex/context/base/mkxl/math-ini.mkxl @@ -111,6 +111,8 @@ +\analyzescriptnucleusboxmathcontrolcode +\accenttopskewwithoffsetmathcontrolcode % +\ignorekerndimensionsmathcontrolcode % xits needs this (bad depth of fences) + % +\ignoreflataccentsmathcontrolcode + +\extendaccentsmathcontrolcode \relax % \mathpenaltiesmode\plusone @@ -891,7 +893,6 @@ % Now we redefine \type {\mathematics} and \type {\m}: \pushoverloadmode - \permanent\protected\def\mathematics{\doifelsenextoptionalcs\math_m_yes\math_m_nop} \aliased\let\m \mathematics % we keep the simple versions @@ -3723,6 +3724,54 @@ \definemathtext[mathsplitbi][mathsplit][\c!style=\bi] \definemathtext[mathsplitbs][mathsplit][\c!style=\bs] +% \startbuffer +% $ +% { x\! \neq x!} \quad {\ss x\! \neq x!} \qquad +% {\it x\! \neq x!} \quad {\ss \it x\! \neq x!} \qquad +% {\fi x\! \neq x!} \quad {\ss \fi x\! \neq x!} \qquad +% {\bi x\! \neq x!} \quad {\ss \bi x\! \neq x!} +% $ +% \stopbuffer +% +% \startTEXpage[offset=1dk] +% \getbuffer \par \automathtext \getbuffer +% \stopTEXpage + +\newconditional\c_mathtextauto % we need aproper key: \settrue\c_mathtextauto + +\permanent\protected\def\automathtext{\settrue\c_mathtextauto} + +\let\currentmathalphabet \s!rm +\let\currentmathfontstyle\s!tf + +\permanent\protected\def\mathtextauto#1#2% + {\ifconditional\c_mathtextauto + \mathortext + {\mathpunct + {\begincsname\currentmathalphabet\endcsname + \begincsname mathtext\currentmathfontstyle\endcsname + {#1}}}% + {#1}% + \else + #2% + \fi} + +%D Actually in spac-hor.mkxl we defined them using \suggestedalias which redefines +%D these so basically we now make that sort of obsolete. +%D +%D \starttyping +%D $x\, x$\quad\automathtext$x\, x$ +%D \stoptyping + +\pushoverloadmode + \permanent\protected\def\.{\mathtextauto{.}{.}} + \permanent\protected\def\,{\mathtextauto{,}{\thinspace }} + \permanent\protected\def\:{\mathtextauto{:}{\medspace }} + \permanent\protected\def\;{\mathtextauto{;}{\thickspace}} + \permanent\protected\def\!{\mathtextauto{!}{\negthinspace}} + \permanent\protected\def\?{\mathtextauto{?}{?}} +\popoverloadmode + \appendtoks \reinstatecatcodecommand\barasciicode \obeydiscretionaries @@ -4294,13 +4343,21 @@ %D Just to be sure: -\immutable\integerdef\c_math_glyph_options\numexpr +\immutable\integerdef\c_math_glyph_options_default\numexpr \noexpansionglyphoptioncode +\noprotrusionglyphoptioncode \relax +\immutable\integerdef\c_math_glyph_options_hz\numexpr + \noprotrusionglyphoptioncode +\relax + \appendtoks - \glyphoptions\c_math_glyph_options + \ifcstok{\mathematicsparameter\v!hz}\v!yes + \glyphoptions\c_math_glyph_options_hz + \else + \glyphoptions\c_math_glyph_options_default + \fi \to \everymathematics %D Bonus for testing: diff --git a/tex/context/base/mkxl/math-lop.mkxl b/tex/context/base/mkxl/math-lop.mkxl index 8be8fc98d..327d663e8 100644 --- a/tex/context/base/mkxl/math-lop.mkxl +++ b/tex/context/base/mkxl/math-lop.mkxl @@ -67,7 +67,9 @@ \ifchkdim\mathoperatorparameter\c!size\or \s!depth \mathoperatorparameter\c!size \s!height\mathoperatorparameter\c!size - \s!axis + \s!axis % variants + \s!noaxis % extensibles (assumes also axis) + \s!exact % make sure we don't overshoot when there are no variants and extensibles \orelse\ifcstok{\mathoperatorparameter\c!size}\v!auto \s!auto \fi @@ -118,9 +120,10 @@ \setupmathematics[\c!integral=nolimits] -\definemathoperator [integral] [integrals] [\c!left="222B] % these might go unless we decide -\definemathoperator [iintegral] [integrals] [\c!left="222C] % to have verbose parents but who -\definemathoperator [iiintegral] [integrals] [\c!left="222D] % will use them +\definemathoperator [integral] [integrals] [\c!left="222B] % these might go unless we decide +\definemathoperator [iintegral] [integrals] [\c!left="222C] % to have verbose parents but who +\definemathoperator [iiintegral] [integrals] [\c!left="222D] % will use them +\definemathoperator [iiiintegral] [integrals] [\c!left="2A0C] \definemathoperator [int] [integrals] [\c!left="222B] % INTEGRAL \definemathoperator [iint] [integrals] [\c!left="222C] % DOUBLE INTEGRAL diff --git a/tex/context/base/mkxl/math-map.lmt b/tex/context/base/mkxl/math-map.lmt index d0a1410a1..98cc59c89 100644 --- a/tex/context/base/mkxl/math-map.lmt +++ b/tex/context/base/mkxl/math-map.lmt @@ -46,6 +46,8 @@ local setmetatableindex = table.setmetatableindex local texgetattribute = tex.getattribute local texsetattribute = tex.setattribute +local setmacro = tokens.setters.macro + local texgetmode = tex.getmode local mathmode_code = tex.modelevels.math @@ -711,9 +713,19 @@ implement { protected = true, actions = function(alphabet,style) if texgetmode() == mathmode_code then - local data = alphabets[alphabet] or regular - data = data[style] or data.tf - texsetattribute(mathalphabet,data and data.attribute or texattribute[mathalphabet]) + local data = alphabets[alphabet] + if not data then + alphabet = "regular" + data = regular + end + local used = data[style] + if not used then + style = "tf" + used = data.tf + end + setmacro("currentmathalphabet",alphabet == "regular" and "rm" or alphabet) + setmacro("currentmathfontstyle",style) + texsetattribute(mathalphabet,used and used.attribute or texattribute[mathalphabet]) end end } @@ -728,6 +740,7 @@ implement { local r = mathremap[texgetattribute(mathalphabet)] local alphabet = r and r.alphabet or "regular" local data = alphabets[alphabet][style] + setmacro("currentmathfontstyle",style) texsetattribute(mathalphabet,data and data.attribute or texattribute[mathalphabet]) end end diff --git a/tex/context/base/mkxl/math-vfu.lmt b/tex/context/base/mkxl/math-vfu.lmt index 86d1fca0d..c1d45551b 100644 --- a/tex/context/base/mkxl/math-vfu.lmt +++ b/tex/context/base/mkxl/math-vfu.lmt @@ -85,7 +85,7 @@ local shared = { } local function brace(main,characters,id,size,unicode,first,rule,left,right,rule,last) if not characters[unicode] then characters[unicode] = { - hparts = { + parts = { { extender = 0, glyph = first }, { extender = 1, glyph = rule }, { extender = 0, glyph = left }, @@ -123,7 +123,7 @@ local function extension(main,characters,id,size,unicode,first,middle,last) if lw == 0 then lw = 1 end - chr.hparts = { + chr.parts = { { extender = 0, glyph = first, ["end"] = fw/2, start = 0, advance = fw }, { extender = 1, glyph = middle, ["end"] = mw/2, start = mw/2, advance = mw }, { extender = 0, glyph = last, ["end"] = 0, start = lw/2, advance = lw }, @@ -133,7 +133,7 @@ end local function parent(main,characters,id,size,unicode,first,rule,last) if not characters[unicode] then characters[unicode] = { - hparts = { + parts = { { extender = 0, glyph = first }, { extender = 1, glyph = rule }, { extender = 0, glyph = last }, @@ -668,13 +668,13 @@ local function copy_glyph(main,target,original,unicode,slot) break -- safeguard (when testing stuff) end end - local hv = olddata.hparts - if hv then - hv = fastcopy(hv) - newdata.hparts = hv - for i=1,#hv do - local hvi = hv[i] - local oldglyph = hvi.glyph + local pv = olddata.parts + if pv then + pv = fastcopy(pv) + newdata.parts = pv + for i=1,#hp do + local pvi = pv[i] + local oldglyph = pvi.glyph local olddata = original[oldglyph] local newdata = { width = olddata.width, @@ -683,25 +683,7 @@ local function copy_glyph(main,target,original,unicode,slot) tounicode = olddata.tounicode, commands = { { "slot", slot, oldglyph } }, } - hvi.glyph = addprivate(main,formatters["M-H-%H"](oldglyph),newdata) - end - end - local vv = olddata.vparts - if vv then - vv = fastcopy(vv) - newdata.vparts = vv - for i=1,#vv do - local vvi = vv[i] - local oldglyph = vvi.glyph - local olddata = original[oldglyph] - local newdata = { - width = olddata.width, - height = olddata.height, - depth = olddata.depth, - tounicode = olddata.tounicode, - commands = { { "slot", slot, oldglyph } }, - } - vvi.glyph = addprivate(main,formatters["M-V-%H"](oldglyph),newdata) + pvi.glyph = addprivate(main,formatters["M-P-%H"](oldglyph),newdata) end end local smaller = olddata.smaller @@ -1029,30 +1011,18 @@ function vfmath.define(specification,set,goodies) if n then t.next = offset + n elseif variants_done then - local vv = fci.vparts - if vv then - t.vparts = vv - end - local hv = fci.hparts - if hv then - t.hparts = hv + local v = fci.parts + if v then + t.parts = v end else - local vv = fci.vparts - if vv then - for i=1,#vv do - local vvi = vv[i] - vvi.glyph = vvi.glyph + offset - end - t.vparts = vv - end - local hv = fci.hparts - if hv then - for i=1,#hv do - local hvi = hv[i] - hvi.glyph = hvi.glyph + offset + local v = fci.parts + if v then + for i=1,#v do + local vi = v[i] + vi.glyph = vi.glyph + offset end - t.hparts = hv + t.parts = v end end characters[offset + index] = t diff --git a/tex/context/base/mkxl/meta-imp-glyphs.mkxl b/tex/context/base/mkxl/meta-imp-glyphs.mkxl new file mode 100644 index 000000000..96f7aecd3 --- /dev/null +++ b/tex/context/base/mkxl/meta-imp-glyphs.mkxl @@ -0,0 +1,65 @@ +%D \module +%D [ file=meta-imp-glyphs, +%D version=2022.10.26, % moved from test files by MS and HH +%D title=\METAPOST\ Graphics, +%D subtitle=Glyph Shape Manipulations, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startMPdefinitions + + def LoadGlyph(expr tag, filename, unicode) = + glyphshape_start(filename,unicode) ; + expandafter picture scantokens(tag & "char"); + expandafter path scantokens(tag & "bbox") ; + expandafter numeric scantokens(tag & "accent") ; + expandafter numeric scantokens(tag & "italic") ; + scantokens(tag & "char") := image (draw for i=1 upto glyphshape_n : glyphshape_path(i) && endfor cycle ;) ; + scantokens(tag & "bbox") := glyphshape_usedbox ; + scantokens(tag & "accent") := glyphshape_accent ; + scantokens(tag & "italic") := xpart urcorner glyphshape_usedbox - glyphshape_italic ; + glyphshape_stop ; + enddef ; + + def ScaleGlyph(expr tag, s) = + scantokens(tag & "char") := scantokens(tag & "char") scaled s ; + scantokens(tag & "bbox") := scantokens(tag & "bbox") scaled s ; + scantokens(tag & "accent") := s * scantokens(tag & "accent") ; + scantokens(tag & "italic") := s * scantokens(tag & "italic") ; + enddef ; + + def ShiftGlyph(expr tag, dx, dy) = + scantokens(tag & "char") := scantokens(tag & "char") shifted (dx, dy) ; + scantokens(tag & "bbox") := scantokens(tag & "bbox") shifted (dx, dy) ; + scantokens(tag & "accent") := scantokens(tag & "accent") + dx ; + scantokens(tag & "italic") := scantokens(tag & "italic") + dx ; + enddef ; + + def DrawGlyph(expr tag) = + draw scantokens(tag & "char") withpen pencircle scaled 1 ; + draw scantokens(tag & "bbox") withcolor "darkyellow" ; + draw (scantokens(tag & "accent"), (ypart urcorner scantokens(tag & "bbox"))) withcolor "darkmagenta" withpen pencircle scaled 5 ; + draw (scantokens(tag & "italic"), .5(ypart urcorner scantokens(tag & "bbox"))) withcolor "orange" withpen pencircle scaled 5 ; + enddef ; + +\stopMPdefinitions + +\startMPdefinitions + + def ShowShape(expr font, slot) = + glyphshape_start(font, slot) ; + draw for i=1 upto glyphshape_n : glyphshape_path(i) && endfor cycle ; + draw glyphshape_boundingbox withcolor red ; + draw glyphshape_usedline withcolor green ; + draw glyphshape_usedbox withcolor blue ; + draw (glyphshape_accent,glyphshape_depth) withcolor "orange" withpen pencircle scaled 5 ; + draw (glyphshape_italic,glyphshape_depth) withcolor "orange" withpen pencircle scaled 5 ; + glyphshape_stop ; + enddef; + +\stopMPdefinitions diff --git a/tex/context/base/mkxl/mlib-ctx.mkxl b/tex/context/base/mkxl/mlib-ctx.mkxl index 384650a45..7c88585e9 100644 --- a/tex/context/base/mkxl/mlib-ctx.mkxl +++ b/tex/context/base/mkxl/mlib-ctx.mkxl @@ -29,6 +29,7 @@ \registerctxluafile{mlib-pos}{autosuffix} \registerctxluafile{mlib-cnt}{autosuffix} \registerctxluafile{mlib-svg}{autosuffix} +\registerctxluafile{mlib-fnt}{autosuffix} % outline fun \unprotect diff --git a/tex/context/base/mkxl/font-mps.lmt b/tex/context/base/mkxl/mlib-fnt.lmt index 7afc48d0f..e53ded38a 100644 --- a/tex/context/base/mkxl/font-mps.lmt +++ b/tex/context/base/mkxl/mlib-fnt.lmt @@ -6,9 +6,10 @@ if not modules then modules = { } end modules ['font-mps'] = { license = "see context related readme files" } -local tostring = tostring -local concat = table.concat -local formatters = string.formatters +local type, tonumber, tostring = type, tonumber, tostring +local concat, insert, remove = table.concat, table.insert, table.remove +local formatters, match = string.formatters, string.match +local utfbyte = utf.byte -- QP0 [QP1] QP2 => CP0 [CP1 CP2] CP3 @@ -33,8 +34,8 @@ local f_dofill = formatters["fill %s;"] local f_draw_trace = formatters["drawpathonly %s;"] local f_draw = formatters["draw %s;"] -local f_boundingbox = formatters["((%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--cycle)"] -local f_vertical = formatters["((%N,%N)--(%N,%N))"] +local f_rectangle = formatters["((%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--cycle)"] +local f_line = formatters["((%N,%N)--(%N,%N))"] function metapost.boundingbox(d,factor) local bounds = d.boundingbox @@ -43,7 +44,7 @@ function metapost.boundingbox(d,factor) local lly = factor*bounds[2] local urx = factor*bounds[3] local ury = factor*bounds[4] - return f_boundingbox(llx,lly,urx,lly,urx,ury,llx,ury) + return f_rectangle(llx,lly,urx,lly,urx,ury,llx,ury) end function metapost.baseline(d,factor) @@ -51,7 +52,7 @@ function metapost.baseline(d,factor) local factor = factor or 1 local llx = factor*bounds[1] local urx = factor*bounds[3] - return f_vertical(llx,0,urx,0) + return f_line(llx,0,urx,0) end function metapost.widthline(d,factor) @@ -60,7 +61,7 @@ function metapost.widthline(d,factor) local lly = factor*bounds[2] local ury = factor*bounds[4] local width = factor*d.width - return f_vertical(width,lly,width,ury) + return f_line(width,lly,width,ury) end function metapost.zeroline(d,factor) @@ -68,7 +69,7 @@ function metapost.zeroline(d,factor) local factor = factor or 1 local lly = factor*bounds[2] local ury = factor*bounds[4] - return f_vertical(0,lly,0,ury) + return f_line(0,lly,0,ury) end function metapost.paths(d,xfactor,yfactor) @@ -247,7 +248,7 @@ function metapost.maxbounds(data,index,factor) if width > urx then urx = width end - return f_boundingbox( + return f_rectangle( factor*llx,factor*ymin, factor*urx,factor*ymin, factor*urx,factor*ymax, @@ -274,11 +275,15 @@ local emptyrule_code = rulecodes.empty local nuts = nodes.nuts local getwhd = nuts.getwhd local getexpansion = nuts.getexpansion +local getscales = nuts.getscales local isglyph = nuts.isglyph -local characters = fonts.hashes.characters -local parameters = fonts.hashes.parameters -local shapes = fonts.hashes.shapes +local fonthashes = fonts.hashes +local fontcharacters = fonthashes.characters +local fontparameters = fonthashes.parameters +local fontshapes = fonthashes.shapes +local fontdescriptions = fonthashes.descriptions + local topaths = metapost.paths local f_text = formatters["mfun_do_outline_text_flush(%q,%i,%N,%N,%q)(%,t);"] @@ -289,18 +294,18 @@ local s_nothing = "(origin scaled 10)" local sc = 10 local fc = number.dimenfactors.bp -local function glyph(kind,font,char,advance,shift,ex) - local character = characters[font][char] +local function glyph(kind,font,char,advance,shift,ex,s, sx,sy) + local character = fontcharacters[font][char] if character then local index = character.index if index then - local shapedata = shapes[font] - local glyphs = shapedata.glyphs -- todo: subfonts fonts.shapes.indexed(font,sub) + local shapedata = fontshapes[font] + local glyphs = shapedata.glyphs if glyphs then local glyf = glyphs[index] if glyf then local units = 1000 -- factor already takes shapedata.units into account - local yfactor = (sc/units) * parameters[font].factor / 655.36 + local yfactor = (sc/units) * fontparameters[font].factor / 655.36 local xfactor = yfactor local shift = shift or 0 local advance = advance or 0 @@ -311,6 +316,10 @@ local function glyph(kind,font,char,advance,shift,ex) wfactor = (1+(ex/units)/1000) xfactor = xfactor * wfactor end + if s then + xfactor = (s/1000) * ((sx or 1000)/1000) * xfactor + yfactor = (s/1000) * ((sy or 1000)/1000) * yfactor + end local paths = topaths(glyf,xfactor,yfactor) if paths then return f_text(kind,#paths,advance,shift,detail,paths) -- , character.width * fc * wfactor @@ -334,7 +343,8 @@ end local function flushcharacter(current, pos_h, pos_v, pod_r, font, char) local char, font = isglyph(current) - local code = glyph(kind,font,char,pos_h*fc,pos_v*fc,getexpansion(current)) + local s, sx, sy = getscales(current) + local code = glyph(kind,font,char,pos_h*fc,pos_v*fc,getexpansion(current),s,sx,sy) if code then b = b + 1 buffer[b] = code @@ -405,3 +415,134 @@ function metapost.boxtomp(n,k) return result end +-- This is a new set of commands: + +local loaded = table.setmetatableindex(function(t,k) + local v = fonts.definers.internal({ name = k } ,"<lmt:glyphshape:font>") + t[k] = v + return v +end) + +local mpdata = 0 +local mpstack = { } + +function mp.lmt_glyphshape_start(id,character) + if type(id) == "string" then + id = loaded[id] + end + local fontid = (id and id ~= 0 and id) or font.current() + local shapedata = fontshapes [fontid] -- by index + local characters = fontcharacters [fontid] -- by unicode + local descriptions = fontdescriptions[fontid] -- by unicode + local mathgaps = mathematics.gaps -- not yet loaded + local shapeglyphs = shapedata.glyphs or { } + if type(character) == "string" and character ~= "" then + local hex = match(character,"^0x(.+)") + if hex then + character = tonumber(hex,16) + else + character = utfbyte(character) + end + else + character = tonumber(character) + end + local unicode = mathgaps[character] or character + local chardata = characters[unicode] + local descdata = descriptions[unicode] + if chardata then + glyph = shapeglyphs[chardata.index] + if glyph then + mpdata = glyph.mpdata + if not mpdata then + if glyph.segments or glyph.sequence then + local units = shapedata.units or 1000 + local factor = 100/units + local width = (descdata.width or 0) * factor + local height = descdata.boundingbox[4] * factor + local depth = descdata.boundingbox[2] * factor + local math = descdata.math + local italic = (math and math.italic or 0) * factor + local accent = (math and math.accent or 0) * factor + mpdata = { + paths = metapost.paths(glyph,factor), + boundingbox = metapost.boundingbox(glyph,factor), + baseline = metapost.baseline(glyph,factor), + width = width, + height = height, + depth = depth, + italic = italic, + accent = accent, + usedbox = f_rectangle(0,depth,width,depth,width,height,0,height), + usedline = f_line(0,0,width,0), + } + glyph.mpdata = mpdata + else + print("CHECK 1",id,character) + end + end + end + else + print("CHECK 2",id,character) + end + insert(mpstack, mpdata) +end + +local mpprint = mp.print +local injectpair = mp.inject.pair +local injectnumeric = mp.inject.numeric + +function mp.lmt_glyphshape_stop() + mpdata = remove(mpstack) +end + +function mp.lmt_glyphshape_n() + if mpdata then + mpprint(#mpdata.paths) + else + injectnumeric(0) + end +end + +function mp.lmt_glyphshape_path(i) + if mpdata then + mpprint(mpdata.paths[i]) + else + injectpair(0,0) + end +end + +function mp.lmt_glyphshape_boundingbox() + if mpdata then + mpprint(mpdata.boundingbox) + else + injectpair(0,0) + end +end +function mp.lmt_glyphshape_usedbox() + if mpdata then + mpprint(mpdata.usedbox) + else + injectpair(0,0) + end +end + +function mp.lmt_glyphshape_baseline() + if mpdata then + mpprint(mpdata.baseline) + else + injectpair(0,0) + end +end +function mp.lmt_glyphshape_usedline() + if mpdata then + mpprint(mpdata.usedline) + else + injectpair(0,0) + end +end + +function mp.lmt_glyphshape_width () injectnumeric(mpdata and mpdata.width or 0) end +function mp.lmt_glyphshape_depth () injectnumeric(mpdata and mpdata.depth or 0) end +function mp.lmt_glyphshape_height() injectnumeric(mpdata and mpdata.height or 0) end +function mp.lmt_glyphshape_italic() injectnumeric(mpdata and mpdata.italic or 0) end +function mp.lmt_glyphshape_accent() injectnumeric(mpdata and mpdata.accent or 0) end diff --git a/tex/context/base/mkxl/mult-sys.mkxl b/tex/context/base/mkxl/mult-sys.mkxl index 636c15363..f04418e43 100644 --- a/tex/context/base/mkxl/mult-sys.mkxl +++ b/tex/context/base/mkxl/mult-sys.mkxl @@ -45,6 +45,9 @@ \definesystemconstant {afrikaans} \definesystemconstant {af} \definesystemconstant {albanian} \definesystemconstant {sq} +\definesystemconstant {armenian} \definesystemconstant {hy} + \definesystemconstant {hye} + \definesystemconstant {hyw} \definesystemconstant {ancientgreek} \definesystemconstant {agr} \definesystemconstant {ancientlatin} \definesystemconstant {ala} \definesystemconstant {arabic} \definesystemconstant {ar} diff --git a/tex/context/base/mkxl/node-cmp.lmt b/tex/context/base/mkxl/node-cmp.lmt index 8f805abd9..887020351 100644 --- a/tex/context/base/mkxl/node-cmp.lmt +++ b/tex/context/base/mkxl/node-cmp.lmt @@ -202,12 +202,8 @@ local iszeroglue = direct.iszeroglue local getglue = direct.getglue local setglue = direct.setglue -function node.iszeroglue(n) return iszeroglue(todirect(n)) end -function node.getglue (n) return getglue (todirect(n)) end -function node.setglue (n) return setglue (todirect(n)) end - -node.family_font = tex.getfontoffamily - --- node.get_glue = node.getglue --- node.set_glue = node.setglue +function node.iszeroglue(n) return iszeroglue(todirect(n)) end +function node.getglue (n) return getglue (todirect(n)) end +function node.setglue (n,...) return setglue (todirect(n),...) end +node.family_font = tex.getfontoffamily diff --git a/tex/context/base/mkxl/node-res.lmt b/tex/context/base/mkxl/node-res.lmt index e023499e5..daf0187e8 100644 --- a/tex/context/base/mkxl/node-res.lmt +++ b/tex/context/base/mkxl/node-res.lmt @@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['node-res'] = { local type, next, rawset = type, next, rawset local gmatch, format = string.gmatch, string.format +local round = math.round --[[ldx-- <p>The next function is not that much needed but in <l n='context'/> we use @@ -381,7 +382,7 @@ function nutpool.outlinerule(width,height,depth,line) -- w/h/d == nil will let t setwhd(n,width,height,depth) end if line then - setruledata(n,line) + setruledata(n,round(line)) -- has to be an integer end return n end diff --git a/tex/context/base/mkxl/spac-chr.lmt b/tex/context/base/mkxl/spac-chr.lmt index 554dc0400..a71c4a0e1 100644 --- a/tex/context/base/mkxl/spac-chr.lmt +++ b/tex/context/base/mkxl/spac-chr.lmt @@ -28,6 +28,9 @@ local nodes, node = nodes, node local nuts = nodes.nuts +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local setsubtype = nuts.setsubtype local getboth = nuts.getboth local getnext = nuts.getnext local getprev = nuts.getprev @@ -37,7 +40,6 @@ local getlanguage = nuts.getlanguage local setchar = nuts.setchar local setattrlist = nuts.setattrlist local getfont = nuts.getfont -local setsubtype = nuts.setsubtype local isglyph = nuts.isglyph local setcolor = nodes.tracers.colors.set @@ -60,10 +62,12 @@ local nodecodes = nodes.nodecodes local gluecodes = nodes.gluecodes local glyph_code = nodecodes.glyph +local glue_code = nodecodes.glue local spaceskip_code = gluecodes.spaceskip local chardata = characters.data -local is_punctuation = characters.is_punctuation +local ispunctuation = characters.is_punctuation +local canhavespace = characters.can_have_space local typesetters = typesetters @@ -182,16 +186,28 @@ local methods = { -- maybe also 0x0008 : backspace + [0x001E] = function(head,current) -- kind of special + local next = getnext(current) + head, current = remove_node(head,current,true) + if next and getid(next) == glue_code and getsubtype(next) == spaceskip_code then + local nextnext = getnext(next) + if nextnext then + local char, font = isglyph(nextnext) + if char and not canhavespace[char] then + remove_node(head,next,true) + end + end + end + end, + [0x001F] = function(head,current) -- kind of special local next = getnext(current) if next then local char, font = isglyph(next) - if char then - head, current = remove_node(head,current,true) - if not is_punctuation[char] then - local p = fontparameters[font] - head, current = insertnodebefore(head,current,new_glue(p.space,p.spacestretch,p.spaceshrink)) - end + head, current = remove_node(head,current,true) + if char and not ispunctuation[char] then + local p = fontparameters[font] + head, current = insertnodebefore(head,current,new_glue(p.space,p.spacestretch,p.spaceshrink)) end end end, diff --git a/tex/context/base/mkxl/spac-chr.mkxl b/tex/context/base/mkxl/spac-chr.mkxl index 82c8be0ec..a7d339019 100644 --- a/tex/context/base/mkxl/spac-chr.mkxl +++ b/tex/context/base/mkxl/spac-chr.mkxl @@ -66,7 +66,8 @@ \popoverloadmode -\immutable\chardef\optionalspace"1F % will be space unless before punctuation +\immutable\chardef\optionalspace "1F % will be space unless before punctuation +\immutable\chardef\autoinsertedspace"1E % a more clever \autoinsertspace % Shortcuts: diff --git a/tex/context/base/mkxl/spac-hor.lmt b/tex/context/base/mkxl/spac-hor.lmt index d32684448..a4a8f0ade 100644 --- a/tex/context/base/mkxl/spac-hor.lmt +++ b/tex/context/base/mkxl/spac-hor.lmt @@ -10,24 +10,14 @@ local chardata = characters.data local peekchar = tokens.scanners.peekchar local ctx_space = context.space -local can_have_space = table.tohash { - "lu", "ll", "lt", "lm", "lo", -- letters - -- "mn", "mc", "me", -- marks - "nd", "nl", "no", -- numbers - "ps", "pi", -- initial - -- "pe", "pf", -- final - -- "pc", "pd", "po", -- punctuation - "sm", "sc", "sk", "so", -- symbols - -- "zs", "zl", "zp", -- separators - -- "cc", "cf", "cs", "co", "cn", -- others -} +local can_have_space = characters.can_have_space interfaces.implement { name = "autoinsertnextspace", protected = true, public = true, actions = function() - local char = peekchar() + local char = peekchar() -- nil means space command if char then local d = chardata[char] if d and can_have_space[d.category] then diff --git a/tex/context/base/mkxl/spac-hor.mkxl b/tex/context/base/mkxl/spac-hor.mkxl index c4c806a40..4c153931b 100644 --- a/tex/context/base/mkxl/spac-hor.mkxl +++ b/tex/context/base/mkxl/spac-hor.mkxl @@ -1073,6 +1073,8 @@ \definehspace[2] [.2222\emwidth] % med \definehspace[3] [.2777\emwidth] % thick +% These will be redefined anyway in math-ini: + \suggestedalias \, \thinspace \suggestedalias \: \medspace \suggestedalias \; \thickspace diff --git a/tex/context/base/mkxl/strc-mat.mkxl b/tex/context/base/mkxl/strc-mat.mkxl index 71676c9ec..90321a627 100644 --- a/tex/context/base/mkxl/strc-mat.mkxl +++ b/tex/context/base/mkxl/strc-mat.mkxl @@ -2010,6 +2010,20 @@ \fi \to \everysetupformula +%D Also new, handy for articles and manuals: + +% \starttext +% \showmakeup[line] +% \input tufte \startformula e = mc^2 \stopformula +% \input tufte \startformula[bodyfont=10pt] e = mc^2 \stopformula +% \input tufte \startformula[bodyfont=24pt] e = mc^2 \stopformula +% \input tufte +% \stoptext + +\prependtoks + \usebodyfontparameter\formulaparameter +\to \everymathematics + \protect \endinput % \abovedisplayshortskip0pt \belowdisplayshortskip0pt \abovedisplayskip0pt \belowdisplayskip0pt \forgetall diff --git a/tex/context/base/mkxl/tabl-tbl.mkxl b/tex/context/base/mkxl/tabl-tbl.mkxl index 851984bea..91ee0262a 100644 --- a/tex/context/base/mkxl/tabl-tbl.mkxl +++ b/tex/context/base/mkxl/tabl-tbl.mkxl @@ -3060,6 +3060,9 @@ %D \stoptabulate %D \stoptyping +% Not okay yet as we loose alignment in later columns .. weird .. do +% we miss a tab? + \installcorenamespace{tabulatespanb} \installcorenamespace{tabulatespana} @@ -3076,7 +3079,9 @@ \noaligned\tolerant\def\tabl_tabulate_NS[#1]#*[#2]% {\NC\loopcs{#1}\tabl_tabulate_span - \gdef\tabl_tabulate_kooh{\begincsname\??tabulatespana#2\endcsname}% + \gdef\tabl_tabulate_kooh + {\begincsname\??tabulatespana#2\endcsname + \glet\tabl_tabulate_kooh\relax}% \begincsname\??tabulatespanb#2\endcsname \ignorepars} % \ignorespaces diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt index e2c79022a..09c0e020c 100644 --- a/tex/context/base/mkxl/trac-vis.lmt +++ b/tex/context/base/mkxl/trac-vis.lmt @@ -41,6 +41,7 @@ local setattr = nuts.setattr local setwidth = nuts.setwidth local setshift = nuts.setshift local setoffsets = nuts.setoffsets +local getglyphdimensions = nuts.getglyphdimensions local getid = nuts.getid local getfont = nuts.getfont @@ -922,22 +923,27 @@ local ruledglyph do -- local ligature_code = 0x8000 + nodes.glyphcodes.ligature ruledglyph = function(head,current,previous) -- wrong for vertical glyphs - local wd = getwidth(current) + local wd, ht, dp = getglyphdimensions(current) if wd ~= 0 then - local wd, ht, dp = getwhd(current) local next = getnext(current) local prev = previous setboth(current) local linewidth = emwidth/(2*fraction) local x_offset, y_offset, l_margin, r_margin, raise = getoffsets(current) - local info = setlink((dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule { - width = wd, - height = ht, - depth = dp, - line = linewidth, - type = "box", - },new_kern(-wd)) - -- if getsubtype(n) == ligature_code then +-- local info = setlink((dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule { +-- width = wd, +-- height = ht, +-- depth = dp, +-- line = linewidth, +-- type = "box", +-- },new_kern(-wd)) +local info = (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule { + width = wd, + height = ht, + depth = dp, + line = linewidth, + type = "box", +} local c, f = isglyph(current) local char = chardata[f][c] if char and type(char.unicode) == "table" then -- hackery test diff --git a/tex/context/base/mkxl/type-imp-euler.mkxl b/tex/context/base/mkxl/type-imp-euler.mkxl index c0a3f73f6..a2e066f6b 100644 --- a/tex/context/base/mkxl/type-imp-euler.mkxl +++ b/tex/context/base/mkxl/type-imp-euler.mkxl @@ -11,6 +11,10 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +% Instead of euler.otf we now use euler-math.otf which is a copy of the version +% that Daniel Flipo maintains now. We will also make an euler-regular.otf for +% text usage (which might have slighty different metrics then). + \loadtypescriptfile[texgyre] \loadtypescriptfile[dejavu] @@ -21,11 +25,11 @@ \starttypescript [\s!serif] [eulernova] [\s!name] \setups[\s!font:\s!fallback:\s!serif] - \definefontsynonym [\s!Serif] [\s!file:euler.otf] [\s!features=\s!default] + \definefontsynonym [\s!Serif] [\s!file:euler-math.otf] [\s!features=\s!default] \stoptypescript \starttypescript [\s!math] [eulernova] [\s!name] - \definefontsynonym [\s!MathRoman] [\s!file:euler.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=euler-math] + \definefontsynonym [\s!MathRoman] [\s!file:euler-math.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=euler-math] \stoptypescript \starttypescript [pagella-eulernova] @@ -47,7 +51,7 @@ \stoptypescript \starttypescript [\s!math] [pagellaovereuler] [\s!name] - \definefontsynonym [\s!MathRoman] [\s!file:euler.otf] [\s!features={\s!math\mathsizesuffix,pagellaovereuler,mathextra},\s!fallbacks=pagellaovereuler,\s!goodies=euler-math] + \definefontsynonym [\s!MathRoman] [\s!file:euler-math.otf] [\s!features={\s!math\mathsizesuffix,pagellaovereuler,mathextra},\s!fallbacks=pagellaovereuler,\s!goodies=euler-math] \stoptypescript \starttypescript [pagella-with-euler,euleroverpagella] diff --git a/tex/context/base/mkxl/type-set.mkxl b/tex/context/base/mkxl/type-set.mkxl index ae07bd914..7eec5cc60 100644 --- a/tex/context/base/mkxl/type-set.mkxl +++ b/tex/context/base/mkxl/type-set.mkxl @@ -31,7 +31,7 @@ \loadfoundtypescriptfile\empty{type-lua.mkxl} \loadfoundtypescriptfile\empty{type-siz.mkxl} \loadfoundtypescriptfile\empty{type-fbk.mkxl} - \loadfoundtypescriptfile\empty{type-imp-latinmodern.mkiv} + \loadfoundtypescriptfile\empty{type-imp-latinmodern.mkiv} % maybe no longer % and not: @@ -54,19 +54,19 @@ \usetypescriptfile[fbk] \usetypescriptfile[lua] \usetypescriptfile[siz] - \usetypescriptfile[latinmodern] + \usetypescriptfile[latinmodern] % maybe no longer \usetypescriptfile[loc] \fi +\definefilesynonym [type-imp-modern.mkiv] [type-imp-latinmodern.mkiv] \definefilesynonym [type-imp-latin-modern.mkiv] [type-imp-latinmodern.mkiv] \definefilesynonym [type-imp-modern-latin.mkiv] [type-imp-modernlatin.mkiv] \definefilesynonym [type-imp-less-modern-latin.mkiv] [type-imp-modernlatin.mkiv] -%definefilesynonym [type-imp-lucida.mkiv] [type-imp-lucida-typeone.mkiv] -\definefilesynonym [type-imp-lucida.mkiv] [type-imp-lucida-opentype.mkiv] -\definefilesynonym [type-imp-lucidaot.mkiv] [type-imp-lucida-opentype.mkiv] -\definefilesynonym [type-imp-lucidadk.mkiv] [type-imp-lucida-opentype.mkiv] +\definefilesynonym [type-imp-lucida-opentype.mkiv] [type-imp-lucida.mkiv] +\definefilesynonym [type-imp-lucidaot.mkiv] [type-imp-lucida.mkiv] +\definefilesynonym [type-imp-lucidadk.mkiv] [type-imp-lucida.mkiv] \definefilesynonym [type-imp-dejavu-condensed.mkiv] [type-imp-dejavu.mkiv] @@ -148,4 +148,24 @@ \definefilesynonym [type-imp-gentiumplus.mkiv] [type-imp-gentium.mkiv] \definefilesynonym [type-imp-gentiumbook.mkiv] [type-imp-gentium.mkiv] +%D These \type {*-nt} variants come in handy when we want top compare with non-tweaked math. + +\definefilesynonym [type-imp-bonum-nt.mkiv] [type-imp-texgyre.mkiv] +\definefilesynonym [type-imp-schola-nt.mkiv] [type-imp-texgyre.mkiv] +\definefilesynonym [type-imp-pagella-nt.mkiv] [type-imp-texgyre.mkiv] +\definefilesynonym [type-imp-termes-nt.mkiv] [type-imp-texgyre.mkiv] +\definefilesynonym [type-imp-dejavu-nt.mkiv] [type-imp-dejavu.mkiv] +\definefilesynonym [type-imp-cambria-nt.mkiv] [type-imp-cambria.mkiv] +\definefilesynonym [type-imp-lucidaot-nt.mkiv] [type-imp-lucida-opentype.mkiv] +\definefilesynonym [type-imp-lucida-nt.mkiv] [type-imp-lucida-opentype.mkiv] +\definefilesynonym [type-imp-modern-nt.mkiv] [type-imp-latinmodern.mkiv] +\definefilesynonym [type-imp-stix-nt.mkiv] [type-imp-stix.mkiv] +\definefilesynonym [type-imp-stixtwo-nt.mkiv] [type-imp-stix.mkiv] +\definefilesynonym [type-imp-libertinus-nt.mkiv] [type-imp-libertinus.mkiv] +\definefilesynonym [type-imp-ebgaramond-nt.mkiv] [type-imp-ebgaramond.mkiv] +\definefilesynonym [type-imp-erewhon-nt.mkiv] [type-imp-erewhon.mkiv] +\definefilesynonym [type-imp-kpfonts-nt.mkiv] [type-imp-kpfonts.mkiv] +\definefilesynonym [type-imp-concrete-nt.mkiv] [type-imp-concrete.mkiv] +\definefilesynonym [type-imp-xcharter-nt.mkiv] [type-imp-xcharter.mkiv] + \protect \endinput diff --git a/tex/context/base/mkxl/typo-chr.lmt b/tex/context/base/mkxl/typo-chr.lmt index 745a35a14..160981ab7 100644 --- a/tex/context/base/mkxl/typo-chr.lmt +++ b/tex/context/base/mkxl/typo-chr.lmt @@ -31,7 +31,7 @@ local flushnode = nodes.flushnode local flushlist = nodes.flushlist local settexattribute = tex.setattribute -local punctuation = characters.is_punctuation +local ispunctuation = characters.is_punctuation local variables = interfaces.variables local v_all = variables.all @@ -51,7 +51,7 @@ local function pickup() local list = texgetnest() if list then local tail = list.tail - if tail and tail.id == glyph_code and punctuation[tail.char] then + if tail and tail.id == glyph_code and ispunctuation[tail.char] then local prev = tail.prev list.tail = prev if prev then diff --git a/tex/context/base/mkxl/typo-itc.lmt b/tex/context/base/mkxl/typo-itc.lmt index f0b6980f4..c26d4a824 100644 --- a/tex/context/base/mkxl/typo-itc.lmt +++ b/tex/context/base/mkxl/typo-itc.lmt @@ -72,7 +72,7 @@ local italicsdata = fonthashes.italics local exheights = fonthashes.exheights local chardata = fonthashes.characters -local is_punctuation = characters.is_punctuation +local ispunctuation = characters.is_punctuation local implement = interfaces.implement @@ -217,7 +217,7 @@ local function domath(head,current) if glyph and getid(glyph) == glyph_code then -- [math: <glyph><kern>]<glyph> : we remove the correction when we have -- punctuation - if is_punctuation[char] then + if ispunctuation[char] then local a = getattr(glyph,a_mathitalics) if a then local i = getkern(kern) @@ -257,7 +257,7 @@ local function domath(head,current) -- if glyph and getid(glyph) == glyph_code then -- -- [math: <glyph>]<glyph> : we add the correction when we have -- -- no punctuation - -- if not is_punctuation[char] then + -- if not ispunctuation[char] then -- local a = getattr(glyph,a_mathitalics) -- if a and (a < 100 or a > 100) then -- if a > 100 then |