Skip to main content

skrifa/
lib.rs

1//! Drawing glyphs from fonts at a size, with hinting.
2//!
3//! A [`Font`] is a font at a location in its variation space. A
4//! [`ScalerFont`] draws the font's glyph outlines at a size in pixels per em,
5//! hinted or not.
6//!
7//! ```
8//! use skrifa::{
9//!     font::{glyph::outline::SvgSink, Font},
10//!     DrawMemory, HintOptions, RasterTarget, ScalerFont,
11//! };
12//!
13//! # fn wrapper(data: Vec<u8>) -> Result<(), skrifa::ScaleError> {
14//! // Load the first font in the file and create a bold instance.
15//! let font = Font::new(data, 0).unwrap();
16//! let bold = font.instance_builder().variations([("wght", 700.0)]).build();
17//!
18//! // Find the glyph ID for the character 'A'.
19//! let glyph_id = bold.charmap().map_unicode('A').unwrap_or_default();
20//!
21//! // Configure a scaler font for hinted drawing at 16 pixels per em, using
22//! // the interpreter with a horizontal subpixel target.
23//! let options = HintOptions::interpreter().with_target(RasterTarget::Lcd);
24//! let scaler = ScalerFont::hinted(bold, 16.0, options);
25//!
26//! if let Some(outline) = scaler.outline(glyph_id) {
27//!     let mut path = SvgSink::new();
28//!     // Draw into the path and store the resulting metrics.
29//!     let metrics = outline.draw(DrawMemory::Scratch, &mut path)?;
30//!     println!("{path} advances by {:?}", metrics.h_advance);
31//! }
32//! # Ok(())
33//! # }
34//! ```
35//!
36//! # Drawing
37//!
38//! [`ScalerFont::outline`] returns a glyph's outline as a [`ScalerOutline`],
39//! which draws into any [`PathSink`]. Drawing needs working memory. By
40//! default it uses short-lived scratch memory, and a caller drawing many
41//! glyphs can supply a reusable buffer instead.
42//!
43//! A scaler draws from the first outline table the font contains, in
44//! [`GlyphSourceOrder::DEFAULT`]: `VARC` composites over `glyf`, `CFF2`,
45//! `CFF` or Type 1 charstrings. To choose other tables, pass a
46//! [`ScalerSource`] in place of the font. The scaler reports the tables it
47//! draws from.
48//!
49//! A scaler with no size draws in font units.
50//!
51//! # Hinting
52//!
53//! Hinting fits an outline to the pixel grid at the scaler's size.
54//! [`HintOptions`] configures it:
55//!
56//! - **Engine.** Run the font's own hints, either TrueType instructions or
57//!   PostScript hints; run the automatic hinter, which derives hints from
58//!   the outline; or pick based on the font, using its own hints where they
59//!   are worth running. A TrueType font that needs its instructions to draw
60//!   correct contours always runs them.
61//! - **Target.** Monochrome, grayscale, light grayscale, or horizontal or
62//!   vertical subpixel rendering. Each target hints to suit the way its
63//!   pixels are drawn.
64//! - **Linear metrics.** Hint only vertically, keeping the unhinted
65//!   horizontal shape and spacing.
66//! - **ClearType compatibility.** Choose between the current ClearType
67//!   behavior of the TrueType interpreter, which follows the font's `gasp`
68//!   table, and the classic behavior, which grid fits every glyph.
69//! - **Strictness.** Fail a draw when a glyph's instructions fail, instead of
70//!   keeping the outline as they left it.
71//!
72//! The scaler reports the engine that runs, and the rasterizer settings the
73//! font requests at the size: whether to smooth along both axes, and the
74//! dropout control a glyph asks of a monochrome rasterizer.
75//!
76//! # Metrics
77//!
78//! A scaler returns the font's line metrics and heights, its style metrics
79//! such as the underline and italic angle, and the advance and bounds of each
80//! glyph, all scaled linearly to its size. Hinting can change a glyph's
81//! advance, so hinted glyph metrics come from drawing the outline.
82//!
83//! # The font model
84//!
85//! The [`font`] module holds everything else about a font: its character
86//! map, names, variation axes and instances, and color and bitmap glyphs.
87//!
88//! # Need shaping?
89//!
90//! [HarfRust](https://docs.rs/harfrust) turns text into positioned glyphs.
91//! It reads fonts through the same font model, so a [`Font`] can be shaped
92//! with HarfRust and drawn with a [`ScalerFont`].
93
94#![cfg_attr(docsrs, feature(doc_cfg))]
95// Compiles the README's example.
96#![cfg_attr(doctest, doc = include_str!("../README.md"))]
97#![forbid(unsafe_code)]
98#![cfg_attr(not(any(test, feature = "std")), no_std)]
99
100#[cfg(not(any(feature = "libm", feature = "std")))]
101compile_error!("Either feature \"std\" or \"libm\" must be enabled for this crate.");
102
103#[cfg(not(any(test, feature = "std")))]
104#[macro_use]
105extern crate core as std;
106
107#[macro_use]
108extern crate alloc;
109
110/// Expose our "raw" underlying parser crate.
111pub extern crate read_fonts as raw;
112
113pub mod font;
114mod scaler;
115
116#[doc(inline)]
117pub use font::Font;
118pub use read_fonts::types::{GlyphId, Tag};
119pub use scaler::{
120    DrawMemory, DrawnMetrics, DropoutControl, GlyphSource, GlyphSourceOrder, HintEngine,
121    HintOptions, OutlineSource, PathSink, RasterPolicy, RasterTarget, ScaleError, ScalerFont,
122    ScalerOutline, ScalerSource,
123};
124
125// The API that `ScalerFont` and the font model replace. It is kept so that
126// existing code builds, and hidden from the documentation.
127
128#[doc(hidden)]
129pub mod attribute;
130#[doc(hidden)]
131pub mod bitmap;
132#[doc(hidden)]
133pub mod charmap;
134#[doc(hidden)]
135pub mod color;
136#[doc(hidden)]
137pub mod instance;
138#[doc(hidden)]
139pub mod metrics;
140#[doc(hidden)]
141pub mod outline;
142#[doc(hidden)]
143pub mod setting;
144#[doc(hidden)]
145pub mod string;
146
147mod decycler;
148mod glyph_name;
149mod provider;
150mod variation;
151
152#[doc(hidden)]
153pub use glyph_name::{GlyphName, GlyphNameSource, GlyphNames};
154#[doc(hidden)]
155pub use outline::{OutlineGlyph, OutlineGlyphCollection};
156#[doc(hidden)]
157pub use provider::MetadataProvider;
158#[doc(hidden)]
159pub use read_fonts::{types::GlyphId16, FontRef};
160#[doc(hidden)]
161pub use variation::{Axis, AxisCollection, NamedInstance, NamedInstanceCollection};
162
163/// Useful collection of common types suitable for glob importing.
164#[doc(hidden)]
165pub mod prelude {
166    #[doc(no_inline)]
167    pub use super::{
168        font::FontRef,
169        instance::{LocationRef, NormalizedCoord, Size},
170        GlyphId, MetadataProvider, Tag,
171    };
172}
173
174use read_fonts::limits::MAX_OUTLINE_POINTS;