diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/font-sel.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/font-sel.lua | 1431 |
1 files changed, 803 insertions, 628 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua b/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua index c3431a213ca..455310e145c 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua @@ -1,326 +1,101 @@ if not modules then modules = { } end modules ['font-sel'] = { - version = 1.000, + version = 1.001, comment = "companion to font-sel.mkvi", author = "Wolfgang Schuster", copyright = "Wolfgang Schuster", license = "GNU General Public License" } -local context = context -local cleanname = fonts.names.cleanname -local gsub, splitup, find = string.gsub, string.splitup, string.find -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 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 - -local selectfont = fonts.select or { } -fonts.select = selectfont - -local data = selectfont.data or { } -selectfont.data = data - -local fallbacks = selectfont.fallbacks or { } -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 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 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 }, - } -} - --- 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", - }, - }, -} - -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 context = context +local cleanname = fonts.names.cleanname +local gsub, splitup, find, lower = string.gsub, string.splitup, string.find, string.lower +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 allocate = utilities.storage.allocate + +local v_default = interfaces.variables.default + +local implement = interfaces.implement + +local fonts = fonts + +local getlookups = fonts.names.getlookups +local registerdesignsizes = fonts.goodies.designsizes.register +local bodyfontsizes = storage.shared.bodyfontsizes + +fonts.select = fonts.select or { } +local selectfont = fonts.select + +selectfont.data = selectfont.data or allocate() +selectfont.fallbacks = selectfont.fallbacks or allocate() +selectfont.methods = selectfont.methods or allocate() +selectfont.extras = selectfont.extras or allocate() +selectfont.alternatives = selectfont.alternatives or allocate() +selectfont.presets = selectfont.presets or allocate() +selectfont.defaults = selectfont.defaults or allocate() + +storage.register("fonts/select/presets", selectfont.presets, "fonts.select.presets") + +local data = selectfont.data +local fallbacks = selectfont.fallbacks +local methods = selectfont.methods +local extras = selectfont.extras +local alternatives = selectfont.alternatives +local presets = selectfont.presets +local defaults = selectfont.defaults + +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_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["minionmath"] = { options = { extras = "minion-math", features = "math\\mathsizesuffix", goodies = "minion-math" } } +defaults["texgyredejavumath"] = { options = { extras = "dejavu", features = "math\\mathsizesuffix" } } +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,843 @@ 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",fontname[1]) + elseif #fullname > 0 then + selectfont_savefile(data,alternative,0,"default",fullname[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) +local m_weight = { + ["thin"] = 100, + ["extralight"] = 200, + ["light"] = 300, + ["regular"] = 400, + ["medium"] = 500, + ["semibold"] = 600, + ["bold"] = 700, + ["extrabold"] = 800, + ["black"] = 900 +} + +local m_width = { + ["ultracondensed"] = 1, + ["extracondensed"] = 2, + ["condensed"] = 3, + ["semicondensed"] = 4, + ["normal"] = 5, + ["semiexpanded"] = 6, + ["expanded"] = 7, + ["extraexpanded"] = 8, + ["ultraexpanded"] = 9, +} + +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" }, +} + +local m_alternative = { + ["tf"] = "regular", + ["bf"] = "bold", + ["it"] = "italic", + ["sl"] = "italic", + ["bi"] = "bolditalic", + ["bs"] = "bolditalic", + ["sc"] = "smallcaps" +} + +--~ 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 -methods["style"] = function(data,alternative,style) - local method = data.options.alternative or nil - (methods[method] or methods[v_default])(data,alternative,style) +local function m_style_subfamily(entries,style,family) + local t = { } + local style = cleanname(style) + local family = cleanname(family) + for index, entry in next, entries do + if entry["familyname"] == family and entry["subfamilyname"] == style then -- familyname + subfamilyname + t[#t+1] = entry + elseif entry["family"] == family and entry["subfamily"] == style then -- family + subfamily + t[#t+1] = entry + end + end + return #t ~= 0 and t or nil end -methods["features"] = function(data,alternative,features) - savefeatures(data,alternative,features) +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 + 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 + end + end + return #t ~= 0 and t or nil end -methods["goodies"] = function(data,alternative,goodies) - savegoodies(data,alternative,goodies) +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 -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) - end - else - method, filename = splitup(filename,":") - if not filename then - filename = method - method = "name" - end - (methods[method] or methods["name"])(data,alternative,filename) +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 -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_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 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_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 + local subfamily = m_style_subfamily(entries,fontstyle,fontfamily) + if subfamily then + entries = subfamily + else + 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 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 + 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 - ctx_stopfontclass() + 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 fontclass = lower(class) + --~ 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"](fontclass,style,alternative) + local fontsynonym = formatters ["synonym-%s-%s-%s"](fontclass,style,alternative) + if fallback then + fontfile = formatters ["file-%s-%s-%s-%s"](fontclass,style,alternative,index) + fontsynonym = formatters ["synonym-%s-%s-%s-%s"](fontclass,style,alternative,index) + end + local fontfallback = formatters["fallback-%s-%s-%s"](fontclass,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 "" + local force = data.options.force ~= "" and data.options.force or "" + local fontfeature = data.features and data.features[alternative] or data.options.features + local fontclass = lower(class) + local fontsynonym = formatters ["synonym-%s-%s-%s-%s"](fontclass,style,alternative,index) + local fontfallback = formatters["fallback-%s-%s-%s"] (fontclass,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 fontclass = lower(class) + local fontfallback = formatters["fallback-%s-%s-%s"](fontclass,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 class = data.metadata.typeface + local fontstyle = data.metadata.style + local fontclass = lower(class) + 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( { class }, { fontsizes }, { fontstyle }, { fontlist } ) 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 } ) +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 + ctx_definetypeface( { fontclass }, { fontstyle }, { style }, { "" }, { "default" }, { designsize = size, rscale = scale } ) 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.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 + +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" } } |