Expand description
Fonts service and text shaping.
The most common types in this module are used through the Text!
widget properties related to font configuration.
use zng::{prelude::*, font::FontName};
Text! {
txt = "hello";
font_family = FontName::monospace();
}
Internally the Text!
widget implements text segmenting and shaping using the types provided by this module,
but you only need to interact with these types directly if you are authoring new text properties or a new custom
text rendering widget.
The second most common type used is the FONTS
service. The service can be used to register custom fonts, query system fonts and
manage the font cache.
§Fonts Service
The example below demonstrates a font query and custom embedded font installation.
/// set custom fallback font for the ⌫ symbol.
async fn set_fallback_font() {
use zng::font::*;
let und = lang!(und);
let shaped_icon = FONTS
.list(
&FontNames::system_ui(&und),
FontStyle::Normal,
FontWeight::NORMAL,
FontStretch::NORMAL,
&und,
)
.wait_rsp()
.await
.sized(layout::Px(11), vec![])
.shape_text(&SegmentedText::new("⌫", layout::LayoutDirection::LTR), &TextShapingArgs::default());
if shaped_icon.is_empty() || shaped_icon.glyphs().flat_map(|g| g.1).any(|g| g.index == 0) {
// OS UI and fallback fonts do not support `⌫`, load custom font that does.
static FALLBACK: &[u8] = include_bytes!("res/calculator/notosanssymbols2-regular-subset.ttf");
let fallback = CustomFont::from_bytes("fallback", FontDataRef::from_static(FALLBACK), 0);
FONTS.register(fallback).wait_rsp().await.unwrap();
FONTS.generics().set_fallback(und, "fallback");
}
}
This code is taken from the examples/calculator.rs
example,
it uses FONTS.list
to get the font system_ui
fonts that are used by default. The code
then checks if any of system fonts has a glyph for the ⌫
character, if none of the fonts support it a CustomFont
is
loaded from an embedded font and installed using FONTS.register
. Finally the FONTS.generics
is used to override the fallback font.
The FONTS.generics
can also be used to change what font is used for the specially named fonts like FontName::sans_serif
.
§Text Segmenting and Shaping
The most advance feature provided by this module is text segmenting and shaping. Text segmenting is the process of analyzing
raw text and splitting it into distinct segments that define things like the layout direction of text runs, words and spaces,
points where text can be inserted and where wrap line-breaks can happen, this is defined the type SegmentedText
.
A segmented text can then be shaped, that is actual glyphs resolved for each segment and positioned according to available space,
this is defined by the ShapedText
type.
The example below segments and shapes a text, generating a markdown report from some of the data computed.
use std::fmt::Write as _;
use zng::{font::*, l10n::Lang, prelude_wgt::Px, text::*, var::Var};
async fn report_segment_and_glyphs(txt: &str, lang: &Lang) -> Txt {
let mut report = formatx!("# Shape & Segment\n\n{txt}\n\n");
// start font query in parallel
let font_face = FONTS.list(
&FontNames::system_ui(lang),
FontStyle::Normal,
FontWeight::NORMAL,
FontStretch::NORMAL,
lang,
);
// segment text
let segmented_txt = SegmentedText::new(Txt::from_str(txt), lang.direction());
write!(&mut report, "### Segments\n\n|text|kind|\n|--|--|\n").unwrap();
for (txt, seg) in segmented_txt.iter() {
writeln!(&mut report, "|{txt:?}|{:?}|", seg.kind).unwrap();
}
// wait font query
let font = font_face.wait_into_rsp().await;
// gets the best font for the size
let font = font.sized(Px(20), vec![]);
write!(&mut report, "### Fonts\n\n").unwrap();
let mut sep = "";
for f in font.iter() {
write!(&mut report, "{sep}{}", f.face().family_name()).unwrap();
sep = ", ";
}
writeln!(&mut report, "\n").unwrap();
// shape text
let shaped_txt = font.shape_text(
&segmented_txt,
&TextShapingArgs {
lang: lang.clone(),
direction: segmented_txt.base_direction(),
line_height: font.best().metrics().line_height(),
..TextShapingArgs::default()
},
);
write!(&mut report, "### Glyphs\n\n|text|glyphs|\n|--|--|\n").unwrap();
for line in shaped_txt.lines() {
for seg in line.segs() {
let txt = seg.text(txt);
write!(&mut report, "|{txt:?}|").unwrap();
let mut sep = "";
for (font, glyphs) in seg.glyphs() {
write!(&mut report, "{sep}**{}** ", font.face().family_name(),).unwrap();
sep = " | ";
let mut sep = "";
for g in glyphs {
write!(&mut report, "{sep}{}", g.index).unwrap();
sep = ", ";
}
}
writeln!(&mut report).unwrap();
}
}
report
}
Note that you can access the segmented and shaped text of a Text!
widget using the TEXT
service.
§Full API
See zng_ext_font
for the full font and shaping API.
Modules§
- Font features and variation types.
Structs§
- Embedding Level
- Defines an insert offset in a shaped text.
- Represents all layer glyphs selected by the font to replace a colored glyph.
- COLR table.
- Represents a color palette entry.
- Represents a color palette v1 flag.
- CPAL table.
- Custom font builder.
- Font loading, custom fonts and app font configuration.
- A sized font face.
FONT_CHANGED_EVENT
arguments.- Reference to in memory font data.
- A font face selected from a font family.
- Various metrics that apply to the entire
FontFace
. - A list of
Font
created from aFontFaceList
. - Various metrics about a
Font
. - Font family name.
- A list of font names in priority order.
- The width of a font as an approximate fraction of the normal width.
- The degree of stroke thickness of a font. This value ranges from 100.0 to 900.0, with 400.0 as normal.
- Hyphenation service.
- Represents a hyphenation data source that searches a directory.
- Identifies what direction segments a
ShapedLine
has. - A string segmented in sequences of words, spaces, tabs and separated line breaks.
- Segmented text iterator.
- Represents a line selection of a
ShapedText
. - Represents a word or space selection of a
ShapedText
. - Output of text layout.
- Info about a shaped text overflow in constraint.
- Represents a single text segment in a
SegmentedText
. - Extra configuration for
shape_text
.
Enums§
- Possible changes in a
FontChangedArgs
. - Color palette selector for colored fonts.
- The italic or oblique form of a font.
- Hyphenation mode.
- Text alignment justification mode.
- Configuration of text wrapping for Chinese, Japanese, or Korean text.
- Represents normal and colored glyphs in
ShapedText::colored_glyphs
. - The type of an inline/text segment.
- Text transform function.
- Text white space transform.
- Configure line breaks inside words during text wrap.
Statics§
- Change in
FONTS
that may cause a font query to now give a different result.
Traits§
- Represents a hyphenation dictionary source.
- Receives Bézier path rendering commands from
Font::outline
.
Functions§
- Compute initial bidirectional levels of each segment of a
line
. - Compute a map of segments in
line
to their final LTR display order.
Type Aliases§
- Text font size.
- Extra spacing added in between text letters.
- Text line height.
- Extra spacing in-between text lines.
- Extra spacing in-between paragraphs.
- Length of a
TAB
space. - Height of the text overline or strikethrough decoration.
- Height of the text underline decoration.
- Extra spacing added to the Unicode
U+0020 SPACE
character.