Class: Ucode::Glyphs::LastResort::Svg

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

Overview

Converts a Glif::Outline into a standalone SVG document.

Two transforms are applied:

1. **Y-axis flip.** UFO point y grows upward (PostScript
   convention); SVG y grows downward. We reflect y about the
   glyph's vertical midpoint so the rendered glyph appears
   upright.

2. **ViewBox normalization.** The viewBox is set to the
   outline's bounding box, with a small padding so strokes
   are not clipped at the edges. The `width`/`height`
   attributes match the viewBox aspect ratio so consumers
   can scale via CSS.

Path data semantics:

* `move`   → `M x y`
* `line`   → `L x y`
* `curve`  → `C cx1 cy1 cx2 cy2 x y` (cubic; preceding 1–2
            off-curve points are control points)
* `qcurve` → `Q cx cy x y` (quadratic; ≥1 preceding off-curve
            points; multiple off-curves are emitted as chained
            quadratic segments with implicit on-curve midpoints
            per the UFO spec)

Contours are closed with ‘Z` per UFO convention.

Instance Method Summary collapse

Constructor Details

#initialize(outline, codepoint: nil) ⇒ Svg

Returns a new instance of Svg.

Parameters:

  • outline (Glif::Outline)
  • codepoint (Integer, nil) (defaults to: nil)

    optional codepoint for the ‘<title>` element (accessibility + debugging)



43
44
45
46
# File 'lib/ucode/glyphs/last_resort/svg.rb', line 43

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

Instance Method Details

#path_dataString

Just the path ‘d` attribute — exposed for tests and for callers that want to embed the path inside their own SVG wrapper.

Returns:

  • (String)


63
64
65
# File 'lib/ucode/glyphs/last_resort/svg.rb', line 63

def path_data
  @outline.contours.map { |contour| PathBuilder.new(contour.points).to_path }.join(" ")
end

#to_sString

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

Returns:

  • (String)

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



49
50
51
52
53
54
55
56
57
# File 'lib/ucode/glyphs/last_resort/svg.rb', line 49

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>U+#{format("%04X", @codepoint)} (Last Resort)</title>) if @codepoint
  lines << %(  <path d="#{path_data.strip}" fill="currentColor" fill-rule="evenodd"/>)
  lines << %(</svg>)
  %(<?xml version="1.0" encoding="UTF-8"?>\n#{lines.join("\n")}\n)
end