Class: Fontisan::Ufo::Glyph
- Inherits:
-
Object
- Object
- Fontisan::Ufo::Glyph
- Defined in:
- lib/fontisan/ufo/glyph.rb
Overview
A glyph in a UFO source. Holds contours, components, anchors,
guidelines, images, unicode codepoints, advance width/height,
and a custom-data bag (lib).
The .glif XML format has multiple revisions (1, 2, 3); the
parser accepts all of them.
Instance Attribute Summary collapse
-
#anchors ⇒ Object
readonly
Returns the value of attribute anchors.
-
#components ⇒ Object
readonly
Returns the value of attribute components.
-
#contours ⇒ Object
readonly
Returns the value of attribute contours.
-
#guidelines ⇒ Object
readonly
Returns the value of attribute guidelines.
-
#height ⇒ Object
Returns the value of attribute height.
-
#images ⇒ Object
readonly
Returns the value of attribute images.
-
#lib ⇒ Object
Returns the value of attribute lib.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#note ⇒ Object
Returns the value of attribute note.
-
#unicodes ⇒ Object
readonly
Returns the value of attribute unicodes.
-
#width ⇒ Object
Returns the value of attribute width.
Class Method Summary collapse
-
.from_glif(xml) ⇒ Glyph
Parsed glyph.
Instance Method Summary collapse
- #add_anchor(anchor) ⇒ Object
- #add_component(component) ⇒ Object
- #add_contour(contour) ⇒ Object
- #add_guideline(guideline) ⇒ Object
- #add_image(image) ⇒ Object
- #add_unicode(codepoint) ⇒ Object
-
#bbox ⇒ BoundingBox?
Axis-aligned bbox of contours.
-
#composite? ⇒ Boolean
Composite glyphs reference other glyphs via components.
-
#initialize(name:) ⇒ Glyph
constructor
A new instance of Glyph.
-
#point_count ⇒ Object
Total number of points across all contours.
-
#read_from(root) ⇒ Object
Populate this glyph from a
Nokogiri node. -
#to_glif ⇒ String
Render this glyph back to .glif XML.
-
#to_outline ⇒ Fontisan::Models::Outline
Convert this glyph to a fontisan Models::Outline for use by the CFF charstring builder.
Constructor Details
#initialize(name:) ⇒ Glyph
Returns a new instance of Glyph.
18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/fontisan/ufo/glyph.rb', line 18 def initialize(name:) @name = name.to_s @unicodes = [] @width = 0.0 @height = 0.0 @contours = [] @components = [] @anchors = [] @guidelines = [] @images = [] @note = nil @lib = Lib.new end |
Instance Attribute Details
#anchors ⇒ Object (readonly)
Returns the value of attribute anchors.
15 16 17 |
# File 'lib/fontisan/ufo/glyph.rb', line 15 def anchors @anchors end |
#components ⇒ Object (readonly)
Returns the value of attribute components.
15 16 17 |
# File 'lib/fontisan/ufo/glyph.rb', line 15 def components @components end |
#contours ⇒ Object (readonly)
Returns the value of attribute contours.
15 16 17 |
# File 'lib/fontisan/ufo/glyph.rb', line 15 def contours @contours end |
#guidelines ⇒ Object (readonly)
Returns the value of attribute guidelines.
15 16 17 |
# File 'lib/fontisan/ufo/glyph.rb', line 15 def guidelines @guidelines end |
#height ⇒ Object
Returns the value of attribute height.
14 15 16 |
# File 'lib/fontisan/ufo/glyph.rb', line 14 def height @height end |
#images ⇒ Object (readonly)
Returns the value of attribute images.
15 16 17 |
# File 'lib/fontisan/ufo/glyph.rb', line 15 def images @images end |
#lib ⇒ Object
Returns the value of attribute lib.
14 15 16 |
# File 'lib/fontisan/ufo/glyph.rb', line 14 def lib @lib end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
15 16 17 |
# File 'lib/fontisan/ufo/glyph.rb', line 15 def name @name end |
#note ⇒ Object
Returns the value of attribute note.
14 15 16 |
# File 'lib/fontisan/ufo/glyph.rb', line 14 def note @note end |
#unicodes ⇒ Object (readonly)
Returns the value of attribute unicodes.
15 16 17 |
# File 'lib/fontisan/ufo/glyph.rb', line 15 def unicodes @unicodes end |
#width ⇒ Object
Returns the value of attribute width.
14 15 16 |
# File 'lib/fontisan/ufo/glyph.rb', line 14 def width @width end |
Class Method Details
Instance Method Details
#add_anchor(anchor) ⇒ Object
46 47 48 49 |
# File 'lib/fontisan/ufo/glyph.rb', line 46 def add_anchor(anchor) @anchors << anchor anchor end |
#add_component(component) ⇒ Object
41 42 43 44 |
# File 'lib/fontisan/ufo/glyph.rb', line 41 def add_component(component) @components << component component end |
#add_contour(contour) ⇒ Object
36 37 38 39 |
# File 'lib/fontisan/ufo/glyph.rb', line 36 def add_contour(contour) @contours << contour contour end |
#add_guideline(guideline) ⇒ Object
51 52 53 54 |
# File 'lib/fontisan/ufo/glyph.rb', line 51 def add_guideline(guideline) @guidelines << guideline guideline end |
#add_image(image) ⇒ Object
56 57 58 59 |
# File 'lib/fontisan/ufo/glyph.rb', line 56 def add_image(image) @images << image image end |
#add_unicode(codepoint) ⇒ Object
32 33 34 |
# File 'lib/fontisan/ufo/glyph.rb', line 32 def add_unicode(codepoint) @unicodes << codepoint.to_i end |
#bbox ⇒ BoundingBox?
Returns axis-aligned bbox of contours.
72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/fontisan/ufo/glyph.rb', line 72 def bbox return nil if @contours.empty? points = @contours.flat_map(&:points) return nil if points.empty? BoundingBox.new( x_min: points.map(&:x).min, y_min: points.map(&:y).min, x_max: points.map(&:x).max, y_max: points.map(&:y).max, ) end |
#composite? ⇒ Boolean
Composite glyphs reference other glyphs via components.
62 63 64 |
# File 'lib/fontisan/ufo/glyph.rb', line 62 def composite? !@components.empty? end |
#point_count ⇒ Object
Total number of points across all contours.
67 68 69 |
# File 'lib/fontisan/ufo/glyph.rb', line 67 def point_count @contours.sum(&:point_count) end |
#read_from(root) ⇒ Object
Populate this glyph from a
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/fontisan/ufo/glyph.rb', line 110 def read_from(root) read_advance(root) read_unicodes(root) read_outline(root) read_anchors(root) read_guidelines(root) read_image(root) read_lib(root) read_note(root) end |
#to_glif ⇒ String
Render this glyph back to .glif XML.
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/fontisan/ufo/glyph.rb', line 96 def to_glif builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| xml.glyph(name: @name, format: "2") do emit_advance(xml) emit_unicodes(xml) emit_outline(xml) emit_lib(xml) emit_note(xml) end end builder.to_xml end |
#to_outline ⇒ Fontisan::Models::Outline
Convert this glyph to a fontisan Models::Outline for use by the CFF charstring builder.
UFO contours use cubic Bezier curves ("curve" type with two off-curve controls). Single off-curves are interpreted as quadratic and degree-elevated to cubic.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/fontisan/ufo/glyph.rb', line 129 def to_outline commands = [] bbox_hash = { x_min: 0, y_min: 0, x_max: 0, y_max: 0 } @contours.each do |contour| next if contour.points.empty? points = contour.points commands << { type: :move_to, x: points.first.x, y: points.first.y } i = 1 while i < points.size pt = points[i] if pt.on_curve? commands << { type: :line_to, x: pt.x, y: pt.y } i += 1 elsif i + 2 < points.size && !points[i + 1].on_curve? && points[i + 2].on_curve? commands << { type: :curve_to, cx1: points[i].x, cy1: points[i].y, cx2: points[i + 1].x, cy2: points[i + 1].y, x: points[i + 2].x, y: points[i + 2].y } i += 3 elsif i + 1 < points.size && points[i + 1].on_curve? prev = points[i - 1] nxt = points[i + 1] cx1 = prev.x + (2.0 / 3.0) * (pt.x - prev.x) cy1 = prev.y + (2.0 / 3.0) * (pt.y - prev.y) cx2 = nxt.x + (2.0 / 3.0) * (pt.x - nxt.x) cy2 = nxt.y + (2.0 / 3.0) * (pt.y - nxt.y) commands << { type: :curve_to, cx1: cx1, cy1: cy1, cx2: cx2, cy2: cy2, x: nxt.x, y: nxt.y } i += 2 else i += 1 end end commands << { type: :close_path } end bb = bbox if bb bbox_hash = { x_min: bb.x_min.to_i, y_min: bb.y_min.to_i, x_max: bb.x_max.to_i, y_max: bb.y_max.to_i } end Fontisan::Models::Outline.new( glyph_id: 0, commands: commands, bbox: bbox_hash, width: @width.to_i, ) end |