# `Cauldron2D.Blend`
[🔗](https://github.com/jaman/cauldron/blob/v0.2.2/cauldron_2d/lib/cauldron_2d/blend.ex#L1)

Source-over compositing of two equal-sized RGBA rectangles.

    Cauldron2D.Blend.over(beneath, above)

Both binaries are four bytes per pixel and must be the same length. The result is the
same length: `above` laid over `beneath`, premultiplied by `above`'s alpha.

`available?/0` says whether the C library loaded. Where it did not the same picture is
produced in Elixir, some fifty times slower.

# `available?`

```elixir
@spec available?() :: boolean()
```

Whether the library is loaded and compositing is done in C.

# `draw`

```elixir
@spec draw(
  binary(),
  {pos_integer(), pos_integer()},
  binary(),
  {pos_integer(), pos_integer()},
  map(),
  keyword()
) :: binary()
```

`picture` drawn over `canvas`, both RGBA, placed by `placement`, as a new canvas.

`placement` is a map:

  * `:position` — `{x, y}`, the canvas pixel the picture's origin lands on; fractions
    allowed
  * `:origin` — `{x, y}` in the picture's pixels, default `{0, 0}`
  * `:scale` — `{x, y}`, default `{1, 1}`; a negative scale mirrors along that axis
    and a zero scale draws nothing
  * `:angle` — degrees, counter-clockwise as seen on the canvas, default `0`
  * `:blend` — `{r, g, b}` multiplied into the picture's colours, default white
  * `:alpha` — `0.0`–`1.0` multiplied into the picture's alpha, default `1.0`
  * `:mode` — `:over` (the default), `:add` or `:subtract`; or `{:gamemaker, mode}`, the
    same blend with GameMaker's blend factors applied to the alpha channel as well as
    the colours, as GameMaker draws onto a surface: over `colour × As + beneath × (1 −
    As)` and alpha `As² + Ad × (1 − As)`; add `colour × As + beneath` and alpha `As² +
    Ad`; subtract `beneath × (1 − colour)` and alpha `Ad × (1 − As)`

Every canvas pixel whose centre falls inside the turned and scaled picture takes the
nearest picture pixel, laid over the canvas as `over/2` lays one pixel over another —
or, with `mode: :add`, its colour times its alpha added to the canvas's, each channel
at most 255, as GameMaker's additive blend mode adds it — or, with `mode: :subtract`,
each canvas channel times one less the picture's colour times its alpha, the canvas's
alpha kept, as GameMaker's `bm_subtract` takes it away.
Pixels outside the canvas are dropped. `native: false` draws in Elixir where the C
library is loaded.

# `over`

```elixir
@spec over(binary(), binary()) :: binary()
```

`above` laid over `beneath`, both RGBA of the same length.

# `render_band`

```elixir
@spec render_band(
  pos_integer(),
  non_neg_integer(),
  non_neg_integer(),
  binary(),
  list()
) :: binary()
```

The rows `top` up to `bottom` of a canvas `width` pixels wide, starting as
`background` — four RGBA bytes repeated, or those rows' own pixels — with each of
`items` drawn over it in order. An
item is `{picture, picture_width, picture_height, transform}`, `transform` as
`transform/1` builds it. The rows are drawn exactly as the same rows of the whole
canvas would be.

# `sized!`

```elixir
@spec sized!(binary(), integer(), integer(), String.t()) :: :ok
```

Raises `ArgumentError` unless `rgba` is a picture of `width` by `height` pixels, both
positive, four bytes each. `name` says what the picture is in the message.

# `transform`

```elixir
@spec transform(map()) :: binary()
```

The 104-byte transform `placement` (as `draw/6` takes it) is drawn with.

---

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