Ascii.Frame (Ascii v0.3.0)

Copy Markdown View Source

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

Types

A run of cells along row y from column x: their text and colours.

t()

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

run()

@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.

t()

@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

changes(prev, frame, opts \\ [])

@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.

color_at(frame, x, y)

@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.