v1.2.0

Outlines

daegun does not rasterize. It hands your rasterizer the outline, through the five calls of anOutlinePen, and your rasterizer fills it.

use daegun::{OutlineOptions, Path};

let mut outline = Path::default();
let glyph = font.prepared_outline(gid, 32.0, &[], &OutlineOptions::default(), &mut outline)
    .expect("is in the font");

glyph.advance_width;    // f32, already in pixels
outline.bounds();       // the tight box, (x_min, y_min, x_max, y_max) in pixels

Points arrive in pixels, y up from the glyph's origin, so flip y for a bitmap whose rows run downward and add your pen position. None means nothing was drawn: a size or option that is not finite, a glyph that does not decode, or one too large once scaled.

A pen of your own

Implement the trait on your rasterizer, or on an adapter in front of one:

use daegun::OutlinePen;

struct Recorder(Vec<(f32, f32)>);

impl OutlinePen for Recorder {
    fn move_to(&mut self, x: f32, y: f32) { self.0.push((x, -y)) }
    fn line_to(&mut self, x: f32, y: f32) { self.0.push((x, -y)) }
    fn quad_to(&mut self, _cx: f32, _cy: f32, x: f32, y: f32) { self.0.push((x, -y)) }
    fn curve_to(&mut self, _ax: f32, _ay: f32, _bx: f32, _by: f32, x: f32, y: f32) { self.0.push((x, -y)) }
    fn close(&mut self) {}
}

A TrueType glyph comes as lines and quadratics, a CFF glyph as lines and cubics. Fill with the non-zero winding rule.

Options

use daegun::{HintMode, OutlineOptions};

let opts = OutlineOptions::default().with_hinting(HintMode::Auto).with_embolden(40.0);
let glyph = font.prepared_outline(gid, 16.0, &[], &opts, &mut outline).expect("is in the font");
// glyph.advance_width includes the embolden, and glyph.hinted says a hinter ran
BuilderEffect
with_hintingNone, Subpixel (FreeType's v40), Classic (v35), Auto, AutoForce.
with_transformAn affine applied after hinting; its offsets are in font units.
with_obliqueA synthetic slant, as a tangent, applied before the transform.
with_strokeStroke the outline instead of filling it, width in font units.
with_emboldenSynthetic bold, in font units. Widens the advances too.

A stroke or an embolden overlaps itself, which a non-zero fill hides and a rasterizer that sums coverage does not. Resolve the overlaps for that one: see Curves and polygons.

In font units

outline_glyph gives the outline as the font stores it, in font units, andoutline_glyph_instanced at a position in a variable font's design space. Scale bypx / font.upm() yourself. hinted_glyph gives a hinter's points, andprewarm decodes outlines ahead of the frame that needs them.

Type to search.