# `Drafter.Widget.Digits.Font`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/widget/digits/font.ex#L1)

The font catalogue for `Drafter.Widget.Digits`.

Built-in fonts are monospaced and share one repertoire: digits, upper and
lower case, and common punctuation. Lower case falls back to the upper-case
glyph, and a character the font cannot draw renders as blanks of the font's
widest glyph rather than raising.

## Built-in fonts

| Name | Cell | Built from |
|---|---|---|
| `:block` | 7×5 | Box-drawing outlines. The default. |
| `:compact` | 5×3 | The same outlines at half the height. |
| `:tall` | 8×4 | Half blocks — 1×2 pixels a cell. |
| `:pixel` | 4×4 | Quadrant blocks — 2×2 pixels a cell. |
| `:braille` | 4×4 | Braille — 2×4 pixels a cell. |

`:tall`, `:pixel` and `:braille` are rasterised at compile time from the 8×16
bitmaps in `Drafter.Widget.Digits.Bitmap` by `Drafter.Widget.Digits.Raster`.
See the [large text guide](large_text.md) for how to choose between them.

## FIGlet fonts

`Drafter.Widget.Digits.Figlet` reads `.flf` files. Register one and it is used
like any other font:

    {:ok, font} = Drafter.Widget.Digits.Figlet.load("fonts/slant.flf")
    Drafter.Widget.Digits.Font.register(:slant, font)
    digits("Vellum", font: :slant)

FIGlet fonts are proportional, so `width/1` reports the widest glyph rather
than a fixed cell. Measure a string with `text_width/2`.

## Examples

    iex> Drafter.Widget.Digits.Font.builtin_names()
    [:block, :braille, :compact, :pixel, :tall]

    iex> Drafter.Widget.Digits.Font.height(:block)
    5

    iex> Drafter.Widget.Digits.Font.glyph_width(:compact, "7")
    5

    iex> Drafter.Widget.Digits.Font.text_width(:compact, "42%")
    15

    iex> Drafter.Widget.Digits.Font.supports?(:block, "a")
    true

# `font`

```elixir
@type font() :: %{
  height: pos_integer(),
  width: pos_integer(),
  glyphs: %{required(String.t()) =&gt; [String.t()]}
}
```

# `name`

```elixir
@type name() :: :block | :compact | :braille | :pixel | :tall | atom()
```

# `builtin_names`

```elixir
@spec builtin_names() :: [name()]
```

The names of the fonts compiled into the library.

# `get`

```elixir
@spec get(name() | font() | term()) :: font()
```

Looks up a font by name, falling back to `:block` for an unknown name.

A font map is returned as given, so one loaded by
`Drafter.Widget.Digits.Figlet.load/1` may be passed straight through without
registering it.

# `glyph`

```elixir
@spec glyph(name() | font(), String.t()) :: [String.t()]
```

The rows of one character, upper-casing when a font has no lower-case form.

A character the font cannot draw yields blanks of the font's widest glyph.

# `glyph_width`

```elixir
@spec glyph_width(name() | font(), String.t()) :: non_neg_integer()
```

Columns one character occupies in a font.

# `height`

```elixir
@spec height(name() | font()) :: pos_integer()
```

Row height of a font's glyphs.

# `names`

```elixir
@spec names() :: [name()]
```

Every font name available, built in and registered.

# `register`

```elixir
@spec register(atom(), font()) :: :ok
```

Adds a font under `name`, making it available as `digits(text, font: name)`.

Registered fonts live for the life of the node. A registered name takes
precedence over a built-in one of the same name.

# `registered`

```elixir
@spec registered() :: %{required(atom()) =&gt; font()}
```

Every registered font, keyed by name.

# `repertoire`

```elixir
@spec repertoire(name() | font()) :: [String.t()]
```

Every character a font can draw, sorted.

# `supports?`

```elixir
@spec supports?(name() | font(), String.t()) :: boolean()
```

Whether a font can draw a character in some form.

# `text_width`

```elixir
@spec text_width(name() | font(), String.t()) :: non_neg_integer()
```

Columns a whole string occupies in a font.

# `unregister`

```elixir
@spec unregister(atom()) :: :ok
```

Removes a registered font. Built-in fonts are unaffected.

# `width`

```elixir
@spec width(name() | font()) :: pos_integer()
```

Column width of the widest glyph in a font.

FIGlet fonts are proportional; use `glyph_width/2` or `text_width/2` to
measure what will actually be drawn.

---

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