Skip to main content

azul_layout/
lib.rs

1//! Layout crate for the Azul GUI framework.
2//!
3//! Provides the layout solver (`solver3`), text shaping (`text3`), font
4//! management (`font`), hit testing, page fragmentation, and widget support.
5//! Integrates with `azul-core` for DOM types and `azul-css` for style
6//! properties.
7
8#![doc(
9    html_logo_url = "https://raw.githubusercontent.com/maps4print/azul/master/assets/images/azul_logo_full_min.svg.png",
10    html_favicon_url = "https://raw.githubusercontent.com/maps4print/azul/master/assets/images/favicon.ico"
11)]
12// Lint policy: deny correctness/safety issues, warn on style
13#![deny(unused_must_use)]
14#![warn(clippy::all)]
15#![allow(
16    clippy::non_canonical_partial_ord_impl,
17    clippy::legacy_numeric_constants,
18    clippy::should_implement_trait,
19    clippy::result_unit_err,
20    clippy::ptr_as_ptr,
21    clippy::too_many_arguments,
22    clippy::type_complexity,
23    unused_imports,
24    unused_variables,
25    unused_mut,
26    dead_code,
27    unused_parens,
28    unused_doc_comments,                   // doc comments before macro invocations
29    unused_assignments,                    // layout solver incremental updates
30    unused_labels,
31    dropping_references,                   // intentional scope markers in layout solver
32    private_interfaces,                    // internal solver types exposed for testing
33    function_casts_as_integer,             // widget callback pointer identity
34    improper_ctypes_definitions,           // node_graph extern fn returns ()
35    mismatched_lifetime_syntaxes,
36    unreachable_patterns,                  // exhaustive match in generated property code
37    unexpected_cfgs,
38    deprecated,                            // image crate tiff encoder
39)]
40
41#[macro_use]
42extern crate alloc;
43extern crate core;
44
45/// Font traits available regardless of text layout feature.
46pub mod font_traits;
47/// Optional probe instrumentation. With the `probe` feature off this
48/// is a tiny module of no-op stubs and pays zero cost.
49pub mod probe;
50/// Image decoding and encoding (wraps the `image` crate).
51#[cfg(feature = "image_decoding")]
52pub mod image;
53/// Scroll, hover, clipboard, cursor, and focus managers.
54#[cfg(feature = "text_layout")]
55pub mod managers;
56/// CSS layout solver: block, inline, flex, grid, and table formatting.
57#[cfg(feature = "text_layout")]
58pub mod solver3;
59
60/// C-compatible string formatting via `strfmt`.
61#[cfg(feature = "strfmt")]
62pub mod fmt;
63#[cfg(feature = "strfmt")]
64pub use fmt::{FmtArg, FmtArgVec, FmtArgVecDestructor, FmtValue, fmt_string};
65
66/// Built-in widgets: button, text input, tabs, tree view, node graph, etc.
67#[cfg(feature = "widgets")]
68pub mod widgets;
69
70/// Desktop platform helpers (file dialogs, notifications).
71#[cfg(feature = "extra")]
72pub mod desktop;
73/// Color parsing, XML DOM construction, and misc utilities.
74#[cfg(feature = "extra")]
75pub mod extra;
76
77/// ICU internationalization: date/time formatting, plurals, list formatting.
78#[cfg(any(
79    feature = "icu",
80    all(target_os = "macos", feature = "icu_macos"),
81    all(target_os = "windows", feature = "icu_windows"),
82))]
83pub mod icu;
84#[cfg(any(
85    feature = "icu",
86    all(target_os = "macos", feature = "icu_macos"),
87    all(target_os = "windows", feature = "icu_windows"),
88))]
89pub use icu::{
90    DateTimeFieldSet, FormatLength, IcuDate, IcuDateTime, IcuError,
91    IcuLocalizer, IcuLocalizerHandle, IcuResult, IcuStringVec, IcuTime,
92    LayoutCallbackInfoIcuExt, ListType, PluralCategory,
93};
94
95/// Project Fluent localization: message bundles, argument formatting, ZIP I/O.
96#[cfg(feature = "fluent")]
97pub mod fluent;
98#[cfg(feature = "fluent")]
99pub use fluent::{
100    check_fluent_syntax, check_fluent_syntax_bytes, create_fluent_zip,
101    create_fluent_zip_from_strings, export_to_zip, FluentError,
102    FluentLanguageInfo, FluentLanguageInfoVec,
103    FluentLocalizerHandle, FluentResult, FluentSyntaxCheckResult,
104    FluentSyntaxError, FluentZipLoadResult, LayoutCallbackInfoFluentExt,
105};
106
107/// URL parsing (RFC 3986 compliant).
108#[cfg(feature = "http")]
109pub mod url;
110#[cfg(feature = "http")]
111pub use url::{Url, UrlParseError, ResultUrlUrlParseError};
112
113/// File system operations (C-compatible wrappers for `std::fs`).
114pub mod file;
115pub use file::{
116    dir_create, dir_create_all, dir_list, dir_delete, dir_delete_all,
117    file_copy, path_exists, file_metadata, file_read, file_delete, file_rename, file_write,
118    path_is_dir, path_is_file, path_join, temp_dir,
119    DirEntry, DirEntryVec, DirEntryVecDestructor, DirEntryVecDestructorType,
120    FileError, FileErrorKind, FileMetadata, FilePath, OptionFilePath,
121};
122
123/// HTTP client: GET/POST requests with pure-Rust TLS.
124#[cfg(feature = "http")]
125pub mod http;
126#[cfg(feature = "http")]
127pub use http::{
128    download_bytes, download_bytes_with_config, http_get,
129    http_get_with_config, is_url_reachable, HttpError, HttpHeader,
130    HttpRequestConfig, HttpResponse, HttpResponseTooLargeError, HttpResult,
131    HttpStatusError,
132};
133
134/// JSON parsing and serialization for the C API.
135#[cfg(feature = "json")]
136pub mod json;
137#[cfg(feature = "json")]
138pub use json::{
139    json_parse, json_parse_bytes, json_stringify, json_stringify_pretty,
140    Json, JsonInternal, JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor, JsonKeyValueVecDestructorType,
141    JsonParseError, JsonType, JsonVec,
142    ResultJsonJsonParseError, OptionJson, OptionJsonVec, OptionJsonKeyValueVec,
143};
144
145/// ZIP file creation, extraction, and listing.
146#[cfg(feature = "zip_support")]
147pub mod zip;
148#[cfg(feature = "zip_support")]
149pub use zip::{
150    zip_create, zip_create_from_files, zip_extract_all, zip_list_contents,
151    ZipFile, ZipFileEntry, ZipFileEntryVec, ZipPathEntry, ZipPathEntryVec,
152    ZipReadConfig, ZipWriteConfig, ZipReadError, ZipWriteError,
153};
154
155/// Icon provider: resolves icons from Material Icons font, images, or ZIP packs.
156pub mod icon;
157pub use icon::{
158    // Resolver
159    default_icon_resolver,
160    // Data types for RefAny
161    ImageIconData, FontIconData,
162    // Helpers
163    create_default_icon_provider,
164    register_material_icons,
165    register_embedded_material_icons,
166};
167// Re-export core icon types
168pub use azul_core::icon::{
169    IconProviderHandle, IconResolverCallbackType,
170    resolve_icons_in_styled_dom, OptionIconProviderHandle,
171};
172
173/// Callback handling for layout events (invocation, result processing).
174#[cfg(feature = "text_layout")]
175pub mod callbacks;
176/// CPU-based software rendering (no GPU required).
177#[cfg(feature = "cpurender")]
178pub mod cpurender;
179/// Glyph path and cell cache for CPU text rendering.
180#[cfg(feature = "cpurender")]
181pub mod glyph_cache;
182/// Default keyboard actions (copy, paste, select-all, undo, etc.).
183#[cfg(feature = "text_layout")]
184pub mod default_actions;
185/// Event determination: maps raw input to DOM node callbacks.
186#[cfg(feature = "text_layout")]
187pub mod event_determination;
188/// Font parsing, metrics extraction, and subsetting.
189#[cfg(feature = "text_layout")]
190pub mod font;
191
192/// Headless backend for CPU-only rendering without a display server.
193/// Used with `AZUL_HEADLESS=1` for E2E testing, CI, and screenshot capture.
194#[cfg(feature = "text_layout")]
195pub mod headless;
196// Re-export allsorts types needed by printpdf
197#[cfg(feature = "text_layout")]
198pub use allsorts::subset::CmapTarget;
199#[cfg(feature = "text_layout")]
200pub use font::parsed::{
201    FontParseWarning, FontParseWarningSeverity, FontType, OwnedGlyph, ParsedFont, PdfFontMetrics,
202    SubsetFont,
203};
204// Re-export hyphenation for external crates (like printpdf)
205#[cfg(feature = "text_layout_hyphenation")]
206pub use hyphenation;
207/// CSS fragmentation engine for paged media (page/column breaks).
208pub mod fragmentation;
209/// Hit-testing: maps screen coordinates to DOM nodes.
210#[cfg(feature = "text_layout")]
211pub mod hit_test;
212/// Paged media layout engine (infinite canvas with physical spacers).
213pub mod paged;
214/// Text shaping, line breaking (Knuth-Plass), and inline formatting.
215#[cfg(feature = "text_layout")]
216pub mod text3;
217/// Thread callback wrappers for the C API.
218#[cfg(feature = "text_layout")]
219pub mod thread;
220/// Timer callback wrappers for the C API.
221#[cfg(feature = "text_layout")]
222pub mod timer;
223/// Scroll physics timer for momentum-based smooth scrolling.
224#[cfg(feature = "text_layout")]
225pub mod scroll_timer;
226/// Window layout management: relayout, event processing, state sync.
227#[cfg(feature = "text_layout")]
228pub mod window;
229/// Window state types (keyboard, mouse, DPI, focus).
230#[cfg(feature = "text_layout")]
231pub mod window_state;
232/// XML and XHTML parsing for declarative UI definitions.
233#[cfg(feature = "xml")]
234pub mod xml;
235
236// Export the main layout function and window management
237pub use fragmentation::{
238    BoxBreakBehavior, BreakDecision, FragmentationDefaults, FragmentationLayoutContext,
239    KeepTogetherPriority, PageCounter, PageFragment, PageMargins, PageNumberStyle, PageSlot,
240    PageSlotContent, PageSlotPosition, PageTemplate,
241};
242#[cfg(feature = "text_layout")]
243pub use hit_test::{CursorTypeHitTest, FullHitTest};
244pub use paged::FragmentationState;
245#[cfg(feature = "text_layout")]
246pub use solver3::cache::LayoutCache as Solver3LayoutCache;
247#[cfg(feature = "text_layout")]
248pub use solver3::display_list::DisplayList as DisplayList3;
249#[cfg(feature = "text_layout")]
250pub use solver3::layout_document;
251#[cfg(feature = "text_layout")]
252pub use solver3::paged_layout::layout_document_paged;
253#[cfg(feature = "text_layout")]
254pub use solver3::{LayoutContext, LayoutError, Result as LayoutResult3};
255#[cfg(feature = "text_layout")]
256pub use text3::cache::{FontContext, FontManager, TextShapingCache};
257/// Backwards-compat alias for the old `TextLayoutCache` name.
258/// Will be dropped at the next API revision; new code should use
259/// [`TextShapingCache`] directly.
260pub use text3::cache::TextShapingCache as TextLayoutCache;
261#[cfg(feature = "font_async_registry")]
262pub use rust_fontconfig::registry::FcFontRegistry;
263#[cfg(feature = "text_layout")]
264pub use window::{CursorBlinkTimerAction, LayoutWindow, ScrollbarDragState, TooltipTimerAction};
265#[cfg(feature = "text_layout")]
266pub use managers::text_input::{PendingTextEdit, OptionPendingTextEdit};
267
268#[cfg(feature = "text_layout")]
269/// Parses raw font bytes into a [`FontRef`](azul_css::props::basic::FontRef)
270/// suitable for use in the layout system.
271pub fn parse_font_fn(
272    source: azul_core::resources::LoadedFontSource,
273) -> Option<azul_css::props::basic::FontRef> {
274    use crate::font::parsed::ParsedFont;
275
276    ParsedFont::from_bytes(
277        source.data.as_ref(),
278        source.index as usize,
279        &mut Vec::new(), // Ignore warnings for now
280    )
281    .map(parsed_font_to_font_ref)
282}
283
284#[cfg(feature = "text_layout")]
285/// Wraps a [`ParsedFont`] in a [`FontRef`](azul_css::props::basic::FontRef),
286/// transferring ownership to the returned handle.
287pub fn parsed_font_to_font_ref(
288    parsed_font: crate::font::parsed::ParsedFont,
289) -> azul_css::props::basic::FontRef {
290    use core::ffi::c_void;
291
292    extern "C" fn parsed_font_destructor(ptr: *mut c_void) {
293        unsafe {
294            let _ = Box::from_raw(ptr as *mut crate::font::parsed::ParsedFont);
295        }
296    }
297
298    let boxed = Box::new(parsed_font);
299    let raw_ptr = Box::into_raw(boxed) as *const c_void;
300    azul_css::props::basic::FontRef::new(raw_ptr, parsed_font_destructor)
301}
302
303#[cfg(feature = "text_layout")]
304/// Recovers a reference to the [`ParsedFont`] stored inside a [`FontRef`](azul_css::props::basic::FontRef).
305///
306/// # Safety contract
307/// The `font_ref` must have been created by [`parsed_font_to_font_ref`],
308/// so that `font_ref.parsed` points to a valid `ParsedFont`.
309pub fn font_ref_to_parsed_font(
310    font_ref: &azul_css::props::basic::FontRef,
311) -> &crate::font::parsed::ParsedFont {
312    // SAFETY: `font_ref.parsed` was created by `parsed_font_to_font_ref`
313    // via `Box::into_raw`, so it points to a valid, aligned `ParsedFont`.
314    unsafe { &*(font_ref.parsed as *const crate::font::parsed::ParsedFont) }
315}