Class: Ucode::Glyphs::EmbeddedFonts::Svg

Inherits:
Object
  • Object
show all
Defined in:
lib/ucode/glyphs/embedded_fonts/svg.rb

Overview

Converts a fontisan ‘GlyphOutline` into a standalone SVG document shaped to match the LastResort::Svg output (y-flipped, viewBox padded around the bbox, single `<path>` child).

The fontisan outline is in font units, with y growing upward (PostScript convention). SVG y grows downward. We:

1. Walk `outline.to_commands` and re-emit each command with
   the y coordinate negated. The commands we get are
   `:move_to`, `:line_to`, `:curve_to` (quadratic; one
   control + one end point), and `:close_path`.
2. Build a viewBox from the outline's bbox with a small pad,
   y-flipped so min_y is the SVG-space top.

The y-negation happens at emit time, not at parse time, so we never have to read back a serialized path string.

Instance Method Summary collapse

Constructor Details

#initialize(outline, codepoint: nil, base_font: nil) ⇒ Svg

Returns a new instance of Svg.

Parameters:

  • outline (Fontisan::Models::GlyphOutline)
  • codepoint (Integer, nil) (defaults to: nil)

    optional, for the ‘<title>`

  • base_font (String, nil) (defaults to: nil)

    optional source-font name, also for the ‘<title>` (debugging which PDF font a glyph came from)



30
31
32
33
34
# File 'lib/ucode/glyphs/embedded_fonts/svg.rb', line 30

def initialize(outline, codepoint: nil, base_font: nil)
  @outline = outline
  @codepoint = codepoint
  @base_font = base_font
end

Instance Method Details

#path_dataString

SVG path data with y already negated. Exposed for tests and for callers that want to embed the path in their own wrapper.

Returns:

  • (String)


51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ucode/glyphs/embedded_fonts/svg.rb', line 51

def path_data
  parts = []
  @outline.to_commands.each do |cmd|
    case cmd.first
    when :move_to then parts << format_cmd("M", cmd[1], cmd[2])
    when :line_to then parts << format_cmd("L", cmd[1], cmd[2])
    when :curve_to
      parts << format_cmd_q(cmd[1], cmd[2], cmd[3], cmd[4])
    when :close_path then parts << "Z"
    end
  end
  parts.join(" ")
end

#to_sString

Returns complete ‘<svg>…</svg>` document.

Returns:

  • (String)

    complete ‘<svg>…</svg>` document



37
38
39
40
41
42
43
44
45
# File 'lib/ucode/glyphs/embedded_fonts/svg.rb', line 37

def to_s
  box = view_box
  lines = []
  lines << %(<svg xmlns="http://www.w3.org/2000/svg" viewBox="#{format_dims(box)}" width="#{format_num(box[:width])}" height="#{format_num(box[:height])}" preserveAspectRatio="xMidYMid meet">)
  lines << %(  <title>#{title_text}</title>) if title_text
  lines << %(  <path d="#{path_data}" fill="currentColor" fill-rule="evenodd"/>)
  lines << %(</svg>)
  %(<?xml version="1.0" encoding="UTF-8"?>\n#{lines.join("\n")}\n)
end