summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-05-19 14:44:17 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-05-19 14:44:17 +0200
commitdb581096187dc2d3cbdbe4cdc39d247c168b1607 (patch)
tree529b5baf164aac250975e51937e024a8cd5c71c8
parent2017d30b4ca772c8eeac4fc0eb9b54e547a9a1d8 (diff)
downloadcontext-db581096187dc2d3cbdbe4cdc39d247c168b1607.tar.gz
2016-05-19 13:48:00
-rw-r--r--doc/context/documents/general/manuals/luatex.pdfbin994871 -> 995319 bytes
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-nodes.tex16
-rw-r--r--tex/context/base/context-version.pdfbin4255 -> 4250 bytes
-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/font-one.lua14
-rw-r--r--tex/context/base/mkiv/font-onr.lua38
-rw-r--r--tex/context/base/mkiv/font-ots.lua30
-rw-r--r--tex/context/base/mkiv/font-sel.lua1354
-rw-r--r--tex/context/base/mkiv/font-sel.mkvi243
-rw-r--r--tex/context/base/mkiv/node-ini.lua27
-rw-r--r--tex/context/base/mkiv/node-res.lua64
-rw-r--r--tex/context/base/mkiv/spac-prf.lua10
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin9209 -> 9253 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin266761 -> 268228 bytes
-rw-r--r--tex/context/base/mkiv/typo-mar.lua212
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin820905 -> 820707 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60792 -> 60793 bytes
-rw-r--r--tex/context/modules/mkiv/m-scite.mkiv11
-rw-r--r--tex/context/modules/mkiv/x-setups-basics.mkiv9
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua61
21 files changed, 1126 insertions, 967 deletions
diff --git a/doc/context/documents/general/manuals/luatex.pdf b/doc/context/documents/general/manuals/luatex.pdf
index 8b746b0f2..92424d805 100644
--- a/doc/context/documents/general/manuals/luatex.pdf
+++ b/doc/context/documents/general/manuals/luatex.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
index e90813c33..b7b81b5a6 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
@@ -646,14 +646,14 @@ The \type {type} can have one of six distinct values. The number is the \ASCII\
value if the first character if the type name (so you can use string.byte("l")
instead of \type {108}).
-\starttabulate[|lT|p|]
-\NC \rmbf value \NC \bf meaning \NC \bf explanation \NC \NR
-\NC 97 \NC a \NC list of attributes (a node list) \NC \NR
-\NC 100 \NC d \NC a \LUA\ number \NC \NR
-\NC 108 \NC l \NC a \LUA\ value (table, number, boolean, etc) \NC \NR
-\NC 110 \NC n \NC a node list \NC \NR
-\NC 115 \NC s \NC a \LUA\ string \NC \NR
-\NC 116 \NC t \NC a \LUA\ token list in \LUA\ table form (a list of triplets) \NC \NR
+\starttabulate[|lT|lT|p|]
+\NC \rmbf value \NC \bf meaning \NC \bf explanation \NC \NR
+\NC 97 \NC a \NC list of attributes (a node list) \NC \NR
+\NC 100 \NC d \NC a \LUA\ number \NC \NR
+\NC 108 \NC l \NC a \LUA\ value (table, number, boolean, etc) \NC \NR
+\NC 110 \NC n \NC a node list \NC \NR
+\NC 115 \NC s \NC a \LUA\ string \NC \NR
+\NC 116 \NC t \NC a \LUA\ token list in \LUA\ table form (a list of triplets) \NC \NR
\stoptabulate
\subsubsubsection{save_pos whatsits}
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index b40235cc8..ff75a0a20 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 13050577d..8e4d59750 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2016.05.17 19:20}
+\newcontextversion{2016.05.19 13:43}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 032682a1d..e0bd762a9 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2016.05.17 19:20}
+\edef\contextversion{2016.05.19 13:43}
\edef\contextkind {current}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-one.lua b/tex/context/base/mkiv/font-one.lua
index 77f2560f6..a9f78f4fb 100644
--- a/tex/context/base/mkiv/font-one.lua
+++ b/tex/context/base/mkiv/font-one.lua
@@ -812,7 +812,8 @@ local function check_afm(specification,fullname)
end
function readers.afm(specification,method)
- local fullname, tfmdata = specification.filename or "", nil
+ local fullname = specification.filename or ""
+ local tfmdata = nil
if fullname == "" then
local forced = specification.forced or ""
if forced ~= "" then
@@ -841,7 +842,16 @@ function readers.pfb(specification,method) -- only called when forced
if trace_defining then
report_afm("using afm reader for %a",original)
end
- specification.specification = file.replacesuffix(original,"afm")
specification.forced = "afm"
+ local function swap(name)
+ local value = specification[swap]
+ if value then
+ specification[swap] = gsub("%.pfb",".afm",1)
+ end
+ end
+ swap("filename")
+ swap("fullname")
+ swap("forcedname")
+ swap("specification")
return readers.afm(specification,method)
end
diff --git a/tex/context/base/mkiv/font-onr.lua b/tex/context/base/mkiv/font-onr.lua
index 2699f25bb..a4969ad73 100644
--- a/tex/context/base/mkiv/font-onr.lua
+++ b/tex/context/base/mkiv/font-onr.lua
@@ -33,6 +33,7 @@ local trace_indexing = false trackers.register("afm.indexing", function(v
local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end)
local report_afm = logs.reporter("fonts","afm loading")
+local report_afm = logs.reporter("fonts","pfb loading")
fonts = fonts or { }
local handlers = fonts.handlers or { }
@@ -122,19 +123,19 @@ do
local data = io.loaddata(resolvers.findfile(filename))
if not data then
- print("no data",filename)
+ report_pfb("no data in %a",filename)
return
end
- if not find(data,"!PS%-AdobeFont%-") then
- print("no font",filename)
+ if not (find(data,"!PS%-AdobeFont%-") or find(data,"%%!FontType1")) then
+ report_pfb("no font in %a",filename)
return
end
local ascii, binary = match(data,"(.*)eexec%s+......(.*)")
if not binary then
- print("no binary",filename)
+ report_pfb("no binary data in %a",filename)
return
end
@@ -148,7 +149,7 @@ do
end
if not vector then
- print("no vector",filename)
+ report_pfb("no vector in %a",filename)
return
end
@@ -184,16 +185,18 @@ and <l n='otf'/> reader. We only need data that is relevant for our use. We don'
more complex arrangements like multiple master (obsolete), direction specific kerning, etc.</p>
--ldx]]--
-local spacing = patterns.whitespace
-local lineend = patterns.newline
-local number = spacing * S("+-")^-1 * (R("09") + S("."))^1 / tonumber
-local name = spacing * C((1-spacing)^1)
-local words = spacing * (1 - lineend)^1 / strip
-local rest = (1 - lineend)^0
-local fontdata = Carg(1)
-local semicolon = spacing * P(";")
-local plus = P("plus") * number
-local minus = P("minus") * number
+local spacer = patterns.spacer
+local whitespace = patterns.whitespace
+local lineend = patterns.newline
+local spacing = spacer^0
+local number = spacing * S("+-")^-1 * (R("09") + S("."))^1 / tonumber
+local name = spacing * C((1 - whitespace)^1)
+local words = spacing * ((1 - lineend)^1 / strip)
+local rest = (1 - lineend)^0
+local fontdata = Carg(1)
+local semicolon = spacing * P(";")
+local plus = spacing * P("plus") * number
+local minus = spacing * P("minus") * number
-- kern pairs
@@ -333,6 +336,10 @@ local fullparser = ( P("StartFontMetrics") * fontdata * name / start )
* ( p_charmetrics + p_kernpairs + p_parameters + (1-P("EndFontMetrics")) )^0
* ( P("EndFontMetrics") / stop )
+local fullparser = ( P("StartFontMetrics") * fontdata * name / start )
+ * ( p_charmetrics + p_kernpairs + p_parameters + (1-P("EndFontMetrics")) )^0
+ * ( P("EndFontMetrics") / stop )
+
local infoparser = ( P("StartFontMetrics") * fontdata * name / start )
* ( p_parameters + (1-P("EndFontMetrics")) )^0
* ( P("EndFontMetrics") / stop )
@@ -402,4 +409,3 @@ function readers.getinfo(filename)
return data.metadata
end
end
-
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index c173de2be..1af7bacf3 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -3064,7 +3064,7 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
while start do
local char = ischar(start,font)
if char then
- local a = getattr(start,0)
+ local a = attr and getattr(start,0)
if not a or (a == attr) then
local lookupmatch = lookupcache[char]
if lookupmatch then
@@ -3097,7 +3097,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
while start ~= stop do
local char = ischar(start,font)
if char then
- local a = getattr(start,0)
+ local a = attr and getattr(start,0)
if not a or (a == attr) then
local lookupmatch = lookupcache[char]
if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check
@@ -3132,7 +3132,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
end
-- local function d_run_single(prev,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
--- local a = getattr(prev,0)
+-- local a = attr and getattr(prev,0)
-- if not a or (a == attr) then
-- local char = ischar(prev) -- can be disc
-- if char then
@@ -3149,7 +3149,7 @@ end
-- end
local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
- local a = getattr(sub,0)
+ local a = attr and getattr(sub,0)
if not a or (a == attr) then
for n in traverse_nodes(sub) do -- only gpos
if n == last then
@@ -3181,7 +3181,7 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
while start do
local char = ischar(start,font)
if char then
- local a = getattr(start,0)
+ local a = attr and getattr(start,0)
if not a or (a == attr) then
for i=1,nofsteps do
local step = steps[i]
@@ -3228,7 +3228,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
while start ~= stop do
local char = ischar(start,font)
if char then
- local a = getattr(start,0)
+ local a = attr and getattr(start,0)
if not a or (a == attr) then
for i=1,nofsteps do
local step = steps[i]
@@ -3271,7 +3271,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
end
-- local function d_run_multiple(prev,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
--- local a = getattr(prev,0)
+-- local a = attr and getattr(prev,0)
-- if not a or (a == attr) then
-- local char = ischar(prev) -- can be disc
-- if char then
@@ -3297,7 +3297,7 @@ end
-- end
local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
- local a = getattr(sub,0)
+ local a = attr and getattr(sub,0)
if not a or (a == attr) then
for n in traverse_nodes(sub) do -- only gpos
if n == last then
@@ -3394,6 +3394,10 @@ local function featuresprocessor(head,font,attr)
end
+ if attr == 0 then
+ attr = false -- some 10% faster when no dynamics but hardly measureable on real runs
+ end
+
head = tonut(head)
if trace_steps then
@@ -3405,7 +3409,7 @@ local function featuresprocessor(head,font,attr)
local done = false
local datasets = otf.dataset(tfmdata,font,attr)
- local dirstack = { } -- could move outside function btu we can have local runss
+ local dirstack = { } -- could move outside function but we can have local runs
sweephead = { }
@@ -3451,7 +3455,7 @@ local function featuresprocessor(head,font,attr)
while start do
local char = ischar(start,font)
if char then
- local a = getattr(start,0)
+ local a = attr and getattr(start,0)
if not a or (a == attr) then
for i=1,nofsteps do
local step = steps[i]
@@ -3489,14 +3493,12 @@ local function featuresprocessor(head,font,attr)
local step = steps[1]
local lookupcache = step.coverage
if not lookupcache then
- -- can't happen, no check in loop either
report_missing_coverage(dataset,sequence)
else
-
while start do
local char, id = ischar(start,font)
if char then
- local a = getattr(start,0)
+ local a = attr and getattr(start,0)
if a then
a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
else
@@ -3553,7 +3555,7 @@ local function featuresprocessor(head,font,attr)
while start do
local char, id = ischar(start,font)
if char then
- local a = getattr(start,0)
+ local a = attr and getattr(start,0)
if a then
a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
else
diff --git a/tex/context/base/mkiv/font-sel.lua b/tex/context/base/mkiv/font-sel.lua
index c3431a213..4c80ff1fb 100644
--- a/tex/context/base/mkiv/font-sel.lua
+++ b/tex/context/base/mkiv/font-sel.lua
@@ -9,15 +9,16 @@ if not modules then modules = { } end modules ['font-sel'] = {
local context = context
local cleanname = fonts.names.cleanname
local gsub, splitup, find = string.gsub, string.splitup, string.find
+local concat, sortedkeys = table.concat, table.sortedkeys
+local merge, remove = table.merge, table.remove
local splitbase, removesuffix = file.splitbase, file.removesuffix
local splitat, lpegmatch = lpeg.splitat, lpeg.match
local formatters = string.formatters
local settings_to_array = utilities.parsers.settings_to_array
+local settings_to_hash = utilities.parsers.settings_to_hash
local v_yes = interfaces.variables.yes
-local v_simplefonts = interfaces.variables.simplefonts
-local v_selectfont = interfaces.variables.selectfont
local v_default = interfaces.variables.default
local implement = interfaces.implement
@@ -34,293 +35,67 @@ selectfont.fallbacks = fallbacks
local methods = selectfont.methods or { }
selectfont.methods = methods
-local getlookups = fonts.names.getlookups
-local registerdesignsizes = fonts.goodies.designsizes.register
-
-local alternatives = {
- ["tf"] = "regular",
- ["it"] = "italic",
- ["sl"] = "slanted",
- ["bf"] = "bold",
- ["bi"] = "bolditalic",
- ["bs"] = "boldslanted",
- ["sc"] = "smallcaps",
-}
-
-local styles = {
- ["rm"] = "serif",
- ["ss"] = "sans",
- ["tt"] = "mono",
- ["hw"] = "handwriting",
- ["cg"] = "calligraphy",
- ["mm"] = "math",
-}
-
-local sizes = {
- ["default"] = {
- { 40, "4pt" },
- { 50, "5pt" },
- { 60, "6pt" },
- { 70, "7pt" },
- { 80, "8pt" },
- { 90, "9pt" },
- { 100, "10pt" },
- { 110, "11pt" },
- { 120, "12pt" },
- { 144, "14.4pt" },
- { 173, "17.3pt" },
- },
- ["dtp"] = {
- { 50, "5pt" },
- { 60, "6pt" },
- { 70, "7pt" },
- { 80, "8pt" },
- { 90, "9pt" },
- { 100, "10pt" },
- { 110, "11pt" },
- { 120, "12pt" },
- { 130, "13pt" },
- { 140, "14pt" },
- { 160, "16pt" },
- { 180, "18pt" },
- { 220, "22pt" },
- { 280, "28pt" },
- }
-}
-
-local synonyms = {
- ["rm"] = {
- ["tf"] = "Serif",
- ["it"] = "SerifItalic",
- ["sl"] = "SerifSlanted",
- ["bf"] = "SerifBold",
- ["bi"] = "SerifBoldItalic",
- ["bs"] = "SerifBoldSlanted",
- ["sc"] = "SerifCaps",
- },
- ["ss"] = {
- ["tf"] = "Sans",
- ["it"] = "SansItalic",
- ["sl"] = "SansSlanted",
- ["bf"] = "SansBold",
- ["bi"] = "SansBoldItalic",
- ["bs"] = "SansBoldSlanted",
- ["sc"] = "SansCaps",
- },
- ["tt"] = {
- ["tf"] = "Mono",
- ["it"] = "MonoItalic",
- ["sl"] = "MonoSlanted",
- ["bf"] = "MonoBold",
- ["bi"] = "MonoBoldItalic",
- ["bs"] = "MonoBoldSlanted",
- ["sc"] = "MonoCaps",
- },
- ["hw"] = {
- ["tf"] = "Handwriting",
- },
- ["cg"] = {
- ["tf"] = "Calligraphy",
- },
- ["mm"] = {
- ["tf"] = "MathRoman",
- ["bf"] = "MathBold",
- }
-}
+local extras = selectfont.extras or { }
+selectfont.extras = extras
-local replacement = {
- ["style"] = {
- ["it"] = "tf",
- ["sl"] = "it",
- ["bf"] = "tf",
- ["bi"] = "bf",
- ["bs"] = "bi",
- ["sc"] = "tf",
- },
- ["weight"] = {
- ["it"] = "tf",
- ["sl"] = "tf",
- ["bf"] = "tf",
- ["bi"] = "bf",
- ["bs"] = "bf",
- ["sc"] = "tf",
- },
-}
+local alternatives = selectfont.alternatives or { }
+selectfont.alternatives = alternatives
-local names = {
- ["selectfont"] = { -- weight, style, width, variant, italic
- ["regular"] = { weight = "normal", style = "normal", width = "normal", variant = "normal", italic = false },
- ["italic"] = { weight = "normal", style = "italic", width = "normal", variant = "normal", italic = true },
- ["slanted"] = { weight = "normal", style = "slanted", width = "normal", variant = "normal", italic = true },
- ["medium"] = { weight = "medium", style = "normal", width = "normal", variant = "normal", italic = false },
- ["mediumitalic"] = { weight = "medium", style = "italic", width = "normal", variant = "normal", italic = true },
- ["mediumcaps"] = { weight = "medium", style = "normal", width = "normal", variant = "smallcaps", italic = true },
- ["bold"] = { weight = "bold", style = "normal", width = "normal", variant = "normal", italic = false },
- ["bolditalic"] = { weight = "bold", style = "italic", width = "normal", variant = "normal", italic = true },
- ["boldslanted"] = { weight = "bold", style = "slanted", width = "normal", variant = "normal", italic = true },
- ["smallcaps"] = { weight = "normal", style = "normal", width = "normal", variant = "smallcaps", italic = false },
- },
- ["simplefonts"] = {
- ["light"] = { "lightregular", "light" },
- ["lightitalic"] = { "lightitalic", "lightit", "lightoblique" },
- ["lightcaps"] = { "smallcapslight" },
- ["regular"] = { "roman", "regular", "book", "" },
- ["italic"] = { "italic", "it", "oblique", "kursiv", "bookitalic", "bookit" },
- ["medium"] = { "mediumregular", "medregular", "medium" },
- ["mediumitalic"] = { "mediumitalic", "meditalic" },
- ["mediumcaps"] = { "mediumcaps" },
- ["bold"] = { "bold", "bd", "kraeftig", "mediumregular", "semibold", "demi" },
- ["bolditalic"] = { "bolditalic", "boldit", "bdit", "boldoblique", "mediumitalic", "semibolditalic", "demiitalic" },
- ["smallcaps"] = { "smallcaps", "capitals", "sc" },
- ["heavy"] = { "heavyregular", "heavy" },
- ["heavyitalic"] = { "heavyitalic" },
- },
- ["default"] = { -- weight, width, italic
- ["thin"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = false },
- ["thinitalic"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = true },
- ["extralight"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = false },
- ["extralightitalic"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = true },
- ["light"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = false },
- ["lightitalic"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = true },
- ["regular"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = false },
- ["italic"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = true },
- ["medium"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = false },
- ["mediumitalic"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = true },
- ["demibold"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = false },
- ["demibolditalic"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = true },
- ["bold"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = false },
- ["bolditalic"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = true },
- ["extrabold"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = false },
- ["extrabolditalic"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = true },
- ["heavy"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = false },
- ["heavyitalic"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = true },
- }
-}
+local presets = selectfont.presets or { }
+selectfont.presets = presets
--- simplefonts synonyms
-
-names.simplefonts.slanted = names.simplefonts.italic
-names.simplefonts.boldslanted = names.simplefonts.bolditalic
-
--- default synonyms
-
-names.default.ultralight = names.default.extralight
-names.default.semibold = names.default.demibold
-names.default.ultrabold = names.default.extrabold
-names.default.black = names.default.heavy
-
-names.default.ultralightitalic = names.default.extralightitalic
-names.default.semibolditalic = names.default.demibolditalic
-names.default.ultrabolditalic = names.default.extrabolditalic
-names.default.blackitalic = names.default.heavyitalic
-
-names.default.thinslanted = names.default.thinitalic
-names.default.extralightslanted = names.default.extralightitalic
-names.default.ultralightslanted = names.default.extralightitalic
-names.default.lightslanted = names.default.lightitalic
-names.default.slanted = names.default.italic
-names.default.demiboldslanted = names.default.demibolditalic
-names.default.semiboldslanted = names.default.demibolditalic
-names.default.boldslanted = names.default.bolditalic
-names.default.extraboldslanted = names.default.extrabolditalic
-names.default.ultraboldslanted = names.default.extrabolditalic
-names.default.heavyslanted = names.default.heavyitalic
-names.default.blackslanted = names.default.heavyitalic
-
-names.default.smallcaps = names.default.regular
-
-local mathsettings = {
- ["asanamath"] = {
- extras = "asana-math",
- goodies = {
- ["tf"] = "anana-math",
- },
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
- ["cambriamath"] = {
- extras = "cambria-math",
- goodies = {
- ["tf"] = "cambria-math",
- },
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
- ["neoeuler"] = {
- extras = "euler-math",
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
- ["latinmodernmath"] = {
- extras = "lm,lm-math",
- goodies = {
- ["tf"] = "lm",
- },
- features = {
- ["tf"] = "math\\mathsizesuffix,lm-math",
- },
- },
- ["lucidabrightmathot"] = {
- extras = "lucida-opentype-math",
- goodies = {
- ["tf"] = "lucida-opentype-math",
- },
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
- ["texgyrepagellamath"] = {
- extras = "texgyre",
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
- ["texgyrebonummath"] = {
- extras = "texgyre",
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
- ["texgyretermesmath"] = {
- extras = "texgyre",
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
- ["xitsmath"] = {
- extras = "xits-math",
- goodies = {
- ["tf"] = "xits-math",
- },
- features = {
- ["tf"] = "math\\mathsizesuffix",
- },
- },
-}
+local defaults = selectfont.defaults or { }
+selectfont.defaults = defaults
-function selectfont.define(settings)
- local index = #data + 1
- data[index] = settings
- selectfont.searchfiles(index)
- selectfont.filterinput(index)
- return index
-end
-
-local function savefont(data,alternative,entries)
- local f = data.fonts
- if not f then
- f = { }
- data.fonts = f
- end
- f[alternative] = entries
-end
-
-local function savefeatures(data,alternative,entries)
- local e = gsub(entries,"{(.*)}","%1")
+local getlookups = fonts.names.getlookups
+local registerdesignsizes = fonts.goodies.designsizes.register
+local bodyfontsizes = storage.shared.bodyfontsizes
+
+local ctx_definefontsynonym = context.definefontsynonym
+local ctx_resetfontfallback = context.resetfontfallback
+local ctx_startfontclass = context.startfontclass
+local ctx_stopfontclass = context.stopfontclass
+local ctx_loadfontgoodies = context.loadfontgoodies
+local ctx_definefontfallback = context.definefontfallback
+local ctx_definetypeface = context.definetypeface
+local ctx_definebodyfont = context.definebodyfont
+
+local trace_register = false trackers.register("selectfont.register", function(v) trace_register = v end)
+local trace_files = false trackers.register("selectfont.files", function(v) trace_files = v end)
+local trace_features = false trackers.register("selectfont.features", function(v) trace_features = v end)
+local trace_goodies = false trackers.register("selectfont.goodies", function(v) trace_goodies = v end)
+local trace_alternatives = false trackers.register("selectfont.alternatives", function(v) trace_alternatives = v end)
+local trace_typescript = false trackers.register("selectfont.typescripts", function(v) trace_typescript = v end)
+
+local report_selectfont = logs.reporter("selectfont")
+local report_files = logs.reporter("selectfont","files")
+local report_features = logs.reporter("selectfont","features")
+local report_goodies = logs.reporter("selectfont","goodies")
+local report_alternatives = logs.reporter("selectfont","alternatives")
+local report_typescript = logs.reporter("selectfont","typescripts")
+
+defaults["rm"] = { features = { ["sc"] = "*,f:smallcaps" } }
+defaults["ss"] = { features = { ["sc"] = "*,f:smallcaps" } }
+
+defaults["asanamath"] = { options = { extras = "asana-math", features = "math\\mathsizesuffix", goodies = "anana-math" } }
+defaults["cambriamath"] = { options = { extras = "cambria-math", features = "math\\mathsizesuffix", goodies = "cambria-math" } }
+defaults["dejavumath"] = { options = { extras = "dejavu", features = "math\\mathsizesuffix" } }
+defaults["neoeuler"] = { options = { extras = "euler-math", features = "math\\mathsizesuffix" } }
+defaults["latinmodernmath"] = { options = { extras = "lm,lm-math", features = "math\\mathsizesuffix,lm-math", goodies = "lm" } }
+defaults["lucidabrightmathot"] = { options = { extras = "lucida-opentype-math", features = "math\\mathsizesuffix", goodies = "lucida-opentype-math" } }
+defaults["texgyrepagellamath"] = { options = { extras = "texgyre", features = "math\\mathsizesuffix" } }
+defaults["texgyrebonummath"] = { options = { extras = "texgyre", features = "math\\mathsizesuffix" } }
+defaults["texgyrescholamath"] = { options = { extras = "texgyre", features = "math\\mathsizesuffix" } }
+defaults["texgyretermesmath"] = { options = { extras = "texgyre", features = "math\\mathsizesuffix" } }
+defaults["xitsmath"] = { options = { extras = "xits-math", features = "math\\mathsizesuffix", goodies = "xits-math" } }
+
+extras["features"] = function(data,alternative,features)
+ local d = data.options.features
+ local e = gsub(gsub(features,"*",d),"{(.*)}","%1")
local f = data.features
+ if trace_features then
+ report_features("Alternative '%s': Saving features '%s'",alternative,e)
+ end
if not f then
f = { }
data.features = f
@@ -328,443 +103,824 @@ local function savefeatures(data,alternative,entries)
f[alternative] = e
end
-local function savegoodies(data,alternative,entries)
- local e = gsub(entries,"{(.*)}","%1")
+extras["goodies"] = function(data,alternative,goodies)
+ local e = gsub(goodies,"{(.*)}","%1")
local g = data.goodies
- if not f then
+ if trace_goodies then
+ report_goodies("Alternative '%s': Saving goodies '%s'",alternative,e)
+ end
+ if not g then
g = { }
data.goodies = g
end
g[alternative] = e
end
-methods[v_simplefonts] = function(data,alternative,style)
- local family = data.metadata.family
- local names = names["simplefonts"][style] or names["simplefonts"]["regular"]
- for _, name in next, names do
- local filename = cleanname(formatters["%s%s"](family,name))
- local fullname = getlookups{ fullname = filename }
- local fontname = getlookups{ fontname = filename }
- local cleanfilename = getlookups{ cleanfilename = filename }
- if #fullname > 0 then
- savefont(data,alternative,fullname)
- break
- elseif #fontname > 0 then
- savefont(data,alternative,fontname)
- break
- elseif #cleanfilename > 0 then
- savefont(data,alternative,cleanfilename)
- break
- end
+local function selectfont_savefile(data,alternative,bodyfontsize,size,file)
+ local f = data.files
+ local p, n = splitbase(file["filename"])
+ local t = file["format"]
+ local r = file["rawname"]
+ if t == "ttc" then
+ n = formatters["%s(%s)"](n,r)
end
-end
-
-methods[v_default] = function(data,alternative,style)
- local family = data.metadata.family
- local spec = names["default"][style] or names["default"]["regular"]
- local weights = spec["weight"]
- for _, weight in next, weights do
- local pattern = getlookups{
- familyname = cleanname(family),
- pfmweight = weight,
- pfmwidth = spec["width"],
- }
- if #pattern > 0 then
- local fontfiles = { }
- for _, fontfile in next, pattern do
- if (fontfile["angle"] and spec["italic"] == true) or (not fontfile["angle"] and spec["italic"] == false) then
- fontfiles[#fontfiles + 1] = fontfile
- end
- end
- savefont(data,alternative,fontfiles)
- break
- end
+ if not f then
+ f = { }
+ data.files = f
end
-end
-
-methods[v_selectfont] = function(data,alternative,style)
- local family = data.metadata.family
- local spec = names["selectfont"][style] or names["selectfont"]["regular"]
- local pattern = getlookups{
- familyname = cleanname(family),
- weight = spec["weight"],
- style = spec["style"],
- width = spec["width"],
- variant = spec["variant"]
- }
- if #pattern > 0 then
- local fontfiles = { }
- for _, fontfile in next, pattern do
- if (fontfile["angle"] and spec["italic"] == true) or (not fontfile["angle"] and spec["italic"] == false) then
- fontfiles[#fontfiles + 1] = fontfile
- end
- end
- savefont(data,alternative,fontfiles)
+ local a = f[alternative]
+ if not a then
+ a = { }
+ f[alternative] = a
+ end
+ a[bodyfontsize] = { size, n }
+ if trace_files then
+ report_files("Alternative '%s': Saving file '%s' for size '%s'",alternative,n,size)
end
end
-methods["name"] = function(data,alternative,filename)
- local data = data
+methods["name"] = function(data,alternative,name)
local family = data.metadata.family
- local filename = cleanname(gsub(filename,"*",family))
- local fullname = getlookups{ fullname = filename }
+ local filename = cleanname(gsub(name,"*",family))
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': Using method 'name' with argument '%s'",alternative,filename)
+ end
local fontname = getlookups{ fontname = filename }
- if #fullname > 0 then
- savefont(data,alternative,fullname)
- elseif #fontname > 0 then
- savefont(data,alternative,fontname)
+ local fullname = getlookups{ fullname = filename }
+ if #fontname > 0 then
+ selectfont_savefile(data,alternative,0,"default",fullname[1])
+ elseif #fullname > 0 then
+ selectfont_savefile(data,alternative,0,"default",fontname[1])
+ else
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': No font was found for the requested name '%s'",alternative,filename)
+ end
end
end
-methods["file"] = function(data,alternative,filename)
- local data = data
+methods["file"] = function(data,alternative,file)
local family = data.metadata.family
- local filename = gsub(removesuffix(filename),"*",family)
+ local filename = cleanname(gsub(removesuffix(file),"*",family))
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': Using method 'file' with argument '%s'",alternative,filename)
+ end
local filename = getlookups{ cleanfilename = cleanname(filename) }
if #filename > 0 then
- savefont(data,alternative,filename)
+ selectfont_savefile(data,alternative,0,"default",filename[1])
+ else
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': No font was found for the requested file '%s'",alternative,cleanname(gsub(removesuffix(file),"*",family)))
+ end
end
end
-methods["spec"] = function(data,alternative,filename)
- local family = data.metadata.family
- local weight, style, width, variant = splitup(filename,"-")
- local pattern = getlookups{
- familyname = cleanname(family),
- weight = weight or "normal",
- style = style or "normal",
- width = width or "normal",
- variant = variant or "normal",
- }
- if #pattern > 0 then
- savefont(data,alternative,pattern)
- end
-end
+local m_weight = {
+ ["thin"] = 100,
+ ["extralight"] = 200,
+ ["light"] = 300,
+ ["regular"] = 400,
+ ["medium"] = 500,
+ ["semibold"] = 600,
+ ["bold"] = 700,
+ ["extrabold"] = 800,
+ ["black"] = 900
+}
-methods["style"] = function(data,alternative,style)
- local method = data.options.alternative or nil
- (methods[method] or methods[v_default])(data,alternative,style)
-end
+local m_width = {
+ ["ultracondensed"] = 1,
+ ["extracondensed"] = 2,
+ ["condensed"] = 3,
+ ["semicondensed"] = 4,
+ ["normal"] = 5,
+ ["semiexpanded"] = 6,
+ ["expanded"] = 7,
+ ["extraexpanded"] = 8,
+ ["ultraexpanded"] = 9,
+}
-methods["features"] = function(data,alternative,features)
- savefeatures(data,alternative,features)
-end
+local m_name = {
+ ["thin"] = { weight = "thin" },
+ ["thinitalic"] = { weight = "thin", style = "italic" },
+ ["extralight"] = { weight = "extralight" },
+ ["extralightitalic"] = { weight = "extralight", style = "italic" },
+ ["light"] = { weight = "light" },
+ ["lightitalic"] = { weight = "light", style = "italic" },
+ ["regular"] = { weight = { "regular", "medium" } },
+ ["italic"] = { weight = { "regular", "medium" }, style = "italic" },
+ ["medium"] = { weight = "medium" },
+ ["mediumitalic"] = { weight = "medium", style = "italic" },
+ ["semibold"] = { weight = "semibold" },
+ ["semibolditalic"] = { weight = "semibold", style = "italic" },
+ ["bold"] = { weight = { "bold", "semibold" } },
+ ["bolditalic"] = { weight = { "bold", "semibold" }, style = "italic" },
+ ["extrabold"] = { weight = "extrabold" },
+ ["extrabolditalic"] = { weight = "extrabold", style = "italic" },
+ ["black"] = { weight = "black" },
+ ["blackitalic"] = { weight = "black", style = "italic" },
+ ["smallcaps"] = { weight = "regular", variant = "smallcaps" },
+}
-methods["goodies"] = function(data,alternative,goodies)
- savegoodies(data,alternative,goodies)
+local m_alternative = {
+ ["tf"] = "regular",
+ ["bf"] = "bold",
+ ["it"] = "italic",
+ ["sl"] = "italic",
+ ["bi"] = "bolditalic",
+ ["bs"] = "bolditalic",
+ ["sc"] = "regular"
+}
+
+--~ methods["style"] = function(data,alternative,style)
+--~ local family = data.metadata.family
+--~ local style = m_alternative[style] or style
+--~ if trace_alternatives then
+--~ report_selectfont("Alternative '%s': Using method 'style' with argument '%s'",alternative,style)
+--~ end
+--~ local fontweight = m_name[style] and m_name[style]["weight"] or "regular"
+--~ local fontstyle = m_name[style] and m_name[style]["style"] or "normal"
+--~ local fontwidth = m_name[style] and m_name[style]["width"] or "normal"
+--~ local pattern = getlookups{
+--~ familyname = cleanname(family),
+--~ pfmweight = m_weight[fontweight],
+--~ style = fontstyle
+--~ }
+--~ if #pattern == 1 then
+--~ selectfont_savefile(data,alternative,0,"default",pattern[1])
+--~ elseif #pattern > 1 then
+--~ local bodyfontsize, minsize, maxsize, width = nil, nil, nil, nil
+--~ for patternindex, patternentry in next, pattern do
+--~ minsize = patternentry["minsize"]
+--~ maxsize = patternentry["maxsize"]
+--~ width = patternentry["pfmwidth"]
+--~ if minsize and maxsize then
+--~ for fontsize, fontstate in next, bodyfontsizes do
+--~ bodyfontsize, _ = number.splitdimen(fontsize)
+--~ bodyfontsize = bodyfontsize * 10
+--~ if minsize < bodyfontsize and bodyfontsize < maxsize then
+--~ if bodyfontsize == 100 then
+--~ selectfont_savefile(data,alternative,0,"default",patternentry)
+--~ end
+--~ selectfont_savefile(data,alternative,bodyfontsize,fontsize,patternentry)
+--~ end
+--~ end
+--~ else
+--~ if width == m_width[fontwidth] then
+--~ selectfont_savefile(data,alternative,0,"default",patternentry)
+--~ end
+--~ end
+--~ end
+--~ else
+--~ if trace_alternatives then
+--~ report_selectfont("Alternative '%s': No font was found for the requested style '%s' from '%s'",alternative,style,family)
+--~ end
+--~ end
+--~ end
+
+local function m_style_family(family)
+ local askedname = cleanname(family)
+ local familyname = getlookups{ familyname = askedname }
+ local family = getlookups{ family = askedname }
+ local fontname = getlookups{ fontname = askedname }
+ if #familyname > 0 then
+ return familyname
+ elseif #family > 0 then
+ return family
+ elseif #fontname > 0 then
+ local fontfamily = fontname[1]["familyname"]
+ report_selectfont("The name '%s' is not a proper family name, use '%s' instead.",askedname,fontfamily)
+ return nil
+ else
+ return nil
+ end
end
-function selectfont.searchfiles(index)
- local data = data[index]
- for alternative, _ in next, alternatives do
- local filename = data.files[alternative]
- local method = data.options.alternative
- local family = data.metadata.family
- local style = alternatives[alternative]
- if filename == "" then
- local pattern = getlookups{ familyname = cleanname(family) }
- if #pattern == 1 and alternative == "tf" then -- needs to be improved
- savefont(data,alternative,pattern)
- else
- (methods[method] or methods[v_default])(data,alternative,style)
+local function m_style_weight(entries,style)
+ local t = { }
+ local weight = m_name[style] and m_name[style]["weight"] or "regular"
+ if type(weight) == "table" then
+ for _, w in next, weight do
+ local found = false
+ local pfmweight = m_weight[w]
+ for index, entry in next, entries do
+ if entry["pfmweight"] == pfmweight then
+ found = true
+ t[#t+1] = entry
+ elseif entry["weight"] == w then
+ found = true
+ t[#t+1] = entry
+ end
end
- else
- method, filename = splitup(filename,":")
- if not filename then
- filename = method
- method = "name"
+ if found then break end
+ end
+ else
+ local pfmweight = m_weight[weight]
+ for index, entry in next, entries do
+ if entry["pfmweight"] == pfmweight then
+ t[#t+1] = entry
+ elseif entry["weight"] == weight then
+ t[#t+1] = entry
end
- (methods[method] or methods["name"])(data,alternative,filename)
end
end
+ return #t ~= 0 and t or nil
end
-function selectfont.filterinput(index)
- local data = data[index]
- local p = splitat(":",true)
- for alternative, _ in next, alternatives do
- local list = settings_to_array(data.alternatives[alternative])
- for _, entry in next, list do
- method, entries = lpegmatch(p,entry)
- if not entries then
- entries = method
- method = "name"
- end
- (methods[method] or methods["name"])(data,alternative,entries)
+local function m_style_style(entries,style)
+ local t = { }
+ local style = m_name[style] and m_name[style]["style"] or "normal"
+ for index, entry in next, entries do
+ if style == "italic" and entry["angle"] and entry["angle"] ~= 0 then
+ t[#t+1] = entry
+ elseif style == "normal" and entry["angle"] and entry["angle"] ~= 0 then
+ --~ Fix needed for fonts with wrong value for the style field
+ elseif entry["style"] == style then
+ t[#t+1] = entry
end
end
+ return #t ~= 0 and t or nil
end
-local ctx_definefontsynonym = context.definefontsynonym
-local ctx_resetfontfallback = context.resetfontfallback
-local ctx_startfontclass = context.startfontclass
-local ctx_stopfontclass = context.stopfontclass
-local ctx_loadfontgoodies = context.loadfontgoodies
-local ctx_definefontfallback = context.definefontfallback
-local ctx_definetypeface = context.definetypeface
-
-local function definefontsynonym(data,alternative,index,fallback)
- local fontdata = data.fonts and data.fonts[alternative]
- local style = data.metadata.style
- local typeface = data.metadata.typeface
- local mathsettings = mathsettings[cleanname(data.metadata.family)]
- local features = mathsettings and mathsettings["features"] and (mathsettings["features"][alternative] or mathsettings["features"]["tf"]) or data.features and data.features[alternative] or ""
- local goodies = mathsettings and mathsettings["goodies"] and (mathsettings["goodies"] [alternative] or mathsettings["goodies"] ["tf"]) or data.goodies and data.goodies [alternative] or ""
- local parent = replacement["style"][alternative] or ""
- local fontname, fontfile, fontparent
- if fallback then
- fontname = formatters["%s-%s-%s-fallback-%s"](typeface, style, alternative, index)
- fontfile = formatters["%s-%s-%s-%s"] (typeface, style, alternative, index)
- fontparent = formatters["%s-%s-%s-fallback-%s"](typeface, style, parent, index)
+local function m_style_variant(entries,style)
+ local t = { }
+ local variant = m_name[style] and m_name[style]["variant"] or "normal"
+ for index, entry in next, entries do
+ if entry["variant"] == variant then
+ t[#t+1] = entry
+ end
+ end
+ return #t ~= 0 and t or nil
+end
+
+local function m_style_width(entries,style)
+ local t = { }
+ local width = m_name[style] and m_name[style]["width"] or "normal"
+ local pfmwidth = m_width[width]
+ for index, entry in next, entries do
+ if entry["pfmwidth"] == pfmwidth then
+ t[#t+1] = entry
+ end
+ end
+ return #t ~= 0 and t or nil
+end
+
+local function m_style_size(data,alternative,entries)
+ if #entries == 1 then
+ selectfont_savefile(data,alternative,0,"default",entries[1])
else
- fontname = synonyms[style][alternative]
- fontfile = formatters["%s-%s-%s"](typeface, style, alternative)
- fontparent = formatters["%s-%s-%s"](typeface, style, parent)
- end
- if fontdata and #fontdata > 0 then
- for _, size in next, sizes["default"] do
- for _, entry in next, fontdata do
- if entry["minsize"] and entry["maxsize"] then
- if size[1] > entry["minsize"] and size[1] <= entry["maxsize"] then
- local filepath, filename = splitbase(entry["filename"])
- registerdesignsizes( fontfile, size[2], filename )
+ for index, entry in next, entries do
+ local minsize = entry["minsize"]
+ local maxsize = entry["maxsize"]
+ if minsize and maxsize then
+ for size, state in next, bodyfontsizes do
+ local bodyfontsize, _ = number.splitdimen(size)
+ bodyfontsize = bodyfontsize * 10
+ if minsize < bodyfontsize and bodyfontsize < maxsize then
+ if bodyfontsize == 100 then
+ selectfont_savefile(data,alternative,0,"default",entry)
+ end
+ selectfont_savefile(data,alternative,bodyfontsize,size,entry)
end
end
+ else
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': Multiple files are available for the requested style '%s' from '%s'",alternative,style,family)
+ end
end
end
- for _, entry in next, fontdata do
- local designsize = entry["designsize"] or 100
- if designsize == 100 or designsize == 110 or designsize == 120 or designsize == 0 or #fontdata == 1 then
- local filepath, filename = splitbase(entry["filename"])
- if entry["format"] == "ttc" or entry["format"] == "dfont" then
- filename = formatters["%s(%s)"](filename, entry["rawname"])
+ end
+end
+
+methods["style"] = function(data,alternative,style)
+ local fontfamily = data.metadata.family
+ local designsize = data.options.designsize
+ local fontstyle = m_alternative[style] or style
+ local entries = m_style_family(fontfamily)
+ if entries then
+ entries = m_style_weight(entries,fontstyle)
+ if entries then
+ entries = m_style_style(entries,fontstyle)
+ if entries then
+ entries = m_style_variant(entries,fontstyle)
+ if entries and #entries > 1 and designsize == "default" then
+ entries = m_style_width(entries,fontstyle)
end
- registerdesignsizes( fontfile, "default", filename )
- break
end
end
- if fallback then
- -- can we use
- ctx_definefontsynonym( { fontname }, { fontfile }, { features = features } )
- else
- ctx_definefontsynonym( { fontname }, { fontfile }, { features = features, fallbacks = fontfile, goodies = goodies } )
+ end
+ if entries then
+ m_style_size(data,alternative,entries)
+ else
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': No font was found for the requested style '%s' from '%s'",alternative,style,family)
+ end
+ end
+end
+
+methods[v_default] = function(data,alternative)
+ local family = data.metadata.family
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': Using method 'default'",alternative)
+ end
+ local result = getlookups{ familyname = cleanname(family) }
+ if #result == 1 and alternative == "tf" then
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': The family '%s' contains only one font",alternative,family)
end
+ selectfont_savefile(data,alternative,0,"default",result[1])
+ --~ if trace_alternatives then
+ --~ report_selectfont("Alternative '%s': Changing method 'default' to method 'style'",alternative)
+ --~ end
+ --~ methods["file"](data,alternative,result[1]["filename"])
else
- if fallback then
- ctx_definefontsynonym( { fontname }, { fontparent }, { features = features } )
- else
- ctx_definefontsynonym( { fontname }, { fontparent }, { features = features, fallbacks = fontfile, goodies = goodies } )
+ if trace_alternatives then
+ report_selectfont("Alternative '%s': Changing method 'default' to method 'style'",alternative)
end
+ methods["style"](data,alternative,alternative)
+ end
+end
+
+local function selectfont_savealternative(data,alternative,userdata)
+ local a = data.alternatives
+ local e = userdata[alternative]
+ if not a then
+ a = { }
+ data.alternatives = a
end
+ a[alternative] = e
end
-local function definetypescript(index)
- local data = data[index]
- local entry = data.fonts
- local mathsettings = mathsettings[cleanname(data.metadata.family)]
- local goodies = mathsettings and mathsettings.extras or data.options.goodies
- local typeface = data.metadata.typeface
- local style = data.metadata.style
- if entry and entry["tf"] then
- ctx_startfontclass( { typeface } )
- if goodies ~= "" then
- goodies = utilities.parsers.settings_to_array(goodies)
- for _, goodie in next, goodies do
- ctx_loadfontgoodies( { goodie } )
+function selectfont.fontdata(index)
+ local data = data[index]
+ local style = data.metadata.style
+ local defaults = defaults[style]
+ if defaults then
+ for category, argument in next, defaults do
+ local extra = extras[category]
+ if extra then
+ for alternative, entry in next, argument do
+ extra(data,alternative,entry)
+ end
end
end
- for alternative, _ in next, alternatives do
- if synonyms[style][alternative] then -- prevent unnecessary synonyms for handwriting, calligraphy and math
- definefontsynonym(data,alternative)
+ end
+end
+
+function selectfont.userdata(index)
+ local data = data[index]
+ local preset = data.options.preset
+ local presets = presets[preset]
+ local userdata = settings_to_hash(data.userdata)
+ if presets then
+ merge(userdata,presets)
+ end
+ for alternative, _ in next, alternatives do
+ selectfont_savealternative(data,alternative,userdata)
+ end
+end
+
+--~ function selectfont.registerfiles(index)
+--~ local data = data[index]
+--~ local colon = splitat(":",true)
+--~ for alternative, _ in next, alternatives do
+--~ local arguments = data.alternatives[alternative]
+--~ if arguments ~= "" then
+--~ local entries = settings_to_array(arguments)
+--~ local setmethod = false
+--~ for index, entry in next, entries do
+--~ method, argument = lpegmatch(colon,entry)
+--~ if not argument then
+--~ argument = method
+--~ method = "name"
+--~ end
+--~ if extras[method] then
+--~ extras[method](data,alternative,argument)
+--~ elseif methods[method] then
+--~ if not setmethod then
+--~ setmethod = true
+--~ methods[method](data,alternative,argument)
+--~ end
+--~ end
+--~ end
+--~ if not setmethod then
+--~ methods[v_default](data,alternative)
+--~ end
+--~ else
+--~ methods[v_default](data,alternative)
+--~ end
+--~ end
+--~ end
+
+function selectfont.registerfiles(index)
+ local data = data[index]
+ local colon = splitat(":",true)
+ for alternative, _ in next, alternatives do
+ local arguments = data.alternatives[alternative]
+ if arguments and arguments ~= "" then
+ local entries = settings_to_array(arguments)
+ for index, entry in next, entries do
+ method, argument = lpegmatch(colon,entry)
+ if not argument then
+ argument = method
+ method = "name"
+ end
+ (extras[method] or methods[method] or methods[v_default])(data,alternative,argument)
end
+ else
+ methods[v_default](data,alternative)
end
- ctx_stopfontclass()
+ end
+end
+
+function selectfont.registerfontalternative(alternative)
+ local a = alternatives[alternative]
+ if not a then
+ if trace_register then
+ report_selectfont("Register alternative '%s'",alternative)
+ end
+ a = true
+ alternatives[alternative] = a
+ end
+end
+
+function selectfont.registerfallback(index)
+ local data = data[index]
+ local fontclass = data.metadata.typeface
+ local fontstyle = data.metadata.style
+ local fallback = fallbacks[fontclass]
+ if not fallback then
+ fallback = { }
+ fallbacks[fontclass] = fallback
+ end
+ local entries = fallback[fontstyle]
+ if not entries then
+ entries = { }
+ fallback[fontstyle] = entries
+ end
+ entries[#entries+1] = index
+end
+
+function selectfont.registerfontfamily(settings)
+ local index = #data + 1
+ data[index] = settings
+ selectfont.fontdata (index)
+ selectfont.userdata (index)
+ selectfont.registerfiles(index)
+ return index
+end
+
+local m_synonym = {
+ ["rm"] = {
+ ["tf"] = "Serif",
+ ["bf"] = "SerifBold",
+ ["it"] = "SerifItalic",
+ ["sl"] = "SerifSlanted",
+ ["bi"] = "SerifBoldItalic",
+ ["bs"] = "SerifBoldSlanted",
+ ["sc"] = "SerifCaps",
+ },
+ ["ss"] = {
+ ["tf"] = "Sans",
+ ["bf"] = "SansBold",
+ ["it"] = "SansItalic",
+ ["sl"] = "SansSlanted",
+ ["bi"] = "SansBoldItalic",
+ ["bs"] = "SansBoldSlanted",
+ ["sc"] = "SansCaps",
+ },
+ ["tt"] = {
+ ["tf"] = "Mono",
+ ["bf"] = "MonoBold",
+ ["it"] = "MonoItalic",
+ ["sl"] = "MonoSlanted",
+ ["bi"] = "MonoBoldItalic",
+ ["bs"] = "MonoBoldSlanted",
+ ["sc"] = "MonoCaps",
+ },
+ ["mm"] = {
+ ["tf"] = "MathRoman",
+ ["bf"] = "MathBold",
+ },
+ ["hw"] = {
+ ["tf"] = "Handwriting",
+ },
+ ["cg"] = {
+ ["tf"] = "Calligraphy",
+ },
+}
+
+function selectfont.features(data,style,alternative)
+ local family = data.metadata.family
+ local features = data.features
+ local options = data.options
+ local defaults = defaults[cleanname(family)]
+ if features and features[alternative] then
+ return features[alternative]
+ elseif defaults and defaults.options and defaults.options.features then
+ return defaults.options.features
else
- -- regular style not available, loading aborted
+ return options.features
end
end
-function selectfont.registerfallback(typeface,style,index)
- local t = fallbacks[typeface]
- if not t then
- fallbacks[typeface] = { [style] = { index } }
+function selectfont.goodies(data,style,alternative)
+ local family = data.metadata.family
+ local goodies = data.goodies
+ local options = data.options
+ local defaults = defaults[cleanname(family)]
+ if goodies and goodies[alternative] then
+ return goodies[alternative]
+ elseif defaults and defaults.options and defaults.options.goodies then
+ return defaults.options.goodies
else
- local s = t[style]
- if not s then
- fallbacks[typeface][style] = { index }
- else
- fallbacks[typeface][style][#s+1] = index
+ return options.goodies
+ end
+end
+
+function selectfont.fontsynonym(data,class,style,alternative,index)
+ local fontfiles = data.files[alternative] or data.files["tf"]
+ local fontsizes = sortedkeys(fontfiles)
+ local fallback = index ~= 0
+ --~ local fontfeature = data.features and data.features[alternative] or data.options.features
+ --~ local fontgoodie = data.goodies and data.goodies [alternative] or data.options.goodies
+ local fontfeature = selectfont.features(data,style,alternative)
+ local fontgoodie = selectfont.goodies (data,style,alternative)
+ local synonym = m_synonym[style] and m_synonym[style][alternative]
+ local fontfile = formatters ["file-%s-%s-%s"](class,style,alternative)
+ local fontsynonym = formatters ["synonym-%s-%s-%s"](class,style,alternative)
+ if fallback then
+ fontfile = formatters ["file-%s-%s-%s-%s"](class,style,alternative,index)
+ fontsynonym = formatters ["synonym-%s-%s-%s-%s"](class,style,alternative,index)
+ end
+ local fontfallback = formatters["fallback-%s-%s-%s"](class,style,alternative)
+ for _, fontsize in next, fontsizes do
+ --~ if trace_typescript then
+ --~ report_typescript("Synonym: '%s', Size: '%s', File: '%s'",fontfile,fontfiles[fontsize][1],fontfiles[fontsize][2])
+ --~ end
+ registerdesignsizes(fontfile,fontfiles[fontsize][1],fontfiles[fontsize][2])
+ end
+ if fallback then
+ --~ if trace_typescript then
+ --~ report_typescript("Synonym: '%s', File: '%s', Features: '%s'",fontsynonym,fontfile,fontfeature)
+ --~ end
+ ctx_definefontsynonym( { fontsynonym }, { fontfile }, { features = fontfeature } )
+ else
+ --~ if trace_typescript then
+ --~ report_typescript("Synonym: '%s', File: '%s', Features: '%s', Goodies: '%s', Fallbacks: '%s'",fontsynonym,fontfile,fontfeature,fontgoodie,fontfallback)
+ --~ end
+ ctx_definefontsynonym( { fontsynonym }, { fontfile }, { features = fontfeature, goodies = fontgoodie, fallbacks = fontfallback } )
+ if synonym then
+ --~ if trace_typescript then
+ --~ report_typescript("Synonym: '%s', File: '%s'",synonym,fontsynonym)
+ --~ end
+ ctx_definefontsynonym( { synonym }, { fontsynonym } )
end
end
end
-local function definetextfontfallback(data,alternative,index)
- local typeface = data.metadata.typeface
- local style = data.metadata.style
- local features = data.features[alternative]
- local range = data.options.range
- local rscale = data.options.scale ~= "" and data.options.scale or 1
- local check = data.options.check ~= "" and data.options.check or "yes"
- local force = data.options.force ~= "" and data.options.force or "yes"
- local synonym = formatters["%s-%s-%s-fallback-%s"](typeface, style, alternative, index)
- local fallback = formatters["%s-%s-%s"] (typeface, style, alternative)
+function selectfont.fontfallback(data,class,style,alternative,index)
+ local range = data.options.range
+ local scale = data.options.rscale ~= "" and data.options.rscale or 1
+ local check = data.options.check ~= "" and data.options.check or "yes"
+ local force = data.options.force ~= "" and data.options.force or "no"
+ local fontfeature = data.features and data.features[alternative] or data.options.features
+ local fontsynonym = formatters["synonym-%s-%s-%s-%s"](class,style,alternative,index)
+ local fontfallback = formatters["fallback-%s-%s-%s"] (class,style,alternative)
if index == 1 then
- ctx_resetfontfallback( { fallback } )
+ ctx_resetfontfallback( { fontfallback } )
end
- ctx_definefontfallback( { fallback }, { synonym }, { range }, { rscale = rscale, check = check, force = force } )
+ --~ if trace_typescript then
+ --~ report_typescript("Fallback: '%s', Synonym: '%s', Range: '%s', Scale: '%s', Check: '%s', Force: '%s'",fontfallback,fontsynonym,range,scale,check,force)
+ --~ end
+ ctx_definefontfallback( { fontfallback }, { fontsynonym }, { range }, { rscale = scale, check = check, force = force } )
end
-local function definetextfallback(entry,index)
- local data = data[index]
- local typeface = data.metadata.typeface
- ctx_startfontclass( { typeface } )
- for alternative, _ in next, alternatives do
- definefontsynonym (data,alternative,entry,true)
- definetextfontfallback(data,alternative,entry)
+function selectfont.filefallback(data,class,style,alternative,index)
+ local range = data.options.range
+ local offset = data.options.offset
+ local scale = data.options.rscale ~= "" and data.options.rscale or 1
+ local check = data.options.check ~= "" and data.options.check or "yes"
+ local force = data.options.force ~= "" and data.options.force or "yes"
+ local fontfile = data.files[alternative] and data.files[alternative][0] or data.files["tf"][0]
+ local fontfeature = data.features and data.features[alternative] or data.options.features
+ local fontfallback = formatters["fallback-%s-%s-%s"](class,style,alternative)
+ if index == 1 then
+ ctx_resetfontfallback( { fontfallback } )
end
+ --~ if trace_typescript then
+ --~ report_typescript("Fallback: '%s', File: '%s', Features: '%s', Range: '%s', Scale: '%s', Check: '%s', Force: '%s', Offset: '%s'",fontfallback,fontfile[2],fontfeature,range,scale,check,force,offset)
+ --~ end
+ ctx_definefontfallback( { fontfallback }, { formatters["file:%s*%s"](fontfile[2],fontfeature) }, { range }, { rscale = scale, check = check, force = force, offset = offset } )
+end
+
+function selectfont.mathfallback(index,entry,class,style)
+ local data = data[entry]
+ ctx_startfontclass( { class } )
+ for alternative, _ in next, alternatives do
+ if alternative == "tf" or alternative == "bf" then
+ selectfont.filefallback(data,class,style,alternative,index)
+ end
+ end
ctx_stopfontclass()
- -- inspect(data)
end
-local function definemathfontfallback(data,alternative,index)
- local typeface = data.metadata.typeface
- local style = data.metadata.style
- local range = data.options.range
- local rscale = data.options.scale ~= "" and data.options.scale or 1
- local check = data.options.check ~= "" and data.options.check or "yes"
- local force = data.options.force ~= "" and data.options.force or "yes"
- local offset = data.options.offset
- local features = data.features[alternative]
- local fontdata = data.fonts and data.fonts[alternative]
- local fallback = formatters["%s-%s-%s"](typeface, style, alternative)
- if index == 1 then
- ctx_resetfontfallback( { fallback } )
- end
- if fontdata and #fontdata > 0 then
- for _, entry in next, fontdata do
- local filename = entry["filename"]
- local designsize = entry["designsize"] or 100
- if designsize == 100 or designsize == 110 or designsize == 120 or designsize == 0 or #fontdata == 1 then
- ctx_definefontfallback( { fallback }, { formatters["file:%s*%s"](filename,features) }, { range }, { rscale = rscale, check = check, force = force, offset = offset } )
- break
+function selectfont.textfallback(index,entry,class,style)
+ local data = data[entry]
+ ctx_startfontclass( { class } )
+ for alternative, _ in next, alternatives do
+ selectfont.fontsynonym (data,class,style,alternative,index)
+ selectfont.fontfallback(data,class,style,alternative,index)
+ end
+ ctx_stopfontclass()
+end
+
+function selectfont.fallback(data)
+ local fontclass = data.metadata.typeface
+ local fontstyle = data.metadata.style
+ local fallbacks = fallbacks[fontclass] and fallbacks[fontclass][fontstyle]
+ if fallbacks then
+ for index, entry in next, fallbacks do
+ --~ I need different fallback routines for math and text because
+ --~ font synonyms can’t be used with math fonts and I have to apply
+ --~ feature settings with the \definefontfallback command.
+ if fontstyle == "mm" then
+ selectfont.mathfallback(index,entry,fontclass,fontstyle)
+ else
+ selectfont.textfallback(index,entry,fontclass,fontstyle)
end
end
end
end
-local function definemathfallback(entry,index)
- local data = data[index]
- local typeface = data.metadata.typeface
+function selectfont.typescript(data)
+ local class = data.metadata.typeface
+ local family = data.metadata.family
local style = data.metadata.style
- ctx_startfontclass( { typeface } )
- for alternative, _ in next, alternatives do
- if synonyms[style][alternative] then
- definemathfontfallback(data,alternative,entry)
- end
+ local extras = data.options.extras
+ local defaults = defaults[cleanname(family)]
+ if extras == "" then
+ extras = defaults and defaults.options and defaults.options.extras or ""
end
- ctx_stopfontclass()
- -- inspect(data)
-end
-
-local function definefallbackfont(index)
- local data = data[index]
- local f = fallbacks[data.metadata.typeface]
- if f then
- local s = f[data.metadata.style]
- if s then
- for entry, fallback in next, s do
- if data.metadata.style == "mm" then
- definemathfallback(entry,fallback)
- else
- definetextfallback(entry,fallback)
+ ctx_startfontclass( { class } )
+ if extras ~= "" then
+ extras = settings_to_array(extras)
+ for _, extra in next, extras do
+ ctx_loadfontgoodies( { extra } )
+ end
+ end
+ for alternative, _ in next, alternatives do
+ if style == "mm" then -- Set math fonts only for upright and bold alternatives
+ if alternative == "tf" or alternative == "bf" then
+ selectfont.fontsynonym (data,class,style,alternative,0)
end
+ else
+ selectfont.fontsynonym (data,class,style,alternative,0)
end
end
+ ctx_stopfontclass()
+end
+
+function selectfont.bodyfont(data)
+ local fontclass = data.metadata.typeface
+ local fontstyle = data.metadata.style
+ local fontsizes = concat(sortedkeys(bodyfontsizes),",")
+ local fontsynonym = nil
+ local fontlist = { }
+ for alternative, _ in next, alternatives do
+ fontsynonym = formatters["synonym-%s-%s-%s"](fontclass,fontstyle,alternative)
+ fontlist[#fontlist+1] = formatters["%s=%s sa 1"] (alternative,fontsynonym)
+ --~ if trace_typescript then
+ --~ report_typescript("Alternative '%s': Synonym '%s'",alternative,fontsynonym)
+ --~ end
+ end
+ fontlist = concat(fontlist,",")
+ ctx_definebodyfont( { fontclass }, { fontsizes }, { fontstyle }, { fontlist } )
+end
+
+local m_style = {
+ ["rm"] = "serif",
+ ["ss"] = "sans",
+ ["tt"] = "mono",
+ ["mm"] = "math",
+ ["hw"] = "handwriting",
+ ["cg"] = "calligraphy",
+}
+
+function selectfont.typeface(data)
+ local fontclass = data.metadata.typeface
+ local fontstyle = data.metadata.style
+ local style = m_style[fontstyle]
+ local size = data.options.designsize ~= "" and data.options.designsize or "default"
+ local scale = data.options.rscale ~= "" and data.options.rscale or 1
+ --~ if trace_typescript then
+ --~ report_typescript("Class: '%s', Style: '%s', Size: '%s', Scale: '%s'",fontclass,fontstyle,size,scale)
+ --~ end
+ if fontstyle == "mm" then -- math uses the default bodyfont settings because it uses 'ma' and 'mb' as alternative names
+ ctx_definetypeface( { fontclass }, { fontstyle }, { style }, { "" }, { "default" }, { designsize = size, rscale = scale } )
+ else
+ ctx_definetypeface( { fontclass }, { fontstyle }, { "" }, { "" }, { "" }, { designsize = size, rscale = scale } )
end
end
-local function definetextfont(index)
- local data = data[index]
- local fontclass = data.metadata.typeface
- local shortstyle = data.metadata.style
- local style = styles[data.metadata.style]
- local designsize = data.options.opticals == v_yes and "auto" or "default"
- local scale = data.options.scale ~= "" and data.options.scale or 1
- ctx_definetypeface( { fontclass }, { shortstyle }, { style }, { "" }, { "default" }, { designsize = designsize, rscale = scale } )
+function selectfont.default(data)
+ local family = data.metadata.family
+ local fontclass = data.metadata.typeface
+ local fontstyle = data.metadata.style
+ local style = m_style[fontstyle]
+ report_selectfont("The requested font '%s' has no files for the 'tf' alternative, Latin Modern is used instead.",family)
+ ctx_definetypeface( { fontclass }, { fontstyle }, { style }, { "modern" }, { "default" } )
end
-local function definemathfont(index)
- local data = data[index]
- local fontclass = data.metadata.typeface
- local shortstyle = data.metadata.style
- local style = styles[data.metadata.style]
- local scale = data.options.scale ~= "" and data.options.scale or 1
- local typescript = cleanname(data.metadata.family)
- local entries = data.fonts
- if entries then
- ctx_definetypeface( { fontclass }, { shortstyle }, { style }, { "" }, { "default" }, { rscale = scale } )
+function selectfont.definefontfamily(index)
+ local data = data[index]
+ local fontstyle = data.metadata.style
+ local fontfiles = data.files and data.files["tf"]
+ if fontfiles then
+ selectfont.fallback (data)
+ selectfont.typescript(data)
+ if fontstyle ~= "mm" then
+ selectfont.bodyfont(data)
+ end
+ selectfont.typeface(data)
else
- ctx_definetypeface( { fontclass }, { shortstyle }, { style }, { typescript }, { "default" }, { rscale = scale } )
+ selectfont.default(data)
end
end
-function selectfont.definetypeface(index)
- local data = data[index]
- if data.metadata.style == "mm" then
- definefallbackfont(index)
- definetypescript (index)
- definemathfont (index)
+function selectfont.definefallbackfamily(index)
+ local data = data[index]
+ local family = data.metadata.family
+ local fontclass = data.metadata.typeface
+ local fontstyle = data.metadata.style
+ local fontfiles = data.files
+ if fontfiles then
+ selectfont.registerfallback(index)
else
- definefallbackfont(index)
- definetypescript (index)
- definetextfont (index)
+ report_selectfont("The requested fallback font '%s' for typeface '%s' style '%s' was ignored because no files where found.",family,fontclass,fontstyle)
end
- -- inspect(data)
end
-local styles = {
- { "tf" }, { "bf" }, { "it" }, { "sl" }, { "bi" }, { "bs" }, { "sc" },
-}
+function selectfont.definefontfamilypreset(name,data)
+ local p = presets[name]
+ local d = settings_to_hash(data)
+ if not p then
+ p = d
+ presets[name] = p
+ end
+end
implement {
- name = "defineselectfont",
- actions = { selectfont.define, context },
+ name = "registerfontfamily",
+ actions = { selectfont.registerfontfamily, context },
arguments = {
{
{
"metadata", {
{ "typeface" },
{ "style" },
- { "family" },
+ { "family" }
}
},
{
"options", {
- { "opticals" },
- { "scale" },
+ { "designsize" },
+ { "rscale" },
{ "goodies" },
- { "alternative" },
+ { "preset" },
+ { "extras" },
+ { "features" },
{ "range" },
{ "offset" },
{ "check" },
- { "force" },
+ { "force" }
}
},
- { "alternatives", styles },
- { "files", styles },
- { "features", styles },
+ {
+ "userdata"
+ }
}
- }
+ }
+}
+
+implement {
+ name = "registerfontalternative",
+ actions = selectfont.registerfontalternative,
+ arguments = "string"
}
implement {
name = "definefontfamily",
- actions = selectfont.definetypeface,
+ actions = selectfont.definefontfamily,
arguments = "integer"
}
implement {
name = "definefallbackfamily",
- actions = selectfont.registerfallback,
- arguments = { "string", "string", "integer"}
+ actions = selectfont.definefallbackfamily,
+ arguments = "integer"
}
+
+implement {
+ name = "definefontfamilypreset",
+ actions = selectfont.definefontfamilypreset,
+ arguments = { "string", "string" }
+} \ No newline at end of file
diff --git a/tex/context/base/mkiv/font-sel.mkvi b/tex/context/base/mkiv/font-sel.mkvi
index eb45ea033..4e74f6864 100644
--- a/tex/context/base/mkiv/font-sel.mkvi
+++ b/tex/context/base/mkiv/font-sel.mkvi
@@ -1,6 +1,6 @@
%D \module
%D [ file=font-sel,
-%D version=2014.07.27,
+%D version=2016.05.16,
%D title=\CONTEXT\ User Module,
%D subtitle=Selectfont,
%D author=Wolfgang Schuster,
@@ -17,7 +17,7 @@
\installcorenamespace {selectfont}
\installsimplecommandhandler \??selectfont {selectfont}
-\unexpanded\def\selectfont_setparameters[#settings]%
+\unexpanded\def\selectfont_register[#settings]%
{\begingroup
\setupcurrentselectfont[#settings]%
\edef\p_selectfont_preset{\selectfontparameter\c!preset}%
@@ -25,75 +25,32 @@
\processcommacommand[\p_selectfont_preset]\selectfont_preset_process
\setupcurrentselectfont[#settings]%
\fi
- \setexpandedselectfontparameter\c!style {\expandnamespaceparameter\??selectfontstyle \selectfontparameter\c!style \s!rm }%
- \setexpandedselectfontparameter\c!alternative{\expandnamespaceparameter\??selectfontalternative\selectfontparameter\c!alternative\v!default}%
- \xdef\selectfont_index{\clf_defineselectfont
+ \font_helpers_process_alternative_list\clf_registerfontalternative
+ \setexpandedselectfontparameter\c!style{\expandnamespaceparameter\??fontshortstyle\selectfontparameter\c!style\s!rm}%
+ \xdef\selectfont_index{\clf_registerfontfamily
metadata {%
- typeface {\selectfontparameter\c!name}%
+ typeface {\selectfontparameter\c!label}%
style {\selectfontparameter\c!style}%
- family {\selectfontparameter\c!family}%
+ family {\selectfontparameter\c!name}%
}
options {%
- opticals {\selectfontparameter\c!opticalsize}%
- scale {\selectfontparameter\c!scale}%
+ designsize {\selectfontparameter\s!designsize}%
+ rscale {\selectfontparameter\s!rscale}%
goodies {\selectfontparameter\c!goodies}%
- alternative {\selectfontparameter\c!alternative}%
+ extras {\selectfontparameter\c!extras}%
+ features {\selectfontparameter\c!features}%
+ preset {\selectfontparameter\c!preset}%
range {\selectfontparameter\c!range}% fallback only
offset {\selectfontparameter\c!offset}% fallback only
check {\selectfontparameter\c!check}% fallback only
force {\selectfontparameter\c!force}% fallback only
}
- alternatives {%
- tf {\selectfontparameter\s!tf}%
- bf {\selectfontparameter\s!bf}%
- it {\selectfontparameter\s!it}%
- sl {\selectfontparameter\s!sl}%
- bi {\selectfontparameter\s!bi}%
- bs {\selectfontparameter\s!bs}%
- sc {\selectfontparameter\s!sc}%
- }
- files {%
- tf {\selectfontparameter\c!regularfont}%
- bf {\selectfontparameter\c!boldfont}%
- it {\selectfontparameter\c!italicfont}%
- sl {\selectfontparameter\c!slantedfont}%
- bi {\selectfontparameter\c!bolditalicfont}%
- bs {\selectfontparameter\c!boldslantedfont}%
- sc {\selectfontparameter\c!smallcapsfont}%
- }
- features {%
- tf {\selectfontparameter\c!regularfeatures}%
- bf {\selectfontparameter\c!boldfeatures}%
- it {\selectfontparameter\c!italicfeatures}%
- sl {\selectfontparameter\c!slantedfeatures}%
- bi {\selectfontparameter\c!bolditalicfeatures}%
- bs {\selectfontparameter\c!boldslantedfeatures}%
- sc {\selectfontparameter\c!smallcapsfeatures}%
- }}%
+ userdata {%
+ \luaexpanded{#settings}%
+ }}%
\endgroup}
%D \macros
-%D {defineselectfontstyle}
-
-\installcorenamespace {selectfontstyle}
-
-\unexpanded\def\defineselectfontstyle
- {\dodoubleargument\selectfont_style_define}
-
-\def\selectfont_style_define[#styles][#shortstyle]%
- {\processcommalist[#styles]{\selectfont_style_define_indeed{#shortstyle}}}
-
-\def\selectfont_style_define_indeed#shortstyle#style%
- {\setvalue{\??selectfontstyle#style}{#shortstyle}}
-
-\defineselectfontstyle [\s!rm,\s!serif] [\s!rm]
-\defineselectfontstyle [\s!ss,\s!sans] [\s!ss]
-\defineselectfontstyle [\s!tt,\s!mono] [\s!tt]
-\defineselectfontstyle [\s!hw,\s!handwriting] [\s!hw]
-\defineselectfontstyle [\s!cg,\s!calligraphy] [\s!cg]
-\defineselectfontstyle [\s!mm,\s!math] [\s!mm]
-
-%D \macros
%D {definefontfamilypreset}
\installcorenamespace {selectfontpreset}
@@ -113,6 +70,10 @@
% unknown preset
\fi}
+\def\selectfont_preset_define[#name][#settings]%
+ {\setvalue{\??selectfontpreset#name}{\setupcurrentselectfont[#settings]}%
+ \clf_definefontfamilypreset{#name}{\luaexpanded{#settings}}}
+
\definefontfamilypreset
[range:chinese]
[\c!range={cjkcompatibilityforms,
@@ -131,19 +92,19 @@
\definefontfamilypreset
[range:japanese]
- [\crange={cjkcompatibilityforms,
- cjkcompatibilityideographs,
- cjkcompatibilityideographssupplement,
- cjkradicalssupplement,
- cjkstrokes,
- cjksymbolsandpunctuation,
- cjkunifiedideographs,
- cjkunifiedideographsextensiona,
- cjkunifiedideographsextensionb,
- halfwidthandfullwidthforms,
- verticalforms,
- hiragana,
- katakana}]
+ [\c!range={cjkcompatibilityforms,
+ cjkcompatibilityideographs,
+ cjkcompatibilityideographssupplement,
+ cjkradicalssupplement,
+ cjkstrokes,
+ cjksymbolsandpunctuation,
+ cjkunifiedideographs,
+ cjkunifiedideographsextensiona,
+ cjkunifiedideographsextensionb,
+ halfwidthandfullwidthforms,
+ verticalforms,
+ hiragana,
+ katakana}]
\definefontfamilypreset
[range:korean]
@@ -207,36 +168,6 @@
\definefontfamilypreset [math:uppercasegreekbold] [\c!range=uppercasegreeknormal,\c!offset=uppercasegreekbold, \s!tf=style:bold]
\definefontfamilypreset [math:uppercasegreekbolditalic] [\c!range=uppercasegreeknormal,\c!offset=uppercasegreekbolditalic,\s!tf=style:bolditalic]
-
-%D \macros
-%D {defineselectfontalternative}
-%D
-%D The results between the old {\em simplefonts} and the new {\em selectfont}
-%D can be different because simplefonts the name entries in the database to find
-%D the styles for a font while selectfont the newer spec-method to the find the
-%D files for each style.
-%D
-%D The used method depends on the command one uses to load a font but it is
-%D also possible to switch between them with the {\em alternative} key, possible
-%D values are:
-%D
-%D \startitemize[packed]
-%D \startitem selectfont and \stopitem
-%D \startitem simplefonts. \stopitem
-%D \stopitemize
-
-\installcorenamespace {selectfontalternative}
-
-\unexpanded\def\defineselectfontalternative
- {\dodoubleargument\selectfont_alternative_define}
-
-\def\selectfont_alternative_define[#name][#alternative]%
- {\setvalue{\??selectfontalternative#name}{#alternative}}
-
-\defineselectfontalternative [\v!selectfont ] [\v!selectfont ]
-\defineselectfontalternative [\v!simplefonts] [\v!simplefonts]
-\defineselectfontalternative [\v!default ] [\v!default ]
-
%D \macros
%D {definefontfamily,definefallbackfamily}
%D
@@ -250,17 +181,17 @@
%D \definefontfamily [dejavu] [serif] [DejaVu Serif]
%D \definefontfamily [dejavu] [sans] [DejaVu Sans]
%D \definefontfamily [dejavu] [mono] [DejaVu Sans Mono]
-%D \definefontfamily [dejavu] [math] [XITS Math] [scale=1.1]
+%D \definefontfamily [dejavu] [math] [XITS Math] [rscale=1.1]
%D
%D \definefontfamily [office] [serif] [Times New Roman]
-%D \definefontfamily [office] [sans] [Arial] [scale=0.9]
+%D \definefontfamily [office] [sans] [Arial] [rscale=0.9]
%D \definefontfamily [office] [mono] [Courier]
%D \definefontfamily [office] [math] [TeX Gyre Termes Math]
%D
%D \definefontfamily [linux] [serif] [Linux Libertine O]
%D \definefontfamily [linux] [sans] [Linux Biolinum O]
%D \definefontfamily [linux] [mono] [Latin Modern Mono]
-%D \definefontfamily [linux] [math] [TeX Gyre Pagella Math] [scale=0.9]
+%D \definefontfamily [linux] [math] [TeX Gyre Pagella Math] [rscale=0.9]
%D
%D \setupbodyfont[dejavu]
%D
@@ -306,7 +237,7 @@
%D optical sizes when they are a feature of the requested font.
%D
%D \starttyping
-%D \definefontfamily[mainface][serif][Latin Modern Roman][opticalsize=yes]
+%D \definefontfamily[mainface][serif][Latin Modern Roman][designsize=auto]
%D
%D \setupbodyfont[mainface]
%D
@@ -319,15 +250,15 @@
%D \stoptext
%D \stoptyping
-% regularfont = … | * … | name:… | name:* … | file:… | file:* … | spec:…-…-… | style:medium
+% tf = … | * … | name:… | name:* … | file:… | file:* … | style:medium
\unexpanded\def\definefontfamily
{\doquadrupleempty\selectfont_family_define}
\def\selectfont_family_define[#typeface][#style][#family][#settings]%
{\doifelseassignment{#settings}
- {\selectfont_setparameters[\c!name={#typeface},\c!style={#style},\c!family={#family},#settings]}
- {\selectfont_setparameters[\c!name={#typeface},\c!style={#style},\c!family={#family},\c!preset={#settings}]}%
+ {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]}
+ {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}%
\clf_definefontfamily\selectfont_index\relax}
\unexpanded\def\definefallbackfamily
@@ -335,95 +266,13 @@
\def\selectfont_fallback_define[#typeface][#style][#family][#settings]%
{\doifelseassignment{#settings}
- {\selectfont_setparameters[\c!name={#typeface},\c!style={#style},\c!family={#family},#settings]}
- {\selectfont_setparameters[\c!name={#typeface},\c!style={#style},\c!family={#family},\c!preset={#settings}]}%
- \edef\p_selectfont_style{\expandnamespacevalue\??selectfontstyle{#style}\s!rm}%
- \clf_definefallbackfamily{#typeface}{\p_selectfont_style}\selectfont_index\relax}
-
-%D \macros
-%D {setupfontfamily,setupfallbackfamily}
-%D
-%D For simple documents which don’t need complex font settings one could use
-%D the \tex{setupfontfamily} command where the requested font is enabled immediately
-%D without the need to load it with \tex{setupbodyfont}. The downside of this method
-%D is that processing of the document takes longer with each additional font which
-%D is set with \tex{setupfontfamily}.
-%D
-%D \starttyping
-%D \setupfontfamily [serif] [DejaVu Serif]
-%D \setupfontfamily [sans] [DejaVu Sans]
-%D \setupfontfamily [mono] [DejaVu Sans Mono]
-%D \setupfontfamily [math] [XITS Math] [scale=1.1]
-%D
-%D \starttext
-%D
-%D \rm Serif 123 \ss Sans \tt Mono \m{1+2=3}
-%D
-%D \stoptext
-%D \stoptyping
-
-\newcount\c_selectfont_family
-\newtoks \t_selectfont_fallback
-\newtoks \t_selectfont_styles
-
-\unexpanded\def\setupfontfamily
- {\dotripleempty\selectfont_family_setup}
-
-\def\selectfont_family_setup
- {\ifsecondargument
- \expandafter\selectfont_family_setup_yes
- \else
- \expandafter\selectfont_family_setup_nop
- \fi}
-
-\def\selectfont_family_setup_yes[#style][#family][#settings]%
- {\normalexpanded{\t_selectfont_styles{\selectfont_set_font_family[#style][#family][#settings]\the\t_selectfont_styles}}%
- \selectfont_set_font_indeed}
-
-\def\selectfont_family_setup_nop[#settings][#dummya][#dummyb]%
- {\setupselectfont[#settings]}
-
-\unexpanded\def\selectfont_set_default
- {\selectfont_set_font_family[\v!serif][Latin Modern Roman][\c!opticalsize=\v!yes]%
- \selectfont_set_font_family[\v!sans] [Latin Modern Sans] [\c!opticalsize=\v!yes]%
- \selectfont_set_font_family[\v!mono] [Latin Modern Mono] [\c!opticalsize=\v!yes,\c!features=\s!none]%
- \selectfont_set_font_family[\v!math] [Latin Modern Math] [\c!opticalsize=\v!yes]}
-
-\unexpanded\def\setupfallbackfamily
- {\dotripleempty\selectfont_fallback_setup}
-
-\def\selectfont_fallback_setup[#style][#family][#settings]%
- {\normalexpanded{\t_selectfont_fallback{\the\t_selectfont_fallback\selectfont_set_font_fallback[#style][#family][#settings]}}}
-
-\def\selectfont_set_font_indeed
- {\global\advance\c_selectfont_family\plusone
- \edef\m_selectfont_typeface{\v!selectfont-\number\c_selectfont_family}%
- \the\t_selectfont_fallback
- \the\t_selectfont_styles
- \selectfont_set_default
- \setupbodyfont[\m_selectfont_typeface,\rootselectfontparameter\c!style]}
-
-\unexpanded\def\selectfont_set_font_family[#style]#dummy[#family]#dummy[#settings]%
- {\ifcsname\m_selectfont_typeface#style\endcsname \else
- \expandafter\let\csname\m_selectfont_typeface#style\endcsname\relax
- \selectfont_family_define[\m_selectfont_typeface][#style][#family][#settings]%
- \fi}
-
-\unexpanded\def\selectfont_set_font_fallback[#style]#dummy[#family]#dummy[#settings]%
- {\selectfont_fallback_define[\m_selectfont_typeface][#style][#family][#settings]}
-
-%D You can apply a different feature set to each style of a font but if nothing
-%D is set the global features are used.
+ {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]}
+ {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}%
+ \clf_definefallbackfamily\selectfont_index\relax}
\setupselectfont
- [ \c!features=\s!default,
- \c!regularfeatures=\selectfontparameter\c!features,
- \c!boldfeatures=\selectfontparameter\c!features,
- \c!italicfeatures=\selectfontparameter\c!features,
- \c!slantedfeatures=\selectfontparameter\c!features,
- \c!bolditalicfeatures=\selectfontparameter\c!features,
- \c!boldslantedfeatures=\selectfontparameter\c!features,
- \c!smallcapsfeatures=\s!smallcaps,
- \c!style=\s!rm]
+ [ \c!features=\s!default,
+ \s!designsize=\s!default,
+ \s!rscale=1]
-\protect
+\protect \ No newline at end of file
diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua
index bb8a7d331..f8720f717 100644
--- a/tex/context/base/mkiv/node-ini.lua
+++ b/tex/context/base/mkiv/node-ini.lua
@@ -265,6 +265,15 @@ end
local nodecodes = simplified(node.types())
local whatcodes = simplified(node.whatsits())
+local usercodes = allocate {
+ [ 97] = "attributes", -- a
+ [100] = "number", -- d
+ [108] = "lua", -- l
+ [110] = "nodes", -- n
+ [115] = "string", -- s
+ [116] = "tokens" -- t
+}
+
skipcodes = allocate(swapped(skipcodes,skipcodes))
boundarycodes = allocate(swapped(boundarycodes,boundarycodes))
noadcodes = allocate(swapped(noadcodes,noadcodes))
@@ -283,25 +292,32 @@ accentcodes = allocate(swapped(accentcodes,accentcodes))
fencecodes = allocate(swapped(fencecodes,fencecodes))
rulecodes = allocate(swapped(rulecodes,rulecodes))
leadercodes = allocate(swapped(leadercodes,leadercodes))
+usercodes = allocate(swapped(usercodes,usercodes))
-nodes.skipcodes = skipcodes nodes.gluecodes = skipcodes -- more official
+nodes.skipcodes = skipcodes
nodes.boundarycodes = boundarycodes
nodes.noadcodes = noadcodes
nodes.nodecodes = nodecodes
-nodes.whatcodes = whatcodes nodes.whatsitcodes = whatcodes -- more official
+nodes.whatcodes = whatcodes
nodes.listcodes = listcodes
nodes.glyphcodes = glyphcodes
nodes.kerncodes = kerncodes
nodes.penaltycodes = penaltycodes
nodes.mathcodes = mathcodes
nodes.fillcodes = fillcodes
-nodes.margincodes = margincodes nodes.marginkerncodes = margincodes
-nodes.disccodes = disccodes nodes.discretionarycodes = disccodes
+nodes.margincodes = margincodes
+nodes.disccodes = disccodes
nodes.accentcodes = accentcodes
nodes.radicalcodes = radicalcodes
nodes.fencecodes = fencecodes
nodes.rulecodes = rulecodes
nodes.leadercodes = leadercodes
+nodes.usercodes = usercodes
+
+nodes.gluecodes = skipcodes -- more official
+nodes.whatsitcodes = whatcodes -- more official
+nodes.marginkerncodes = margincodes
+nodes.discretionarycodes = disccodes
listcodes.row = listcodes.alignment
listcodes.column = listcodes.alignment
@@ -327,6 +343,9 @@ nodes.codes = allocate { -- mostly for listing
whatsit = whatcodes,
accent = accentcodes,
fence = fencecodes,
+ rule = rulecodes,
+ leader = leadercodes,
+ user = usercodes,
}
local report_codes = logs.reporter("nodes","codes")
diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua
index 4d25314ad..bb09656fb 100644
--- a/tex/context/base/mkiv/node-res.lua
+++ b/tex/context/base/mkiv/node-res.lua
@@ -27,6 +27,7 @@ local kerncodes = nodes.kerncodes
local rulecodes = nodes.rulecodes
local nodecodes = nodes.nodecodes
local boundarycodes = nodes.boundarycodes
+local usercodes = nodes.usercodes
local glyph_code = nodecodes.glyph
@@ -150,11 +151,15 @@ local textdir = register_nut(new_nut("dir"))
local latelua = register_nut(new_nut("whatsit",whatsitcodes.latelua))
local special = register_nut(new_nut("whatsit",whatsitcodes.special))
-local user_n = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_n,"type",100) -- 44
-local user_l = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_l,"type",110) -- 44
-local user_s = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_s,"type",115) -- 44
-local user_t = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_t,"type",116) -- 44
------ user_c = register_nut(new_nut("whatsit",whatsitcodes.userdefined)) setfield(user_c,"type",108) -- 44
+
+local user_node = new_nut("whatsit",whatsitcodes.userdefined)
+
+local user_number = register_nut(copy_nut(user_node)) setfield(user_number, "type",usercodes.number)
+local user_nodes = register_nut(copy_nut(user_node)) setfield(user_nodes, "type",usercodes.nodes)
+local user_string = register_nut(copy_nut(user_node)) setfield(user_string, "type",usercodes.string)
+local user_tokens = register_nut(copy_nut(user_node)) setfield(user_tokens, "type",usercodes.tokens)
+----- user_lua = register_nut(copy_nut(user_node)) setfield(user_lua, "type",usercodes.lua) -- in > 0.95
+local user_attributes = register_nut(copy_nut(user_node)) setfield(user_attributes,"type",usercodes.attributes)
local left_margin_kern = register_nut(new_nut("margin_kern",0))
local right_margin_kern = register_nut(new_nut("margin_kern",1))
@@ -571,7 +576,7 @@ end
-- local str = userids[num]
function nutpool.usernumber(id,num)
- local n = copy_nut(user_n)
+ local n = copy_nut(user_number)
if num then
setfield(n,"user_id",id)
setfield(n,"value",num)
@@ -582,7 +587,7 @@ function nutpool.usernumber(id,num)
end
function nutpool.userlist(id,list)
- local n = copy_nut(user_l)
+ local n = copy_nut(user_nodes)
if list then
setfield(n,"user_id",id)
setfield(n,"value",list)
@@ -593,7 +598,7 @@ function nutpool.userlist(id,list)
end
function nutpool.userstring(id,str)
- local n = copy_nut(user_s)
+ local n = copy_nut(user_string)
if str then
setfield(n,"user_id",id)
setfield(n,"value",str)
@@ -604,7 +609,7 @@ function nutpool.userstring(id,str)
end
function nutpool.usertokens(id,tokens)
- local n = copy_nut(user_t)
+ local n = copy_nut(user_tokens)
if tokens then
setfield(n,"user_id",id)
setfield(n,"value",tokens)
@@ -614,16 +619,27 @@ function nutpool.usertokens(id,tokens)
return n
end
--- function nutpool.usercode(id,code)
--- local n = copy_nut(user_c)
--- if code then
--- setfield(n,"user_id",id)
--- setfield(n,"value",code)
--- else
--- setfield(n,"value",id)
--- end
--- return n
--- end
+function nutpool.userlua(id,code)
+ local n = copy_nut(user_lua)
+ if code then
+ setfield(n,"user_id",id)
+ setfield(n,"value",code)
+ else
+ setfield(n,"value",id)
+ end
+ return n
+end
+
+function nutpool.userattributes(id,attr)
+ local n = copy_nut(user_attributes)
+ if attr then
+ setfield(n,"user_id",id)
+ setfield(n,"value",attr)
+ else
+ setfield(n,"value",id)
+ end
+ return n
+end
function nutpool.special(str)
local n = copy_nut(special)
@@ -637,24 +653,22 @@ local function cleanup(nofboxes) -- todo
if nodes.tracers.steppers then -- to be resolved
nodes.tracers.steppers.reset() -- todo: make a registration subsystem
end
- local nl, nr = 0, nofreserved
+ local nl = 0
+ local nr = nofreserved
for i=1,nofreserved do
local ri = reserved[i]
- -- if not (getid(ri) == glue_spec and not getfield(ri,"is_writable")) then
- free_nut(reserved[i])
- -- end
+ free_nut(reserved[i])
end
if nofboxes then
for i=0,nofboxes do
local l = getbox(i)
if l then
--- print(nodes.listtoutf(getlist(l)))
free_nut(l) -- also list ?
nl = nl + 1
end
end
end
- reserved = { }
+ reserved = { }
nofreserved = 0
return nr, nl, nofboxes -- can be nil
end
diff --git a/tex/context/base/mkiv/spac-prf.lua b/tex/context/base/mkiv/spac-prf.lua
index 39d90794c..4cd39336e 100644
--- a/tex/context/base/mkiv/spac-prf.lua
+++ b/tex/context/base/mkiv/spac-prf.lua
@@ -60,6 +60,9 @@ local setlink = nuts.setlink
local setlist = nuts.setlist
local setattr = nuts.setattr
+local properties = nodes.properties.data
+local setprop = nuts.setprop
+local getprop = nuts.getprop
local theprop = nuts.theprop
local floor = math.floor
@@ -73,12 +76,10 @@ local link_nodes = nuts.link
local find_node_tail = nuts.tail
local setglue = nuts.setglue
-local properties = nodes.properties.data
-
local a_visual = attributes.private("visual")
local a_snapmethod = attributes.private("snapmethod")
local a_profilemethod = attributes.private("profilemethod")
-local a_specialcontent = attributes.private("specialcontent")
+----- a_specialcontent = attributes.private("specialcontent")
local variables = interfaces.variables
local v_none = variables.none
@@ -203,7 +204,8 @@ local function getprofile(line,step)
-- we could do a nested check .. but then we need to push / pop glue
local shift = getfield(current,"shift")
wd = getfield(current,"width")
- if getattr(current,a_specialcontent) then
+ -- if getattr(current,a_specialcontent) then
+ if getprop(current,"specialcontent") then
-- like a margin note, maybe check for wd
ht = 0
dp = 0
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 2df57c9f6..e1434d8c7 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 07fdd4da4..1a1577b9e 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/typo-mar.lua b/tex/context/base/mkiv/typo-mar.lua
index cbac9f851..727846678 100644
--- a/tex/context/base/mkiv/typo-mar.lua
+++ b/tex/context/base/mkiv/typo-mar.lua
@@ -74,7 +74,7 @@ if not modules then modules = { } end modules ['typo-mar'] = {
-- so far
local format, validstring = string.format, string.valid
-local insert, remove, sortedkeys = table.insert, table.remove, table.sortedkeys
+local insert, remove, sortedkeys, fastcopy = table.insert, table.remove, table.sortedkeys, table.fastcopy
local setmetatable, next = setmetatable, next
local formatters = string.formatters
local toboolean = toboolean
@@ -86,7 +86,7 @@ local trace_margindata = false trackers.register("typesetters.margindata",
local trace_marginstack = false trackers.register("typesetters.margindata.stack", function(v) trace_marginstack = v end)
local trace_margingroup = false trackers.register("typesetters.margindata.group", function(v) trace_margingroup = v end)
-local report_margindata = logs.reporter("typesetters","margindata")
+local report_margindata = logs.reporter("margindata")
local tasks = nodes.tasks
local prependaction = tasks.prependaction
@@ -147,6 +147,9 @@ local getbox = nuts.getbox
local getlist = nuts.getlist
local setlist = nuts.setlist
+local setprop = nuts.setprop
+local getprop = nuts.getprop
+
local nodecodes = nodes.nodecodes
local listcodes = nodes.listcodes
local gluecodes = nodes.gluecodes
@@ -183,8 +186,7 @@ local addtoline = paragraphs.addtoline
local moveinline = paragraphs.moveinline
local calculatedelta = paragraphs.calculatedelta
-local a_margindata = attributes.private("margindata")
-local a_specialcontent = attributes.private("specialcontent")
+----- a_specialcontent = attributes.private("specialcontent")
local a_linenumber = attributes.private('linenumber')
local inline_mark = nodepool.userids["margins.inline"]
@@ -268,7 +270,8 @@ end
function margins.save(t)
setmetatable(t,defaults)
local content = getbox(t.number)
-setattr(content,a_specialcontent,1) -- todo: a property
+ -- setattr(content,a_specialcontent,1)
+ setprop(content,"specialcontent","margindata")
local location = t.location
local category = t.category
local inline = t.inline
@@ -276,10 +279,6 @@ setattr(content,a_specialcontent,1) -- todo: a property
local name = t.name
local option = t.option
local stack = t.stack
- if stack == v_yes or stack == v_continue then
- inline = false
- t.inline = false
- end
if option then
option = settings_to_hash(option)
t.option = option
@@ -388,8 +387,6 @@ end
-- When the prototype inner/outer code that was part of this proved to be
-- okay it was moved elsewhere.
-local status, nofstatus = { }, 0
-
-- local f_anchor = formatters["_plib_.set('md:h',%i,{x=true,c=true})"]
-- local s_anchor = 'md:h'
--
@@ -420,7 +417,6 @@ local function realign(current,candidate)
local atleft = true
local hmove = 0
local delta = 0
- -- local realpageno = candidate.realpageno
local leftpage = isleftpage(false,true)
local leftdelta = 0
local rightdelta = 0
@@ -489,11 +485,10 @@ local function realign(current,candidate)
moveinline(hook,candidate.node,delta)
end
-local function realigned(current,a)
- local candidate = status[a]
+local function realigned(current,candidate)
realign(current,candidate)
nofdelayed = nofdelayed - 1
- status[a] = nil
+ setprop(current,"margindata",false)
return true
end
@@ -509,36 +504,43 @@ end
local stacked = { } -- left/right keys depending on location
local cache = { }
-
-local function resetstacked()
- stacked = { }
+local anchors = { }
+
+local function resetstacked(location)
+ if location then
+ local s = { }
+ stacked[location] = s
+ anchors[location] = false
+ return s
+ else
+ stacked = { }
+ anchors = { }
+ return stacked
+ end
end
--- resetstacked()
+-- anchors are only set for lines that have a note
-local function ha(tag) -- maybe l/r keys ipv left/right keys
+local function sa(tag) -- maybe l/r keys ipv left/right keys
local p = cache[tag]
+ if trace_marginstack then
+ report_margindata("updating anchor %a",tag)
+ end
p.p = true
p.y = true
+-- p.a = tag
setposition('md:v',tag,p)
cache[tag] = nil
end
-margins.ha = ha
-
-local f_anchor = formatters["typesetters.margins.ha(%s)"]
-
-local function setanchor(v_anchor)
- return new_latelua(f_anchor(v_anchor))
+local function setanchor(v_anchor) -- freezes the global here
+ return lateluafunction(function() sa(v_anchor) end)
end
--- local function setanchor(v_anchor) -- freezes the global here
--- return lateluafunction(function() ha(v_anchor) end)
--- end
-
local function markovershoot(current) -- todo: alleen als offset > line
v_anchors = v_anchors + 1
- cache[v_anchors] = stacked
+ cache[v_anchors] = fastcopy(stacked)
+-- cache[v_anchors] = stacked -- so we adapt the previous too
local anchor = setanchor(v_anchors)
-- local list = hpack_nodes(linked_nodes(anchor,getlist(current))) -- not ok, we need to retain width
local list = hpack_nodes(linked_nodes(anchor,getlist(current)),getfield(current,"width"),"exactly")--
@@ -550,27 +552,66 @@ local function markovershoot(current) -- todo: alleen als offset > line
setlist(current,list)
end
+-- local function getovershoot(location)
+-- local p = getposition("md:v",v_anchors)
+-- local c = getposition("md:v",v_anchors+1)
+-- if p and c and p.p and p.p == c.p then
+-- local distance = p.y - c.y
+-- local offset = p[location] or 0
+-- local overshoot = offset - distance
+-- if trace_marginstack then
+-- report_margindata("location %a, anchor %a, distance %p, offset %p, overshoot %p",location,v_anchors,distance,offset,overshoot)
+-- end
+-- if overshoot > 0 then
+-- return overshoot, offset, distance
+-- else
+-- return 0, offset, distance
+-- end
+-- elseif trace_marginstack then
+-- report_margindata("location %a, anchor %a, nothing to correct",location,v_anchors)
+-- end
+-- return 0, 0, 0
+-- end
+
local function getovershoot(location)
- local p = getposition("md:v",v_anchors)
local c = getposition("md:v",v_anchors+1)
- if p and c and p.p and p.p == c.p then
- local distance = p.y - c.y
- local offset = p[location] or 0
- local overshoot = offset - distance
- if trace_marginstack then
- report_margindata("location %a, anchor %a, distance %p, offset %p, overshoot %p",location,v_anchors,distance,offset,overshoot)
+ if c then
+ local p = false
+ local cp = c.p
+ for i=v_anchors,1,-1 do
+ local pi = getposition("md:v",i)
+ if pi.p == cp then
+ p = pi
+ else
+ break
+ end
end
- if overshoot > 0 then
- return overshoot
+ if p then
+ local distance = p.y - c.y
+ local offset = p[location] or 0
+ local overshoot = offset - distance
+ if trace_marginstack then
+ report_margindata("location %a, anchor %a, distance %p, offset %p, overshoot %p",location,v_anchors,distance,offset,overshoot)
+ end
+ if overshoot > 0 then
+ return overshoot, offset, distance
+ else
+ return 0, offset, distance
+ end
end
- elseif trace_marginstack then
+ end
+ if trace_marginstack then
report_margindata("location %a, anchor %a, nothing to correct",location,v_anchors)
end
- return 0
+ return 0, 0, 0
+end
+
+local function getanchor(location,anchor)
+ return getposition("md:v",anchor)
end
local function inject(parent,head,candidate)
- local box = candidate.box
+ local box = candidate.box
if not box then
return head, nil, false -- we can have empty texts
end
@@ -586,12 +627,11 @@ local function inject(parent,head,candidate)
local baseline = candidate.baseline
local strutheight = candidate.strutheight
local strutdepth = candidate.strutdepth
+ local inline = candidate.inline
local psubtype = getsubtype(parent)
local offset = stacked[location]
local firstonstack = offset == false or offset == nil
- nofstatus = nofstatus + 1
nofdelayed = nofdelayed + 1
- status[nofstatus] = candidate
-- yet untested
baseline = tonumber(baseline)
if not baseline then
@@ -613,6 +653,34 @@ local function inject(parent,head,candidate)
if trace_margindata then
report_margindata("processing, index %s, height %p, depth %p, parent %a, method %a",candidate.n,height,depth,listcodes[psubtype],method)
end
+ -- The next section handles the inline notes that are checked for overlap which
+ -- is somewhat tricky as that mechanism is mostly for paragraph boundnotes.
+ local stackedinline = inline and (stack == v_yes or stack == v_continue)
+ if stackedinline then
+ firstonstack = true
+ if anchors[location] then
+ local a1 = getanchor(location,anchors[location])
+ local a2 = getanchor(location,v_anchors+1)
+ if a1 and a2 then
+ local distance = a1.y - a2.y
+ if distance > offset then
+ -- report_margindata("location %s, no overlap, case 1",location)
+ elseif offset > 0 then
+ offset = offset - distance
+ firstonstack = false
+ -- report_margindata("location %s, overlap %a",location,offset)
+ -- else
+ -- report_margindata("location %s, no overlap, case 2",location)
+ end
+ -- else
+ -- report_margindata("location %s, no overlap, case 3",location)
+ end
+ -- else
+ -- report_margindata("location %s, no overlap, case 4",location)
+ end
+ anchors[location] = v_anchors + 1
+ end
+ -- end of special section
if firstonstack then
offset = 0
else
@@ -693,7 +761,7 @@ local function inject(parent,head,candidate)
--
candidate.hook, candidate.node = addtoline(parent,box)
--
- setattr(box,a_margindata,nofstatus)
+ setprop(box,"margindata",candidate)
if trace_margindata then
report_margindata("injected, location %a, shift %p",location,shift)
end
@@ -704,14 +772,16 @@ local function inject(parent,head,candidate)
depth = offset,
slack = candidate.bottomspace, -- todo: 'depth' => strutdepth
lineheight = candidate.lineheight, -- only for tracing
+ stacked = stackedinline,
}
offset = offset + height
- stacked[location] = offset -- weird, no table ?
+ -- we need a restart ... when there is no overlap at all
+ stacked[location] = offset
-- todo: if no real depth then zero
if trace_margindata then
report_margindata("status, offset %s",offset)
end
- return getlist(parent), room, stack == v_continue
+ return getlist(parent), room, stackedinline or (stack == v_continue)
end
local function flushinline(parent,head)
@@ -729,9 +799,15 @@ local function flushinline(parent,head)
inlinestore[n] = nil
nofinlined = nofinlined - 1
head, room, con = inject(parent,head,candidate) -- maybe return applied offset
- continue = continue or con
- done = true
+ done = true
+ continue = continue or con
nofstored = nofstored - 1
+ if room and room.stacked then
+ -- for now we also check for inline+yes/continue, maybe someday no such check
+ -- will happen; we can assume most inlines are one line heigh; also this
+ -- together feature can become optional
+ registertogether(tonode(parent),room) -- !! tonode
+ end
end
end
elseif id == hlist_code or id == vlist_code then
@@ -761,8 +837,8 @@ local function flushed(scope,parent) -- current is hlist
local candidate = remove(store,1) -- brr, local stores are sparse
if candidate then -- no vpack, as we want to realign
head, room, con = inject(parent,head,candidate)
- done = true
- continue = continue or con
+ done = true
+ continue = continue or con
nofstored = nofstored - 1
if room then
registertogether(tonode(parent),room) -- !! tonode
@@ -817,11 +893,11 @@ local function handler(scope,head,group)
local done = false
while current do
local id = getid(current)
- if (id == vlist_code or id == hlist_code) and not getattr(current,a_margindata) then
+ if (id == vlist_code or id == hlist_code) and getprop(current,"margindata") == nil then
local don, continue = flushed(scope,current)
if don then
done = true
- setattr(current,a_margindata,0) -- signal to prevent duplicate processing
+ setprop(current,"margindata",false) -- signal to prevent duplicate processing
if continue then
markovershoot(current)
end
@@ -909,8 +985,9 @@ local function finalhandler(head)
while current and nofdelayed > 0 do
local id = getid(current)
if id == hlist_code then -- only lines?
- local a = getattr(current,a_margindata)
- if not a or a == 0 then
+ local a = getprop(current,"margindata")
+-- if not a or a == 0 then
+ if not a then
finalhandler(getlist(current))
elseif realigned(current,a) then
done = true
@@ -946,26 +1023,23 @@ end
-- Somehow the vbox builder (in combinations) gets pretty confused and decides to
-- go horizontal. So this needs more testing.
-prependaction("finalizers", "lists", "typesetters.margins.localhandler")
--- ("vboxbuilders", "normalizers", "typesetters.margins.localhandler")
-prependaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler")
-prependaction("shipouts", "normalizers", "typesetters.margins.finalhandler")
+prependaction("finalizers", "lists", "typesetters.margins.localhandler")
+prependaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler")
+prependaction("shipouts", "normalizers", "typesetters.margins.finalhandler")
-disableaction("finalizers", "typesetters.margins.localhandler")
--- ("vboxbuilders", "typesetters.margins.localhandler")
-disableaction("mvlbuilders", "typesetters.margins.globalhandler")
-disableaction("shipouts", "typesetters.margins.finalhandler")
+disableaction("finalizers", "typesetters.margins.localhandler")
+disableaction("mvlbuilders", "typesetters.margins.globalhandler")
+disableaction("shipouts", "typesetters.margins.finalhandler")
enablelocal = function()
- enableaction("finalizers", "typesetters.margins.localhandler")
- -- enableaction("vboxbuilders", "typesetters.margins.localhandler")
- enableaction("shipouts", "typesetters.margins.finalhandler")
+ enableaction("finalizers", "typesetters.margins.localhandler")
+ enableaction("shipouts", "typesetters.margins.finalhandler")
enablelocal = nil
end
enableglobal = function()
- enableaction("mvlbuilders", "typesetters.margins.globalhandler")
- enableaction("shipouts", "typesetters.margins.finalhandler")
+ enableaction("mvlbuilders", "typesetters.margins.globalhandler")
+ enableaction("shipouts", "typesetters.margins.finalhandler")
enableglobal = nil
end
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index d07ada96c..fb29c8b5b 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 73a93c89a..652553799 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/mkiv/m-scite.mkiv b/tex/context/modules/mkiv/m-scite.mkiv
index e033235c3..fd4a3c7a1 100644
--- a/tex/context/modules/mkiv/m-scite.mkiv
+++ b/tex/context/modules/mkiv/m-scite.mkiv
@@ -62,6 +62,8 @@ local f_fore_bold = formatters["\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"]
local f_none_bold = formatters["\\def\\slx%s#1{{\\bf#1}}%%"]
local f_none_none = formatters["\\def\\slx%s#1{{#1}}%%"]
local f_texstyled = formatters["\\slx%s{%s}"]
+local f_hanging = formatters["\\slxb{%s}%s\\slxe"]
+
local f_mapping = [[
\let\string\slxL\string\letterleftbrace
@@ -165,20 +167,21 @@ function scite.installcommands()
context(exportcolors())
end
-local p = lpeg.P("\\slxS ")^1
+local p1 = lpeg.tsplitat(lpeg.patterns.newline)
+local p2 = lpeg.P("\\slxS ")^1
local function indent(str)
- local l = string.split(str,"\n")
+ local l = lpegmatch(p1,str)
for i=1,#l do
local s = l[i]
if #s > 0 then
- local n = lpegmatch(p,s)
+ local n = lpegmatch(p2,s)
if n then
n = (n-1)/6
else
n = 0
end
- l[i] = formatters["\\slxb{%s}%s\\slxe"](n,s)
+ l[i] = f_hanging(n,s)
end
end
return concat(l,"\n")
diff --git a/tex/context/modules/mkiv/x-setups-basics.mkiv b/tex/context/modules/mkiv/x-setups-basics.mkiv
index 02376deea..4a7859c7f 100644
--- a/tex/context/modules/mkiv/x-setups-basics.mkiv
+++ b/tex/context/modules/mkiv/x-setups-basics.mkiv
@@ -686,6 +686,13 @@
\getsetupstring{\xmlatt{#1}{type}}
\stopxmlsetups
+\definebar % in case we mess with underbar settings
+ [cmd_underbar]
+ [\v!underbar]
+ [\c!foregroundcolor=,
+ \c!foregroundstyle=,
+ \c!color=]
+
\startxmlsetups xml:setups:constant
\doifelsemode {setups-pass-one} {
} {
@@ -694,7 +701,7 @@
\xmlmappedvalue{setups:method}{\xmlatt{#1}{method}}{none}
} {
\doif {\xmlatt{#1}{default}} {yes} {
- \underbar % next needs to be {braced}
+ \cmd_underbar % next needs to be {braced}
}
}
{\getsetupstring{\xmlatt{#1}{type}}}
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 83efc517f..b8d5ef8f0 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 : 05/17/16 19:20:58
+-- merge date : 05/19/16 13:43:44
do -- begin closure to overcome local limits and interference
@@ -19686,7 +19686,7 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
while start do
local char=ischar(start,font)
if char then
- local a=getattr(start,0)
+ local a=attr and getattr(start,0)
if not a or (a==attr) then
local lookupmatch=lookupcache[char]
if lookupmatch then
@@ -19716,7 +19716,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
while start~=stop do
local char=ischar(start,font)
if char then
- local a=getattr(start,0)
+ local a=attr and getattr(start,0)
if not a or (a==attr) then
local lookupmatch=lookupcache[char]
if lookupmatch then
@@ -19749,7 +19749,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
end
end
local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
- local a=getattr(sub,0)
+ local a=attr and getattr(sub,0)
if not a or (a==attr) then
for n in traverse_nodes(sub) do
if n==last then
@@ -19780,7 +19780,7 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
while start do
local char=ischar(start,font)
if char then
- local a=getattr(start,0)
+ local a=attr and getattr(start,0)
if not a or (a==attr) then
for i=1,nofsteps do
local step=steps[i]
@@ -19821,7 +19821,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
while start~=stop do
local char=ischar(start,font)
if char then
- local a=getattr(start,0)
+ local a=attr and getattr(start,0)
if not a or (a==attr) then
for i=1,nofsteps do
local step=steps[i]
@@ -19862,7 +19862,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
end
end
local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
- local a=getattr(sub,0)
+ local a=attr and getattr(sub,0)
if not a or (a==attr) then
for n in traverse_nodes(sub) do
if n==last then
@@ -19944,6 +19944,9 @@ local function featuresprocessor(head,font,attr)
nesting=nesting-1
return head,false
end
+ if attr==0 then
+ attr=false
+ end
head=tonut(head)
if trace_steps then
checkstep(head)
@@ -19981,7 +19984,7 @@ local function featuresprocessor(head,font,attr)
while start do
local char=ischar(start,font)
if char then
- local a=getattr(start,0)
+ local a=attr and getattr(start,0)
if not a or (a==attr) then
for i=1,nofsteps do
local step=steps[i]
@@ -20022,7 +20025,7 @@ local function featuresprocessor(head,font,attr)
while start do
local char,id=ischar(start,font)
if char then
- local a=getattr(start,0)
+ local a=attr and getattr(start,0)
if a then
a=(a==attr) and (not attribute or getprop(start,a_state)==attribute)
else
@@ -20072,7 +20075,7 @@ local function featuresprocessor(head,font,attr)
while start do
local char,id=ischar(start,font)
if char then
- local a=getattr(start,0)
+ local a=attr and getattr(start,0)
if a then
a=(a==attr) and (not attribute or getprop(start,a_state)==attribute)
else
@@ -22272,6 +22275,7 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
local report_afm=logs.reporter("fonts","afm loading")
+local report_afm=logs.reporter("fonts","pfb loading")
fonts=fonts or {}
local handlers=fonts.handlers or {}
fonts.handlers=handlers
@@ -22324,16 +22328,16 @@ do
local function loadpfbvector(filename)
local data=io.loaddata(resolvers.findfile(filename))
if not data then
- print("no data",filename)
+ report_pfb("no data in %a",filename)
return
end
- if not find(data,"!PS%-AdobeFont%-") then
- print("no font",filename)
+ if not (find(data,"!PS%-AdobeFont%-") or find(data,"%%!FontType1")) then
+ report_pfb("no font in %a",filename)
return
end
local ascii,binary=match(data,"(.*)eexec%s+......(.*)")
if not binary then
- print("no binary",filename)
+ report_pfb("no binary data in %a",filename)
return
end
binary=decrypt(binary,4)
@@ -22342,7 +22346,7 @@ do
vector[0]=table.remove(vector,1)
end
if not vector then
- print("no vector",filename)
+ report_pfb("no vector in %a",filename)
return
end
return vector
@@ -22367,16 +22371,18 @@ do
end
end
end
-local spacing=patterns.whitespace
+local spacer=patterns.spacer
+local whitespace=patterns.whitespace
local lineend=patterns.newline
+local spacing=spacer^0
local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber
-local name=spacing*C((1-spacing)^1)
-local words=spacing*(1-lineend)^1/strip
+local name=spacing*C((1-whitespace)^1)
+local words=spacing*((1-lineend)^1/strip)
local rest=(1-lineend)^0
local fontdata=Carg(1)
local semicolon=spacing*P(";")
-local plus=P("plus")*number
-local minus=P("minus")*number
+local plus=spacing*P("plus")*number
+local minus=spacing*P("minus")*number
local function addkernpair(data,one,two,value)
local chr=data.characters[one]
if chr then
@@ -22461,6 +22467,7 @@ local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName
+(fontdata*C("AXISHEIGHT")*number*rest)/set_1
)
local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
+local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
local function read(filename,parser)
local afmblob=io.loaddata(filename)
@@ -23195,7 +23202,8 @@ local function check_afm(specification,fullname)
end
end
function readers.afm(specification,method)
- local fullname,tfmdata=specification.filename or "",nil
+ local fullname=specification.filename or ""
+ local tfmdata=nil
if fullname=="" then
local forced=specification.forced or ""
if forced~="" then
@@ -23223,8 +23231,17 @@ function readers.pfb(specification,method)
if trace_defining then
report_afm("using afm reader for %a",original)
end
- specification.specification=file.replacesuffix(original,"afm")
specification.forced="afm"
+ local function swap(name)
+ local value=specification[swap]
+ if value then
+ specification[swap]=gsub("%.pfb",".afm",1)
+ end
+ end
+ swap("filename")
+ swap("fullname")
+ swap("forcedname")
+ swap("specification")
return readers.afm(specification,method)
end