Constants
ASCII_DECODE_512 = begin
table =
Array(
Char).new(512, ' ')
sorted_lookup =
ASCII_LOOKUP_MAP.to_a.sort_by do |k, _v| k end
(0_u32...512_u32).each do |pattern|
if pattern == 0
table[pattern] = ' '
elsif
ASCII_LOOKUP_MAP.has_key?(pattern)
table[pattern] =
ASCII_LOOKUP_MAP[pattern]
else
best_char = ' '
best_dist =
Int32::MAX
sorted_lookup.each do |__temp_74|
k, v = __temp_74
dist = 0
x = pattern ^ k
while x != 0
if (x & 1) != 0
dist = dist + 1
end
x = x >> 1
end
if dist < best_dist
best_dist = dist
best_char = v
end
end
table[pattern] = best_char
end
end
table
end
Full 512-entry decode table built at startup.
For unmapped patterns, the closest entry by Hamming distance is used.
ASCII_LOOKUP_MAP = {320_u32 => '"', 511_u32 => '@', 128_u32 => '\'', 162_u32 => '(', 138_u32 => ')', 16_u32 => '*', 186_u32 => '+', 18_u32 => ',', 36_u32 => ',', 9_u32 => ',', 56_u32 => '-', 2_u32 => '.', 4_u32 => '.', 1_u32 => '.', 84_u32 => '/', 160_u32 => '/', 86_u32 => '/', 210_u32 => '/', 82_u32 => '/', 407_u32 => '1', 130_u32 => ':', 455_u32 => '=', 471_u32 => 'I', 295_u32 => 'L', 466_u32 => 'T', 362_u32 => 'V', 341_u32 => 'X', 338_u32 => 'Y', 422_u32 => '[', 136_u32 => '\\', 273_u32 => '\\', 402_u32 => '\\', 275_u32 => '\\', 274_u32 => '\\', 203_u32 => ']', 168_u32 => '^', 7_u32 => '_', 256_u32 => '`', 403_u32 => 'l', 60_u32 => 'r', 42_u32 => 'v', 243_u32 => '{', 146_u32 => '|', 292_u32 => '|', 73_u32 => '|', 414_u32 => '}'}
Exact 9-bit → character mappings from Julia's ASCII_LOOKUP.
ASCII_SIGNS_3X3 = [[256_u32, 128_u32, 64_u32], [32_u32, 16_u32, 8_u32], [4_u32, 2_u32, 1_u32]]
3×3 pixel grid per character cell — 9-bit pattern per cell (bit 8 = top-left).
Matches Julia UnicodePlots AsciiCanvas (y_pixel_per_char=3, x_pixel_per_char=3).
BASES = {:identity => nil, :ln => "ℯ", :sqrt => nil, :log2 => "2", :log10 => "10"}
BLANK_BRAILLE = 10240_u32
BLOCK_DECODE = [' ', '▗', '▖', '▄', '▝', '▐', '▞', '▟', '▘', '▚', '▌', '▙', '▀', '▜', '▛', '█']
BLOCK_SIGNS = [[8_u32, 4_u32], [2_u32, 1_u32]]
2×2 pixel per character, encoded with block drawing characters.
BORDER_ASCII = Border.new('+', '+', '+', '+', '-', '|', '-', '|')
BORDER_BARPLOT = Border.new('┌', '┐', '└', '┘', ' ', '┤', ' ', ' ')
BORDER_BNONE = Border.new('⠀', '⠀', '⠀', '⠀', '⠀', '⠀', '⠀', '⠀')
BORDER_BOLD = Border.new('┏', '┓', '┗', '┛', '━', '┃', '━', '┃')
BORDER_CORNERS = Border.new('┌', '┐', '└', '┘', ' ', ' ', ' ', ' ')
BORDER_DASHED = Border.new('┌', '┐', '└', '┘', '╌', '┊', '╌', '┊')
BORDER_DOTTED = Border.new('⡤', '⢤', '⠓', '⠚', '⠤', '⡇', '⠒', '⢸')
BORDER_NONE = Border.new(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ')
BORDER_SOLID = Border.new('┌', '┐', '└', '┘', '─', '│', '─', '│')
BORDERMAP = {:solid => BORDER_SOLID, :corners => BORDER_CORNERS, :barplot => BORDER_BARPLOT, :bold => BORDER_BOLD, :none => BORDER_NONE, :bnone => BORDER_BNONE, :dashed => BORDER_DASHED, :dotted => BORDER_DOTTED, :ascii => BORDER_ASCII}
BRAILLE_SIGNS = [[1_u32, 8_u32], [2_u32, 16_u32], [4_u32, 32_u32], [64_u32, 128_u32]]
Braille dot offsets within a 4×2 pixel cell.
Index: [pixel_row_offset][pixel_col_offset] (1-based)
COLOR_CYCLE_BRIGHT = [:light_green, :light_blue, :light_red, :light_magenta, :light_yellow, :light_cyan]
COLOR_CYCLE_FAINT = [:green, :blue, :red, :magenta, :yellow, :cyan]
COLORMAP_STOPS = {:viridis => [{0.00, 68, 1, 84}, {0.25, 59, 82, 139}, {0.50, 33, 145, 140}, {0.75, 94, 201, 98}, {1.00, 253, 231, 37}], :plasma => [{0.00, 13, 8, 135}, {0.25, 126, 3, 167}, {0.50, 203, 71, 120}, {0.75, 248, 149, 64}, {1.00, 240, 249, 33}], :inferno => [{0.00, 0, 0, 4}, {0.25, 87, 16, 110}, {0.50, 188, 55, 84}, {0.75, 249, 142, 9}, {1.00, 252, 255, 164}], :magma => [{0.00, 0, 0, 4}, {0.25, 81, 18, 124}, {0.50, 183, 55, 121}, {0.75, 252, 137, 97}, {1.00, 252, 253, 191}], :cividis => [{0.00, 0, 32, 76}, {0.25, 50, 82, 130}, {0.50, 119, 136, 138}, {0.75, 181, 188, 101}, {1.00, 254, 233, 55}], :gray => [{0.00, 0, 0, 0}, {1.00, 255, 255, 255}]}
Multi-stop colormap: each stop is {t, r, g, b} with t in [0,1].
DENSITY_CHARS = [' ', '░', '▒', '▓', '█']
HEATMAP_ASPECT_RATIO = 4.0 / 3.0
INVALID_COLOR = UInt32::MAX
ISCALES = {:identity => ->(x :
Float64) do
x
end, :ln => ->(x :
Float64) do
Math::E ** x
end, :sqrt => ->(x :
Float64) do
x ** 2
end, :log2 => ->(x :
Float64) do
2.0 ** x
end, :log10 => ->(x :
Float64) do
10.0 ** x
end}
MARKERS = {:circle => '⚬', :rect => '▫', :diamond => '◇', :hexagon => '⬡', :cross => '✚', :xcross => '✖', :utriangle => '△', :dtriangle => '▽', :rtriangle => '▷', :ltriangle => '◁', :pentagon => '⬠', :star4 => '✦', :star5 => '★', :star6 => '✶', :star8 => '✴', :vline => '|', :hline => '―', :plus => '+', :x => '⨯'}
NAMED_COLORS = {:black => 0_u32, :red => 1_u32, :green => 2_u32, :yellow => 3_u32, :blue => 4_u32, :magenta => 5_u32, :cyan => 6_u32, :white => 7_u32, :dark_gray => 8_u32, :light_red => 9_u32, :light_green => 10_u32, :light_yellow => 11_u32, :light_blue => 12_u32, :light_magenta => 13_u32, :light_cyan => 14_u32, :light_white => 15_u32}
Named ANSI 4-bit colors → 256-color palette index (stored as THRESHOLD + idx)
SUPERSCRIPT = {'.' => '⸱', '-' => '⁻', '+' => '⁺', '0' => '⁰', '1' => '¹', '2' => '²', '3' => '³', '4' => '⁴', '5' => '⁵', '6' => '⁶', '7' => '⁷', '8' => '⁸', '9' => '⁹', 'e' => 'ᵉ'}