Glyphs derived from their Unicode geometry instead of drawn by hand, for any cell size.
Braille patterns, eighth blocks, and quadrants are exact subdivisions of the cell, so a font gets them for free: each function returns a %{codepoint => glyph} map for a {width, height} cell, ready to merge under the hand-drawn glyphs (hand-drawn wins on conflict when merged second).
Widgets lean on these: Canvas draws with braille by default, Sparkline and BarChart with eighth blocks, BigText with quadrants.
Summary
Functions
The braille block U+2800..U+28FF.
Eighth blocks: lower ▁..▇ (U+2581..U+2587), left ▏..▉ (U+2589..U+258F), the right half ▐, the upper eighth ▔, and the right eighth ▕.
A hatched checkerboard with a blank bottom row: the conventional "no glyph for this codepoint" placeholder, visibly different from a space.
The quadrant blocks ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▞ ▟ (U+2596..U+259F), splitting the cell at half its width and height.
Builds a {width, height} glyph from a per-pixel predicate ink?.(x, y).
Types
@type size() :: {pos_integer(), pos_integer()}
Functions
@spec braille(size()) :: %{required(non_neg_integer()) => bitstring()}
The braille block U+2800..U+28FF.
The cell splits into two dot columns and four dot rows; each lit dot fills its whole sub-rectangle, so neighbouring dots merge into continuous lines rather than a dotted texture. Bit n of the codepoint offset lights dot n + 1: dots 1-2-3 run down the left column, 4-5-6 down the right, 7 and 8 are the bottom row.
Examples
iex> glyphs = RasterExRatatui.Font.Generated.braille({2, 4})
iex> map_size(glyphs)
256
iex> RasterExRatatui.Font.Art.render(glyphs[0x2801], {2, 4})
"#.\n..\n..\n..\n"
iex> RasterExRatatui.Font.Art.render(glyphs[0x2880], {2, 4})
"..\n..\n..\n.#\n"
@spec eighths(size()) :: %{required(non_neg_integer()) => bitstring()}
Eighth blocks: lower ▁..▇ (U+2581..U+2587), left ▏..▉ (U+2589..U+258F), the right half ▐, the upper eighth ▔, and the right eighth ▕.
Fractions round to whole pixel rows or columns of the cell; the thin edges are at least one pixel.
Examples
iex> glyphs = RasterExRatatui.Font.Generated.eighths({4, 8})
iex> RasterExRatatui.Font.Art.render(glyphs[0x2583], {4, 8}) |> String.split("\n", trim: true) |> Enum.drop(4)
["....", "####", "####", "####"]
iex> RasterExRatatui.Font.Art.render(glyphs[0x258C], {4, 8}) |> String.split("\n", trim: true) |> hd()
"##.."
A hatched checkerboard with a blank bottom row: the conventional "no glyph for this codepoint" placeholder, visibly different from a space.
Examples
iex> RasterExRatatui.Font.Art.render(RasterExRatatui.Font.Generated.hatched({4, 3}), {4, 3})
"#.#.\n.#.#\n....\n"
@spec quadrants(size()) :: %{required(non_neg_integer()) => bitstring()}
The quadrant blocks ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▞ ▟ (U+2596..U+259F), splitting the cell at half its width and height.
Examples
iex> glyphs = RasterExRatatui.Font.Generated.quadrants({2, 2})
iex> RasterExRatatui.Font.Art.render(glyphs[0x259A], {2, 2})
"#.\n.#\n"
@spec rasterise(size(), (non_neg_integer(), non_neg_integer() -> boolean())) :: bitstring()
Builds a {width, height} glyph from a per-pixel predicate ink?.(x, y).
Examples
iex> RasterExRatatui.Font.Generated.rasterise({3, 1}, fn x, _y -> x != 1 end)
<<0b101::3>>