Class: Thaum::Rendering::Canvas

Inherits:
Object
  • Object
show all
Defined in:
lib/thaum/rendering/canvas.rb

Constant Summary collapse

BORDERS =
{
  single:  { tl: "", tr: "", bl: "", br: "", h: "", v: "" },
  rounded: { tl: "", tr: "", bl: "", br: "", h: "", v: "" },
  double:  { tl: "", tr: "", bl: "", br: "", h: "", v: "" },
  thick:   { tl: "", tr: "", bl: "", br: "", h: "", v: "" },
  # Dashed + dotted reuse the light corner glyphs — Unicode does not
  # define dashed corners. The horizontal/vertical runs use 2-dash
  # (dashed) or 4-dash (dotted, denser-looking) light glyphs.
  dashed:  { tl: "", tr: "", bl: "", br: "", h: "", v: "" },
  dotted:  { tl: "", tr: "", bl: "", br: "", h: "", v: "" },
  ascii:   { tl: "+", tr: "+", bl: "+", br: "+", h: "-", v: "|" }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(buffer:, rect:) ⇒ Canvas

Returns a new instance of Canvas.



22
23
24
25
# File 'lib/thaum/rendering/canvas.rb', line 22

def initialize(buffer:, rect:)
  @buffer = buffer
  @rect   = rect
end

Instance Attribute Details

#rectObject (readonly)

Returns the value of attribute rect.



20
21
22
# File 'lib/thaum/rendering/canvas.rb', line 20

def rect
  @rect
end

Instance Method Details

#border(fg: nil, bg: nil, style: :single) ⇒ Object

Draws a box around the perimeter and returns the inset canvas (w-2 × h-2) so callers can render contents inside. style is one of BORDERS’ keys.



56
57
58
59
60
61
62
# File 'lib/thaum/rendering/canvas.rb', line 56

def border(fg: nil, bg: nil, style: :single)
  chars = BORDERS.fetch(style) { raise ArgumentError, "unknown border style: #{style.inspect}" }
  return inset(1) if @rect.width < 2 || @rect.height < 2

  draw_border(chars: chars, fg: fg, bg: bg)
  inset(1)
end

#bottom(n) ⇒ Object



84
85
86
87
# File 'lib/thaum/rendering/canvas.rb', line 84

def bottom(n)
  child_canvas(Rect.new(x: @rect.x, y: @rect.y + @rect.height - n, width: @rect.width,
                        height: [n, @rect.height].min))
end

#cursor(x:, y:) ⇒ Object



50
51
52
# File 'lib/thaum/rendering/canvas.rb', line 50

def cursor(x:, y:)
  @buffer.cursor = [@rect.x + x, @rect.y + y]
end

#fill(char: " ", fg: nil, bg: nil, x: 0, y: 0, width: @rect.width, height: @rect.height) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/thaum/rendering/canvas.rb', line 32

def fill(char: " ", fg: nil, bg: nil, x: 0, y: 0, width: @rect.width, height: @rect.height)
  height.times do |dy|
    width.times do |dx|
      cx = @rect.x + x + dx
      cy = @rect.y + y + dy
      @buffer.set(x: cx, y: cy, char: char, style: blend_style(cx: cx, cy: cy, fg: fg, bg: bg))
    end
  end
end

#heightObject



30
# File 'lib/thaum/rendering/canvas.rb', line 30

def height = @rect.height

#inset(n_or_opts) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/thaum/rendering/canvas.rb', line 98

def inset(n_or_opts)
  if n_or_opts.is_a?(Integer)
    n = n_or_opts
    child_canvas(Rect.new(x: @rect.x + n, y: @rect.y + n, width: @rect.width - (n * 2),
                          height: @rect.height - (n * 2)))
  else
    t = n_or_opts[:top]    || 0
    r = n_or_opts[:right]  || 0
    b = n_or_opts[:bottom] || 0
    l = n_or_opts[:left]   || 0
    child_canvas(Rect.new(x: @rect.x + l, y: @rect.y + t, width: @rect.width - l - r,
                          height: @rect.height - t - b))
  end
end

#left(n) ⇒ Object



89
90
91
# File 'lib/thaum/rendering/canvas.rb', line 89

def left(n)
  child_canvas(Rect.new(x: @rect.x, y: @rect.y, width: [n, @rect.width].min, height: @rect.height))
end

#measure(content:, wrap: :none, width: @rect.width) ⇒ Object



64
65
66
67
# File 'lib/thaum/rendering/canvas.rb', line 64

def measure(content:, wrap: :none, width: @rect.width)
  lines = wrap == :none ? [content.to_s] : wrap_lines(text: content.to_s, width: width)
  { width: lines.map(&:display_width).max || 0, height: lines.size }
end

#right(n) ⇒ Object



93
94
95
96
# File 'lib/thaum/rendering/canvas.rb', line 93

def right(n)
  child_canvas(Rect.new(x: @rect.x + @rect.width - n, y: @rect.y, width: [n, @rect.width].min,
                        height: @rect.height))
end

#row(n) ⇒ Object



69
70
71
72
73
# File 'lib/thaum/rendering/canvas.rb', line 69

def row(n)
  return nil if n.negative? || n >= @rect.height

  child_canvas(Rect.new(x: @rect.x, y: @rect.y + n, width: @rect.width, height: 1))
end

#sub(rect:) ⇒ Object

rect is in local coordinates (relative to this canvas’s origin).



76
77
78
# File 'lib/thaum/rendering/canvas.rb', line 76

def sub(rect:)
  child_canvas(Rect.new(x: @rect.x + rect.x, y: @rect.y + rect.y, width: rect.width, height: rect.height))
end

#text(content:, fg: nil, bg: nil, x: 0, y: 0, align: :left, wrap: :none, **_opts) ⇒ Object



42
43
44
45
46
47
48
# File 'lib/thaum/rendering/canvas.rb', line 42

def text(content:, fg: nil, bg: nil, x: 0, y: 0, align: :left, wrap: :none, **_opts)
  if content.is_a?(Array)
    draw_styled_runs(runs: content, x: x, y: y, align: align)
  else
    draw_string_text(content: content.to_s, x: x, y: y, align: align, wrap: wrap, fg: fg, bg: bg)
  end
end

#top(n) ⇒ Object



80
81
82
# File 'lib/thaum/rendering/canvas.rb', line 80

def top(n)
  child_canvas(Rect.new(x: @rect.x, y: @rect.y, width: @rect.width, height: [n, @rect.height].min))
end

#widthObject



29
# File 'lib/thaum/rendering/canvas.rb', line 29

def width  = @rect.width

#xObject



27
# File 'lib/thaum/rendering/canvas.rb', line 27

def x      = @rect.x

#yObject



28
# File 'lib/thaum/rendering/canvas.rb', line 28

def y      = @rect.y