Class: TokenReel::Renderer

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

Overview

Turns a Timeline::State into a terminal-window PNG. Text layout is done in Ruby (word wrap, cursor placement); ImageMagick just draws the rectangles and glyphs we tell it to.

Constant Summary collapse

HEADER_H =
40
PAD_X =
18
PAD_Y =
14
DOT_R =
6

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, timeline) ⇒ Renderer

Returns a new instance of Renderer.



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/token_reel/renderer.rb', line 22

def initialize(config, timeline)
  @config = config
  @timeline = timeline
  @palette = Theme.fetch(config.theme)
  @font = Fonts.resolve!(config.font)
  calibrate!
  # The window is a fixed config.rows lines tall, like a real
  # console -- every frame shares this height regardless of how
  # much text it holds.
  @total_lines = @config.rows
  @width = @config.cols * char_w + PAD_X * 2
  @height = HEADER_H + PAD_Y * 2 + total_lines * char_h
end

Instance Attribute Details

#char_hObject (readonly)

Returns the value of attribute char_h.



15
16
17
# File 'lib/token_reel/renderer.rb', line 15

def char_h
  @char_h
end

#char_wObject (readonly)

Returns the value of attribute char_w.



15
16
17
# File 'lib/token_reel/renderer.rb', line 15

def char_w
  @char_w
end

#total_linesObject (readonly)

Returns the value of attribute total_lines.



15
16
17
# File 'lib/token_reel/renderer.rb', line 15

def total_lines
  @total_lines
end

Class Method Details

.convert_binaryObject



17
18
19
20
# File 'lib/token_reel/renderer.rb', line 17

def self.convert_binary
  @convert_binary ||= %w[magick convert].find { |bin| system("which #{bin} > /dev/null 2>&1") } ||
                       raise(RenderError, "ImageMagick not found: install `imagemagick` (needs `convert` or `magick` on PATH)")
end

Instance Method Details

#render(state, out_path) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/token_reel/renderer.rb', line 36

def render(state, out_path)
  lines = wrap_body(state)
  # Once a frame's content outgrows the window, scroll: keep only
  # the most recent total_lines lines, same as a real terminal
  # dropping its oldest lines off the top.
  lines = lines.last(total_lines) if lines.size > total_lines
  pad = [total_lines - lines.size, 0].max
  lines += [{ text: "", color: @palette[:fg] }] * pad

  argv = ["-size", "#{@width}x#{@height}", "xc:#{@palette[:bg]}"]
  argv += header_bar_args
  y = HEADER_H + PAD_Y + char_h - (char_h * 0.28).round
  lines.each do |line|
    argv += line_args(line, y)
    y += char_h
  end
  argv << out_path

  run!(argv)
  out_path
end