Class: Clogs::TextBlock

Inherits:
Object
  • Object
show all
Defined in:
lib/clogs/text.rb

Overview

A laid-out paragraph.

libui gives us Pango/DirectWrite/Core Text via uiDrawTextLayout: an attributed string plus a wrap width, and it reports the resulting extents. That covers Shoes' text model (a paragraph of differently-styled spans that wraps) without us writing a line breaker.

What it does not give us is per-character hit testing or caret geometry, which is why Clogs' own text editing (edit_line / edit_box) measures substrings instead of asking the layout where a click landed.

Constant Summary collapse

ALIGN_LEFT =
0
ALIGN_CENTER =
1
ALIGN_RIGHT =
2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(runs, wrap_width, align: ALIGN_LEFT, default_family: nil, default_size: nil) ⇒ TextBlock

Returns a new instance of TextBlock.



30
31
32
33
34
35
36
37
# File 'lib/clogs/text.rb', line 30

def initialize(runs, wrap_width, align: ALIGN_LEFT, default_family: nil, default_size: nil)
  @runs = runs
  @wrap_width = wrap_width.to_f
  @align = align
  @default_family = default_family || Clogs.default_font_family
  @default_size = default_size || Clogs.default_font_size
  build
end

Instance Attribute Details

#heightObject (readonly)

Returns the value of attribute height.



28
29
30
# File 'lib/clogs/text.rb', line 28

def height
  @height
end

#runsObject (readonly)

Returns the value of attribute runs.



28
29
30
# File 'lib/clogs/text.rb', line 28

def runs
  @runs
end

#widthObject (readonly)

Returns the value of attribute width.



28
29
30
# File 'lib/clogs/text.rb', line 28

def width
  @width
end

Instance Method Details

#draw(painter, x, y) ⇒ Object



39
40
41
# File 'lib/clogs/text.rb', line 39

def draw(painter, x, y)
  painter.draw_text(@layout, x, y)
end

#freeObject



67
68
69
70
71
72
# File 'lib/clogs/text.rb', line 67

def free
  UI::L.draw_free_text_layout(@layout) if @layout
  UI::L.free_attributed_string(@astr) if @astr
  @layout = nil
  @astr = nil
end

#plain_textObject



63
64
65
# File 'lib/clogs/text.rb', line 63

def plain_text
  @plain_text ||= @runs.map { |r| r.text.to_s }.join
end

#prefix_width(n) ⇒ Object

Width of the first n characters, used to place text carets.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/clogs/text.rb', line 44

def prefix_width(n)
  return 0.0 if n <= 0

  text = plain_text
  n = text.length if n > text.length
  @prefix_cache ||= {}
  @prefix_cache[n] ||= begin
    sub = TextBlock.new(
      [Run.new(text: text[0, n], **first_style)],
      -1,
      default_family: @default_family,
      default_size: @default_size
    )
    w = sub.width
    sub.free
    w
  end
end