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

sile-typesetter / sile / 11770252752

11 Nov 2024 01:09AM UTC coverage: 32.853% (-27.5%) from 60.402%
11770252752

Pull #2164

github

web-flow
chore(deps): Bump DeterminateSystems/nix-installer-action from 14 to 15

Bumps [DeterminateSystems/nix-installer-action](https://github.com/determinatesystems/nix-installer-action) from 14 to 15.
- [Release notes](https://github.com/determinatesystems/nix-installer-action/releases)
- [Commits](https://github.com/determinatesystems/nix-installer-action/compare/v14...v15)

---
updated-dependencies:
- dependency-name: DeterminateSystems/nix-installer-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #2164: chore(deps): Bump DeterminateSystems/nix-installer-action from 14 to 15

5855 of 17822 relevant lines covered (32.85%)

2493.73 hits per line

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

74.4
/shapers/harfbuzz.lua
1
local hb = require("justenoughharfbuzz")
4✔
2
local icu = require("justenoughicu")
4✔
3
local bitshim = require("bitshim")
4✔
4

5
SILE.settings:declare({
4✔
6
   parameter = "harfbuzz.subshapers",
7
   type = "string or nil",
8
   default = "",
9
   help = "Comma-separated shaper list to pass to Harfbuzz",
10
})
11

12
local base = require("shapers.base")
4✔
13

14
local smallTokenSize = 20 -- Small words will be cached
4✔
15
local shapeCache = {}
4✔
16
local _key = function (options, text)
17
   return table.concat({
1,015✔
18
      text,
1,015✔
19
      options.tracking or "1",
1,015✔
20
      options.language,
1,015✔
21
      options.script,
1,015✔
22
      SILE.font._key(options),
2,030✔
23
   }, ";")
1,015✔
24
end
25

26
local substwarnings = {}
4✔
27
local usedfonts = {}
4✔
28

29
local shaper = pl.class(base)
4✔
30
shaper._name = "harfbuzz"
4✔
31

32
function shaper:shapeToken (text, options)
4✔
33
   local items
34
   if #text < smallTokenSize then
809✔
35
      items = shapeCache[_key(options, text)]
1,600✔
36
      if items then
800✔
37
         return items
585✔
38
      end
39
   end
40
   local face = SILE.font.cache(options, self.getFace)
224✔
41
   if self:checkHBProblems(text, face) then
448✔
42
      return {}
×
43
   end
44
   if not face then
224✔
45
      SU.error("Could not find requested font " .. options .. " or any suitable substitutes")
×
46
   end
47
   if not options.filename and face.family ~= options.family and not substwarnings[options.family] then
224✔
48
      substwarnings[options.family] = true
×
49
      SU.warn("Font family '" .. options.family .. "' not available, falling back to '" .. face.family .. "'")
×
50
   end
51
   usedfonts[face] = true
224✔
52
   items = {
224✔
53
      hb._shape(
448✔
54
         text,
224✔
55
         face,
224✔
56
         options.script,
224✔
57
         options.direction,
224✔
58
         options.language,
224✔
59
         face.pointsize,
224✔
60
         options.features,
224✔
61
         SILE.settings:get("harfbuzz.subshapers") or ""
448✔
62
      ),
224✔
63
   }
224✔
64
   for i = 1, #items do
2,841✔
65
      local j = (i == #items) and #text or items[i + 1].index
2,617✔
66
      items[i].text = text:sub(items[i].index + 1, j) -- Lua strings are 1-indexed
5,234✔
67
      if options.tracking then
2,617✔
68
         items[i].width = items[i].width * options.tracking
×
69
      end
70
   end
71
   if #text < smallTokenSize then
224✔
72
      shapeCache[_key(options, text)] = items
430✔
73
   end
74
   return items
224✔
75
end
76

77
local _pretty_varitions = function (face)
78
   local text = face.filename
×
79
   if face.variations and face.variations ~= "" then
×
80
      text = text .. "@" .. face.variations
×
81
   end
82
   local index = bitshim.band(face.index, 0xFFFF) or 0
×
83
   local instance = bitshim.rshift(face.index, 16) or 0
×
84
   if index or instance then
×
85
      text = text .. "[" .. index .. "," .. instance .. "]"
×
86
   end
87
   return text
×
88
end
89

90
-- TODO: normalize this method to accept self as first arg
91
function shaper.getFace (opts)
4✔
92
   local face = SILE.fontManager:face(opts)
6✔
93
   SU.debug("fonts", "Resolved font family", opts.family, "->", face and face.filename)
6✔
94
   if not face or not face.filename then
6✔
95
      SU.error("Couldn't find face '" .. opts.family .. "'")
×
96
   end
97
   if SILE.makeDeps then
6✔
98
      SILE.makeDeps:add(face.filename)
×
99
   end
100
   face.variations = opts.variations or ""
6✔
101
   face.pointsize = ("%g"):format(SILE.types.measurement(opts.size):tonumber())
18✔
102
   face.weight = ("%d"):format(opts.weight or 0)
6✔
103

104
   -- Try instantiating the font, hb.instantiate() will return nil if it is not
105
   -- a variable font or if instantiation failed.
106
   face.tempfilename = face.filename
6✔
107
   local data = hb.instantiate(face)
6✔
108
   if data then
6✔
109
      local tmp = os.tmpname()
×
110
      local file = io.open(tmp, "wb")
×
111
      file:write(data)
×
112
      file:close()
×
113
      face.tempfilename = tmp
×
114
      SU.debug("fonts", "Instantiated", _pretty_varitions(face), "as", face.tempfilename)
×
115
   elseif (face.variations ~= "") or (bitshim.rshift(face.index, 16) ~= 0) then
6✔
116
      if not SILE.features.font_variations then
×
117
         SU.warn([[
×
118
            This build of SILE was compiled with font variations support disabled
119

120
            This is likely due to the configuration script not detecting the subsetter
121
            library included in HarfBuzz >= 6. This document specifies font variations
122
            which cannot be correctly rendered. Please rebuild SILE with the necessary
123
            library support. Alternatively to proceed anyway *incorrectly* render this
124
            document run:
125

126
              sile -e 'SILE.features.font_variations = true' ...
127

128
            Or modify the document to remove variations options from font commands.
129
         ]])
×
130
      end
131
      SU.error("Failed to instantiate: " .. _pretty_varitions(face))
×
132
   end
133

134
   return face
6✔
135
end
136

137
function shaper.preAddNodes (_, items, nnodeValue) -- Check for complex nodes
4✔
138
   for i = 1, #items do
4,397✔
139
      if items[i].y_offset or items[i].x_offset or items[i].width ~= items[i].glyphAdvance then
3,247✔
140
         nnodeValue.complex = true
×
141
         break
142
      end
143
   end
144
end
145

146
function shaper.addShapedGlyphToNnodeValue (_, nnodevalue, shapedglyph)
4✔
147
   -- Note: previously we stored the shaped items only for "complex" nodes
148
   -- (nodevalue.complete). We now always do it, so as to have them at hand for
149
   -- italic correction.
150
   if not nnodevalue.items then
3,247✔
151
      nnodevalue.items = {}
1,150✔
152
   end
153
   nnodevalue.items[#nnodevalue.items + 1] = shapedglyph
3,247✔
154

155
   if not nnodevalue.glyphString then
3,247✔
156
      nnodevalue.glyphString = {}
×
157
   end
158
   if not nnodevalue.glyphNames then
3,247✔
159
      nnodevalue.glyphNames = {}
1,150✔
160
   end
161
   table.insert(nnodevalue.glyphString, shapedglyph.gid)
3,247✔
162
   table.insert(nnodevalue.glyphNames, shapedglyph.name)
3,247✔
163
end
164

165
function shaper.debugVersions (_)
4✔
166
   local ot = require("core.opentype-parser")
4✔
167
   print("Harfbuzz version: " .. hb.version())
4✔
168
   print("Shapers enabled: " .. table.concat({ hb.shapers() }, ", "))
4✔
169
   if icu then
4✔
170
      print("ICU support enabled")
4✔
171
   end
172
   print("")
4✔
173
   print("Fonts used:")
4✔
174
   for face, _ in pairs(usedfonts) do
10✔
175
      local font = ot.parseFont(face)
6✔
176
      local version = "Unknown version"
6✔
177
      if font and font.names and font.names[5] then
6✔
178
         -- luacheck: ignore 512
179
         -- (It's OK to grab the first version we find in the name table)
180
         for _, v in pairs(font.names[5]) do
6✔
181
            version = v[1]
6✔
182
            break
6✔
183
         end
184
      end
185
      print(face.filename .. ":" .. face.index, version)
6✔
186
   end
187
end
188

189
function shaper.checkHBProblems (_, text, face)
4✔
190
   if hb.version_lessthan(1, 0, 4) and #text < 1 then
224✔
191
      return true
×
192
   end
193
   if hb.version_lessthan(2, 3, 0) and hb.get_table(face, "CFF "):len() > 0 and not substwarnings["CFF "] then
224✔
194
      SILE.status.unsupported = true
×
195
      SU.warn([[
×
196
         Vertical spacing of CFF fonts may be subtly inconsistent between systems
197

198
         Upgrade to Harfbuzz 2.3.0 if you need absolute consistency.
199
      ]])
×
200
      substwarnings["CFF "] = true
×
201
   end
202
   return false
224✔
203
end
204

205
return shaper
4✔
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