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 pixelsPoints 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| Builder | Effect |
|---|---|
with_hinting | None, Subpixel (FreeType's v40), Classic (v35), Auto, AutoForce. |
with_transform | An affine applied after hinting; its offsets are in font units. |
with_oblique | A synthetic slant, as a tangent, applied before the transform. |
with_stroke | Stroke the outline instead of filling it, width in font units. |
with_embolden | Synthetic 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.