Class: Fontisan::Ufo::Bounds

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/fontisan/ufo/bounds.rb

Overview

Immutable axis-aligned bounding box over outline points.

Bounds is a value object: equality and hash are based on the four coordinates, not identity. Bounds composes via #union so callers can fold bounds across many contours or many glyphs without mutating either side.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(min_x:, min_y:, max_x:, max_y:) ⇒ Bounds

Returns a new instance of Bounds.



16
17
18
19
20
21
# File 'lib/fontisan/ufo/bounds.rb', line 16

def initialize(min_x:, min_y:, max_x:, max_y:)
  @min_x = min_x.to_f
  @min_y = min_y.to_f
  @max_x = max_x.to_f
  @max_y = max_y.to_f
end

Instance Attribute Details

#max_xObject (readonly)

Returns the value of attribute max_x.



14
15
16
# File 'lib/fontisan/ufo/bounds.rb', line 14

def max_x
  @max_x
end

#max_yObject (readonly)

Returns the value of attribute max_y.



14
15
16
# File 'lib/fontisan/ufo/bounds.rb', line 14

def max_y
  @max_y
end

#min_xObject (readonly)

Returns the value of attribute min_x.



14
15
16
# File 'lib/fontisan/ufo/bounds.rb', line 14

def min_x
  @min_x
end

#min_yObject (readonly)

Returns the value of attribute min_y.



14
15
16
# File 'lib/fontisan/ufo/bounds.rb', line 14

def min_y
  @min_y
end

Class Method Details

.emptyBounds

Returns zero-extent bounds anchored at the origin.

Returns:

  • (Bounds)

    zero-extent bounds anchored at the origin



46
47
48
# File 'lib/fontisan/ufo/bounds.rb', line 46

def self.empty
  new(min_x: 0, min_y: 0, max_x: 0, max_y: 0)
end

.measure(contours) ⇒ Bounds

Parameters:

Returns:



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/fontisan/ufo/bounds.rb', line 25

def self.measure(contours)
  min_x = min_y = +Float::INFINITY
  max_x = max_y = -Float::INFINITY
  saw_point = false

  contours.each do |contour|
    contour.points.each do |pt|
      saw_point = true
      min_x = pt.x if pt.x < min_x
      min_y = pt.y if pt.y < min_y
      max_x = pt.x if pt.x > max_x
      max_y = pt.y if pt.y > max_y
    end
  end

  return empty unless saw_point

  new(min_x: min_x, min_y: min_y, max_x: max_x, max_y: max_y)
end

Instance Method Details

#<=>(other) ⇒ Object



79
80
81
82
83
84
# File 'lib/fontisan/ufo/bounds.rb', line 79

def <=>(other)
  return nil unless other.is_a?(Bounds)

  [@min_x, @min_y, @max_x, @max_y] <=>
    [other.min_x, other.min_y, other.max_x, other.max_y]
end

#empty?Boolean

A bounds is empty when it has zero extent in both axes. Note that a contour containing a single point yields zero-extent bounds but is not "empty" in the geometric sense — callers that need to distinguish should test the contour directly.

Returns:

  • (Boolean)


62
63
64
# File 'lib/fontisan/ufo/bounds.rb', line 62

def empty?
  width.zero? && height.zero?
end

#hashObject



86
87
88
# File 'lib/fontisan/ufo/bounds.rb', line 86

def hash
  [@min_x, @min_y, @max_x, @max_y].hash
end

#heightObject



54
55
56
# File 'lib/fontisan/ufo/bounds.rb', line 54

def height
  max_y - min_y
end

#union(other) ⇒ Bounds

Smallest bounds containing both self and other.

Parameters:

Returns:



70
71
72
73
74
75
76
77
# File 'lib/fontisan/ufo/bounds.rb', line 70

def union(other)
  self.class.new(
    min_x: [@min_x, other.min_x].min,
    min_y: [@min_y, other.min_y].min,
    max_x: [@max_x, other.max_x].max,
    max_y: [@max_y, other.max_y].max,
  )
end

#widthObject



50
51
52
# File 'lib/fontisan/ufo/bounds.rb', line 50

def width
  max_x - min_x
end