diff --git a/.clippy.toml b/.clippy.toml index aab49e8d..91af1608 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -3,3 +3,5 @@ # it makes sense to optimize for 64-bit and accept the performance hits on 32-bit. # 16 bytes is the number of bytes that fits into two 64-bit CPU registers. trivial-copy-size-limit = 16 +# Don't warn about these identifiers when using clippy::doc_markdown. +doc-valid-idents = ["OpenType", ".."] diff --git a/fontique/Cargo.toml b/fontique/Cargo.toml index cabcc0ec..1e65b246 100644 --- a/fontique/Cargo.toml +++ b/fontique/Cargo.toml @@ -9,6 +9,9 @@ rust-version.workspace = true license.workspace = true repository.workspace = true +[package.metadata.docs.rs] +all-features = true + [lints] workspace = true diff --git a/fontique/src/attributes.rs b/fontique/src/attributes.rs index 83954bae..5ed84e87 100644 --- a/fontique/src/attributes.rs +++ b/fontique/src/attributes.rs @@ -8,7 +8,12 @@ use core_maths::*; use core::fmt; -/// Primary attributes for font matching: stretch, style and weight. +/// Primary attributes for font matching: [`Stretch`], [`Style`] and [`Weight`]. +/// +/// These are used to [configure] a [`Query`]. +/// +/// [configure]: crate::Query::set_attributes +/// [`Query`]: crate::Query #[derive(Copy, Clone, PartialEq, Default, Debug)] pub struct Attributes { pub stretch: Stretch, @@ -38,11 +43,18 @@ impl fmt::Display for Attributes { } /// Visual width of a font-- a relative change from the normal aspect -/// ratio, typically in the range 0.5 to 2.0. +/// ratio, typically in the range `0.5` to `2.0`. /// -/// In variable fonts, this can be controlled with the `wdth` axis. +/// The default value is [`Stretch::NORMAL`] or `1.0`. +/// +/// In variable fonts, this can be controlled with the `wdth` [axis]. /// /// See +/// +/// In CSS, this corresponds to the [`font-width`] property. +/// +/// [axis]: crate::AxisInfo +/// [`font-width`]: https://www.w3.org/TR/css-fonts-4/#font-width-prop #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] pub struct Stretch(f32); @@ -59,7 +71,7 @@ impl Stretch { /// Width that is 87.5% of normal. pub const SEMI_CONDENSED: Self = Self(0.875); - /// Width that is 100% of normal. + /// Width that is 100% of normal. This is the default value. pub const NORMAL: Self = Self(1.0); /// Width that is 112.5% of normal. @@ -77,18 +89,43 @@ impl Stretch { impl Stretch { /// Creates a new stretch attribute with the given ratio. + /// + /// This can also be created [from a percentage](Self::from_percentage). + /// + /// # Example + /// + /// ``` + /// # use fontique::Stretch; + /// assert_eq!(Stretch::from_ratio(1.5), Stretch::EXTRA_EXPANDED); + /// ``` pub fn from_ratio(ratio: f32) -> Self { Self(ratio) } /// Creates a stretch attribute from a percentage. + /// + /// This can also be created [from a ratio](Self::from_ratio). + /// + /// # Example + /// + /// ``` + /// # use fontique::Stretch; + /// assert_eq!(Stretch::from_percentage(87.5), Stretch::SEMI_CONDENSED); + /// ``` pub fn from_percentage(percentage: f32) -> Self { Self(percentage / 100.0) } /// Returns the stretch attribute as a ratio. /// - /// This is a linear scaling factor with 1.0 being "normal" width. + /// This is a linear scaling factor with `1.0` being "normal" width. + /// + /// # Example + /// + /// ``` + /// # use fontique::Stretch; + /// assert_eq!(Stretch::NORMAL.ratio(), 1.0); + /// ``` pub fn ratio(self) -> f32 { self.0 } @@ -100,22 +137,37 @@ impl Stretch { self.0 * 100.0 } - /// Returns true if the stretch is normal. + /// Returns `true` if the stretch is [normal]. + /// + /// [normal]: Stretch::NORMAL pub fn is_normal(self) -> bool { self == Self::NORMAL } - /// Returns true if the stretch is condensed (less than normal). + /// Returns `true` if the stretch is condensed (less than [normal]). + /// + /// [normal]: Stretch::NORMAL pub fn is_condensed(self) -> bool { self < Self::NORMAL } - /// Returns true if the stretch is expanded (greater than normal). + /// Returns `true` if the stretch is expanded (greater than [normal]). + /// + /// [normal]: Stretch::NORMAL pub fn is_expanded(self) -> bool { self > Self::NORMAL } /// Parses the stretch from a CSS style keyword or a percentage value. + /// + /// # Examples + /// + /// ``` + /// # use fontique::Stretch; + /// assert_eq!(Stretch::parse("semi-condensed"), Some(Stretch::SEMI_CONDENSED)); + /// assert_eq!(Stretch::parse("80%"), Some(Stretch::from_percentage(80.0))); + /// assert_eq!(Stretch::parse("wideload"), None); + /// ``` pub fn parse(s: &str) -> Option { let s = s.trim(); Some(match s { @@ -171,9 +223,16 @@ impl Default for Stretch { /// Visual weight class of a font, typically on a scale from 1.0 to 1000.0. /// -/// In variable fonts, this can be controlled with the `wght` axis. +/// The default value is [`Weight::NORMAL`] or `400.0`. +/// +/// In variable fonts, this can be controlled with the `wght` [axis]. /// /// See +/// +/// In CSS, this corresponds to the [`font-weight`] property. +/// +/// [axis]: crate::AxisInfo +/// [`font-weight`]: https://www.w3.org/TR/css-fonts-4/#font-weight-prop #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] pub struct Weight(f32); @@ -190,7 +249,7 @@ impl Weight { /// Weight value of 350. pub const SEMI_LIGHT: Self = Self(350.0); - /// Weight value of 400. + /// Weight value of 400. This is the default value. pub const NORMAL: Self = Self(400.0); /// Weight value of 500. @@ -224,6 +283,16 @@ impl Weight { } /// Parses a CSS style font weight attribute. + /// + /// # Examples + /// + /// ``` + /// # use fontique::Weight; + /// assert_eq!(Weight::parse("normal"), Some(Weight::NORMAL)); + /// assert_eq!(Weight::parse("bold"), Some(Weight::BOLD)); + /// assert_eq!(Weight::parse("850"), Some(Weight::new(850.0))); + /// assert_eq!(Weight::parse("invalid"), None); + /// ``` pub fn parse(s: &str) -> Option { let s = s.trim(); Some(match s { @@ -265,10 +334,17 @@ impl fmt::Display for Weight { /// Visual style or 'slope' of a font. /// +/// The default value is [`Style::Normal`]. +/// /// In variable fonts, this can be controlled with the `ital` -/// and `slnt` axes for italic and oblique styles, respectively. +/// and `slnt` [axes] for italic and oblique styles, respectively. /// /// See +/// +/// In CSS, this corresponds to the [`font-style`] property. +/// +/// [axes]: crate::AxisInfo +/// [`font-style`]: https://www.w3.org/TR/css-fonts-4/#font-style-prop #[derive(Copy, Clone, PartialEq, Default, Debug)] pub enum Style { /// An upright or "roman" style. diff --git a/fontique/src/collection/mod.rs b/fontique/src/collection/mod.rs index a5601bf1..631a013b 100644 --- a/fontique/src/collection/mod.rs +++ b/fontique/src/collection/mod.rs @@ -28,7 +28,7 @@ use std::sync::{atomic::Ordering, Mutex}; type FamilyMap = HashMap>; -/// Options for a font collection. +/// Options for a [font collection](Collection). #[derive(Copy, Clone, Debug)] pub struct CollectionOptions { /// If true, the font collection will use a secondary shared store @@ -38,13 +38,13 @@ pub struct CollectionOptions { /// If the font collection will be used by a single thread, this is /// pure overhead and should be disabled. /// - /// The default value is false. + /// The default value is `false`. pub shared: bool, /// If true, the font collection will provide access to system fonts /// using platform specific APIs. /// - /// The default value is true. + /// The default value is `true`. pub system_fonts: bool, } @@ -66,6 +66,14 @@ pub struct Collection { impl Collection { /// Creates a new collection with the given options. + /// + /// If `fontique` was compiled with the `"system"` feature and + /// [`CollectionOptions::system_fonts`] was set to `true` when + /// creating this collection, then it will register the fonts + /// available on the system. + /// + /// Additional fonts can be registered via [`Collection::register_fonts`] + /// and providing it with the data for those fonts. pub fn new(options: CollectionOptions) -> Self { Self { inner: Inner::new(options), @@ -75,7 +83,8 @@ impl Collection { /// Returns an iterator over all available family names in the collection. /// - /// This includes both system and registered fonts. + /// If `fontique` was compiled with the `"system"` feature, then it will + /// include system fonts after the registered fonts. pub fn family_names(&mut self) -> impl Iterator + '_ + Clone { self.inner.family_names() } diff --git a/fontique/src/collection/query.rs b/fontique/src/collection/query.rs index 9917692e..48e42b42 100644 --- a/fontique/src/collection/query.rs +++ b/fontique/src/collection/query.rs @@ -28,6 +28,8 @@ impl QueryState { } /// State for font selection. +/// +/// Instances of this can be obtained from [`Collection::query`]. pub struct Query<'a> { collection: &'a mut Inner, state: &'a mut QueryState, @@ -103,6 +105,9 @@ impl<'a> Query<'a> { /// Invokes the given callback with all fonts that match the current /// settings. + /// + /// Return [`QueryStatus::Stop`] to end iterating over the matching + /// fonts or [`QueryStatus::Continue`] to continue iterating. #[cfg(feature = "std")] pub fn matches_with(&mut self, mut f: impl FnMut(&QueryFont) -> QueryStatus) { for family in self @@ -166,6 +171,8 @@ impl Drop for Query<'_> { } /// Determines whether a font query operation will continue. +/// +/// See [`Query::matches_with`]. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum QueryStatus { /// Query should continue with the next font. @@ -175,6 +182,9 @@ pub enum QueryStatus { } /// Family descriptor for a font query. +/// +/// This allows [`Query::set_families`] to +/// take a variety of family types. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum QueryFamily<'a> { /// A named font family. @@ -203,14 +213,14 @@ impl From for QueryFamily<'static> { } } -/// Candidate font generated by a query. +/// Candidate font generated by a [`Query`]. #[derive(Clone, Debug)] pub struct QueryFont { /// Family identifier and index of the font in the family font list. pub family: (FamilyId, usize), /// Blob containing the font data. pub blob: Blob, - /// Index of a font in a font collection (ttc) file. + /// Index of a font in a font collection (`ttc`) file. pub index: u32, /// Synthesis suggestions for this font based on the requested attributes. pub synthesis: Synthesis, diff --git a/fontique/src/fallback.rs b/fontique/src/fallback.rs index 39a81456..42be44ff 100644 --- a/fontique/src/fallback.rs +++ b/fontique/src/fallback.rs @@ -36,7 +36,7 @@ impl FallbackMap { /// Inserts or replaces the fallback families for the given script and /// language. /// - /// Returns false if we don't track that particular pair of script and + /// Returns `false` if we don't track that particular pair of script and /// language. pub fn set( &mut self, @@ -49,7 +49,7 @@ impl FallbackMap { /// Inserts or appends the fallback families for the given script and /// language. /// - /// Returns false if we don't track that particular pair of script and + /// Returns `false` if we don't track that particular pair of script and /// language. pub fn append( &mut self, @@ -105,6 +105,12 @@ impl FallbackMap { } /// Describes a selector for fallback families. +/// +/// This is a [`Script`] and optionally, a `locale`, represented +/// as a `&'static str`. +/// +/// It can be constructed directly via [`FallbackKey::new`] or any of +/// a variety of `From` implementations to improve the ease of use. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct FallbackKey { script: Script, @@ -139,15 +145,15 @@ impl FallbackKey { self.locale } - /// Returns true if the requested locale is considered the "default" + /// Returns `true` if the requested locale is considered the "default" /// language/region for the requested script. /// - /// Always returns `true` when `locale()` returns `None`. + /// Always returns `true` when [`locale`](Self::locale) returns `None`. pub fn is_default(&self) -> bool { self.is_default } - /// Returns true if the requested script and locale pair are actually + /// Returns `true` if the requested script and locale pair are actually /// tracked for fallback. pub fn is_tracked(&self) -> bool { self.is_tracked diff --git a/fontique/src/font.rs b/fontique/src/font.rs index 38fcfcd0..b566eddc 100644 --- a/fontique/src/font.rs +++ b/fontique/src/font.rs @@ -67,7 +67,7 @@ impl FontInfo { } /// Returns the visual width of the font-- a relative change from the normal - /// aspect ratio, typically in the range 0.5 to 2.0. + /// aspect ratio, typically in the range `0.5` to `2.0`. pub fn stretch(&self) -> Stretch { self.stretch } @@ -78,7 +78,7 @@ impl FontInfo { } /// Returns the visual weight class of the font, typically on a scale - /// from 1.0 to 1000.0. + /// from `1.0` to `1000.0`. pub fn weight(&self) -> Weight { self.weight } @@ -135,32 +135,59 @@ impl FontInfo { synth } - /// Returns the variation axes for the font. + /// Returns the variation [axes] for the font. + /// + /// [axes]: crate::AxisInfo pub fn axes(&self) -> &[AxisInfo] { &self.axes } - /// Returns true if the font has a `wght` axis. + /// Returns `true` if the font has a `wght` [axis]. + /// + /// This is a quicker check than scanning the [axes]. + /// + /// [axes]: Self::axes + /// [axis]: crate::AxisInfo pub fn has_weight_axis(&self) -> bool { self.attr_axes & WEIGHT_AXIS != 0 } - /// Returns true if the font has a `wdth` axis. + /// Returns `true` if the font has a `wdth` [axis]. + /// + /// This is a quicker check than scanning the [axes]. + /// + /// [axes]: Self::axes + /// [axis]: crate::AxisInfo pub fn has_width_axis(&self) -> bool { self.attr_axes & WIDTH_AXIS != 0 } - /// Returns true if the font has a `slnt` axis. + /// Returns `true` if the font has a `slnt` [axis]. + /// + /// This is a quicker check than scanning the [axes]. + /// + /// [axes]: Self::axes + /// [axis]: crate::AxisInfo pub fn has_slant_axis(&self) -> bool { self.attr_axes & SLANT_AXIS != 0 } - /// Returns true if the font has an `ital` axis. + /// Returns `true` if the font has an `ital` [axis]. + /// + /// This is a quicker check than scanning the [axes]. + /// + /// [axes]: Self::axes + /// [axis]: crate::AxisInfo pub fn has_italic_axis(&self) -> bool { self.attr_axes & ITALIC_AXIS != 0 } - /// Returns true if the font as an `opsz` axis. + /// Returns `true` if the font as an `opsz` [axis]. + /// + /// This is a quicker check than scanning the [axes]. + /// + /// [axes]: Self::axes + /// [axis]: crate::AxisInfo pub fn has_optical_size_axis(&self) -> bool { self.attr_axes & OPTICAL_SIZE_AXIS != 0 } @@ -230,6 +257,24 @@ const ITALIC_AXIS: u8 = 0x08; const OPTICAL_SIZE_AXIS: u8 = 0x10; /// An axis of variation for a variable font. +/// +/// Instances of this can be obtained from [`FontInfo::axes`]. +/// +/// These give the [`Tag`] and range of valid values for a given font +/// variation. In `parley`, these values are used to create a +/// `FontVariation`. +/// +/// OpenType defines some common axes: +/// +/// * [Italic](https://fonts.google.com/knowledge/glossary/italic_axis) or `ital` +/// * [Optical Size](https://fonts.google.com/knowledge/glossary/optical_size_axis) or `opsz` +/// * [Slant](https://fonts.google.com/knowledge/glossary/slant_axis) or `slnt` +/// * [Weight](https://fonts.google.com/knowledge/glossary/weight_axis) or `wght` +/// * [Width](https://fonts.google.com/knowledge/glossary/width_axis) or `wdth` +/// +/// For a broader explanation of this, see +/// [Axis in Variable Fonts](https://fonts.google.com/knowledge/glossary/axis_in_variable_fonts) +/// from Google Fonts. #[derive(Copy, Clone, Default, Debug)] pub struct AxisInfo { /// The tag that identifies the axis. @@ -242,8 +287,13 @@ pub struct AxisInfo { pub default: f32, } -/// Suggestions for sythesizing a set of font attributes for a given +/// Suggestions for synthesizing a set of font attributes for a given /// font. +/// +/// Instances of this can be obtained from [`FontInfo::synthesis`] +/// as well as [`QueryFont::synthesis`]. +/// +/// [`QueryFont::synthesis`]: crate::QueryFont::synthesis #[derive(Copy, Clone, Default, Debug)] pub struct Synthesis { vars: [(Tag, f32); 3], @@ -253,18 +303,21 @@ pub struct Synthesis { } impl Synthesis { - /// Returns true if any synthesis suggestions are available. + /// Returns `true` if any synthesis suggestions are available. pub fn any(&self) -> bool { self.len != 0 || self.embolden || self.skew != 0 } /// Returns the variation settings that should be applied to match the /// requested attributes. + /// + /// When using `parley`, these can be used to create `FontVariation` + /// settings. pub fn variation_settings(&self) -> &[(Tag, f32)] { &self.vars[..self.len as usize] } - /// Returns true if the scaler should apply a faux bold. + /// Returns `true` if the scaler should apply a faux bold. pub fn embolden(&self) -> bool { self.embolden } diff --git a/fontique/src/generic.rs b/fontique/src/generic.rs index 50b959ac..afbdc4ca 100644 --- a/fontique/src/generic.rs +++ b/fontique/src/generic.rs @@ -14,7 +14,7 @@ type FamilyVec = SmallVec<[FamilyId; 2]>; #[repr(u8)] pub enum GenericFamily { /// Glyphs have finishing strokes, flared or tapering ends, or have actual - /// serifed endings. + /// serifed endings. Serif = 0, /// Glyphs have stroke endings that are plain. SansSerif = 1, diff --git a/fontique/src/lib.rs b/fontique/src/lib.rs index ad6eaecb..d5892be3 100644 --- a/fontique/src/lib.rs +++ b/fontique/src/lib.rs @@ -3,6 +3,7 @@ //! Font enumeration and fallback. +#![cfg_attr(docsrs, feature(doc_auto_cfg))] // TODO: Remove this dead code allowance and hide the offending code behind the std feature gate. #![cfg_attr(not(feature = "std"), allow(dead_code))] #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] diff --git a/fontique/src/script.rs b/fontique/src/script.rs index 3ce56f38..555a83d3 100644 --- a/fontique/src/script.rs +++ b/fontique/src/script.rs @@ -6,6 +6,12 @@ use core::{convert::TryInto, fmt}; /// Four byte tag representing a Unicode script. +/// +/// If the `"icu_properties"` feature is enabled, this can +/// be created from a [`icu_properties::Script`]. +/// +/// If the `"unicode_script"` feature is enabled this can +/// be created from a [`unicode_script::Script`]. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Script(pub [u8; 4]); diff --git a/fontique/src/source.rs b/fontique/src/source.rs index e2055bc0..680e8b25 100644 --- a/fontique/src/source.rs +++ b/fontique/src/source.rs @@ -12,6 +12,8 @@ use { }; /// Unique identifier for a font source. +/// +/// See [`SourceInfo`]. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[repr(transparent)] pub struct SourceId(u64); @@ -55,6 +57,8 @@ impl SourceInfo { } /// Font data that is either a path to the font file or shared data in memory. +/// +/// See [`SourceInfo`]. #[derive(Clone)] pub enum SourceKind { /// Shared data containing the content of the font file. diff --git a/fontique/src/source_cache.rs b/fontique/src/source_cache.rs index 5cd6586a..6b92de44 100644 --- a/fontique/src/source_cache.rs +++ b/fontique/src/source_cache.rs @@ -11,7 +11,9 @@ use std::{ sync::{Arc, Mutex}, }; -/// Options for a source cache. +/// Options for a [source cache]. +/// +/// [source cache]: SourceCache #[derive(Copy, Clone, Default, Debug)] pub struct SourceCacheOptions { /// If true, the source cache will use a secondary shared cache @@ -20,7 +22,7 @@ pub struct SourceCacheOptions { /// This is useful for ensuring that only one copy of font data is /// loaded into memory in multi-threaded scenarios. /// - /// The default value is false. + /// The default value is `false`. pub shared: bool, } @@ -33,7 +35,9 @@ pub struct SourceCache { } impl SourceCache { - /// Creates an empty cache with the given options. + /// Creates an empty cache with the given [options]. + /// + /// [options]: SourceCacheOptions pub fn new(options: SourceCacheOptions) -> Self { if options.shared { Self { @@ -50,6 +54,9 @@ impl SourceCache { /// /// A cache created with this function maintains a synchronized internal /// store that is shared among all clones. + /// + /// This is the same as calling [`SourceCache::new`] with an options + /// struct where `shared = true`. pub fn new_shared() -> Self { Self { cache: Default::default(), @@ -58,10 +65,12 @@ impl SourceCache { } } - /// Returns the blob for the given font data, attempting to load + /// Returns the [blob] for the given font data, attempting to load /// it from the file system if not already present. /// /// Returns `None` if loading failed. + /// + /// [blob]: Blob pub fn get(&mut self, source: &SourceInfo) -> Option> { let path = match &source.kind { SourceKind::Memory(memory) => return Some(memory.clone()),