From a47f8b79968593e7cbfdce1c2523a27e00e4cf65 Mon Sep 17 00:00:00 2001 From: Samuel Guerra Date: Tue, 13 Feb 2024 00:18:45 -0300 Subject: [PATCH] More docs refactor. --- TODO/_current.md | 1 - zero-ui-ext-font/src/hyphenation.rs | 2 +- zero-ui-ext-font/src/lib.rs | 63 +++++++++++++++++++++---- zero-ui-ext-font/src/segmenting.rs | 2 +- zero-ui-ext-font/src/shaping.rs | 71 ++++++++++++++++++++++++----- zero-ui/src/font.rs | 8 ++-- 6 files changed, 120 insertions(+), 27 deletions(-) diff --git a/TODO/_current.md b/TODO/_current.md index bed1805fb..1646cdcdb 100644 --- a/TODO/_current.md +++ b/TODO/_current.md @@ -6,7 +6,6 @@ * Review docs. - Do a full read, look for typos or failed links. - Last reviewing `zero_ui::font`. - - Last reviewed `HYPHENATION` # Publish diff --git a/zero-ui-ext-font/src/hyphenation.rs b/zero-ui-ext-font/src/hyphenation.rs index 508f0a2fb..7677ac959 100644 --- a/zero-ui-ext-font/src/hyphenation.rs +++ b/zero-ui-ext-font/src/hyphenation.rs @@ -118,7 +118,7 @@ pub trait HyphenationDataSource: Send + 'static { /// Represents a hyphenation data source that searches a directory. /// -/// The file names must follow a pattern that includes the [`hyphenation::Language`] display print, the pattern mut be defined +/// The file names must follow a pattern that includes the language display print, the pattern mut be defined /// with a replacement `{lang}`. For example the file `dir/en-us.bincode` is matched by `"{lang}.bincode"`. /// /// See the [hyphenation](https://github.com/tapeinosyne/hyphenation) crate docs for more details about the data files. diff --git a/zero-ui-ext-font/src/lib.rs b/zero-ui-ext-font/src/lib.rs index 36cf565e5..036b17a77 100644 --- a/zero-ui-ext-font/src/lib.rs +++ b/zero-ui-ext-font/src/lib.rs @@ -67,8 +67,6 @@ use zero_ui_var::{ use zero_ui_view_api::webrender_api as wr; use zero_ui_view_api::{config::FontAntiAliasing, ViewProcessOffline}; -pub use font_kit::properties::Style as FontStyle; - /// Font family name. /// /// A possible value for the `font_family` property. @@ -588,9 +586,14 @@ pub enum FontChange { SystemFonts, /// Custom fonts change caused by call to [`FONTS.register`] or [`FONTS.unregister`]. + /// + /// [`FONTS.register`]: FONTS::register + /// [`FONTS.unregister`]: FONTS::unregister CustomFonts, /// Custom request caused by call to [`FONTS.refresh`]. + /// + /// [`FONTS.refresh`]: FONTS::refresh Refesh, /// One of the [`GenericFonts`] was set for the language. @@ -603,7 +606,7 @@ pub enum FontChange { } /// Application extension that manages text fonts. -/// +/// /// Services this extension provides: /// /// * [`FONTS`] - Service that finds and loads fonts. @@ -911,7 +914,7 @@ impl FontFace { postscript_name: None, is_monospace: true, properties: font_kit::properties::Properties { - style: FontStyle::Normal, + style: FontStyle::Normal.into(), weight: FontWeight::NORMAL.into(), stretch: FontStretch::NORMAL.into(), }, @@ -1026,7 +1029,7 @@ impl FontFace { family_name: custom_font.name, postscript_name: None, properties: font_kit::properties::Properties { - style: custom_font.style, + style: custom_font.style.into(), weight: custom_font.weight.into(), stretch: custom_font.stretch.into(), }, @@ -1220,7 +1223,7 @@ impl FontFace { /// Font style. pub fn style(&self) -> FontStyle { - self.0.properties.style + self.0.properties.style.into() } /// Font weight. @@ -2035,7 +2038,7 @@ impl FontFaceLoader { match font_kit::source::SystemSource::new().select_best_match( &[family_name], &font_kit::properties::Properties { - style, + style: style.into(), weight: weight.into(), stretch: stretch.into(), }, @@ -2605,9 +2608,53 @@ impl From for FontStretch { } } +/// The italic or oblique form of a font. +#[derive(Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize)] +pub enum FontStyle { + /// The regular form. + #[default] + Normal, + /// A form that is generally cursive in nature. + Italic, + /// A skewed version of the regular form. + Oblique, +} +impl fmt::Debug for FontStyle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if f.alternate() { + write!(f, "FontStyle::")?; + } + match self { + Self::Normal => write!(f, "Normal"), + Self::Italic => write!(f, "Italic"), + Self::Oblique => write!(f, "Oblique"), + } + } +} +impl From for font_kit::properties::Style { + fn from(value: FontStyle) -> Self { + use font_kit::properties::Style::*; + match value { + FontStyle::Normal => Normal, + FontStyle::Italic => Italic, + FontStyle::Oblique => Oblique, + } + } +} +impl From for FontStyle { + fn from(value: font_kit::properties::Style) -> Self { + use font_kit::properties::Style::*; + match value { + Normal => FontStyle::Normal, + Italic => FontStyle::Italic, + Oblique => FontStyle::Oblique, + } + } +} + /// The degree of stroke thickness of a font. This value ranges from 100.0 to 900.0, /// with 400.0 as normal. -#[derive(Clone, Copy, Transitionable)] +#[derive(Clone, Copy, Transitionable, serde::Serialize, serde::Deserialize)] pub struct FontWeight(pub f32); impl Default for FontWeight { fn default() -> FontWeight { diff --git a/zero-ui-ext-font/src/segmenting.rs b/zero-ui-ext-font/src/segmenting.rs index aa38eb557..a1cd1151c 100644 --- a/zero-ui-ext-font/src/segmenting.rs +++ b/zero-ui-ext-font/src/segmenting.rs @@ -35,7 +35,7 @@ impl TextSegment { /// A string segmented in sequences of words, spaces, tabs and separated line breaks. /// -/// Each segment is tagged with a [`TextSegmentKind`] and is represented as +/// Each segment is tagged with a [`TextSegmentKind`] and is defines as /// an offset from the last segment. #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct SegmentedText { diff --git a/zero-ui-ext-font/src/shaping.rs b/zero-ui-ext-font/src/shaping.rs index 4c4199cb2..989f7e2f6 100644 --- a/zero-ui-ext-font/src/shaping.rs +++ b/zero-ui-ext-font/src/shaping.rs @@ -15,8 +15,8 @@ use zero_ui_txt::Txt; use zero_ui_view_api::webrender_api::{self, units::LayoutVector2D, GlyphIndex, GlyphInstance}; use crate::{ - font_features::RFontFeatures, BidiLevel, CaretIndex, Font, FontList, HYPHENATION, Hyphens, LineBreak, SegmentedText, TextSegment, - WordBreak, + font_features::RFontFeatures, BidiLevel, CaretIndex, Font, FontList, Hyphens, LineBreak, SegmentedText, TextSegment, WordBreak, + HYPHENATION, }; /// Extra configuration for [`shape_text`](Font::shape_text). @@ -69,16 +69,16 @@ pub struct TextShapingArgs { /// World break config. /// - /// This value is only considered if it is impossible to fit the a word to a line. + /// This value is only considered if it is impossible to fit the word to a line. pub word_break: WordBreak, /// Hyphen breaks config. pub hyphens: Hyphens, - /// Character rendered when text is auto-hyphenated. + /// Character rendered when text is hyphenated by break. pub hyphen_char: Txt, - /// Replacement char if the text must be obscured. + /// Obscure the text with the replacement char. pub obscuring_char: Option, } impl Default for TextShapingArgs { @@ -1735,7 +1735,7 @@ pub struct TextOverflowInfo { /// All segments in this line and next lines are fully overflown. The previous line line may /// be partially overflown, the lines before that are fully visible. /// - /// Is the [`ShapedText::lines_len`] if the last line is partially not overflown. + /// Is the [`ShapedText::lines_len`] if the last line is fully visible. pub line: usize, /// First overflow character in the text. @@ -3811,10 +3811,11 @@ impl Font { let scale = self.metrics().size_scale; - self.face() - .font_kit() - .ok_or(GlyphLoadingError::NoSuchGlyph)? - .outline(glyph_id, hinting_options, &mut AdapterSink { sink, scale }) + self.face().font_kit().ok_or(GlyphLoadingError::NoSuchGlyph)?.outline( + glyph_id, + hinting_options.into(), + &mut AdapterSink { sink, scale }, + ) } /// Returns the boundaries of a glyph in pixel units. @@ -3922,8 +3923,54 @@ impl Font { } } -/// Hinting options for [`Font::outline`]. -pub type OutlineHintingOptions = font_kit::hinting::HintingOptions; +/// Specifies how hinting (grid fitting) is to be performed (or not performed) for [`Font::outline`]. +#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)] +pub enum OutlineHintingOptions { + /// No hinting is performed unless absolutely necessary to assemble the glyph. + /// + /// This corresponds to what macOS and FreeType in its "no hinting" mode do. + None, + + /// Hinting is performed only in the vertical direction. The specified point size is used for + /// grid fitting. + /// + /// This corresponds to what DirectWrite and FreeType in its light hinting mode do. + Vertical(f32), + + /// Hinting is performed only in the vertical direction, and further tweaks are applied to make + /// subpixel antialiasing look better. The specified point size is used for grid fitting. + /// + /// This matches DirectWrite, GDI in its ClearType mode, and FreeType in its LCD hinting mode. + VerticalSubpixel(f32), + + /// Hinting is performed in both horizontal and vertical directions. The specified point size + /// is used for grid fitting. + /// + /// This corresponds to what GDI in non-ClearType modes and FreeType in its normal hinting mode + /// do. + Full(f32), +} +impl OutlineHintingOptions { + /// Returns the point size that will be used for grid fitting, if any. + #[inline] + pub fn grid_fitting_size(&self) -> Option { + match *self { + Self::None => None, + Self::Vertical(size) | Self::VerticalSubpixel(size) | Self::Full(size) => Some(size), + } + } +} +impl From for font_kit::hinting::HintingOptions { + fn from(value: OutlineHintingOptions) -> Self { + use font_kit::hinting::HintingOptions::*; + match value { + OutlineHintingOptions::None => None, + OutlineHintingOptions::Vertical(s) => Vertical(s), + OutlineHintingOptions::VerticalSubpixel(s) => VerticalSubpixel(s), + OutlineHintingOptions::Full(s) => Full(s), + } + } +} /// Receives Bézier path rendering commands from [`Font::outline`]. /// diff --git a/zero-ui/src/font.rs b/zero-ui/src/font.rs index 4c83f8b32..c653af5c6 100644 --- a/zero-ui/src/font.rs +++ b/zero-ui/src/font.rs @@ -162,9 +162,9 @@ pub use zero_ui_ext_font::{ font_features, unicode_bidi_levels, unicode_bidi_sort, BidiLevel, CaretIndex, ColorGlyph, ColorGlyphs, ColorPalette, ColorPaletteType, ColorPalettes, CustomFont, Font, FontChange, FontChangedArgs, FontColorPalette, FontDataRef, FontFace, FontFaceList, FontFaceMetrics, - FontList, FontMetrics, FontName, FontNames, FontSize, FontStretch, FontStyle, FontWeight, HYPHENATION, HyphenationDataDir, - HyphenationDataSource, Hyphens, Justify, LayoutDirections, LetterSpacing, LineBreak, LineHeight, LineSpacing, OutlineHintingOptions, - OutlineSink, ParagraphSpacing, SegmentedText, SegmentedTextIter, ShapedColoredGlyphs, ShapedLine, ShapedSegment, ShapedText, TabLength, + FontList, FontMetrics, FontName, FontNames, FontSize, FontStretch, FontStyle, FontWeight, HyphenationDataDir, HyphenationDataSource, + Hyphens, Justify, LayoutDirections, LetterSpacing, LineBreak, LineHeight, LineSpacing, OutlineHintingOptions, OutlineSink, + ParagraphSpacing, SegmentedText, SegmentedTextIter, ShapedColoredGlyphs, ShapedLine, ShapedSegment, ShapedText, TabLength, TextLineThickness, TextOverflowInfo, TextSegment, TextSegmentKind, TextShapingArgs, TextTransformFn, UnderlineThickness, WhiteSpace, - WordBreak, WordSpacing, FONTS, FONT_CHANGED_EVENT, + WordBreak, WordSpacing, FONTS, FONT_CHANGED_EVENT, HYPHENATION, };