Class: Fontisan::Tables::SimpleGlyph

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/tables/glyf/simple_glyph.rb

Overview

Represents a simple TrueType glyph with contours

A simple glyph is defined by one or more contours, where each contour is a closed path made up of on-curve and off-curve points. The points are stored using delta encoding to save space.

The glyph structure consists of:

  • Header: numberOfContours, xMin, yMin, xMax, yMax (10 bytes)
  • endPtsOfContours: array marking the last point of each contour
  • instructions: TrueType hinting instructions (optional)
  • flags: array of point flags (compressed with repeat counts)
  • xCoordinates: x-coordinates (delta-encoded, variable byte length)
  • yCoordinates: y-coordinates (delta-encoded, variable byte length)

Point flags (8-bit) indicate:

  • Bit 0 (0x01): ON_CURVE_POINT - point is on the curve
  • Bit 1 (0x02): X_SHORT_VECTOR - x-coordinate is 1 byte
  • Bit 2 (0x04): Y_SHORT_VECTOR - y-coordinate is 1 byte
  • Bit 3 (0x08): REPEAT_FLAG - repeat this flag n times
  • Bit 4 (0x10): X_IS_SAME_OR_POSITIVE_X_SHORT - x value interpretation
  • Bit 5 (0x20): Y_IS_SAME_OR_POSITIVE_Y_SHORT - y value interpretation

Reference: OpenType specification, glyf table - Simple Glyph Description https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#simple-glyph-description

Constant Summary collapse

ON_CURVE_POINT =

Flag constants

0x01
X_SHORT_VECTOR =
0x02
Y_SHORT_VECTOR =
0x04
REPEAT_FLAG =
0x08
X_IS_SAME_OR_POSITIVE_X_SHORT =
0x10
Y_IS_SAME_OR_POSITIVE_Y_SHORT =
0x20

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(glyph_id) ⇒ SimpleGlyph

Initialize a new simple glyph

Parameters:

  • glyph_id (Integer)

    Glyph ID



61
62
63
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 61

def initialize(glyph_id)
  @glyph_id = glyph_id
end

Instance Attribute Details

#end_pts_of_contoursObject (readonly)

Glyph data fields



44
45
46
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 44

def end_pts_of_contours
  @end_pts_of_contours
end

#flagsObject (readonly)

Returns the value of attribute flags.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def flags
  @flags
end

#glyph_idObject (readonly)

Glyph header fields



39
40
41
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 39

def glyph_id
  @glyph_id
end

#instruction_lengthObject (readonly)

Returns the value of attribute instruction_length.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def instruction_length
  @instruction_length
end

#instructionsObject (readonly)

Returns the value of attribute instructions.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def instructions
  @instructions
end

#num_contoursObject (readonly)

Returns the value of attribute num_contours.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def num_contours
  @num_contours
end

#x_coordinatesObject (readonly)

Returns the value of attribute x_coordinates.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def x_coordinates
  @x_coordinates
end

#x_maxObject (readonly)

Returns the value of attribute x_max.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def x_max
  @x_max
end

#x_minObject (readonly)

Returns the value of attribute x_min.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def x_min
  @x_min
end

#y_coordinatesObject (readonly)

Returns the value of attribute y_coordinates.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def y_coordinates
  @y_coordinates
end

#y_maxObject (readonly)

Returns the value of attribute y_max.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def y_max
  @y_max
end

#y_minObject (readonly)

Returns the value of attribute y_min.



40
41
42
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 40

def y_min
  @y_min
end

Class Method Details

.parse(data, glyph_id) ⇒ SimpleGlyph

Parse simple glyph data

Parameters:

  • data (String)

    Binary glyph data

  • glyph_id (Integer)

    Glyph ID for error reporting

Returns:

Raises:



52
53
54
55
56
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 52

def self.parse(data, glyph_id)
  glyph = new(glyph_id)
  glyph.parse_data(data)
  glyph
end

Instance Method Details

#bounding_boxArray<Integer>

Get bounding box as array

Returns:

  • (Array<Integer>)

    Bounding box [xMin, yMin, xMax, yMax]



106
107
108
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 106

def bounding_box
  [x_min, y_min, x_max, y_max]
end

#compound?Boolean

Check if this is a compound glyph

Returns:

  • (Boolean)

    Always false for SimpleGlyph



92
93
94
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 92

def compound?
  false
end

#contour_for_point(point_index) ⇒ Integer?

Get contour for a specific point

Parameters:

  • point_index (Integer)

    Point index (0-based)

Returns:

  • (Integer, nil)

    Contour index (0-based) or nil if invalid



133
134
135
136
137
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 133

def contour_for_point(point_index)
  return nil if point_index.negative? || point_index >= num_points

  end_pts_of_contours.index { |end_pt| point_index <= end_pt }
end

#empty?Boolean

Check if glyph has no outline data

Returns:

  • (Boolean)

    True if no contours



99
100
101
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 99

def empty?
  num_contours.zero?
end

#num_pointsInteger

Get total number of points

Returns:

  • (Integer)

    Total points in all contours



113
114
115
116
117
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 113

def num_points
  return 0 if empty?

  end_pts_of_contours.last + 1
end

#on_curve?(index) ⇒ Boolean?

Check if a specific point is on the curve

Parameters:

  • index (Integer)

    Point index (0-based)

Returns:

  • (Boolean, nil)

    True if on curve, false if off curve, nil if invalid



123
124
125
126
127
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 123

def on_curve?(index)
  return nil if index.negative? || index >= num_points

  (flags[index] & ON_CURVE_POINT) != 0
end

#parse_data(data) ⇒ Object

Parse glyph data

Parameters:

  • data (String)

    Binary glyph data

Raises:



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 69

def parse_data(data)
  io = StringIO.new(data)
  io.set_encoding(Encoding::BINARY)

  parse_header(io)
  parse_contour_ends(io)
  parse_instructions(io)
  parse_flags(io)
  parse_coordinates(io)

  validate_parsed_data!
end

#points_for_contour(contour_index) ⇒ Array<Hash>?

Get all points for a specific contour

Parameters:

  • contour_index (Integer)

    Contour index (0-based)

Returns:

  • (Array<Hash>, nil)

    Array of point hashes or nil if invalid



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 143

def points_for_contour(contour_index)
  return nil if contour_index.negative? || contour_index >= num_contours

  start_pt = contour_index.zero? ? 0 : end_pts_of_contours[contour_index - 1] + 1
  end_pt = end_pts_of_contours[contour_index]

  (start_pt..end_pt).map do |i|
    {
      x: x_coordinates[i],
      y: y_coordinates[i],
      on_curve: on_curve?(i),
    }
  end
end

#simple?Boolean

Check if this is a simple glyph

Returns:

  • (Boolean)

    Always true for SimpleGlyph



85
86
87
# File 'lib/fontisan/tables/glyf/simple_glyph.rb', line 85

def simple?
  true
end