A bitmap that a pixel-mode widget handed to an ExRatatui.CellSession
created with a :font_size, covering a rect of cells.
Terminal graphics protocols smuggle their bytes through one cell's
symbol, which a cell diff cannot carry. A surface with real pixels does
not need the escape at all: it wants the bitmap and the rect it covers.
So on a session that knows its cell pixel size, ExRatatui.Widgets.Viewport3D
and ExRatatui.Widgets.Image in a pixel mode rasterize into a region,
and the cells they cover arrive as plain blank cells.
Fields
:x,:y,:width,:height— the covered rect, in cells:pixel_width,:pixel_height— the bitmap's size in pixels. Usuallywidth * font_widthbyheight * font_height; the longest side is capped (1280 px), so a very large rect gets a smaller bitmap to scale up:format—:rgb8: row-major, three bytes per pixel, no padding:data— the pixel bytes,pixel_width * pixel_height * 3long
Contract
ExRatatui.CellSession.Snapshot and ExRatatui.CellSession.Diff carry the
complete list of regions on screen for that frame, never a delta. A
region that is not listed is gone. Paint the cells first, then blit every
region over its rect, scaling if the bitmap is smaller than the rect.
Examples
iex> ExRatatui.CellSession.Region.from_native(%{
...> x: 2, y: 1, width: 2, height: 1,
...> pixel_width: 2, pixel_height: 1, format: :rgb8,
...> data: <<255, 0, 0, 0, 0, 255>>
...> })
%ExRatatui.CellSession.Region{
x: 2, y: 1, width: 2, height: 1,
pixel_width: 2, pixel_height: 1, format: :rgb8,
data: <<255, 0, 0, 0, 0, 255>>
}
Summary
Types
@type t() :: %ExRatatui.CellSession.Region{ data: binary(), format: :rgb8, height: non_neg_integer(), pixel_height: non_neg_integer(), pixel_width: non_neg_integer(), width: non_neg_integer(), x: non_neg_integer(), y: non_neg_integer() }
Functions
Builds a t/0 from the raw map the NIF returns for one region.
@spec rotate(t(), ExRatatui.Pixels.angle()) :: t()
Rotates the region's bitmap clockwise by angle degrees.
Returns the region with :data, :pixel_width and :pixel_height
updated; at 90 and 270 the two dimensions are swapped. For a surface
whose panel is mounted on its side, this turns the bitmap once so the
rest of the paint stays a flat row-by-row copy.
The cell rect is left alone. :x, :y, :width and :height are
the app's cell coordinates, and turning them needs the size of the grid
they sit in, which a region does not carry. A consumer that rotates its
whole screen already knows that size and computes the turned rect
itself — raster_ex_ratatui does exactly that, in its physical_rect/2.
Raises ArgumentError on a bitmap whose byte count is not
pixel_width * pixel_height * 3, or on an unsupported angle. See
ExRatatui.Pixels.rotate_rgb8/4 for the corner mapping.
Examples
iex> region = %ExRatatui.CellSession.Region{
...> x: 4, y: 2, width: 2, height: 1,
...> pixel_width: 2, pixel_height: 1,
...> data: <<255, 0, 0, 0, 0, 255>>
...> }
iex> ExRatatui.CellSession.Region.rotate(region, 90)
%ExRatatui.CellSession.Region{
x: 4, y: 2, width: 2, height: 1,
pixel_width: 1, pixel_height: 2, format: :rgb8,
data: <<255, 0, 0, 0, 0, 255>>
}
Encodes the region's bitmap as a PNG binary.
For consumers that ship regions over a text channel (a LiveView push,
a JSON API), where raw RGB would be several times heavier. The PNG has
the region's pixel_width × pixel_height.
Raises ArgumentError when data does not hold exactly
pixel_width * pixel_height * 3 bytes.