From 6032373f72b7980d5b197eb371f1d56ecb800ee8 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Tue, 5 Jan 2021 11:45:00 +0100 Subject: 2021-01-05 10:44:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-nl.mkii | 1 + tex/context/base/mkiv/cldf-ini.lua | 1 - tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-con.lua | 16 +- tex/context/base/mkiv/font-imp-italics.lua | 18 - tex/context/base/mkiv/font-imp-math.lua | 22 + tex/context/base/mkiv/font-pre.mkiv | 6 + tex/context/base/mkiv/font-tfm.lua | 13 +- tex/context/base/mkiv/good-mth.lua | 2 +- tex/context/base/mkiv/math-ali.mkiv | 1 + tex/context/base/mkiv/math-fbk.lua | 12 +- tex/context/base/mkiv/math-ttv.lua | 2 +- tex/context/base/mkiv/math-vfu.lua | 9 +- tex/context/base/mkiv/mtx-context-compare.tex | 10 +- tex/context/base/mkiv/mult-prm.lua | 2 + tex/context/base/mkiv/status-files.pdf | Bin 26481 -> 26485 bytes tex/context/base/mkiv/status-lua.pdf | Bin 253845 -> 253534 bytes tex/context/base/mkxl/cont-log.mkxl | 3 +- tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 2 +- tex/context/base/mkxl/font-con.lmt | 43 +- tex/context/base/mkxl/font-ctx.lmt | 7 +- tex/context/base/mkxl/font-glf.mklx | 130 +-- tex/context/base/mkxl/font-imp-math.lmt | 82 +- tex/context/base/mkxl/font-ini.mklx | 182 +++- tex/context/base/mkxl/font-mat.mklx | 97 +- tex/context/base/mkxl/font-ots.lmt | 108 +- tex/context/base/mkxl/font-pre.mkxl | 67 +- tex/context/base/mkxl/lpdf-lmt.lmt | 2 - tex/context/base/mkxl/math-ali.mkxl | 1 + tex/context/base/mkxl/math-ini.mkxl | 2 +- tex/context/base/mkxl/math-noa.lmt | 10 +- tex/context/base/mkxl/math-vfu.lmt | 1148 ++++++++++++++++++++ tex/context/base/mkxl/typo-cap.lmt | 19 + tex/context/fonts/mkiv/type-imp-modernlatin.mkiv | 4 +- tex/context/fonts/mkiv/type-imp-texgyre.mkiv | 16 +- tex/context/interface/mkii/keys-nl.xml | 1 + tex/generic/context/luatex/luatex-fonts-merged.lua | 5 +- 41 files changed, 1682 insertions(+), 372 deletions(-) create mode 100644 tex/context/base/mkxl/math-vfu.lmt (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 9343bef06..a466ff87a 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2020.12.30 16:42} +\newcontextversion{2021.01.05 10:41} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 630e02b76..063d2e462 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2020.12.30 16:42} +\edef\contextversion{2021.01.05 10:41} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii index 03cedd1cd..7bf09dd57 100644 --- a/tex/context/base/mkii/mult-nl.mkii +++ b/tex/context/base/mkii/mult-nl.mkii @@ -1131,6 +1131,7 @@ \setinterfaceconstant{reference}{referentie} \setinterfaceconstant{referencemethod}{referencemethod} \setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencetext}{referencetext} \setinterfaceconstant{referencing}{refereren} \setinterfaceconstant{region}{gebied} \setinterfaceconstant{regionin}{gebiedin} diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua index 77391580f..bb5a058a5 100644 --- a/tex/context/base/mkiv/cldf-ini.lua +++ b/tex/context/base/mkiv/cldf-ini.lua @@ -419,7 +419,6 @@ local registerscanner if CONTEXTLMTXMODE > 0 then end end - registerscanner = function(name,action,specification) rawset(interfacescanners,name,action) local n = registerfunction("interfaces.scanners."..name,true,storedscanners[name]) diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index c234af299..dff51fd71 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2020.12.30 16:42} +\newcontextversion{2021.01.05 10:41} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index b7a0b6f8d..8e9dda9c3 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2020.12.30 16:42} +\edef\contextversion{2021.01.05 10:41} %D Kind of special: diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua index 7162338c6..f650e5b03 100644 --- a/tex/context/base/mkiv/font-con.lua +++ b/tex/context/base/mkiv/font-con.lua @@ -600,13 +600,17 @@ function constructors.scale(tfmdata,specification) -- if hasmath then constructors.assignmathparameters(target,tfmdata) -- does scaling and whatever is needed - properties.hasmath = true - target.nomath = false - target.MathConstants = target.mathparameters + properties.hasmath = true + target.nomath = false + target.MathConstants = target.mathparameters + -- + local oldmath = properties.oldmath + targetproperties.oldmath = oldmath + target.oldmath = oldmath else - properties.hasmath = false - target.nomath = true - target.mathparameters = nil -- nop + properties.hasmath = false + target.nomath = true + target.mathparameters = nil -- nop end -- -- Here we support some context specific trickery (this might move to a plugin). During the diff --git a/tex/context/base/mkiv/font-imp-italics.lua b/tex/context/base/mkiv/font-imp-italics.lua index 3e172bede..6c432d7cf 100644 --- a/tex/context/base/mkiv/font-imp-italics.lua +++ b/tex/context/base/mkiv/font-imp-italics.lua @@ -79,24 +79,6 @@ if context then registerotffeature(specification) registerafmfeature(specification) - -- no longer used - - -- local function initializemathitalics(tfmdata,value) -- yes no delay - -- tfmdata.properties.mathitalics = toboolean(value) - -- end - -- - -- local specification = { - -- name = "mathitalics", - -- description = "use alternative math italic correction", - -- initializers = { - -- base = initializemathitalics, - -- node = initializemathitalics, - -- } - -- } - -- - -- registerotffeature(specification) - -- registerafmfeature(specification) - -- only used when testing local letter = characters.is_letter diff --git a/tex/context/base/mkiv/font-imp-math.lua b/tex/context/base/mkiv/font-imp-math.lua index d93ece405..ed82fcc48 100644 --- a/tex/context/base/mkiv/font-imp-math.lua +++ b/tex/context/base/mkiv/font-imp-math.lua @@ -79,3 +79,25 @@ registerotffeature { node = initialize, } } + +local function initialize(tfmdata,key,value) + if value then + local rawdata = tfmdata.shared.rawdata + local rawresources = rawdata and rawdata.resources + local mathconstants = rawresources.mathconstants + if mathconstants then + tfmdata.properties.oldmath = true + end + end +end + +local specification = { + name = "oldmath", + description = "deal with fake opentype fonts", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) diff --git a/tex/context/base/mkiv/font-pre.mkiv b/tex/context/base/mkiv/font-pre.mkiv index 19d4f3f7e..c32690375 100644 --- a/tex/context/base/mkiv/font-pre.mkiv +++ b/tex/context/base/mkiv/font-pre.mkiv @@ -409,6 +409,12 @@ language=dflt, script=math] +% Users can define this: +% +% \definefontfeature +% [oldmath] +% [oldmath=yes] + \ifdefined\mathnolimitsmode \mathnolimitsmode\plusone % font driven (only opentype) \fi diff --git a/tex/context/base/mkiv/font-tfm.lua b/tex/context/base/mkiv/font-tfm.lua index 63f3276b1..4dbd5fc66 100644 --- a/tex/context/base/mkiv/font-tfm.lua +++ b/tex/context/base/mkiv/font-tfm.lua @@ -150,7 +150,6 @@ local function read_from_tfm(specification) features.pfbfile = pfbfile end end - local newtfmdata = (depth[filename] == 1) and tfm.reencode(tfmdata,specification) if newtfmdata then tfmdata = newtfmdata @@ -443,7 +442,7 @@ do local characters = { } local originals = tfmdata.characters local indices = { } - local parentfont = { "font", 1 } + local parentfont = { "font", 1 } -- can be zero (self referencing) local private = tfmdata.privateoffset or constructors.privateoffset local reported = encdone[tfmfile][encfile] -- bah, encdone for tfm or pfb ? -- create characters table @@ -451,6 +450,14 @@ do -- vector : pfbindex -> name -- encoding : tfmindex -> name + -- we store the order also because some tex encodings (see math-vfu) needs + -- that for remapping with non standard glyphs names cq. lack of unicode + -- slot information + + for k, v in next, originals do + v.order = k + end + local backmap = vector and table.swapped(vector) local done = { } -- prevent duplicate for tfmindex, name in sortedhash(encoding) do -- predictable order @@ -462,7 +469,7 @@ do else unicode = private private = private + 1 - if not reported then + if trace_defining and not reported then report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) end end diff --git a/tex/context/base/mkiv/good-mth.lua b/tex/context/base/mkiv/good-mth.lua index 18a97976f..b85e680cc 100644 --- a/tex/context/base/mkiv/good-mth.lua +++ b/tex/context/base/mkiv/good-mth.lua @@ -58,7 +58,7 @@ local function initialize(goodies) local maplines = mathgoodies.maplines if virtuals then for name, specification in next, virtuals do - -- beware, they are all constructed + -- beware, they are all constructed ... we should be more selective mathematics.makefont(name,specification,goodies) end end diff --git a/tex/context/base/mkiv/math-ali.mkiv b/tex/context/base/mkiv/math-ali.mkiv index 0ce9ee6d0..e617224d2 100644 --- a/tex/context/base/mkiv/math-ali.mkiv +++ b/tex/context/base/mkiv/math-ali.mkiv @@ -61,6 +61,7 @@ {\ifnum\scratchcounter=\scratchcountertwo \scratchcounter\plusone \etoksapp\scratchtoks{\math_eqalign_distance}% + \etoksapp\scratchtoks{\global\c_math_eqalign_column\zerocount}% \else \advance\scratchcounter\plusone \fi diff --git a/tex/context/base/mkiv/math-fbk.lua b/tex/context/base/mkiv/math-fbk.lua index 963461de5..6b43a901b 100644 --- a/tex/context/base/mkiv/math-fbk.lua +++ b/tex/context/base/mkiv/math-fbk.lua @@ -53,13 +53,15 @@ function fallbacks.apply(target,original) -- we also have forcedsize ... at this moment we already passed through -- constructors.scale so we have this set local parameters = target.parameters + local properties = target.properties local mathsize = parameters.mathsize if mathsize < 1 or mathsize > 3 then return end - local characters = target.characters - local size = parameters.size - local usedfonts = target.fonts + local characters = target.characters + local size = parameters.size + local usedfonts = target.fonts + local compactmath = properties.compactmath if not usedfonts then usedfonts = { { id = 0 } } -- we need at least one entry (automatically done anyway) target.fonts = usedfonts @@ -91,6 +93,10 @@ function fallbacks.apply(target,original) else textdata = target end + if compactmath then + scriptid = textid + scriptscriptid = textid + end if scriptid and scriptid ~= 0 then scriptindex = #usedfonts + 1 scriptdata = identifiers[scriptid] diff --git a/tex/context/base/mkiv/math-ttv.lua b/tex/context/base/mkiv/math-ttv.lua index 1f644e788..151183212 100644 --- a/tex/context/base/mkiv/math-ttv.lua +++ b/tex/context/base/mkiv/math-ttv.lua @@ -62,7 +62,7 @@ mathencodings["large-to-small"] = { } -- Beware: these are (in cm/lm) below the baseline due to limitations --- in the tfm format bu the engien (combined with the mathclass) takes +-- in the tfm format but the engine (combined with the mathclass) takes -- care of it. If we need them in textmode, we should make them virtual -- and move them up but we're in no hurry with that. diff --git a/tex/context/base/mkiv/math-vfu.lua b/tex/context/base/mkiv/math-vfu.lua index c7079caca..627f85e57 100644 --- a/tex/context/base/mkiv/math-vfu.lua +++ b/tex/context/base/mkiv/math-vfu.lua @@ -628,10 +628,6 @@ setmetatableindex(reverse, function(t,name) return r end) --- use char and font hash --- --- commands = { { "font", slot }, { "char", unicode } }, - local function copy_glyph(main,target,original,unicode,slot) local addprivate = fonts.helpers.addprivate local olddata = original[unicode] @@ -851,10 +847,8 @@ function vfmath.define(specification,set,goodies) main.fullname = properties.fullname main.nomath = false -- -if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then properties.virtualized = true main.type = "virtual" -end -- parameters.x_height = parameters.x_height or 0 -- @@ -1114,7 +1108,8 @@ end -- so better is to also reserve the id already which then involves some more -- management (so not now). fontlist[#fontlist+1] = { - id = font.nextid(), + -- id = font.nextid(), + id = 0, -- self size = size, } vfmath.addmissing(main,#fontlist,size) diff --git a/tex/context/base/mkiv/mtx-context-compare.tex b/tex/context/base/mkiv/mtx-context-compare.tex index ffa744013..c940270c8 100644 --- a/tex/context/base/mkiv/mtx-context-compare.tex +++ b/tex/context/base/mkiv/mtx-context-compare.tex @@ -24,17 +24,17 @@ \starttext \starttexdefinition unexpanded ShowBoth #1#2#3 - \startTEXpage + \startTEXpage[width=21cm] \startoverlay - {\externalfigure[#1][page=#3]} - {\externalfigure[#2][page=#3]} + {\externalfigure[#1][page=#3,width=21cm]} + {\externalfigure[#2][page=#3,width=21cm]} \stopoverlay \stopTEXpage \stoptexdefinition \starttexdefinition unexpanded ShowPage #1#2 - \startTEXpage - \externalfigure[#1][page=#2] + \startTEXpage[width=21cm] + \externalfigure[#1][page=#2,width=21cm] \stopTEXpage \stoptexdefinition diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index a62c43db7..f25625a9f 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -80,6 +80,7 @@ return { "Uhextensible", "Uleft", "Umathaccent", + "Umathaccentbaseheight", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", @@ -299,6 +300,7 @@ return { "gluespecdef", "glyphdatafield", "glyphoptions", + "glyphscale", "glyphscriptfield", "glyphstatefield", "glyphxoffset", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index a258dd735..6f1f7acfe 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index ef505e334..2e51acc39 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkxl/cont-log.mkxl b/tex/context/base/mkxl/cont-log.mkxl index 1bb48f0b2..d2d8e0e4f 100644 --- a/tex/context/base/mkxl/cont-log.mkxl +++ b/tex/context/base/mkxl/cont-log.mkxl @@ -187,7 +187,8 @@ %D Some placeholders: -\frozen\instance\protected\def\eTeX {\mathematics{\varepsilon}-\TeX} +%frozen\instance\protected\def\eTeX {\mathematics{\varepsilon}-\TeX} +\frozen\instance\protected\def\eTeX {{\tf \nocap $\varepsilon$}-\TeX} % compact mode hack for epsilon \frozen\instance\protected\def\pdfTeX {pdf\wordboundary\TeX} \frozen\instance\protected\def\pdfeTeX {pdfe-\wordboundary\TeX} \frozen\instance\protected\def\luaTeX {lua\wordboundary\TeX} diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index d18fc6867..0fae7c684 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{2020.12.30 16:42} +\newcontextversion{2021.01.05 10:41} %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 9b69a436c..8c6701d81 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{2020.12.30 16:42} +\immutable\edef\contextversion{2021.01.05 10:41} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/font-con.lmt b/tex/context/base/mkxl/font-con.lmt index 248bf9ec0..88e17290a 100644 --- a/tex/context/base/mkxl/font-con.lmt +++ b/tex/context/base/mkxl/font-con.lmt @@ -477,23 +477,40 @@ function constructors.scale(tfmdata,specification) -- if hasmath then constructors.assignmathparameters(target,tfmdata) -- does scaling and whatever is needed - properties.hasmath = true - target.nomath = false - target.MathConstants = target.mathparameters - target.compactmath = true - target.textscale = parameters.textscale - target.scriptscale = parameters.scriptscale - target.scriptscriptscale = parameters.scriptscriptscale + properties.hasmath = true + target.nomath = false + target.MathConstants = target.mathparameters - targetparameters.textscale = parameters.textscale - targetparameters.scriptscale = parameters.scriptscale - targetparameters.scriptscriptscale = parameters.scriptscriptscale + properties.compactmath = true + target.compactmath = true + + local textscale = parameters.textscale -- or 1000 + local scriptscale = parameters.scriptscale -- or 700 + local scriptscriptscale = parameters.scriptscriptscale -- or 500 + + parameters.textscale = textscale + parameters.scriptscale = scriptscale + parameters.scriptscriptscale = scriptscriptscale + + target.textscale = textscale + target.scriptscale = scriptscale + target.scriptscriptscale = scriptscriptscale + + targetparameters.textscale = textscale + targetparameters.scriptscale = scriptscale + targetparameters.scriptscriptscale = scriptscriptscale + + -- todo: maybe retrofit to font-con.lua + + local oldmath = properties.oldmath + targetproperties.oldmath = oldmath + target.oldmath = oldmath else - properties.hasmath = false - target.nomath = true - target.mathparameters = nil -- nop + properties.hasmath = false + target.nomath = true + target.mathparameters = nil -- nop end -- -- During the transition to opentype the engine had troubles with italics so we had some diff --git a/tex/context/base/mkxl/font-ctx.lmt b/tex/context/base/mkxl/font-ctx.lmt index 8d4cfa05d..b316bcc0a 100644 --- a/tex/context/base/mkxl/font-ctx.lmt +++ b/tex/context/base/mkxl/font-ctx.lmt @@ -1628,7 +1628,12 @@ function constructors.calculatescale(tfmdata,scaledpoints,relativeid,specificati if scaledpoints < 0 then scaledpoints = (- scaledpoints/1000) * (tfmdata.designsize or parameters.designsize) -- already in sp end - return round(scaledpoints), round(scaledpoints/units) -- delta + -- a temp hack till we have upgraded all mechanisms + local delta = round(scaledpoints/units) + local size = round(scaledpoints) + texsetcount("c_font_scaled_points",size) + -- + return size, delta end local designsizes = constructors.designsizes diff --git a/tex/context/base/mkxl/font-glf.mklx b/tex/context/base/mkxl/font-glf.mklx index 125acb29b..ba950feea 100644 --- a/tex/context/base/mkxl/font-glf.mklx +++ b/tex/context/base/mkxl/font-glf.mklx @@ -46,128 +46,14 @@ \c!xscale=\scaledfontparameter\c!scale, \c!yscale=\scaledfontparameter\c!scale] -\installcorenamespace{scaledfontbody} - -\permanent\protected\def\definescaledfontbody[#1]#*[#2]% only for testing - {%\expandafter\integerdef\csname\??scaledfontbody#1\endcsname\integerdef\bodyglyphscale\numericscale#2\relax - \frozen\protected\defcsname#1\endcsname% - {\integerdef\bodyglyphscale\numericscale#2\relax - \glyphxscale\bodyglyphscale - \glyphyscale\bodyglyphscale - \the\everybodyfont}} - -\def\font_helpers_set_glyph_scale_by_size#fontsize% gets character (x xx a etc) - {\glyphxscale\numexpr\numericscale - \ifcsname\??fontenvironments\fontclass\fontbody#fontsize\endcsname - \lastnamedcs - \orelse\ifcsname\??fontenvironments\fontclass\s!default#fontsize\endcsname - \lastnamedcs - \orelse\ifcsname\??fontenvironments\fontbody#fontsize\endcsname - \lastnamedcs - \orelse\ifcsname\??fontenvironments\s!default#fontsize\endcsname - \lastnamedcs - \orelse\ifcsname\??fontenvironments\fontclass\s!default\s!text\endcsname - \lastnamedcs - \orelse\ifcsname\??fontenvironments\s!default\s!text\endcsname - \lastnamedcs - \else - \plusthousand - \fi*\bodyglyphscale/\plusthousand\relax - \glyphyscale\glyphxscale} - -% \protected\def\font_helpers_set_current_font_alternative_size#alternative#size% \sla -% {\edef\fontalternative{#alternative}% -% \edef\fontsize {#size}% -% \font_helpers_check_big_math_synchronization % double? better in everymath? -% \font_helpers_synchronize_font} - -\protected\def\font_helpers_set_current_font_alternative_size_g#alternative#size% \sla - {\edef\fontalternative{#alternative}% - \edef\fontsize{#size}% - \csname\fontalternative\endcsname - \font_helpers_set_glyph_scale_by_size\fontsize - \ifskipfontcharacteristics - \setfontcharacteristics - \the\everyfontswitch - \fi} - -% \protected\def\font_helpers_set_current_font_size#size% -% {\edef\fontsize{#size}% -% \font_helpers_check_big_math_synchronization % double? better in everymath? -% \font_helpers_synchronize_font} - -\protected\def\font_helpers_set_current_font_size_g#size% - {\edef\fontsize{#size}% - \font_helpers_set_glyph_scale_by_size\fontsize - \ifskipfontcharacteristics - \setfontcharacteristics - \the\everyfontswitch - \fi} - -% \protected\def\font_helpers_set_current_font_style_size#style#size% \rma -% {\edef\fontstyle{#style}% -% \edef\fontsize {#size}% -% \font_helpers_check_big_math_synchronization % double? better in everymath? -% \font_helpers_synchronize_font} - -\protected\def\font_helpers_set_current_font_style_size_g#style#size% \rma - {\edef\fontstyle{#style}% - \edef\fontsize{#size}% - \csname\fontstyle\endcsname - \font_helpers_set_glyph_scale_by_size\fontsize - \ifskipfontcharacteristics - \setfontcharacteristics - \the\everyfontswitch - \fi} - -% \protected\def\font_helpers_set_current_font_style_alternative_size#style#alternative#size% \rmsla -% {\edef\fontstyle {#style}% -% \edef\fontalternative{#alternative}% -% \edef\fontsize {#size}% -% \font_helpers_check_big_math_synchronization % double? better in everymath? -% \font_helpers_synchronize_font} - -\protected\def\font_helpers_set_current_font_style_alternative_size_g#style#alternative#size% \rmsla - {\edef\fontstyle{#style}% - \edef\fontalternative{#alternative}% - \edef\fontsize{#size}% - \csname\fontstyle\endcsname - \csname\fontalternative\endcsname - \font_helpers_set_glyph_scale_by_size\fontsize - \ifskipfontcharacteristics - \setfontcharacteristics - \the\everyfontswitch - \fi} - -% \def\font_helpers_set_current_font_xxx_alternative#alternative#xsize#scriptstyle% -% {\ifmmode -% #scriptstyle% -% \else -% \font_helpers_set_current_xsize_alternative{#xsize}{#alternative}% -% \fi} - -\def\font_helpers_set_current_font_xxx_alternative_g#alternative#xsize#scriptstyle% - {\ifmmode - #scriptstyle% - \else - \csname#alternative\endcsname - \font_helpers_set_glyph_scale_by_size{#alternative}% - \ifskipfontcharacteristics - \setfontcharacteristics - \fi - \fi} - -% \newtoks\everyenableautoglyphscaling -% -% \permanent\protected\def\enableautoglyphscaling -% {\the\everyenableautoglyphscaling} +% \installcorenamespace{scaledfontbody} % -% \appendtoks -% \let\font_helpers_set_current_font_alternative_size \font_helpers_set_current_font_alternative_size_g -% \let\font_helpers_set_current_font_size \font_helpers_set_current_font_size_g -% \let\font_helpers_set_current_font_style_size \font_helpers_set_current_font_style_size_g -% \let\font_helpers_set_current_font_style_alternative_size\font_helpers_set_current_font_style_alternative_size_g -% \let\font_helpers_set_current_font_xxx_alternative \font_helpers_set_current_font_xxx_alternative_g -% \to \everyenableautoglyphscaling +% \permanent\protected\def\definescaledfontbody[#1]#*[#2]% only for testing +% {%\expandafter\integerdef\csname\??scaledfontbody#1\endcsname\integerdef\bodyglyphscale\numericscale#2\relax +% \frozen\protected\defcsname#1\endcsname% +% {\integerdef\bodyglyphscale\numericscale#2\relax +% \glyphxscale\bodyglyphscale +% \glyphyscale\bodyglyphscale +% \the\everybodyfont}} \protect \endinput diff --git a/tex/context/base/mkxl/font-imp-math.lmt b/tex/context/base/mkxl/font-imp-math.lmt index 664a0c147..47fcf344c 100644 --- a/tex/context/base/mkxl/font-imp-math.lmt +++ b/tex/context/base/mkxl/font-imp-math.lmt @@ -6,7 +6,6 @@ if not modules then modules = { } end modules ['font-imp-math'] = { license = "see context related readme files" } - local next, type, tonumber = next, type, tonumber local fonts = fonts @@ -15,20 +14,6 @@ local registerotffeature = fonts.handlers.otf.features.register local setmetatableindex = table.setmetatableindex --- requested for latex but not supported unless really needed in context: --- --- registerotffeature { --- name = "ignoremathconstants", --- description = "ignore math constants table", --- initializers = { --- base = function(tfmdata,value) --- if value then --- tfmdata.mathparameters = nil --- end --- end --- } --- } - -- tfmdata.properties.mathnolimitsmode = tonumber(value) or 0 local splitter = lpeg.splitat(",",tonumber) @@ -66,6 +51,8 @@ registerotffeature { } } +-- this will become a mode in the engine + local function initialize(tfmdata,value) tfmdata.properties.nostackmath = value and true end @@ -82,12 +69,13 @@ registerotffeature { -- A quick and dirty and low level implementation but okay for testing: local function manipulate(tfmdata,key,value) - if value then + if tex.conditionals["c_font_compact"] then local rawdata = tfmdata.shared.rawdata local rawresources = rawdata and rawdata.resources local rawfeatures = rawresources and rawresources.features local basesubstitutions = rawfeatures and rawfeatures.gsub local sequences = basesubstitutions and tfmdata.resources.sequences + if sequences then local characters = tfmdata.characters for s=1,#sequences do @@ -122,21 +110,19 @@ local function manipulate(tfmdata,key,value) end local function initialize(tfmdata,key,value) - if value then + if tex.conditionals["c_font_compact"] then local rawdata = tfmdata.shared.rawdata local rawresources = rawdata and rawdata.resources local mathconstants = rawresources.mathconstants if mathconstants then local parameters = tfmdata.parameters - -- will become configurable: 1000 = 100% - parameters.textscale = 1000 -- math_scale_identity + parameters.textscale = 1000 parameters.scriptscale = mathconstants.ScriptPercentScaleDown * 10 parameters.scriptscriptscale = mathconstants.ScriptScriptPercentScaleDown * 10 end end end - local specification = { name = "compactmath", description = "use one math font", @@ -151,3 +137,59 @@ local specification = { } registerotffeature(specification) + +-- The problem is that the traditional code path doesn't add an italic to the subscript, +-- simply because it assumes that the width has that already subtracted. So, we cannot +-- compensate in the following way. We're stuck with the fact that the texgyre fonts +-- assume a traditional tex engine. + +-- local function manipulate(tfmdata,key,value) +-- if value == "correct" then +-- local chardata = characters.data +-- for unicode, data in next, tfmdata.characters do +-- local italic = data.italic +-- if italic then +-- -- todo: only letters +-- data.width = (data.width or 0) + italic +-- local cd = chardata[unicode] +-- if cd then +-- local visual = cd.visual +-- if visual == "it" or visual == "bi" then +-- italic = -italic +-- else +-- italic = 0 +-- end +-- else +-- italic = 0 +-- end +-- data.italic = italic +-- end +-- end +-- end +-- end + +local function initialize(tfmdata,key,value) + if value then + local rawdata = tfmdata.shared.rawdata + local rawresources = rawdata and rawdata.resources + local mathconstants = rawresources.mathconstants + if mathconstants then + tfmdata.properties.oldmath = true + end + end +end + +local specification = { + name = "oldmath", + description = "deal with fake opentype fonts", + -- manipulators = { + -- base = manipulate, + -- node = manipulate, + -- }, + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) diff --git a/tex/context/base/mkxl/font-ini.mklx b/tex/context/base/mkxl/font-ini.mklx index b186b8a02..bb5050527 100644 --- a/tex/context/base/mkxl/font-ini.mklx +++ b/tex/context/base/mkxl/font-ini.mklx @@ -685,7 +685,124 @@ \newconditional\c_font_body_scale \newfraction \f_font_body_scale -\protected\def\font_helpers_low_level_define#specification#csname% +\newconditional\c_font_compact +\newcount \c_font_scaled_glyph_scale + +\immutable\dimensiondef\d_font_scaled_default 10pt + +\newcount\c_font_future_glyph_scale + +% todo: move all to lua: use localcall for resolving filename + +\newcount\c_font_future_glyph_scale +\newcount\c_font_scaled_font_mode_saved +\newcount\c_font_scaled_points + +\protected\def\font_helpers_low_level_define + {\ifconditional\c_font_compact + \expandafter\font_helpers_low_level_define_compact + \else + \expandafter\font_helpers_low_level_define_normal + \fi} + +\protected\def\font_helpers_low_level_define_normal#specification#csname% + {% we can now set more at the lua end + \glet\somefontname\defaultfontfile + \let\somefontsize\empty + \clf_definefont_one{\detokenize\expandafter{\normalexpanded{#specification}}}% the escapestring catches at \somedimen + % sets \scaledfontmode and \somefontname and \somefontsize + \ifcase\fontface\relax + % \let\v_font_size_absolute\textface % fontbody + \or + \let\v_font_size_absolute\textface + \or + \let\v_font_size_absolute\scriptface + \or + \let\v_font_size_absolute\scriptscriptface + \or + \let\v_font_size_absolute\xtextface + \or + \let\v_font_size_absolute\xxtextface + \fi + % + \ifcase\scaledfontmode\relax + % none, avoid the designsize if possible + \d_font_scaled_font_size-\plusthousand\scaledpoint + \or + % at + \d_font_scaled_font_size\somefontsize + \or + % sa + \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 + \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 + % scaled, don't use this one as it's unpredictable + \d_font_scaled_font_size-\somefontsize\scaledpoint + \else % ht cp + % experiment, yet undocumented + \d_font_scaled_font_size\somefontsize + \fi + \relax + \d_font_scaled_font_size\v_font_size_relative\d_font_scaled_font_size + \relax + % + \ifconditional\c_font_auto_size + \font_helpers_check_body_scale\fontsize + \ifconditional\c_font_body_scale + \d_font_scaled_font_size\f_font_body_scale\d_font_scaled_font_size + \d_font_scaled_text_face\f_font_body_scale\dimexpr\textface\relax + \else + \d_font_scaled_font_size\f_font_body_scale + \d_font_scaled_text_face\textface + \fi + \else + \d_font_scaled_text_face\textface + \fi + % + \edef\somefontspec{at \number\d_font_scaled_font_size sp}% + \edef\somefontfile{\truefontname\somefontname}% + \ifx\somefontfile\s!unknown + \edef\somefontfile{\defaultfontfile}% + \fi + \font_helpers_update_font_parameters + \font_helpers_update_font_class_parameters + %\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}% + \clf_definefont_two + \ifempty\fontclass\s!false\else\s!true\fi + {#csname}% + {\somefontfile}% + \d_font_scaled_font_size + \c_font_feature_inheritance_mode + {\m_font_class_features}% + {\m_font_features}% + {\m_font_class_fallbacks}% + {\m_font_fallbacks}% + \fontface + \d_font_scaled_text_face + \relativefontid + {\m_font_class_goodies}% + {\m_font_goodies}% + {\m_font_class_designsize}% + {\m_font_designsize}% + \scaledfontmode + \relax + \ifcase\scaledfontsize + %\scaledfontsize\plusone + \let\somefontspec\empty + \let\lastrawfontcall\relax + \letcsname#csname\endcsname\relax + \else + \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks) + \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname + \the\everydefinefont + \fi + \c_font_feature_inheritance_mode\c_font_feature_inheritance_default} + +\protected\def\font_helpers_low_level_define_compact#specification#csname% {% we can now set more at the lua end \glet\somefontname\defaultfontfile \let\somefontsize\empty @@ -728,6 +845,8 @@ \fi \relax \d_font_scaled_font_size\v_font_size_relative\d_font_scaled_font_size + \relax + % \ifconditional\c_font_auto_size \font_helpers_check_body_scale\fontsize \ifconditional\c_font_body_scale @@ -740,13 +859,26 @@ \else \d_font_scaled_text_face\textface \fi + % + \ifnum\c_font_scaled_font_mode_saved>\plusfour + \c_font_scaled_font_mode_saved\scaledfontmode + \scaledfontmode\zerocount + \fi + \c_font_future_glyph_scale\numexpr\plushundred*\d_font_scaled_font_size/\maxcard\relax + \glyphscale\numexpr\plushundred*\d_font_scaled_font_size/\maxcard\relax % needed ? for math i guess +% \glyphscale\plusthousand + \d_font_scaled_font_size\d_font_scaled_default + \d_font_scaled_text_face\d_font_scaled_default + % \edef\somefontspec{at \number\d_font_scaled_font_size sp}% + % this has to happen at the tex end ... \edef\somefontfile{\truefontname\somefontname}% \ifx\somefontfile\s!unknown \edef\somefontfile{\defaultfontfile}% \fi \font_helpers_update_font_parameters \font_helpers_update_font_class_parameters + % ... till here %\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}% \clf_definefont_two \ifempty\fontclass\s!false\else\s!true\fi @@ -774,6 +906,18 @@ \letcsname#csname\endcsname\relax \else \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks) + % + \ifnum\c_font_scaled_font_mode_saved>\plusfour + \glyphscale\numexpr\plusthousand*\dimexpr\d_font_scaled_font_size\relax/\c_font_scaled_points\relax + \else + \glyphscale\c_font_future_glyph_scale + \fi + % actually this has to happen elsewhere .. temp hack (do we know here if we are global?) + \gletcsname\??frozenfont#csname\expandafter\endcsname\csname#csname\endcsname + \protected\xdefcsname#csname\endcsname + {\csname\??frozenfont#csname\endcsname + \glyphscale\the\glyphscale\relax}% + % \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname \the\everydefinefont \fi @@ -907,14 +1051,28 @@ %D Beware, in the frozen variants no settings are supported yet, but that might happen %D some day. +\installcorenamespace{frozenfont} +%installcorenamespace{frozensize} + +\newcount\c_last_global_glyph_scale + \permanent\tolerant\protected\def\definefrozenfont[#name]#spacer[#specification]#spacer[#settings]% {\ifparameter#name\or \begingroup - \definefont[#name][#specification][#settings]% - \csname#name\endcsname - \glet\lastglobalrawfontcall\lastrawfontcall + \definefont[#name][#specification][#settings]% + \csname#name\endcsname + \glet\lastglobalrawfontcall\lastrawfontcall + \global\c_last_global_glyph_scale\glyphscale \endgroup - \letcsname#name\endcsname\lastglobalrawfontcall + \ifconditional\c_font_compact + % temp hack + \letcsname\??frozenfont#name\endcsname\lastglobalrawfontcall + \protected\edefcsname#name\endcsname + {\csname\??frozenfont#name\endcsname + \glyphscale\the\c_last_global_glyph_scale\relax}% + \else + \letcsname#name\endcsname\lastglobalrawfontcall + \fi \fi} %D The instance namespace protection makes the switch local so that we can redefine a @@ -1051,7 +1209,7 @@ %D \item smaller and even more smaller alternatives (super- and subscripts) %D \stopitemize %D -%D \TEX\ offers a powerfull family mechanism for super- and subscripts in math mode. +%D \TEX\ offers a powerful family mechanism for super- and subscripts in math mode. %D In text mode however, we don't use families for the smaller alternatives, and %D therefore have to take care of it otherwise. %D @@ -1602,8 +1760,20 @@ \font_helpers_check_bodyfont_environment\normalizedbodyfontsize\normalizedbodyfontsize % !! \else \showmessage\m!fonts4{#body}% + \fi + \ifconditional\c_font_compact + \glyphscale\numexpr\plushundred*\dimexpr\normalizedbodyfontsize\relax/\maxcard\relax \fi} +% \prependtoks +% \ifconditional\c_font_compact +% % better in lua ... accuracy +% \glyphtextscale \numexpr\plusthousand*\dimexpr\textface \relax/\d_font_scaled_default\relax +% \glyphscriptscale \numexpr\plusthousand*\dimexpr\scriptface \relax/\d_font_scaled_default\relax +% \glyphscriptscriptscale \numexpr\plusthousand*\dimexpr\scriptscriptface\relax/\d_font_scaled_default\relax +% \fi +% \to \everymathematics + \protected\def\font_basics_switch_style#style% {\ifcsname\??fontstyle#style\endcsname \lastnamedcs diff --git a/tex/context/base/mkxl/font-mat.mklx b/tex/context/base/mkxl/font-mat.mklx index b364e1520..0e3b3fbad 100644 --- a/tex/context/base/mkxl/font-mat.mklx +++ b/tex/context/base/mkxl/font-mat.mklx @@ -21,7 +21,7 @@ \ifdefined\??fontinstancebasic \else \installcorenamespace{fontinstancebasic} \fi \ifdefined\??fontinstanceclass \else \installcorenamespace{fontinstanceclass} \fi -%D The order 3 2 1 of siuze matters: needed for math-fbk relative size storage! +%D The order 3 2 1 of size matters: needed for math-fbk relative size storage! %D \macros %D {textonly} @@ -104,7 +104,7 @@ %def\mathsizesuffix{\ifcase\fontface\or\mathtextsuffix\or\mathscriptsuffix\or\mathscriptscriptsuffix\fi} \mutable\let\mathsizesuffix\empty -\def\font_helpers_set_math_family_indeed#mrtag#family% \fontface etc are also used later on +\def\font_helpers_set_math_family_indeed_normal#mrtag#family% \fontface etc are also used later on {\let\savedfontbody\fontbody \let\fontfamily#family% % the order is important as we depend on known id's when completing fonts @@ -122,11 +122,46 @@ \let\fontbody\savedfontbody \setfalse\c_font_auto_size} -\def\font_helpers_set_math_family_bold_indeed#mbfam#familytag#mrfam% \c_font_fam_mb \s!mb \c_font_fam_mr +\def\font_helpers_set_math_family_set_scales_compact + {% these are used when no font setting is there, the settings come before setting the parameters + % and are stored with the family + \glyphtextscale \plusthousand + \glyphscriptscale \numexpr\plusthousand*\dimexpr\scriptface \relax/\dimexpr\textface\relax\relax + \glyphscriptscriptscale \numexpr\plusthousand*\dimexpr\scriptscriptface\relax/\dimexpr\textface\relax\relax} + +\def\font_helpers_set_math_family_set_scales_normal + {\glyphtextscale \plusthousand + \glyphscriptscale \plusthousand + \glyphscriptscriptscale\plusthousand} + +\def\font_helpers_set_math_family_indeed_compact#mrtag#family% \fontface etc are also used later on + {\let\savedfontbody\fontbody + \let\fontfamily#family% + \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 + \scriptfont #mrtag\font % reuses + \scriptscriptfont#mrtag\font % reuses + \let\mathsizesuffix\empty \let\fontface\!!zerocount + \let\fontbody\savedfontbody + \setfalse\c_font_auto_size} + +\def\font_helpers_set_math_family_indeed + {\ifconditional\c_font_compact + \expandafter\font_helpers_set_math_family_indeed_compact + \else + \expandafter\font_helpers_set_math_family_indeed_normal + \fi} + +\def\font_helpers_set_math_family_bold_indeed_normal#mbfam#familytag#mrfam% \c_font_fam_mb \s!mb \c_font_fam_mr {\let\savedfontclass\defaultfontclass \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one \let\savedfontbody\fontbody \let\fontfamily#familytag% + \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 @@ -141,28 +176,6 @@ \let\defaultfontclass\savedfontclass \setfalse\c_font_auto_size} -\def\font_helpers_set_math_family_bold_a#font#mbfam#mrfam% - {\ifcsname\??fontinstanceready\fontclass-\fontbody-\s!mm-\fontfamily-\fontsize\endcsname \setfalse\c_font_auto_size - \lastnamedcs #font#mbfam\font \orelse - \ifcsname\??fontinstanceready\fontclass-\fontbody-\s!mm-\fontfamily \endcsname \settrue \c_font_auto_size - \lastnamedcs #font#mbfam\font \else - #font#mbfam#font#mrfam% - \fi} - -\def\font_helpers_set_math_family_indeed_compact#mrtag#family% \fontface etc are also used later on - {\let\savedfontbody\fontbody - \let\fontfamily#family% - % 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 - \scriptfont #mrtag\font % reuses - \scriptscriptfont#mrtag\font % reuses - \let\mathsizesuffix\empty \let\fontface\!!zerocount - \let\fontbody\savedfontbody - \setfalse\c_font_auto_size} - \def\font_helpers_set_math_family_bold_indeed_compact#mbfam#familytag#mrfam% \c_font_fam_mb \s!mb \c_font_fam_mr {\let\savedfontclass\defaultfontclass \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one @@ -171,13 +184,28 @@ \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 - \scriptfont #mbfam\scriptfont #mrfam % reuses - \scriptscriptfont#mbfam\scriptscriptfont#mrfam % reuses + \scriptfont #mbfam\scriptfont #mrfam% reuses + \scriptscriptfont#mbfam\scriptscriptfont#mrfam% reuses \let\mathsizesuffix\empty \let\fontface\!!zerocount \let\fontbody\savedfontbody \let\defaultfontclass\savedfontclass \setfalse\c_font_auto_size} +\def\font_helpers_set_math_family_bold_indeed + {\ifconditional\c_font_compact + \expandafter\font_helpers_set_math_family_bold_indeed_compact + \else + \expandafter\font_helpers_set_math_family_bold_indeed_normal + \fi} + +\def\font_helpers_set_math_family_bold_a#font#mbfam#mrfam% + {\ifcsname\??fontinstanceready\fontclass-\fontbody-\s!mm-\fontfamily-\fontsize\endcsname \setfalse\c_font_auto_size + \lastnamedcs #font#mbfam\font \orelse + \ifcsname\??fontinstanceready\fontclass-\fontbody-\s!mm-\fontfamily \endcsname \settrue \c_font_auto_size + \lastnamedcs #font#mbfam\font \else + #font#mbfam#font#mrfam% + \fi} + % optimized: math fonts are never changed (10K \bfa $x$: 3.2 => 2.5 (baseline 1.0)) % % sort of tricky: we cannot reset in \everybeforedefinetypeface as we don't know @@ -236,16 +264,25 @@ \def\font_helpers_preset_math_family_warning {\writestatus{fonts}{math: unset for global bodyfont \fontclass\space at \fontbody}} -\def\font_helpers_preset_math_family_indeed_changed#fam#familytag% - {\scriptscriptfont#fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname +\def\font_helpers_preset_math_family_indeed_changed_normal#fam#familytag% + {\font_helpers_set_math_family_set_scales_normal + \scriptscriptfont#fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-3\endcsname \scriptfont #fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname \textfont #fam\v_font_math_one} \def\font_helpers_preset_math_family_indeed_changed_compact#fam#familytag% - {\scriptscriptfont#fam\v_font_math_one + {\font_helpers_set_math_family_set_scales_compact + \scriptscriptfont#fam\v_font_math_one \scriptfont #fam\v_font_math_one \textfont #fam\v_font_math_one} +\def\font_helpers_preset_math_family_indeed_changed + {\ifconditional\c_font_compact + \expandafter\font_helpers_preset_math_family_indeed_changed_compact + \else + \expandafter\font_helpers_preset_math_family_indeed_changed_normal + \fi} + \let\font_helpers_reset_fontclass_math_families\gobbleoneargument %D It would be nice if characters could be defined in a neutral way (say fam 255) diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt index 06268206f..03e0f47fa 100644 --- a/tex/context/base/mkxl/font-ots.lmt +++ b/tex/context/base/mkxl/font-ots.lmt @@ -205,7 +205,6 @@ local setlink = nuts.setlink local getwidth = nuts.getwidth local getglyphdata = nuts.getglyphdata -local getscales = nuts.getscales local getwhatever = nuts.getwhatever --------------------------------------------------------------------------------------- @@ -296,6 +295,7 @@ local marks = false local classes = false local currentfont = false local currentattr = false +local currentscale = false local currentxscale = false local currentyscale = false local factor = 0 @@ -764,7 +764,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip local startchar = getchar(start) if skiphash and skiphash[startchar] then while current do - local nxt, char = isnextchar(current,currentfont,currentxscale,currentyscale) + local nxt, char = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) if char then local lg = ligature[char] if lg then @@ -798,7 +798,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip local discfound = false local hasmarks = marks[startchar] while current do - local nxt, char, id = isnextchar(current,currentfont,currentxscale,currentyscale) + local nxt, char, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then current = nxt @@ -833,20 +833,20 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip local pre, post, replace = getdisc(discfound) local match if replace then - local char = ischar(replace,currentfont,currentxscale,currentyscale) + local char = ischar(replace,currentfont,currentscale,currentxscale,currentyscale) if char and ligature[char] then match = true end end if not match and pre then - local char = ischar(pre,currentfont,currentxscale,currentyscale) + local char = ischar(pre,currentfont,currentscale,currentxscale,currentyscale) if char and ligature[char] then match = true end end if not match and not pre or not replace then local n = getnext(discfound) - local char = ischar(n,currentfont,currentxscale,currentyscale) + local char = ischar(n,currentfont,currentscale,currentxscale,currentyscale) if char and ligature[char] then match = true end @@ -950,7 +950,7 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,st else local prev = start while snext do - local nextchar = ischar(snext,currentfont,currentxscale,currentyscale) + local nextchar = ischar(snext,currentfont,currentscale,currentxscale,currentyscale) if nextchar then if skiphash and skiphash[nextchar] then -- includes marks too when flag prev = snext @@ -1016,13 +1016,13 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode, if marks[markchar] then local base = getprev(start) -- [glyph] [start=mark] if base then - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then while base do base = getprev(base) if base then - basechar = ischar(base,currentfont,currentxscale,currentyscale) + basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1071,13 +1071,13 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm if marks[markchar] then local base = getprev(start) -- [glyph] [optional marks] [start=mark] if base then - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then while base do base = getprev(base) if base then - basechar = ischar(base,currentfont,currentxscale,currentyscale) + basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1147,7 +1147,7 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode, end end if base then - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then -- subtype test can go local ba = markanchors[1][basechar] -- slot 1 has been made copy of the class hash if ba then @@ -1176,7 +1176,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,sk else local nxt = getnext(start) while nxt do - local nextchar = ischar(nxt,currentfont,currentxscale,currentyscale) + local nextchar = ischar(nxt,currentfont,currentscale,currentxscale,currentyscale) if not nextchar then break elseif marks[nextchar] then -- always sequence.flags[1] @@ -1504,7 +1504,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup -- end -- end -- - local nxt, schar, id = isnextchar(current,currentfont,currentxscale,currentyscale) + local nxt, schar, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) if schar then if skiphash and skiphash[schar] then -- marks -- if current == stop then -- maybe add this @@ -1615,7 +1615,7 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm if kerns then local prev = start while snext do - local nextchar = ischar(snext,currentfont,currentxscale,currentyscale) + local nextchar = ischar(snext,currentfont,currentscale,currentxscale,currentyscale) if not nextchar then break end @@ -1684,13 +1684,13 @@ function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlooku if markanchors then local base = getprev(start) -- [glyph] [start=mark] if base then - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then while base do base = getprev(base) if base then - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1749,13 +1749,13 @@ function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentl if markanchors then local base = getprev(start) -- [glyph] [optional marks] [start=mark] if base then - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if marks[basechar] then while base do base = getprev(base) if base then - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then if not marks[basechar] then break @@ -1829,7 +1829,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlooku end end if base then -- subtype test can go - local basechar = ischar(base,currentfont,currentxscale,currentyscale) + local basechar = ischar(base,currentfont,currentscale,currentxscale,currentyscale) if basechar then local ba = markanchors[1][basechar] if ba then @@ -1875,7 +1875,7 @@ function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup, else local nxt = getnext(start) while nxt do - local nextchar = ischar(nxt,currentfont,currentxscale,currentyscale) + local nextchar = ischar(nxt,currentfont,currentscale,currentxscale,currentyscale) if not nextchar then break elseif marks[nextchar] then @@ -2050,7 +2050,7 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) while start do if skiphash then -- hm, so we know we skip some while start do - local char = ischar(start,currentfont,currentxscale,currentyscale) + local char = ischar(start,currentfont,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then start = getnext(start) @@ -2311,7 +2311,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) local insertedmarks = 0 while cprev do - local char = ischar(cf,currentfont,currentxscale,currentyscale) + local char = ischar(cf,currentfont,currentscale,currentxscale,currentyscale) if char and marks[char] then insertedmarks = insertedmarks + 1 cf = cprev @@ -2377,7 +2377,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) local insertedmarks = 0 while cnext do - local char = ischar(cnext,currentfont,currentxscale,currentyscale) + local char = ischar(cnext,currentfont,currentscale,currentxscale,currentyscale) if char and marks[char] then insertedmarks = insertedmarks + 1 cl = cnext @@ -2487,6 +2487,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s checkdisc = getprev(head) end local currentfont = currentfont -- really ? + local currentscale = currentscale -- really ? local currentxscale = currentxscale -- really ? local currentyscale = currentyscale -- really ? @@ -2507,7 +2508,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s local nofcontexts = contexts.n -- #contexts - local startchar = nofcontext == 1 or ischar(start,currentfont,currentxscale,currentyscale) -- only needed in a chain + local startchar = nofcontext == 1 or ischar(start,currentfont,currentscale,currentxscale,currentyscale) -- only needed in a chain for k=1,nofcontexts do -- does this disc mess work well with n > 1 @@ -2541,7 +2542,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s end if last then -- local char, id = ischar(last,currentfont) - local nxt, char, id = isnextchar(last,currentfont,currentxscale,currentyscale) + local nxt, char, id = isnextchar(last,currentfont,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then skipped = true @@ -2654,7 +2655,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s while n >= 1 do if prev then -- local char, id = ischar(prev,currentfont) - local prv, char, id = isprevchar(prev,currentfont,currentxscale,currentyscale) + local prv, char, id = isprevchar(prev,currentfont,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then skipped = true @@ -2792,7 +2793,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s while n <= s do if current then -- local char, id = ischar(current,currentfont) - local nxt, char, id = isnextchar(current,currentfont,currentxscale,currentyscale) + local nxt, char, id = isnextchar(current,currentfont,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then skipped = true @@ -3826,6 +3827,7 @@ do if nesting == 1 then currentfont = font currentattr = attr + currentscale = false currentxscale = false currentyscale = false tfmdata = fontdata[font] @@ -3853,14 +3855,6 @@ do end - -- some 10% faster when no dynamics but hardly measureable on real runs .. but: it only - -- works when we have no other dynamics as otherwise the zero run will be applied to the - -- whole stream for which we then need to pass another variable which we won't - - -- if attr == 0 then - -- attr = false - -- end - if trace_steps then checkstep(head) end @@ -3916,22 +3910,13 @@ do local rlmode = 0 -- how important is this .. do we need to check for dir? local merged = steps.merged while start do --- local prv, char, id = isprevchar(start,font) local prv, char, id = isprevchar(start,font) if char then local m = merged[char] if m then --- local a -- happens often so no assignment is faster --- if attr then --- a = getglyphdata(start) --- end --- if not a or (a == attr) then --- currentxscale, currentyscale = getscales(start) - local a - a, currentxscale, currentyscale = getwhatever(start,attr,attribute) + a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute) if a then - for i=m[1],m[2] do local step = steps[i] local lookupcache = step.coverage @@ -3965,28 +3950,16 @@ do local step = steps[1] local lookupcache = step.coverage while start do - local nxt, char, id = isnextchar(start,font) + local nxt, char, id = isnextchar(start,font) -- we can move the data/state checks here if char then if skiphash and skiphash[char] then -- we never needed it here but let's try start = nxt else local lookupmatch = lookupcache[char] if lookupmatch then --- local a -- happens often so no assignment is faster --- if attr then --- if getglyphdata(start) == attr and (not attribute or getstate(start,attribute)) then --- a = true --- end --- elseif not attribute or getstate(start,attribute) then --- a = true --- end --- if a then --- currentxscale, currentyscale = getscales(start) - local a - a, currentxscale, currentyscale = getwhatever(start,attr,attribute) + a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute) if a then - local ok, df head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) if df then @@ -4043,21 +4016,9 @@ do else local m = merged[char] if m then --- local a -- happens often so no assignment is faster --- if attr then --- if getglyphdata(start) == attr and (not attribute or getstate(start,attribute)) then --- a = true --- end --- elseif not attribute or getstate(start,attribute) then --- a = true --- end --- if a then --- currentxscale, currentyscale = getscales(start) - local a - a, currentxscale, currentyscale = getwhatever(start,attr,attribute) + a, currentscale, currentxscale, currentyscale = getwhatever(start,attr,attribute) if a then - local ok, df for i=m[1],m[2] do local step = steps[i] @@ -4137,6 +4098,7 @@ do function otf.datasetpositionprocessor(head,font,direction,dataset) currentfont = font + currentscale = false currentxscale = false currentyscale = false tfmdata = fontdata[font] diff --git a/tex/context/base/mkxl/font-pre.mkxl b/tex/context/base/mkxl/font-pre.mkxl index ee3159b1b..fafe20a60 100644 --- a/tex/context/base/mkxl/font-pre.mkxl +++ b/tex/context/base/mkxl/font-pre.mkxl @@ -405,10 +405,15 @@ mathalternates=yes, mathitalics=yes, % we pass them mathdimensions=all, +compactmath=yes, % mathgaps=yes, language=dflt, script=math] +\definefontfeature + [oldmath] + [oldmath=yes] + \ifdefined\mathnolimitsmode \mathnolimitsmode\plusone % font driven (only opentype) \fi @@ -425,22 +430,15 @@ [mathematics] [] -% \definefontfeature -% [mathematics-r2l] -% [mathematics] -% [language=ara, -% rtlm=yes, -% locl=yes] - \definefontfeature [mathematics-r2l] [mathematics] [rtlm=yes, locl=yes] -\definefontfeature[virtualmath] [mathematics] % downward compatibility -\definefontfeature[virtualmath-l2r] [mathematics-l2r] % downward compatibility -\definefontfeature[virtualmath-r2l] [mathematics-r2l] % downward compatibility +\definefontfeature[virtualmath] [mathematics] +\definefontfeature[virtualmath-l2r] [mathematics-l2r] +\definefontfeature[virtualmath-r2l] [mathematics-r2l] \definefontfeature[math-text] [mathematics] [ssty=no] \definefontfeature[math-script] [mathematics] [ssty=1,mathsize=yes] @@ -454,6 +452,8 @@ \definefontfeature[math-script-r2l] [mathematics-r2l] [ssty=1,mathsize=yes] \definefontfeature[math-scriptscript-r2l] [mathematics-r2l] [ssty=2,mathsize=yes] +% this will go away: could be a mode in the engine + \definefontfeature[math-nostack-text] [math-text] [nostackmath=yes] \definefontfeature[math-nostack-script] [math-script] [nostackmath=yes] \definefontfeature[math-nostack-scriptscript][math-scriptscript][nostackmath=yes] @@ -937,38 +937,27 @@ % experiment: -\startsetups experiment:math:fonts:compact - \let\font_helpers_set_math_family_indeed \font_helpers_set_math_family_indeed_compact - \let\font_helpers_set_math_family_bold_indeed \font_helpers_set_math_family_bold_indeed_compact - \let\font_helpers_preset_math_family_indeed_changed\font_helpers_preset_math_family_indeed_changed_compact - - \definefontfeature[math-text] [mathematics] [compactmath=yes] - \definefontfeature[math-script] [mathematics] [compactmath=yes] - \definefontfeature[math-scriptscript] [mathematics] [compactmath=yes] - \definefontfeature[math-text-l2r] [mathematics-l2r][compactmath=yes] - \definefontfeature[math-script-l2r] [mathematics-l2r][compactmath=yes] - \definefontfeature[math-scriptscript-l2r][mathematics-l2r][compactmath=yes] - \definefontfeature[math-text-r2l] [mathematics-r2l][compactmath=yes] - \definefontfeature[math-script-r2l] [mathematics-r2l][compactmath=yes] - \definefontfeature[math-scriptscript-r2l][mathematics-r2l][compactmath=yes] -\stopsetups - -\installtexexperiment - {math.fonts.compact} - {\directsetup{experiment:math:fonts:compact}} - {} - -\startsetups experiment:text:fonts:compact - \let\font_helpers_set_current_font_alternative_size \font_helpers_set_current_font_alternative_size_g - \let\font_helpers_set_current_font_size \font_helpers_set_current_font_size_g - \let\font_helpers_set_current_font_style_size \font_helpers_set_current_font_style_size_g - \let\font_helpers_set_current_font_style_alternative_size\font_helpers_set_current_font_style_alternative_size_g - \let\font_helpers_set_current_font_xxx_alternative \font_helpers_set_current_font_xxx_alternative_g +\startsetups experiment:fonts:compact + \settrue\c_font_compact + +% \definefontfeature[virtualmath] [mathematics] [compactmath=yes] +% \definefontfeature[virtualmath-l2r] [mathematics-l2r][compactmath=yes] +% \definefontfeature[virtualmath-r2l] [mathematics-r2l][compactmath=yes] + +% \definefontfeature[math-text] [mathematics] [compactmath=yes] +% \definefontfeature[math-script] [mathematics] [compactmath=yes] +% \definefontfeature[math-scriptscript] [mathematics] [compactmath=yes] +% \definefontfeature[math-text-l2r] [mathematics-l2r][compactmath=yes] +% \definefontfeature[math-script-l2r] [mathematics-l2r][compactmath=yes] +% \definefontfeature[math-scriptscript-l2r][mathematics-l2r][compactmath=yes] +% \definefontfeature[math-text-r2l] [mathematics-r2l][compactmath=yes] +% \definefontfeature[math-script-r2l] [mathematics-r2l][compactmath=yes] +% \definefontfeature[math-scriptscript-r2l][mathematics-r2l][compactmath=yes] \stopsetups \installtexexperiment - {text.fonts.compact} - {\directsetup{experiment:text:fonts:compact}} + {fonts.compact} + {\directsetup{experiment:fonts:compact}} {} \protect \endinput diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt index ce2de4f89..44352994a 100644 --- a/tex/context/base/mkxl/lpdf-lmt.lmt +++ b/tex/context/base/mkxl/lpdf-lmt.lmt @@ -592,8 +592,6 @@ local flushcharacter do -- luatex (a precursor to lmtx and also for comparison) but only in lmtx now so ... -- time to move on I guess. - local getscales = nuts.getscales -- move to caller (driv-shp) - flushcharacter = function(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor,sx,sy) -- ,naturalwidth,width) if sx ~= f_x_scale or sy ~= f_y_scale or need_tf or font ~= f_cur or f_pdf ~= f_pdf_cur or fs ~= fs_cur or mode == "page" then pdf_goto_textmode() diff --git a/tex/context/base/mkxl/math-ali.mkxl b/tex/context/base/mkxl/math-ali.mkxl index a8b0fa113..d90f3ab0f 100644 --- a/tex/context/base/mkxl/math-ali.mkxl +++ b/tex/context/base/mkxl/math-ali.mkxl @@ -62,6 +62,7 @@ {\ifnum\scratchcounter=\scratchcountertwo \scratchcounter\plusone \etoksapp\scratchtoks{\math_eqalign_distance}% + \etoksapp\scratchtoks{\global\c_math_eqalign_column\zerocount}% \else \advance\scratchcounter\plusone \fi diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl index 2b1a54edf..95501be65 100644 --- a/tex/context/base/mkxl/math-ini.mkxl +++ b/tex/context/base/mkxl/math-ini.mkxl @@ -68,7 +68,7 @@ \registerctxluafile{math-dim}{} \registerctxluafile{math-act}{} \registerctxluafile{math-ext}{} -\registerctxluafile{math-vfu}{} +\registerctxluafile{math-vfu}{autosuffix} \registerctxluafile{math-ttv}{} \registerctxluafile{math-map}{optimize} \registerctxluafile{math-ren}{} diff --git a/tex/context/base/mkxl/math-noa.lmt b/tex/context/base/mkxl/math-noa.lmt index 25e1823e2..c884e6927 100644 --- a/tex/context/base/mkxl/math-noa.lmt +++ b/tex/context/base/mkxl/math-noa.lmt @@ -661,8 +661,14 @@ do local setnodecolor = colortracers.set local function report_remap(tag,id,old,new,extra) - report_remapping("remapping %s in font (%s,%s) from %C to %C%s", - tag,id,fontdata[id].properties.fontname or "",old,new,extra) + if new then + report_remapping("remapping %s in font (%s,%s) from %C to %C%s", + tag,id,fontdata[id].properties.fontname or "",old,new,extra) + else + -- error ! + report_remapping("remapping %s in font (%s,%s) from %C to ?", + tag,id,fontdata[id].properties.fontname or "",old) + end end local function checked(pointer) diff --git a/tex/context/base/mkxl/math-vfu.lmt b/tex/context/base/mkxl/math-vfu.lmt new file mode 100644 index 000000000..daa6bbf5e --- /dev/null +++ b/tex/context/base/mkxl/math-vfu.lmt @@ -0,0 +1,1148 @@ +if not modules then modules = { } end modules ['math-vfu'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- All these math vectors .. thanks to Aditya and Mojca they become +-- better and better. If you have problems with math fonts or miss +-- characters report it to the ConTeXt mailing list. Also thanks to +-- Boguslaw for finding a couple of errors. +-- +-- This mechanism will stay around. Even when we've switched to the +-- real fonts, one can still say: +-- +-- \enablemode[lmmath,pxmath,txmath] +-- +-- to get the virtual counterparts. There are still areas where the +-- virtuals are better. + +-- 20D6 -> 2190 +-- 20D7 -> 2192 + +local type, next, tonumber = type, next, tonumber +local max = math.max +local fastcopy = table.copy + +local fonts, nodes, mathematics = fonts, nodes, mathematics + +local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end) +local trace_timings = false trackers.register("math.timings", function(v) trace_timings = v end) + +local add_optional = false directives.register("math.virtual.optional",function(v) add_optional = v end) + +local report_virtual = logs.reporter("fonts","virtual math") + +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex +local formatters = string.formatters + +local chardata = characters.data + +local mathencodings = allocate() +fonts.encodings.math = mathencodings -- better is then: fonts.encodings.vectors +local vfmath = allocate() +fonts.handlers.vf.math = vfmath + +local helpers = fonts.helpers +local vfcommands = helpers.commands +local rightcommand = vfcommands.right +local leftcommand = vfcommands.left +local downcommand = vfcommands.down +local upcommand = vfcommands.up +local push = vfcommands.push +local pop = vfcommands.pop + +local shared = { } + +-- local back = { "slot", 1, 0x2215 } +-- +-- local function negate(main,characters,id,size,unicode,basecode) +-- if not characters[unicode] then +-- local basechar = characters[basecode] +-- if basechar then +-- local ht, wd = basechar.height, basechar.width +-- characters[unicode] = { +-- width = wd, +-- height = ht, +-- depth = basechar.depth, +-- italic = basechar.italic, +-- kerns = basechar.kerns, +-- commands = { +-- { "slot", 1, basecode }, +-- push, +-- downcommand[ht/5], +-- leftcommand[wd/2], +-- back, +-- push, +-- } +-- } +-- end +-- end +-- end +-- +-- \Umathchardef\braceld="0 "1 "FF07A +-- \Umathchardef\bracerd="0 "1 "FF07B +-- \Umathchardef\bracelu="0 "1 "FF07C +-- \Umathchardef\braceru="0 "1 "FF07D + +local function brace(main,characters,id,size,unicode,first,rule,left,right,rule,last) + if not characters[unicode] then + characters[unicode] = { + horiz_variants = { + { extender = 0, glyph = first }, + { extender = 1, glyph = rule }, + { extender = 0, glyph = left }, + { extender = 0, glyph = right }, + { extender = 1, glyph = rule }, + { extender = 0, glyph = last }, + } + } + end +end + +local function extension(main,characters,id,size,unicode,first,middle,last) + local chr = characters[unicode] + if not chr then + return -- skip + end + local fw = characters[first] + if not fw then + return + end + local mw = characters[middle] + if not mw then + return + end + local lw = characters[last] + if not lw then + return + end + fw = fw.width + mw = mw.width + lw = lw.width + if fw == 0 then + fw = 1 + end + if lw == 0 then + lw = 1 + end + chr.horiz_variants = { + { 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 }, + } +end + +local function parent(main,characters,id,size,unicode,first,rule,last) + if not characters[unicode] then + characters[unicode] = { + horiz_variants = { + { extender = 0, glyph = first }, + { extender = 1, glyph = rule }, + { extender = 0, glyph = last }, + } + } + end +end + +local step = 0.2 -- 0.1 is nicer but gives larger files + +local function make(main,characters,id,size,n,m) + local old = 0xFF000 + n + local c = characters[old] + if c then + local upslot = 0xFF100 + n + local dnslot = 0xFF200 + n + local uprule = 0xFF300 + m + local dnrule = 0xFF400 + m + local xu = main.parameters.x_height + 0.3*size + local xd = 0.3*size + local w = c.width or 0 + local h = c.height or 0 + local d = c.depth or 0 + local thickness = h - d + local rulewidth = step*size -- we could use an overlap + local slot = { "slot", id, old } + local rule = { "rule", thickness, rulewidth } + local up = upcommand[xu] + local dn = downcommand[xd] + local ht = xu + 3*thickness + local dp = 0 + if not characters[uprule] then + characters[uprule] = { + width = rulewidth, + height = ht, + depth = dp, + commands = { push, up, rule, pop }, + } + end + characters[upslot] = { + width = w, + height = ht, + depth = dp, + commands = { push, up, slot, pop }, + } + local ht = 0 + local dp = xd + 3*thickness + if not characters[dnrule] then + characters[dnrule] = { + width = rulewidth, + height = ht, + depth = dp, + commands = { push, dn, rule, pop } + } + end + characters[dnslot] = { + width = w, + height = ht, + depth = dp, + commands = { push, dn, slot, pop }, + } + end +end + +local function clipped(main,characters,id,size,unicode,original) -- push/pop needed? + local minus = characters[original] + if minus then + local mu = size/18 + local step = 3*mu + local width = minus.width + if width > step then + width = width - step + step = step / 2 + else + width = width / 2 + step = width + end + characters[unicode] = { + width = width, + height = minus.height, + depth = minus.depth, + commands = { + push, + leftcommand[step], + { "slot", id, original }, + pop, + } + } + end +end + +local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess + local raised = fonts.hashes.characters[main.fonts[id_of_smaller].id][private] -- characters[private] + if raised then + local up = 0.85 * main.parameters.x_height + local slot = { "slot", id_of_smaller, private } + local commands = { + push, upcommand[up], slot, + } + for i=2,n do + commands[#commands+1] = slot + end + commands[#commands+1] = pop + characters[unicode] = { + width = n * raised.width, + height = (raised.height or 0) + up, + depth = (raised.depth or 0) - up, + italic = raised.italic, + commands = commands, + } + end +end + +local function dots(main,characters,id,size,unicode) + local c = characters[0x002E] + if c then + local w = c.width + local h = c.height + local d = c.depth + local mu = size/18 + local right3mu = rightcommand[3*mu] + local right1mu = rightcommand[1*mu] + local up1size = upcommand[.1*size] + local up4size = upcommand[.4*size] + local up7size = upcommand[.7*size] + local right2muw = rightcommand[2*mu + w] + local slot = { "slot", id, 0x002E } + if unicode == 0x22EF then + local c = characters[0x022C5] + if c then + local width = c.width + local height = c.height + local depth = c.depth + local slot = { "slot", id, 0x022C5 } + characters[unicode] = { + width = 3*width + 2*3*mu, + height = height, + depth = depth, + commands = { + push, slot, right3mu, slot, right3mu, slot, pop, + } + } + end + elseif unicode == 0x22EE then + -- weird height ! + characters[unicode] = { + width = w, + height = h+(1.4)*size, + depth = 0, + commands = { + push, push, slot, pop, up4size, push, slot, pop, up4size, slot, pop, + } + } + elseif unicode == 0x22F1 then + characters[unicode] = { + width = 3*w + 6*size/18, + height = 1.5*size, + depth = 0, + commands = { + push, + right1mu, + push, up7size, slot, pop, + right2muw, + push, up4size, slot, pop, + right2muw, + push, up1size, slot, pop, + right1mu, + pop + } + } + elseif unicode == 0x22F0 then + characters[unicode] = { + width = 3*w + 6*size/18, + height = 1.5*size, + depth = 0, + commands = { + push, + right1mu, + push, up1size, slot, pop, + right2muw, + push, up4size, slot, pop, + right2muw, + push, up7size, slot, pop, + right1mu, + pop + } + } + else + characters[unicode] = { + width = 3*w + 2*3*mu, + height = h, + depth = d, + commands = { + push, slot, right3mu, slot, right3mu, slot, pop, + } + } + end + end +end + +local function vertbar(main,characters,id,size,parent,scale,unicode) + local cp = characters[parent] + if cp then + local sc = scale * size + local pc = { "slot", id, parent } + characters[unicode] = { + width = cp.width, + height = cp.height + sc, + depth = cp.depth + sc, + next = cp.next, -- can be extensible + commands = { + push, upcommand [sc], pc, pop, + push, downcommand[sc], pc, pop, + pc, + }, + } + cp.next = unicode + end +end + +local function jointwo(main,characters,id,size,unicode,u1,d12,u2,what) + local c1 = characters[u1] + local c2 = characters[u2] + if c1 and c2 then + local w1 = c1.width + local w2 = c2.width + local mu = size/18 + characters[unicode] = { + width = w1 + w2 - d12 * mu, + height = max(c1.height or 0, c2.height or 0), + depth = max(c1.depth or 0, c2.depth or 0), + commands = { + { "slot", id, u1 }, + leftcommand[d12*mu], + { "slot", id, u2 }, + }, + } + end +end + +local function jointhree(main,characters,id,size,unicode,u1,d12,u2,d23,u3) + local c1 = characters[u1] + local c2 = characters[u2] + local c3 = characters[u3] + if c1 and c2 and c3 then + local w1 = c1.width + local w2 = c2.width + local w3 = c3.width + local mu = size/18 + characters[unicode] = { + width = w1 + w2 + w3 - d12*mu - d23*mu, + height = max(c1.height or 0, c2.height or 0, c3.height or 0), + depth = max(c1.depth or 0, c2.depth or 0, c3.depth or 0), + commands = { + { "slot", id, u1 }, + leftcommand[d12*mu], + { "slot", id, u2 }, + leftcommand[d23*mu], + { "slot", id, u3 }, + } + } + end +end + +local function stack(main,characters,id,size,unicode,u1,d12,u2) + local c1 = characters[u1] + if not c1 then + return + end + local c2 = characters[u2] + if not c2 then + return + end + local w1 = c1.width or 0 + local h1 = c1.height or 0 + local d1 = c1.depth or 0 + local w2 = c2.width or 0 + local h2 = c2.height or 0 + local d2 = c2.depth or 0 + local mu = size/18 + characters[unicode] = { + width = w1, + height = h1 + h2 + d12, + depth = d1, + commands = { + { "slot", id, u1 }, + leftcommand[w1/2 + w2/2], + downcommand[-h1 + d2 -d12*mu], + { "slot", id, u2 }, + } + } +end + +local function repeated(main,characters,id,size,unicode,u,n,private,fraction) -- math-fbk.lua + local c = characters[u] + if c then + local width = c.width + local italic = fraction*width -- c.italic or 0 -- larger ones have funny italics + local tc = { "slot", id, u } + local tr = leftcommand[italic] -- see hack elsewhere + local commands = { } + for i=1,n-1 do + commands[#commands+1] = tc + commands[#commands+1] = tr + end + commands[#commands+1] = tc + local next = c.next + if next then + repeated(main,characters,id,size,private,next,n,private+1,fraction) + next = private + end + characters[unicode] = { + width = width + (n-1)*(width-italic), + height = c.height, + depth = c.depth, + italic = italic, + commands = commands, + next = next, + } + end +end + +local function cloned(main,characters,id,size,source,target) + local data = characters[source] + if data then + characters[target] = data + return true + end +end + +-- we use the fact that context defines the smallest sizes first .. a real dirty and ugly hack + +local data_of_smaller = nil +local size_of_smaller = 0 + +function vfmath.addmissing(main,id,size) + + local id_of_smaller = nil + + if size < size_of_smaller or size_of_smaller == 0 then + data_of_smaller = main.fonts[id] + id_of_smaller = id + else + id_of_smaller = #main.fonts + 1 + main.fonts[id_of_smaller] = data_of_smaller + end + + -- here id is the index in fonts (normally 14 or so) and that slot points to self + + local characters = main.characters + local shared = main.shared + local variables = main.goodies.mathematics and main.goodies.mathematics.variables or { } + local joinrelfactor = variables.joinrelfactor or 3 + + for i=0x7A,0x7D do + make(main,characters,id,size,i,1) + end + + brace (main,characters,id,size,0x23DE,0xFF17A,0xFF301,0xFF17D,0xFF17C,0xFF301,0xFF17B) + brace (main,characters,id,size,0x23DF,0xFF27C,0xFF401,0xFF27B,0xFF27A,0xFF401,0xFF27D) + + parent (main,characters,id,size,0x23DC,0xFF17A,0xFF301,0xFF17B) + parent (main,characters,id,size,0x23DD,0xFF27C,0xFF401,0xFF27D) + + -- negate (main,characters,id,size,0x2260,0x003D) + dots (main,characters,id,size,0x2026) -- ldots + dots (main,characters,id,size,0x22EE) -- vdots + dots (main,characters,id,size,0x22EF) -- cdots + dots (main,characters,id,size,0x22F1) -- ddots + dots (main,characters,id,size,0x22F0) -- udots + + vertbar (main,characters,id,size,0x0007C,0.10,0xFF601) -- big : 0.85 bodyfontsize + vertbar (main,characters,id,size,0xFF601,0.30,0xFF602) -- Big : 1.15 bodyfontsize + vertbar (main,characters,id,size,0xFF602,0.30,0xFF603) -- bigg : 1.45 bodyfontsize + vertbar (main,characters,id,size,0xFF603,0.30,0xFF604) -- Bigg : 1.75 bodyfontsize + vertbar (main,characters,id,size,0x02016,0.10,0xFF605) + vertbar (main,characters,id,size,0xFF605,0.30,0xFF606) + vertbar (main,characters,id,size,0xFF606,0.30,0xFF607) + vertbar (main,characters,id,size,0xFF607,0.30,0xFF608) + + clipped (main,characters,id,size,0xFF501,0x0002D) -- minus + clipped (main,characters,id,size,0xFF502,0x02190) -- lefthead + clipped (main,characters,id,size,0xFF503,0x02192) -- righthead + clipped (main,characters,id,size,0xFF504,0xFE321) -- mapsto + clipped (main,characters,id,size,0xFF505,0xFE322) -- lhook + clipped (main,characters,id,size,0xFF506,0xFE323) -- rhook + clipped (main,characters,id,size,0xFF507,0xFE324) -- mapsfrom + clipped (main,characters,id,size,0xFF508,0x021D0) -- double lefthead + clipped (main,characters,id,size,0xFF509,0x021D2) -- double righthead + clipped (main,characters,id,size,0xFF50A,0x0003D) -- equal + clipped (main,characters,id,size,0xFF50B,0x0219E) -- lefttwohead + clipped (main,characters,id,size,0xFF50C,0x021A0) -- righttwohead + clipped (main,characters,id,size,0xFF50D,0xFF350) -- lr arrow combi snippet + clipped (main,characters,id,size,0xFF50E,0xFF351) -- lr arrow combi snippet + clipped (main,characters,id,size,0xFF50F,0xFF352) -- lr arrow combi snippet + clipped (main,characters,id,size,0xFF510,0x02261) -- equiv + + extension(main,characters,id,size,0x2190,0xFF502,0xFF501,0xFF501) -- \leftarrow + extension(main,characters,id,size,0x2192,0xFF501,0xFF501,0xFF503) -- \rightarrow + + extension(main,characters,id,size,0x002D,0xFF501,0xFF501,0xFF501) -- \rel + extension(main,characters,id,size,0x003D,0xFF50A,0xFF50A,0xFF50A) -- \equal + extension(main,characters,id,size,0x2261,0xFF510,0xFF510,0xFF510) -- \equiv + + jointwo (main,characters,id,size,0x21A6,0xFE321,0,0x02192) -- \mapstochar\rightarrow + jointwo (main,characters,id,size,0x21A9,0x02190,joinrelfactor,0xFE323) -- \leftarrow\joinrel\rhook + jointwo (main,characters,id,size,0x21AA,0xFE322,joinrelfactor,0x02192) -- \lhook\joinrel\rightarrow + jointwo (main,characters,id,size,0x27F5,0x02190,joinrelfactor,0x0002D) -- \leftarrow\joinrel\relbar + jointwo (main,characters,id,size,0x27F6,0x0002D,joinrelfactor,0x02192,2) -- \relbar\joinrel\rightarrow + jointwo (main,characters,id,size,0x27F7,0x02190,joinrelfactor,0x02192) -- \leftarrow\joinrel\rightarrow + jointwo (main,characters,id,size,0x27F8,0x021D0,joinrelfactor,0x0003D) -- \Leftarrow\joinrel\Relbar + jointwo (main,characters,id,size,0x27F9,0x0003D,joinrelfactor,0x021D2) -- \Relbar\joinrel\Rightarrow + jointwo (main,characters,id,size,0x27FA,0x021D0,joinrelfactor,0x021D2) -- \Leftarrow\joinrel\Rightarrow + jointhree(main,characters,id,size,0x27FB,0x02190,joinrelfactor,0x0002D,0,0xFE324) -- \leftarrow\joinrel\relbar\mapsfromchar + jointhree(main,characters,id,size,0x27FC,0xFE321,0,0x0002D,joinrelfactor,0x02192) -- \mapstochar\relbar\joinrel\rightarrow + + extension(main,characters,id,size,0x21A6,0xFF504,0xFF501,0xFF503) -- \mapstochar\rightarrow + extension(main,characters,id,size,0x21A9,0xFF502,0xFF501,0xFF506) -- \leftarrow\joinrel\rhook + extension(main,characters,id,size,0x21AA,0xFF505,0xFF501,0xFF503) -- \lhook\joinrel\rightarrow + extension(main,characters,id,size,0x27F5,0xFF502,0xFF501,0xFF501) -- \leftarrow\joinrel\relbar + extension(main,characters,id,size,0x27F6,0xFF501,0xFF501,0xFF503) -- \relbar\joinrel\rightarrow + extension(main,characters,id,size,0x27F7,0xFF502,0xFF501,0xFF503) -- \leftarrow\joinrel\rightarrow + extension(main,characters,id,size,0x27F8,0xFF508,0xFF50A,0xFF50A) -- \Leftarrow\joinrel\Relbar + extension(main,characters,id,size,0x27F9,0xFF50A,0xFF50A,0xFF509) -- \Relbar\joinrel\Rightarrow + extension(main,characters,id,size,0x27FA,0xFF508,0xFF50A,0xFF509) -- \Leftarrow\joinrel\Rightarrow + extension(main,characters,id,size,0x27FB,0xFF502,0xFF501,0xFF507) -- \leftarrow\joinrel\relbar\mapsfromchar + extension(main,characters,id,size,0x27FC,0xFF504,0xFF501,0xFF503) -- \mapstochar\relbar\joinrel\rightarrow + + extension(main,characters,id,size,0x219E,0xFF50B,0xFF501,0xFF501) -- \twoheadleftarrow\joinrel\relbar + extension(main,characters,id,size,0x21A0,0xFF501,0xFF501,0xFF50C) -- \relbar\joinrel\twoheadrightarrow + extension(main,characters,id,size,0x21C4,0xFF50D,0xFF50E,0xFF50F) -- leftoverright + + -- 21CB leftrightharpoon + -- 21CC rightleftharpoon + + stack(main,characters,id,size,0x2259,0x0003D,3,0x02227) -- \buildrel\wedge\over= + + jointwo(main,characters,id,size,0x22C8,0x022B3,joinrelfactor,0x022B2) -- \mathrel\triangleright\joinrel\mathrel\triangleleft (4 looks better than 3) + jointwo(main,characters,id,size,0x22A7,0x0007C,joinrelfactor,0x0003D) -- \mathrel|\joinrel= + jointwo(main,characters,id,size,0x2260,0x00338,0,0x0003D) -- \not\equal + jointwo(main,characters,id,size,0x2284,0x00338,0,0x02282) -- \not\subset + jointwo(main,characters,id,size,0x2285,0x00338,0,0x02283) -- \not\supset + jointwo(main,characters,id,size,0x2209,0x00338,0,0x02208) -- \not\in + jointwo(main,characters,id,size,0x2254,0x03A,0,0x03D) -- := (≔) + + repeated(main,characters,id,size,0x222C,0x222B,2,0xFF800,1/3) + repeated(main,characters,id,size,0x222D,0x222B,3,0xFF810,1/3) + + if cloned(main,characters,id,size,0x2032,0xFE325) then + raise(main,characters,id,size,0x2032,0xFE325,1,id_of_smaller) -- prime + raise(main,characters,id,size,0x2033,0xFE325,2,id_of_smaller) -- double prime + raise(main,characters,id,size,0x2034,0xFE325,3,id_of_smaller) -- triple prime + -- to satisfy the prime resolver + characters[0xFE932] = characters[0x2032] + characters[0xFE933] = characters[0x2033] + characters[0xFE934] = characters[0x2034] + end + + -- there are more (needs discussion first): + + -- characters[0x20D6] = characters[0x2190] + -- characters[0x20D7] = characters[0x2192] + + characters[0x02B9] = characters[0x2032] -- we're nice + + data_of_smaller = main.fonts[id] + size_of_smaller = size + +end + +local unique = 0 -- testcase: \startTEXpage \math{!\text{-}\text{-}\text{-}} \stopTEXpage + +local reported = { } +local reverse = { } -- index -> unicode + +setmetatableindex(reverse, function(t,name) + if trace_virtual then + report_virtual("initializing math vector %a",name) + end + local m = mathencodings[name] + local r = { } + for u, i in next, m do + r[i] = u + end + reverse[name] = r + return r +end) + +local function copy_glyph(main,target,original,unicode,slot) + local addprivate = fonts.helpers.addprivate + local olddata = original[unicode] + if olddata then + local newdata = { + width = olddata.width, + height = olddata.height, + depth = olddata.depth, + italic = olddata.italic, + kerns = olddata.kerns, + tounicode = olddata.tounicode, + commands = { { "slot", slot, unicode } }, + } + local glyphdata = newdata + local nextglyph = olddata.next + while nextglyph do + local oldnextdata = original[nextglyph] + if oldnextdata then + local newnextdata = { + width = oldnextdata.width, + height = oldnextdata.height, + depth = oldnextdata.depth, + tounicode = olddata.tounicode, + commands = { { "slot", slot, nextglyph } }, + } + local newnextglyph = addprivate(main,formatters["M-N-%H"](nextglyph),newnextdata) + newdata.next = newnextglyph + local nextnextglyph = oldnextdata.next + if nextnextglyph == nextglyph then + break + else + olddata = oldnextdata + newdata = newnextdata + nextglyph = nextnextglyph + end + else + break -- safeguard (when testing stuff) + end + end + local hv = olddata.horiz_variants + if hv then + hv = fastcopy(hv) + newdata.horiz_variants = hv + for i=1,#hv do + local hvi = hv[i] + local oldglyph = hvi.glyph + local olddata = original[oldglyph] + local newdata = { + width = olddata.width, + height = olddata.height, + depth = olddata.depth, + tounicode = olddata.tounicode, + commands = { { "slot", slot, oldglyph } }, + } + hvi.glyph = addprivate(main,formatters["M-H-%H"](oldglyph),newdata) + end + end + local vv = olddata.vert_variants + if vv then + vv = fastcopy(vv) + newdata.vert_variants = 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) + end + end + return newdata + end +end + +vfmath.copy_glyph = copy_glyph + +-- It's time to get rid of this type 1 mess ... take iwona: uppercase /A .. Z but +-- lowercase /a.math ... /z.math ... anyway, we now follow a slightly different +-- route: use the "order" field. I can probably make it a bit leaner but it's not +-- worth spending much time on now. + +function vfmath.define(specification,set,goodies) + local name = specification.name -- symbolic name + local size = specification.size -- given size + local loaded = { } + local fontlist = { } + local names = { } + local main = nil + local start = (trace_virtual or trace_timings) and os.clock() + local okset = { } + local n = 0 + for s=1,#set do + local ss = set[s] + local ssname = ss.name + if add_optional and ss.optional then + if trace_virtual then + report_virtual("loading font %a subfont %s with name %a at %p is skipped",name,s,ssname,size) + end + else + if ss.features then + ssname = ssname .. "*" .. ss.features + end + if ss.main then + main = s + end + local alreadyloaded = names[ssname] -- for px we load one twice (saves .04 sec) + local f, id + if alreadyloaded then + f, id = alreadyloaded.f, alreadyloaded.id + if trace_virtual then + report_virtual("loading font %a subfont %s with name %a is reused",name,s,ssname) + end + else + f, id = fonts.constructors.readanddefine(ssname,size) + names[ssname] = { f = f, id = id } + end + if not f or id == 0 then + report_virtual("loading font %a subfont %s with name %a at %p is skipped, not found",name,s,ssname,size) + else + n = n + 1 + okset[n] = ss + loaded[n] = f + fontlist[n] = { id = id, size = size } + if not shared[s] then + shared[n] = { } + end + if trace_virtual then + report_virtual("loading font %a subfont %s with name %a at %p as id %s using encoding %a",name,s,ssname,size,id,ss.vector) + end + end + end + end + -- beware, loaded[1] is already passed to tex (we need to make a simple copy then .. todo) + local parent = loaded[1] or { } -- a text font + local characters = { } + local parameters = { } + local mathparameters = { } + local descriptions = { } + local metadata = { } + local properties = { } + local goodies = { } + local main = { + metadata = metadata, + properties = properties, + characters = characters, + descriptions = descriptions, + parameters = parameters, + mathparameters = mathparameters, + fonts = fontlist, + goodies = goodies, + } + -- + for key, value in next, parent do + if type(value) ~= "table" then + main[key] = value + end + end + -- + if parent.characters then + for unicode, character in next, parent.characters do + characters[unicode] = character + end + else + report_virtual("font %a has no characters",name) + end + -- + if parent.parameters then + for key, value in next, parent.parameters do + parameters[key] = value + end + else + report_virtual("font %a has no parameters",name) + end + -- + local description = { name = "" } + setmetatableindex(descriptions,function() return description end) + -- + if parent.properties then + setmetatableindex(properties,parent.properties) + end + -- + if parent.goodies then + setmetatableindex(goodies,parent.goodies) + end + -- + properties.hasitalics = true + properties.hasmath = true + -- + local fullname = properties.fullname -- parent via mt + if fullname then + unique = unique + 1 + properties.fullname = fullname .. "-" .. unique + end + -- + -- we need to set some values in main as well (still?) + -- + main.fullname = properties.fullname + main.nomath = false + -- + parameters.x_height = parameters.x_height or 0 + -- + local already_reported = false + local parameters_done = false + for s=1,n do + local ss, fs = okset[s], loaded[s] + if not fs then + -- skip, error + elseif add_optional and ss.optional then + -- skip, redundant + else + local newparameters = fs.parameters + local newmathparameters = fs.mathparameters + if newmathparameters then + if not parameters_done or ss.parameters then + mathparameters = newmathparameters + parameters_done = true + end + elseif not newparameters then + report_virtual("no parameters set in font %a",name) + elseif ss.extension then + mathparameters.math_x_height = newparameters.x_height or 0 -- math_x_height : height of x + mathparameters.default_rule_thickness = newparameters[ 8] or 0 -- default_rule_thickness : thickness of \over bars + mathparameters.big_op_spacing1 = newparameters[ 9] or 0 -- big_op_spacing1 : minimum clearance above a displayed op + mathparameters.big_op_spacing2 = newparameters[10] or 0 -- big_op_spacing2 : minimum clearance below a displayed op + mathparameters.big_op_spacing3 = newparameters[11] or 0 -- big_op_spacing3 : minimum baselineskip above displayed op + mathparameters.big_op_spacing4 = newparameters[12] or 0 -- big_op_spacing4 : minimum baselineskip below displayed op + mathparameters.big_op_spacing5 = newparameters[13] or 0 -- big_op_spacing5 : padding above and below displayed limits + -- report_virtual("loading and virtualizing font %a at size %p, setting ex parameters",name,size) + elseif ss.parameters then + mathparameters.x_height = newparameters.x_height or mathparameters.x_height + mathparameters.x_height = mathparameters.x_height or fp.x_height or 0 -- x_height : height of x + mathparameters.num1 = newparameters[ 8] or 0 -- num1 : numerator shift-up in display styles + mathparameters.num2 = newparameters[ 9] or 0 -- num2 : numerator shift-up in non-display, non-\atop + mathparameters.num3 = newparameters[10] or 0 -- num3 : numerator shift-up in non-display \atop + mathparameters.denom1 = newparameters[11] or 0 -- denom1 : denominator shift-down in display styles + mathparameters.denom2 = newparameters[12] or 0 -- denom2 : denominator shift-down in non-display styles + mathparameters.sup1 = newparameters[13] or 0 -- sup1 : superscript shift-up in uncramped display style + mathparameters.sup2 = newparameters[14] or 0 -- sup2 : superscript shift-up in uncramped non-display + mathparameters.sup3 = newparameters[15] or 0 -- sup3 : superscript shift-up in cramped styles + mathparameters.sub1 = newparameters[16] or 0 -- sub1 : subscript shift-down if superscript is absent + mathparameters.sub2 = newparameters[17] or 0 -- sub2 : subscript shift-down if superscript is present + mathparameters.sup_drop = newparameters[18] or 0 -- sup_drop : superscript baseline below top of large box + mathparameters.sub_drop = newparameters[19] or 0 -- sub_drop : subscript baseline below bottom of large box + mathparameters.delim1 = newparameters[20] or 0 -- delim1 : size of \atopwithdelims delimiters in display styles + mathparameters.delim2 = newparameters[21] or 0 -- delim2 : size of \atopwithdelims delimiters in non-displays + mathparameters.axis_height = newparameters[22] or 0 -- axis_height : height of fraction lines above the baseline + -- report_virtual("loading and virtualizing font %a at size %p, setting sy parameters",name,size) + end + if ss.overlay then + local fc = fs.characters + local first = ss.first + if first then + local last = ss.last or first + for unicode = first, last do + characters[unicode] = copy_glyph(main,characters,fc,unicode,s) + end + else + for unicode, data in next, fc do + characters[unicode] = copy_glyph(main,characters,fc,unicode,s) + end + end + else + local vectorname = ss.vector + if vectorname then + local offset = 0xFF000 -- todo: -- private + local vector = mathencodings[vectorname] + local rotcev = reverse[vectorname] + local isextension = ss.extension + if vector and rotcev then + local fc = fs.characters + local fd = fs.descriptions + local si = shared[s] + local skewchar = ss.skewchar + local indices = { } + -- we need to know the original order because the loader has made a + -- unicode font of it and weird glyphnames have spoiled that a bit + for unicode, character in next, fc do + indices[character.order or character.index or unicode] = unicode + end + for unicode, i in next, vector do + -- so, here we have an extra remapping (compared to mkiv) + local index = indices[i] + local fci = fc[index] + if not fci then + local fontname = fs.properties.name or "unknown" + local rf = reported[fontname] + if not rf then rf = { } reported[fontname] = rf end + local rv = rf[vectorname] + if not rv then rv = { } rf[vectorname] = rv end + local ru = rv[unicode] + if not ru then + if trace_virtual then + local d = chardata[unicode].description + if index then + report_virtual("unicode slot %U has no index %H in vector %a for font %a (%S)",unicode,index,vectorname,fontname,d) + else + report_virtual("unicode slot %U has no entry in vector %a for font %a (%S)",unicode,vectorname,fontname,d) + end + elseif not already_reported then + report_virtual("the mapping is incomplete for %a at %p",name,size) + already_reported = true + end + rv[unicode] = true + end + else + local ref = si[index] + if not ref then + ref = { { 'slot', s, index } } + si[index] = ref + end + local kerns = fci.kerns + local width = fci.width + local italic = fci.italic + if italic and italic > 0 then + -- int_a^b + if isextension then + width = width + italic -- for obscure reasons the integral as a width + italic correction + end + end + if kerns then + local krn = { } + for k, v in next, kerns do -- kerns is sparse + local rk = rotcev[k] + if rk then + krn[rk] = v -- kerns[k] + end + end + if not next(krn) then + krn = nil + end + local t = { + width = width, + height = fci.height, + depth = fci.depth, + italic = italic, + kerns = krn, + commands = ref, + } + if skewchar then + local k = kerns[skewchar] + if k then + t.top_accent = width/2 + k + end + end + characters[unicode] = t + else + characters[unicode] = { + width = width, + height = fci.height, + depth = fci.depth, + italic = italic, + commands = ref, + } + end + end + end + if isextension then + -- todo: if multiple ex, then 256 offsets per instance + local extension = mathencodings["large-to-small"] + local variants_done = fs.variants_done + for index, fci in next, fc do -- the raw ex file + if type(index) == "number" then + local ref = si[index] + if not ref then + ref = { { 'slot', s, index } } + si[index] = ref + end + local italic = fci.italic + local t = { + width = fci.width, + height = fci.height, + depth = fci.depth, + italic = italic, + commands = ref, + } + local n = fci.next + if n then + t.next = offset + n + elseif variants_done then + local vv = fci.vert_variants + if vv then + t.vert_variants = vv + end + local hv = fci.horiz_variants + if hv then + t.horiz_variants = hv + end + else + local vv = fci.vert_variants + if vv then + for i=1,#vv do + local vvi = vv[i] + vvi.glyph = vvi.glyph + offset + end + t.vert_variants = vv + end + local hv = fci.horiz_variants + if hv then + for i=1,#hv do + local hvi = hv[i] + hvi.glyph = hvi.glyph + offset + end + t.horiz_variants = hv + end + end + characters[offset + index] = t + end + end + fs.variants_done = true + for unicode, index in next, extension do + local cu = characters[unicode] + if cu then + cu.next = offset + index + else + local fci = fc[index] + if not fci then + -- do nothing + else + -- probably never entered + local ref = si[index] + if not ref then + ref = { { 'slot', s, index } } + si[index] = ref + end + local kerns = fci.kerns + if kerns then + local krn = { } + -- for k=1,#kerns do + -- krn[offset + k] = kerns[k] + -- end + for k, v in next, kerns do -- is kerns sparse? + krn[offset + k] = v + end + characters[unicode] = { + width = fci.width, + height = fci.height, + depth = fci.depth, + italic = fci.italic, + commands = ref, + kerns = krn, + next = offset + index, + } + else + characters[unicode] = { + width = fci.width, + height = fci.height, + depth = fci.depth, + italic = fci.italic, + commands = ref, + next = offset + index, + } + end + end + end + end + end + else + report_virtual("error in loading %a, problematic vector %a",name,vectorname) + end + end + end + mathematics.extras.copy(main) --not needed here (yet) + end + end + -- + main.mathparameters = mathparameters -- still traditional ones + -- This should change (some day) as it's the only place where we look forward, + -- so better is to also reserve the id already which then involves some more + -- management (so not now). + fontlist[#fontlist+1] = { + -- id = font.nextid(), + id = 0, -- self + size = size, + } + vfmath.addmissing(main,#fontlist,size) + -- + mathematics.addfallbacks(main) + -- + main.properties.math_is_scaled = true -- signal + fonts.constructors.assignmathparameters(main,main) + -- + main.MathConstants = main.mathparameters -- we directly pass it to TeX (bypasses the scaler) so this is needed + -- + if trace_virtual or trace_timings then + report_virtual("loading and virtualizing font %a at size %p took %0.3f seconds",name,size,os.clock()-start) + end + -- + main.oldmath = true + return main +end + +function mathematics.makefont(name,set,goodies) + fonts.definers.methods.variants[name] = function(specification) + return vfmath.define(specification,set,goodies) + end +end + +-- helpers + +function vfmath.setletters(font_encoding, name, uppercase, lowercase) + local enc = font_encoding[name] + for i = 0,25 do + enc[uppercase+i] = i + 0x41 + enc[lowercase+i] = i + 0x61 + end +end + +function vfmath.setdigits(font_encoding, name, digits) + local enc = font_encoding[name] + for i = 0,9 do + enc[digits+i] = i + 0x30 + end +end diff --git a/tex/context/base/mkxl/typo-cap.lmt b/tex/context/base/mkxl/typo-cap.lmt index fe7406e76..dbf6950c8 100644 --- a/tex/context/base/mkxl/typo-cap.lmt +++ b/tex/context/base/mkxl/typo-cap.lmt @@ -32,6 +32,7 @@ local getdisc = nuts.getdisc local setchar = nuts.setchar local setfont = nuts.setfont +local setscales = nuts.setscales local copy_node = nuts.copy local end_of_math = nuts.end_of_math @@ -66,6 +67,7 @@ local v_reset = variables.reset local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue +local texgetcount = tex.getcount typesetters = typesetters or { } local typesetters = typesetters @@ -80,6 +82,8 @@ local a_cases = attributes.private("case") local run = 0 -- a trick to make neighbouring ranges work local blocked = { } +local fontstate = { } -- this will become something generic + local function set(tag,font) if run < 0x7F then run = run + 1 @@ -90,6 +94,13 @@ local function set(tag,font) + (tag << 8) + (run << 0) blocked[a] = false + -- it makes sense to fetch them all at once + fontstate[a] = { + texgetcount("glyphscale"), + texgetcount("glyphxscale"), + texgetcount("glyphyscale"), + texgetcount("glyphdatafield") + } return a end @@ -206,7 +217,11 @@ local function mixed(start,attr,lastfont,n,count,where,first) elseif dc == char then local lfa = lastfont[n] if lfa then + local s = fontstate[attr] setfont(used,lfa) + if s then + setscales(used, s[1], s[2], s[3]) + end end else replacer(used,uccodes) @@ -221,7 +236,11 @@ local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3 if lfa then local dc = uccodes[getchar(used)] if dc then + local s = fontstate[attr] setfont(used,lfa) + if s then + setscales(used, s[1], s[2], s[3]) + end end end end diff --git a/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv b/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv index 2494d1af2..e3417fca5 100644 --- a/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv +++ b/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv @@ -54,8 +54,8 @@ \starttypescript [\s!math] [modern-latin] \loadfontgoodies[lm] - \definefontsynonym [MathRoman] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,lm-math-regular,mathextra},\s!goodies=lm] - \definefontsynonym [MathRomanBold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,lm-math-bold,mathextra},\s!goodies=lm] + \definefontsynonym [MathRoman] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,oldmath,lm-math-regular,mathextra},\s!goodies=lm] + \definefontsynonym [MathRomanBold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,oldmath,lm-math-bold,mathextra},\s!goodies=lm] \stoptypescript \starttypescript [modern-latin,modernlatin] diff --git a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv index 72d3b3588..d10fe505f 100644 --- a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv +++ b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv @@ -247,8 +247,8 @@ \starttypescript [\s!math][times,termes][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-termes-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman] [file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=termes-math] - \definefontsynonym[\s!MathRomanBold][file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,termes-math-bold,mathextra},\s!goodies=termes-math] + \definefontsynonym[\s!MathRoman] [file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=termes-math] + \definefontsynonym[\s!MathRomanBold][file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,termes-math-bold,mathextra},\s!goodies=termes-math] \stoptypescript \stoptypescriptcollection @@ -276,8 +276,8 @@ \starttypescript [\s!math][palatino,pagella][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-pagella-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman] [file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=pagella-math] - \definefontsynonym[\s!MathRomanBold][file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,pagella-math-bold,mathextra},\s!goodies=pagella-math] + \definefontsynonym[\s!MathRoman] [file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=pagella-math] + \definefontsynonym[\s!MathRomanBold][file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,pagella-math-bold,mathextra},\s!goodies=pagella-math] \stoptypescript \stoptypescriptcollection @@ -289,8 +289,8 @@ \starttypescript [\s!math][bookman,bonum][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-bonum-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman] [file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=bonum-math] - \definefontsynonym[\s!MathRomanBold][file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,bonum-math-bold,mathextra},\s!goodies=bonum-math] + \definefontsynonym[\s!MathRoman] [file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=bonum-math] + \definefontsynonym[\s!MathRomanBold][file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,bonum-math-bold,mathextra},\s!goodies=bonum-math] \stoptypescript \stoptypescriptcollection @@ -300,8 +300,8 @@ \starttypescript [\s!math][schoolbook,schola][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-schola-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman] [file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=schola-math] - \definefontsynonym[\s!MathRomanBold][file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,schola-math-bold,mathextra},\s!goodies=schola-math] + \definefontsynonym[\s!MathRoman] [file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,mathextra},\s!goodies=schola-math] + \definefontsynonym[\s!MathRomanBold][file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,oldmath,schola-math-bold,mathextra},\s!goodies=schola-math] \stoptypescript \stoptypescriptcollection diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml index 9e18a2793..87fe9ba15 100644 --- a/tex/context/interface/mkii/keys-nl.xml +++ b/tex/context/interface/mkii/keys-nl.xml @@ -1137,6 +1137,7 @@ + diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 0b220327c..1b6212597 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2020-12-30 16:42 +-- merge date : 2021-01-05 10:41 do -- begin closure to overcome local limits and interference @@ -9268,6 +9268,9 @@ function constructors.scale(tfmdata,specification) properties.hasmath=true target.nomath=false target.MathConstants=target.mathparameters + local oldmath=properties.oldmath + targetproperties.oldmath=oldmath + target.oldmath=oldmath else properties.hasmath=false target.nomath=true -- cgit v1.2.3