# `FrenchCurve.Draw`
[🔗](https://github.com/jaman/french_curve/blob/v0.1.4/lib/french_curve/draw.ex#L1)

Rasterises lines, rectangles and circles into a `FrenchCurve.Raster`.

Every function takes a raster as its first argument and returns a new one, so calls
compose in a pipeline. Coordinates are integer pixels, `{0, 0}` at the top left, and may
fall outside the raster: the parts that land inside are drawn and the rest is clipped.
Colours are `{r, g, b, a}` byte tuples written opaquely, with no blending against what
is already there.

    FrenchCurve.Raster.new(40, 20)
    |> FrenchCurve.Draw.rect({0, 0}, {39, 19}, {80, 80, 80, 255})
    |> FrenchCurve.Draw.fill_circle({20, 10}, 6, {255, 0, 0, 255})

# `coord`

```elixir
@type coord() :: {integer(), integer()}
```

# `circle`

```elixir
@spec circle(
  FrenchCurve.Raster.t(),
  coord(),
  non_neg_integer(),
  FrenchCurve.Raster.color()
) ::
  FrenchCurve.Raster.t()
```

Draws a one-pixel-wide circle outline of `radius` pixels around the centre `{cx, cy}`.

`radius` must be a non-negative integer. The interior is untouched.

# `fill_circle`

```elixir
@spec fill_circle(
  FrenchCurve.Raster.t(),
  coord(),
  non_neg_integer(),
  FrenchCurve.Raster.color()
) ::
  FrenchCurve.Raster.t()
```

Fills a disc of `radius` pixels around the centre `{cx, cy}`.

`radius` must be a non-negative integer.

# `fill_polygon`

```elixir
@spec fill_polygon(
  FrenchCurve.Raster.t(),
  [{number(), number()}],
  FrenchCurve.Raster.color()
) ::
  FrenchCurve.Raster.t()
```

Fills the polygon whose corners are `points`, edges included.

The polygon is closed from the last point back to the first. Points may be fractional;
a pixel is filled when its centre lies inside, using the even-odd rule, and the outline
is drawn as well so thin shapes are never lost. Fewer than three points draw as a
polyline.

# `fill_rect`

```elixir
@spec fill_rect(FrenchCurve.Raster.t(), coord(), coord(), FrenchCurve.Raster.color()) ::
  FrenchCurve.Raster.t()
```

Fills every pixel of the rectangle spanned by two opposite corners, edges included.

Both corners are inclusive and may be given in any order.

# `line`

```elixir
@spec line(FrenchCurve.Raster.t(), coord(), coord(), FrenchCurve.Raster.color()) ::
  FrenchCurve.Raster.t()
```

Draws a one-pixel-wide line between the two endpoints, both inclusive.

Handles any direction, including purely horizontal, vertical and single-point lines.

# `polyline`

```elixir
@spec polyline(FrenchCurve.Raster.t(), [coord()], FrenchCurve.Raster.color()) ::
  FrenchCurve.Raster.t()
```

Draws a connected run of line segments through `points` in order.

A single point plots that pixel and an empty list leaves the raster unchanged. Points
are not closed back to the first one; pass the first point again to close the shape.

# `rect`

```elixir
@spec rect(FrenchCurve.Raster.t(), coord(), coord(), FrenchCurve.Raster.color()) ::
  FrenchCurve.Raster.t()
```

Draws the four edges of the rectangle spanned by two opposite corners.

Both corners are inclusive and may be given in any order. The interior is untouched.

---

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