summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2023-02-14 18:21:35 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2023-02-14 18:21:35 +0100
commitcd404631d7079a9af603d173eb015f026731aa01 (patch)
tree588c6c8e860bb26955999dfc8be67eb78cc7ff7f /tex
parentd643b65f7ab840157f538914b07f8d3cddf94bec (diff)
downloadcontext-cd404631d7079a9af603d173eb015f026731aa01.tar.gz
2023-02-14 17:44:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/buff-ini.lua12
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/regi-ini.lua1
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin24576 -> 24546 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin265606 -> 265635 bytes
-rw-r--r--tex/context/base/mkiv/tabl-xtb.mkvi2
-rw-r--r--tex/context/base/mkxl/back-imp-lua.mkxl2
-rw-r--r--tex/context/base/mkxl/back-imp-mps.mkxl2
-rw-r--r--tex/context/base/mkxl/buff-ini.lmt43
-rw-r--r--tex/context/base/mkxl/buff-ini.mkxl79
-rw-r--r--tex/context/base/mkxl/buff-ver.mkxl25
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl30
-rw-r--r--tex/context/base/mkxl/data-vir.lmt104
-rw-r--r--tex/context/base/mkxl/file-ini.mklx6
-rw-r--r--tex/context/base/mkxl/font-cff.lmt2788
-rw-r--r--tex/context/base/mkxl/font-dsp.lmt57
-rw-r--r--tex/context/base/mkxl/font-lib.mklx25
-rw-r--r--tex/context/base/mkxl/font-map.lmt518
-rw-r--r--tex/context/base/mkxl/font-onr.lmt8
-rw-r--r--tex/context/base/mkxl/font-tpk.lmt100
-rw-r--r--tex/context/base/mkxl/font-ttf.lmt1496
-rw-r--r--tex/context/base/mkxl/libs-ini.lmt206
-rw-r--r--tex/context/base/mkxl/libs-ini.mkxl6
-rw-r--r--tex/context/base/mkxl/luat-lib.mkxl2
-rw-r--r--tex/context/base/mkxl/math-act.lmt15
-rw-r--r--tex/context/base/mkxl/math-rad.mklx36
-rw-r--r--tex/context/base/mkxl/math-stc.mklx92
-rw-r--r--tex/context/base/mkxl/math-ttv.lmt543
-rw-r--r--tex/context/base/mkxl/math-vfu.lmt20
-rw-r--r--tex/context/base/mkxl/node-bck.mkxl2
-rw-r--r--tex/context/base/mkxl/node-fin.mkxl4
-rw-r--r--tex/context/base/mkxl/node-rul.mkxl2
-rw-r--r--tex/context/base/mkxl/pack-rul.mkxl2
-rw-r--r--tex/context/base/mkxl/regi-ini.lmt367
-rw-r--r--tex/context/base/mkxl/regi-ini.mkxl21
-rw-r--r--tex/context/base/mkxl/spac-ali.mkxl2
-rw-r--r--tex/context/base/mkxl/spac-chr.mkxl2
-rw-r--r--tex/context/base/mkxl/spac-hor.mkxl16
-rw-r--r--tex/context/base/mkxl/spac-ver.mkxl4
-rw-r--r--tex/context/base/mkxl/strc-flt.mklx52
-rw-r--r--tex/context/base/mkxl/strc-lst.lmt33
-rw-r--r--tex/context/base/mkxl/strc-ref.mklx2
-rw-r--r--tex/context/base/mkxl/supp-box.mkxl2
-rw-r--r--tex/context/base/mkxl/tabl-xtb.mklx2
-rw-r--r--tex/context/base/mkxl/type-set.mkxl6
-rw-r--r--tex/context/base/mkxl/typo-lan.lmt89
-rw-r--r--tex/context/base/mkxl/typo-lan.mkxl72
-rw-r--r--tex/context/base/mkxl/typo-pnc.lmt170
-rw-r--r--tex/context/base/mkxl/typo-pnc.mkxl2
-rw-r--r--tex/context/fonts/mkiv/antykwa-math.lfg18
-rw-r--r--tex/context/fonts/mkiv/bonum-math.lfg12
-rw-r--r--tex/context/fonts/mkiv/type-imp-antykwa.mkiv141
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
57 files changed, 6525 insertions, 728 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index c61c97d8a..736e64033 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{2023.02.07 19:02}
+\newcontextversion{2023.02.14 17: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 b62aa3a85..3337f07f0 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{2023.02.07 19:02}
+\edef\contextversion{2023.02.14 17:41}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/buff-ini.lua b/tex/context/base/mkiv/buff-ini.lua
index 9af76f72e..f23344eda 100644
--- a/tex/context/base/mkiv/buff-ini.lua
+++ b/tex/context/base/mkiv/buff-ini.lua
@@ -816,7 +816,7 @@ local function getbuffermkvi(name) -- rather direct !
ctx_viafile(resolvers.macros.preprocessed(getcontent(name)),formatters["buffer.%s.mkiv"](validstring(name,"noname")))
end
-local function gettexbuffer(name)
+local function getbuffertex(name)
local buffer = name and cache[name]
if buffer and buffer.data ~= "" then
ctx_pushcatcodetable()
@@ -831,15 +831,15 @@ local function gettexbuffer(name)
end
end
-buffers.get = getbuffer
-buffers.getmkiv = getbuffermkiv
-buffers.gettexbuffer = gettexbuffer
-buffers.run = runbuffer
+buffers.get = getbuffer
+buffers.getmkvi = getbuffermkvi
+buffers.gettex = getbuffertex
+buffers.run = runbuffer
implement { name = "getbufferctxlua", actions = loadcontent, arguments = "string" }
implement { name = "getbuffer", actions = getbuffer, arguments = "string" }
implement { name = "getbuffermkvi", actions = getbuffermkvi, arguments = "string" }
-implement { name = "gettexbuffer", actions = gettexbuffer, arguments = "string" }
+implement { name = "getbuffertex", actions = getbuffertex, arguments = "string" }
interfaces.implement {
name = "getbuffercontent",
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index d524240e6..b525836df 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{2023.02.07 19:02}
+\newcontextversion{2023.02.14 17: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 1e3ce084e..a5e343291 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -49,7 +49,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2023.02.07 19:02}
+\edef\contextversion{2023.02.14 17:41}
%D Kind of special:
diff --git a/tex/context/base/mkiv/regi-ini.lua b/tex/context/base/mkiv/regi-ini.lua
index 8d4f2bfd5..2a3b2caaf 100644
--- a/tex/context/base/mkiv/regi-ini.lua
+++ b/tex/context/base/mkiv/regi-ini.lua
@@ -16,7 +16,6 @@ runtime.</p>
local commands, context = commands, context
-
local tostring = tostring
local utfchar = utf.char
local P, Cs, Cc, lpegmatch = lpeg.P, lpeg.Cs, lpeg.Cc, lpeg.match
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index cf4d8480a..70fe4d224 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 258228978..9540ac450 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/tabl-xtb.mkvi b/tex/context/base/mkiv/tabl-xtb.mkvi
index 3f3ef4be3..c340efdfa 100644
--- a/tex/context/base/mkiv/tabl-xtb.mkvi
+++ b/tex/context/base/mkiv/tabl-xtb.mkvi
@@ -267,7 +267,7 @@
}% else whitespace mess
\def\tabl_x_get_buffer
- {\clf_gettexbuffer{\tabl_x_current_buffer}}
+ {\clf_getbuffertex{\tabl_x_current_buffer}}
\let\tabl_x_start_row_yes \relax
\let\tabl_x_start_row_nop \relax
diff --git a/tex/context/base/mkxl/back-imp-lua.mkxl b/tex/context/base/mkxl/back-imp-lua.mkxl
index db26657ef..641123842 100644
--- a/tex/context/base/mkxl/back-imp-lua.mkxl
+++ b/tex/context/base/mkxl/back-imp-lua.mkxl
@@ -11,6 +11,6 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\registerctxluafile{back-imp-lua}{autosuffix,optimize}
+\registerctxluafile{back-imp-lua}{autosuffix}
\endinput
diff --git a/tex/context/base/mkxl/back-imp-mps.mkxl b/tex/context/base/mkxl/back-imp-mps.mkxl
index 45dde7e36..bda053706 100644
--- a/tex/context/base/mkxl/back-imp-mps.mkxl
+++ b/tex/context/base/mkxl/back-imp-mps.mkxl
@@ -11,6 +11,6 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\registerctxluafile{back-imp-mps}{autosuffix,optimize}
+\registerctxluafile{back-imp-mps}{autosuffix}
\endinput
diff --git a/tex/context/base/mkxl/buff-ini.lmt b/tex/context/base/mkxl/buff-ini.lmt
index 1d4722531..9f5535638 100644
--- a/tex/context/base/mkxl/buff-ini.lmt
+++ b/tex/context/base/mkxl/buff-ini.lmt
@@ -88,12 +88,19 @@ local buffers = buffers
local cache = { }
local function erase(name)
- cache[name] = nil
+ if not name or name == "" then
+ cache[""] = false -- nil
+ else
+ local list = settings_to_array(name)
+ for i=1,#list do
+ cache[list[i]] = false -- nil
+ end
+ end
end
local assign do
- -- Ther eis no gain in an immediate concatenating lpeg
+ -- There is no gain in an immediate concatenating lpeg
local action = whitespace^0 * C(P("+")^1 + P("*")) * whitespace^0
local equal = whitespace^0 * patterns.equal * whitespace^0
@@ -708,12 +715,17 @@ local function runbuffer(name,encapsulate,runnername,suffixes)
end
local f_getbuffer = formatters["buffer.%s"]
+local defaultlist = { "" }
local function getbuffer(name)
- local str = getcontent(name)
- if str ~= "" then
- -- characters.showstring(str)
- ctx_viafile(str,f_getbuffer(validstring(name,"noname")))
+ local list = name and name ~= "" and settings_to_array(name) or defaultlist
+ for i=1,#list do
+ local buf = list[i]
+ local str = getcontent(buf)
+ if str ~= "" then
+ -- characters.showstring(str)
+ ctx_viafile(str,f_getbuffer(validstring(buf,"noname")))
+ end
end
end
@@ -721,7 +733,7 @@ local function getbuffermkvi(name) -- rather direct !
ctx_viafile(resolvers.macros.preprocessed(getcontent(name)),formatters["buffer.%s.mkiv"](validstring(name,"noname")))
end
-local function gettexbuffer(name)
+local function getbuffertex(name)
local buffer = name and cache[name]
if buffer and buffer.data ~= "" then
ctx_pushcatcodetable()
@@ -736,15 +748,16 @@ local function gettexbuffer(name)
end
end
-buffers.get = getbuffer
-buffers.getmkiv = getbuffermkiv
-buffers.gettexbuffer = gettexbuffer
-buffers.run = runbuffer
+buffers.get = getbuffer
+buffers.getmkvi = getbuffermkvi
+buffers.gettex = getbuffertex
+buffers.getctxlua = loadcontent
+buffers.run = runbuffer
-implement { name = "getbufferctxlua", actions = loadcontent, arguments = "string" }
-implement { name = "getbuffer", actions = getbuffer, arguments = "string" }
-implement { name = "getbuffermkvi", actions = getbuffermkvi, arguments = "string" }
-implement { name = "gettexbuffer", actions = gettexbuffer, arguments = "string" }
+implement { name = "getbufferctxlua", actions = loadcontent, arguments = "argument" }
+implement { name = "getbuffer", actions = getbuffer, arguments = "argument" }
+implement { name = "getbuffermkvi", actions = getbuffermkvi, arguments = "argument" }
+implement { name = "getbuffertex", actions = getbuffertex, arguments = "argument" }
interfaces.implement {
name = "getbuffercontent",
diff --git a/tex/context/base/mkxl/buff-ini.mkxl b/tex/context/base/mkxl/buff-ini.mkxl
index d192a01ea..0bc4d665f 100644
--- a/tex/context/base/mkxl/buff-ini.mkxl
+++ b/tex/context/base/mkxl/buff-ini.mkxl
@@ -107,9 +107,9 @@
\permanent\tolerant\protected\def\setbuffer[#1]#:#2\endbuffer % seldom used so we just pass #2
{\clf_assignbuffer{#1}{\detokenize{#2}}\catcodetable\relax}
-% beware, never adapt the global buffer settings, actually we might introduce
+% Beware, never adapt the global buffer settings, actually we might introduce
% a broken parent chain for this purpose but on the other hand it's not that
-% different from framed cum suis
+% different from framed cum suis.
\installcorenamespace{buffer}
@@ -143,35 +143,40 @@
\permanent\def\thebuffernumber #1{\namedbufferparameter{#1}\c!number}
\permanent\def\thedefinedbuffer#1{def-\namedbufferparameter{#1}\c!number}
-\permanent\tolerant\protected\def\getbuffer[#1]% [name]
+\permanent\def\getbufferdata[#1]% expandable
+ {\clf_getbuffer{#1}}
+
+\permanent\tolerant\protected\def\getbuffer[#1]% [namelist]
{\namedbufferparameter\empty\c!before\relax
- \doifelsenothing{#1}
- {\buff_get_stored_indeed\empty}
- {\processcommalist[#1]\buff_get_stored_indeed}%
+ \clf_getbuffer{#1}%
\namedbufferparameter\empty\c!after\relax}
\protected\def\buff_get_stored#1#2%
{\namedbufferparameter{#1}\c!before\relax
- \buff_get_stored_indeed{#2}%
+ \clf_getbuffer{#2}%
\namedbufferparameter{#1}\c!after\relax}
-\protected\def\buff_get_stored_indeed#1%
- {\clf_getbuffer{#1}}
+\aliased\let\rawbuffer\clf_getbuffer % expandable
\permanent\protected\def\getdefinedbuffer[#1]%
{\buff_get_stored{#1}{\thedefinedbuffer{#1}}}%
-\permanent\tolerant\protected\def\inlinebuffer[#1]% [name]
- {\doifelsenothing{#1}
- {\buff_get_stored_inline_indeed\empty}
- {\processcommalist[#1]\buff_get_stored_inline_indeed}}
+% We had this:
+%
+% \permanent\tolerant\protected\def\inlinebuffer[#1]% [name]
+% {\doifelsenothing{#1}
+% {\buff_get_stored_inline_indeed\empty}
+% {\processcommalist[#1]\buff_get_stored_inline_indeed}}
+%
+% \protected\def\buff_get_stored_inline_indeed#1%
+% {\ignorespaces\clf_getbuffer{#1}\removeunwantedspaces}
+%
+% but it makes no sense to ignore spaces in between and we now do the
+% list at the \LUA\ end anyway:
-\protected\def\buff_get_stored_inline_indeed#1%
+\permanent\tolerant\protected\def\inlinebuffer[#1]% [name]
{\ignorespaces\clf_getbuffer{#1}\removeunwantedspaces}
-\permanent\def\rawbuffer#1% expandable
- {\clf_getbuffer{#1}}
-
\definebuffer
[\v!hiding]
@@ -180,20 +185,14 @@
[\c!before=,
\c!after=]
-\permanent\protected\protected\def\processTEXbuffer[#1]% keep case, maybe also lower
- {\pushcatcodetable
- \catcodetable\ctxcatcodes % \setcatcodetable
- \buff_get_stored_indeed{#1}%
- \popcatcodetable}
-
-% only mkiv:
-%
-% \startbuffer[x]
-% x
-% \stopbuffer
-%
-% \savebuffer[x] [temp] % gets name: jobname-temp.tmp
-% \savebufferinfile[x][temp.log] % gets name: temp.log
+%D \starttyping
+%D \startbuffer[x]
+%D x y z
+%D \stopbuffer
+%D
+%D \savebuffer[x] [temp] % gets name: jobname-temp.tmp
+%D \savebufferinfile[x][temp.log] % gets name: temp.log
+%D \stoptyping
\installcorenamespace{savebuffer}
\installcorenamespace{savebuffercounter}
@@ -242,6 +241,9 @@
%D \stoptext
%D \stoptyping
+% We can keep the counter at the lua end and explicitly reset it when we
+% save.
+
\appendtoks
\ifcsname\e!stop\currentsavebuffer\endcsname\else
\definebuffer[\currentsavebuffer]%
@@ -272,8 +274,15 @@
%
% \ctxluabuffer[what] \ctxluabuffer
-\permanent\tolerant\protected\def\ctxluabuffer[#1]{\clf_getbufferctxlua{#1}} % todo: use public implementor
-\permanent\tolerant\protected\def\mkvibuffer [#1]{\clf_getbuffermkvi {#1}} % todo: use public implementor
+\permanent\tolerant\protected\def\processTEXbuffer[#1]#;#=% keep case, maybe also lower
+ {\pushcatcodetable
+ \catcodetable\ctxcatcodes % \setcatcodetable
+ \clf_getbuffer{#1#2}%
+ \popcatcodetable}
+
+\permanent\tolerant\protected\def\ctxluabuffer[#1]#;#={\clf_getbufferctxlua{#1#2}} % todo: use public implementor
+\permanent\tolerant\protected\def\mkvibuffer [#1]#;#={\clf_getbuffermkvi {#1#2}} % todo: use public implementor
+\permanent\tolerant\protected\def\texbuffer [#1]#;#={\clf_getbuffertex {#1#2}} % todo: use public implementor
% maybe still used elsewhere
@@ -281,10 +290,6 @@
\aliased\let\dostartbuffer\grabbufferdata % for old times sake, this will go away
-% new (expandable):
-
-\permanent\def\getbufferdata[#1]{\buff_get_stored_indeed{#1}}
-
% low level helper (for math manual):
% \showboxinbuffer{temp}<boxnumber><detail> % defined in lua, detail cf \shownodedetails 0|1|2
diff --git a/tex/context/base/mkxl/buff-ver.mkxl b/tex/context/base/mkxl/buff-ver.mkxl
index 461807162..8c42694a3 100644
--- a/tex/context/base/mkxl/buff-ver.mkxl
+++ b/tex/context/base/mkxl/buff-ver.mkxl
@@ -31,7 +31,6 @@
\installcorenamespace{typinglines}
\installcorenamespace{typingspace}
-\installcorenamespace{typingblank} % needs checking ... used?
\newtoks\everyinitializeverbatim
@@ -58,14 +57,6 @@
\defcsname\??typingspace\v!fixed \endcsname{\enforced\let\obeyedspace\specialfixedspace}
\defcsname\??typingspace\v!character \endcsname{\enforced\chardef\obeyedspace\spaceasciicode}
-\defcsname\??typingblank\v!standard \endcsname{\s_spac_whitespace_parskip}
-\defcsname\??typingblank\v!small \endcsname{\smallskipamount}
-\defcsname\??typingblank\v!medium \endcsname{\medskipamount}
-\defcsname\??typingblank\v!big \endcsname{\bigskipamount}
-\defcsname\??typingblank\v!halfline \endcsname{.5\baselineskip}
-\defcsname\??typingblank\v!line \endcsname{\baselineskip}
-\defcsname\??typingblank\v!none \endcsname{\zeropoint}
-
\protected\def\buff_verbatim_obey_hyphens
{}
@@ -109,12 +100,10 @@
\def\buff_verbatim_initialize_typing_one
{\usebodyfontparameter\typingparameter
- \scratchskip\typingparameter\c!oddmargin\relax
- \ifzeropt\scratchskip \else
+ \ifzerodim\typingparameter\c!oddmargin\else
\let\buff_verbatim_set_line_margin\buff_verbatim_set_line_margin_indeed
\fi
- \scratchskip\typingparameter\c!evenmargin\relax
- \ifzeropt\scratchskip \else
+ \ifzerodim\typingparameter\c!evenmargin\else
\let\buff_verbatim_set_line_margin\buff_verbatim_set_line_margin_indeed
\fi
\ifrelax\buff_verbatim_set_line_margin
@@ -289,8 +278,8 @@
\futureexpand\bgroup\buff_verbatim_type_a\buff_verbatim_type_one}
\def\buff_verbatim_type_one
- {\catcode`<=\othercatcode % old precaution
- \catcode`>=\othercatcode % old precaution
+ {\catcode\lessthanasciicode\othercatcode % old precaution
+ \catcode\morethanasciicode\othercatcode % old precaution
\futureexpandis<\buff_verbatim_type_b\buff_verbatim_type_c}
\def\buff_verbatim_type_three
@@ -461,10 +450,10 @@
\futureexpandis[\buff_verbatim_typing_start_yes\buff_verbatim_typing_start_nop}
\def\buff_verbatim_typing_start_yes[#1]%
- {\ifcondition\validassignment{#1}%
+ {\ifhastok={#1}%
\setupcurrenttyping[#1]%
- \else
- \doif\v!continue{#1}{\lettypingparameter\c!continue\v!yes}%
+ \orelse\ifcstok{#1}\v!continue
+ \lettypingparameter\c!continue\v!yes
\fi
\typingparameter\c!before\relax % moved down
\startpacked[\v!blank]% % moved down
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 9a267bc5f..667b2bc6d 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{2023.02.07 19:02}
+\newcontextversion{2023.02.14 17: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 143c67ffb..b0539ce74 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{2023.02.07 19:02}
+\immutable\edef\contextversion{2023.02.14 17:41}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
@@ -642,8 +642,16 @@
\errorstopmode \dump \endinput
-% These lua files are (still) shared with mkiv amd some are large and
-% rather generic. However there are some that can be improved in lmtx.
+% Some lua files are (still) shared with mkiv amd some are large and rather
+% generic. However there are some that can be improved in lmtx. At some point
+% we will definitely freeze mkiv and then use lmt files for futher development
+% of lmtx. We also no longer use the macro feature to replace 5.3 compatible
+% function calls by native 5.4 features as lmt files assume 5.4 anyway. This
+% makes format generation a little faster (not that it's that slow). It might \
+% take a while before we dealt with all of them because I'll also clean them
+% up a bit when doing.
+%
+% % luat-bas.mkxl l-macro-imp-optimize % this will go away
% c:/data/develop/context/sources/attr-eff.lua
% c:/data/develop/context/sources/attr-mkr.lua
@@ -689,6 +697,8 @@
% c:/data/develop/context/sources/core-dat.lua
% c:/data/develop/context/sources/core-two.lua
+% data...
+
% c:/data/develop/context/sources/file-ini.lua
% c:/data/develop/context/sources/file-lib.lua
% c:/data/develop/context/sources/file-res.lua
@@ -697,14 +707,11 @@
% c:/data/develop/context/sources/font-afk.lua
% c:/data/develop/context/sources/font-agl.lua
% c:/data/develop/context/sources/font-aux.lua
-% c:/data/develop/context/sources/font-cff.lua
% c:/data/develop/context/sources/font-cid.lua
% c:/data/develop/context/sources/font-enc.lua
% c:/data/develop/context/sources/font-log.lua
% c:/data/develop/context/sources/font-lua.lua % not realy used, more a demo
-% c:/data/develop/context/sources/font-map.lua
% c:/data/develop/context/sources/font-nod.lua % some trace helpers
-% c:/data/develop/context/sources/font-onr.lua % type one afm/pfb
% c:/data/develop/context/sources/font-osd.lua
% c:/data/develop/context/sources/font-otc.lua
% c:/data/develop/context/sources/font-oth.lua
@@ -720,7 +727,6 @@
% c:/data/develop/context/sources/font-sol.lua
% c:/data/develop/context/sources/font-syn.lua % identification code
% c:/data/develop/context/sources/font-trt.lua
-% c:/data/develop/context/sources/font-ttf.lua
% c:/data/develop/context/sources/font-web.lua % proof of concept, never used
% c:/data/develop/context/sources/font-imp-combining.lua % shared, like typescript
@@ -753,8 +759,6 @@
% c:/data/develop/context/sources/lang-txt.lua % these are data files
% c:/data/develop/context/sources/lang-wrd.lua
-% c:/data/develop/context/sources/libs-ini.lua % will become lmt
-
% c:/data/develop/context/sources/luat-exe.lua
% c:/data/develop/context/sources/luat-iop.lua
% c:/data/develop/context/sources/luat-mac.lua % will become lmt
@@ -790,7 +794,7 @@
% c:/data/develop/context/sources/phys-dim.lua
-% c:/data/develop/context/sources/publ-aut.lua
+% c:/data/develop/context/sources/publ-aut.lua % shared
% c:/data/develop/context/sources/publ-dat.lua
% c:/data/develop/context/sources/publ-fnd.lua
% c:/data/develop/context/sources/publ-inc.lua
@@ -802,8 +806,6 @@
% c:/data/develop/context/sources/publ-tra.lua
% c:/data/develop/context/sources/publ-usr.lua
-% c:/data/develop/context/sources/regi-ini.lua
-
% c:/data/develop/context/sources/scrn-but.lua
% c:/data/develop/context/sources/scrn-fld.lua
% c:/data/develop/context/sources/scrn-hlp.lua
@@ -838,13 +840,11 @@
% c:/data/develop/context/sources/trac-par.lua
% c:/data/develop/context/sources/trac-tex.lua
-% c:/data/develop/context/sources/typo-cln.lua
+% c:/data/develop/context/sources/typo-cln.lua -- wrong name for what it does
% c:/data/develop/context/sources/typo-dha.lua
% c:/data/develop/context/sources/typo-fkr.lua
% c:/data/develop/context/sources/typo-inj.lua
-% c:/data/develop/context/sources/typo-lan.lua
% c:/data/develop/context/sources/typo-man.lua
-% c:/data/develop/context/sources/typo-pnc.lua
% c:/data/develop/context/sources/typo-prc.lua
% c:/data/develop/context/sources/typo-rep.lua
diff --git a/tex/context/base/mkxl/data-vir.lmt b/tex/context/base/mkxl/data-vir.lmt
new file mode 100644
index 000000000..b78211fc9
--- /dev/null
+++ b/tex/context/base/mkxl/data-vir.lmt
@@ -0,0 +1,104 @@
+if not modules then modules = { } end modules ['data-vir'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type = type
+local formatters = string.formatters
+
+local trace_virtual = false
+local report_virtual = logs.reporter("resolvers","virtual")
+
+trackers.register("resolvers.locating", function(v) trace_virtual = v end)
+trackers.register("resolvers.virtual", function(v) trace_virtual = v end)
+
+local resolvers = resolvers
+local savers = resolvers.savers
+local cleaners = resolvers.cleaners
+
+local data = { }
+local n = 0 -- hm, number can be query
+local f_virtual_n = formatters["virtual://%s.%s"]
+local f_virtual_y = formatters["virtual://%s-%s.%s"]
+
+function savers.virtual(specification,content,suffix)
+ n = n + 1 -- one number for all namespaces
+ local path = type(specification) == "table" and specification.path or specification
+ if type(path) ~= "string" or path == "" then
+ path = "virtualfile"
+ end
+ local filename = suffix and f_virtual_y(path,n,suffix) or f_virtual_n(path,n)
+ if trace_virtual then
+ report_virtual("saver: file %a saved",filename)
+ end
+ data[filename] = content
+ return filename
+end
+
+function cleaners.virtual(filename)
+ data[filename] = nil
+end
+
+local finders = resolvers.finders
+local notfound = finders.notfound
+
+function finders.virtual(specification)
+ local original = specification.original
+ local d = data[original]
+ if d then
+ if trace_virtual then
+ report_virtual("finder: file %a found",original)
+ end
+ return original
+ else
+ if trace_virtual then
+ report_virtual("finder: unknown file %a",original)
+ end
+ return notfound()
+ end
+end
+
+local openers = resolvers.openers
+local notfound = openers.notfound
+local textopener = openers.helpers.textopener
+
+function openers.virtual(specification)
+ local original = specification.original
+ local d = data[original]
+ if d then
+ if trace_virtual then
+ report_virtual("opener: file %a opened",original)
+ end
+ data[original] = nil -- when we comment this we can have error messages
+ -- With utf-8 we signal that no regime is to be applied!
+ -- characters.showstring(d)
+ return textopener("virtual",original,d,"utf-8")
+ else
+ if trace_virtual then
+ report_virtual("opener: file %a not found",original)
+ end
+ return notfound()
+ end
+end
+
+local loaders = resolvers.loaders
+local notfound = loaders.notfound
+
+function loaders.virtual(specification)
+ local original = specification.original
+ local d = data[original]
+ if d then
+ if trace_virtual then
+ report_virtual("loader: file %a loaded",original)
+ end
+ data[original] = nil
+ return true, d, #d
+ end
+ if trace_virtual then
+ report_virtual("loader: file %a not loaded",original)
+ end
+ return notfound()
+end
diff --git a/tex/context/base/mkxl/file-ini.mklx b/tex/context/base/mkxl/file-ini.mklx
index 106536eea..7c4645a9a 100644
--- a/tex/context/base/mkxl/file-ini.mklx
+++ b/tex/context/base/mkxl/file-ini.mklx
@@ -99,11 +99,11 @@
\the\everystartreadingfile
\pushcatcodetable % saveguard
\setcatcodetable\ctxcatcodes
- \clf_pushregime}% temporarily this way
+ \pushregime}% temporarily this way
\permanent\protected\def\stopreadingfile
- {\popcatcodetable % saveguard
- \clf_popregime % temporarily this way
+ {\popcatcodetable % saveguard
+ \popregime % temporarily this way
\the\everystopreadingfile
\global\advanceby\readingfilelevel\minusone}
diff --git a/tex/context/base/mkxl/font-cff.lmt b/tex/context/base/mkxl/font-cff.lmt
new file mode 100644
index 000000000..dc5f98382
--- /dev/null
+++ b/tex/context/base/mkxl/font-cff.lmt
@@ -0,0 +1,2788 @@
+if not modules then modules = { } end modules ['font-cff'] = {
+ version = 1.001,
+ optimize = true,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: option.outlines
+-- todo: option.boundingbox
+-- per charstring (less memory)
+
+-- This is a heavy one as it is a rather packed format. We don't need al the information
+-- now but we might need it later (who know what magic we can do with metapost). So at
+-- some point this might become a module. We just follow Adobe Technical Notes #5176 and
+-- #5177. In case of doubt I looked in the fontforge code that comes with LuaTeX but
+-- it's not the easiest source to read (and doesn't cover cff2).
+
+-- For now we save the segments in a list of segments with the operator last in an entry
+-- because that reflects the original. But it might make more sense to use a single array
+-- per segment. For pdf a simple concat works ok, but for other purposes a operator first
+-- flush is nicer.
+--
+-- In retrospect I could have looked into the backend code of LuaTeX but it never
+-- occurred to me that parsing charstrings was needed there (which has to to
+-- with merging subroutines and flattening, not so much with calculations.) On
+-- the other hand, we can now feed back cff2 stuff.
+
+local next, type, tonumber, rawget = next, type, tonumber, rawget
+local byte, char, gmatch, sub = string.byte, string.char, string.gmatch, string.sub
+local concat, insert, remove, unpack = table.concat, table.insert, table.remove, table.unpack
+local floor, abs, round, ceil, min, max = math.floor, math.abs, math.round, math.ceil, math.min, math.max
+local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct
+local lpegmatch = lpeg.match
+local formatters = string.formatters
+local bytetable = string.bytetable
+----- rshift, band, extract = bit32.rshift, bit32.band, bit32.extract
+
+local readers = fonts.handlers.otf.readers
+local streamreader = readers.streamreader
+
+local readstring = streamreader.readstring
+local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
+local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
+local readuint = streamreader.readcardinal3 -- 24-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 32-bit unsigned integer
+local setposition = streamreader.setposition
+local getposition = streamreader.getposition
+local readbytetable = streamreader.readbytetable
+
+directives.register("fonts.streamreader",function()
+
+ streamreader = utilities.streams
+
+ readstring = streamreader.readstring
+ readbyte = streamreader.readcardinal1
+ readushort = streamreader.readcardinal2
+ readuint = streamreader.readcardinal3
+ readulong = streamreader.readcardinal4
+ setposition = streamreader.setposition
+ getposition = streamreader.getposition
+ readbytetable = streamreader.readbytetable
+
+end)
+
+local setmetatableindex = table.setmetatableindex
+
+local trace_charstrings = false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings = v end)
+local report = logs.reporter("otf reader","cff")
+
+local parsedictionaries
+local parsecharstring
+local parsecharstrings
+local resetcharstrings
+local parseprivates
+local startparsing
+local stopparsing
+
+local defaultstrings = { [0] = -- taken from ff
+ ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
+ "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
+ "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H",
+ "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
+ "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum",
+ "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
+ "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
+ "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent",
+ "sterling", "fraction", "yen", "florin", "section", "currency",
+ "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft",
+ "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl",
+ "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase",
+ "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown",
+ "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent",
+ "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash",
+ "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+ "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior",
+ "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn",
+ "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters",
+ "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior",
+ "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring",
+ "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave",
+ "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute",
+ "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute",
+ "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+ "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde",
+ "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute",
+ "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex",
+ "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex",
+ "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+ "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
+ "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+ "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle",
+ "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle",
+ "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior",
+ "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+ "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior",
+ "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+ "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior",
+ "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall",
+ "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall",
+ "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+ "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall",
+ "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah",
+ "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall",
+ "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall",
+ "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior",
+ "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth",
+ "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds",
+ "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior",
+ "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
+ "oneinferior", "twoinferior", "threeinferior", "fourinferior",
+ "fiveinferior", "sixinferior", "seveninferior", "eightinferior",
+ "nineinferior", "centinferior", "dollarinferior", "periodinferior",
+ "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall",
+ "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+ "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
+ "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall",
+ "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall",
+ "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall",
+ "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall",
+ "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003",
+ "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold",
+}
+
+local standardnames = { [0] = -- needed for seac
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false,
+ "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
+ "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
+ "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H",
+ "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
+ "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum",
+ "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
+ "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
+ "z", "braceleft", "bar", "braceright", "asciitilde", false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, "exclamdown",
+ "cent", "sterling", "fraction", "yen", "florin", "section", "currency",
+ "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft",
+ "guilsinglright", "fi", "fl", false, "endash", "dagger", "daggerdbl",
+ "periodcentered", false, "paragraph", "bullet", "quotesinglbase",
+ "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand",
+ false, "questiondown", false, "grave", "acute", "circumflex", "tilde",
+ "macron", "breve", "dotaccent", "dieresis", false, "ring", "cedilla", false,
+ "hungarumlaut", "ogonek", "caron", "emdash", false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, "AE", false, "ordfeminine", false, false, false, false, "Lslash",
+ "Oslash", "OE", "ordmasculine", false, false, false, false, false, "ae",
+ false, false, false, "dotlessi", false, false, "lslash", "oslash", "oe",
+ "germandbls", false, false, false, false
+}
+
+local cffreaders = {
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+}
+
+directives.register("fonts.streamreader",function()
+ cffreaders = {
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+ }
+end)
+
+-- The header contains information about its own size.
+
+local function readheader(f)
+ local offset = getposition(f)
+ local major = readbyte(f)
+ local header = {
+ offset = offset,
+ major = major,
+ minor = readbyte(f),
+ size = readbyte(f), -- headersize
+ }
+ if major == 1 then
+ header.dsize = readbyte(f) -- list of dict offsets
+ elseif major == 2 then
+ header.dsize = readushort(f) -- topdict size
+ else
+ -- I'm probably no longer around by then and we use AI's to
+ -- handle this kind of stuff, if we typeset documents at all.
+ end
+ setposition(f,offset+header.size)
+ return header
+end
+
+-- The indexes all look the same, so we share a loader. We could pass a handler
+-- and run over the array but why bother, we only have a few uses.
+
+local function readlengths(f,longcount)
+ local count = longcount and readulong(f) or readushort(f)
+ if count == 0 then
+ return { }
+ end
+ local osize = readbyte(f)
+ local read = cffreaders[osize]
+ if not read then
+ report("bad offset size: %i",osize)
+ return { }
+ end
+ local lengths = { }
+ local previous = read(f)
+ for i=1,count do
+ local offset = read(f)
+ local length = offset - previous
+ if length < 0 then
+ report("bad offset: %i",length)
+ length = 0
+ end
+ lengths[i] = length
+ previous = offset
+ end
+ return lengths
+end
+
+-- There can be subfonts so names is an array. However, in our case it's always
+-- one font. The same is true for the top dictionaries. Watch how we only load
+-- the dictionary string as for interpretation we need to have the strings loaded
+-- as well.
+
+local function readfontnames(f)
+ local names = readlengths(f)
+ for i=1,#names do
+ names[i] = readstring(f,names[i])
+ end
+ return names
+end
+
+local function readtopdictionaries(f)
+ local dictionaries = readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i] = readstring(f,dictionaries[i])
+ end
+ return dictionaries
+end
+
+-- Strings are added to a list of standard strings so we start the font specific
+-- one with an offset. Strings are shared so we have one table.
+
+local function readstrings(f)
+ local lengths = readlengths(f)
+ local strings = setmetatableindex({ }, defaultstrings)
+ local index = #defaultstrings
+ for i=1,#lengths do
+ index = index + 1
+ strings[index] = readstring(f,lengths[i])
+ end
+ return strings
+end
+
+-- Parsing the dictionaries is delayed till we have the strings loaded. The parser
+-- is stack based so the operands come before the operator (like in postscript).
+
+-- local function delta(t)
+-- local n = #t
+-- if n > 1 then
+-- local p = t[1]
+-- for i=2,n do
+-- local c = t[i]
+-- t[i] = c + p
+-- p = c
+-- end
+-- end
+-- end
+
+do
+
+ -- We use a closure so that we don't need to pass too much around. For cff2 we can
+ -- at some point use a simple version as there is less.
+
+ local stack = { }
+ local top = 0
+ local result = { }
+ local strings = { }
+
+ local p_single =
+ P("\00") / function()
+ result.version = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\01") / function()
+ result.notice = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\02") / function()
+ result.fullname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\03") / function()
+ result.familyname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\04") / function()
+ result.weight = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\05") / function()
+ result.fontbbox = { unpack(stack,1,4) }
+ top = 0
+ end
+ + P("\06") / function()
+ result.bluevalues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\07") / function()
+ result.otherblues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\08") / function()
+ result.familyblues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\09") / function()
+ result.familyotherblues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\10") / function()
+ result.stdhw = stack[top]
+ top = 0
+ end
+ + P("\11") / function()
+ result.stdvw = stack[top]
+ top = 0
+ end
+ + P("\13") / function()
+ result.uniqueid = stack[top]
+ top = 0
+ end
+ + P("\14") / function()
+ result.xuid = concat(stack,"",1,top)
+ top = 0
+ end
+ + P("\15") / function()
+ result.charset = stack[top]
+ top = 0
+ end
+ + P("\16") / function()
+ result.encoding = stack[top]
+ top = 0
+ end
+ + P("\17") / function() -- valid cff2
+ result.charstrings = stack[top]
+ top = 0
+ end
+ + P("\18") / function()
+ result.private = {
+ size = stack[top-1],
+ offset = stack[top],
+ }
+ top = 0
+ end
+ + P("\19") / function()
+ result.subroutines = stack[top]
+ top = 0 -- new, forgotten ?
+ end
+ + P("\20") / function()
+ result.defaultwidthx = stack[top]
+ top = 0 -- new, forgotten ?
+ end
+ + P("\21") / function()
+ result.nominalwidthx = stack[top]
+ top = 0 -- new, forgotten ?
+ end
+ -- + P("\22") / function() -- reserved
+ -- end
+ -- + P("\23") / function() -- reserved
+ -- end
+ + P("\24") / function() -- new in cff2
+ result.vstore = stack[top]
+ top = 0
+ end
+ + P("\25") / function() -- new in cff2
+ result.maxstack = stack[top]
+ top = 0
+ end
+ -- + P("\26") / function() -- reserved
+ -- end
+ -- + P("\27") / function() -- reserved
+ -- end
+
+ local p_double = P("\12") * (
+ P("\00") / function()
+ result.copyright = stack[top]
+ top = 0
+ end
+ + P("\01") / function()
+ result.monospaced = stack[top] == 1 and true or false -- isfixedpitch
+ top = 0
+ end
+ + P("\02") / function()
+ result.italicangle = stack[top]
+ top = 0
+ end
+ + P("\03") / function()
+ result.underlineposition = stack[top]
+ top = 0
+ end
+ + P("\04") / function()
+ result.underlinethickness = stack[top]
+ top = 0
+ end
+ + P("\05") / function()
+ result.painttype = stack[top]
+ top = 0
+ end
+ + P("\06") / function()
+ result.charstringtype = stack[top]
+ top = 0
+ end
+ + P("\07") / function() -- valid cff2
+ result.fontmatrix = { unpack(stack,1,6) }
+ top = 0
+ end
+ + P("\08") / function()
+ result.strokewidth = stack[top]
+ top = 0
+ end
+ + P("\09") / function()
+ result.bluescale = stack[top]
+ top = 0
+ end
+ + P("\10") / function()
+ result.blueshift = stack[top]
+ top = 0
+ end
+ + P("\11") / function()
+ result.bluefuzz = stack[top]
+ top = 0
+ end
+ + P("\12") / function()
+ result.stemsnaph = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\13") / function()
+ result.stemsnapv = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\20") / function()
+ result.syntheticbase = stack[top]
+ top = 0
+ end
+ + P("\21") / function()
+ result.postscript = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\22") / function()
+ result.basefontname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\21") / function()
+ result.basefontblend = stack[top]
+ top = 0
+ end
+ + P("\30") / function()
+ result.cid.registry = strings[stack[top-2]] or "unset"
+ result.cid.ordering = strings[stack[top-1]] or "unset"
+ result.cid.supplement = stack[top]
+ top = 0
+ end
+ + P("\31") / function()
+ result.cid.fontversion = stack[top]
+ top = 0
+ end
+ + P("\32") / function()
+ result.cid.fontrevision= stack[top]
+ top = 0
+ end
+ + P("\33") / function()
+ result.cid.fonttype = stack[top]
+ top = 0
+ end
+ + P("\34") / function()
+ result.cid.count = stack[top]
+ top = 0
+ end
+ + P("\35") / function()
+ result.cid.uidbase = stack[top]
+ top = 0
+ end
+ + P("\36") / function() -- valid cff2
+ result.cid.fdarray = stack[top]
+ top = 0
+ end
+ + P("\37") / function() -- valid cff2
+ result.cid.fdselect = stack[top]
+ top = 0
+ end
+ + P("\38") / function()
+ result.cid.fontname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ )
+
+ -- Some lpeg fun ... a first variant split the byte and made a new string but
+ -- the second variant is much faster. Not that it matters much as we don't see
+ -- such numbers often.
+
+ local remap_1 = {
+ ["\x00"] = "00", ["\x01"] = "01", ["\x02"] = "02", ["\x03"] = "03", ["\x04"] = "04", ["\x05"] = "05", ["\x06"] = "06", ["\x07"] = "07", ["\x08"] = "08", ["\x09"] = "09", ["\x0A"] = "0.", ["\x0B"] = "0E", ["\x0C"] = "0E-", ["\x0D"] = "0", ["\x0E"] = "0-", ["\x0F"] = "0",
+ ["\x10"] = "10", ["\x11"] = "11", ["\x12"] = "12", ["\x13"] = "13", ["\x14"] = "14", ["\x15"] = "15", ["\x16"] = "16", ["\x17"] = "17", ["\x18"] = "18", ["\x19"] = "19", ["\x1A"] = "1.", ["\x1B"] = "1E", ["\x1C"] = "1E-", ["\x1D"] = "1", ["\x1E"] = "1-", ["\x1F"] = "1",
+ ["\x20"] = "20", ["\x21"] = "21", ["\x22"] = "22", ["\x23"] = "23", ["\x24"] = "24", ["\x25"] = "25", ["\x26"] = "26", ["\x27"] = "27", ["\x28"] = "28", ["\x29"] = "29", ["\x2A"] = "2.", ["\x2B"] = "2E", ["\x2C"] = "2E-", ["\x2D"] = "2", ["\x2E"] = "2-", ["\x2F"] = "2",
+ ["\x30"] = "30", ["\x31"] = "31", ["\x32"] = "32", ["\x33"] = "33", ["\x34"] = "34", ["\x35"] = "35", ["\x36"] = "36", ["\x37"] = "37", ["\x38"] = "38", ["\x39"] = "39", ["\x3A"] = "3.", ["\x3B"] = "3E", ["\x3C"] = "3E-", ["\x3D"] = "3", ["\x3E"] = "3-", ["\x3F"] = "3",
+ ["\x40"] = "40", ["\x41"] = "41", ["\x42"] = "42", ["\x43"] = "43", ["\x44"] = "44", ["\x45"] = "45", ["\x46"] = "46", ["\x47"] = "47", ["\x48"] = "48", ["\x49"] = "49", ["\x4A"] = "4.", ["\x4B"] = "4E", ["\x4C"] = "4E-", ["\x4D"] = "4", ["\x4E"] = "4-", ["\x4F"] = "4",
+ ["\x50"] = "50", ["\x51"] = "51", ["\x52"] = "52", ["\x53"] = "53", ["\x54"] = "54", ["\x55"] = "55", ["\x56"] = "56", ["\x57"] = "57", ["\x58"] = "58", ["\x59"] = "59", ["\x5A"] = "5.", ["\x5B"] = "5E", ["\x5C"] = "5E-", ["\x5D"] = "5", ["\x5E"] = "5-", ["\x5F"] = "5",
+ ["\x60"] = "60", ["\x61"] = "61", ["\x62"] = "62", ["\x63"] = "63", ["\x64"] = "64", ["\x65"] = "65", ["\x66"] = "66", ["\x67"] = "67", ["\x68"] = "68", ["\x69"] = "69", ["\x6A"] = "6.", ["\x6B"] = "6E", ["\x6C"] = "6E-", ["\x6D"] = "6", ["\x6E"] = "6-", ["\x6F"] = "6",
+ ["\x70"] = "70", ["\x71"] = "71", ["\x72"] = "72", ["\x73"] = "73", ["\x74"] = "74", ["\x75"] = "75", ["\x76"] = "76", ["\x77"] = "77", ["\x78"] = "78", ["\x79"] = "79", ["\x7A"] = "7.", ["\x7B"] = "7E", ["\x7C"] = "7E-", ["\x7D"] = "7", ["\x7E"] = "7-", ["\x7F"] = "7",
+ ["\x80"] = "80", ["\x81"] = "81", ["\x82"] = "82", ["\x83"] = "83", ["\x84"] = "84", ["\x85"] = "85", ["\x86"] = "86", ["\x87"] = "87", ["\x88"] = "88", ["\x89"] = "89", ["\x8A"] = "8.", ["\x8B"] = "8E", ["\x8C"] = "8E-", ["\x8D"] = "8", ["\x8E"] = "8-", ["\x8F"] = "8",
+ ["\x90"] = "90", ["\x91"] = "91", ["\x92"] = "92", ["\x93"] = "93", ["\x94"] = "94", ["\x95"] = "95", ["\x96"] = "96", ["\x97"] = "97", ["\x98"] = "98", ["\x99"] = "99", ["\x9A"] = "9.", ["\x9B"] = "9E", ["\x9C"] = "9E-", ["\x9D"] = "9", ["\x9E"] = "9-", ["\x9F"] = "9",
+ ["\xA0"] = ".0", ["\xA1"] = ".1", ["\xA2"] = ".2", ["\xA3"] = ".3", ["\xA4"] = ".4", ["\xA5"] = ".5", ["\xA6"] = ".6", ["\xA7"] = ".7", ["\xA8"] = ".8", ["\xA9"] = ".9", ["\xAA"] = "..", ["\xAB"] = ".E", ["\xAC"] = ".E-", ["\xAD"] = ".", ["\xAE"] = ".-", ["\xAF"] = ".",
+ ["\xB0"] = "E0", ["\xB1"] = "E1", ["\xB2"] = "E2", ["\xB3"] = "E3", ["\xB4"] = "E4", ["\xB5"] = "E5", ["\xB6"] = "E6", ["\xB7"] = "E7", ["\xB8"] = "E8", ["\xB9"] = "E9", ["\xBA"] = "E.", ["\xBB"] = "EE", ["\xBC"] = "EE-", ["\xBD"] = "E", ["\xBE"] = "E-", ["\xBF"] = "E",
+ ["\xC0"] = "E-0", ["\xC1"] = "E-1", ["\xC2"] = "E-2", ["\xC3"] = "E-3", ["\xC4"] = "E-4", ["\xC5"] = "E-5", ["\xC6"] = "E-6", ["\xC7"] = "E-7", ["\xC8"] = "E-8", ["\xC9"] = "E-9", ["\xCA"] = "E-.", ["\xCB"] = "E-E", ["\xCC"] = "E-E-", ["\xCD"] = "E-", ["\xCE"] = "E--", ["\xCF"] = "E-",
+ ["\xD0"] = "-0", ["\xD1"] = "-1", ["\xD2"] = "-2", ["\xD3"] = "-3", ["\xD4"] = "-4", ["\xD5"] = "-5", ["\xD6"] = "-6", ["\xD7"] = "-7", ["\xD8"] = "-8", ["\xD9"] = "-9", ["\xDA"] = "-.", ["\xDB"] = "-E", ["\xDC"] = "-E-", ["\xDD"] = "-", ["\xDE"] = "--", ["\xDF"] = "-",
+ }
+ local remap_2 = {
+ ["\x0F"] = "0", ["\x1F"] = "1", ["\x2F"] = "2", ["\x3F"] = "3", ["\x4F"] = "4",
+ ["\x5F"] = "5", ["\x6F"] = "6", ["\x7F"] = "7", ["\x8F"] = "8", ["\x9F"] = "9",
+ }
+
+ local p_last_1 = S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")
+ local p_last_2 = R("\xF0\xFF")
+
+ -- tricky, we don't want to append last
+
+ -- local p_nibbles = P("\30") * Cs(((1-p_last)/remap)^0 * (P(1)/remap)) / function(n)
+ local p_nibbles = P("\30") * Cs(((1-(p_last_1+p_last_2))/remap_1)^0 * (p_last_1/remap_2 + p_last_2/"")) / function(n)
+ -- 0-9=digit a=. b=E c=E- d=reserved e=- f=finish
+ top = top + 1
+ stack[top] = tonumber(n) or 0
+ end
+
+ local p_byte = C(R("\32\246")) / function(b0)
+ -- -107 .. +107
+ top = top + 1
+ stack[top] = byte(b0) - 139
+ end
+
+ local p_positive = C(R("\247\250")) * C(1) / function(b0,b1)
+ -- +108 .. +1131
+ top = top + 1
+ stack[top] = (byte(b0)-247)*256 + byte(b1) + 108
+ end
+
+ local p_negative = C(R("\251\254")) * C(1) / function(b0,b1)
+ -- -1131 .. -108
+ top = top + 1
+ stack[top] = -(byte(b0)-251)*256 - byte(b1) - 108
+ end
+
+ -- local p_float = P("\255") * C(1) * C(1) * C(1) * C(1) / function(b0,b1,b2,b3)
+ -- top = top + 1
+ -- stack[top] = 0
+ -- end
+
+ local p_short = P("\28") * C(1) * C(1) / function(b1,b2)
+ -- -32768 .. +32767 : b1<<8 | b2
+ top = top + 1
+ local n = 0x100 * byte(b1) + byte(b2)
+ if n >= 0x8000 then
+ stack[top] = n - 0xFFFF - 1
+ else
+ stack[top] = n
+ end
+ end
+
+ local p_long = P("\29") * C(1) * C(1) * C(1) * C(1) / function(b1,b2,b3,b4)
+ -- -2^31 .. +2^31-1 : b1<<24 | b2<<16 | b3<<8 | b4
+ top = top + 1
+ local n = 0x1000000 * byte(b1) + 0x10000 * byte(b2) + 0x100 * byte(b3) + byte(b4)
+ if n >= 0x8000000 then
+ stack[top] = n - 0xFFFFFFFF - 1
+ else
+ stack[top] = n
+ end
+ end
+
+ local p_unsupported = P(1) / function(detail)
+ top = 0
+ end
+
+ local p_dictionary = (
+ p_byte
+ + p_positive
+ + p_negative
+ + p_short
+ + p_long
+ + p_nibbles
+ + p_single
+ + p_double
+ -- + p_float
+ + p_unsupported
+ )^1
+
+ parsedictionaries = function(data,dictionaries,version)
+ stack = { }
+ strings = data.strings
+ if trace_charstrings then
+ report("charstring format %a",version)
+ end
+ for i=1,#dictionaries do
+ top = 0
+ result = version == "cff" and {
+ monospaced = false,
+ italicangle = 0,
+ underlineposition = -100,
+ underlinethickness = 50,
+ painttype = 0,
+ charstringtype = 2,
+ fontmatrix = { 0.001, 0, 0, 0.001, 0, 0 },
+ fontbbox = { 0, 0, 0, 0 },
+ strokewidth = 0,
+ charset = 0,
+ encoding = 0,
+ cid = {
+ fontversion = 0,
+ fontrevision = 0,
+ fonttype = 0,
+ count = 8720,
+ }
+ } or {
+ charstringtype = 2,
+ charset = 0,
+ vstore = 0,
+ cid = {
+ -- nothing yet
+ },
+ }
+ lpegmatch(p_dictionary,dictionaries[i])
+ dictionaries[i] = result
+ end
+ --
+ result = { }
+ top = 0
+ stack = { }
+ end
+
+ parseprivates = function(data,dictionaries)
+ stack = { }
+ strings = data.strings
+ for i=1,#dictionaries do
+ local private = dictionaries[i].private
+ if private and private.data then
+ top = 0
+ result = {
+ forcebold = false,
+ languagegroup = 0,
+ expansionfactor = 0.06,
+ initialrandomseed = 0,
+ subroutines = 0,
+ defaultwidthx = 0,
+ nominalwidthx = 0,
+ cid = {
+ -- actually an error
+ },
+ }
+ lpegmatch(p_dictionary,private.data)
+ private.data = result
+ end
+ end
+ result = { }
+ top = 0
+ stack = { }
+ end
+
+ -- All bezier curves have 6 points with successive pairs relative to
+ -- the previous pair. Some can be left out and are then copied or zero
+ -- (optimization).
+ --
+ -- We are not really interested in all the details of a glyph because we
+ -- only need to calculate the boundingbox. So, todo: a quick no result but
+ -- calculate only variant.
+ --
+ -- The conversion is straightforward and the specification os clear once
+ -- you understand that the x and y needs to be updates each step. It's also
+ -- quite easy to test because in mp a shape will look bad when a few variables
+ -- are swapped. But still there might be bugs down here because not all
+ -- variants are seen in a font so far. We are less compact that the ff code
+ -- because there quite some variants are done in one helper with a lot of
+ -- testing for states.
+
+ local x = 0
+ local y = 0
+ local width = false
+ local lsb = 0
+ local result = { }
+ local r = 0
+ local stems = 0
+ local globalbias = 0
+ local localbias = 0
+ local nominalwidth = 0
+ local defaultwidth = 0
+ local charset = false
+ local globals = false
+ local locals = false
+ local depth = 1
+ local xmin = 0
+ local xmax = 0
+ local ymin = 0
+ local ymax = 0
+ local checked = false
+ local keepcurve = false
+ local version = 2
+ local regions = false
+ local nofregions = 0
+ local region = false
+ local factors = false
+ local axis = false
+ local vsindex = 0
+ local justpass = false
+ local seacs = { }
+ local procidx = nil
+
+ local function showstate(where,i,n)
+ if i then
+ local j = i + n - 1
+ report("%w%-10s : [%s] step",depth*2+2,where,concat(stack," ",i,j <= top and j or top))
+ else
+ report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
+ end
+ end
+
+ local function showvalue(where,value,showstack)
+ if showstack then
+ report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
+ else
+ report("%w%-10s : %s",depth*2,where,tostring(value))
+ end
+ end
+
+ -- All these indirect calls make this run slower but it's cleaner this way
+ -- and we cache the result. As we moved the boundingbox code inline we gain
+ -- some back. I inlined some of then and a bit speed can be gained by more
+ -- inlining but not that much.
+
+ -- Maybe have several action tables:
+ --
+ -- keep curve / checked
+ -- keep curve / not checked
+ -- checked
+ -- not checked
+
+ local function xymoveto()
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if checked then
+ if x > xmax then xmax = x elseif x < xmin then xmin = x end
+ if y > ymax then ymax = y elseif y < ymin then ymin = y end
+ else
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ end
+ end
+
+ local function xmoveto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif x > xmax then
+ xmax = x
+ elseif x < xmin then
+ xmin = x
+ end
+ end
+
+ local function ymoveto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif y > ymax then
+ ymax = y
+ elseif y < ymin then
+ ymin = y
+ end
+ end
+
+ local function moveto()
+ if trace_charstrings then
+ showstate("moveto")
+ end
+ top = 0 -- forgotten
+ xymoveto()
+ end
+
+ local function xylineto() -- we could inline, no blend
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if checked then
+ if x > xmax then xmax = x elseif x < xmin then xmin = x end
+ if y > ymax then ymax = y elseif y < ymin then ymin = y end
+ else
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ end
+ end
+
+ local function xlineto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif x > xmax then
+ xmax = x
+ elseif x < xmin then
+ xmin = x
+ end
+ end
+
+ local function ylineto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif y > ymax then
+ ymax = y
+ elseif y < ymin then
+ ymin = y
+ end
+ end
+
+ local function xycurveto(x1,y1,x2,y2,x3,y3,i,n) -- called local so no blend here
+ if trace_charstrings then
+ showstate("curveto",i,n)
+ end
+ if keepcurve then
+ r = r + 1
+ result[r] = { x1, y1, x2, y2, x3, y3, "c" }
+ end
+ if checked then
+ if x1 > xmax then xmax = x1 elseif x1 < xmin then xmin = x1 end
+ if y1 > ymax then ymax = y1 elseif y1 < ymin then ymin = y1 end
+ else
+ xmin = x1
+ ymin = y1
+ xmax = x1
+ ymax = y1
+ checked = true
+ end
+ if x2 > xmax then xmax = x2 elseif x2 < xmin then xmin = x2 end
+ if y2 > ymax then ymax = y2 elseif y2 < ymin then ymin = y2 end
+ if x3 > xmax then xmax = x3 elseif x3 < xmin then xmin = x3 end
+ if y3 > ymax then ymax = y3 elseif y3 < ymin then ymin = y3 end
+ end
+
+ local function rmoveto()
+ if not width then
+ if top > 2 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width = true
+ end
+ end
+ if trace_charstrings then
+ showstate("rmoveto")
+ end
+ x = x + stack[top-1] -- dx1
+ y = y + stack[top] -- dy1
+ top = 0
+ xymoveto()
+ end
+
+ local function hmoveto()
+ if not width then
+ if top > 1 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width = true
+ end
+ end
+ if trace_charstrings then
+ showstate("hmoveto")
+ end
+ x = x + stack[top] -- dx1
+ top = 0
+ xmoveto()
+ end
+
+ local function vmoveto()
+ if not width then
+ if top > 1 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width = true
+ end
+ end
+ if trace_charstrings then
+ showstate("vmoveto")
+ end
+ y = y + stack[top] -- dy1
+ top = 0
+ ymoveto()
+ end
+
+ local function rlineto()
+ if trace_charstrings then
+ showstate("rlineto")
+ end
+ for i=1,top,2 do
+ x = x + stack[i] -- dxa
+ y = y + stack[i+1] -- dya
+ xylineto()
+ end
+ top = 0
+ end
+
+ local function hlineto() -- x (y,x)+ | (x,y)+
+ if trace_charstrings then
+ showstate("hlineto")
+ end
+ if top == 1 then
+ x = x + stack[1]
+ xlineto()
+ else
+ local swap = true
+ for i=1,top do
+ if swap then
+ x = x + stack[i]
+ xlineto()
+ swap = false
+ else
+ y = y + stack[i]
+ ylineto()
+ swap = true
+ end
+ end
+ end
+ top = 0
+ end
+
+ local function vlineto() -- y (x,y)+ | (y,x)+
+ if trace_charstrings then
+ showstate("vlineto")
+ end
+ if top == 1 then
+ y = y + stack[1]
+ ylineto()
+ else
+ local swap = false
+ for i=1,top do
+ if swap then
+ x = x + stack[i]
+ xlineto()
+ swap = false
+ else
+ y = y + stack[i]
+ ylineto()
+ swap = true
+ end
+ end
+ end
+ top = 0
+ end
+
+ local function rrcurveto()
+ if trace_charstrings then
+ showstate("rrcurveto")
+ end
+if top == 6 then
+ local ax = x + stack[1] -- dxa
+ local ay = y + stack[2] -- dya
+ local bx = ax + stack[3] -- dxb
+ local by = ay + stack[4] -- dyb
+ x = bx + stack[5] -- dxc
+ y = by + stack[6] -- dyc
+ xycurveto(ax,ay,bx,by,x,y,1,6)
+else
+-- print("rr",top==6,top)
+ for i=1,top,6 do
+ local ax = x + stack[i] -- dxa
+ local ay = y + stack[i+1] -- dya
+ local bx = ax + stack[i+2] -- dxb
+ local by = ay + stack[i+3] -- dyb
+ x = bx + stack[i+4] -- dxc
+ y = by + stack[i+5] -- dyc
+ xycurveto(ax,ay,bx,by,x,y,i,6)
+ end
+end
+ top = 0
+ end
+
+ local function hhcurveto()
+ if trace_charstrings then
+ showstate("hhcurveto")
+ end
+ local s = 1
+ if top % 2 ~= 0 then
+ y = y + stack[1] -- dy1
+ s = 2
+ end
+if top == 4 then
+ local ax = x + stack[1] -- dxa
+ local ay = y
+ local bx = ax + stack[2] -- dxb
+ local by = ay + stack[3] -- dyb
+ x = bx + stack[4] -- dxc
+ y = by
+ xycurveto(ax,ay,bx,by,x,y,1,4)
+else
+ for i=s,top,4 do
+ local ax = x + stack[i] -- dxa
+ local ay = y
+ local bx = ax + stack[i+1] -- dxb
+ local by = ay + stack[i+2] -- dyb
+ x = bx + stack[i+3] -- dxc
+ y = by
+ xycurveto(ax,ay,bx,by,x,y,i,4)
+ end
+end
+ top = 0
+ end
+
+ local function vvcurveto()
+ if trace_charstrings then
+ showstate("vvcurveto")
+ end
+ local s = 1
+ local d = 0
+ if top % 2 ~= 0 then
+ d = stack[1] -- dx1
+ s = 2
+ end
+if top == 4 then
+ local ax = x + d
+ local ay = y + stack[1] -- dya
+ local bx = ax + stack[2] -- dxb
+ local by = ay + stack[3] -- dyb
+ x = bx
+ y = by + stack[4] -- dyc
+ xycurveto(ax,ay,bx,by,x,y,1,4)
+ d = 0
+else
+ for i=s,top,4 do
+ local ax = x + d
+ local ay = y + stack[i] -- dya
+ local bx = ax + stack[i+1] -- dxb
+ local by = ay + stack[i+2] -- dyb
+ x = bx
+ y = by + stack[i+3] -- dyc
+ xycurveto(ax,ay,bx,by,x,y,i,4)
+ d = 0
+ end
+end
+ top = 0
+ end
+
+ local function xxcurveto(swap)
+ local last = top % 4 ~= 0 and stack[top]
+ if last then
+ top = top - 1
+ end
+if top == 4 then
+ local ax, ay, bx, by
+ if swap then
+ ax = x + stack[1]
+ ay = y
+ bx = ax + stack[2]
+ by = ay + stack[3]
+ y = by + stack[4]
+ if last then
+ x = bx + last
+ else
+ x = bx
+ end
+ else
+ ax = x
+ ay = y + stack[1]
+ bx = ax + stack[2]
+ by = ay + stack[3]
+ x = bx + stack[4]
+ if last then
+ y = by + last
+ else
+ y = by
+ end
+ end
+ xycurveto(ax,ay,bx,by,x,y,1 ,4)
+else
+ for i=1,top,4 do
+ local ax, ay, bx, by
+ if swap then
+ ax = x + stack[i]
+ ay = y
+ bx = ax + stack[i+1]
+ by = ay + stack[i+2]
+ y = by + stack[i+3]
+ if last and i+3 == top then
+ x = bx + last
+ else
+ x = bx
+ end
+ swap = false
+ else
+ ax = x
+ ay = y + stack[i]
+ bx = ax + stack[i+1]
+ by = ay + stack[i+2]
+ x = bx + stack[i+3]
+ if last and i+3 == top then
+ y = by + last
+ else
+ y = by
+ end
+ swap = true
+ end
+ xycurveto(ax,ay,bx,by,x,y,i,4)
+ end
+end
+ top = 0
+ end
+
+ local function hvcurveto()
+ if trace_charstrings then
+ showstate("hvcurveto")
+ end
+ xxcurveto(true)
+ end
+
+ local function vhcurveto()
+ if trace_charstrings then
+ showstate("vhcurveto")
+ end
+ xxcurveto(false)
+ end
+
+ local function rcurveline()
+ if trace_charstrings then
+ showstate("rcurveline")
+ end
+ for i=1,top-2,6 do
+ local ax = x + stack[i] -- dxa
+ local ay = y + stack[i+1] -- dya
+ local bx = ax + stack[i+2] -- dxb
+ local by = ay + stack[i+3] -- dyb
+ x = bx + stack[i+4] -- dxc
+ y = by + stack[i+5] -- dyc
+ xycurveto(ax,ay,bx,by,x,y,i,6)
+ end
+ x = x + stack[top-1] -- dxc
+ y = y + stack[top] -- dyc
+ xylineto()
+ top = 0
+ end
+
+ local function rlinecurve()
+ if trace_charstrings then
+ showstate("rlinecurve")
+ end
+ if top > 6 then
+ for i=1,top-6,2 do
+ x = x + stack[i]
+ y = y + stack[i+1]
+ xylineto()
+ end
+ end
+ local ax = x + stack[top-5]
+ local ay = y + stack[top-4]
+ local bx = ax + stack[top-3]
+ local by = ay + stack[top-2]
+ x = bx + stack[top-1]
+ y = by + stack[top]
+ xycurveto(ax,ay,bx,by,x,y)
+ top = 0
+ end
+
+ -- flex is not yet tested! no loop
+
+ local function flex() -- fd not used
+ if trace_charstrings then
+ showstate("flex")
+ end
+ local ax = x + stack[1] -- dx1
+ local ay = y + stack[2] -- dy1
+ local bx = ax + stack[3] -- dx2
+ local by = ay + stack[4] -- dy2
+ local cx = bx + stack[5] -- dx3
+ local cy = by + stack[6] -- dy3
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[7] -- dx4
+ local dy = cy + stack[8] -- dy4
+ local ex = dx + stack[9] -- dx5
+ local ey = dy + stack[10] -- dy5
+ x = ex + stack[11] -- dx6
+ y = ey + stack[12] -- dy6
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function hflex()
+ if trace_charstrings then
+ showstate("hflex")
+ end
+ local ax = x + stack[1] -- dx1
+ local ay = y
+ local bx = ax + stack[2] -- dx2
+ local by = ay + stack[3] -- dy2
+ local cx = bx + stack[4] -- dx3
+ local cy = by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[5] -- dx4
+ local dy = by
+ local ex = dx + stack[6] -- dx5
+ local ey = y
+ x = ex + stack[7] -- dx6
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function hflex1()
+ if trace_charstrings then
+ showstate("hflex1")
+ end
+ local ax = x + stack[1] -- dx1
+ local ay = y + stack[2] -- dy1
+ local bx = ax + stack[3] -- dx2
+ local by = ay + stack[4] -- dy2
+ local cx = bx + stack[5] -- dx3
+ local cy = by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[6] -- dx4
+ local dy = by
+ local ex = dx + stack[7] -- dx5
+ local ey = dy + stack[8] -- dy5
+ x = ex + stack[9] -- dx6
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function flex1()
+ if trace_charstrings then
+ showstate("flex1")
+ end
+ local ax = x + stack[1] --dx1
+ local ay = y + stack[2] --dy1
+ local bx = ax + stack[3] --dx2
+ local by = ay + stack[4] --dy2
+ local cx = bx + stack[5] --dx3
+ local cy = by + stack[6] --dy3
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[7] --dx4
+ local dy = cy + stack[8] --dy4
+ local ex = dx + stack[9] --dx5
+ local ey = dy + stack[10] --dy5
+ if abs(ex - x) > abs(ey - y) then -- spec: abs(dx) > abs(dy)
+ x = ex + stack[11]
+ else
+ y = ey + stack[11]
+ end
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function getstem()
+ if top == 0 then
+ -- bad
+ elseif top % 2 ~= 0 then
+ if width then
+ remove(stack,1)
+ else
+ width = remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top = top - 1
+ end
+ if trace_charstrings then
+ showstate("stem")
+ end
+ stems = stems + (top // 2)
+ top = 0
+ end
+
+ local function getmask()
+ if top == 0 then
+ -- bad
+ elseif top % 2 ~= 0 then
+ if width then
+ remove(stack,1)
+ else
+ width = remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top = top - 1
+ end
+ if trace_charstrings then
+ showstate(operator == 19 and "hintmark" or "cntrmask")
+ end
+ stems = stems + (top // 2)
+ top = 0
+ if stems == 0 then
+ -- forget about it
+ elseif stems <= 8 then
+ return 1
+ else
+ return (stems + 7) // 8
+ end
+ end
+
+ local function unsupported(t)
+ if trace_charstrings then
+ showstate("unsupported " .. t)
+ end
+ top = 0
+ end
+
+ local function unsupportedsub(t)
+ if trace_charstrings then
+ showstate("unsupported sub " .. t)
+ end
+ top = 0
+ end
+
+ -- type 1 (not used in type 2)
+
+ local function getstem3()
+ if trace_charstrings then
+ showstate("stem3")
+ end
+ top = 0
+ end
+
+ local function divide()
+ if version == "cff" then
+ local d = stack[top]
+ top = top - 1
+ stack[top] = stack[top] / d
+ end
+ end
+
+ local function closepath()
+ if version == "cff" then
+ if trace_charstrings then
+ showstate("closepath")
+ end
+ end
+ top = 0
+ end
+
+ local function hsbw()
+ if version == "cff" then
+ if trace_charstrings then
+ showstate("hsbw")
+ end
+ lsb = stack[top-1] or 0
+ width = stack[top]
+ end
+ top = 0
+ end
+
+ local function sbw()
+ if version == "cff" then
+ if trace_charstrings then
+ showstate("sbw")
+ end
+ lsb = stack[top-3]
+ width = stack[top-1]
+ end
+ top = 0
+ end
+
+ -- asb adx ady bchar achar seac (accented characters)
+
+ local function seac()
+ if version == "cff" then
+ if trace_charstrings then
+ showstate("seac")
+ end
+ end
+ top = 0
+ end
+
+ -- These are probably used for special cases i.e. call out to the
+ -- postscript interpreter (p 61 of the spec as well as chapter 8).
+ --
+ -- This needs checking (I have to ask Taco next time we meet.)
+
+ local popped = 3
+ local hints = 3
+
+ -- arg1 ... argn n othersubr# <callothersubr> (on postscript stack)
+
+ local function callothersubr()
+ if version == "cff" then
+ if trace_charstrings then
+ showstate("callothersubr")
+ end
+ if stack[top] == hints then
+ popped = stack[top-2]
+ else
+ popped = 3
+ end
+ local t = stack[top-1]
+ if t then
+ top = top - (t + 2)
+ if top < 0 then
+ top = 0
+ end
+ else
+ top = 0
+ end
+ else
+ top = 0
+ end
+ end
+
+ -- <pop> number (from postscript stack)
+
+ local function pop()
+ if version == "cff" then
+ if trace_charstrings then
+ showstate("pop")
+ end
+ top = top + 1
+ stack[top] = popped
+ else
+ top = 0
+ end
+ end
+
+ local function setcurrentpoint()
+ if version == "cff" then
+ if trace_charstrings then
+ showstate("setcurrentpoint (unsupported)")
+ end
+ x = x + stack[top-1]
+ y = y + stack[top]
+ end
+ top = 0
+ end
+
+ -- So far for unsupported postscript. Now some cff2 magic. As I still need
+ -- to wrap my head around the rather complex variable font specification
+ -- with regions and axis, the following approach kind of works but is more
+ -- some trial and error trick. It's still not clear how much of the complex
+ -- truetype description applies to cff. Once there are fonts out there we'll
+ -- get there. (Marcel and friends did some tests with recent cff2 fonts so
+ -- the code has been adapted accordingly.)
+
+ local reginit = false
+
+ local function updateregions(n) -- n + 1
+ if regions then
+ local current = regions[n+1] or regions[1]
+ nofregions = #current
+ if axis and n ~= reginit then
+ factors = { }
+ for i=1,nofregions do
+ local region = current[i]
+ local s = 1
+ for j=1,#axis do
+ local f = axis[j]
+ local r = region[j]
+ local start = r.start
+ local peak = r.peak
+ local stop = r.stop
+ if start > peak or peak > stop then
+ -- * 1
+ elseif start < 0 and stop > 0 and peak ~= 0 then
+ -- * 1
+ elseif peak == 0 then
+ -- * 1
+ elseif f < start or f > stop then
+ -- * 0
+ s = 0
+ break
+ elseif f < peak then
+ s = s * (f - start) / (peak - start)
+ elseif f > peak then
+ s = s * (stop - f) / (stop - peak)
+ else
+ -- * 1
+ end
+ end
+ factors[i] = s
+ end
+ end
+ end
+ reginit = n
+ end
+
+ local function setvsindex()
+ local vsindex = stack[top]
+ if trace_charstrings then
+ showstate(formatters["vsindex %i"](vsindex))
+ end
+ updateregions(vsindex)
+ top = top - 1
+ end
+
+ local function blend()
+ local n = stack[top]
+ top = top - 1
+ if axis then
+ -- x (r1x,r2x,r3x)
+ -- (x,y) (r1x,r2x,r3x) (r1y,r2y,r3y)
+ if trace_charstrings then
+ local t = top - nofregions * n
+ local m = t - n
+ for i=1,n do
+ local k = m + i
+ local d = m + n + (i-1)*nofregions
+ local old = stack[k]
+ local new = old
+ for r=1,nofregions do
+ new = new + stack[d+r] * factors[r]
+ end
+ stack[k] = new
+ showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new))
+ end
+ top = t
+ elseif n == 1 then
+ top = top - nofregions
+ local v = stack[top]
+ for r=1,nofregions do
+ v = v + stack[top+r] * factors[r]
+ end
+ stack[top] = v
+ else
+ top = top - nofregions * n
+ local d = top
+ local k = top - n
+ for i=1,n do
+ k = k + 1
+ local v = stack[k]
+ for r=1,nofregions do
+ v = v + stack[d+r] * factors[r]
+ end
+ stack[k] = v
+ d = d + nofregions
+ end
+ end
+ else
+ top = top - nofregions * n
+ end
+ end
+
+ -- Bah, we cannot use a fast lpeg because a hint has an unknown size and a
+ -- runtime capture cannot handle that well.
+
+ local actions = { [0] =
+ unsupported, -- 0
+ getstem, -- 1 -- hstem
+ unsupported, -- 2
+ getstem, -- 3 -- vstem
+ vmoveto, -- 4
+ rlineto, -- 5
+ hlineto, -- 6
+ vlineto, -- 7
+ rrcurveto, -- 8
+ unsupported, -- 9 -- closepath
+ unsupported, -- 10 -- calllocal,
+ unsupported, -- 11 -- callreturn,
+ unsupported, -- 12 -- elsewhere
+ hsbw, -- 13 -- hsbw (type 1 cff)
+ unsupported, -- 14 -- endchar,
+ setvsindex, -- 15 -- cff2
+ blend, -- 16 -- cff2
+ unsupported, -- 17
+ getstem, -- 18 -- hstemhm
+ getmask, -- 19 -- hintmask
+ getmask, -- 20 -- cntrmask
+ rmoveto, -- 21
+ hmoveto, -- 22
+ getstem, -- 23 -- vstemhm
+ rcurveline, -- 24
+ rlinecurve, -- 25
+ vvcurveto, -- 26
+ hhcurveto, -- 27
+ unsupported, -- 28 -- elsewhere
+ unsupported, -- 29 -- elsewhere
+ vhcurveto, -- 30
+ hvcurveto, -- 31
+ }
+
+ local reverse = { [0] =
+ "unsupported",
+ "getstem",
+ "unsupported",
+ "getstem",
+ "vmoveto",
+ "rlineto",
+ "hlineto",
+ "vlineto",
+ "rrcurveto",
+ "unsupported",
+ "unsupported",
+ "unsupported",
+ "unsupported",
+ "hsbw",
+ "unsupported",
+ "setvsindex",
+ "blend",
+ "unsupported",
+ "getstem",
+ "getmask",
+ "getmask",
+ "rmoveto",
+ "hmoveto",
+ "getstem",
+ "rcurveline",
+ "rlinecurve",
+ "vvcurveto",
+ "hhcurveto",
+ "unsupported",
+ "unsupported",
+ "vhcurveto",
+ "hvcurveto",
+ }
+
+ local subactions = {
+ -- cff 1
+ [000] = dotsection,
+ [001] = getstem3,
+ [002] = getstem3,
+ [006] = seac,
+ [007] = sbw,
+ [012] = divide,
+ [016] = callothersubr,
+ [017] = pop,
+ [033] = setcurrentpoint,
+ -- cff 2
+ [034] = hflex,
+ [035] = flex,
+ [036] = hflex1,
+ [037] = flex1,
+ }
+
+ local chars = setmetatableindex(function (t,k)
+ local v = char(k)
+ t[k] = v
+ return v
+ end)
+
+ local c_endchar = chars[14]
+
+ -- todo: round in blend
+
+ local encode = { }
+ local typeone = false
+
+ -- this eventually can become a helper
+
+ setmetatableindex(encode,function(t,i)
+ for i=-2048,-1130 do
+ -- t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ t[i] = char(28,(i >> 8) & 0xFF,i & 0xFF)
+ end
+ for i=-1131,-108 do
+ local v = 0xFB00 - i - 108
+ -- t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF))
+ t[i] = char((v >> 8) & 0xFF,v & 0xFF)
+ end
+ for i=-107,107 do
+ t[i] = chars[i + 139]
+ end
+ for i=108,1131 do
+ local v = 0xF700 + i - 108
+ -- t[i] = char(extract(v,8,8),extract(v,0,8))
+ t[i] = char((v >> 8) & 0xFF,v & 0xFF)
+ end
+ for i=1132,2048 do
+ -- t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ t[i] = char(28,(i >> 8) & 0xFF,i & 0xFF)
+ end
+ setmetatableindex(encode,function(t,k)
+ -- as we're cff2 we write 16.16-bit signed fixed value
+ local r = round(k)
+ local v = rawget(t,r)
+ if v then
+ return v
+ end
+ local v1 = floor(k)
+ local v2 = floor((k - v1) * 0x10000)
+ -- return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8))
+ return char(255,(v1 >> 8) & 0xFF,v1 & 0xFF,(v2 >> 8) & 0xFF,v2 & 0xFF)
+ end)
+ return t[i]
+ end)
+
+ readers.cffencoder = encode
+
+ local function p_setvsindex()
+ local vsindex = stack[top]
+ updateregions(vsindex)
+ top = top - 1
+ end
+
+ local function p_blend()
+ -- leaves n values on stack
+ local n = stack[top]
+ top = top - 1
+ if not axis then
+ -- fatal error
+ elseif n == 1 then
+ top = top - nofregions
+ local v = stack[top]
+ for r=1,nofregions do
+ v = v + stack[top+r] * factors[r]
+ end
+ stack[top] = round(v)
+ else
+ top = top - nofregions * n
+ local d = top
+ local k = top - n
+ for i=1,n do
+ k = k + 1
+ local v = stack[k]
+ for r=1,nofregions do
+ v = v + stack[d+r] * factors[r]
+ end
+ stack[k] = round(v)
+ d = d + nofregions
+ end
+ end
+ end
+
+ local function p_getstem()
+ local n = 0
+ if top % 2 ~= 0 then
+ n = 1
+ end
+ if top > n then
+ stems = stems + ((top - n) // 2)
+ end
+ end
+
+ local function p_getmask()
+ local n = 0
+ if top % 2 ~= 0 then
+ n = 1
+ end
+ if top > n then
+ stems = stems + ((top - n) // 2)
+ end
+ if stems == 0 then
+ return 0
+ elseif stems <= 8 then
+ return 1
+ else
+ return (stems + 7) // 8
+ end
+ end
+
+ -- end of experiment
+
+ local process
+
+ local function call(scope,list,bias) -- ,process)
+ depth = depth + 1
+ if top == 0 then
+ showstate(formatters["unknown %s call %s, case %s"](scope,"?",1))
+ top = 0
+ else
+ local index = stack[top] + bias
+ top = top - 1
+ if trace_charstrings then
+ showvalue(scope,index,true)
+ end
+ local tab = list[index]
+ if tab then
+ process(tab)
+ else
+ showstate(formatters["unknown %s call %s, case %s"](scope,index,2))
+ top = 0
+ end
+ end
+ depth = depth - 1
+ end
+
+ -- precompiling and reuse is much slower than redoing the calls
+
+ process = function(tab)
+ local i = 1
+ local n = #tab
+ while i <= n do
+ local t = tab[i]
+ if t >= 32 then
+ top = top + 1
+ if t <= 246 then
+ -- -107 .. +107
+ stack[top] = t - 139
+ i = i + 1
+ elseif t <= 250 then
+ -- +108 .. +1131
+ -- stack[top] = (t-247)*256 + tab[i+1] + 108
+ -- stack[top] = t*256 - 247*256 + tab[i+1] + 108
+ stack[top] = t*256 - 63124 + tab[i+1]
+ i = i + 2
+ elseif t <= 254 then
+ -- -1131 .. -108
+ -- stack[top] = -(t-251)*256 - tab[i+1] - 108
+ -- stack[top] = -t*256 + 251*256 - tab[i+1] - 108
+ stack[top] = -t*256 + 64148 - tab[i+1]
+ i = i + 2
+ elseif typeone then
+ local n = 0x1000000 * tab[i+1] + 0x10000 * tab[i+2] + 0x100 * tab[i+3] + tab[i+4]
+ if n >= 0x8000000 then
+ n = n - 0xFFFFFFFF - 1
+ end
+ stack[top] = n
+ i = i + 5
+ else
+ local n1 = 0x100 * tab[i+1] + tab[i+2]
+ local n2 = 0x100 * tab[i+3] + tab[i+4]
+ if n1 >= 0x8000 then
+ n1 = n1 - 0x10000
+ end
+ stack[top] = n1 + n2/0xFFFF
+ i = i + 5
+ end
+ elseif t == 28 then
+ -- -32768 .. +32767 : b1<<8 | b2
+ top = top + 1
+ local n = 0x100 * tab[i+1] + tab[i+2]
+ if n >= 0x8000 then
+ -- stack[top] = n - 0xFFFF - 1
+ stack[top] = n - 0x10000
+ else
+ stack[top] = n
+ end
+ i = i + 3
+ elseif t == 11 then -- not in cff2
+ if trace_charstrings then
+ showstate("return")
+ end
+ return
+ elseif t == 10 then
+ call("local",locals,localbias) -- ,process)
+ i = i + 1
+ elseif t == 14 then -- not in cff2
+ if width then
+ -- okay
+ elseif top > 0 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ else
+ width = true
+ end
+ if trace_charstrings then
+ showstate("endchar")
+ end
+ return
+ elseif t == 29 then
+ call("global",globals,globalbias) -- ,process)
+ i = i + 1
+ elseif t == 12 then
+ i = i + 1
+ local t = tab[i]
+ if justpass then
+ if t >= 34 and t <= 37 then -- flexes
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ r = r + 1 ; result[r] = chars[12]
+ r = r + 1 ; result[r] = chars[t]
+ top = 0
+ elseif t == 6 then
+ seacs[procidx] = {
+ asb = stack[1],
+ adx = stack[2],
+ ady = stack[3],
+ base = stack[4],
+ accent = stack[5],
+ width = width,
+ lsb = lsb,
+ }
+ top = 0
+ else
+ local a = subactions[t]
+ if a then
+ a(t)
+ else
+ top = 0
+ end
+ end
+ else
+ local a = subactions[t]
+ if a then
+ a(t)
+ else
+ if trace_charstrings then
+ showvalue("<subaction>",t)
+ end
+ top = 0
+ end
+ end
+ i = i + 1
+ elseif justpass then
+ -- todo: local a = passactions
+ if t == 15 then
+ p_setvsindex()
+ i = i + 1
+ elseif t == 16 then
+ local s = p_blend() or 0
+ i = i + s + 1
+ -- cff 1: (when cff2 strip them)
+ elseif t == 1 or t == 3 or t == 18 or operation == 23 then
+ p_getstem() -- at the start
+ if version == "cff" then
+-- if true then
+ if top > 0 then
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ top = 0
+ end
+ r = r + 1 ; result[r] = chars[t]
+ else
+ top = 0
+ end
+ i = i + 1
+ -- cff 1: (when cff2 strip them)
+ elseif t == 19 or t == 20 then
+ local s = p_getmask() or 0 -- after the stems
+-- if version == "cff" then
+ if true then
+ if top > 0 then
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ top = 0
+ end
+ r = r + 1 ; result[r] = chars[t]
+ for j=1,s do
+ i = i + 1
+ r = r + 1 ; result[r] = chars[tab[i]]
+ end
+ else
+ i = i + s
+ top = 0
+ end
+ i = i + 1
+ -- cff 1: closepath
+ elseif t == 9 then
+ top = 0
+ i = i + 1
+ elseif t == 13 then
+ hsbw()
+-- if version == "cff" then
+ if true then
+ -- we do a moveto over lsb
+ r = r + 1 ; result[r] = encode[lsb]
+ r = r + 1 ; result[r] = chars[22]
+ else
+ -- lsb is supposed to be zero
+ end
+ i = i + 1
+ else
+ if trace_charstrings then
+ showstate(reverse[t] or "<action>")
+ end
+ if top > 0 then
+ -- if t == 8 and top > 42 then
+ if t == 8 and top > 48 then
+ -- let's assume this only happens for rrcurveto .. the other ones would need some more
+ -- complex handling (cff2 stuff)
+ --
+ -- dx1 dy1 (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) (dy1+dy2+dy3) rcurveto.
+ local n = 0
+ for i=1,top do
+ -- if n == 42 then
+ if n == 48 then
+-- local zero = encode[0]
+-- local res3 = result[r-3]
+-- local res2 = result[r-2]
+-- local res1 = result[r-1]
+-- local res0 = result[r]
+-- result[r-3] = zero
+-- result[r-2] = zero
+ r = r + 1 ; result[r] = chars[t]
+-- r = r + 1 ; result[r] = zero
+-- r = r + 1 ; result[r] = zero
+-- r = r + 1 ; result[r] = res3
+-- r = r + 1 ; result[r] = res2
+-- r = r + 1 ; result[r] = res1
+-- r = r + 1 ; result[r] = res0
+ n = 1
+ else
+ n = n + 1
+ end
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ else
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ end
+ top = 0
+ end
+ r = r + 1 ; result[r] = chars[t]
+ i = i + 1
+ end
+ else
+ local a = actions[t]
+ if a then
+ local s = a(t)
+ if s then
+ i = i + s + 1
+ else
+ i = i + 1
+ end
+ else
+ if trace_charstrings then
+ showstate(reverse[t] or "<action>")
+ end
+ top = 0
+ i = i + 1
+ end
+ end
+ end
+ end
+
+ -- local function calculatebounds(segments,x,y)
+ -- local nofsegments = #segments
+ -- if nofsegments == 0 then
+ -- return { x, y, x, y }
+ -- else
+ -- local xmin = 10000
+ -- local xmax = -10000
+ -- local ymin = 10000
+ -- local ymax = -10000
+ -- if x < xmin then xmin = x end
+ -- if x > xmax then xmax = x end
+ -- if y < ymin then ymin = y end
+ -- if y > ymax then ymax = y end
+ -- -- we now have a reasonable start so we could
+ -- -- simplify the next checks
+ -- for i=1,nofsegments do
+ -- local s = segments[i]
+ -- local x = s[1]
+ -- local y = s[2]
+ -- if x < xmin then xmin = x end
+ -- if x > xmax then xmax = x end
+ -- if y < ymin then ymin = y end
+ -- if y > ymax then ymax = y end
+ -- if s[#s] == "c" then -- "curveto"
+ -- local x = s[3]
+ -- local y = s[4]
+ -- if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ -- if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ -- local x = s[5]
+ -- local y = s[6]
+ -- if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ -- if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ -- end
+ -- end
+ -- return { round(xmin), round(ymin), round(xmax), round(ymax) } -- doesn't make ceil more sense
+ -- end
+ -- end
+
+ local function setbias(globals,locals,nobias)
+ if nobias then
+ return 0, 0
+ else
+ local g = #globals
+ local l = #locals
+ return
+ ((g < 1240 and 107) or (g < 33900 and 1131) or 32768) + 1,
+ ((l < 1240 and 107) or (l < 33900 and 1131) or 32768) + 1
+ end
+ end
+
+ local function processshape(glyphs,tab,index,hack)
+
+ if not tab then
+ glyphs[index] = {
+ boundingbox = { 0, 0, 0, 0 },
+ width = 0,
+ name = charset and charset[index] or nil,
+ }
+ return
+ end
+
+ tab = bytetable(tab)
+
+ x = 0
+ y = 0
+ width = false
+ lsb = 0
+ r = 0
+ top = 0
+ stems = 0
+ result = { } -- we could reuse it when only boundingbox calculations are needed
+ popped = 3
+ procidx = index
+
+ xmin = 0
+ xmax = 0
+ ymin = 0
+ ymax = 0
+ checked = false
+ if trace_charstrings then
+ report("glyph: %i",index)
+ report("data : % t",tab)
+ end
+
+ if regions then
+ updateregions(vsindex)
+ end
+
+ process(tab)
+ if hack then
+ return x, y
+ end
+
+ local boundingbox = {
+ round(xmin),
+ round(ymin),
+ round(xmax),
+ round(ymax),
+ }
+
+ if width == true or width == false then
+ width = defaultwidth
+ else
+ width = nominalwidth + width
+ end
+
+ local glyph = glyphs[index] -- can be autodefined in otr
+ if justpass then
+ r = r + 1
+ result[r] = c_endchar
+ local stream = concat(result)
+result = nil
+ -- if trace_charstrings then
+ -- report("vdata: %s",stream)
+ -- end
+ if glyph then
+ glyph.stream = stream
+ glyph.width = width
+ else
+ glyphs[index] = { stream = stream, width = width }
+ end
+ elseif glyph then
+ glyph.segments = keepcurve ~= false and result or nil
+ glyph.boundingbox = boundingbox
+ if not glyph.width then
+ glyph.width = width
+ end
+ if charset and not glyph.name then
+ glyph.name = charset[index]
+ end
+ -- glyph.sidebearing = 0 -- todo
+ elseif keepcurve then
+ glyphs[index] = {
+ segments = result,
+ boundingbox = boundingbox,
+ width = width,
+ name = charset and charset[index] or nil,
+ -- sidebearing = 0,
+ }
+result = nil
+ else
+ glyphs[index] = {
+ boundingbox = boundingbox,
+ width = width,
+ name = charset and charset[index] or nil,
+ }
+ end
+ if trace_charstrings then
+ report("width : %s",tostring(width))
+ report("boundingbox: % t",boundingbox)
+ end
+
+ end
+
+ startparsing = function(fontdata,data,streams)
+ reginit = false
+ axis = false
+ regions = data.regions
+ justpass = streams == true
+ popped = 3
+ seacs = { }
+ if regions then
+ -- this was:
+ -- regions = { regions } -- needs checking
+ -- and is now (MFC):
+ regions = { }
+ local deltas = data.deltas
+ for i = 1, #deltas do
+ regions[i] = deltas[i].regions
+ end
+ axis = data.factors or false
+ end
+ end
+
+ stopparsing = function(fontdata,data)
+ stack = { }
+ glyphs = false
+ result = { }
+ top = 0
+ locals = false
+ globals = false
+ strings = false
+ popped = 3
+ seacs = { }
+ end
+
+ local function setwidths(private)
+ if not private then
+ return 0, 0
+ end
+ local privatedata = private.data
+ if not privatedata then
+ return 0, 0
+ end
+ return privatedata.nominalwidthx or 0, privatedata.defaultwidthx or 0
+ end
+
+ parsecharstrings = function(fontdata,data,glphs,doshapes,tversion,streams,nobias,istypeone)
+
+ local dictionary = data.dictionaries[1]
+ local charstrings = dictionary.charstrings
+
+ keepcurve = doshapes
+ version = tversion
+ typeone = istypeone or false
+ strings = data.strings
+ globals = data.routines or { }
+ locals = dictionary.subroutines or { }
+ charset = dictionary.charset
+ vsindex = dictionary.vsindex or 0
+
+ local glyphs = glphs or { }
+
+ globalbias, localbias = setbias(globals,locals,nobias)
+ nominalwidth, defaultwidth = setwidths(dictionary.private)
+
+ if charstrings then
+ startparsing(fontdata,data,streams)
+ for index=1,#charstrings do
+ processshape(glyphs,charstrings[index],index-1)
+ end
+ if justpass and next(seacs) then
+ -- old type 1 stuff ... seacs
+ local charset = data.dictionaries[1].charset
+ if charset then
+ local lookup = table.swapped(charset)
+ for index, v in next, seacs do
+ local bindex = lookup[standardnames[v.base]]
+ local aindex = lookup[standardnames[v.accent]]
+ local bglyph = bindex and glyphs[bindex]
+ local aglyph = aindex and glyphs[aindex]
+ if bglyph and aglyph then
+ -- this is a real ugly hack but we seldom enter this branch (e.g. old lbr)
+ local jp = justpass
+ justpass = false
+ local x, y = processshape(glyphs,charstrings[bindex+1],bindex,true)
+ justpass = jp
+ --
+ local base = bglyph.stream
+ local accent = aglyph.stream
+ local moveto = encode[-x-v.asb+v.adx] .. chars[22]
+ .. encode[-y +v.ady] .. chars[ 4]
+ -- prune an endchar
+ base = sub(base,1,#base-1)
+ -- combine them
+ glyphs[index].stream = base .. moveto .. accent
+ end
+ end
+ end
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no charstrings")
+ end
+ return glyphs
+ end
+
+ parsecharstring = function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams)
+
+ keepcurve = doshapes
+ version = tversion
+ strings = data.strings
+ globals = data.routines or { }
+ locals = dictionary.subroutines or { }
+ charset = false
+ vsindex = dictionary.vsindex or 0
+
+ local glyphs = glphs or { }
+
+ justpass = streams == true
+ seacs = { }
+
+ globalbias, localbias = setbias(globals,locals,nobias)
+ nominalwidth, defaultwidth = setwidths(dictionary.private)
+
+ processshape(glyphs,tab,index-1)
+
+ return glyphs[index]
+ end
+
+end
+
+local function readglobals(f,data,version)
+ local routines = readlengths(f,version == "cff2")
+ for i=1,#routines do
+ routines[i] = readbytetable(f,routines[i])
+ end
+ data.routines = routines
+end
+
+local function readencodings(f,data)
+ data.encodings = { }
+end
+
+local function readcharsets(f,data,dictionary)
+ local header = data.header
+ local strings = data.strings
+ local nofglyphs = data.nofglyphs
+ local charsetoffset = dictionary.charset
+ if charsetoffset and charsetoffset ~= 0 then
+ setposition(f,header.offset+charsetoffset)
+ local format = readbyte(f)
+ local charset = { [0] = ".notdef" }
+ dictionary.charset = charset
+ if format == 0 then
+ for i=1,nofglyphs do
+ charset[i] = strings[readushort(f)]
+ end
+ elseif format == 1 or format == 2 then
+ local readcount = format == 1 and readbyte or readushort
+ local i = 1
+ while i <= nofglyphs do
+ local sid = readushort(f)
+ local n = readcount(f)
+ for s=sid,sid+n do
+ charset[i] = strings[s]
+ i = i + 1
+ if i > nofglyphs then
+ break
+ end
+ end
+ end
+ else
+ report("cff parser: unsupported charset format %a",format)
+ end
+ else
+ dictionary.nocharset = true
+ dictionary.charset = nil
+ end
+end
+
+local function readprivates(f,data)
+ local header = data.header
+ local dictionaries = data.dictionaries
+ local private = dictionaries[1].private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data = readstring(f,private.size)
+ end
+end
+
+local function readlocals(f,data,dictionary,version)
+ local header = data.header
+ local private = dictionary.private
+ if private then
+ local subroutineoffset = private.data.subroutines
+ if subroutineoffset ~= 0 then
+ setposition(f,header.offset+private.offset+subroutineoffset)
+ local subroutines = readlengths(f,version == "cff2")
+ for i=1,#subroutines do
+ subroutines[i] = readbytetable(f,subroutines[i])
+ end
+ dictionary.subroutines = subroutines
+ private.data.subroutines = nil
+ else
+ dictionary.subroutines = { }
+ end
+ else
+ dictionary.subroutines = { }
+ end
+end
+
+-- These charstrings are little programs and described in: Technical Note #5177. A truetype
+-- font has only one dictionary.
+
+local function readcharstrings(f,data,version)
+ local header = data.header
+ local dictionaries = data.dictionaries
+ local dictionary = dictionaries[1]
+ local stringtype = dictionary.charstringtype
+ local offset = dictionary.charstrings
+ if type(offset) ~= "number" then
+ -- weird
+ elseif stringtype == 2 then
+ setposition(f,header.offset+offset)
+ -- could be a metatable .. delayed loading
+ local charstrings = readlengths(f,version=="cff2")
+ local nofglyphs = #charstrings
+ for i=1,nofglyphs do
+ charstrings[i] = readstring(f,charstrings[i])
+ end
+ data.nofglyphs = nofglyphs
+ dictionary.charstrings = charstrings
+ else
+ report("unsupported charstr type %i",stringtype)
+ data.nofglyphs = 0
+ dictionary.charstrings = { }
+ end
+end
+
+-- cid (maybe do this stepwise so less mem) -- share with above
+
+local function readcidprivates(f,data)
+ local header = data.header
+ local dictionaries = data.dictionaries[1].cid.dictionaries
+ for i=1,#dictionaries do
+ local dictionary = dictionaries[i]
+ local private = dictionary.private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data = readstring(f,private.size)
+ end
+ end
+ parseprivates(data,dictionaries)
+end
+
+readers.parsecharstrings = parsecharstrings -- used in font-onr.lua (type 1)
+
+local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local dictionaries = data.dictionaries
+ local dictionary = dictionaries[1]
+ local cid = not dictionary.private and dictionary.cid
+ readglobals(f,data,version)
+ readcharstrings(f,data,version)
+ if version == "cff2" then
+ dictionary.charset = nil
+ else
+ readencodings(f,data)
+ readcharsets(f,data,dictionary)
+ end
+ if cid then
+ local fdarray = cid.fdarray
+ if fdarray then
+ setposition(f,data.header.offset + fdarray)
+ local dictionaries = readlengths(f,version=="cff2")
+ local nofdictionaries = #dictionaries
+ if nofdictionaries > 0 then
+ for i=1,nofdictionaries do
+ dictionaries[i] = readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ dictionary.private = dictionaries[1].private
+ if nofdictionaries > 1 then
+ report("ignoring dictionaries > 1 in cid font")
+ end
+ end
+ end
+ end
+ readprivates(f,data)
+ parseprivates(data,data.dictionaries)
+ readlocals(f,data,dictionary,version)
+ startparsing(fontdata,data,streams)
+ parsecharstrings(fontdata,data,glyphs,doshapes,version,streams,false)
+ stopparsing(fontdata,data)
+end
+
+local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local header = data.header
+ local dictionaries = data.dictionaries
+ local dictionary = dictionaries[1]
+ local cid = dictionary.cid
+ local cidselect = cid and cid.fdselect
+ readglobals(f,data,version)
+ readcharstrings(f,data,version)
+ if version ~= "cff2" then
+ readencodings(f,data)
+ end
+ local charstrings = dictionary.charstrings
+ local fdindex = { }
+ local nofglyphs = data.nofglyphs
+ local maxindex = -1
+ setposition(f,header.offset+cidselect)
+ local format = readbyte(f)
+ if format == 1 then
+ for i=0,nofglyphs do -- notdef included (needs checking)
+ local index = readbyte(f)
+ fdindex[i] = index
+ if index > maxindex then
+ maxindex = index
+ end
+ end
+ elseif format == 3 then
+ local nofranges = readushort(f)
+ local first = readushort(f)
+ local index = readbyte(f)
+ while true do
+ local last = readushort(f)
+ if index > maxindex then
+ maxindex = index
+ end
+ for i=first,last do
+ fdindex[i] = index
+ end
+ if last >= nofglyphs then
+ break
+ else
+ first = last + 1
+ index = readbyte(f)
+ end
+ end
+ else
+ report("unsupported fd index format %i",format)
+ end
+ -- hm, always
+ if maxindex >= 0 then
+ local cidarray = cid.fdarray
+ if cidarray then
+ setposition(f,header.offset+cidarray)
+ local dictionaries = readlengths(f,version == "cff2")
+ if #dictionaries > 0 then
+ for i=1,#dictionaries do
+ dictionaries[i] = readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ cid.dictionaries = dictionaries
+ readcidprivates(f,data)
+ for i=1,#dictionaries do
+ readlocals(f,data,dictionaries[i],version)
+ end
+ startparsing(fontdata,data,streams)
+ for i=1,#charstrings do
+ local dictionary = dictionaries[fdindex[i]+1]
+ if dictionary then
+ parsecharstring(fontdata,data,dictionary,charstrings[i],glyphs,i,doshapes,version,streams)
+ else
+ -- report("no dictionary for %a : %a => %a",version,i,fdindex[i]+1)
+ end
+ -- charstrings[i] = false
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no cid dictionaries")
+ end
+ else
+ report("no cid array")
+ end
+ end
+end
+
+local gotodatatable = readers.helpers.gotodatatable
+
+local function cleanup(data,dictionaries)
+ -- for i=1,#dictionaries do
+ -- local d = dictionaries[i]
+ -- d.subroutines = nil
+ -- end
+ -- data.strings = nil
+ -- if data then
+ -- data.charstrings = nil
+ -- data.routines = nil
+ -- end
+end
+
+function readers.cff(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs)
+ if tableoffset then
+ local header = readheader(f)
+ if header.major ~= 1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local glyphs = fontdata.glyphs
+ local names = readfontnames(f)
+ local dictionaries = readtopdictionaries(f)
+ local strings = readstrings(f)
+ local data = {
+ header = header,
+ names = names,
+ dictionaries = dictionaries,
+ strings = strings,
+ nofglyphs = fontdata.nofglyphs,
+ }
+ --
+ parsedictionaries(data,dictionaries,"cff")
+ --
+ local dic = dictionaries[1]
+ local cid = dic.cid
+ --
+ local cffinfo = {
+ familyname = dic.familyname,
+ fullname = dic.fullname,
+ boundingbox = dic.boundingbox,
+ weight = dic.weight,
+ italicangle = dic.italicangle,
+ underlineposition = dic.underlineposition,
+ underlinethickness = dic.underlinethickness,
+ defaultwidth = dic.defaultwidthx,
+ nominalwidth = dic.nominalwidthx,
+ monospaced = dic.monospaced,
+ }
+ fontdata.cidinfo = cid and {
+ registry = cid.registry,
+ ordering = cid.ordering,
+ supplement = cid.supplement,
+ }
+ fontdata.cffinfo = cffinfo
+ --
+ local all = specification.shapes or specification.streams or false
+ if specification.glyphs or all then
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ end
+ end
+ local private = dic.private
+ if private then
+ local data = private.data
+ if type(data) == "table" then
+ cffinfo.defaultwidth = data.defaultwidthx or cffinfo.defaultwidth
+ cffinfo.nominalwidth = data.nominalwidthx or cffinfo.nominalwidth
+ cffinfo.bluevalues = data.bluevalues
+ cffinfo.otherblues = data.otherblues
+ cffinfo.familyblues = data.familyblues
+ cffinfo.familyotherblues = data.familyotherblues
+ cffinfo.bluescale = data.bluescale
+ cffinfo.blueshift = data.blueshift
+ cffinfo.bluefuzz = data.bluefuzz
+ cffinfo.stdhw = data.stdhw
+ cffinfo.stdvw = data.stdvw
+ cffinfo.stemsnaph = data.stemsnaph
+ cffinfo.stemsnapv = data.stemsnapv
+ end
+ end
+ cleanup(data,dictionaries)
+ end
+end
+
+function readers.cff2(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"cff2",specification.glyphs)
+ if tableoffset then
+ local header = readheader(f)
+ if header.major ~= 2 then
+ report("only version %s is supported for table %a",2,"cff2")
+ return
+ end
+ local glyphs = fontdata.glyphs
+ local dictionaries = { readstring(f,header.dsize) }
+ local data = {
+ header = header,
+ dictionaries = dictionaries,
+ nofglyphs = fontdata.nofglyphs,
+ }
+ --
+ parsedictionaries(data,dictionaries,"cff2")
+ --
+ local offset = dictionaries[1].vstore
+ if offset > 0 then
+ local storeoffset = dictionaries[1].vstore + data.header.offset + 2 -- cff has a preceding size field
+ local regions, deltas = readers.helpers.readvariationdata(f,storeoffset,factors)
+ --
+ data.regions = regions
+ data.deltas = deltas
+ else
+ data.regions = { }
+ data.deltas = { }
+ end
+ data.factors = specification.factors
+ --
+ local cid = data.dictionaries[1].cid
+ local all = specification.shapes or specification.streams or false
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ end
+ cleanup(data,dictionaries)
+ end
+end
+
+-- temporary helper needed for checking backend patches
+
+-- function readers.cffcheck(filename)
+-- local f = io.open(filename,"rb")
+-- if f then
+-- local fontdata = {
+-- glyphs = { },
+-- }
+-- local header = readheader(f)
+-- if header.major ~= 1 then
+-- report("only version %s is supported for table %a",1,"cff")
+-- return
+-- end
+-- local names = readfontnames(f)
+-- local dictionaries = readtopdictionaries(f)
+-- local strings = readstrings(f)
+-- local glyphs = { }
+-- local data = {
+-- header = header,
+-- names = names,
+-- dictionaries = dictionaries,
+-- strings = strings,
+-- glyphs = glyphs,
+-- nofglyphs = 0,
+-- }
+-- --
+-- parsedictionaries(data,dictionaries,"cff")
+-- --
+-- local cid = data.dictionaries[1].cid
+-- if cid and cid.fdselect then
+-- readfdselect(f,fontdata,data,glyphs,false)
+-- else
+-- readnoselect(f,fontdata,data,glyphs,false)
+-- end
+-- return data
+-- end
+-- end
diff --git a/tex/context/base/mkxl/font-dsp.lmt b/tex/context/base/mkxl/font-dsp.lmt
index 1b54bf463..a1bf6f641 100644
--- a/tex/context/base/mkxl/font-dsp.lmt
+++ b/tex/context/base/mkxl/font-dsp.lmt
@@ -56,11 +56,6 @@ if not modules then modules = { } end modules ['font-dsp'] = {
-- less code. After all there are often not that many demanding features.
local next, type, tonumber = next, type, tonumber
-local band = bit32.band
-local extract = bit32.extract
-local bor = bit32.bor
-local lshift = bit32.lshift
-local rshift = bit32.rshift
local gsub = string.gsub
local lower = string.lower
local sub = string.sub
@@ -298,7 +293,7 @@ local lookupnames = {
-- local lookupstate = setmetatableindex(function(t,k)
-- local v = { }
-- for kk, vv in next, lookupbits do
--- if band(k,kk) ~= 0 then
+-- if (k & kk) ~= 0 then
-- v[vv] = true
-- end
-- end
@@ -308,10 +303,10 @@ local lookupnames = {
local lookupflags = setmetatableindex(function(t,k)
local v = {
- band(k,0x0008) ~= 0 and true or false, -- ignoremarks
- band(k,0x0004) ~= 0 and true or false, -- ignoreligatures
- band(k,0x0002) ~= 0 and true or false, -- ignorebaseglyphs
- band(k,0x0001) ~= 0 and true or false, -- r2l
+ (k & 0x0008) ~= 0 and true or false, -- ignoremarks
+ (k & 0x0004) ~= 0 and true or false, -- ignoreligatures
+ (k & 0x0002) ~= 0 and true or false, -- ignorebaseglyphs
+ (k & 0x0001) ~= 0 and true or false, -- r2l
}
t[k] = v
return v
@@ -751,16 +746,17 @@ local function readposition(f,format,mainoffset,getdelta)
-- ....
-- end
--
- local x = band(format,0x1) ~= 0 and readshort(f) or 0 -- x placement
- local y = band(format,0x2) ~= 0 and readshort(f) or 0 -- y placement
- local h = band(format,0x4) ~= 0 and readshort(f) or 0 -- h advance
- local v = band(format,0x8) ~= 0 and readshort(f) or 0 -- v advance
+ local x = (format & 0x1) ~= 0 and readshort(f) or 0 -- x placement
+ local y = (format & 0x2) ~= 0 and readshort(f) or 0 -- y placement
+ local h = (format & 0x4) ~= 0 and readshort(f) or 0 -- h advance
+ local v = (format & 0x8) ~= 0 and readshort(f) or 0 -- v advance
if format >= 0x10 then
- local X = band(format,0x10) ~= 0 and skipshort(f) or 0
- local Y = band(format,0x20) ~= 0 and skipshort(f) or 0
- local H = band(format,0x40) ~= 0 and skipshort(f) or 0
- local V = band(format,0x80) ~= 0 and skipshort(f) or 0
- local s = skips[extract(format,4,4)]
+ local X = (format & 0x10) ~= 0 and skipshort(f) or 0
+ local Y = (format & 0x20) ~= 0 and skipshort(f) or 0
+ local H = (format & 0x40) ~= 0 and skipshort(f) or 0
+ local V = (format & 0x80) ~= 0 and skipshort(f) or 0
+ -- local s = skips[extract(format,4,4)]
+ local s = skips[(format >> 4) & 0xF]
if s > 0 then
skipshort(f,s)
end
@@ -2159,11 +2155,12 @@ do
subtables[j] = offset + readushort(f) -- we can probably put lookupoffset here
end
-- which one wins?
- local markclass = band(flagbits,0x0010) ~= 0 -- usemarkfilteringset
+ local markclass = (flagbits & 0x0010) ~= 0 -- usemarkfilteringset
if markclass then
markclass = readushort(f) -- + 1
end
- local markset = rshift(flagbits,8)
+ -- local markset = rshift(flagbits,8)
+ local markset = (flagbits >> 8) & 0xFFFFFFFF
if markset > 0 then
markclass = markset -- + 1
end
@@ -2607,7 +2604,8 @@ do
local length = readushort(f)
local coverage = readushort(f)
-- bit 8-15 of coverage: format 0 or 2
- local format = rshift(coverage,8) -- is this ok
+ -- local format = rshift(coverage,8) -- is this ok
+ local format = (coverage >> 8) & 0xFFFFFFFF -- is this ok
if format == 0 then
local nofpairs = readushort(f)
local searchrange = readushort(f)
@@ -3051,7 +3049,7 @@ local function readmathvariants(f,fontdata,offset)
advance = readushort(f),
}
local flags = readushort(f)
- if band(flags,0x0001) ~= 0 then
+ if (flags & 0x0001) ~= 0 then
p.extender = 1 -- true
end
parts[i] = p
@@ -4533,16 +4531,19 @@ local function calculate(f,fontdata,specification,offset,field,regions,deltas,no
setposition(f,offset)
local format = readushort(f) -- todo: check
local mapcount = readushort(f)
- local entrysize = rshift(band(format,0x0030),4) + 1
- local nofinnerbits = band(format,0x000F) + 1 -- n of inner bits
- local innermask = lshift(1,nofinnerbits) - 1
+ -- local entrysize = rshift(band(format,0x0030),4) + 1
+ local entrysize = (((format & 0x0030) >> 4) & 0xFFFFFFFF) + 1
+ local nofinnerbits = (format & 0x000F) + 1 -- n of inner bits
+ -- local innermask = lshift(1,nofinnerbits) - 1
+ local innermask = (1 << nofinnerbits) - 1
local readcardinal = read_cardinal[entrysize] -- 1 upto 4 bytes
local innerindex = { } -- size is mapcount
local outerindex = { } -- size is mapcount
for i=0,mapcount-1 do
local mapdata = readcardinal(f)
- outerindex[i] = rshift(mapdata,nofinnerbits)
- innerindex[i] = band(mapdata,innermask)
+ -- outerindex[i] = rshift(mapdata,nofinnerbits)
+ outerindex[i] = (mapdata >> nofinnerbits) & 0xFFFFFFFF
+ innerindex[i] = (mapdata & innermask)
end
-- use last entry when no match i
setvariabledata(fontdata,"hvarwidths",true)
diff --git a/tex/context/base/mkxl/font-lib.mklx b/tex/context/base/mkxl/font-lib.mklx
index cf6b51102..6caf1daf8 100644
--- a/tex/context/base/mkxl/font-lib.mklx
+++ b/tex/context/base/mkxl/font-lib.mklx
@@ -35,30 +35,29 @@
\registerctxluafile{font-fmp}{autosuffix}
\registerctxluafile{font-agl}{} % if needed we can comment this and delay loading
\registerctxluafile{font-cid}{} % cid maps
-\registerctxluafile{font-map}{optimize}
+\registerctxluafile{font-map}{}
% helpers
-\registerctxluafile{font-otr}{optimize} % opentype fontloader
+\registerctxluafile{font-otr}{} % opentype fontloader
\registerctxluafile{font-web}{} % opentype fontloader
-\registerctxluafile{font-cff}{optimize} % quadratic outlines
-\registerctxluafile{font-ttf}{optimize} % cubic outlines
-\registerctxluafile{font-dsp}{autosuffix,optimize}
+\registerctxluafile{font-cff}{autosuffix} % quadratic outlines
+\registerctxluafile{font-ttf}{autosuffix} % cubic outlines
+\registerctxluafile{font-dsp}{autosuffix}
\registerctxluafile{font-hsh}{autosuffix} % hashes used by context
\registerctxluafile{font-vfc}{autosuffix}
\registerctxluafile{font-prv}{} % needs hashes
\registerctxluafile{font-vir}{}
-\registerctxluafile{font-nod}{optimize}
+\registerctxluafile{font-nod}{}
\registerctxluafile{font-oti}{} % otf initialization
\registerctxluafile{font-ott}{} % otf tables (first)
\registerctxluafile{font-otl}{autosuffix}
\registerctxluafile{font-oto}{}
-\registerctxluafile{font-otj}{autosuffix,optimize}
+\registerctxluafile{font-otj}{autosuffix}
\registerctxluafile{font-oup}{}
\registerctxluafile{font-ota}{autosuffix}
-%registerctxluafile{font-ots-pre-scale}{autosuffix,optimize}
-\registerctxluafile{font-ots}{autosuffix,optimize}
-\registerctxluafile{font-otd}{autosuffix,optimize}
+\registerctxluafile{font-ots}{autosuffix}
+\registerctxluafile{font-otd}{autosuffix}
\registerctxluafile{font-otc}{}
\registerctxluafile{font-oth}{}
% \doifelsefileexists{font-osd-new.lmt}{
@@ -71,15 +70,15 @@
% we use otf code for type one
-\registerctxluafile{font-onr}{autosuffix,optimize}
-\registerctxluafile{font-one}{autosuffix,optimize}
+\registerctxluafile{font-onr}{autosuffix}
+\registerctxluafile{font-one}{autosuffix}
\registerctxluafile{font-afk}{}
\registerctxluafile{font-txt}{autosuffix}
% tfm
-\registerctxluafile{font-tpk}{autosuffix,optimize}
+\registerctxluafile{font-tpk}{autosuffix}
\registerctxluafile{font-tfm}{autosuffix}
% name database
diff --git a/tex/context/base/mkxl/font-map.lmt b/tex/context/base/mkxl/font-map.lmt
new file mode 100644
index 000000000..be1321384
--- /dev/null
+++ b/tex/context/base/mkxl/font-map.lmt
@@ -0,0 +1,518 @@
+if not modules then modules = { } end modules ['font-map'] = {
+ version = 1.001,
+ optimize = true,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local tonumber, next, type = tonumber, next, type
+
+local match, format, find, concat, gsub, lower = string.match, string.format, string.find, table.concat, string.gsub, string.lower
+local P, R, S, C, Ct, Cc, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.match
+local formatters = string.formatters
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
+
+local trace_loading = false trackers.register("fonts.loading", function(v) trace_loading = v end)
+local trace_mapping = false trackers.register("fonts.mapping", function(v) trace_mapping = v end)
+
+local report_fonts = logs.reporter("fonts","loading") -- not otf only
+
+-- force_ligatures was true for a while so that these emoji's with bad names work too
+
+local force_ligatures = false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures = v end)
+
+local fonts = fonts or { }
+local mappings = fonts.mappings or { }
+fonts.mappings = mappings
+
+local allocate = utilities.storage.allocate
+
+local hex = R("AF","af","09")
+local hexfour = (hex*hex*hex^-2) / function(s) return tonumber(s,16) end
+local hexsix = (hex*hex*hex^-4) / function(s) return tonumber(s,16) end
+local dec = (R("09")^1) / tonumber
+local period = P(".")
+local unicode = (P("uni") + P("UNI")) * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) -- base planes
+local ucode = (P("u") + P("U") ) * (hexsix * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) -- extended
+local index = P("index") * dec * Cc(false)
+
+local parser = unicode + ucode + index
+local parsers = { }
+
+local function makenameparser(str)
+ if not str or str == "" then
+ return parser
+ else
+ local p = parsers[str]
+ if not p then
+ p = P(str) * period * dec * Cc(false)
+ parsers[str] = p
+ end
+ return p
+ end
+end
+
+local f_single = formatters["%04X"]
+local f_double = formatters["%04X%04X"]
+local s_unknown = "FFFD"
+
+local function tounicode16(unicode)
+ if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
+ return f_single(unicode)
+ elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
+ return s_unknown
+ elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
+ return s_unknown
+ elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
+ return s_unknown
+ elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then
+ return s_unknown
+ else
+ unicode = unicode - 0x10000
+ return f_double((k//0x400)+0xD800,unicode%0x400+0xDC00)
+ end
+end
+
+local function tounicode16sequence(unicodes)
+ local t = { }
+ for l=1,#unicodes do
+ local u = unicodes[l]
+ if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then
+ t[l] = f_single(u)
+ elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
+ t[l] = s_unknown
+ elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
+ t[l] = s_unknown
+ elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
+ t[l] = s_unknown
+ -- elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then
+ elseif unicode >= 0x00D7FF and unicode <= 0x00DFFF then
+ t[l] = s_unknown
+ else
+ u = u - 0x10000
+ t[l] = f_double((k//0x400)+0xD800,u%0x400+0xDC00)
+ end
+ end
+ return concat(t)
+end
+
+
+local hash = { }
+local conc = { }
+
+table.setmetatableindex(hash,function(t,k)
+ local v
+ if k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
+ v = f_single(k)
+ else
+ local k = k - 0x10000
+ v = f_double((k//0x400)+0xD800,k%0x400+0xDC00)
+ end
+ t[k] = v
+ return v
+end)
+
+local function tounicode(k)
+ if type(k) == "table" then
+ local n = #k
+ for l=1,n do
+ conc[l] = hash[k[l]]
+ end
+ return concat(conc,"",1,n)
+ elseif k >= 0x00E000 and k <= 0x00F8FF then
+ return s_unknown
+ elseif k >= 0x0F0000 and k <= 0x0FFFFF then
+ return s_unknown
+ elseif k >= 0x100000 and k <= 0x10FFFF then
+ return s_unknown
+ -- elseif k >= 0x00D800 and k <= 0x00DFFF then
+ elseif k >= 0x00D7FF and k <= 0x00DFFF then
+ return s_unknown
+ else
+ return hash[k]
+ end
+end
+
+local function fromunicode16(str)
+ if #str == 4 then
+ return tonumber(str,16)
+ else
+ local l, r = match(str,"(....)(....)")
+ return 0x10000 + (tonumber(l,16)-0xD800)*0x400 + tonumber(r,16) - 0xDC00
+ end
+end
+
+-- Slightly slower:
+--
+-- local p = C(4) * (C(4)^-1) / function(l,r)
+-- if r then
+-- return (tonumber(l,16))*0x400 + tonumber(r,16) - 0xDC00
+-- else
+-- return tonumber(l,16)
+-- end
+-- end
+--
+-- local function fromunicode16(str)
+-- return lpegmatch(p,str)
+-- end
+
+mappings.makenameparser = makenameparser
+mappings.tounicode = tounicode
+mappings.tounicode16 = tounicode16
+mappings.tounicode16sequence = tounicode16sequence
+mappings.fromunicode16 = fromunicode16
+
+-- mozilla emoji has bad lig names: name = gsub(name,"(u[a-f0-9_]+)%-([a-f0-9_]+)","%1_%2")
+
+local ligseparator = P("_")
+local varseparator = P(".")
+local namesplitter = Ct(C((1 - ligseparator - varseparator)^1) * (ligseparator * C((1 - ligseparator - varseparator)^1))^0)
+
+-- maybe: ff fi fl ffi ffl => f_f f_i f_l f_f_i f_f_l
+
+-- local function test(name)
+-- local split = lpegmatch(namesplitter,name)
+-- print(string.formatters["%s: [% t]"](name,split))
+-- end
+
+-- test("i.f_")
+-- test("this")
+-- test("this.that")
+-- test("japan1.123")
+-- test("such_so_more")
+-- test("such_so_more.that")
+
+-- to be completed .. for fonts that use unicodes for ligatures which
+-- is a actually a bad thing and should be avoided in the first place
+
+do
+
+ local overloads = {
+ IJ = { name = "I_J", unicode = { 0x49, 0x4A }, mess = 0x0132 },
+ ij = { name = "i_j", unicode = { 0x69, 0x6A }, mess = 0x0133 },
+ ff = { name = "f_f", unicode = { 0x66, 0x66 }, mess = 0xFB00 },
+ fi = { name = "f_i", unicode = { 0x66, 0x69 }, mess = 0xFB01 },
+ fl = { name = "f_l", unicode = { 0x66, 0x6C }, mess = 0xFB02 },
+ ffi = { name = "f_f_i", unicode = { 0x66, 0x66, 0x69 }, mess = 0xFB03 },
+ ffl = { name = "f_f_l", unicode = { 0x66, 0x66, 0x6C }, mess = 0xFB04 },
+ fj = { name = "f_j", unicode = { 0x66, 0x6A } },
+ fk = { name = "f_k", unicode = { 0x66, 0x6B } },
+
+ -- endash = { name = "endash", unicode = 0x2013, mess = 0x2013 },
+ -- emdash = { name = "emdash", unicode = 0x2014, mess = 0x2014 },
+ }
+
+ local o = allocate { }
+
+ for k, v in next, overloads do
+ local name = v.name
+ local mess = v.mess
+ if name then
+ o[name] = v
+ end
+ if mess then
+ o[mess] = v
+ end
+ o[k] = v
+ end
+
+ mappings.overloads = o
+
+end
+
+function mappings.addtounicode(data,filename,checklookups,forceligatures)
+ local resources = data.resources
+ local unicodes = resources.unicodes
+ if not unicodes then
+ if trace_mapping then
+ report_fonts("no unicode list, quitting tounicode for %a",filename)
+ end
+ return
+ end
+ local properties = data.properties
+ local descriptions = data.descriptions
+ local overloads = mappings.overloads
+ -- we need to move this code
+ unicodes['space'] = unicodes['space'] or 32
+ unicodes['hyphen'] = unicodes['hyphen'] or 45
+ unicodes['zwj'] = unicodes['zwj'] or 0x200D
+ unicodes['zwnj'] = unicodes['zwnj'] or 0x200C
+ --
+ local private = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF
+ local unicodevector = fonts.encodings.agl.unicodes or { } -- loaded runtime in context
+ local contextvector = fonts.encodings.agl.ctxcodes or { } -- loaded runtime in context
+ local missing = { }
+ local nofmissing = 0
+ local oparser = nil
+ local cidnames = nil
+ local cidcodes = nil
+ local cidinfo = properties.cidinfo
+ local usedmap = cidinfo and fonts.cid.getmap(cidinfo)
+ local uparser = makenameparser() -- hm, every time?
+ if usedmap then
+ oparser = usedmap and makenameparser(cidinfo.ordering)
+ cidnames = usedmap.names
+ cidcodes = usedmap.unicodes
+ end
+ local ns = 0
+ local nl = 0
+ --
+ -- in order to avoid differences between runs due to hash randomization we
+ -- run over a sorted list
+ --
+ local dlist = sortedkeys(descriptions)
+ --
+ -- for du, glyph in next, descriptions do
+ for i=1,#dlist do
+ local du = dlist[i]
+ local glyph = descriptions[du]
+ local name = glyph.name
+ if name then
+ local overload = overloads[name] or overloads[du]
+ if overload then
+ -- get rid of weird ligatures
+ -- glyph.name = overload.name
+ glyph.unicode = overload.unicode
+ else
+ local gu = glyph.unicode -- can already be set (number or table)
+ if not gu or gu == -1 or du >= private or (du >= 0xE000 and du <= 0xF8FF) or du == 0xFFFE or du == 0xFFFF then
+ local unicode = unicodevector[name] or contextvector[name]
+ if unicode then
+ glyph.unicode = unicode
+ ns = ns + 1
+ end
+ -- cidmap heuristics, beware, there is no guarantee for a match unless
+ -- the chain resolves
+ if (not unicode) and usedmap then
+ local foundindex = lpegmatch(oparser,name)
+ if foundindex then
+ unicode = cidcodes[foundindex] -- name to number
+ if unicode then
+ glyph.unicode = unicode
+ ns = ns + 1
+ else
+ local reference = cidnames[foundindex] -- number to name
+ if reference then
+ local foundindex = lpegmatch(oparser,reference)
+ if foundindex then
+ unicode = cidcodes[foundindex]
+ if unicode then
+ glyph.unicode = unicode
+ ns = ns + 1
+ end
+ end
+ if not unicode or unicode == "" then
+ local foundcodes, multiple = lpegmatch(uparser,reference)
+ if foundcodes then
+ glyph.unicode = foundcodes
+ if multiple then
+ nl = nl + 1
+ unicode = true
+ else
+ ns = ns + 1
+ unicode = foundcodes
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ -- a.whatever or a_b_c.whatever or a_b_c (no numbers) a.b_
+ --
+ -- It is not trivial to find a solution that suits all fonts. We tried several alternatives
+ -- and this one seems to work reasonable also with fonts that use less standardized naming
+ -- schemes. The extra private test is tested by KE and seems to work okay with non-typical
+ -- fonts as well.
+ --
+ if not unicode or unicode == "" then
+ local split = lpegmatch(namesplitter,name)
+ local nsplit = split and #split or 0 -- add if
+ if nsplit == 0 then
+ -- skip
+ elseif nsplit == 1 then
+ local base = split[1]
+ local u = unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ -- skip
+ elseif type(u) == "table" then
+ -- unlikely
+ if u[1] < private then
+ unicode = u
+ glyph.unicode = unicode
+ end
+ elseif u < private then
+ unicode = u
+ glyph.unicode = unicode
+ end
+ else
+ local t = { }
+ local n = 0
+ for l=1,nsplit do
+ local base = split[l]
+ local u = unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ break
+ elseif type(u) == "table" then
+ if u[1] >= private then
+ break
+ end
+ n = n + 1
+ t[n] = u[1]
+ else
+ if u >= private then
+ break
+ end
+ n = n + 1
+ t[n] = u
+ end
+ end
+ if n > 0 then
+ if n == 1 then
+ unicode = t[1]
+ else
+ unicode = t
+ end
+ glyph.unicode = unicode
+ end
+ end
+ nl = nl + 1
+ end
+ -- last resort (we might need to catch private here as well)
+ if not unicode or unicode == "" then
+ local foundcodes, multiple = lpegmatch(uparser,name)
+ if foundcodes then
+ glyph.unicode = foundcodes
+ if multiple then
+ nl = nl + 1
+ unicode = true
+ else
+ ns = ns + 1
+ unicode = foundcodes
+ end
+ end
+ end
+ -- check using substitutes and alternates
+ local r = overloads[unicode]
+ if r then
+ unicode = r.unicode
+ glyph.unicode = unicode
+ end
+ --
+ if not unicode then
+ missing[du] = true
+ nofmissing = nofmissing + 1
+ end
+ else
+ -- maybe a message or so
+ end
+ end
+ else
+ local overload = overloads[du]
+ if overload then
+ glyph.unicode = overload.unicode
+ elseif not glyph.unicode then
+ missing[du] = true
+ nofmissing = nofmissing + 1
+ end
+ end
+ end
+ if type(checklookups) == "function" then
+ checklookups(data,missing,nofmissing)
+ end
+
+ local unicoded = 0
+ local collected = fonts.handlers.otf.readers.getcomponents(data) -- neglectable overhead
+
+ local function resolve(glyph,u)
+ local n = #u
+ for i=1,n do
+ if u[i] > private then
+ n = 0
+ break
+ end
+ end
+ if n > 0 then
+ if n > 1 then
+ glyph.unicode = u
+ else
+ glyph.unicode = u[1]
+ end
+ unicoded = unicoded + 1
+ end
+ end
+
+ if not collected then
+ -- move on
+ elseif forceligatures or force_ligatures then
+ for i=1,#dlist do
+ local du = dlist[i]
+ if du >= private or (du >= 0xE000 and du <= 0xF8FF) then
+ local u = collected[du] -- always tables
+ if u then
+ resolve(descriptions[du],u)
+ end
+ end
+ end
+ else
+ for i=1,#dlist do
+ local du = dlist[i]
+ if du >= private or (du >= 0xE000 and du <= 0xF8FF) then
+ local glyph = descriptions[du]
+ if glyph.class == "ligature" and not glyph.unicode then
+ local u = collected[du] -- always tables
+ if u then
+ resolve(glyph,u)
+ end
+ end
+ end
+ end
+ end
+
+ if trace_mapping and unicoded > 0 then
+ report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
+ end
+ if trace_mapping then
+ -- for unic, glyph in sortedhash(descriptions) do
+ for i=1,#dlist do
+ local du = dlist[i]
+ local glyph = descriptions[du]
+ local name = glyph.name or "-"
+ local index = glyph.index or 0
+ local unicode = glyph.unicode
+ if unicode then
+ if type(unicode) == "table" then
+ local unicodes = { }
+ for i=1,#unicode do
+ unicodes[i] = formatters("%U",unicode[i])
+ end
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
+ else
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
+ end
+ else
+ report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
+ end
+ end
+ end
+ if trace_loading and (ns > 0 or nl > 0) then
+ report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
+ end
+end
+
+-- local parser = makenameparser("Japan1")
+-- local parser = makenameparser()
+-- local function test(str)
+-- local b, a = lpegmatch(parser,str)
+-- print((a and table.serialize(b)) or b)
+-- end
+-- test("a.sc")
+-- test("a")
+-- test("uni1234")
+-- test("uni1234.xx")
+-- test("uni12349876")
+-- test("u123400987600")
+-- test("index1234")
+-- test("Japan1.123")
diff --git a/tex/context/base/mkxl/font-onr.lmt b/tex/context/base/mkxl/font-onr.lmt
index 2c18f6e89..d28c247df 100644
--- a/tex/context/base/mkxl/font-onr.lmt
+++ b/tex/context/base/mkxl/font-onr.lmt
@@ -26,7 +26,7 @@ local next, type, tonumber, rawset = next, type, tonumber, rawset
local match, lower, gsub, strip, find = string.match, string.lower, string.gsub, string.strip, string.find
local char, byte, sub = string.char, string.byte, string.sub
local abs = math.abs
-local bxor, rshift = bit32.bxor, bit32.rshift
+----- bxor, rshift = bit32.bxor, bit32.rshift
local P, S, R, V, Cmt, C, Ct, Cs, Carg, Cf, Cg, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.V, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cf, lpeg.Cg, lpeg.Cc
local lpegmatch, patterns = lpeg.match, lpeg.patterns
@@ -68,8 +68,10 @@ do
local function step(c)
local cipher = byte(c)
- local plain = bxor(cipher,rshift(r,8))
- r = ((cipher + r) * c1 + c2) % 65536
+ -- local plain = bxor(cipher,rshift(r,8))
+ local plain = (cipher ~ ((r >> 8) & 0xFFFFFFFF))
+ -- r = ((cipher + r) * c1 + c2) % 65536
+ r = ((cipher + r) * c1 + c2) % 0x10000
return char(plain)
end
diff --git a/tex/context/base/mkxl/font-tpk.lmt b/tex/context/base/mkxl/font-tpk.lmt
index d265433c5..fc6789402 100644
--- a/tex/context/base/mkxl/font-tpk.lmt
+++ b/tex/context/base/mkxl/font-tpk.lmt
@@ -13,8 +13,8 @@ if not modules then modules = { } end modules ['font-tpk'] = {
-- luatex. All do things a bit more luaish and errors are of course mine.
local next = next
-local extract, band, lshift, rshift = bit32.extract, bit32.band, bit32.lshift, bit32.rshift
-local idiv = number.idiv
+----- extract, band, lshift, rshift = bit32.extract, bit32.band, bit32.lshift, bit32.rshift
+----- idiv = number.idiv
local char = string.char
local concat, insert, remove, copy = table.concat, table.insert, table.remove, table.copy
local tobitstring = number.tobitstring
@@ -67,20 +67,22 @@ do
if bitweight == 0 then
bitweight = 16
inputbyte = readbyte(s)
- return extract(inputbyte,4,4)
+ -- return extract(inputbyte,4,4)
+ return (inputbyte >> 4) & 0xF
else
bitweight = 0
- return band(inputbyte,15)
+ return inputbyte & 15
end
end
local function getbit() -- can be inlined
- bitweight = rshift(bitweight,1)
+ -- bitweight = rshift(bitweight,1)
+ bitweight = (bitweight >> 1) & 0xFFFFFFFF
if bitweight == 0 then -- actually we can check for 1
inputbyte = readbyte(s)
bitweight = 128
end
- return band(inputbyte,bitweight)
+ return inputbyte & bitweight
end
local function pkpackednum()
@@ -130,8 +132,8 @@ do
local function handlehuge(i,j)
while i ~= 0 do
- j = lshift(j,4) + getnyb()
- -- j = extract(j,8,4) + getnyb()
+ -- j = lshift(j,4) + getnyb()
+ j = ((j << 4) & 0xFFFFFFFF) + getnyb()
i = i - 1
end
remainder = j - 15 + (13 - dynf) * 16 + dynf
@@ -153,14 +155,14 @@ do
local ysize = glyph.ysize
local word = 0
local wordweight = 0
- local wordwidth = idiv(xsize + 15,16)
+ local wordwidth = (xsize + 15) // 16
local rowsleft = 0
- local turnon = band(flagbyte,8) == 8 and true or false
+ local turnon = (flagbyte & 8) == 8 and true or false
local hbit = 0
local count = 0
--
realfunc = pkpackednum
- dynf = idiv(flagbyte,16)
+ dynf = flagbyte // 16
--
if dynf == 14 then
bitweight = 0
@@ -171,7 +173,8 @@ do
if getbit() ~= 0 then
word = word + wordweight
end
- wordweight = rshift(wordweight,1)
+ -- wordweight = rshift(wordweight,1)
+ wordweight = (wordweight >> 1) & 0xFFFFFFFF
if wordweight == 0 then
r = r + 1
raster[r] = word
@@ -247,8 +250,8 @@ do
local rr = { }
local r = 0
local s = 0
- local cw = idiv(xsize+ 7, 8)
- local rw = idiv(xsize+15,16)
+ local cw = (xsize+ 7) // 8
+ local rw = (xsize+15) // 16
local extra = 2 * rw == cw
local b
for y=1,ysize do
@@ -261,7 +264,8 @@ do
if extra then
r = r + 1 ; rr[r] = tobitstring(b,16,16)
else
- r = r + 1 ; rr[r] = tobitstring(extract(b,8+(8-cw),cw),cw,cw)
+ -- r = r + 1 ; rr[r] = tobitstring(extract(b,8+(8-cw),cw),cw,cw)
+ r = r + 1 ; rr[r] = tobitstring((b >> (8+(8-cw))) &~ (-1 << cw),cw,cw)
end
result[y] = concat(rr)
end
@@ -304,20 +308,23 @@ Q]] ]
local result = { }
local r = 0
local s = 0
- local cw = idiv(xsize+ 7, 8)
- local rw = idiv(xsize+15,16)
+ local cw = (xsize+ 7) // 8
+ local rw = (xsize+15) // 16
local extra = 2 * rw == cw
local b
for y=1,ysize do
for x=1,rw-1 do
s = s + 1 ; b = stream[s]
- r = r + 1 ; result[r] = char(extract(b,8,8),extract(b,0,8))
+ -- r = r + 1 ; result[r] = char(extract(b,8,8),extract(b,0,8))
+ r = r + 1 ; result[r] = char((b >> 8) & 0xFF,b & 0xFF)
end
s = s + 1 ; b = stream[s]
if extra then
- r = r + 1 ; result[r] = char(extract(b,8,8),extract(b,0,8))
+ -- r = r + 1 ; result[r] = char(extract(b,8,8),extract(b,0,8))
+ r = r + 1 ; result[r] = char((b >> 8) & 0xFF,b & 0xFF)
else
- r = r + 1 ; result[r] = char(extract(b,8,8))
+ -- r = r + 1 ; result[r] = char(extract(b,8,8))
+ r = r + 1 ; result[r] = char((b >> 8) & 0xFF)
end
end
return template(width,llx,lly,urx,ury,xdpi,ydpi,llx,lly,xsize,ysize,result), width
@@ -346,10 +353,10 @@ Q]] ]
while true do
local flagbyte = readcardinal1(s)
if flagbyte < 240 then
- local c = band(flagbyte,7)
+ local c = flagbyte & 7
local length, index, width, pixels, xsize, ysize, xoffset, yoffset
if c >= 0 and c <= 3 then
- length = band(flagbyte,7) * 256 + readcardinal1(s) - 3
+ length = (flagbyte & 7) * 256 + readcardinal1(s) - 3
index = readcardinal1(s)
width = readinteger3(s)
pixels = readcardinal1(s)
@@ -364,7 +371,7 @@ Q]] ]
yoffset = yoffset - 256
end
elseif c >= 4 and c <= 6 then
- length = band(flagbyte,3) * 65536 + readcardinal1(s) * 256 + readcardinal1(s) - 4
+ length = (flagbyte & 3) * 65536 + readcardinal1(s) * 256 + readcardinal1(s) - 4
index = readcardinal1(s)
width = readinteger3(s)
pixels = readcardinal2(s)
@@ -587,8 +594,9 @@ do
end
local checksum = readcardinal4(s)
local designsize = readcardinal2(s)
- designsize = designsize * 256 + readcardinal1(s)
- designsize = designsize * 16 + rshift(readcardinal1(s),4)
+ designsize = designsize * 256 + readcardinal1(s)
+ -- designsize = designsize * 16 + rshift(readcardinal1(s),4)
+ designsize = designsize * 16 + (readcardinal1(s) >> 4)
if designsize < 0xFFFF then
return someerror("weird designsize")
end
@@ -596,15 +604,17 @@ do
local alpha = 16
local z = designsize
while z >= 040000000 do
- z = rshift(z,1)
+ -- z = rshift(z,1)
+ z = (z >> 1) & 0xFFFFFFFF
alpha = alpha + alpha
end
- local beta = idiv(256,alpha)
+ local beta = 256 // alpha
alpha = alpha * z
--
local function readscaled()
local a, b, c, d = readbytes(s,4)
- local n = idiv(rshift(rshift(d*z,8)+c*z,8)+b*z,beta)
+ -- local n = idiv(rshift(rshift(d*z,8)+c*z,8)+b*z,beta)
+ local n = (((((((d * z) >> 8) & 0xFFFFFFFF) + c * z) >> 8) & 0xFFFFFFFF) + b * z) // beta
if a == 0 then
return n
elseif a == 255 then
@@ -619,7 +629,8 @@ do
if a > 127 then
a = a - 256
end
- return a * 0xFFFFF + b * 0xFFF + c * 0xF + rshift(d,4)
+ -- return a * 0xFFFFF + b * 0xFFF + c * 0xF + rshift(d,4)
+ return a * 0xFFFFF + b * 0xFFF + c * 0xF + ((d >> 4) & 0xFFFFFFFF)
end
--
while lh > 2 do -- can be one-liner
@@ -775,11 +786,15 @@ do
else
width = readcardinal1(s)
height = readcardinal1(s)
- depth = extract(height,0,4)
- height = extract(height,4,4)
+ -- depth = extract(height,0,4)
+ depth = height & 0xF
+ -- height = extract(height,4,4)
+ height = (height >> 4) & 0xF
italic = readcardinal1(s)
- tag = extract(italic,0,2)
- italic = extract(italic,2,6)
+ -- tag = extract(italic,0,2)
+ tag = italic & 0x03
+ -- italic = extract(italic,2,6)
+ italic = (italic >> 2) & 0xFF
remainder = readcardinal1(s)
end
if width == 0 then
@@ -964,7 +979,7 @@ do
local function scaled2()
local a, b = readbytes(s,2)
- local sw = idiv(b*z,beta)
+ local sw = (b*z) // beta
if a == 0 then
return sw
elseif a == 255 then
@@ -976,7 +991,8 @@ do
local function scaled3()
local a, b, c = readbytes(s,3)
- local sw = idiv(rshift(c*z,8)+b*z,beta)
+ -- local sw = idiv(rshift(c*z,8)+b*z,beta)
+ local sw = ((((c * z) >> 8) & 0xFFFFFFFF) + b * z) // beta
if a == 0 then
return sw
elseif a == 255 then
@@ -988,7 +1004,8 @@ do
local function scaled4()
local a, b, c, d = readbytes(s,4)
- local sw = idiv( rshift(rshift(d*z,8)+(c*z),8)+b*z,beta)
+ -- local sw = idiv( rshift(rshift(d*z,8)+(c*z),8)+b*z,beta)
+ local sw = (((((d * z) >> 8) & 0xFFFFFFFF + (c * z)) >> 8) & 0xFFFFFFFF + b * z) // beta
if a == 0 then
return sw
elseif a == 255 then
@@ -1162,17 +1179,18 @@ do
end
local header = readstring(s,readcardinal1(s))
local checksum = readcardinal4(s)
- local designsize = idiv(readcardinal4(s),16)
+ local designsize = readcardinal4(s) // 16
local fonts = data and data.fonts or { }
local glyphs = data and data.glyphs or { }
--
alpha = 16
z = designsize
while z >= 040000000 do
- z = rshift(z,1)
+ -- z = rshift(z,1)
+ z = (z >> 1) & 0xFFFFFFFF
alpha = alpha + alpha
end
- beta = idiv(256,alpha)
+ beta = 256 // alpha
alpha = alpha * z
--
cmd = readcardinal1(s)
@@ -1191,7 +1209,7 @@ do
end
local checksum = skipbytes(s,4)
local size = scaled4()
- local designsize = idiv(readcardinal4(s),16)
+ local designsize = readcardinal4(s) // 16
local pathlen = readcardinal1(s)
local namelen = readcardinal1(s)
local path = readstring(s,pathlen)
@@ -1267,7 +1285,7 @@ do
local vffile = resolvers.findbinfile(vfname,"ovf")
if tfmfile and tfmfile ~= "" then
if size < 0 then
- size = idiv(65536 * -size,100)
+ size = (65536 * -size) // 100
end
local data = readers.loadtfm(tfmfile)
if data.error then
diff --git a/tex/context/base/mkxl/font-ttf.lmt b/tex/context/base/mkxl/font-ttf.lmt
new file mode 100644
index 000000000..fa0e3c494
--- /dev/null
+++ b/tex/context/base/mkxl/font-ttf.lmt
@@ -0,0 +1,1496 @@
+if not modules then modules = { } end modules ['font-ttf'] = {
+ version = 1.001,
+ optimize = true,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This version is different from previous in the sense that we no longer store
+-- contours but keep points and contours (endpoints) separate for a while
+-- because later on we need to apply deltas and that is easier on a list of
+-- points.
+
+-- The code is a bit messy. I looked at the ff code but it's messy too. It has
+-- to do with the fact that we need to look at points on the curve and control
+-- points in between. This also means that we start at point 2 and have to look
+-- at point 1 when we're at the end. We still use a ps like storage with the
+-- operator last in an entry. It's typical code that evolves stepwise till a
+-- point of no comprehension.
+
+-- For deltas we need a rather complex loop over points that can have holes and
+-- be less than nofpoints and even can have duplicates and also the x and y value
+-- lists can be shorter than etc. I need fonts in order to complete this simply
+-- because I need to visualize in order to understand (what the standard tries
+-- to explain).
+
+-- 0 point then none applied
+-- 1 points then applied to all
+-- otherwise inferred deltas using nearest
+-- if no lower point then use highest referenced point
+-- if no higher point then use lowest referenced point
+-- factor = (target-left)/(right-left)
+-- delta = (1-factor)*left + factor * right
+
+local next, type, unpack = next, type, unpack
+----- band, rshift = bit32.band, bit32.rshift
+local sqrt, round, abs, min, max = math.sqrt, math.round, math.abs, math.min, math.max
+local char, rep = string.char, string.rep
+local concat = table.concat
+local setmetatableindex = table.setmetatableindex
+
+local report = logs.reporter("otf reader","ttf")
+
+local trace_deltas = false
+
+local readers = fonts.handlers.otf.readers
+local streamreader = readers.streamreader
+
+local setposition = streamreader.setposition
+local getposition = streamreader.getposition
+local skipbytes = streamreader.skip
+local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
+local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
+local readchar = streamreader.readinteger1 -- 8-bit signed integer
+local readshort = streamreader.readinteger2 -- 16-bit signed integer
+local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
+local readinteger = streamreader.readinteger1
+local readcardinaltable = streamreader.readcardinaltable
+local readintegertable = streamreader.readintegertable
+
+directives.register("fonts.streamreader",function()
+
+ streamreader = utilities.streams
+
+ setposition = streamreader.setposition
+ getposition = streamreader.getposition
+ skipbytes = streamreader.skip
+ readbyte = streamreader.readcardinal1
+ readushort = streamreader.readcardinal2
+ readulong = streamreader.readcardinal4
+ readchar = streamreader.readinteger1
+ readshort = streamreader.readinteger2
+ read2dot14 = streamreader.read2dot14
+ readinteger = streamreader.readinteger1
+ readcardinaltable = streamreader.readcardinaltable
+ readintegertable = streamreader.readintegertable
+
+end)
+
+local short = 2
+local ushort = 2
+local ulong = 4
+
+local helpers = readers.helpers
+local gotodatatable = helpers.gotodatatable
+
+local function mergecomposites(glyphs,shapes)
+
+ -- todo : deltas
+
+ local function merge(index,shape,components)
+ local contours = { }
+ local points = { }
+ local nofcontours = 0
+ local nofpoints = 0
+ local offset = 0
+ local deltas = shape.deltas
+ for i=1,#components do
+ local component = components[i]
+ local subindex = component.index
+ local subshape = shapes[subindex]
+ local subcontours = subshape.contours
+ local subpoints = subshape.points
+ if not subcontours then
+ local subcomponents = subshape.components
+ if subcomponents then
+ subcontours, subpoints = merge(subindex,subshape,subcomponents)
+ end
+ end
+ if subpoints then
+ local matrix = component.matrix
+ local xscale = matrix[1]
+ local xrotate = matrix[2]
+ local yrotate = matrix[3]
+ local yscale = matrix[4]
+ local xoffset = matrix[5]
+ local yoffset = matrix[6]
+ local count = #subpoints
+ if xscale == 1 and yscale == 1 and xrotate == 0 and yrotate == 0 then
+ for i=1,count do
+ local p = subpoints[i]
+ nofpoints = nofpoints + 1
+ points[nofpoints] = {
+ p[1] + xoffset,
+ p[2] + yoffset,
+ p[3]
+ }
+ end
+ else
+ for i=1,count do
+ local p = subpoints[i]
+ local x = p[1]
+ local y = p[2]
+ nofpoints = nofpoints + 1
+ points[nofpoints] = {
+ -- unifractur : u n
+ -- seguiemj : 0x270E 0x2710
+ xscale * x + xrotate * y + xoffset,
+ yscale * y + yrotate * x + yoffset,
+-- xscale * x + yrotate * y + xoffset,
+-- xrotate * x + yscale * y + yoffset,
+ p[3]
+ }
+ end
+ end
+ local subcount = #subcontours
+ if subcount == 1 then
+ nofcontours = nofcontours + 1
+ contours[nofcontours] = offset + subcontours[1]
+ else
+ for i=1,#subcontours do
+ nofcontours = nofcontours + 1
+ contours[nofcontours] = offset + subcontours[i]
+ end
+ end
+ offset = offset + count
+ else
+ report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
+ end
+ end
+ shape.points = points -- todo : phantom points
+ shape.contours = contours
+ shape.components = nil
+ return contours, points
+ end
+
+ for index=0,#glyphs do
+ local shape = shapes[index]
+ if shape then
+ local components = shape.components
+ if components then
+ merge(index,shape,components)
+ end
+ end
+ end
+
+end
+
+local function readnothing(f)
+ return {
+ type = "nothing",
+ }
+end
+
+-- begin of converter
+
+local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) -- todo: inline this
+ return
+ l_x + 2/3 *(m_x-l_x), l_y + 2/3 *(m_y-l_y),
+ r_x + 2/3 *(m_x-r_x), r_y + 2/3 *(m_y-r_y),
+ r_x, r_y, "c"
+end
+
+-- We could omit the operator which saves some 10%:
+--
+-- #2=lineto #4=quadratic #6=cubic #3=moveto (with "m")
+--
+-- This is tricky ... something to do with phantom points .. however, the hvar
+-- and vvar tables should take care of the width .. the test font doesn't have
+-- those so here we go then (we need a flag for hvar).
+--
+-- h-advance left-side-bearing v-advance top-side-bearing
+--
+-- We had two loops (going backward) but can do it in one loop .. but maybe we
+-- should only accept fonts with proper hvar tables.
+
+-- dowidth is kind of hack ... fonts are not always ok wrt these extra points
+
+local xv = { } -- we share this cache
+local yv = { } -- we share this cache
+
+local function applyaxis(glyph,shape,deltas,dowidth)
+ local points = shape.points
+ if points then
+ local nofpoints = #points
+ local dw = 0
+ local dl = 0
+ for i=1,#deltas do
+ local deltaset = deltas[i]
+ local xvalues = deltaset.xvalues
+ local yvalues = deltaset.yvalues
+ if xvalues and yvalues then
+ local dpoints = deltaset.points
+ local factor = deltaset.factor
+ if dpoints then
+ local cnt = #dpoints
+ if dowidth then
+ cnt = cnt - 4
+ end
+ if cnt > 0 then
+ -- Not the most efficient solution but we seldom do this. We
+ -- actually need to avoid the extra points here but I'll deal
+ -- with that when needed.
+ local contours = shape.contours
+ local nofcontours = #contours
+ local first = 1
+ local firstindex = 1
+ for contour=1,nofcontours do
+ local last = contours[contour]
+ if last >= first then
+ local lastindex = cnt
+ if firstindex < cnt then
+ for currentindex=firstindex,cnt do
+ local found = dpoints[currentindex]
+ if found <= first then
+ firstindex = currentindex
+ end
+ if found == last then
+ lastindex = currentindex
+ break
+ elseif found > last then
+ -- \definefontfeature[book][default][axis={weight=800}]
+ -- \definefont[testfont][file:Commissioner-vf-test.ttf*book]
+ -- \testfont EΘÄΞ
+ while lastindex > 1 and dpoints[lastindex] > last do
+ lastindex = lastindex - 1
+ end
+ --
+ break
+ end
+ end
+ end
+ -- print("unicode: ",glyph.unicode or "?")
+ -- print("contour: ",first,contour,last)
+ -- print("index : ",firstindex,lastindex,cnt)
+ -- print("points : ",dpoints[firstindex],dpoints[lastindex])
+ local function find(i)
+ local prv = lastindex
+ for j=firstindex,lastindex do
+ local nxt = dpoints[j] -- we could save this lookup when we return it
+ if nxt == i then
+ return false, j, false
+ elseif nxt > i then
+ return prv, false, j
+ end
+ prv = j
+ end
+ return prv, false, firstindex
+ end
+ -- We need the first and last points untouched so we first
+ -- collect data.
+ for point=first,last do
+ local d1, d2, d3 = find(point)
+ local p2 = points[point]
+ if d2 then
+ xv[point] = xvalues[d2]
+ yv[point] = yvalues[d2]
+ else
+ local n1 = dpoints[d1]
+ local n3 = dpoints[d3]
+ -- Some day I need to figure out these extra points but
+ -- I'll wait till the standard is more clear and fonts
+ -- become better (ntg-context: fraunces.ttf > abcdef).
+ if n1 > nofpoints then
+ n1 = nofpoints
+ end
+ if n3 > nofpoints then
+ n3 = nofpoints
+ end
+ --
+ local p1 = points[n1]
+ local p3 = points[n3]
+ local p1x = p1[1]
+ local p2x = p2[1]
+ local p3x = p3[1]
+ local p1y = p1[2]
+ local p2y = p2[2]
+ local p3y = p3[2]
+ local x1 = xvalues[d1]
+ local y1 = yvalues[d1]
+ local x3 = xvalues[d3]
+ local y3 = yvalues[d3]
+ --
+ local fx
+ local fy
+ --
+ if p1x == p3x then
+ if x1 == x3 then
+ fx = x1
+ else
+ fx = 0
+ end
+ elseif p2x <= min(p1x,p3x) then
+ if p1x < p3x then
+ fx = x1
+ else
+ fx = x3
+ end
+ elseif p2x >= max(p1x,p3x) then
+ if p1x > p3x then
+ fx = x1
+ else
+ fx = x3
+ end
+ else
+ fx = (p2x - p1x)/(p3x - p1x)
+-- fx = round(fx)
+ fx = (1 - fx) * x1 + fx * x3
+ end
+ --
+ if p1y == p3y then
+ if y1 == y3 then
+ fy = y1
+ else
+ fy = 0
+ end
+ elseif p2y <= min(p1y,p3y) then
+ if p1y < p3y then
+ fy = y1
+ else
+ fy = y3
+ end
+ elseif p2y >= max(p1y,p3y) then
+ if p1y > p3y then
+ fy = y1
+ else
+ fy = y3
+ end
+ else
+ fy = (p2y - p1y)/(p3y - p1y)
+-- fy = round(fy)
+ fy = (1 - fy) * y1 + fy * y3
+ end
+ -- -- maybe:
+ -- if p1y ~= p3y then
+ -- fy = (p2y - p1y)/(p3y - p1y)
+ -- fy = (1 - fy) * y1 + fy * y3
+ -- elseif abs(p1y-p2y) < abs(p3y-p2y) then
+ -- fy = y1
+ -- else
+ -- fy = y3
+ -- end
+ --
+ xv[point] = fx
+ yv[point] = fy
+ end
+ end
+ if lastindex < cnt then
+ firstindex = lastindex + 1
+ end
+ end
+ first = last + 1
+ end
+
+ for i=1,nofpoints do
+ local pi = points[i]
+ local fx = xv[i]
+ local fy = yv[i]
+ if fx ~= 0 then
+ pi[1] = pi[1] + factor * fx
+ end
+ if fy ~= 0 then
+ pi[2] = pi[2] + factor * fy
+ end
+ end
+ else
+ report("bad deltapoint data, maybe a missing hvar table")
+ end
+ else
+ for i=1,nofpoints do
+ local p = points[i]
+ local x = xvalues[i]
+ if x then
+ local y = yvalues[i]
+ if x ~= 0 then
+ p[1] = p[1] + factor * x
+ end
+ if y ~= 0 then
+ p[2] = p[2] + factor * y
+ end
+ else
+ break
+ end
+ end
+ end
+ if dowidth then
+ local h = nofpoints + 2 -- weird, the example font seems to have left first
+ local l = nofpoints + 1
+ ----- v = nofpoints + 3
+ ----- t = nofpoints + 4
+ local x = xvalues[h]
+ if x then
+ dw = dw + factor * x
+ end
+ local x = xvalues[l]
+ if x then
+ dl = dl + factor * x
+ end
+ end
+ end
+ end
+ -- for i=1,nofpoints do
+ -- local p = points[i]
+ -- p[1] = round(p[1])
+ -- p[2] = round(p[2])
+ -- end
+ if dowidth then
+ local width = glyph.width or 0
+ -- local lsb = glyph.lsb or 0
+ glyph.width = width + dw - dl
+ end
+ else
+ report("no points for glyph %a",glyph.name)
+ end
+end
+
+-- round or not ?
+
+-- local quadratic = true -- both methods work, todo: install a directive
+local quadratic = false
+
+local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox overhead
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
+ local shape = shapes[index]
+ if shape then
+ local glyph = glyphs[index]
+ local contours = shape.contours
+ local points = shape.points
+ if contours then
+ local nofcontours = #contours
+ local segments = { }
+ local nofsegments = 0
+ glyph.segments = segments
+ if nofcontours > 0 then
+ local px = 0
+ local py = 0
+ local first = 1
+ for i=1,nofcontours do
+ local last = contours[i]
+ if last >= first then
+ local first_pt = points[first]
+ local first_on = first_pt[3]
+ -- todo no new tables but reuse lineto and quadratic
+ if first == last then
+ first_pt[3] = "m" -- "moveto"
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = first_pt
+ else -- maybe also treat n == 2 special
+ local first_on = first_pt[3]
+ local last_pt = points[last]
+ local last_on = last_pt[3]
+ local start = 1
+ local control_pt = false
+ if first_on then
+ start = 2
+ else
+ if last_on then
+ first_pt = last_pt
+ else
+ first_pt = { (first_pt[1]+last_pt[1])/2, (first_pt[2]+last_pt[2])/2, false }
+ end
+ control_pt = first_pt
+ end
+ local x = first_pt[1]
+ local y = first_pt[2]
+ if not done then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ done = true
+ end
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "m" } -- "moveto"
+ if not quadratic then
+ px = x
+ py = y
+ end
+ local previous_pt = first_pt
+ for i=first,last do
+ local current_pt = points[i]
+ local current_on = current_pt[3]
+ local previous_on = previous_pt[3]
+ if previous_on then
+ if current_on then
+ -- both normal points
+ local x, y = current_pt[1], current_pt[2]
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "l" } -- "lineto"
+ if not quadratic then
+ px, py = x, y
+ end
+ else
+ control_pt = current_pt
+ end
+ elseif current_on then
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = current_pt[1]
+ local y2 = current_pt[2]
+ nofsegments = nofsegments + 1
+ if quadratic then
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ control_pt = false
+ else
+ local x2 = (previous_pt[1]+current_pt[1])/2
+ local y2 = (previous_pt[2]+current_pt[2])/2
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ nofsegments = nofsegments + 1
+ if quadratic then
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ control_pt = current_pt
+ end
+ previous_pt = current_pt
+ end
+ if first_pt == last_pt then
+ -- we're already done, probably a simple curve
+ else
+ nofsegments = nofsegments + 1
+ local x2 = first_pt[1]
+ local y2 = first_pt[2]
+ if not control_pt then
+ segments[nofsegments] = { x2, y2, "l" } -- "lineto"
+ elseif quadratic then
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ else
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ -- px, py = x2, y2
+ end
+ end
+ end
+ end
+ first = last + 1
+ end
+ end
+ end
+ end
+ end
+end
+
+local function contours2outlines_shaped(glyphs,shapes,keepcurve)
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
+ local shape = shapes[index]
+ if shape then
+ local glyph = glyphs[index]
+ local contours = shape.contours
+ local points = shape.points
+ if contours then
+ local nofcontours = #contours
+ local segments = keepcurve and { } or nil
+ local nofsegments = 0
+ if keepcurve then
+ glyph.segments = segments
+ end
+ if nofcontours > 0 then
+ local xmin, ymin, xmax, ymax, done = 0, 0, 0, 0, false
+ local px, py = 0, 0 -- we could use these in calculations which saves a copy
+ local first = 1
+ for i=1,nofcontours do
+ local last = contours[i]
+ if last >= first then
+ local first_pt = points[first]
+ local first_on = first_pt[3]
+ -- todo no new tables but reuse lineto and quadratic
+ if first == last then
+ -- this can influence the boundingbox
+ if keepcurve then
+ first_pt[3] = "m" -- "moveto"
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = first_pt
+ end
+ else -- maybe also treat n == 2 special
+ local first_on = first_pt[3]
+ local last_pt = points[last]
+ local last_on = last_pt[3]
+ local start = 1
+ local control_pt = false
+ if first_on then
+ start = 2
+ else
+ if last_on then
+ first_pt = last_pt
+ else
+ first_pt = { (first_pt[1]+last_pt[1])/2, (first_pt[2]+last_pt[2])/2, false }
+ end
+ control_pt = first_pt
+ end
+ local x = first_pt[1]
+ local y = first_pt[2]
+ if not done then
+ xmin, ymin, xmax, ymax = x, y, x, y
+ done = true
+ else
+ if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "m" } -- "moveto"
+ end
+ if not quadratic then
+ px = x
+ py = y
+ end
+ local previous_pt = first_pt
+ for i=first,last do
+ local current_pt = points[i]
+ local current_on = current_pt[3]
+ local previous_on = previous_pt[3]
+ if previous_on then
+ if current_on then
+ -- both normal points
+ local x = current_pt[1]
+ local y = current_pt[2]
+ if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "l" } -- "lineto"
+ end
+ if not quadratic then
+ px = x
+ py = y
+ end
+ else
+ control_pt = current_pt
+ end
+ elseif current_on then
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = current_pt[1]
+ local y2 = current_pt[2]
+ if quadratic then
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ end
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end
+ if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end
+ if px < xmin then xmin = px elseif px > xmax then xmax = px end
+ if py < ymin then ymin = py elseif py > ymax then ymax = py end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ end
+ control_pt = false
+ else
+ local x2 = (previous_pt[1]+current_pt[1])/2
+ local y2 = (previous_pt[2]+current_pt[2])/2
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ if quadratic then
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ end
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end
+ if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end
+ if px < xmin then xmin = px elseif px > xmax then xmax = px end
+ if py < ymin then ymin = py elseif py > ymax then ymax = py end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ end
+ control_pt = current_pt
+ end
+ previous_pt = current_pt
+ end
+ if first_pt == last_pt then
+ -- we're already done, probably a simple curve
+ elseif not control_pt then
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { first_pt[1], first_pt[2], "l" } -- "lineto"
+ end
+ else
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = first_pt[1]
+ local y2 = first_pt[2]
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if quadratic then
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ end
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end
+ if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end
+ if px < xmin then xmin = px elseif px > xmax then xmax = px end
+ if py < ymin then ymin = py elseif py > ymax then ymax = py end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ -- px, py = x2, y2
+ end
+ end
+ end
+ end
+ first = last + 1
+ end
+ -- See readers.hvar where we set the delta lsb as well as the adapted
+ -- width. At this point we do know the boundingbox's llx. The xmax is
+ -- not that relevant. It needs more testing!
+ --
+ xmin = glyph.boundingbox[1]
+ --
+ local dlsb = glyph.dlsb
+ if dlsb then
+ xmin = xmin + dlsb
+ glyph.dlsb = nil -- save space
+ end
+ --
+ glyph.boundingbox = { round(xmin), round(ymin), round(xmax), round(ymax) }
+ end
+ end
+ end
+ end
+end
+
+-- optimize for zero
+
+local c_zero = char(0)
+local s_zero = char(0,0)
+
+-- local shorthash = setmetatableindex(function(t,k)
+-- -- t[k] = char(band(rshift(k,8),0xFF),band(k,0xFF)) return t[k]
+-- t[k] = char((k >> 8) & 0xFF,k & 0xFF) return t[k]
+-- end)
+
+local function toushort(n)
+ -- return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ return char((n >> 8) & 0xFF,n & 0xFF)
+ -- return shorthash[n]
+end
+
+local function toshort(n)
+ if n < 0 then
+ n = n + 0x10000
+ end
+ -- return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ return char((n >> 8) & 0xFF,n & 0xFF)
+ -- return shorthash[n]
+end
+
+-- todo: we can reuse result, xpoints and ypoints
+
+local chars = setmetatableindex(function(t,k)
+ for i=0,255 do local v = char(i) t[i] = v end return t[k]
+end)
+
+local function repackpoints(glyphs,shapes)
+ local noboundingbox = { 0, 0, 0, 0 }
+ local result = { } -- reused
+ local xpoints = { } -- reused
+ local ypoints = { } -- reused
+ for index=0,#glyphs do
+ local shape = shapes[index]
+ if shape then
+ local r = 0
+ local glyph = glyphs[index]
+ local contours = shape.contours
+ local nofcontours = contours and #contours or 0
+ local boundingbox = glyph.boundingbox or noboundingbox
+ r = r + 1 result[r] = toshort(nofcontours)
+ r = r + 1 result[r] = toshort(boundingbox[1]) -- xmin
+ r = r + 1 result[r] = toshort(boundingbox[2]) -- ymin
+ r = r + 1 result[r] = toshort(boundingbox[3]) -- xmax
+ r = r + 1 result[r] = toshort(boundingbox[4]) -- ymax
+ if nofcontours > 0 then
+ for i=1,nofcontours do
+ r = r + 1 result[r] = toshort(contours[i]-1)
+ end
+ r = r + 1 result[r] = s_zero -- no instructions
+ local points = shape.points
+ local currentx = 0
+ local currenty = 0
+ -- local xpoints = { }
+ -- local ypoints = { }
+ local x = 0
+ local y = 0
+ local lastflag = nil
+ local nofflags = 0
+ for i=1,#points do
+ local pt = points[i]
+ local px = pt[1]
+ local py = pt[2]
+ local fl = pt[3] and 0x01 or 0x00
+ if px == currentx then
+ fl = fl + 0x10
+ else
+ local dx = round(px - currentx)
+ x = x + 1
+ if dx < -255 or dx > 255 then
+ xpoints[x] = toshort(dx)
+ elseif dx < 0 then
+ fl = fl + 0x02
+ -- xpoints[x] = char(-dx)
+ xpoints[x] = chars[-dx]
+ elseif dx > 0 then
+ fl = fl + 0x12
+ -- xpoints[x] = char(dx)
+ xpoints[x] = chars[dx]
+ else
+ fl = fl + 0x02
+ xpoints[x] = c_zero
+ end
+ end
+ if py == currenty then
+ fl = fl + 0x20
+ else
+ local dy = round(py - currenty)
+ y = y + 1
+ if dy < -255 or dy > 255 then
+ ypoints[y] = toshort(dy)
+ elseif dy < 0 then
+ fl = fl + 0x04
+ -- ypoints[y] = char(-dy)
+ ypoints[y] = chars[-dy]
+ elseif dy > 0 then
+ fl = fl + 0x24
+ -- ypoints[y] = char(dy)
+ ypoints[y] = chars[dy]
+ else
+ fl = fl + 0x04
+ ypoints[y] = c_zero
+ end
+ end
+ currentx = px
+ currenty = py
+ if lastflag == fl then
+ if nofflags == 255 then
+ -- This happens in koeieletters!
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ nofflags = 1
+ lastflag = fl
+ else
+ nofflags = nofflags + 1
+ end
+ else -- if > 255
+ if nofflags == 1 then
+ -- r = r + 1 result[r] = char(lastflag)
+ r = r + 1 result[r] = chars[lastflag]
+ elseif nofflags == 2 then
+ r = r + 1 result[r] = char(lastflag,lastflag)
+ elseif nofflags > 2 then
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ end
+ nofflags = 1
+ lastflag = fl
+ end
+ end
+ if nofflags == 1 then
+ -- r = r + 1 result[r] = char(lastflag)
+ r = r + 1 result[r] = chars[lastflag]
+ elseif nofflags == 2 then
+ r = r + 1 result[r] = char(lastflag,lastflag)
+ elseif nofflags > 2 then
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ end
+ -- r = r + 1 result[r] = concat(xpoints)
+ -- r = r + 1 result[r] = concat(ypoints)
+ r = r + 1 result[r] = concat(xpoints,"",1,x)
+ r = r + 1 result[r] = concat(ypoints,"",1,y)
+ end
+ -- can be helper or delegated to user
+ local stream = concat(result,"",1,r)
+ local length = #stream
+ local padding = ((length+3) // 4) * 4 - length
+ if padding > 0 then
+ -- stream = stream .. rep("\0",padding) -- can be a repeater
+ if padding == 1 then
+ padding = "\0"
+ elseif padding == 2 then
+ padding = "\0\0"
+ else
+ padding = "\0\0\0"
+ end
+ padding = stream .. padding
+ end
+ glyph.stream = stream
+ end
+ end
+end
+
+-- end of converter
+
+local flags = { }
+
+local function readglyph(f,nofcontours) -- read deltas here, saves space
+ local points = { }
+ -- local instructions = { }
+ local contours = { } -- readintegertable(f,nofcontours,short)
+ for i=1,nofcontours do
+ contours[i] = readshort(f) + 1
+ end
+ local nofpoints = contours[nofcontours]
+ local nofinstructions = readushort(f)
+ skipbytes(f,nofinstructions)
+ -- because flags can repeat we don't know the amount ... in fact this is
+ -- not that efficient (small files but more mem)
+ local i = 1
+ while i <= nofpoints do
+ local flag = readbyte(f)
+ flags[i] = flag
+ if (flag & 0x08) ~= 0 then
+ local n = readbyte(f)
+ if n == 1 then
+ i = i + 1
+ flags[i] = flag
+ else
+ for j=1,n do
+ i = i + 1
+ flags[i] = flag
+ end
+ end
+ end
+ i = i + 1
+ end
+ -- first come the x coordinates, and next the y coordinates and they
+ -- can be repeated
+ local x = 0
+ for i=1,nofpoints do
+ local flag = flags[i]
+ -- local short = (flag & 0x02) ~= 0
+ -- local same = (flag & 0x10) ~= 0
+ if (flag & 0x02) ~= 0 then
+ if (flag & 0x10) ~= 0 then
+ x = x + readbyte(f)
+ else
+ x = x - readbyte(f)
+ end
+ elseif (flag & 0x10) ~= 0 then
+ -- copy
+ else
+ x = x + readshort(f)
+ end
+ points[i] = { x, 0, (flag & 0x01) ~= 0 }
+ end
+ local y = 0
+ for i=1,nofpoints do
+ local flag = flags[i]
+ -- local short = (flag & 0x04) ~= 0
+ -- local same = (flag & 0x20) ~= 0
+ if (flag & 0x04) ~= 0 then
+ if (flag & 0x20) ~= 0 then
+ y = y + readbyte(f)
+ else
+ y = y - readbyte(f)
+ end
+ elseif (flag & 0x20) ~= 0 then
+ -- copy
+ else
+ y = y + readshort(f)
+ end
+ points[i][2] = y
+ end
+ return {
+ type = "glyph",
+ points = points,
+ contours = contours,
+ nofpoints = nofpoints,
+ }
+end
+
+local function readcomposite(f)
+ local components = { }
+ local nofcomponents = 0
+ local instructions = false
+ while true do
+ local flags = readushort(f)
+ local index = readushort(f)
+ ----- f_words = (flags & 0x0001) ~= 0
+ local f_xyarg = (flags & 0x0002) ~= 0
+ ----- f_round = (flags & 0x0006) ~= 0 -- 2 + 4
+ ----- f_scale = (flags & 0x0008) ~= 0
+ ----- f_reserved = (flags & 0x0010) ~= 0
+ ----- f_more = (flags & 0x0020) ~= 0
+ ----- f_xyscale = (flags & 0x0040) ~= 0
+ ----- f_matrix = (flags & 0x0080) ~= 0
+ ----- f_instruct = (flags & 0x0100) ~= 0
+ ----- f_usemine = (flags & 0x0200) ~= 0
+ ----- f_overlap = (flags & 0x0400) ~= 0
+ local f_offset = (flags & 0x0800) ~= 0
+ ----- f_uoffset = (flags & 0x1000) ~= 0
+ local xscale = 1
+ local xrotate = 0
+ local yrotate = 0
+ local yscale = 1
+ local xoffset = 0
+ local yoffset = 0
+ local base = false
+ local reference = false
+ if f_xyarg then
+ if (flags & 0x0001) ~= 0 then -- f_words
+ xoffset = readshort(f)
+ yoffset = readshort(f)
+ else
+ xoffset = readchar(f) -- signed byte, stupid name
+ yoffset = readchar(f) -- signed byte, stupid name
+ end
+ else
+ if (flags & 0x0001) ~= 0 then -- f_words
+ base = readshort(f)
+ reference = readshort(f)
+ else
+ base = readchar(f) -- signed byte, stupid name
+ reference = readchar(f) -- signed byte, stupid name
+ end
+ end
+ if (flags & 0x0008) ~= 0 then -- f_scale
+ xscale = read2dot14(f)
+ yscale = xscale
+ if f_xyarg and f_offset then
+ xoffset = xoffset * xscale
+ yoffset = yoffset * yscale
+ end
+ elseif (flags & 0x0040) ~= 0 then -- f_xyscale
+ xscale = read2dot14(f)
+ yscale = read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset = xoffset * xscale
+ yoffset = yoffset * yscale
+ end
+ elseif (flags & 0x0080) ~= 0 then -- f_matrix
+ xscale = read2dot14(f) -- xxpart
+ xrotate = read2dot14(f) -- yxpart
+ yrotate = read2dot14(f) -- xypart
+ yscale = read2dot14(f) -- yypart
+ if f_xyarg and f_offset then
+ xoffset = xoffset * sqrt(xscale ^2 + yrotate^2) -- was xrotate
+ yoffset = yoffset * sqrt(xrotate^2 + yscale ^2) -- was yrotate
+ end
+ end
+ nofcomponents = nofcomponents + 1
+ components[nofcomponents] = {
+ index = index,
+ usemine = (flags & 0x0200) ~= 0, -- f_usemine
+ round = (flags & 0x0006) ~= 0, -- f_round,
+ base = base,
+ reference = reference,
+ matrix = { xscale, xrotate, yrotate, yscale, xoffset, yoffset },
+ }
+ if (flags & 0x0100) ~= 0 then
+ instructions = true
+ end
+ if (flags & 0x0020) == 0 then -- f_more
+ break
+ end
+ end
+ return {
+ type = "composite",
+ components = components,
+ }
+end
+
+-- function readers.cff(f,offset,glyphs,doshapes) -- false == no shapes (nil or true otherwise)
+
+-- The glyf table depends on the loca table. We have one entry to much
+-- in the locations table (the last one is a dummy) because we need to
+-- calculate the size of a glyph blob from the delta, although we not
+-- need it in our usage (yet). We can remove the locations table when
+-- we're done (todo: cleanup finalizer).
+
+function readers.loca(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable = fontdata.tables.loca
+ if datatable then
+ -- locations are relative to the glypdata table (glyf)
+ local offset = fontdata.tables.glyf.offset
+ local format = fontdata.fontheader.indextolocformat
+ local profile = fontdata.maximumprofile
+ local nofglyphs = profile and profile.nofglyphs
+ local locations = { }
+ setposition(f,datatable.offset)
+ if format == 1 then
+ if not nofglyphs then
+ nofglyphs = (datatable.length // 4) - 1
+ end
+ for i=0,nofglyphs do
+ locations[i] = offset + readulong(f)
+ end
+ fontdata.nofglyphs = nofglyphs
+ else
+ if not nofglyphs then
+ nofglyphs = (datatable.length // 2) - 1
+ end
+ for i=0,nofglyphs do
+ locations[i] = offset + readushort(f) * 2
+ end
+ end
+ fontdata.nofglyphs = nofglyphs
+ fontdata.locations = locations
+ end
+ end
+end
+
+function readers.glyf(f,fontdata,specification) -- part goes to cff module
+ local tableoffset = gotodatatable(f,fontdata,"glyf",specification.glyphs)
+ if tableoffset then
+ local locations = fontdata.locations
+ if locations then
+ local glyphs = fontdata.glyphs
+ local nofglyphs = fontdata.nofglyphs
+ local filesize = fontdata.filesize
+ local nothing = { 0, 0, 0, 0 }
+ local shapes = { }
+ local loadshapes = specification.shapes or specification.instance or specification.streams
+ for index=0,nofglyphs-1 do
+ local location = locations[index]
+ local length = locations[index+1] - location
+ if location >= filesize then
+ report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
+ fontdata.nofglyphs = index - 1
+ fontdata.badfont = true
+ break
+ elseif length > 0 then
+ setposition(f,location)
+ local nofcontours = readshort(f)
+ glyphs[index].boundingbox = {
+ readshort(f), -- xmin
+ readshort(f), -- ymin
+ readshort(f), -- xmax
+ readshort(f), -- ymax
+ }
+ if not loadshapes then
+ -- save space
+ elseif nofcontours == 0 then
+ shapes[index] = readnothing(f)
+ elseif nofcontours > 0 then
+ shapes[index] = readglyph(f,nofcontours)
+ else
+ shapes[index] = readcomposite(f,nofcontours)
+ end
+ else
+ if loadshapes then
+ shapes[index] = readnothing(f)
+ end
+ glyphs[index].boundingbox = nothing
+ end
+ end
+ if loadshapes then
+ if readers.gvar then
+ readers.gvar(f,fontdata,specification,glyphs,shapes)
+ end
+ mergecomposites(glyphs,shapes)
+ if specification.instance then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_shaped(glyphs,shapes,specification.shapes)
+ end
+ elseif specification.shapes then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_normal(glyphs,shapes)
+ end
+ elseif specification.streams then
+ repackpoints(glyphs,shapes)
+ end
+ end
+ end
+ end
+end
+
+-- gvar is a bit crazy format and one can really wonder if the bit-jugling obscurity
+-- is still needed in these days .. cff is much nicer with these blends while the ttf
+-- coding variant looks quite horrible
+
+local function readtuplerecord(f,nofaxis)
+ local record = { }
+ for i=1,nofaxis do
+ record[i] = read2dot14(f)
+ end
+ return record
+end
+
+-- (1) the first is a real point the rest deltas
+-- (2) points can be present more than once (multiple deltas then)
+
+local function readpoints(f)
+ local count = readbyte(f)
+ if count == 0 then
+ -- second byte not used, deltas for all point numbers
+ return nil, 0 -- todo
+ else
+ if count < 128 then
+ -- no second byte, use count
+ elseif (count & 0x80) ~= 0 then
+ count = (count & 0x7F) * 256 + readbyte(f)
+ else
+ -- bad news
+ end
+ local points = { }
+ local p = 0
+ local n = 1 -- indices
+ while p < count do
+ local control = readbyte(f)
+ local runreader = (control & 0x80) ~= 0 and readushort or readbyte
+ local runlength = (control & 0x7F)
+ for i=1,runlength+1 do
+ n = n + runreader(f)
+ p = p + 1
+ points[p] = n
+ end
+ end
+ return points, p
+ end
+end
+
+local function readdeltas(f,nofpoints)
+ local deltas = { }
+ local p = 0
+ while nofpoints > 0 do
+ local control = readbyte(f)
+ if control then
+ local allzero = (control & 0x80) ~= 0
+ local runlength = (control & 0x3F) + 1
+ if allzero then
+ for i=1,runlength do
+ p = p + 1
+ deltas[p] = 0
+ end
+ else
+ local runreader = (control & 0x40) ~= 0 and readshort or readinteger
+ for i=1,runlength do
+ p = p + 1
+ deltas[p] = runreader(f)
+ end
+ end
+ nofpoints = nofpoints - runlength
+ else
+ -- it happens
+ break
+ end
+ end
+ -- saves space
+ if p > 0 then
+ return deltas
+ else
+ -- forget about all zeros
+ end
+end
+
+function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
+ -- this is one of the messiest tables
+ local instance = specification.instance
+ if not instance then
+ return
+ end
+ local factors = specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset = gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes)
+ if tableoffset then
+ local version = readulong(f) -- 1.0
+ local nofaxis = readushort(f)
+ local noftuples = readushort(f)
+ local tupleoffset = tableoffset + readulong(f)
+ local nofglyphs = readushort(f)
+ local flags = readushort(f)
+ local dataoffset = tableoffset + readulong(f)
+ local data = { }
+ local tuples = { }
+ local glyphdata = fontdata.glyphs
+ local dowidth = not fontdata.variabledata.hvarwidths
+ -- there is one more offset (so that one can calculate the size i suppose)
+ -- so we could test for overflows but we simply assume sane font files
+ if (flags & 0x0001) ~= 0 then
+ for i=1,nofglyphs+1 do
+ data[i] = dataoffset + readulong(f)
+ end
+ else
+ for i=1,nofglyphs+1 do
+ data[i] = dataoffset + 2*readushort(f)
+ end
+ end
+ --
+ if noftuples > 0 then
+ setposition(f,tupleoffset)
+ for i=1,noftuples do
+ tuples[i] = readtuplerecord(f,nofaxis)
+ end
+ end
+ local nextoffset = false
+ local startoffset = data[1]
+ for i=1,nofglyphs do -- hm one more cf spec
+ nextoffset = data[i+1]
+ local glyph = glyphdata[i-1]
+ local name = trace_deltas and glyph.name
+ if startoffset == nextoffset then
+ if name then
+ report("no deltas for glyph %a",name)
+ end
+ else
+ local shape = shapedata[i-1] -- todo 0
+ if not shape then
+ if name then
+ report("no shape for glyph %a",name)
+ end
+ else
+ lastoffset = startoffset
+ setposition(f,startoffset)
+ local flags = readushort(f)
+ local count = (flags & 0x0FFF)
+ local offset = startoffset + readushort(f) -- to serialized
+ local deltas = { }
+ local allpoints = (shape.nofpoints or 0) -- + 1
+ local shared = false
+ local nofshared = 0
+ if (flags & 0x8000) ~= 0 then -- has shared points
+ -- go to the packed stream (get them once)
+ local current = getposition(f)
+ setposition(f,offset)
+ shared, nofshared = readpoints(f)
+ offset = getposition(f)
+ setposition(f,current)
+ -- and back to the table
+ end
+ for j=1,count do
+ local size = readushort(f) -- check
+ local flags = readushort(f)
+ local index = (flags & 0x0FFF)
+ local haspeak = (flags & 0x8000) ~= 0
+ local intermediate = (flags & 0x4000) ~= 0
+ local private = (flags & 0x2000) ~= 0
+ local peak = nil
+ local start = nil
+ local stop = nil
+ local xvalues = nil
+ local yvalues = nil
+ local points = shared -- we default to shared
+ local nofpoints = nofshared -- we default to shared
+ -- local advance = 4
+ if haspeak then
+ peak = readtuplerecord(f,nofaxis)
+ -- advance = advance + 2*nofaxis
+ else
+ if index+1 > #tuples then
+ report("error, bad tuple index",index)
+ end
+ peak = tuples[index+1] -- hm, needs checking, only peak?
+ end
+ if intermediate then
+ start = readtuplerecord(f,nofaxis)
+ stop = readtuplerecord(f,nofaxis)
+ -- advance = advance + 4*nofaxis
+ end
+ -- get the deltas
+ if size > 0 then
+ local current = getposition(f)
+ -- goto the packed stream
+ setposition(f,offset)
+ if private then
+ points, nofpoints = readpoints(f)
+ end -- else
+ if nofpoints == 0 then
+ nofpoints = allpoints + 4
+ end
+ if nofpoints > 0 then
+ -- a nice test is to do only one
+ xvalues = readdeltas(f,nofpoints)
+ yvalues = readdeltas(f,nofpoints)
+ end
+ -- resync offset
+ offset = offset + size
+ -- back to the table
+ setposition(f,current)
+ end
+ if not xvalues and not yvalues then
+ points = nil
+ end
+ local s = 1
+ for i=1,nofaxis do
+ local f = factors[i]
+ local peak = peak and peak [i] or 0
+ -- local start = start and start[i] or 0
+ -- local stop = stop and stop [i] or 0
+ local start = start and start[i] or (peak < 0 and peak or 0)
+ local stop = stop and stop [i] or (peak > 0 and peak or 0) -- or 1 ?
+-- local stop = stop and stop [i] or (peak > 0 and peak or 1) -- or 1 ?
+ -- do we really need these tests ... can't we assume sane values
+ if start > peak or peak > stop then
+ -- * 1
+ elseif start < 0 and stop > 0 and peak ~= 0 then
+ -- * 1
+ elseif peak == 0 then
+ -- * 1
+ elseif f < start or f > stop then
+ -- * 0
+ s = 0
+ break
+ elseif f < peak then
+ s = s * (f - start) / (peak - start)
+ elseif f > peak then
+ s = s * (stop - f) / (stop - peak)
+ else
+ -- * 1
+ end
+ end
+ if s == 0 then
+ if name then
+ report("no deltas applied for glyph %a",name)
+ end
+ else
+ deltas[#deltas+1] = {
+ factor = s,
+ points = points,
+ xvalues = xvalues,
+ yvalues = yvalues,
+ }
+ end
+ end
+ if shape.type == "glyph" then
+ applyaxis(glyph,shape,deltas,dowidth)
+ else
+ -- todo: args_are_xy_values mess .. i have to be really bored
+ -- and motivated to deal with it
+ shape.deltas = deltas
+ end
+ end
+ end
+ startoffset = nextoffset
+ end
+ end
+end
diff --git a/tex/context/base/mkxl/libs-ini.lmt b/tex/context/base/mkxl/libs-ini.lmt
new file mode 100644
index 000000000..4ce0e8e50
--- /dev/null
+++ b/tex/context/base/mkxl/libs-ini.lmt
@@ -0,0 +1,206 @@
+if not modules then modules = { } end modules ['libs-ini'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is a loader for optional libraries in luametatex with context lmtx. It's
+-- kind of experimental. We also use a different locator than in mkiv because we
+-- don't support loading lua libraries and swiglibs any more. Of course one can try
+-- the regular lua loaders but we just assume that a user then knows what (s)he is
+-- doing. At some point this variant will divert more from the original loader
+-- file 'libs-ini.lua'.
+
+local type, unpack = type, unpack
+local find = string.find
+
+-- here we implement the resolver
+
+local nameonly = file.nameonly
+local joinfile = file.join
+local addsuffix = file.addsuffix
+local qualifiedpath = file.is_qualified_path
+
+local isfile = lfs.isfile
+
+local findfile = resolvers.findfile
+local expandpaths = resolvers.expandedpathlistfromvariable
+
+local report = logs.reporter("resolvers","libraries")
+local trace = false
+local silent = false
+
+trackers.register("resolvers.lib", function(v) trace = v end)
+trackers.register("resolvers.lib.silent", function(v) silent = v end)
+
+local function findlib(required) -- todo: cache
+ local suffix = os.libsuffix or "so"
+ if not qualifiedpath(required) then
+ local list = directives.value("system.librarynames" )
+ local only = nameonly(required)
+ if type(list) == "table" then
+ list = list[only]
+ if type(list) ~= "table" then
+ list = { only }
+ end
+ else
+ list = { only }
+ end
+ if trace then
+ report("using lookup list for library %a: % | t",only,list)
+ end
+ for i=1,#list do
+ local name = list[i]
+ local found = findfile(name,"lib")
+ if not found or found == "" then
+ found = findfile(addsuffix(name,suffix),"lib")
+ end
+ if found and found ~= "" then
+ if trace then
+ report("library %a resolved via %a path to %a",name,"tds lib",found)
+ end
+ return found
+ end
+ end
+ if expandpaths then
+ local list = expandpaths("PATH")
+ local base = addsuffix(only,suffix)
+ for i=1,#list do
+ local full = joinfile(list[i],base)
+ local found = isfile(full) and full
+ if found and found ~= "" then
+ if trace then
+ report("library %a resolved via %a path to %a",full,"system",found)
+ end
+ return found
+ end
+ end
+ end
+ elseif isfile(addsuffix(required,suffix)) then
+ if trace then
+ report("library with qualified name %a %sfound",required,"")
+ end
+ return required
+ else
+ if trace then
+ report("library with qualified name %a %sfound",required,"not ")
+ end
+ end
+ return false
+end
+
+local foundlibraries = table.setmetatableindex(function(t,k)
+ local v = findlib(k)
+ t[k] = v
+ return v
+end)
+
+function resolvers.findlib(required)
+ return foundlibraries[required]
+end
+
+-- here we implement the loader
+
+local libraries = { }
+resolvers.libraries = libraries
+
+local report = logs.reporter("optional")
+
+if optional then optional.loaded = { } end
+
+function libraries.validoptional(name)
+ local thelib = optional and optional[name]
+ if not thelib then
+ -- forget about it, no message here
+ elseif thelib.initialize then
+ return thelib
+ else
+ report("invalid optional library %a",libname)
+ end
+end
+
+function libraries.optionalloaded(name,libnames)
+ local thelib = optional and optional[name]
+ if not thelib then
+ report("no optional %a library found",name)
+ else
+ local thelib_initialize = thelib.initialize
+ if not thelib_initialize then
+ report("invalid optional library %a",name)
+ else
+ if type(libnames) == "string" then
+ libnames = { libnames }
+ end
+ if type(libnames) == "table" then
+ for i=1,#libnames do
+ local libname = libnames[i]
+ local filename = foundlibraries[libname]
+ if filename and filename ~= "" then
+ libnames[i] = filename
+ else
+ report("unable to locate library %a",libname)
+ return
+ end
+ end
+ local initialized = thelib_initialize(unpack(libnames))
+ if not initialized then
+ report("unable to initialize library '% + t'",libnames)
+ elseif not silent then
+ report("using library '% + t'",libnames)
+ end
+ return initialized
+ end
+ end
+ end
+end
+
+-- local patterns = {
+-- "libs-imp-%s.mkxl",
+-- "libs-imp-%s.mklx",
+-- }
+--
+-- local function action(name,foundname)
+-- -- could be one command
+-- context.startreadingfile()
+-- context.input(foundname)
+-- context.stopreadingfile()
+-- end
+--
+-- interfaces.implement {
+-- name = "uselibrary",
+-- arguments = "string"
+-- actions = function(name)
+-- resolvers.uselibrary {
+-- category = "color definition",
+-- name = name,
+-- patterns = patterns,
+-- action = action,
+-- onlyonce = true,
+-- }
+-- end
+-- }
+
+-- We overload the standard 'require' function. Because we're in LuaMetaTeX we are
+-- more likely to find 'lmt' files when we deal with the TeX and MetaPost part but
+-- user files likely have the 'lua' suffix.
+
+do
+
+ local dofile = dofile
+ local savedrequire = require
+
+ function require(name,version)
+ if find(name,"%.lua$") or find(name,"%.lmt$") then
+ local m = dofile(findfile(name))
+ if m then
+ package.loaded[name] = m
+ return m
+ end
+ else
+ return savedrequire(name)
+ end
+ end
+
+end
diff --git a/tex/context/base/mkxl/libs-ini.mkxl b/tex/context/base/mkxl/libs-ini.mkxl
index ef24536bf..bc1fe92e0 100644
--- a/tex/context/base/mkxl/libs-ini.mkxl
+++ b/tex/context/base/mkxl/libs-ini.mkxl
@@ -11,12 +11,12 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\registerctxluafile{libs-ini}{} % shared with mkiv
+\registerctxluafile{libs-ini}{autosuffix}
% These are used by the graphic converters:
-\registerctxluafile{libs-imp-curl}{autosuffix}
-\registerctxluafile{libs-imp-ghostscript}{autosuffix}
+\registerctxluafile{libs-imp-curl} {autosuffix}
+\registerctxluafile{libs-imp-ghostscript} {autosuffix}
\registerctxluafile{libs-imp-graphicsmagick}{autosuffix}
% These are loaded on demand:
diff --git a/tex/context/base/mkxl/luat-lib.mkxl b/tex/context/base/mkxl/luat-lib.mkxl
index 7ad29e29e..cb161cafa 100644
--- a/tex/context/base/mkxl/luat-lib.mkxl
+++ b/tex/context/base/mkxl/luat-lib.mkxl
@@ -61,7 +61,7 @@
\registerctxluafile{data-pre}{} % after data-res
\registerctxluafile{data-bin}{} % before data-tex
\registerctxluafile{data-tex}{} % after data-pre
-\registerctxluafile{data-vir}{}
+\registerctxluafile{data-vir}{autosuffix}
\registerctxluafile{data-zip}{}
\registerctxluafile{data-dec}{}
\registerctxluafile{data-tar}{}
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt
index faa0d2ae5..19a43ce87 100644
--- a/tex/context/base/mkxl/math-act.lmt
+++ b/tex/context/base/mkxl/math-act.lmt
@@ -321,7 +321,7 @@ mathtweaks.subsets = {
p = { 0x1D45D },
dotless = { 0x00049, 0x0004A, 0x00131, 0x00237, 0x1D6A4, 0x1D6A5 },
integrals = { 0x0222B, 0x0222C, 0x0222D, 0x0222E, 0x0222F, 0x02230, 0x02231, 0x02232, 0x02233, 0x02A0B, 0x02A0C, 0x02A0D, 0x02A0E, 0x02A0F, 0x02A10, 0x02A11, 0x02A12, 0x02A13, 0x02A14, 0x02A15, 0x02A16, 0x02A17, 0x02A18, 0x02A19, 0x02A1A, 0x02A1B, 0x02A1C, 0x02320, 0x02321 },
- horizontalfences = { 0x023B4, 0x023B5, 0x023DC, 0x023DD, 0x023DE, 0x023DF, 0x023E0, 0x023E1 }, -- not really used
+ horizontalfences = { 0x0203E, 0x023B4, 0x023B5, 0x023DC, 0x023DD, 0x023DE, 0x023DF, 0x023E0, 0x023E1 }, -- not really used
}
local function getalso(target,original)
@@ -1844,7 +1844,8 @@ do
parts = {
{ advance = width, ["end"] = step, glyph = 0x203E, start = 0 },
{ advance = width, ["end"] = 0, glyph = 0x203E, start = step, extender = 1 },
- }
+ },
+ partsorientation = "horizontal",
}
--
characters[0x0332] = characters[0x203E]
@@ -1872,7 +1873,8 @@ do
{ advance = thickness, glyph = tpiece, ["end"] = 0, start = half },
{ advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 },
{ advance = thickness, glyph = tpiece, ["end"] = half, start = 0 },
- }
+ },
+ partsorientation = "horizontal",
}
end
if not characters[0x23B5] then
@@ -1893,7 +1895,8 @@ do
{ advance = thickness, glyph = bpiece, ["end"] = 0, start = half },
{ advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 },
{ advance = thickness, glyph = bpiece, ["end"] = half, start = 0 },
- }
+ },
+ partsorientation = "horizontal",
}
end
--
@@ -1932,7 +1935,8 @@ do
end
if chardata and (force or overloads[unicode] == false or not chardata.parts) then
if not list then
- chardata.parts = nil -- when we test
+ -- chardata.parts = nil -- when we test
+ chardata.parts = { { glyph = unicode } }
else
local overload = overloads[unicode]
local parts = { }
@@ -2030,6 +2034,7 @@ do
[0x21CB] = centered, -- leftrightharpoons
[0x21CC] = centered, -- rightleftharpoons
[0x21C4] = centered, -- rightoverleftarrow
+ [0x21C6] = centered, -- leftoverrightarrow
[0x21A6] = centered, -- mapsto
--
[0x203E] = { slackslack, { left = slack, right = slack, extensible = true } }, -- bar
diff --git a/tex/context/base/mkxl/math-rad.mklx b/tex/context/base/mkxl/math-rad.mklx
index 645d32740..cb3cdb0a8 100644
--- a/tex/context/base/mkxl/math-rad.mklx
+++ b/tex/context/base/mkxl/math-rad.mklx
@@ -26,7 +26,7 @@
% \def\rootradical{\Uroot 0 "221A } % can be done in char-def
% \def\surdradical{\Uradical 0 "221A } % can be done in char-def
-\protected\def\sqrt{\doifelsenextoptionalcs\rootwithdegree\rootwithoutdegree} % will be redefined
+% \protected\def\sqrt{\doifelsenextoptionalcs\rootwithdegree\rootwithoutdegree} % will be redefined
% \permanent\protected\def\styledrootradical#1#2% so that \text works ok ... \rootradical behaves somewhat weird
% {\normalexpanded{\math_radical_common
@@ -39,8 +39,8 @@
% \permanent\protected\def\styledrootradical#1#2% so that \text works ok ... \rootradical behaves somewhat weird
% {\Uroot style \normalmathstyle "0 "221A {#1}{#2}}
-\permanent\protected\def\rootwithdegree[#1]{\math_radical_common{#1}}
-\permanent\protected\def\rootwithoutdegree {\math_radical_common {}}
+% \permanent\protected\def\rootwithdegree[#1]{\math_radical_common{#1}}
+% \permanent\protected\def\rootwithoutdegree {\math_radical_common {}}
%D Even older stuff:
@@ -79,6 +79,20 @@
%D $ \sqrt[3]{5} \RR\sqrt[3]{5} \sqrt[3]{5} $\par
%D $ \sqrt[3]{5} {\RR\sqrt[3]{5}} \sqrt[3]{5} $\par
%D \stoptyping
+%D
+%D And:
+%D
+%D \starttyping
+%D \definemathradical[lsqrt][strut=yes]
+%D \definemathradical[msqrt][strut=math]
+%D \definemathradical[xsqrt][height=3ex,depth=2ex]
+%D
+%D $\sqrt[strut=no][3]{y}$
+%D $\sqrt[strut=no,n=5]{y}$
+%D $\sqrt[strut=no,n=5][6]{y}$
+%D $\sqrt[strut=math]{y}$
+%D $\sqrt[3]{y}$
+%D \stoptyping
\installcorenamespace{mathradical}
\installcorenamespace{mathradicalalternative}
@@ -117,9 +131,14 @@
\tolerant\protected\def\math_radical_handle#tag#*[#settings]#*[#degree]#:#body%
{\begingroup
\edef\currentmathradical{#tag}%
- \ifparameter#degree\or
- \edef\currentmathradicaldegree{#degree}%
+ \ifhastok={#settings}%
+ \lettonothing\currentmathradicaldegree
\setupcurrentmathradical[#settings]%
+ \ifparameter#degree\or
+ \edef\currentmathradicaldegree{#degree}%
+ \else
+ \edef\currentmathradicaldegree{\mathradicalparameter\c!n}%
+ \fi
\else
\edef\currentmathradicaldegree{#settings}%
\fi
@@ -253,7 +272,12 @@
\fi
\endgroup}
-\definemathradical[sqrt][mp=minifun::math:radical:default]
+\pushoverloadmode
+
+\definemathradical[root][mp=minifun::math:radical:default]
+\definemathradical[sqrt][root]
+
+\popoverloadmode
% \setupmathradical[sqrt][alternative=normal,color=darkblue]
% \setupmathradical[sqrt][alternative=mp,color=darkgreen]
diff --git a/tex/context/base/mkxl/math-stc.mklx b/tex/context/base/mkxl/math-stc.mklx
index 952fba6c6..5922fb116 100644
--- a/tex/context/base/mkxl/math-stc.mklx
+++ b/tex/context/base/mkxl/math-stc.mklx
@@ -98,19 +98,30 @@
\fi
\hss}}
-\def\math_stackers_regular
- {\mathstylehbox{\usemathstackerscolorparameter\c!color
- \hskip\d_math_stackers_offset_l
- \Umathaccent\zerocount\zerocount\scratchunicode
- {\hskip\dimexpr\scratchwidth-\d_math_stackers_offset_l-\d_math_stackers_offset_r}%
- \hskip\d_math_stackers_offset_r
- }}
+% \def\math_stackers_regular
+% {\mathstylehbox{\usemathstackerscolorparameter\c!color
+% \hskip\d_math_stackers_offset_l
+% \Umathaccent\zerocount\zerocount\scratchunicode
+% {\hskip\dimexpr\scratchwidth-\d_math_stackers_offset_l-\d_math_stackers_offset_r}%
+% \hskip\d_math_stackers_offset_r
+% }}
+
+% \def\math_stackers_stretch % we don't have that one yet
+% {\mathstylehbox{\usemathstackerscolorparameter\c!color
+% \hskip\d_math_stackers_offset_l
+% \Umathaccent\zerocount\zerocount\scratchunicode
+% {\hskip\dimexpr\hsize-\d_math_stackers_offset_l-\d_math_stackers_offset_r}%
+% \hskip\d_math_stackers_offset_r
+% }}
-\def\math_stackers_stretch % we don't have that one yet
+\def\math_stackers_regular
{\mathstylehbox{\usemathstackerscolorparameter\c!color
\hskip\d_math_stackers_offset_l
- \Umathaccent\zerocount\zerocount\scratchunicode
- {\hskip\dimexpr\hsize-\d_math_stackers_offset_l-\d_math_stackers_offset_r}%
+ \Uhextensible
+ middle
+ width \dimexpr\scratchwidth-\d_math_stackers_offset_l-\d_math_stackers_offset_r\relax
+ \zerocount\scratchunicode
+ \relax
\hskip\d_math_stackers_offset_r
}}
@@ -410,6 +421,9 @@
\setbox\scratchboxthree\csname\??mathstackersalternative\p_alternative\endcsname
\dostoptagged
\fi
+ \ifdim\wd\scratchboxthree>\scratchwidth
+ \scratchwidth\wd\scratchboxthree
+ \fi
%
\ifdim\wd\scratchboxone<\scratchwidth
\setbox\scratchboxone\hpack to \scratchwidth{\hss\unhbox\scratchboxone\hss}% unhboxing makes leaders work
@@ -1192,8 +1206,6 @@
\definemathextensible [\v!chemistry] [crightoverleftarrow] ["21C4]
\definemathextensible [\v!chemistry] [cleftoverrightarrow] ["21C6]
-% for the moment:
-
\def\math_stackers_hacked_fill#1#2#3%
{\mathematics
{\begingroup
@@ -1203,35 +1215,37 @@
\thinmuskip \zeromuskip
\tinymuskip \zeromuskip
\pettymuskip \zeromuskip
- #1%
- \mkern-7\onemuskip
- \cleaders\mathstylehbox{\mkern-2\onemuskip#2\mkern-2\onemuskip}\hfill
- \mkern-7\onemuskip
- #3%
+ \ifrelax#1%
+ \cleaders\mathstylehbox{#2}\hfill
+ \else
+ #1%
+ \mkern-7\onemuskip
+ \cleaders\mathstylehbox{\mkern-2\onemuskip#2\mkern-2\onemuskip}\hfill
+ \mkern-7\onemuskip
+ #3%
+ \fi
\endgroup}}
-% These will become characters defined in math-act.
-
-\immutable\protected\def\rightarrowfill {\math_stackers_hacked_fill \relbar \relbar \rightarrow}
-\immutable\protected\def\leftarrowfill {\math_stackers_hacked_fill \leftarrow \relbar \relbar }
-\immutable\protected\def\rightoverleftarrowfill{\math_stackers_hacked_fill \ctxdoublearrowfillleftend\ctxdoublearrowfillmiddlepart\ctxdoublearrowfillrightend}
-\immutable\protected\def\leftoverrightarrowfill{\math_stackers_hacked_fill \ctxdoublearrowfillrightend\ctxdoublearrowfillmiddlepart\ctxdoublearrowfillleftend}
-\immutable\protected\def\equalfill {\math_stackers_hacked_fill \Relbar \Relbar \Relbar}
-\immutable\protected\def\Rightarrowfill {\math_stackers_hacked_fill \Relbar \Relbar \Rightarrow}
-\immutable\protected\def\Leftarrowfill {\math_stackers_hacked_fill \Leftarrow \Relbar \Relbar}
-\immutable\protected\def\Leftrightarrowfill {\math_stackers_hacked_fill \Leftarrow \Relbar \Rightarrow}
-\immutable\protected\def\leftrightarrowfill {\math_stackers_hacked_fill \leftarrow \relbar \rightarrow}
-\immutable\protected\def\mapstofill {\math_stackers_hacked_fill{\mapstochar\relbar} \relbar \rightarrow}
-\immutable\protected\def\twoheadrightarrowfill {\math_stackers_hacked_fill \relbar \relbar \twoheadrightarrow}
-\immutable\protected\def\twoheadleftarrowfill {\math_stackers_hacked_fill \twoheadleftarrow \relbar \relbar}
-\immutable\protected\def\rightharpoondownfill {\math_stackers_hacked_fill \relbar \relbar \rightharpoondown}
-\immutable\protected\def\rightharpoonupfill {\math_stackers_hacked_fill \relbar \relbar \rightharpoonup}
-\immutable\protected\def\leftharpoondownfill {\math_stackers_hacked_fill \leftharpoondown \relbar \relbar}
-\immutable\protected\def\leftharpoonupfill {\math_stackers_hacked_fill \leftharpoonup \relbar \relbar}
-\immutable\protected\def\hookleftfill {\math_stackers_hacked_fill \leftarrow \relbar {\relbar\joinrel\rhook}}
-\immutable\protected\def\hookrightfill {\math_stackers_hacked_fill{\lhook\joinrel\relbar} \relbar \rightarrow}
-\immutable\protected\def\relfill {\math_stackers_hacked_fill \relbar \relbar \relbar}
-\immutable\protected\def\triplerelfill {\math_stackers_hacked_fill \equiv \equiv \equiv}
+\immutable\protected\def\rightarrowfill {\math_stackers_hacked_fill \relbar \relbar \rightarrow}
+\immutable\protected\def\leftarrowfill {\math_stackers_hacked_fill \leftarrow \relbar \relbar}
+\immutable\protected\def\rightoverleftarrowfill{\math_stackers_hacked_fill \relax \crightoverleftarrow \relax}
+\immutable\protected\def\leftoverrightarrowfill{\math_stackers_hacked_fill \relax \cleftoverrightarrow \relax}
+\immutable\protected\def\equalfill {\math_stackers_hacked_fill \Relbar \Relbar \Relbar}
+\immutable\protected\def\Rightarrowfill {\math_stackers_hacked_fill \Relbar \Relbar \Rightarrow}
+\immutable\protected\def\Leftarrowfill {\math_stackers_hacked_fill \Leftarrow \Relbar \Relbar}
+\immutable\protected\def\Leftrightarrowfill {\math_stackers_hacked_fill \Leftarrow \Relbar \Rightarrow}
+\immutable\protected\def\leftrightarrowfill {\math_stackers_hacked_fill \leftarrow \relbar \rightarrow}
+\immutable\protected\def\mapstofill {\math_stackers_hacked_fill{\mapstochar\relbar} \relbar \rightarrow}
+\immutable\protected\def\twoheadrightarrowfill {\math_stackers_hacked_fill \relbar \relbar \twoheadrightarrow}
+\immutable\protected\def\twoheadleftarrowfill {\math_stackers_hacked_fill \twoheadleftarrow \relbar \relbar}
+\immutable\protected\def\rightharpoondownfill {\math_stackers_hacked_fill \relbar \relbar \rightharpoondown}
+\immutable\protected\def\rightharpoonupfill {\math_stackers_hacked_fill \relbar \relbar \rightharpoonup}
+\immutable\protected\def\leftharpoondownfill {\math_stackers_hacked_fill \leftharpoondown \relbar \relbar}
+\immutable\protected\def\leftharpoonupfill {\math_stackers_hacked_fill \leftharpoonup \relbar \relbar}
+\immutable\protected\def\hookleftfill {\math_stackers_hacked_fill \leftarrow \relbar {\relbar\joinrel\rhook}}
+\immutable\protected\def\hookrightfill {\math_stackers_hacked_fill{\lhook\joinrel\relbar}\relbar \rightarrow}
+\immutable\protected\def\relfill {\math_stackers_hacked_fill \relbar \relbar \relbar}
+\immutable\protected\def\triplerelfill {\math_stackers_hacked_fill \equiv \equiv \equiv}
%D For the moment (needs checking):
diff --git a/tex/context/base/mkxl/math-ttv.lmt b/tex/context/base/mkxl/math-ttv.lmt
index 06e934dcd..e33a23478 100644
--- a/tex/context/base/mkxl/math-ttv.lmt
+++ b/tex/context/base/mkxl/math-ttv.lmt
@@ -152,6 +152,11 @@ mathencodings["tex-mr-missing"] = {
[0x02236] = 0x3A, -- colon
}
+mathencodings["tex-ex-braces"] = {
+ [0x0007B] = 0x7B, -- {, braceleftbig
+ [0x0007D] = 0x7D, -- }, bracerightbig
+}
+
mathencodings["tex-mi"] = {
[0x1D6E4] = 0x00, -- Gamma
[0x1D6E5] = 0x01, -- Delta
@@ -463,275 +468,275 @@ mathencodings["tex-sy"] = {
[0xFE325] = 0x30, -- prime 0x02032
}
--- The names in masm10.enc can be trusted best and are shown in the first
--- column, while in the second column we show the tex/ams names. As usual
--- it costs hours to figure out such a table.
-
-mathencodings["tex-ma"] = {
- [0x022A1] = 0x00, -- squaredot \boxdot
- [0x0229E] = 0x01, -- squareplus \boxplus
- [0x022A0] = 0x02, -- squaremultiply \boxtimes
- [0x025A1] = 0x03, -- square \square \Box
- [0x025A0] = 0x04, -- squaresolid \blacksquare
- [0x025AA] = 0x05, -- squaresmallsolid \centerdot
- [0x022C4] = 0x06, -- diamond \Diamond \lozenge
- [0x02666] = 0x07, -- diamondsolid \blacklozenge
- [0x021BB] = 0x08, -- clockwise \circlearrowright
- [0x021BA] = 0x09, -- anticlockwise \circlearrowleft
- [0x021CC] = 0x0A, -- harpoonleftright \rightleftharpoons
- [0x021CB] = 0x0B, -- harpoonrightleft \leftrightharpoons
- [0x0229F] = 0x0C, -- squareminus \boxminus
- [0x022A9] = 0x0D, -- forces \Vdash
- [0x022AA] = 0x0E, -- forcesbar \Vvdash
- [0x022A8] = 0x0F, -- satisfies \vDash
- [0x021A0] = 0x10, -- dblarrowheadright \twoheadrightarrow
- [0x0219E] = 0x11, -- dblarrowheadleft \twoheadleftarrow
- [0x021C7] = 0x12, -- dblarrowleft \leftleftarrows
- [0x021C9] = 0x13, -- dblarrowright \rightrightarrows
- [0x021C8] = 0x14, -- dblarrowup \upuparrows
- [0x021CA] = 0x15, -- dblarrowdwn \downdownarrows
- [0x021BE] = 0x16, -- harpoonupright \upharpoonright \restriction
- [0x021C2] = 0x17, -- harpoondownright \downharpoonright
- [0x021BF] = 0x18, -- harpoonupleft \upharpoonleft
- [0x021C3] = 0x19, -- harpoondownleft \downharpoonleft
- [0x021A3] = 0x1A, -- arrowtailright \rightarrowtail
- [0x021A2] = 0x1B, -- arrowtailleft \leftarrowtail
- [0x021C6] = 0x1C, -- arrowparrleftright \leftrightarrows
--- [0x021C5] = 0x00, -- \updownarrows (missing in lm)
- [0x021C4] = 0x1D, -- arrowparrrightleft \rightleftarrows
- [0x021B0] = 0x1E, -- shiftleft \Lsh
- [0x021B1] = 0x1F, -- shiftright \Rsh
- [0x021DD] = 0x20, -- squiggleright \leadsto \rightsquigarrow
- [0x021AD] = 0x21, -- squiggleleftright \leftrightsquigarrow
- [0x021AB] = 0x22, -- curlyleft \looparrowleft
- [0x021AC] = 0x23, -- curlyright \looparrowright
- [0x02257] = 0x24, -- circleequal \circeq
- [0x0227F] = 0x25, -- followsorequal \succsim
- [0x02273] = 0x26, -- greaterorsimilar \gtrsim
- [0x02A86] = 0x27, -- greaterorapproxeql \gtrapprox
- [0x022B8] = 0x28, -- multimap \multimap
- [0x02234] = 0x29, -- therefore \therefore
- [0x02235] = 0x2A, -- because \because
- [0x02251] = 0x2B, -- equalsdots \Doteq \doteqdot
- [0x0225C] = 0x2C, -- defines \triangleq
- [0x0227E] = 0x2D, -- precedesorequal \precsim
- [0x02272] = 0x2E, -- lessorsimilar \lesssim
- [0x02A85] = 0x2F, -- lessorapproxeql \lessapprox
- [0x02A95] = 0x30, -- equalorless \eqslantless
- [0x02A96] = 0x31, -- equalorgreater \eqslantgtr
- [0x022DE] = 0x32, -- equalorprecedes \curlyeqprec
- [0x022DF] = 0x33, -- equalorfollows \curlyeqsucc
- [0x0227C] = 0x34, -- precedesorcurly \preccurlyeq
- [0x02266] = 0x35, -- lessdblequal \leqq
- [0x02A7D] = 0x36, -- lessorequalslant \leqslant
- [0x02276] = 0x37, -- lessorgreater \lessgtr
- [0x02035] = 0x38, -- primereverse \backprime
- -- [0x0] = 0x39, -- axisshort \dabar
- [0x02253] = 0x3A, -- equaldotrightleft \risingdotseq
- [0x02252] = 0x3B, -- equaldotleftright \fallingdotseq
- [0x0227D] = 0x3C, -- followsorcurly \succcurlyeq
- [0x02267] = 0x3D, -- greaterdblequal \geqq
- [0x02A7E] = 0x3E, -- greaterorequalslant \geqslant
- [0x02277] = 0x3F, -- greaterorless \gtrless
- [0x0228F] = 0x40, -- squareimage \sqsubset
- [0x02290] = 0x41, -- squareoriginal \sqsupset
- -- wrong: see **
- -- [0x022B3] = 0x42, -- triangleright \rhd \vartriangleright
- -- [0x022B2] = 0x43, -- triangleleft \lhd \vartriangleleft
- -- cf lm
- [0x022B5] = 0x44, -- trianglerightequal \unrhd \trianglerighteq
- [0x022B4] = 0x45, -- triangleleftequal \unlhd \trianglelefteq
- --
- [0x02605] = 0x46, -- star \bigstar
- [0x0226C] = 0x47, -- between \between
- [0x025BC] = 0x48, -- triangledownsld \blacktriangledown
- [0x025B6] = 0x49, -- trianglerightsld \blacktriangleright
- [0x025C0] = 0x4A, -- triangleleftsld \blacktriangleleft
- -- [0x0] = 0x4B, -- arrowaxisright
- -- [0x0] = 0x4C, -- arrowaxisleft
- [0x025B2] = 0x4D, -- triangle \triangleup \vartriangle
- [0x025B2] = 0x4E, -- trianglesolid \blacktriangle
- [0x025BD] = 0x4F, -- triangleinv \triangledown
- [0x02256] = 0x50, -- ringinequal \eqcirc
- [0x022DA] = 0x51, -- lessequalgreater \lesseqgtr
- [0x022DB] = 0x52, -- greaterlessequal \gtreqless
- [0x02A8B] = 0x53, -- lessdbleqlgreater \lesseqqgtr
- [0x02A8C] = 0x54, -- greaterdbleqlless \gtreqqless
- [0x000A5] = 0x55, -- Yen \yen
- [0x021DB] = 0x56, -- arrowtripleright \Rrightarrow
- [0x021DA] = 0x57, -- arrowtripleleft \Lleftarrow
- [0x02713] = 0x58, -- check \checkmark
- [0x022BB] = 0x59, -- orunderscore \veebar
- [0x022BC] = 0x5A, -- nand \barwedge
- [0x02306] = 0x5B, -- perpcorrespond \doublebarwedge
- [0x02220] = 0x5C, -- angle \angle
- [0x02221] = 0x5D, -- measuredangle \measuredangle
- [0x02222] = 0x5E, -- sphericalangle \sphericalangle
- -- [0x0] = 0x5F, -- proportional \varpropto
- -- [0x0] = 0x60, -- smile \smallsmile
- -- [0x0] = 0x61, -- frown \smallfrown
- [0x022D0] = 0x62, -- subsetdbl \Subset
- [0x022D1] = 0x63, -- supersetdbl \Supset
- [0x022D3] = 0x64, -- uniondbl \doublecup \Cup
- [0x022D2] = 0x65, -- intersectiondbl \doublecap \Cap
- [0x022CF] = 0x66, -- uprise \curlywedge
- [0x022CE] = 0x67, -- downfall \curlyvee
- [0x022CB] = 0x68, -- multiopenleft \leftthreetimes
- [0x022CC] = 0x69, -- multiopenright \rightthreetimes
- [0x02AC5] = 0x6A, -- subsetdblequal \subseteqq
- [0x02AC6] = 0x6B, -- supersetdblequal \supseteqq
- [0x0224F] = 0x6C, -- difference \bumpeq
- [0x0224E] = 0x6D, -- geomequivalent \Bumpeq
- [0x022D8] = 0x6E, -- muchless \lll \llless
- [0x022D9] = 0x6F, -- muchgreater \ggg \gggtr
- [0x0231C] = 0x70, -- rightanglenw \ulcorner
- [0x0231D] = 0x71, -- rightanglene \urcorner
- [0x024C7] = 0x72, -- circleR \circledR
- [0x024C8] = 0x73, -- circleS \circledS
- [0x022D4] = 0x74, -- fork \pitchfork
- [0x02214] = 0x75, -- dotplus \dotplus
- [0x0223D] = 0x76, -- revsimilar \backsim
- [0x022CD] = 0x77, -- revasymptequal \backsimeq -- AM: Check this! I mapped it to simeq.
- [0x0231E] = 0x78, -- rightanglesw \llcorner
- [0x0231F] = 0x79, -- rightanglese \lrcorner
- [0x02720] = 0x7A, -- maltesecross \maltese
- [0x02201] = 0x7B, -- complement \complement
- [0x022BA] = 0x7C, -- intercal \intercal
- [0x0229A] = 0x7D, -- circlering \circledcirc
- [0x0229B] = 0x7E, -- circleasterisk \circledast
- [0x0229D] = 0x7F, -- circleminus \circleddash
-}
-
-mathencodings["tex-mb"] = {
- -- [0x0] = 0x00, -- lessornotequal \lvertneqq
- -- [0x0] = 0x01, -- greaterornotequal \gvertneqq
- [0x02270] = 0x02, -- notlessequal \nleq
- [0x02271] = 0x03, -- notgreaterequal \ngeq
- [0x0226E] = 0x04, -- notless \nless
- [0x0226F] = 0x05, -- notgreater \ngtr
- [0x02280] = 0x06, -- notprecedes \nprec
- [0x02281] = 0x07, -- notfollows \nsucc
- [0x02268] = 0x08, -- lessornotdbleql \lneqq
- [0x02269] = 0x09, -- greaterornotdbleql \gneqq
- -- [0x0] = 0x0A, -- notlessorslnteql \nleqslant
- -- [0x0] = 0x0B, -- notgreaterorslnteql \ngeqslant
- [0x02A87] = 0x0C, -- lessnotequal \lneq
- [0x02A88] = 0x0D, -- greaternotequal \gneq
- -- [0x0] = 0x0E, -- notprecedesoreql \npreceq
- -- [0x0] = 0x0F, -- notfollowsoreql \nsucceq
- [0x022E8] = 0x10, -- precedeornoteqvlnt \precnsim
- [0x022E9] = 0x11, -- followornoteqvlnt \succnsim
- [0x022E6] = 0x12, -- lessornotsimilar \lnsim
- [0x022E7] = 0x13, -- greaterornotsimilar \gnsim
- -- [0x0] = 0x14, -- notlessdblequal \nleqq
- -- [0x0] = 0x15, -- notgreaterdblequal \ngeqq
- [0x02AB5] = 0x16, -- precedenotslnteql \precneqq
- [0x02AB6] = 0x17, -- follownotslnteql \succneqq
- [0x02AB9] = 0x18, -- precedenotdbleqv \precnapprox
- [0x02ABA] = 0x19, -- follownotdbleqv \succnapprox
- [0x02A89] = 0x1A, -- lessnotdblequal \lnapprox
- [0x02A8A] = 0x1B, -- greaternotdblequal \gnapprox
- [0x02241] = 0x1C, -- notsimilar \nsim
- [0x02247] = 0x1D, -- notapproxequal \ncong
- -- [0x0] = 0x1E, -- upslope \diagup
- -- [0x0] = 0x1F, -- downslope \diagdown
- -- [0x0] = 0x20, -- notsubsetoreql \varsubsetneq
- -- [0x0] = 0x21, -- notsupersetoreql \varsupsetneq
- -- [0x0] = 0x22, -- notsubsetordbleql \nsubseteqq
- -- [0x0] = 0x23, -- notsupersetordbleql \nsupseteqq
- [0x02ACB] = 0x24, -- subsetornotdbleql \subsetneqq
- [0x02ACC] = 0x25, -- supersetornotdbleql \supsetneqq
- -- [0x0] = 0x26, -- subsetornoteql \varsubsetneqq
- -- [0x0] = 0x27, -- supersetornoteql \varsupsetneqq
- [0x0228A] = 0x28, -- subsetnoteql \subsetneq
- [0x0228B] = 0x29, -- supersetnoteql \supsetneq
- [0x02288] = 0x2A, -- notsubseteql \nsubseteq
- [0x02289] = 0x2B, -- notsuperseteql \nsupseteq
- [0x02226] = 0x2C, -- notparallel \nparallel
- [0x02224] = 0x2D, -- notbar \nmid \ndivides
- -- [0x0] = 0x2E, -- notshortbar \nshortmid
- -- [0x0] = 0x2F, -- notshortparallel \nshortparallel
- [0x022AC] = 0x30, -- notturnstile \nvdash
- [0x022AE] = 0x31, -- notforces \nVdash
- [0x022AD] = 0x32, -- notsatisfies \nvDash
- [0x022AF] = 0x33, -- notforcesextra \nVDash
- [0x022ED] = 0x34, -- nottriangeqlright \ntrianglerighteq
- [0x022EC] = 0x35, -- nottriangeqlleft \ntrianglelefteq
- [0x022EA] = 0x36, -- nottriangleleft \ntriangleleft
- [0x022EB] = 0x37, -- nottriangleright \ntriangleright
- [0x0219A] = 0x38, -- notarrowleft \nleftarrow
- [0x0219B] = 0x39, -- notarrowright \nrightarrow
- [0x021CD] = 0x3A, -- notdblarrowleft \nLeftarrow
- [0x021CF] = 0x3B, -- notdblarrowright \nRightarrow
- [0x021CE] = 0x3C, -- notdblarrowboth \nLeftrightarrow
- [0x021AE] = 0x3D, -- notarrowboth \nleftrightarrow
- [0x022C7] = 0x3E, -- dividemultiply \divideontimes
- [0x02300] = 0x3F, -- diametersign \varnothing
- [0x02204] = 0x40, -- notexistential \nexists
- [0x1D538] = 0x41, -- A (blackboard A)
- [0x1D539] = 0x42, -- B
- [0x02102] = 0x43, -- C
- [0x1D53B] = 0x44, -- D
- [0x1D53C] = 0x45, -- E
- [0x1D53D] = 0x46, -- F
- [0x1D53E] = 0x47, -- G
- [0x0210D] = 0x48, -- H
- [0x1D540] = 0x49, -- I
- [0x1D541] = 0x4A, -- J
- [0x1D542] = 0x4B, -- K
- [0x1D543] = 0x4C, -- L
- [0x1D544] = 0x4D, -- M
- [0x02115] = 0x4E, -- N
- [0x1D546] = 0x4F, -- O
- [0x02119] = 0x50, -- P
- [0x0211A] = 0x51, -- Q
- [0x0211D] = 0x52, -- R
- [0x1D54A] = 0x53, -- S
- [0x1D54B] = 0x54, -- T
- [0x1D54C] = 0x55, -- U
- [0x1D54D] = 0x56, -- V
- [0x1D54E] = 0x57, -- W
- [0x1D54F] = 0x58, -- X
- [0x1D550] = 0x59, -- Y
- [0x02124] = 0x5A, -- Z (blackboard Z)
- [0x02132] = 0x60, -- finv \Finv
- [0x02141] = 0x61, -- fmir \Game
- -- [0x0] = 0x62, tildewide
- -- [0x0] = 0x63, tildewider
- -- [0x0] = 0x64, Finv
- -- [0x0] = 0x65, Gmir
- [0x02127] = 0x66, -- Omegainv \mho
- [0x000F0] = 0x67, -- eth \eth
- [0x02242] = 0x68, -- equalorsimilar \eqsim
- [0x02136] = 0x69, -- beth \beth
- [0x02137] = 0x6A, -- gimel \gimel
- [0x02138] = 0x6B, -- daleth \daleth
- [0x022D6] = 0x6C, -- lessdot \lessdot
- [0x022D7] = 0x6D, -- greaterdot \gtrdot
- [0x022C9] = 0x6E, -- multicloseleft \ltimes
- [0x022CA] = 0x6F, -- multicloseright \rtimes
- -- [0x0] = 0x70, -- barshort \shortmid
- -- [0x0] = 0x71, -- parallelshort \shortparallel
- -- [0x02216] = 0x72, -- integerdivide \smallsetminus (2216 already part of tex-sy
- -- [0x0] = 0x73, -- similar \thicksim
- -- [0x0] = 0x74, -- approxequal \thickapprox
- [0x0224A] = 0x75, -- approxorequal \approxeq
- [0x02AB8] = 0x76, -- followsorequal \succapprox
- [0x02AB7] = 0x77, -- precedesorequal \precapprox
- [0x021B6] = 0x78, -- archleftdown \curvearrowleft
- [0x021B7] = 0x79, -- archrightdown \curvearrowright
- [0x003DC] = 0x7A, -- Digamma \digamma
- [0x003F0] = 0x7B, -- kappa \varkappa
- [0x1D55C] = 0x7C, -- k \Bbbk (blackboard k)
- [0x0210F] = 0x7D, -- planckover2pi \hslash % 0x7D
- [0x00127] = 0x7E, -- planckover2pi1 \hbar % 0x7E
- [0x003F6] = 0x7F, -- epsiloninv \backepsilon
-}
-
-mathencodings["tex-mc"] = {
- -- this file has no tfm so it gets mapped in the private space
- [0xFE324] = "mapsfromchar",
-}
+-- -- The names in masm10.enc can be trusted best and are shown in the first
+-- -- column, while in the second column we show the tex/ams names. As usual
+-- -- it costs hours to figure out such a table.
+--
+-- mathencodings["tex-ma"] = {
+-- [0x022A1] = 0x00, -- squaredot \boxdot
+-- [0x0229E] = 0x01, -- squareplus \boxplus
+-- [0x022A0] = 0x02, -- squaremultiply \boxtimes
+-- [0x025A1] = 0x03, -- square \square \Box
+-- [0x025A0] = 0x04, -- squaresolid \blacksquare
+-- [0x025AA] = 0x05, -- squaresmallsolid \centerdot
+-- [0x022C4] = 0x06, -- diamond \Diamond \lozenge
+-- [0x02666] = 0x07, -- diamondsolid \blacklozenge
+-- [0x021BB] = 0x08, -- clockwise \circlearrowright
+-- [0x021BA] = 0x09, -- anticlockwise \circlearrowleft
+-- [0x021CC] = 0x0A, -- harpoonleftright \rightleftharpoons
+-- [0x021CB] = 0x0B, -- harpoonrightleft \leftrightharpoons
+-- [0x0229F] = 0x0C, -- squareminus \boxminus
+-- [0x022A9] = 0x0D, -- forces \Vdash
+-- [0x022AA] = 0x0E, -- forcesbar \Vvdash
+-- [0x022A8] = 0x0F, -- satisfies \vDash
+-- [0x021A0] = 0x10, -- dblarrowheadright \twoheadrightarrow
+-- [0x0219E] = 0x11, -- dblarrowheadleft \twoheadleftarrow
+-- [0x021C7] = 0x12, -- dblarrowleft \leftleftarrows
+-- [0x021C9] = 0x13, -- dblarrowright \rightrightarrows
+-- [0x021C8] = 0x14, -- dblarrowup \upuparrows
+-- [0x021CA] = 0x15, -- dblarrowdwn \downdownarrows
+-- [0x021BE] = 0x16, -- harpoonupright \upharpoonright \restriction
+-- [0x021C2] = 0x17, -- harpoondownright \downharpoonright
+-- [0x021BF] = 0x18, -- harpoonupleft \upharpoonleft
+-- [0x021C3] = 0x19, -- harpoondownleft \downharpoonleft
+-- [0x021A3] = 0x1A, -- arrowtailright \rightarrowtail
+-- [0x021A2] = 0x1B, -- arrowtailleft \leftarrowtail
+-- [0x021C6] = 0x1C, -- arrowparrleftright \leftrightarrows
+-- -- [0x021C5] = 0x00, -- \updownarrows (missing in lm)
+-- [0x021C4] = 0x1D, -- arrowparrrightleft \rightleftarrows
+-- [0x021B0] = 0x1E, -- shiftleft \Lsh
+-- [0x021B1] = 0x1F, -- shiftright \Rsh
+-- [0x021DD] = 0x20, -- squiggleright \leadsto \rightsquigarrow
+-- [0x021AD] = 0x21, -- squiggleleftright \leftrightsquigarrow
+-- [0x021AB] = 0x22, -- curlyleft \looparrowleft
+-- [0x021AC] = 0x23, -- curlyright \looparrowright
+-- [0x02257] = 0x24, -- circleequal \circeq
+-- [0x0227F] = 0x25, -- followsorequal \succsim
+-- [0x02273] = 0x26, -- greaterorsimilar \gtrsim
+-- [0x02A86] = 0x27, -- greaterorapproxeql \gtrapprox
+-- [0x022B8] = 0x28, -- multimap \multimap
+-- [0x02234] = 0x29, -- therefore \therefore
+-- [0x02235] = 0x2A, -- because \because
+-- [0x02251] = 0x2B, -- equalsdots \Doteq \doteqdot
+-- [0x0225C] = 0x2C, -- defines \triangleq
+-- [0x0227E] = 0x2D, -- precedesorequal \precsim
+-- [0x02272] = 0x2E, -- lessorsimilar \lesssim
+-- [0x02A85] = 0x2F, -- lessorapproxeql \lessapprox
+-- [0x02A95] = 0x30, -- equalorless \eqslantless
+-- [0x02A96] = 0x31, -- equalorgreater \eqslantgtr
+-- [0x022DE] = 0x32, -- equalorprecedes \curlyeqprec
+-- [0x022DF] = 0x33, -- equalorfollows \curlyeqsucc
+-- [0x0227C] = 0x34, -- precedesorcurly \preccurlyeq
+-- [0x02266] = 0x35, -- lessdblequal \leqq
+-- [0x02A7D] = 0x36, -- lessorequalslant \leqslant
+-- [0x02276] = 0x37, -- lessorgreater \lessgtr
+-- [0x02035] = 0x38, -- primereverse \backprime
+-- -- [0x0] = 0x39, -- axisshort \dabar
+-- [0x02253] = 0x3A, -- equaldotrightleft \risingdotseq
+-- [0x02252] = 0x3B, -- equaldotleftright \fallingdotseq
+-- [0x0227D] = 0x3C, -- followsorcurly \succcurlyeq
+-- [0x02267] = 0x3D, -- greaterdblequal \geqq
+-- [0x02A7E] = 0x3E, -- greaterorequalslant \geqslant
+-- [0x02277] = 0x3F, -- greaterorless \gtrless
+-- [0x0228F] = 0x40, -- squareimage \sqsubset
+-- [0x02290] = 0x41, -- squareoriginal \sqsupset
+-- -- wrong: see **
+-- -- [0x022B3] = 0x42, -- triangleright \rhd \vartriangleright
+-- -- [0x022B2] = 0x43, -- triangleleft \lhd \vartriangleleft
+-- -- cf lm
+-- [0x022B5] = 0x44, -- trianglerightequal \unrhd \trianglerighteq
+-- [0x022B4] = 0x45, -- triangleleftequal \unlhd \trianglelefteq
+-- --
+-- [0x02605] = 0x46, -- star \bigstar
+-- [0x0226C] = 0x47, -- between \between
+-- [0x025BC] = 0x48, -- triangledownsld \blacktriangledown
+-- [0x025B6] = 0x49, -- trianglerightsld \blacktriangleright
+-- [0x025C0] = 0x4A, -- triangleleftsld \blacktriangleleft
+-- -- [0x0] = 0x4B, -- arrowaxisright
+-- -- [0x0] = 0x4C, -- arrowaxisleft
+-- [0x025B2] = 0x4D, -- triangle \triangleup \vartriangle
+-- [0x025B2] = 0x4E, -- trianglesolid \blacktriangle
+-- [0x025BD] = 0x4F, -- triangleinv \triangledown
+-- [0x02256] = 0x50, -- ringinequal \eqcirc
+-- [0x022DA] = 0x51, -- lessequalgreater \lesseqgtr
+-- [0x022DB] = 0x52, -- greaterlessequal \gtreqless
+-- [0x02A8B] = 0x53, -- lessdbleqlgreater \lesseqqgtr
+-- [0x02A8C] = 0x54, -- greaterdbleqlless \gtreqqless
+-- [0x000A5] = 0x55, -- Yen \yen
+-- [0x021DB] = 0x56, -- arrowtripleright \Rrightarrow
+-- [0x021DA] = 0x57, -- arrowtripleleft \Lleftarrow
+-- [0x02713] = 0x58, -- check \checkmark
+-- [0x022BB] = 0x59, -- orunderscore \veebar
+-- [0x022BC] = 0x5A, -- nand \barwedge
+-- [0x02306] = 0x5B, -- perpcorrespond \doublebarwedge
+-- [0x02220] = 0x5C, -- angle \angle
+-- [0x02221] = 0x5D, -- measuredangle \measuredangle
+-- [0x02222] = 0x5E, -- sphericalangle \sphericalangle
+-- -- [0x0] = 0x5F, -- proportional \varpropto
+-- -- [0x0] = 0x60, -- smile \smallsmile
+-- -- [0x0] = 0x61, -- frown \smallfrown
+-- [0x022D0] = 0x62, -- subsetdbl \Subset
+-- [0x022D1] = 0x63, -- supersetdbl \Supset
+-- [0x022D3] = 0x64, -- uniondbl \doublecup \Cup
+-- [0x022D2] = 0x65, -- intersectiondbl \doublecap \Cap
+-- [0x022CF] = 0x66, -- uprise \curlywedge
+-- [0x022CE] = 0x67, -- downfall \curlyvee
+-- [0x022CB] = 0x68, -- multiopenleft \leftthreetimes
+-- [0x022CC] = 0x69, -- multiopenright \rightthreetimes
+-- [0x02AC5] = 0x6A, -- subsetdblequal \subseteqq
+-- [0x02AC6] = 0x6B, -- supersetdblequal \supseteqq
+-- [0x0224F] = 0x6C, -- difference \bumpeq
+-- [0x0224E] = 0x6D, -- geomequivalent \Bumpeq
+-- [0x022D8] = 0x6E, -- muchless \lll \llless
+-- [0x022D9] = 0x6F, -- muchgreater \ggg \gggtr
+-- [0x0231C] = 0x70, -- rightanglenw \ulcorner
+-- [0x0231D] = 0x71, -- rightanglene \urcorner
+-- [0x024C7] = 0x72, -- circleR \circledR
+-- [0x024C8] = 0x73, -- circleS \circledS
+-- [0x022D4] = 0x74, -- fork \pitchfork
+-- [0x02214] = 0x75, -- dotplus \dotplus
+-- [0x0223D] = 0x76, -- revsimilar \backsim
+-- [0x022CD] = 0x77, -- revasymptequal \backsimeq -- AM: Check this! I mapped it to simeq.
+-- [0x0231E] = 0x78, -- rightanglesw \llcorner
+-- [0x0231F] = 0x79, -- rightanglese \lrcorner
+-- [0x02720] = 0x7A, -- maltesecross \maltese
+-- [0x02201] = 0x7B, -- complement \complement
+-- [0x022BA] = 0x7C, -- intercal \intercal
+-- [0x0229A] = 0x7D, -- circlering \circledcirc
+-- [0x0229B] = 0x7E, -- circleasterisk \circledast
+-- [0x0229D] = 0x7F, -- circleminus \circleddash
+-- }
+--
+-- mathencodings["tex-mb"] = {
+-- -- [0x0] = 0x00, -- lessornotequal \lvertneqq
+-- -- [0x0] = 0x01, -- greaterornotequal \gvertneqq
+-- [0x02270] = 0x02, -- notlessequal \nleq
+-- [0x02271] = 0x03, -- notgreaterequal \ngeq
+-- [0x0226E] = 0x04, -- notless \nless
+-- [0x0226F] = 0x05, -- notgreater \ngtr
+-- [0x02280] = 0x06, -- notprecedes \nprec
+-- [0x02281] = 0x07, -- notfollows \nsucc
+-- [0x02268] = 0x08, -- lessornotdbleql \lneqq
+-- [0x02269] = 0x09, -- greaterornotdbleql \gneqq
+-- -- [0x0] = 0x0A, -- notlessorslnteql \nleqslant
+-- -- [0x0] = 0x0B, -- notgreaterorslnteql \ngeqslant
+-- [0x02A87] = 0x0C, -- lessnotequal \lneq
+-- [0x02A88] = 0x0D, -- greaternotequal \gneq
+-- -- [0x0] = 0x0E, -- notprecedesoreql \npreceq
+-- -- [0x0] = 0x0F, -- notfollowsoreql \nsucceq
+-- [0x022E8] = 0x10, -- precedeornoteqvlnt \precnsim
+-- [0x022E9] = 0x11, -- followornoteqvlnt \succnsim
+-- [0x022E6] = 0x12, -- lessornotsimilar \lnsim
+-- [0x022E7] = 0x13, -- greaterornotsimilar \gnsim
+-- -- [0x0] = 0x14, -- notlessdblequal \nleqq
+-- -- [0x0] = 0x15, -- notgreaterdblequal \ngeqq
+-- [0x02AB5] = 0x16, -- precedenotslnteql \precneqq
+-- [0x02AB6] = 0x17, -- follownotslnteql \succneqq
+-- [0x02AB9] = 0x18, -- precedenotdbleqv \precnapprox
+-- [0x02ABA] = 0x19, -- follownotdbleqv \succnapprox
+-- [0x02A89] = 0x1A, -- lessnotdblequal \lnapprox
+-- [0x02A8A] = 0x1B, -- greaternotdblequal \gnapprox
+-- [0x02241] = 0x1C, -- notsimilar \nsim
+-- [0x02247] = 0x1D, -- notapproxequal \ncong
+-- -- [0x0] = 0x1E, -- upslope \diagup
+-- -- [0x0] = 0x1F, -- downslope \diagdown
+-- -- [0x0] = 0x20, -- notsubsetoreql \varsubsetneq
+-- -- [0x0] = 0x21, -- notsupersetoreql \varsupsetneq
+-- -- [0x0] = 0x22, -- notsubsetordbleql \nsubseteqq
+-- -- [0x0] = 0x23, -- notsupersetordbleql \nsupseteqq
+-- [0x02ACB] = 0x24, -- subsetornotdbleql \subsetneqq
+-- [0x02ACC] = 0x25, -- supersetornotdbleql \supsetneqq
+-- -- [0x0] = 0x26, -- subsetornoteql \varsubsetneqq
+-- -- [0x0] = 0x27, -- supersetornoteql \varsupsetneqq
+-- [0x0228A] = 0x28, -- subsetnoteql \subsetneq
+-- [0x0228B] = 0x29, -- supersetnoteql \supsetneq
+-- [0x02288] = 0x2A, -- notsubseteql \nsubseteq
+-- [0x02289] = 0x2B, -- notsuperseteql \nsupseteq
+-- [0x02226] = 0x2C, -- notparallel \nparallel
+-- [0x02224] = 0x2D, -- notbar \nmid \ndivides
+-- -- [0x0] = 0x2E, -- notshortbar \nshortmid
+-- -- [0x0] = 0x2F, -- notshortparallel \nshortparallel
+-- [0x022AC] = 0x30, -- notturnstile \nvdash
+-- [0x022AE] = 0x31, -- notforces \nVdash
+-- [0x022AD] = 0x32, -- notsatisfies \nvDash
+-- [0x022AF] = 0x33, -- notforcesextra \nVDash
+-- [0x022ED] = 0x34, -- nottriangeqlright \ntrianglerighteq
+-- [0x022EC] = 0x35, -- nottriangeqlleft \ntrianglelefteq
+-- [0x022EA] = 0x36, -- nottriangleleft \ntriangleleft
+-- [0x022EB] = 0x37, -- nottriangleright \ntriangleright
+-- [0x0219A] = 0x38, -- notarrowleft \nleftarrow
+-- [0x0219B] = 0x39, -- notarrowright \nrightarrow
+-- [0x021CD] = 0x3A, -- notdblarrowleft \nLeftarrow
+-- [0x021CF] = 0x3B, -- notdblarrowright \nRightarrow
+-- [0x021CE] = 0x3C, -- notdblarrowboth \nLeftrightarrow
+-- [0x021AE] = 0x3D, -- notarrowboth \nleftrightarrow
+-- [0x022C7] = 0x3E, -- dividemultiply \divideontimes
+-- [0x02300] = 0x3F, -- diametersign \varnothing
+-- [0x02204] = 0x40, -- notexistential \nexists
+-- [0x1D538] = 0x41, -- A (blackboard A)
+-- [0x1D539] = 0x42, -- B
+-- [0x02102] = 0x43, -- C
+-- [0x1D53B] = 0x44, -- D
+-- [0x1D53C] = 0x45, -- E
+-- [0x1D53D] = 0x46, -- F
+-- [0x1D53E] = 0x47, -- G
+-- [0x0210D] = 0x48, -- H
+-- [0x1D540] = 0x49, -- I
+-- [0x1D541] = 0x4A, -- J
+-- [0x1D542] = 0x4B, -- K
+-- [0x1D543] = 0x4C, -- L
+-- [0x1D544] = 0x4D, -- M
+-- [0x02115] = 0x4E, -- N
+-- [0x1D546] = 0x4F, -- O
+-- [0x02119] = 0x50, -- P
+-- [0x0211A] = 0x51, -- Q
+-- [0x0211D] = 0x52, -- R
+-- [0x1D54A] = 0x53, -- S
+-- [0x1D54B] = 0x54, -- T
+-- [0x1D54C] = 0x55, -- U
+-- [0x1D54D] = 0x56, -- V
+-- [0x1D54E] = 0x57, -- W
+-- [0x1D54F] = 0x58, -- X
+-- [0x1D550] = 0x59, -- Y
+-- [0x02124] = 0x5A, -- Z (blackboard Z)
+-- [0x02132] = 0x60, -- finv \Finv
+-- [0x02141] = 0x61, -- fmir \Game
+-- -- [0x0] = 0x62, tildewide
+-- -- [0x0] = 0x63, tildewider
+-- -- [0x0] = 0x64, Finv
+-- -- [0x0] = 0x65, Gmir
+-- [0x02127] = 0x66, -- Omegainv \mho
+-- [0x000F0] = 0x67, -- eth \eth
+-- [0x02242] = 0x68, -- equalorsimilar \eqsim
+-- [0x02136] = 0x69, -- beth \beth
+-- [0x02137] = 0x6A, -- gimel \gimel
+-- [0x02138] = 0x6B, -- daleth \daleth
+-- [0x022D6] = 0x6C, -- lessdot \lessdot
+-- [0x022D7] = 0x6D, -- greaterdot \gtrdot
+-- [0x022C9] = 0x6E, -- multicloseleft \ltimes
+-- [0x022CA] = 0x6F, -- multicloseright \rtimes
+-- -- [0x0] = 0x70, -- barshort \shortmid
+-- -- [0x0] = 0x71, -- parallelshort \shortparallel
+-- -- [0x02216] = 0x72, -- integerdivide \smallsetminus (2216 already part of tex-sy
+-- -- [0x0] = 0x73, -- similar \thicksim
+-- -- [0x0] = 0x74, -- approxequal \thickapprox
+-- [0x0224A] = 0x75, -- approxorequal \approxeq
+-- [0x02AB8] = 0x76, -- followsorequal \succapprox
+-- [0x02AB7] = 0x77, -- precedesorequal \precapprox
+-- [0x021B6] = 0x78, -- archleftdown \curvearrowleft
+-- [0x021B7] = 0x79, -- archrightdown \curvearrowright
+-- [0x003DC] = 0x7A, -- Digamma \digamma
+-- [0x003F0] = 0x7B, -- kappa \varkappa
+-- [0x1D55C] = 0x7C, -- k \Bbbk (blackboard k)
+-- [0x0210F] = 0x7D, -- planckover2pi \hslash % 0x7D
+-- [0x00127] = 0x7E, -- planckover2pi1 \hbar % 0x7E
+-- [0x003F6] = 0x7F, -- epsiloninv \backepsilon
+-- }
+--
+-- mathencodings["tex-mc"] = {
+-- -- this file has no tfm so it gets mapped in the private space
+-- [0xFE324] = "mapsfromchar",
+-- }
mathencodings["tex-fraktur"] = {
-- [0x1D504] = 0x41, -- A (fraktur A)
diff --git a/tex/context/base/mkxl/math-vfu.lmt b/tex/context/base/mkxl/math-vfu.lmt
index 53988036c..bdd5de103 100644
--- a/tex/context/base/mkxl/math-vfu.lmt
+++ b/tex/context/base/mkxl/math-vfu.lmt
@@ -936,9 +936,12 @@ function vfmath.define(specification,set,goodies)
local skewchar = ss.skewchar
local backmap = ss.backmap
local badones = ss.badones
+ local ignore = ss.ignore
local done = { }
local extras = { }
- if not backmap then
+ if backmap == false then
+ -- backmap = { }
+ elseif not backmap then
backmap = { }
for unicode, character in next, fc do
backmap[character.order or character.index or unicode] = unicode
@@ -969,11 +972,16 @@ function vfmath.define(specification,set,goodies)
rv[unicode] = true
end
else
- local u = mathematics.gaps[unicode] or unicode
- local t = virtualize(s,uni,fci,skewchar,tonumber(badones and badones[fci.name or ""]),mathparameters,u,fp)
- done[uni] = t
- characters[unicode] = t
- fci.unicode = u
+ local name = fci.name or ""
+ if ignore and ignore[name] then
+ -- get rid of ugly slanted antykwa { }
+ else
+ local u = mathematics.gaps[unicode] or unicode
+ local t = virtualize(s,uni,fci,skewchar,tonumber(badones and badones[name]),mathparameters,u,fp)
+ done[uni] = t
+ characters[unicode] = t
+ fci.unicode = u
+ end
end
end
if isextension then
diff --git a/tex/context/base/mkxl/node-bck.mkxl b/tex/context/base/mkxl/node-bck.mkxl
index 357180710..4ee2b0fa9 100644
--- a/tex/context/base/mkxl/node-bck.mkxl
+++ b/tex/context/base/mkxl/node-bck.mkxl
@@ -19,7 +19,7 @@
\unprotect
-\registerctxluafile{node-bck}{autosuffix,optimize}
+\registerctxluafile{node-bck}{autosuffix}
% \backgroundvbox[green] {\input tufte } \par
% \backgroundvbox[blue] {\input ward } \par
diff --git a/tex/context/base/mkxl/node-fin.mkxl b/tex/context/base/mkxl/node-fin.mkxl
index c0ad58f7d..aef7eea58 100644
--- a/tex/context/base/mkxl/node-fin.mkxl
+++ b/tex/context/base/mkxl/node-fin.mkxl
@@ -15,8 +15,8 @@
\unprotect
-\registerctxluafile{node-shp}{autosuffix,optimize}
-\registerctxluafile{node-fin}{autosuffix,optimize}
+\registerctxluafile{node-shp}{autosuffix}
+\registerctxluafile{node-fin}{autosuffix}
\permanent\protected\def\finalizeobjectbox #1{\clf_finalizebox#1\relax}
\permanent\protected\def\finalizeshipoutbox#1{\clf_finalizebox#1\relax}
diff --git a/tex/context/base/mkxl/node-rul.mkxl b/tex/context/base/mkxl/node-rul.mkxl
index 5253c8008..04c0e0dc3 100644
--- a/tex/context/base/mkxl/node-rul.mkxl
+++ b/tex/context/base/mkxl/node-rul.mkxl
@@ -85,7 +85,7 @@
\mutable\lettonothing\m_rule_option
\mutable\lettonothing\m_rule_color
-\registerctxluafile{node-rul}{autosuffix,optimize}
+\registerctxluafile{node-rul}{autosuffix}
\installcorenamespace{bar}
\installcorenamespace{barstack}
diff --git a/tex/context/base/mkxl/pack-rul.mkxl b/tex/context/base/mkxl/pack-rul.mkxl
index 9c25cbf05..36b4fc7b0 100644
--- a/tex/context/base/mkxl/pack-rul.mkxl
+++ b/tex/context/base/mkxl/pack-rul.mkxl
@@ -25,7 +25,7 @@
\newdimension\framedmaxwidth
\newdimension\framedaveragewidth
-\registerctxluafile{pack-rul}{autosuffix,optimize}
+\registerctxluafile{pack-rul}{autosuffix}
\unprotect
diff --git a/tex/context/base/mkxl/regi-ini.lmt b/tex/context/base/mkxl/regi-ini.lmt
new file mode 100644
index 000000000..c0cd4f1c8
--- /dev/null
+++ b/tex/context/base/mkxl/regi-ini.lmt
@@ -0,0 +1,367 @@
+if not modules then modules = { } end modules ['regi-ini'] = {
+ version = 1.001,
+ comment = "companion to regi-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Regimes take care of converting the input characters into
+<l n='utf'/> sequences. The conversion tables are loaded at
+runtime.</p>
+--ldx]]--
+
+local tostring = tostring
+local utfchar = utf.char
+local P, Cs, Cc, lpegmatch = lpeg.P, lpeg.Cs, lpeg.Cc, lpeg.match
+local char, gsub, format, gmatch, byte, match, lower = string.char, string.gsub, string.format, string.gmatch, string.byte, string.match, string.lower
+local next = next
+local insert, remove, fastcopy = table.insert, table.remove, table.fastcopy
+local concat = table.concat
+local totable = string.totable
+
+local allocate = utilities.storage.allocate
+local sequencers = utilities.sequencers
+local textlineactions = resolvers.openers.helpers.textlineactions
+local setmetatableindex = table.setmetatableindex
+
+-- We will hook regime handling code into the input methods.
+
+local trace_translating = false trackers.register("regimes.translating", function(v) trace_translating = v end)
+
+local report_loading = logs.reporter("regimes","loading")
+local report_translating = logs.reporter("regimes","translating")
+
+regimes = regimes or { }
+local regimes = regimes
+
+local mapping = allocate {
+ utf = false
+}
+
+local backmapping = allocate {
+}
+
+-- regimes.mapping = mapping
+
+local synonyms = { -- backward compatibility list
+
+ ["windows-1250"] = "cp1250",
+ ["windows-1251"] = "cp1251",
+ ["windows-1252"] = "cp1252",
+ ["windows-1253"] = "cp1253",
+ ["windows-1254"] = "cp1254",
+ ["windows-1255"] = "cp1255",
+ ["windows-1256"] = "cp1256",
+ ["windows-1257"] = "cp1257",
+ ["windows-1258"] = "cp1258",
+
+ ["il1"] = "8859-1",
+ ["il2"] = "8859-2",
+ ["il3"] = "8859-3",
+ ["il4"] = "8859-4",
+ ["il5"] = "8859-9",
+ ["il6"] = "8859-10",
+ ["il7"] = "8859-13",
+ ["il8"] = "8859-14",
+ ["il9"] = "8859-15",
+ ["il10"] = "8859-16",
+
+ ["iso-8859-1"] = "8859-1",
+ ["iso-8859-2"] = "8859-2",
+ ["iso-8859-3"] = "8859-3",
+ ["iso-8859-4"] = "8859-4",
+ ["iso-8859-9"] = "8859-9",
+ ["iso-8859-10"] = "8859-10",
+ ["iso-8859-13"] = "8859-13",
+ ["iso-8859-14"] = "8859-14",
+ ["iso-8859-15"] = "8859-15",
+ ["iso-8859-16"] = "8859-16",
+
+ ["latin1"] = "8859-1",
+ ["latin2"] = "8859-2",
+ ["latin3"] = "8859-3",
+ ["latin4"] = "8859-4",
+ ["latin5"] = "8859-9",
+ ["latin6"] = "8859-10",
+ ["latin7"] = "8859-13",
+ ["latin8"] = "8859-14",
+ ["latin9"] = "8859-15",
+ ["latin10"] = "8859-16",
+
+ ["utf-8"] = "utf",
+ ["utf8"] = "utf",
+ [""] = "utf",
+
+ ["windows"] = "cp1252",
+
+ ["pdf"] = "pdfdoc",
+
+ ["437"] = "ibm",
+}
+
+local currentregime = "utf"
+
+local function loadregime(mapping,regime)
+ regime = lower(tostring(regime))
+ regime = synonyms[regime] or synonyms["windows-"..regime] or regime
+ local name = resolvers.findfile(format("regi-%s.lua",regime)) or ""
+ local data = name ~= "" and dofile(name)
+ if data then
+ vector = { }
+ for eightbit, unicode in next, data do
+ vector[char(eightbit)] = utfchar(unicode)
+ end
+ report_loading("vector %a is loaded",regime)
+ else
+ vector = false
+ report_loading("vector %a is unknown",regime)
+ end
+ mapping[regime] = vector
+ return vector
+end
+
+local function loadreverse(t,k)
+ local t = { }
+ local m = mapping[k]
+ if m then
+ for k, v in next, m do
+ t[v] = k
+ end
+ end
+ backmapping[k] = t
+ return t
+end
+
+setmetatableindex(mapping, loadregime)
+setmetatableindex(backmapping,loadreverse)
+
+regimes.mapping = mapping
+regimes.backmapping = backmapping
+
+local function fromregime(regime,line)
+ if line and #line > 0 then
+ -- local map = mapping[regime and synonyms[regime] or regime or currentregime]
+ local map = mapping[regime or currentregime]
+ if map then
+ line = gsub(line,".",map)
+ end
+ end
+ return line
+end
+
+local cache = { } -- if really needed we can copy vectors and hash defaults
+
+setmetatableindex(cache, function(t,k)
+ local v = { remappers = { } }
+ t[k] = v
+ return v
+end)
+
+local function toregime(vector,str,default) -- toregime('8859-1',"abcde Ä","?")
+ local d = default or "?"
+ local c = cache[vector].remappers
+ local r = c[d]
+ if not r then
+ local t = fastcopy(backmapping[vector])
+ -- r = utf.remapper(t) -- not good for defaults here
+ local pattern = Cs((lpeg.utfchartabletopattern(t)/t + lpeg.patterns.utf8character/d + P(1)/d)^0)
+ r = function(str)
+ if not str or str == "" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end
+ c[d] = r
+ end
+ return r(str)
+end
+
+local function disable()
+ currentregime = "utf"
+ sequencers.disableaction(textlineactions,"regimes.process")
+ return currentregime
+end
+
+local function enable(regime)
+ regime = synonyms[regime] or regime
+ if mapping[regime] == false then
+ disable()
+ else
+ currentregime = regime
+ sequencers.enableaction(textlineactions,"regimes.process")
+ end
+ return currentregime
+end
+
+regimes.toregime = toregime
+regimes.fromregime = fromregime
+regimes.translate = function(str,regime) return fromregime(regime,str) end
+regimes.enable = enable
+regimes.disable = disable
+
+-- The following function can be used when we want to make sure that utf gets passed
+-- unharmed. This is needed for modules.
+
+local level = 0
+
+function regimes.process(str,filename,currentline,noflines,coding)
+ if level == 0 and coding ~= "utf-8" then
+ str = fromregime(currentregime,str)
+ if trace_translating then
+ report_translating("utf: %s",str)
+ end
+ end
+ return str
+end
+
+local function push()
+ level = level + 1
+ if trace_translating then
+ report_translating("pushing level %s",level)
+ end
+end
+
+local function pop()
+ if level > 0 then
+ if trace_translating then
+ report_translating("popping level %s",level)
+ end
+ level = level - 1
+ end
+end
+
+regimes.push = push
+regimes.pop = pop
+
+function regimes.list()
+ local name = resolvers.findfile(format("regi-ini.lua",regime)) or ""
+ local okay = { }
+ if name then
+ local list = dir.glob(file.join(file.dirname(name),"regi-*.lua"))
+ for i=1,#list do
+ local name = list[i]
+ if name ~= "regi-ini.lua" then
+ okay[#okay+1] = match(name,"regi%-(.-)%.lua")
+ end
+ table.sort(okay)
+ end
+ end
+ return okay
+end
+
+sequencers.prependaction(textlineactions,"system","regimes.process")
+sequencers.disableaction(textlineactions,"regimes.process")
+
+-- Next we provide some hacks. Unfortunately we run into crappy encoded (read:
+-- mixed) encoded xml files that have these ë ä ö ü sequences instead of ë ä ö ü
+-- etc.
+
+local patterns = { }
+
+function regimes.cleanup(regime,str)
+ if not str or str == "" then
+ return str
+ end
+ local p = patterns[regime]
+ if p == nil then
+ regime = regime and synonyms[regime] or regime or currentregime
+ local vector = regime ~= "utf" and regime ~= "utf-8" and mapping[regime]
+ if vector then
+ local mapping = { }
+ for k, v in next, vector do
+ local split = totable(v)
+ for i=1,#split do
+ split[i] = utfchar(byte(split[i]))
+ end
+ split = concat(split)
+ if v ~= split then
+ mapping[split] = v
+ end
+ end
+ p = Cs((lpeg.utfchartabletopattern(mapping)/mapping+P(1))^0)
+ else
+ p = false
+ end
+ patterns[regime] = p
+ end
+ return p and lpegmatch(p,str) or str
+end
+
+-- local old = [[test ë ä ö ü crap]]
+-- local new = regimes.cleanup("cp1252",old)
+-- report_translating("%s -> %s",old,new)
+-- local old = "Pozn" .. char(0xE1) .. "mky"
+-- local new = fromregime("cp1250",old)
+-- report_translating("%s -> %s",old,new)
+
+-- interface (might move to regi-tex.lua)
+
+if interfaces then
+
+ local implement = interfaces.implement
+ local setmacro = interfaces.setmacro
+
+ implement {
+ name = "enableregime",
+ public = true,
+ protected = true,
+ arguments = "optional",
+ actions = function(regime) setmacro("currentregime",enable(regime)) end
+ }
+
+ implement {
+ name = "disableregime",
+ public = true,
+ protected = true,
+ actions = function() setmacro("currentregime",disable()) end
+ }
+
+ implement {
+ name = "pushregime",
+ public = true,
+ protected = true,
+ actions = push
+ }
+
+ implement {
+ name = "popregime",
+ public = true,
+ protected = true,
+ actions = pop
+ }
+
+ local stack = { }
+
+ implement {
+ name = "startregime",
+ public = true,
+ protected = true,
+ arguments = "optional",
+ actions = function(regime)
+ insert(stack,currentregime)
+ if trace_translating then
+ report_translating("start using %a",regime)
+ end
+ setmacro("currentregime",enable(regime))
+ end
+ }
+
+ implement {
+ name = "stopregime",
+ public = true,
+ protected = true,
+ actions = function()
+ if #stack > 0 then
+ local regime = remove(stack)
+ if trace_translating then
+ report_translating("stop using %a",regime)
+ end
+ setmacro("currentregime",enable(regime))
+ end
+ end
+ }
+
+end
diff --git a/tex/context/base/mkxl/regi-ini.mkxl b/tex/context/base/mkxl/regi-ini.mkxl
index 8ba7edc42..da5bdf081 100644
--- a/tex/context/base/mkxl/regi-ini.mkxl
+++ b/tex/context/base/mkxl/regi-ini.mkxl
@@ -11,13 +11,14 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\registerctxluafile{regi-ini}{}
+\registerctxluafile{regi-ini}{autosuffix}
\unprotect
%D \macros
%D {enableregime,disableregime,
%D startregime,stopregime,
+%D pushregime, popregime,
%D currentregime}
%D
%D Beware, the enable and disable commands are global switches, so best use the
@@ -25,13 +26,15 @@
\mutable\lettonothing\currentregime
-\permanent\protected\def\enableregime[#1]{\clf_enableregime{#1}}
-\permanent\protected\def\disableregime {\clf_disableregime}
-\permanent\protected\def\startregime [#1]{\clf_startregime{#1}}
-\permanent\protected\def\stopregime {\clf_stopregime}
-
-% only for diagnostics:
-
-% \def\codepagename#1{\cldcontext{os.tocodepage("#1")}}
+%D These are defined at the \LUA\ end:
+%D
+%D \starttyping
+%D \enableregime[#1]
+%D \disableregime
+%D \startregime [#1]
+%D \stopregime
+%D \pushregime
+%D \popregime
+%D \stoptyping
\protect \endinput
diff --git a/tex/context/base/mkxl/spac-ali.mkxl b/tex/context/base/mkxl/spac-ali.mkxl
index c7d2fb657..f5b0e2fb8 100644
--- a/tex/context/base/mkxl/spac-ali.mkxl
+++ b/tex/context/base/mkxl/spac-ali.mkxl
@@ -19,7 +19,7 @@
%D variants. Starting at the last day of 2011 both methods are merged into one and
%D caching has been added, which makes switching twice as fast.
-\registerctxluafile{spac-ali}{autosuffix,optimize}
+\registerctxluafile{spac-ali}{autosuffix}
% Used once so ... replace it or use if more frequently ...
diff --git a/tex/context/base/mkxl/spac-chr.mkxl b/tex/context/base/mkxl/spac-chr.mkxl
index 346bc2183..ef63b2b82 100644
--- a/tex/context/base/mkxl/spac-chr.mkxl
+++ b/tex/context/base/mkxl/spac-chr.mkxl
@@ -15,7 +15,7 @@
\unprotect
-\registerctxluafile{spac-chr}{autosuffix,optimize}
+\registerctxluafile{spac-chr}{autosuffix}
\definesystemattribute[characters][public]
diff --git a/tex/context/base/mkxl/spac-hor.mkxl b/tex/context/base/mkxl/spac-hor.mkxl
index 017a94d5b..3c4fd1eb4 100644
--- a/tex/context/base/mkxl/spac-hor.mkxl
+++ b/tex/context/base/mkxl/spac-hor.mkxl
@@ -400,13 +400,19 @@
% test test\fsp. test % beats frenchspacing
+% \permanent\protected\def\fsp#1% fixed space puncuation
+% {\begingroup
+% \ifchknum`#1\or
+% \sfcode`#1\plusthousand
+% \fi
+% #1%
+% \endgroup}
+
\permanent\protected\def\fsp#1% fixed space puncuation
- {\begingroup
+ {#1%
\ifchknum`#1\or
- \sfcode`#1\plusthousand
- \fi
- #1%
- \endgroup}
+ \spacefactor\plusthousand
+ \fi}
%D Here's a tweak .. if needed one can configure it in the configuration
%D so that initialization happens more efficient.
diff --git a/tex/context/base/mkxl/spac-ver.mkxl b/tex/context/base/mkxl/spac-ver.mkxl
index 807ecfcd3..640d493b9 100644
--- a/tex/context/base/mkxl/spac-ver.mkxl
+++ b/tex/context/base/mkxl/spac-ver.mkxl
@@ -20,7 +20,7 @@
\newdimen \bodyfontstrutdepth
\newgluespec\globalbodyfontlineheight % why a skip
-\newdimen \globalbodyfontstrutheight
+\newdimen \globalbodyfontstrutheight
\newdimen \globalbodyfontstrutdepth
\newgluespec \s_spac_vspacing_predefined
@@ -31,7 +31,7 @@
% \overloaded\let\strutdp \undefined \newdimen\strutdp
% \overloaded\let\struthtdp\undefined \newdimen\struthtdp
-\registerctxluafile{spac-ver}{autosuffix,optimize}
+\registerctxluafile{spac-ver}{autosuffix}
% todo: use usernodes ?
diff --git a/tex/context/base/mkxl/strc-flt.mklx b/tex/context/base/mkxl/strc-flt.mklx
index 1f2aeaae5..55b825fe1 100644
--- a/tex/context/base/mkxl/strc-flt.mklx
+++ b/tex/context/base/mkxl/strc-flt.mklx
@@ -527,6 +527,53 @@
\fi
\fi}
+\def\strc_floats_apply_caption_command
+ {\setbox\b_strc_floats_caption\hbox\bgroup
+ %\unless\ifcstok{\floatcaptionparameter\c!command}\emptytoks
+ \floatcaptionparameter\c!command{\box\b_strc_floats_caption}%
+ %\orunless\ifcstok{\floatcaptionparameter\c!deeptextcommand}\emptytoks
+ % \floatcaptionparameter\c!deeptextcommand{\unvbox\b_strc_floats_caption}%
+ %\else
+ % \box\b_strc_floats_caption
+ %\fi
+ \egroup}
+
+%D Some trickery (example by MS):
+%D
+%D \starttyping
+%D \defineframed
+%D [MyCaptionFramed]
+%D [align={lohi,flushleft},
+%D width=fit,
+%D frame=off,
+%D strut=no,
+%D topframe=on,
+%D loffset=1em,
+%D toffset=0.25\lineheight]
+%D
+%D \starttexdefinition protected MyCaption #1
+%D \MyCaptionFramed {
+%D % we ignore #1 as we want to unpack
+%D \unvbox\floatcaptionbox
+%D }
+%D \stoptexdefinition
+%D
+%D \definefloat[pagefloat][pagefloats][graphic]
+%D
+%D \setupfloat
+%D [pagefloat]
+%D [default={page,header,footer}]
+%D
+%D \setupcaption
+%D [pagefloat]
+%D [location={top,inner},
+%D align=inner,
+%D command=\MyCaption,
+%D spaceinbetween=nowhite]
+%D \stoptyping
+
+\permanent\protected\def\floatcaptionbox{\b_strc_floats_caption}
+
%D We can do this ...
%D
%D \starttyping
@@ -1683,8 +1730,7 @@
% todo: installable maken, variant/method=auto vs macro
\strc_floats_prepare_page_caption
%\page_backgrounds_add_local_to_box\b_strc_floats_content
- \setbox\b_strc_floats_caption\hbox % text
- {\floatcaptionparameter\c!command{\box\b_strc_floats_caption}}%
+ \strc_floats_apply_caption_command
\strc_floats_set_caption_dimensions\b_strc_floats_caption
%\moveboxontogrid\b_strc_floats_caption{\floatcaptionparameter\c!grid}\d_strc_floats_caption_height
%\page_backgrounds_add_local_to_box\b_strc_floats_caption
@@ -2355,7 +2401,7 @@
\else
\strc_floats_check_caption_content
\strc_floats_prepare_side_caption
- \setbox\b_strc_floats_caption\hbox{\floatcaptionparameter\c!command{\box\b_strc_floats_caption}}% \hpack ?
+ \strc_floats_apply_caption_command
%\moveboxontogrid\b_strc_floats_caption{\floatcaptionparameter\c!grid}\d_strc_floats_caption_height
%\page_backgrounds_add_local_to_box\b_strc_floats_caption
\strc_floats_build_side_box
diff --git a/tex/context/base/mkxl/strc-lst.lmt b/tex/context/base/mkxl/strc-lst.lmt
index 67e06520c..703e580d7 100644
--- a/tex/context/base/mkxl/strc-lst.lmt
+++ b/tex/context/base/mkxl/strc-lst.lmt
@@ -853,17 +853,46 @@ filters[v_component] = function(specification)
return result
end
+-- filters[v_product] = function(specification)
+-- local reference = specification.reference
+-- if reference and reference ~= "" then
+-- -- local utilitydata = job.loadother(reference,true)
+-- local fullname = file.replacesuffix(reference,"tuc")
+-- if lfs.isfile(fullname) then
+-- local utilitydata = job.loadother(fullname)
+-- if utilitydata then
+-- local collected = utilitydata.structures.lists.collected or { }
+-- setmetatableindex(collected,{ external = reference })
+-- return collected
+-- end
+-- end
+-- end
+-- return { }
+-- end
+
filters[v_product] = function(specification)
local reference = specification.reference
if reference and reference ~= "" then
--- local utilitydata = job.loadother(reference,true)
+ -- local utilitydata = job.loadother(reference,true)
local fullname = file.replacesuffix(reference,"tuc")
if lfs.isfile(fullname) then
local utilitydata = job.loadother(fullname)
if utilitydata then
local collected = utilitydata.structures.lists.collected or { }
setmetatableindex(collected,{ external = reference })
- return collected
+ local result = { }
+ local nofresult = 0
+ local all = specification.all
+ local names = specification.names
+ for i=1,#collected do
+ local v = collected[i]
+ local m = v.metadata
+ if m and names[m.name] or all then
+ nofresult = nofresult + 1
+ result[nofresult] = v
+ end
+ end
+ return result
end
end
end
diff --git a/tex/context/base/mkxl/strc-ref.mklx b/tex/context/base/mkxl/strc-ref.mklx
index de8cd29e1..e7073b36d 100644
--- a/tex/context/base/mkxl/strc-ref.mklx
+++ b/tex/context/base/mkxl/strc-ref.mklx
@@ -37,7 +37,7 @@
\registerctxluafile{strc-rsc}{autosuffix}
\registerctxluafile{strc-ref}{autosuffix}
-\registerctxluafile{node-ref}{autosuffix,optimize}
+\registerctxluafile{node-ref}{autosuffix}
\unprotect
diff --git a/tex/context/base/mkxl/supp-box.mkxl b/tex/context/base/mkxl/supp-box.mkxl
index 802815416..710a4892e 100644
--- a/tex/context/base/mkxl/supp-box.mkxl
+++ b/tex/context/base/mkxl/supp-box.mkxl
@@ -34,7 +34,7 @@
\newdimension\lastnaturalboxht
\newdimension\lastnaturalboxdp
-\registerctxluafile{supp-box}{autosuffix,optimize}
+\registerctxluafile{supp-box}{autosuffix}
% \fixupboxesmode\plusone % gone: is now the default
diff --git a/tex/context/base/mkxl/tabl-xtb.mklx b/tex/context/base/mkxl/tabl-xtb.mklx
index 84755cc1c..f7121dc58 100644
--- a/tex/context/base/mkxl/tabl-xtb.mklx
+++ b/tex/context/base/mkxl/tabl-xtb.mklx
@@ -252,7 +252,7 @@
}% else whitespace mess
\def\tabl_x_get_buffer
- {\clf_gettexbuffer{\tabl_x_current_buffer}}
+ {\clf_getbuffertex{\tabl_x_current_buffer}}
\let\tabl_x_start_row_yes \relax
\let\tabl_x_start_row_nop \relax
diff --git a/tex/context/base/mkxl/type-set.mkxl b/tex/context/base/mkxl/type-set.mkxl
index 2425d8538..5b83f287e 100644
--- a/tex/context/base/mkxl/type-set.mkxl
+++ b/tex/context/base/mkxl/type-set.mkxl
@@ -176,8 +176,8 @@
\definefilesynonym [type-imp-kurier-medium.mkiv] [type-imp-kurier.mkiv]
\definefilesynonym [type-imp-kurier-heavy.mkiv] [type-imp-kurier.mkiv]
-\definefilesynonym [type-imp-antykwa-torunska-light.mkiv] [type-imp-antykwa.mkiv]
-\definefilesynonym [type-imp-antykwa-torunska-cond.mkiv] [type-imp-antykwa.mkiv]
-\definefilesynonym [type-imp-antykwa-torunska-lightcond.mkiv] [type-imp-antykwa.mkiv]
+\definefilesynonym [type-imp-antykwa-light.mkiv] [type-imp-antykwa.mkiv]
+\definefilesynonym [type-imp-antykwa-cond.mkiv] [type-imp-antykwa.mkiv]
+\definefilesynonym [type-imp-antykwa-lightcond.mkiv] [type-imp-antykwa.mkiv]
\protect \endinput
diff --git a/tex/context/base/mkxl/typo-lan.lmt b/tex/context/base/mkxl/typo-lan.lmt
new file mode 100644
index 000000000..21aead80c
--- /dev/null
+++ b/tex/context/base/mkxl/typo-lan.lmt
@@ -0,0 +1,89 @@
+if not modules then modules = { } end modules ['typo-lan'] = {
+ version = 1.001,
+ comment = "companion to typo-lan.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next = type, next
+
+local currentfont = font.current
+local setmetatableindex = table.setmetatableindex
+local utfbyte = utf.byte
+
+local hashes = fonts.hashes
+local fontdata = hashes.characters
+local emwidths = hashes.emwidths
+
+local frequencies = languages.frequencies or { }
+languages.frequencies = frequencies
+
+local frequencydata = { }
+local frequencyfile = string.formatters["lang-frq-%s.lua"]
+local frequencycache = { }
+
+setmetatableindex(frequencydata, function(t,language)
+ local fullname = resolvers.findfile(frequencyfile(language))
+ local v = fullname ~= "" and dofile(fullname)
+ if not v or not v.frequencies then
+ v = t.en
+ end
+ t[language] = v
+ return v
+end)
+
+setmetatableindex(frequencycache, function(t,language)
+ local dataset = frequencydata[language]
+ local frequencies = dataset.frequencies
+ if not frequencies then
+ return t.en
+ end
+ local v = { }
+ setmetatableindex(v, function(t,font)
+ local average = emwidths[font] / 2
+ if frequencies then
+ local characters = fontdata[font]
+ local sum, tot = 0, 0
+ for k, v in next, frequencies do
+ local character = characters[k] -- characters[type(k) == "number" and k or utfbyte(k)]
+ tot = tot + v
+ sum = sum + v * (character and character.width or average)
+ end
+ average = sum / tot -- widths
+ end
+ t[font] = average
+ return average
+ end)
+ t[language] = v
+ return v
+end)
+
+function frequencies.getdata(language)
+ return frequencydata[language]
+end
+
+function frequencies.averagecharwidth(language,font)
+ return frequencycache[language or "en"][font or currentfont()]
+end
+
+-- Just because we can, we also have a setter ...
+
+local dimension_value = tokens.values.dimension
+local scanstring = tokens.scanners.string
+local scandimension = tokens.scanners.dimension
+
+interfaces.implement {
+ name = "languagecharwidth",
+ public = true,
+ usage = "value",
+ actions = function(what)
+ local language = scanstring()
+ local font = currentfont()
+ if what == "value" then
+ return dimension_value, frequencycache[language][font] or 0
+ else
+ frequencycache[language][font] = scandimension(false,false,true)
+ end
+ end,
+}
diff --git a/tex/context/base/mkxl/typo-lan.mkxl b/tex/context/base/mkxl/typo-lan.mkxl
index 9d137f5a5..7fc2a7b46 100644
--- a/tex/context/base/mkxl/typo-lan.mkxl
+++ b/tex/context/base/mkxl/typo-lan.mkxl
@@ -15,10 +15,10 @@
\unprotect
-\registerctxluafile{typo-lan}{}
+\registerctxluafile{typo-lan}{autosuffix}
%D \macros
-%D {averagecharwidth, charwidthlanguage}
+%D {languagecharwidth, averagecharwidth, charwidthlanguage}
%D
%D This is a more \MKIV-ish variant of lang-frq.mkiv. The methods are gone as one
%D doesn't need the tables for them. The main macro is \type {\averagecharwidth}
@@ -26,39 +26,41 @@
%D
%D I finally decided to reimplement this as I needed it for a manual (which is often
%D a reason for such a rewrite). With some inspiring Porcupine Tree in the
-%D background it's not the worst thing to do.
+%D background it's not the worst thing to do. The \LMTX\ variant is a bit more
+%D flexible as it can also set, not that someone will notice.
\mutable\def\charwidthlanguage{\currentmainlanguage}
-\permanent\def\averagecharwidth {\dimexpr\clf_averagecharwidth{\charwidthlanguage}\scaledpoint\relax}
-\permanent\def\languagecharwidth#1{\dimexpr\clf_averagecharwidth{#1}\scaledpoint\relax}
-
-\protect
-
-\continueifinputfile{typo-lan.mkiv}
-
-\setuplayout[backspace=4cm]
-
-\showframe
-
-\starttext
-
-\startbuffer
-
-\mainlanguage[en] \hsize65\averagecharwidth \normalexpanded{\inleft{\the\hsize}} \input ward \par
-\mainlanguage[de] \hsize65\averagecharwidth \normalexpanded{\inleft{\the\hsize}} \input ward \par
-\mainlanguage[nl] \hsize65\averagecharwidth \normalexpanded{\inleft{\the\hsize}} \input ward \par
-
-\stopbuffer
-
-\getbuffer \blank
-
-\switchtobodyfont[pagella]
-
-\getbuffer \blank
-
-\switchtobodyfont[tt,8pt]
-
-\getbuffer
-
-\stoptext
+% \languagecharwidth{language} is defined at the lua end
+
+\permanent\def\averagecharwidth{\languagecharwidth{\charwidthlanguage}}
+
+\protect \endinput
+
+% \setuplayout[backspace=4cm]
+%
+% \showframe
+%
+% \starttext
+%
+% \startbuffer
+%
+% \mainlanguage[en] \hsize65\averagecharwidth \normalexpanded{\inleft{\the\hsize}} \input ward \par
+% \mainlanguage[de] \hsize65\averagecharwidth \normalexpanded{\inleft{\the\hsize}} \input ward \par
+% \mainlanguage[nl] \hsize65\averagecharwidth \normalexpanded{\inleft{\the\hsize}} \input ward \par
+%
+% \languagecharwidth{de}=\languagecharwidth{en}
+%
+% \stopbuffer
+%
+% \getbuffer \blank
+%
+% \switchtobodyfont[pagella]
+%
+% \getbuffer \blank
+%
+% \switchtobodyfont[tt,8pt]
+%
+% \getbuffer
+%
+% \stoptext
diff --git a/tex/context/base/mkxl/typo-pnc.lmt b/tex/context/base/mkxl/typo-pnc.lmt
new file mode 100644
index 000000000..090cbb5b6
--- /dev/null
+++ b/tex/context/base/mkxl/typo-pnc.lmt
@@ -0,0 +1,170 @@
+if not modules then modules = { } end modules ['typo-pnc'] = {
+ version = 1.001,
+ comment = "companion to typo-pnc.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local nodes = nodes
+local fonts = fonts
+
+local enableaction = nodes.tasks.enableaction
+
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+
+local nodecodes = nodes.nodecodes
+local gluecodes = nodes.gluecodes
+local glyph_code = nodecodes.glyph
+local glue_code = nodecodes.glue
+local spaceskip_code = gluecodes.spaceskip
+
+local new_kern = nuts.pool.kern
+local insertafter = nuts.insertafter
+
+local nextglyph = nuts.traversers.glyph
+
+local getchar = nuts.getchar
+local getfont = nuts.getfont
+local getboth = nuts.getboth
+local getnext = nuts.getnext
+local getattr = nuts.getattr
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getwidth = nuts.getwidth
+local setwidth = nuts.setwidth
+local findattribute = nuts.findattribute
+
+local glyph_code = nodes.nodecodes.glyph
+
+local parameters = fonts.hashes.parameters
+local categories = characters.categories
+
+local texsetattribute = tex.setattribute
+local unsetvalue = attributes.unsetvalue
+
+local period = 0x2E
+local factor = 0.5
+
+-- alternative: tex.getlccode and tex.getuccode
+
+typesetters = typesetters or { }
+local typesetters = typesetters
+
+local periodkerns = typesetters.periodkerns or { }
+typesetters.periodkerns = periodkerns
+
+local report = logs.reporter("period kerns")
+local trace = false
+
+trackers.register("typesetters.periodkerns",function(v) trace = v end)
+
+periodkerns.mapping = periodkerns.mapping or { }
+periodkerns.factors = periodkerns.factors or { }
+local a_periodkern = attributes.private("periodkern")
+
+storage.register("typesetters/periodkerns/mapping", periodkerns.mapping, "typesetters.periodkerns.mapping")
+storage.register("typesetters/periodkerns/factors", periodkerns.factors, "typesetters.periodkerns.factors")
+
+local mapping = periodkerns.mapping
+local factors = periodkerns.factors
+
+function periodkerns.handler(head)
+ local _, start = findattribute(head,a_periodkern,glyph_code)
+ if start then
+ for current, char, font in nextglyph, start do
+ if char == period then
+ local a = getattr(current,a_periodkern)
+ if a then
+ local factor = mapping[a]
+ if factor then
+ local prev, next = getboth(current)
+ if prev and next and getid(prev) == glyph_code and getid(next) == glyph_code then
+ local pchar = getchar(prev)
+ local pcode = categories[pchar]
+ if pcode == "lu" or pcode == "ll" then
+ local nchar = getchar(next)
+ local ncode = categories[nchar]
+ if ncode == "lu" or ncode == "ll" then
+ local next2 = getnext(next)
+ if next2 and getid(next2) == glyph_code and getchar(next2) == period then
+ -- A.B.
+ local fontspace, inserted
+ if factor ~= 0 then
+ fontspace = parameters[getfont(current)].space -- can be sped up
+ inserted = factor * fontspace
+ insertafter(head,current,new_kern(inserted))
+ if trace then
+ report("inserting space at %C . [%p] %C .",pchar,inserted,nchar)
+ end
+ end
+ local next3 = getnext(next2)
+ if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then
+ local width = getwidth(next3)
+ local space = fontspace or parameters[getfont(current)].space -- can be sped up
+ if width > space then -- space + extraspace
+ local next4 = getnext(next3)
+ if next4 and getid(next4) == glyph_code then
+ local fchar = getchar(next4)
+ if categories[fchar] ~= "lu" then
+ -- A.B.<glue>X
+ if trace then
+ if inserted then
+ report("reverting space at %C . [%p] %C . [%p->%p] %C",pchar,inserted,nchar,width,space,fchar)
+ else
+ report("reverting space at %C . %C . [%p->%p] %C",pchar,nchar,width,space,fchar)
+ end
+ end
+ setwidth(next3,space)
+ else
+ if trace then
+ if inserted then
+ report("keeping space at %C . [%p] %C . [%p] %C",pchar,inserted,nchar,width,fchar)
+ else
+ report("keeping space at %C . %C . [%p] %C",pchar,nchar,width,fchar)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return head
+end
+
+local enabled = false
+
+function periodkerns.set(factor)
+ factor = tonumber(factor) or 0
+ if not enabled then
+ enableaction("processors","typesetters.periodkerns.handler")
+ enabled = true
+ end
+ local a = factors[factor]
+ if not a then
+ a = #mapping + 1
+ factors[factors], mapping[a] = a, factor
+ end
+ factor = a
+ texsetattribute(a_periodkern,factor)
+ return factor
+end
+
+-- interface
+
+interfaces.implement {
+ name = "setperiodkerning",
+ actions = periodkerns.set,
+ arguments = "string"
+}
+
+
diff --git a/tex/context/base/mkxl/typo-pnc.mkxl b/tex/context/base/mkxl/typo-pnc.mkxl
index b5b1a17d6..aceab2685 100644
--- a/tex/context/base/mkxl/typo-pnc.mkxl
+++ b/tex/context/base/mkxl/typo-pnc.mkxl
@@ -19,7 +19,7 @@
% with "foo e.g.\ bar" so let's see if we can automate that and at the same time
% inject spaces between the snippets. It gets boring writing this kind of code.
-\registerctxluafile{typo-pnc}{}
+\registerctxluafile{typo-pnc}{autosuffix}
\definesystemattribute[periodkern][public,global]
diff --git a/tex/context/fonts/mkiv/antykwa-math.lfg b/tex/context/fonts/mkiv/antykwa-math.lfg
index fe259e909..3c34d7af0 100644
--- a/tex/context/fonts/mkiv/antykwa-math.lfg
+++ b/tex/context/fonts/mkiv/antykwa-math.lfg
@@ -19,6 +19,12 @@ local badones = {
coproductdisplay = .25,
}
+local uglyones = {
+ braceleft = true,
+ braceright = true,
+}
+
+
return {
name = "antykwa-math",
version = "1.00",
@@ -42,7 +48,8 @@ return {
{ name = "mi-anttri.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "mi-anttbi.tfm", vector = "tex-bi", skewchar=0x7F },
{ name = "rm-anttb.tfm", vector = "tex-bf", skewchar=0x7F },
- { name = "sy-anttrz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
+ { name = "sy-anttrz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true, ignore = uglyones },
+ { name = "file:AntykwaTorunska-Regular", vector = "tex-ex-braces", backmap = false },
{ name = "ex-anttr.tfm", vector = "tex-ex", extension = true, badones = badones },
},
["antykwa-light-math"] = {
@@ -53,7 +60,8 @@ return {
{ name = "mi-anttli.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "mi-anttri.tfm", vector = "tex-bi", skewchar=0x7F },
{ name = "rm-anttr.tfm", vector = "tex-bf", skewchar=0x7F },
- { name = "sy-anttlz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
+ { name = "sy-anttlz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true, ignore = uglyones },
+ { name = "file:AntykwaTorunskaLight-Regular", vector = "tex-ex-braces", backmap = false },
{ name = "ex-anttl.tfm", vector = "tex-ex", extension = true, badones = badones },
},
["antykwa-cond-math"] = {
@@ -64,7 +72,8 @@ return {
{ name = "mi-anttcri.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "mi-anttcbi.tfm", vector = "tex-bi", skewchar=0x7F },
{ name = "rm-anttcb.tfm", vector = "tex-bf", skewchar=0x7F },
- { name = "sy-anttcrz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
+ { name = "sy-anttcrz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true, ignore = uglyones },
+ { name = "file:AntykwaTorunskaCond-Regular", vector = "tex-ex-braces", backmap = false },
{ name = "ex-anttcr.tfm", vector = "tex-ex", extension = true, badones = badones },
},
["antykwa-lightcond-math"] = {
@@ -75,7 +84,8 @@ return {
{ name = "mi-anttcli.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "mi-anttcri.tfm", vector = "tex-bi", skewchar=0x7F },
{ name = "rm-anttcr.tfm", vector = "tex-bf", skewchar=0x7F },
- { name = "sy-anttclz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
+ { name = "sy-anttclz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true, ignore = uglyones },
+ { name = "file:AntykwaTorunskaCondLight-Regular", vector = "tex-ex-braces", backmap = false },
{ name = "ex-anttcl.tfm", vector = "tex-ex", extension = true, badones = badones },
}
}
diff --git a/tex/context/fonts/mkiv/bonum-math.lfg b/tex/context/fonts/mkiv/bonum-math.lfg
index e3fd4119d..56262eb32 100644
--- a/tex/context/fonts/mkiv/bonum-math.lfg
+++ b/tex/context/fonts/mkiv/bonum-math.lfg
@@ -139,6 +139,16 @@ return {
["0x221A.parts.bottom"] = { location = "left", hfactor = .1, vfactor = 1.15 },
}
},
+ {
+ tweak = "dimensions",
+ list = {
+ -- [0x007D] = { topright = -0.05, bottomright = -0.05 }, -- right brace variants
+ ["0x7C"] = { width = 1.4, xoffset=0.2 }, -- vertical bar
+ -- ["0x7C.variants.*"] = { width = 1, extend = 2.4 }, -- vertical bar
+ -- ["0x7C.parts.top"] = { , }, -- vertical bar
+ -- ["0x7C.parts.bottom"] = { bottomright = -0.15 }, -- vertical bar
+ },
+ },
{
tweak = "fixaccents",
@@ -277,7 +287,7 @@ return {
},
{
tweak = "addbars",
- advance = 0.275,
+ advance = 0.475,
},
{
tweak = "addactuarian",
diff --git a/tex/context/fonts/mkiv/type-imp-antykwa.mkiv b/tex/context/fonts/mkiv/type-imp-antykwa.mkiv
index 15a2f39b6..6ad747307 100644
--- a/tex/context/fonts/mkiv/type-imp-antykwa.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-antykwa.mkiv
@@ -34,7 +34,7 @@
\definefontsynonym [AntykwaTorunska-Light] [\s!file:AntykwaTorunskaLight-Regular] [\s!features=\s!default]
\definefontsynonym [AntykwaTorunska-LightItalic] [\s!file:AntykwaTorunskaLight-Italic] [\s!features=\s!default]
\definefontsynonym [AntykwaTorunska-Medium] [\s!file:AntykwaTorunskaMed-Regular] [\s!features=\s!default]
- \definefontsynonym [AntykwaTorunska-MedItalic] [\s!file:AntykwaTorunskaMed-Italic] [\s!features=\s!default]
+ \definefontsynonym [AntykwaTorunska-MediumItalic] [\s!file:AntykwaTorunskaMed-Italic] [\s!features=\s!default]
\definefontsynonym [AntykwaTorunska-CondRegular] [\s!file:AntykwaTorunskaCond-Regular] [\s!features=\s!default]
\definefontsynonym [AntykwaTorunska-CondItalic] [\s!file:AntykwaTorunskaCond-Italic] [\s!features=\s!default]
\definefontsynonym [AntykwaTorunska-CondBold] [\s!file:AntykwaTorunskaCond-Bold] [\s!features=\s!default]
@@ -42,24 +42,7 @@
\definefontsynonym [AntykwaTorunska-CondLight] [\s!file:AntykwaTorunskaCondLight-Regular] [\s!features=\s!default]
\definefontsynonym [AntykwaTorunska-CondLightItalic] [\s!file:AntykwaTorunskaCondLight-Italic] [\s!features=\s!default]
\definefontsynonym [AntykwaTorunska-CondMedium] [\s!file:AntykwaTorunskaCondMed-Regular] [\s!features=\s!default]
- \definefontsynonym [AntykwaTorunska-CondMedItalic] [\s!file:AntykwaTorunskaCondMed-Italic] [\s!features=\s!default]
-
- \definefontsynonym [AntykwaTorunska-Cap] [\s!file:AntykwaTorunska-Regular] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-ItalicCap] [\s!file:AntykwaTorunska-Italic] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-BoldCap] [\s!file:AntykwaTorunska-Bold] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-BoldItalicCap] [\s!file:AntykwaTorunska-BoldItalic] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-LightCap] [\s!file:AntykwaTorunskaLight-Regular] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-LightItalicCap] [\s!file:AntykwaTorunskaLight-Italic] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-MediumCap] [\s!file:AntykwaTorunskaMed-Regular] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-MedItalicCap] [\s!file:AntykwaTorunskaMed-Italic] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondCap] [\s!file:AntykwaTorunskaCond-Regular] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondItalicCap] [\s!file:AntykwaTorunskaCond-Italic] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondBoldCap] [\s!file:AntykwaTorunskaCond-Bold] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondBoldItalicCap] [\s!file:AntykwaTorunskaCond-BoldItalic] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondLightCap] [\s!file:AntykwaTorunskaCondLight-Regular] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondLightItalicCap][\s!file:AntykwaTorunskaCondLight-Italic] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondMediumCap] [\s!file:AntykwaTorunskaCondMed-Regular] [\s!features=\s!smallcaps]
- \definefontsynonym [AntykwaTorunska-CondMedItalicCap] [\s!file:AntykwaTorunskaCondMed-Italic] [\s!features=\s!smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondMediumItalic] [\s!file:AntykwaTorunskaCondMed-Italic] [\s!features=\s!default]
\stoptypescript
\starttypescript [\s!math][antykwa,antykwa-torunska][\s!all]
@@ -89,7 +72,6 @@
\definefontsynonym [\s!SerifSlanted] [AntykwaTorunska-Italic]
\definefontsynonym [\s!SerifBoldItalic] [AntykwaTorunska-BoldItalic]
\definefontsynonym [\s!SerifBoldSlanted] [AntykwaTorunska-BoldItalic]
- \definefontsynonym [\s!SerifCaps] [AntykwaTorunska-Cap]
\stoptypescript
\starttypescript [\s!serif] [antykwa-light,antykwa-torunska-light] [\s!name]
@@ -97,9 +79,8 @@
\definefontsynonym [\s!SerifBold] [AntykwaTorunska-Medium]
\definefontsynonym [\s!SerifItalic] [AntykwaTorunska-LightItalic]
\definefontsynonym [\s!SerifSlanted] [AntykwaTorunska-LightItalic]
- \definefontsynonym [\s!SerifBoldItalic] [AntykwaTorunska-MedItalic]
- \definefontsynonym [\s!SerifBoldSlanted] [AntykwaTorunska-MedItalic]
- \definefontsynonym [\s!SerifCaps] [AntykwaTorunska-LightCap]
+ \definefontsynonym [\s!SerifBoldItalic] [AntykwaTorunska-MediumItalic]
+ \definefontsynonym [\s!SerifBoldSlanted] [AntykwaTorunska-MediumItalic]
\stoptypescript
\starttypescript [\s!serif] [antykwa-cond,antykwa-torunska-cond] [\s!name]
@@ -109,7 +90,6 @@
\definefontsynonym [\s!SerifSlanted] [AntykwaTorunska-CondItalic]
\definefontsynonym [\s!SerifBoldItalic] [AntykwaTorunska-CondBoldItalic]
\definefontsynonym [\s!SerifBoldSlanted] [AntykwaTorunska-CondBoldItalic]
- \definefontsynonym [\s!SerifCaps] [AntykwaTorunska-CondCap]
\stoptypescript
\starttypescript [\s!serif] [antykwa-lightcond,antykwa-torunska-lightcond] [\s!name]
@@ -117,117 +97,8 @@
\definefontsynonym [\s!SerifBold] [AntykwaTorunska-CondMedium]
\definefontsynonym [\s!SerifItalic] [AntykwaTorunska-CondLightItalic]
\definefontsynonym [\s!SerifSlanted] [AntykwaTorunska-CondLightItalic]
- \definefontsynonym [\s!SerifBoldItalic] [AntykwaTorunska-CondMedItalic]
- \definefontsynonym [\s!SerifBoldSlanted] [AntykwaTorunska-CondMedItalic]
- \definefontsynonym [\s!SerifCaps] [AntykwaTorunska-CondLightCap]
- \stoptypescript
-
- \starttypescript [\s!serif] [antykwa,antykwa-torunska] [\s!name]
- \definefontsynonym [SerifRegular] [Serif]
- \definefontsynonym [SerifRegularCaps] [AntykwaTorunska-Cap]
- \definefontsynonym [SerifBoldCaps] [AntykwaTorunska-BoldCap]
- \definefontsynonym [SerifItalicCaps] [AntykwaTorunska-ItalicCap]
- \definefontsynonym [SerifSlantedCaps] [AntykwaTorunska-ItalicCap]
- \definefontsynonym [SerifBoldItalicCaps] [AntykwaTorunska-BoldItalicCap]
- \definefontsynonym [SerifBoldSlantedCaps] [AntykwaTorunska-BoldItalicCap]
- \definefontsynonym [SerifCapsCaps] [AntykwaTorunska-Cap]
-
- \definefontsynonym [SerifRegularLight] [AntykwaTorunska-Light]
- \definefontsynonym [SerifBoldLight] [AntykwaTorunska-Medium]
- \definefontsynonym [SerifItalicLight] [AntykwaTorunska-LightItalic]
- \definefontsynonym [SerifSlantedLight] [AntykwaTorunska-LightItalic]
- \definefontsynonym [SerifBoldItalicLight] [AntykwaTorunska-MedItalic]
- \definefontsynonym [SerifBoldSlantedLight] [AntykwaTorunska-MedItalic]
- \definefontsynonym [SerifCapsLight] [AntykwaTorunska-LightCap]
-
- \definefontsynonym [SerifRegularCond] [AntykwaTorunska-CondRegular]
- \definefontsynonym [SerifBoldCond] [AntykwaTorunska-CondBold]
- \definefontsynonym [SerifItalicCond] [AntykwaTorunska-CondItalic]
- \definefontsynonym [SerifSlantedCond] [AntykwaTorunska-CondItalic]
- \definefontsynonym [SerifBoldItalicCond] [AntykwaTorunska-CondBoldItalic]
- \definefontsynonym [SerifBoldSlantedCond] [AntykwaTorunska-CondBoldItalic]
- \definefontsynonym [SerifCapsCond] [AntykwaTorunska-CondCap]
- \stoptypescript
-
- \starttypescript [\s!serif] [antykwa-light,antykwa-torunska-light] [\s!name]
- \definefontsynonym [SerifRegular] [Serif]
- \definefontsynonym [SerifRegularCaps] [AntykwaTorunska-LightCap]
- \definefontsynonym [SerifBoldCaps] [AntykwaTorunska-MediumCap]
- \definefontsynonym [SerifItalicCaps] [AntykwaTorunska-LightItalicCap]
- \definefontsynonym [SerifSlantedCaps] [AntykwaTorunska-LightItalicCap]
- \definefontsynonym [SerifBoldItalicCaps] [AntykwaTorunska-MedItalicCap]
- \definefontsynonym [SerifBoldSlantedCaps] [AntykwaTorunska-MedItalicCap]
- \definefontsynonym [SerifCapsCaps] [AntykwaTorunska-LightCap]
-
- \definefontsynonym [SerifRegularDark] [AntykwaTorunska-Regular]
- \definefontsynonym [SerifBoldDark] [AntykwaTorunska-Bold]
- \definefontsynonym [SerifItalicDark] [AntykwaTorunska-Italic]
- \definefontsynonym [SerifSlantedDark] [AntykwaTorunska-Italic]
- \definefontsynonym [SerifBoldItalicDark] [AntykwaTorunska-BoldItalic]
- \definefontsynonym [SerifBoldSlantedDark] [AntykwaTorunska-BoldItalic]
- \definefontsynonym [SerifCapsDark] [AntykwaTorunska-Cap]
-
- \definefontsynonym [SerifRegularCond] [AntykwaTorunska-CondLight]
- \definefontsynonym [SerifBoldCond] [AntykwaTorunska-CondMedium]
- \definefontsynonym [SerifItalicCond] [AntykwaTorunska-CondLightItalic]
- \definefontsynonym [SerifSlantedCond] [AntykwaTorunska-CondLightItalic]
- \definefontsynonym [SerifBoldItalicCond] [AntykwaTorunska-CondMedItalic]
- \definefontsynonym [SerifBoldSlantedCond] [AntykwaTorunska-CondMedItalic]
- \definefontsynonym [SerifCapsCond] [AntykwaTorunska-CondLightCap]
- \stoptypescript
-
- \starttypescript [\s!serif] [antykwa-cond,antykwa-torunska-cond] [\s!name]
- \definefontsynonym [SerifRegular] [Serif]
- \definefontsynonym [SerifRegularCaps] [AntykwaTorunska-CondCap]
- \definefontsynonym [SerifBoldCaps] [AntykwaTorunska-CondBoldCap]
- \definefontsynonym [SerifItalicCaps] [AntykwaTorunska-CondItalicCap]
- \definefontsynonym [SerifSlantedCaps] [AntykwaTorunska-CondItalicCap]
- \definefontsynonym [SerifBoldItalicCaps] [AntykwaTorunska-CondBoldItalicCap]
- \definefontsynonym [SerifBoldSlantedCaps] [AntykwaTorunska-CondBoldItalicCap]
- \definefontsynonym [SerifCapsCaps] [AntykwaTorunska-CondCap]
-
- \definefontsynonym [SerifRegularLight] [AntykwaTorunska-CondLight]
- \definefontsynonym [SerifBoldLight] [AntykwaTorunska-CondMedium]
- \definefontsynonym [SerifItalicLight] [AntykwaTorunska-CondLightItalic]
- \definefontsynonym [SerifSlantedLight] [AntykwaTorunska-CondLightItalic]
- \definefontsynonym [SerifBoldItalicLight] [AntykwaTorunska-CondMedItalic]
- \definefontsynonym [SerifBoldSlantedLight] [AntykwaTorunska-CondMedItalic]
- \definefontsynonym [SerifCapsLight] [AntykwaTorunska-CondLightCap]
-
- \definefontsynonym [SerifRegularExp] [AntykwaTorunska-Regular]
- \definefontsynonym [SerifBoldExp] [AntykwaTorunska-Bold]
- \definefontsynonym [SerifItalicExp] [AntykwaTorunska-Italic]
- \definefontsynonym [SerifSlantedExp] [AntykwaTorunska-Italic]
- \definefontsynonym [SerifBoldItalicExp] [AntykwaTorunska-BoldItalic]
- \definefontsynonym [SerifBoldSlantedExp] [AntykwaTorunska-BoldItalic]
- \definefontsynonym [SerifCapsExp] [AntykwaTorunska-Cap]
- \stoptypescript
-
- \starttypescript [\s!serif] [antykwa-lightcond,antykwa-torunska-lightcond] [\s!name]
- \definefontsynonym [SerifRegular] [Serif]
- \definefontsynonym [SerifRegularCaps] [AntykwaTorunska-CondLightCap]
- \definefontsynonym [SerifBoldCaps] [AntykwaTorunska-CondMediumCap]
- \definefontsynonym [SerifItalicCaps] [AntykwaTorunska-CondLightItalicCap]
- \definefontsynonym [SerifSlantedCaps] [AntykwaTorunska-CondLightItalicCap]
- \definefontsynonym [SerifBoldItalicCaps] [AntykwaTorunska-CondMedItalicCap]
- \definefontsynonym [SerifBoldSlantedCaps] [AntykwaTorunska-CondMedItalicCap]
- \definefontsynonym [SerifCapsCaps] [AntykwaTorunska-CondLightCap]
-
- \definefontsynonym [SerifRegularDark] [AntykwaTorunska-CondRegular]
- \definefontsynonym [SerifBoldDark] [AntykwaTorunska-CondBold]
- \definefontsynonym [SerifItalicDark] [AntykwaTorunska-CondItalic]
- \definefontsynonym [SerifSlantedDark] [AntykwaTorunska-CondItalic]
- \definefontsynonym [SerifBoldItalicDark] [AntykwaTorunska-CondBoldItalic]
- \definefontsynonym [SerifBoldSlantedDark] [AntykwaTorunska-CondBoldItalic]
- \definefontsynonym [SerifCapsDark] [AntykwaTorunska-CondCap]
-
- \definefontsynonym [SerifRegularExp] [AntykwaTorunska-Light]
- \definefontsynonym [SerifBoldExp] [AntykwaTorunska-Medium]
- \definefontsynonym [SerifItalicExp] [AntykwaTorunska-LightItalic]
- \definefontsynonym [SerifSlantedExp] [AntykwaTorunska-LightItalic]
- \definefontsynonym [SerifBoldItalicExp] [AntykwaTorunska-MedItalic]
- \definefontsynonym [SerifBoldSlantedExp] [AntykwaTorunska-MedItalic]
- \definefontsynonym [SerifCapsExp] [AntykwaTorunska-LightCap]
+ \definefontsynonym [\s!SerifBoldItalic] [AntykwaTorunska-CondMediumItalic]
+ \definefontsynonym [\s!SerifBoldSlanted] [AntykwaTorunska-CondMediumItalic]
\stoptypescript
\stoptypescriptcollection
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 9618051bd..aaf99ed45 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 : 2023-02-07 19:02
+-- merge date : 2023-02-14 17:41
do -- begin closure to overcome local limits and interference