Class: Arrolio::GlyphMeasurer

Inherits:
Object
  • Object
show all
Defined in:
lib/arrolio/glyph_measurer.rb

Overview

High-level facade over FontMetrics. Used by TextLayout, TableLayout, ImageFlowable, etc. — anything that needs to ask "how wide is this string at this size in this font?".

Encapsulates the relationship between character_spacing (Tc), word_spacing (Tw), and the underlying glyph widths — matches what the renderer actually emits.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(font_name:, style: :regular) ⇒ GlyphMeasurer

Returns a new instance of GlyphMeasurer.



14
15
16
17
18
# File 'lib/arrolio/glyph_measurer.rb', line 14

def initialize(font_name:, style: :regular)
  @font_name = font_name.to_s
  @style = style
  @metrics = ::Arrolio::FontMetrics::Registry[@font_name]
end

Instance Attribute Details

#font_nameObject (readonly)

Returns the value of attribute font_name.



12
13
14
# File 'lib/arrolio/glyph_measurer.rb', line 12

def font_name
  @font_name
end

#metricsObject (readonly)

Returns the value of attribute metrics.



12
13
14
# File 'lib/arrolio/glyph_measurer.rb', line 12

def metrics
  @metrics
end

Instance Method Details

#advance_width(char, font_size:) ⇒ Object



42
43
44
45
46
# File 'lib/arrolio/glyph_measurer.rb', line 42

def advance_width(char, font_size:)
  return estimate(char, font_size) unless available?

  @metrics.advance_width(char) * font_size.to_f / @metrics.units_per_em
end

#ascender(font_size:) ⇒ Object



48
# File 'lib/arrolio/glyph_measurer.rb', line 48

def ascender(font_size:) = @metrics&.ascender(font_size: font_size) || (font_size * 0.8)

#available?Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/arrolio/glyph_measurer.rb', line 20

def available?
  !@metrics.nil?
end

#cap_height(font_size:) ⇒ Object



50
# File 'lib/arrolio/glyph_measurer.rb', line 50

def cap_height(font_size:) = @metrics&.cap_height(font_size: font_size) || (font_size * 0.7)

#descender(font_size:) ⇒ Object



49
# File 'lib/arrolio/glyph_measurer.rb', line 49

def descender(font_size:) = @metrics&.descender(font_size: font_size) || -(font_size * 0.2)

#line_height(font_size:, line_spacing: 1.2) ⇒ Object



52
53
54
55
56
# File 'lib/arrolio/glyph_measurer.rb', line 52

def line_height(font_size:, line_spacing: 1.2)
  return font_size * 1.2 unless available?

  @metrics.line_height(font_size: font_size, line_spacing: line_spacing)
end

#space_width(font_size:) ⇒ Object



58
59
60
# File 'lib/arrolio/glyph_measurer.rb', line 58

def space_width(font_size:)
  advance_width(' ', font_size: font_size)
end

#width_of_run(str, font_size:, character_spacing: 0, word_spacing: 0) ⇒ Object

Width of a run including character_spacing (Tc — extra space added after every glyph) and word_spacing (Tw — extra space added after every space glyph). Matches PDF rendering rules.



33
34
35
36
37
38
39
40
# File 'lib/arrolio/glyph_measurer.rb', line 33

def width_of_run(str, font_size:, character_spacing: 0, word_spacing: 0)
  base = width_of_string(str, font_size: font_size)
  char_count = str.length
  word_count = str.count('  ')
  extra = (character_spacing.to_f * [char_count - 1, 0].max) +
    (word_spacing.to_f * word_count)
  base + extra
end

#width_of_string(str, font_size:) ⇒ Object



24
25
26
27
28
# File 'lib/arrolio/glyph_measurer.rb', line 24

def width_of_string(str, font_size:)
  return estimate(str, font_size) unless available?

  @metrics.width_of_string(str, font_size: font_size)
end