Class: Charming::UI::BrailleCanvas

Inherits:
Object
  • Object
show all
Defined in:
lib/charming/presentation/ui/braille_canvas.rb

Overview

BrailleCanvas is a monochrome subpixel drawing surface backed by Unicode braille glyphs (U+2800–U+28FF). Each character cell packs a 2×4 grid of dots, so the canvas addresses width×height pixels while rendering to cols×rows cells — 8× the vertical and 2× the horizontal resolution of plain text. It's pure text (works on every terminal) and composes via row/column/Canvas like any other block. Used by Components::Chart.

Constant Summary collapse

BASE =

The first braille code point; OR-ing dot bits onto it yields the glyph for a cell.

0x2800
DOTS =

Dot bit for each (x%2, y%4) position within a cell, indexed DOTS[y % 4][x % 2].

[[0x01, 0x08], [0x02, 0x10], [0x04, 0x20], [0x40, 0x80]].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width, height) ⇒ BrailleCanvas

width and height are the drawable area in pixels (dots).



18
19
20
21
22
23
24
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 18

def initialize(width, height)
  @width = width
  @height = height
  @cols = (width + 1) / 2
  @rows = (height + 3) / 4
  @cells = Array.new(@rows) { Array.new(@cols, 0) }
end

Instance Attribute Details

#colsObject (readonly)

Returns the value of attribute cols.



26
27
28
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 26

def cols
  @cols
end

#heightObject (readonly)

Returns the value of attribute height.



26
27
28
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 26

def height
  @height
end

#rowsObject (readonly)

Returns the value of attribute rows.



26
27
28
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 26

def rows
  @rows
end

#widthObject (readonly)

Returns the value of attribute width.



26
27
28
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 26

def width
  @width
end

Instance Method Details

#line(x0, y0, x1, y1) ⇒ Object

Draws a straight line between (x0, y0) and (x1, y1) with Bresenham's algorithm. Returns self.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 49

def line(x0, y0, x1, y1)
  dx = (x1 - x0).abs
  dy = -(y1 - y0).abs
  sx = (x0 < x1) ? 1 : -1
  sy = (y0 < y1) ? 1 : -1
  err = dx + dy
  x = x0
  y = y0
  loop do
    set(x, y)
    break if x == x1 && y == y1

    e2 = 2 * err
    if e2 >= dy
      err += dy
      x += sx
    end
    if e2 <= dx
      err += dx
      y += sy
    end
  end
  self
end

#set(x, y, on: true) ⇒ Object

Turns the dot at pixel (x, y) on (or off when on: false). Out-of-range points are ignored. Returns self for chaining.



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 30

def set(x, y, on: true)
  return self unless x.between?(0, @width - 1) && y.between?(0, @height - 1)

  bit = DOTS[y % 4][x % 2]
  if on
    @cells[y / 4][x / 2] |= bit
  else
    @cells[y / 4][x / 2] &= ~bit
  end
  self
end

#to_sObject

Renders the canvas as rows lines of cols braille glyphs.



75
76
77
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 75

def to_s
  @cells.map { |row| row.map { |bits| (BASE + bits).chr(Encoding::UTF_8) }.join }.join("\n")
end

#unset(x, y) ⇒ Object

Turns the dot at pixel (x, y) off. Returns self.



43
44
45
# File 'lib/charming/presentation/ui/braille_canvas.rb', line 43

def unset(x, y)
  set(x, y, on: false)
end