# `Drafter.Widget.Chart.Pixel`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/widget/chart/pixel.ex#L1)

Renders chart data as terminal graphics via the frozen `french_curve` library.

Three outputs from a single rasterisation path: a true-image escape sequence for
terminals that support a pixel protocol (kitty / iTerm2 / sixel), anti-aliased
braille `Strip`s for any other truecolor terminal, or block-character `Strip`s in
one of `FrenchCurve.Backend.Cells`' glyph sets (`:half`, `:quad`, `:sextant`,
`:octant`), two colours per cell. Callers pick the mode with `mode/2` ("best
available" for `:pixel`) and pass a chart `spec` to `picture/3` (a raster for
`Drafter.Render.Picture` to encode), `braille_strips/2` or `cells_strips/3`.

A `spec` is `%{type, values, color: {r,g,b,a}, smooth, fill_opacity, min, max}`.
Add a `raster/3` clause to support a new chart type; `supported/0` gates which
types use this path at all.

# `drawing`

```elixir
@type drawing() ::
  :pixel | :braille | {:cells, FrenchCurve.Backend.Cells.set()} | :text
```

How a chart or slider draws: an image, braille, block characters of a glyph set, or text.

# `braille_strips`

```elixir
@spec braille_strips(
  map(),
  {pos_integer(), pos_integer()}
) :: [Drafter.Draw.Strip.t()] | nil
```

# `cell_sets`

```elixir
@spec cell_sets() :: [atom()]
```

The glyph sets accepted as modes, each drawing through `cells_strips/3`.

# `cells_strips`

```elixir
@spec cells_strips(
  map(),
  {pos_integer(), pos_integer()},
  FrenchCurve.Backend.Cells.set()
) ::
  [Drafter.Draw.Strip.t()] | nil
```

Renders `spec` as `rows` strips of `cols` cells in the glyph set `set`, or `nil` when
it cannot be drawn.

# `mode`

```elixir
@spec mode(atom() | nil, atom()) :: drawing()
```

# `modes`

```elixir
@spec modes() :: [atom()]
```

The list of mode atoms accepted by `:renderer`, `DRAFTER_MODE`, and the `mode:`
run option: `[:auto, :pixel, :kitty, :iterm2, :sixel, :braille, :text, :half, :quad, :sextant, :octant]`.

# `picture`

```elixir
@spec picture(map(), atom() | nil, {pos_integer(), pos_integer()}) ::
  Drafter.Render.Picture.t() | nil
```

Draws `spec` as a `Drafter.Render.Picture` filling a `cols` by `rows` cell box at the
widget's top left, to be drawn with `protocol`.

The raster is a whole number of pixels per cell: `:scale` (default `4`) across and
twice that down, reduced where needed to keep it within 512 by 288 pixels. Returns
`nil` when `protocol` is `nil` or the chart cannot be drawn.

# `protocol`

```elixir
@spec protocol(atom() | nil) :: atom() | nil
```

The graphics protocol to draw with, or `nil` when the terminal has none.

A `renderer` naming a protocol (`:kitty`, `:iterm2`, `:sixel`) is used as given;
any mode that is not `:auto` or `:pixel` has no protocol and returns `nil`.

`:auto` and `:pixel` take what the terminal answered when it was probed at
startup — see `Drafter.Terminal.Probe`. A terminal that was never probed, or
that answered the probe without naming a protocol, is guessed at from its
environment instead, through `FrenchCurve.Capability.detect/1`.

Either way the terminal in question is the one this session is attached to, which
for a session served over ssh or telnet is the connecting client's rather than
the host's.

# `resolve`

```elixir
@spec resolve(atom() | nil) :: atom()
```

Resolve an effective mode from precedence: the `DRAFTER_MODE` env var forces and
wins over everything; otherwise an explicit per-widget `renderer` (any mode atom),
then the runtime `:drafter` `:render_mode` application env, then `:text`.

# `supported`

```elixir
@spec supported() :: [atom()]
```

# `terminal`

```elixir
@spec terminal() :: atom() | nil
```

The graphics protocol of this session's terminal, whatever mode is in force.

What the terminal answered when it was probed at startup, or, when it was never
probed or named no protocol, what its environment suggests through
`FrenchCurve.Capability.detect/1`. `nil` when neither names one. An iTerm2 session is
always judged by its environment, whatever it answered: `:iterm2`, or `:kitty` when
`FRENCH_CURVE_ITERM2=kitty` is set (see `FrenchCurve.Capability`).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
