diff --git a/skrifa/Cargo.toml b/skrifa/Cargo.toml index 8aa6f3022..7d2f73912 100644 --- a/skrifa/Cargo.toml +++ b/skrifa/Cargo.toml @@ -8,11 +8,6 @@ repository = "https://github.com/googlefonts/fontations" readme = "README.md" categories = ["text-processing", "parsing", "graphics"] -[features] -default = ["scale"] -scale = [] -hinting = [] - [dependencies] read-fonts = { version = "0.13.1", path = "../read-fonts" } diff --git a/skrifa/src/lib.rs b/skrifa/src/lib.rs index 6cb682194..b555c5c26 100644 --- a/skrifa/src/lib.rs +++ b/skrifa/src/lib.rs @@ -19,7 +19,6 @@ pub mod charmap; pub mod font; pub mod instance; pub mod metrics; -#[cfg(feature = "scale")] pub mod scale; pub mod setting; pub mod string; diff --git a/skrifa/src/scale/glyf/mem.rs b/skrifa/src/scale/glyf/mem.rs index 30d6a4b05..f63573550 100644 --- a/skrifa/src/scale/glyf/mem.rs +++ b/skrifa/src/scale/glyf/mem.rs @@ -7,7 +7,7 @@ use read_fonts::{ types::{F26Dot6, Fixed, Point}, }; -use super::Outline; +use super::{Hinting, Outline}; /// Buffers used during glyph scaling. pub struct OutlineMemory<'a> { @@ -22,11 +22,11 @@ pub struct OutlineMemory<'a> { } impl<'a> OutlineMemory<'a> { - pub(super) fn new(outline: &Outline, buf: &'a mut [u8], with_hinting: bool) -> Option { + pub(super) fn new(outline: &Outline, buf: &'a mut [u8], hinting: Hinting) -> Option { let (scaled, buf) = alloc_slice(buf, outline.points)?; let (unscaled, buf) = alloc_slice(buf, outline.max_other_points)?; // We only need original scaled points when hinting - let (original_scaled, buf) = if outline.has_hinting && with_hinting { + let (original_scaled, buf) = if outline.has_hinting && hinting != Hinting::None { alloc_slice(buf, outline.max_other_points)? } else { (Default::default(), buf) @@ -157,9 +157,9 @@ mod tests { has_variations: true, has_overlaps: false, }; - let required_size = outline_info.required_buffer_size(false); + let required_size = outline_info.required_buffer_size(Hinting::None); let mut buf = vec![0u8; required_size]; - let memory = OutlineMemory::new(&outline_info, &mut buf, false).unwrap(); + let memory = OutlineMemory::new(&outline_info, &mut buf, Hinting::None).unwrap(); assert_eq!(memory.scaled.len(), outline_info.points); assert_eq!(memory.unscaled.len(), outline_info.max_other_points); // We don't allocate this buffer when hinting is disabled @@ -190,8 +190,8 @@ mod tests { }; // Required size adds 4 bytes slop to account for internal alignment // requirements. So subtract 5 to force a failure. - let not_enough = outline_info.required_buffer_size(false) - 5; + let not_enough = outline_info.required_buffer_size(Hinting::None) - 5; let mut buf = vec![0u8; not_enough]; - assert!(OutlineMemory::new(&outline_info, &mut buf, false).is_none()); + assert!(OutlineMemory::new(&outline_info, &mut buf, Hinting::None).is_none()); } } diff --git a/skrifa/src/scale/glyf/mod.rs b/skrifa/src/scale/glyf/mod.rs index a48f37e54..14fc3d614 100644 --- a/skrifa/src/scale/glyf/mod.rs +++ b/skrifa/src/scale/glyf/mod.rs @@ -9,7 +9,7 @@ pub use hint::HinterOutline; pub use mem::OutlineMemory; pub use outline::{Outline, ScaledOutline}; -use super::Error; +use super::{Error, Hinting}; use read_fonts::{ tables::{ diff --git a/skrifa/src/scale/glyf/outline.rs b/skrifa/src/scale/glyf/outline.rs index e36e4f76b..48d2f10d9 100644 --- a/skrifa/src/scale/glyf/outline.rs +++ b/skrifa/src/scale/glyf/outline.rs @@ -7,7 +7,7 @@ use read_fonts::{ types::{F26Dot6, Fixed, GlyphId, Pen, Point}, }; -use super::OutlineMemory; +use super::{Hinting, OutlineMemory}; /// Represents the information necessary to scale a glyph outline. /// @@ -48,9 +48,9 @@ pub struct Outline<'a> { impl<'a> Outline<'a> { /// Returns the minimum size in bytes required to scale an outline based /// on the computed sizes. - pub fn required_buffer_size(&self, with_hinting: bool) -> usize { + pub fn required_buffer_size(&self, hinting: Hinting) -> usize { let mut size = 0; - let hinting = with_hinting && self.has_hinting; + let hinting = self.has_hinting && hinting != Hinting::None; // Scaled, unscaled and (for hinting) original scaled points size += self.points * size_of::>(); // Unscaled and (if hinted) original scaled points @@ -82,9 +82,9 @@ impl<'a> Outline<'a> { pub fn memory_from_buffer( &self, buf: &'a mut [u8], - with_hinting: bool, + hinting: Hinting, ) -> Option> { - OutlineMemory::new(self, buf, with_hinting) + OutlineMemory::new(self, buf, hinting) } } diff --git a/skrifa/src/scale/mod.rs b/skrifa/src/scale/mod.rs index 77e3bda68..b0f0791dc 100644 --- a/skrifa/src/scale/mod.rs +++ b/skrifa/src/scale/mod.rs @@ -167,9 +167,11 @@ use super::{ /// Modes for hinting. /// /// Only the `glyf` source supports all hinting modes. -#[cfg(feature = "hinting")] #[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] pub enum Hinting { + /// Hinting is disabled. + #[default] + None, /// "Full" hinting mode. May generate rough outlines and poor horizontal /// spacing. Full, @@ -181,7 +183,6 @@ pub enum Hinting { LightSubpixel, /// Same as light subpixel, but always prevents adjustment in the /// horizontal direction. This is the default mode. - #[default] VerticalSubpixel, } diff --git a/skrifa/src/scale/scaler.rs b/skrifa/src/scale/scaler.rs index ea3252f63..36f9b01b3 100644 --- a/skrifa/src/scale/scaler.rs +++ b/skrifa/src/scale/scaler.rs @@ -1,10 +1,8 @@ use super::{ - cff, glyf, Context, Error, NormalizedCoord, Pen, Result, Size, UniqueId, VariationSetting, + cff, glyf, Context, Error, Hinting, NormalizedCoord, Pen, Result, Size, UniqueId, + VariationSetting, }; -#[cfg(feature = "hinting")] -use super::Hinting; - use core::borrow::Borrow; use read_fonts::{ types::{Fixed, GlyphId}, @@ -33,8 +31,7 @@ pub struct ScalerBuilder<'a> { context: &'a mut Context, cache_key: Option, size: Size, - #[cfg(feature = "hinting")] - hint: Option, + hinting: Hinting, } impl<'a> ScalerBuilder<'a> { @@ -46,8 +43,7 @@ impl<'a> ScalerBuilder<'a> { context, cache_key: None, size: Size::unscaled(), - #[cfg(feature = "hinting")] - hint: None, + hinting: Hinting::None, } } @@ -70,9 +66,8 @@ impl<'a> ScalerBuilder<'a> { /// Sets the hinting mode. /// /// Passing `None` will disable hinting. - #[cfg(feature = "hinting")] - pub fn hint(mut self, hint: Option) -> Self { - self.hint = hint; + pub fn hint(mut self, hint: Hinting) -> Self { + self.hinting = hint; self } @@ -153,8 +148,7 @@ impl<'a> ScalerBuilder<'a> { Scaler { size, coords, - #[cfg(feature = "hinting")] - hint: self.hint, + hinting: self.hinting, outlines, } } @@ -206,8 +200,7 @@ impl<'a> ScalerBuilder<'a> { pub struct Scaler<'a> { size: f32, coords: &'a [NormalizedCoord], - #[cfg(feature = "hinting")] - hint: Option, + hinting: Hinting, outlines: Option>, } @@ -226,14 +219,7 @@ impl<'a> Scaler<'a> { /// in the given pen for the sequence of path commands that define the outline. pub fn outline(&mut self, glyph_id: GlyphId, pen: &mut impl Pen) -> Result { if let Some(outlines) = &mut self.outlines { - outlines.outline( - glyph_id, - self.size, - self.coords, - #[cfg(feature = "hinting")] - self.hint, - pen, - ) + outlines.outline(glyph_id, self.size, self.coords, self.hinting, pen) } else { Err(Error::NoSources) } @@ -254,18 +240,18 @@ impl<'a> Outlines<'a> { glyph_id: GlyphId, size: f32, coords: &'a [NormalizedCoord], - #[cfg(feature = "hinting")] hint: Option, + hinting: Hinting, pen: &mut impl Pen, ) -> Result { match self { Self::TrueType(scaler, buf) => { let glyph = scaler.outline(glyph_id)?; - let buf_size = glyph.required_buffer_size(false); + let buf_size = glyph.required_buffer_size(hinting); if buf.len() < buf_size { buf.resize(buf_size, 0); } let memory = glyph - .memory_from_buffer(&mut buf[..], false) + .memory_from_buffer(&mut buf[..], hinting) .ok_or(Error::InsufficientMemory)?; let outline = scaler.scale(memory, &glyph, size, coords)?; outline.to_path(pen)?; @@ -281,11 +267,7 @@ impl<'a> Outlines<'a> { } // CFF only has a single hinting mode and FT enables it // if any of the hinting load flags are set. - #[cfg(feature = "hinting")] - let hint = hint.is_some(); - #[cfg(not(feature = "hinting"))] - let hint = false; - scaler.outline(subfont, glyph_id, coords, hint, pen)?; + scaler.outline(subfont, glyph_id, coords, hinting != Hinting::None, pen)?; // CFF does not have overlap flags and hinting never adjusts // horizontal metrics Ok(ScalerMetrics::default())