Vivid.TrueType.Glyph (vivid v1.0.0)

Copy Markdown View Source

A single glyph read from a font's glyf table.

A glyph holds the slice of glyf describing it rather than its parsed outlines, so that loading a font doesn't pay to expand thousands of glyphs which will never be drawn. Slices are sub-binaries, which the runtime shares with the font they were read from rather than copying.

It carries the whole table's slices, not only its own, because a composite glyph - which is what every accented character is - is described in terms of other glyphs, and needs to find them at the point it's drawn.

Coordinates are in font units, and Vivid.Font.line/3 supplies the multiplier which turns them into pixels.

Summary

Functions

Returns how far the pen advances after drawing glyph, in font units.

Returns the contours of glyph as lists of points in font units, with any curves already flattened into line segments.

Initialize a glyph.

Converts glyph into a Vivid.Region in font units, one contour per contour.

Types

t()

@type t() :: %Vivid.TrueType.Glyph{
  advance: number(),
  index: non_neg_integer(),
  outlines: %{required(non_neg_integer()) => binary()}
}

Functions

advance(glyph)

@spec advance(t()) :: number()

Returns how far the pen advances after drawing glyph, in font units.

Example

iex> Vivid.OpenType.load!(Path.join(:code.priv_dir(:vivid), "fonts/roboto-subset.ttf"))
...> |> Vivid.Font.glyph(?l)
...> |> Vivid.TrueType.Glyph.advance()
497

contours(glyph)

@spec contours(t()) :: [[Vivid.Point.t()]]

Returns the contours of glyph as lists of points in font units, with any curves already flattened into line segments.

Examples

l is a single straight-sided contour.

iex> Vivid.OpenType.load!(Path.join(:code.priv_dir(:vivid), "fonts/roboto-subset.ttf"))
...> |> Vivid.Font.glyph(?l)
...> |> Vivid.TrueType.Glyph.contours()
...> |> Enum.count()
1

o is two: the outside, and the counter inside it wound the other way.

iex> Vivid.OpenType.load!(Path.join(:code.priv_dir(:vivid), "fonts/roboto-subset.ttf"))
...> |> Vivid.Font.glyph(?o)
...> |> Vivid.TrueType.Glyph.contours()
...> |> Enum.count()
2

A space has none at all.

iex> Vivid.OpenType.load!(Path.join(:code.priv_dir(:vivid), "fonts/roboto-subset.ttf"))
...> |> Vivid.Font.glyph(?\s)
...> |> Vivid.TrueType.Glyph.contours()
[]

init(index, advance, outlines)

@spec init(non_neg_integer(), number(), %{required(non_neg_integer()) => binary()}) ::
  t()

Initialize a glyph.

  • index this glyph's index in the font.
  • advance how far the pen moves after drawing it, in font units.
  • outlines every glyph slice in the font's glyf table, keyed by index.

to_region(glyph)

@spec to_region(t()) :: Vivid.Region.t()

Converts glyph into a Vivid.Region in font units, one contour per contour.

Example

iex> Vivid.OpenType.load!(Path.join(:code.priv_dir(:vivid), "fonts/roboto-subset.ttf"))
...> |> Vivid.Font.glyph(?o)
...> |> Vivid.TrueType.Glyph.to_region()
...> |> Vivid.Region.contours()
...> |> Enum.count()
2