Class: Fontico::Emitters::Font

Inherits:
Object
  • Object
show all
Defined in:
lib/fontico/emitters/font.rb

Overview

A TTF for Prawn. Not for the web: at this icon count the sprite is both smaller over the wire and not render-blocking. Prawn reads TTF/OTF via ttfunk and cannot read woff2, so TTF is the right container here.

Instance Method Summary collapse

Constructor Details

#initialize(manifest, build, lock: nil, outliner: nil, output: nil) ⇒ Font

Returns a new instance of Font.



9
10
11
12
13
14
15
# File 'lib/fontico/emitters/font.rb', line 9

def initialize(manifest, build, lock: nil, outliner: nil, output: nil)
  @manifest = manifest
  @build = build
  @lock = lock
  @outliner = outliner || Outliner.new
  @output = output
end

Instance Method Details

#accepts?(icon) ⇒ Boolean

Glyphs store no colour, so multicolour icons cannot be represented at all. They stay in the sprite and the build names each one it dropped.

Returns:

  • (Boolean)


19
# File 'lib/fontico/emitters/font.rb', line 19

def accepts?(icon) = !(@lock&.multicolor?(icon.name) || icon.multicolor?)

#call ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/fontico/emitters/font.rb', line 22

def call
  unsupported = @build.select { |icon, body| @outliner.strategy_for(icon, body) == :none }
  @outliner.refuse(unsupported.map(&:first)) if unsupported.any?

  outlines = @outliner.outlines(@build, size: @manifest.size)

  glyphs = @build.map do |icon, body|
    # Never fall back to allocating here. The builder has already
    # save!d the lock by the time it emits, so a codepoint minted now
    # would never reach disk: the font would ship a glyph that
    # Fontico.glyph cannot name. A nil is worse still — it reaches
    # String.fromCodePoint as null and maps the glyph to U+0000
    # without complaint.
    cp = @lock.codepoint_for(icon.name)
    raise Fontico::Error, "#{icon.name} has no codepoint in icons.lock" if cp.nil?

    { name: icon.key, codepoint: cp, svg: document(outlines[icon.name], body) }
  end

  result = @outliner.instance_variable_get(:@runner)
                    .run("build_font.mjs", {
                           fontName: "fontico", size: @manifest.size,
                           output: @output, glyphs: glyphs
                         })
  if result["empty"]&.any?
    raise Fontico::Error, "      \#{result[\"empty\"].size} icon(s) produced an empty glyph and would ship invisible:\n\n        \#{result[\"empty\"].join(\"\\n  \")}\n\n      The usual cause is live <text> in the source SVG, which has no outline\n      to convert. Convert text to paths (Path > Object to Path), or remove\n      the icon from the font target.\n    MSG\n  end\n\n  result\nend\n"

#rules_only? ⇒ Boolean

Returns:

  • (Boolean)


20
# File 'lib/fontico/emitters/font.rb', line 20

def rules_only? = false