azul_text_layout/
lib.rs

1//! General crate for text layout / text shaping
2//!
3//! ![Text layout functions and ](https://i.imgur.com/1T7a1VR.png)
4//!
5//! # Example
6//!
7//! ```rust,ignore,no_run
8//! use azul_text_layout::{
9//!     text_layout::{split_text_into_words, words_to_scaled_words},
10//!     text_shaping::get_font_metrics_freetype,
11//! };
12//!
13//! let text = "hello";
14//! let font_size = 14.0; // px
15//! let font = include_bytes!("Helvetica.ttf");
16//! let font_index = 0; // only for fonts with font collections
17//! let font_metrics = get_font_metrics_freetype(&font, font_index);
18//! let words = split_text_into_words(text);
19//! let scaled_words = words_to_scaled_words(&words, &font, font_index as u32, font_metrics, font_size);
20//!
21//! let total_width = scaled_words.items.iter().map(|i| i.word_width).sum();
22//! ```
23//!
24//! # Full text layout
25//!
26//! ```rust,ignore,no_run
27//! use azul_text_layout::{text_layout, text_shaping::get_font_metrics_freetype};
28//! use azul_css::{LayoutSize, StyleTextAlignmentHorz};
29//! use azul_core::ui_solver::ResolvedTextLayoutOptions;
30//!
31//! // set all options of the text
32//! let text = "hello";
33//! let font_size = 14.0; // px
34//! let font_bytes = include_bytes!("Helvetica.ttf");
35//! let font_index = 0; // only for fonts with font collections
36//! let text_layout_options = ResolvedTextLayoutOptions {
37//!     font_size_px: font_size,
38//!     line_height: None,
39//!     letter_spacing: None,
40//!     word_spacing: None,
41//!     tab_width: None,
42//!     // for line breaking, maximum width that a line can have
43//!     max_horizontal_width: Some(400.0), // px
44//!     leading: None,
45//!     holes: Vec::new(),
46//! };
47//!
48//! // Cache the font metrics of the given font (baseline, height, etc.)
49//! let font_metrics = get_font_metrics_freetype(font_bytes, font_index as i32);
50//! // "Hello World" => ["Hello", "World"]
51//! let words = text_layout::split_text_into_words(text);
52//! // "Hello" @ 14px => Size { width: 50px, height: 14px }
53//! let scaled_words = text_layout::words_to_scaled_words(&words, font_bytes, font_index, font_metrics, text_layout_options.font_size_px);
54//! // Calculate the origin of the word relative to the line
55//! let word_positions = text_layout::position_words(&words, &scaled_words, &text_layout_options);
56//! // Calculate the origin of the line relative to (0, 0)
57//! let mut inline_text_layout = text_layout::word_positions_to_inline_text_layout(&word_positions, &scaled_words);
58//! // Align the line horizontally
59//! inline_text_layout.align_children_horizontal(StyleTextAlignmentHorz::Center);
60//! // Calculate the glyph positons (line_offset + word_offset + glyph_offset)
61//! let layouted_glyphs = text_layout::get_layouted_glyphs(&word_positions, &scaled_words, &inline_text_layout);
62//!
63//! println!("{:#?}", inline_text_layout); // get infos about word offset, line breaking, etc.
64//! println!("{:#?}", layouted_glyphs); // get the final glyph positions relative to the origin
65//! ```
66
67#![doc(
68    html_logo_url = "https://raw.githubusercontent.com/maps4print/azul/master/assets/images/azul_logo_full_min.svg.png",
69    html_favicon_url = "https://raw.githubusercontent.com/maps4print/azul/master/assets/images/favicon.ico",
70)]
71
72extern crate azul_css;
73extern crate azul_core;
74extern crate unicode_normalization;
75extern crate harfbuzz_sys;
76extern crate freetype; // necessary to get baseline of font
77
78pub mod text_layout;
79pub mod text_shaping;
80
81use azul_core::{
82    traits::GetTextLayout,
83    ui_solver::{ResolvedTextLayoutOptions, InlineTextLayout},
84    app_resources::{Words, ScaledWords},
85};
86
87#[derive(Debug, Clone)]
88pub struct InlineText<'a> {
89    pub words: &'a Words,
90    pub scaled_words: &'a ScaledWords,
91}
92
93impl<'a> GetTextLayout for InlineText<'a> {
94    fn get_text_layout(&mut self, text_layout_options: &ResolvedTextLayoutOptions) -> InlineTextLayout {
95        let layouted_text_block = text_layout::position_words(
96            self.words,
97            self.scaled_words,
98            text_layout_options,
99        );
100        // TODO: Cache the layouted text block on the &mut self
101        text_layout::word_positions_to_inline_text_layout(&layouted_text_block, &self.scaled_words)
102    }
103}