One frame of a piece, ready for any renderer.
text is the picture: rows lines of cols characters joined by \n,
and lines the same split into rows. colors, for a coloured piece drawn
in colour, is a binary of cols * rows bytes, one palette index a cell,
row by row; palette holds the #rrggbb colours they index and ground
the colour behind them. A palette entry may be nil, for cells drawn in
the renderer's own ink: a piece in one ink with only some of its parts
coloured (see Ascii.Parts). A palette is the same for every frame of
an animation. cell is a cell's height in widths (2 for the
shape of a character, 1 for square).
Renderers in this library (Ascii.Render.Text, Ascii.Render.ANSI,
the Phoenix components) all take a frame. To draw cells yourself, on a
framebuffer say, walk lines and colors together:
for {line, y} <- Enum.with_index(frame.lines),
{char, x} <- Enum.with_index(String.graphemes(line)) do
index = :binary.at(frame.colors, y * frame.cols + x)
draw(x, y, char, Enum.at(frame.palette, index) || my_ink)
end
Summary
Functions
What changed from prev to frame, as runs of cells along a row:
{y, x, text, colors}, the colours being the run's palette indices (or
nil without colours). A cell counts as changed if its character or its
colour did. Changed cells less than :gap cells apart (default 4) are
taken into one run, since each run costs a little to place.
The #rrggbb colour of the cell at x, y, or nil without colours or
in the renderer's own ink.
Types
@type run() :: {y :: non_neg_integer(), x :: non_neg_integer(), String.t(), binary() | nil}
A run of cells along row y from column x: their text and colours.
@type t() :: %Ascii.Frame{ cell: 1 | 2, colors: binary() | nil, cols: pos_integer(), ground: String.t() | nil, lines: [String.t()], palette: [String.t() | nil] | nil, rows: pos_integer(), t: float(), text: String.t() }
Functions
@spec changes(prev :: t() | nil, frame :: t(), opts :: [{:gap, pos_integer()}]) :: [ run() ]
What changed from prev to frame, as runs of cells along a row:
{y, x, text, colors}, the colours being the run's palette indices (or
nil without colours). A cell counts as changed if its character or its
colour did. Changed cells less than :gap cells apart (default 4) are
taken into one run, since each run costs a little to place.
With no frame before (nil), or one of another size, palette or kind, every row is
a run. Most pieces change a few cells in a hundred a frame, so this is
what to send to a terminal or a browser that already shows prev.
@spec color_at(frame :: t(), x :: non_neg_integer(), y :: non_neg_integer()) :: String.t() | nil
The #rrggbb colour of the cell at x, y, or nil without colours or
in the renderer's own ink.