summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-sel.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/font-sel.lua')
-rw-r--r--tex/context/base/mkiv/font-sel.lua1354
1 files changed, 755 insertions, 599 deletions
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