Class: Thaum::Rendering::Renderer

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

Instance Method Summary collapse

Constructor Details

#initialize(output: $stdout, capability: :truecolor) ⇒ Renderer

Returns a new instance of Renderer.



7
8
9
10
11
12
# File 'lib/thaum/rendering/renderer.rb', line 7

def initialize(output: $stdout, capability: :truecolor)
  @output = output
  @out = +""
  @prev_buffer = nil
  @capability = capability
end

Instance Method Details

#render(buffer) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/thaum/rendering/renderer.rb', line 14

def render(buffer)
  @out.clear
  full_redraw = @prev_buffer.nil? ||
                @prev_buffer.width != buffer.width ||
                @prev_buffer.height != buffer.height
  prev_style = nil
  any_writes = false

  buffer.height.times do |y|
    if full_redraw
      first_x = 0
      last_x  = buffer.width - 1
    else
      first_x, last_x = dirty_span(buffer: buffer, y: y)
      next unless first_x
    end

    # Emit the full span between the first and last dirty cells. Skipping
    # unchanged cells inside the span and jumping the cursor over them
    # would leave their on-screen state untouched, which is only safe if
    # the terminal really mirrors prev_buffer at those positions. When
    # consecutive themes share slot values, that assumption produces the
    # bug where swatches keep stale pixels across transitions.
    @out << Seq.cursor_pos(x: first_x + 1, y: y + 1)
    (first_x..last_x).each do |x|
      cell = buffer.cell(x: x, y: y)
      emit_style(style: cell.style, prev: prev_style)
      @out << cell.char
      prev_style = cell.style
    end
    any_writes = true
  end

  @out << Seq::RESET if any_writes

  emit_cursor(buffer: buffer, full_redraw: full_redraw)

  @prev_buffer = buffer
  return if @out.empty?

  @output.write(Seq::SYNC_BEGIN, @out, Seq::SYNC_END)
  @output.flush
end