• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sile-typesetter / sile / 8288578143

14 Mar 2024 09:39PM UTC coverage: 64.155% (-10.6%) from 74.718%
8288578143

Pull #1904

github

alerque
chore(core): Fixup ec6ed657 which didn't shim old pack styles properly
Pull Request #1904: Merge develop into master (commit to next release being breaking)

1648 of 2421 new or added lines in 107 files covered. (68.07%)

1843 existing lines in 77 files now uncovered.

10515 of 16390 relevant lines covered (64.15%)

3306.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.46
/core/font.lua
1
--- font
2
-- @module SILE.font
3
local icu = require("justenoughicu")
183✔
4

5
local lastshaper
6

7
SILE.registerCommand("font", function (options, content)
366✔
8
  if SU.ast.hasContent(content) then SILE.settings:pushState() end
1,118✔
9
  if options.filename then SILE.settings:set("font.filename", options.filename) end
559✔
10
  if options.family then
559✔
11
    SILE.settings:set("font.family", options.family)
391✔
12
    SILE.settings:set("font.filename", "")
391✔
13
  end
14
  if options.size then
559✔
15
    local size = SU.cast("measurement", options.size)
457✔
16
    if not size then SU.error("Couldn't parse font size "..options.size) end
457✔
17
    SILE.settings:set("font.size", size:absolute())
914✔
18
  end
19
  if options.weight then SILE.settings:set("font.weight", 0+options.weight) end
559✔
20
  if options.style then SILE.settings:set("font.style", options.style) end
559✔
21
  if options.variant then SILE.settings:set("font.variant", options.variant) end
559✔
22
  if options.features then SILE.settings:set("font.features", options.features) end
559✔
23
  if options.variations then SILE.settings:set("font.variations", options.variations) end
559✔
24
  if options.direction then SILE.settings:set("font.direction", options.direction) end
559✔
25
  if options.language then
559✔
26
    if options.language ~= "und" and icu and icu.canonicalize_language then
362✔
27
      local newlang = icu.canonicalize_language(options.language)
362✔
28
      -- if newlang ~= options.language then
29
        -- SU.warn("Language '"..options.language.."' not canonical, '"..newlang.."' will be used instead.")
30
      -- end
31
      options.language = newlang
362✔
32
    end
33
    SILE.settings:set("document.language", options.language)
362✔
34
    fluent:set_locale(options.language)
362✔
35
    SILE.languageSupport.loadLanguage(options.language)
362✔
36
  end
37
  if options.script then SILE.settings:set("font.script", options.script)
914✔
38
  elseif SILE.settings:get("document.language") then
408✔
39
    local lang = SILE.languageSupport.languages[SILE.settings:get("document.language")]
408✔
40
    if lang and lang.defaultScript then
204✔
41
      SILE.settings:set("font.script", lang.defaultScript)
1✔
42
    end
43
  end
44
  if options.hyphenchar then
559✔
45
    -- must be in the form of, for example, "-" or "U+2010" or "0x2010" (Unicode hex codepoint)
46
    SILE.settings:set("font.hyphenchar", SU.utf8charfromcodepoint(options.hyphenchar))
710✔
47
  end
48

49
  -- We must *actually* load the font here, because by the time we're inside
50
  -- SILE.shaper.shapeToken, it's too late to respond appropriately to things
51
  -- that the post-load hook might want to do.
52
  SILE.font.cache(SILE.font.loadDefaults({}), SILE.shaper.getFace)
1,118✔
53

54
  if SU.ast.hasContent(content) then
1,118✔
55
    SILE.process(content)
151✔
56
    SILE.settings:popState()
151✔
57
    if SILE.shaper._name == "harfbuzzWithColor" and lastshaper then
151✔
UNCOV
58
      SU.debug("color-fonts", "Switching from color fonts shaper back to previous shaper")
×
UNCOV
59
      SILE.typesetter:leaveHmode(true)
×
UNCOV
60
      lastshaper, SILE.shaper = nil, lastshaper
×
61
    end
62
  end
63
end, "Set current font family, size, weight, style, variant, script, direction and language", nil, true)
742✔
64

65
SILE.settings:declare({ parameter = "font.family", type = "string or nil", default = "Gentium Plus" })
183✔
66
SILE.settings:declare({ parameter = "font.size", type = "number or integer", default = 10 })
183✔
67
SILE.settings:declare({ parameter = "font.weight", type = "integer", default = 400 })
183✔
68
SILE.settings:declare({ parameter = "font.variant", type = "string", default = "normal" })
183✔
69
SILE.settings:declare({ parameter = "font.script", type = "string", default = "" })
183✔
70
SILE.settings:declare({ parameter = "font.style", type = "string", default = "" })
183✔
71
SILE.settings:declare({ parameter = "font.direction", type = "string", default = "" })
183✔
72
SILE.settings:declare({ parameter = "font.filename", type = "string or nil", default = "" })
183✔
73
SILE.settings:declare({ parameter = "font.features", type = "string", default = "" })
183✔
74
SILE.settings:declare({ parameter = "font.variations", type = "string", default = "" })
183✔
75
SILE.settings:declare({ parameter = "font.hyphenchar", type = "string", default = "-" })
183✔
76

77
SILE.fontCache = {}
183✔
78

79
local _key = function (options)
80
  return table.concat({
24,860✔
81
      options.family,
24,860✔
82
      ("%g"):format(SILE.types.measurement(options.size):tonumber()),
74,580✔
83
      ("%d"):format(options.weight or 0),
24,860✔
84
      options.style,
24,860✔
85
      options.variant,
24,860✔
86
      options.features,
24,860✔
87
      options.variations,
24,860✔
88
      options.direction,
24,860✔
89
      options.filename,
24,860✔
90
    }, ";")
24,860✔
91
end
92

93
local font = {
183✔
94

95
  loadDefaults = function (options)
96
    if not options.family then options.family = SILE.settings:get("font.family") end
7,797✔
97
    if not options.size then options.size = SILE.settings:get("font.size") end
7,797✔
98
    if not options.weight then options.weight = SILE.settings:get("font.weight") end
7,889✔
99
    if not options.style then options.style = SILE.settings:get("font.style") end
7,889✔
100
    if not options.variant then options.variant = SILE.settings:get("font.variant") end
9,638✔
101
    if SILE.settings:get("font.filename") ~= "" then
9,638✔
UNCOV
102
      options.filename = SILE.settings:get("font.filename")
×
UNCOV
103
      options.family = ""
×
104
    end
105
    if not options.language then options.language = SILE.settings:get("document.language") end
9,546✔
106
    if not options.script then options.script = SILE.settings:get("font.script") end
9,638✔
107
    if not options.direction then
4,819✔
108
      options.direction = SILE.settings:get("font.direction")
9,638✔
109
      if not options.direction or options.direction == "" then
4,819✔
110
        options.direction = SILE.typesetter and SILE.typesetter.frame and SILE.typesetter.frame:writingDirection() or "LTR"
8,814✔
111
      end
112
    end
113
    if not options.features then options.features = SILE.settings:get("font.features") end
9,638✔
114
    if not options.variations then options.variations = SILE.settings:get("font.variations") end
9,638✔
115
    if not options.hyphenchar then options.hyphenchar = SILE.settings:get("font.hyphenchar") end
9,638✔
116
    return options
4,819✔
117
  end,
118

119
  cache = function (options, callback)
120
    local key = _key(options)
4,309✔
121
    if not SILE.fontCache[key] then
4,309✔
122
      SU.debug("fonts", "Looking for", key)
188✔
123
      local face = callback(options)
188✔
124
      SILE.fontCache[key] = face
188✔
125
    end
126
    local cached = SILE.fontCache[key]
4,309✔
127
    SILE.font.postLoadHook(cached)
4,309✔
128
    return cached
4,309✔
129
  end,
130

131
  finish = function ()
132
    for key, font in pairs(SILE.fontCache) do
280✔
133
      if font.tempfilename ~= font.filename then
188✔
134
        SU.debug("fonts", "Removing temporary file of", key, ":", font.tempfilename)
×
135
        os.remove(font.tempfilename)
×
136
      end
137
    end
138
  end,
139

140
  postLoadHook = function(face)
141
    local ot = require("core.opentype-parser")
4,309✔
142
    local font = ot.parseFont(face)
4,309✔
143
    if font.cpal then
4,309✔
UNCOV
144
      SILE.require("packages.color-fonts")
×
UNCOV
145
      if SILE.shaper._name ~= "harfbuzzWithColor" then
×
UNCOV
146
        SU.debug("color-fonts", "Switching to color font Shaper")
×
UNCOV
147
        SILE.typesetter:leaveHmode(true)
×
UNCOV
148
        lastshaper, SILE.shaper = SILE.shaper, SILE.shapers.harfbuzzWithColor()
×
149
      end
150
    end
151
  end,
152

153
  _key = _key
183✔
154
}
155

156
return font
183✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc