Skip to content

Commit bad099a

Browse files
committed
Fix feature flag matrix
1 parent 3f1f74a commit bad099a

File tree

8 files changed

+148
-24
lines changed

8 files changed

+148
-24
lines changed

layout/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@ widgets = ["text_layout", "dep:strfmt"]
6969
extra = ["dep:tfd"]
7070

7171
# Basic text shaping (unicode support, allsorts font parsing)
72+
# Requires font_loading for font discovery (FcFontCache)
7273
# Does NOT include hyphenation (saves ~25 dependencies)
7374
text_layout = [
75+
"std",
76+
"font_loading",
7477
"dep:unicode-normalization",
7578
"dep:allsorts",
7679
"dep:tinyvec",

layout/src/font_traits.rs

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
66
use azul_core::geom::LogicalSize;
77

8-
#[cfg(feature = "text_layout")]
8+
#[cfg(all(feature = "text_layout", feature = "font_loading"))]
99
pub use crate::text3::script::Language;
10-
#[cfg(feature = "text_layout")]
10+
#[cfg(all(feature = "text_layout", feature = "font_loading"))]
1111
pub use crate::text3::{
1212
cache::{
1313
AvailableSpace, BidiDirection, ContentIndex, FontHash, FontManager, FontSelector,
@@ -19,8 +19,12 @@ pub use crate::text3::{
1919
script::Script,
2020
};
2121

22+
#[cfg(all(feature = "text_layout", feature = "font_loading"))]
2223
pub type TextLayoutCache = LayoutCache;
2324

25+
#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
26+
pub use stub::TextLayoutCache;
27+
2428
/// Trait for types that support cheap, shallow cloning (e.g., reference-counted types).
2529
pub trait ShallowClone {
2630
/// Create a shallow clone (increment reference count, don't copy data)
@@ -67,11 +71,42 @@ pub trait FontLoaderTrait<T>: Send + core::fmt::Debug {
6771
fn load_font(&self, font_bytes: &[u8], font_index: usize) -> Result<T, LayoutError>;
6872
}
6973

70-
// When text_layout is disabled, provide minimal stub types
71-
#[cfg(not(feature = "text_layout"))]
74+
/// Opaque font identifier - wraps the underlying font system's ID type
75+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
76+
pub struct FontId(pub u64);
77+
78+
/// Trait for font system abstraction (font discovery, fallback chains).
79+
///
80+
/// This abstracts over the underlying font system (e.g., rust_fontconfig, fontdb)
81+
/// allowing text3 to work with or without system font discovery.
82+
pub trait FontSystemTrait: Send + Sync {
83+
/// The type of font fallback chain this system uses
84+
type FallbackChain: FontFallbackChainTrait;
85+
86+
/// Resolve a character to a font ID using the fallback chain
87+
fn resolve_char(&self, chain: &Self::FallbackChain, c: char) -> Option<FontId>;
88+
89+
/// Get the font data (bytes) for a font ID
90+
fn get_font_data(&self, font_id: FontId) -> Option<alloc::vec::Vec<u8>>;
91+
92+
/// Get the font index within the font file
93+
fn get_font_index(&self, font_id: FontId) -> usize;
94+
}
95+
96+
/// Trait for font fallback chains
97+
pub trait FontFallbackChainTrait: Clone + Send + Sync {
98+
/// Check if the chain is empty
99+
fn is_empty(&self) -> bool;
100+
101+
/// Get the primary font ID (if any)
102+
fn primary_font_id(&self) -> Option<FontId>;
103+
}
104+
105+
// When text_layout or font_loading is disabled, provide minimal stub types
106+
#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
72107
pub use stub::*;
73108

74-
#[cfg(not(feature = "text_layout"))]
109+
#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
75110
mod stub {
76111
use super::*;
77112

@@ -94,13 +129,18 @@ mod stub {
94129
RightToLeft,
95130
}
96131

132+
/// Stub for BidiDirection when text_layout is disabled
133+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
134+
pub enum BidiDirection {
135+
Ltr,
136+
Rtl,
137+
}
138+
97139
#[derive(Debug, Clone)]
98140
pub struct StyleProperties;
99141

100142
#[derive(Debug, Clone)]
101-
pub struct Glyph<T> {
102-
_phantom: core::marker::PhantomData<T>,
103-
}
143+
pub struct Glyph;
104144

105145
#[derive(Debug, Clone, Copy)]
106146
pub struct VerticalMetrics {
@@ -124,14 +164,10 @@ mod stub {
124164
pub struct FontSelector;
125165

126166
#[derive(Debug)]
127-
pub struct FontManager<T, Q> {
128-
_phantom: core::marker::PhantomData<(T, Q)>,
129-
}
167+
pub struct FontManager;
130168

131169
#[derive(Debug)]
132-
pub struct LayoutCache<T> {
133-
_phantom: core::marker::PhantomData<T>,
134-
}
170+
pub struct LayoutCache;
135171

136172
// Additional stub types needed by solver3
137173
pub type ContentIndex = usize;
@@ -186,7 +222,7 @@ mod stub {
186222
#[derive(Debug, Clone)]
187223
pub struct UnifiedLayout;
188224

189-
pub type TextLayoutCache = LayoutCache<()>;
225+
pub type TextLayoutCache = LayoutCache;
190226

191227
pub type Size = azul_core::geom::LogicalSize;
192228
}

layout/src/fragmentation.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,20 @@ use azul_css::props::layout::fragmentation::{
3131
BoxDecorationBreak, BreakInside, Orphans, PageBreak, Widows,
3232
};
3333

34+
#[cfg(all(feature = "text_layout", feature = "font_loading"))]
3435
use crate::solver3::display_list::{DisplayList, DisplayListItem};
3536

37+
// Stub types when text_layout or font_loading is disabled
38+
#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
39+
#[derive(Debug, Clone, Default)]
40+
pub struct DisplayList {
41+
pub items: Vec<DisplayListItem>,
42+
}
43+
44+
#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
45+
#[derive(Debug, Clone)]
46+
pub struct DisplayListItem;
47+
3648
// Page Templates (Headers, Footers, Running Content)
3749

3850
/// Counter that tracks page numbers and other running content

layout/src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub mod font_traits;
1515
pub mod image;
1616
#[cfg(feature = "text_layout")]
1717
pub mod managers;
18+
#[cfg(feature = "text_layout")]
1819
pub mod solver3;
1920

2021
// Widget modules (behind feature flags)
@@ -35,12 +36,12 @@ pub mod callbacks;
3536
pub mod cpurender;
3637
#[cfg(feature = "text_layout")]
3738
pub mod event_determination;
38-
#[cfg(feature = "font_loading")]
39+
#[cfg(feature = "text_layout")]
3940
pub mod font;
4041
// Re-export allsorts types needed by printpdf
41-
#[cfg(feature = "font_loading")]
42+
#[cfg(feature = "text_layout")]
4243
pub use allsorts::subset::CmapTarget;
43-
#[cfg(feature = "font_loading")]
44+
#[cfg(feature = "text_layout")]
4445
pub use font::parsed::{
4546
FontParseWarning, FontParseWarningSeverity, FontType, OwnedGlyph, ParsedFont, PdfFontMetrics,
4647
SubsetFont,
@@ -113,7 +114,7 @@ pub fn parse_font_fn(
113114
.map(|parsed_font| parsed_font_to_font_ref(parsed_font))
114115
}
115116

116-
#[cfg(feature = "font_loading")]
117+
#[cfg(feature = "text_layout")]
117118
pub fn parsed_font_to_font_ref(
118119
parsed_font: crate::font::parsed::ParsedFont,
119120
) -> azul_css::props::basic::FontRef {
@@ -130,7 +131,7 @@ pub fn parsed_font_to_font_ref(
130131
azul_css::props::basic::FontRef::new(raw_ptr, parsed_font_destructor)
131132
}
132133

133-
#[cfg(feature = "font_loading")]
134+
#[cfg(feature = "text_layout")]
134135
pub fn font_ref_to_parsed_font(
135136
font_ref: &azul_css::props::basic::FontRef,
136137
) -> &crate::font::parsed::ParsedFont {

layout/src/paged.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@
1515
1616
use azul_core::geom::{LogicalPosition, LogicalSize};
1717

18+
#[cfg(all(feature = "text_layout", feature = "font_loading"))]
1819
use crate::solver3::display_list::DisplayList;
1920

21+
// Stub type when text_layout or font_loading is disabled
22+
#[cfg(not(all(feature = "text_layout", feature = "font_loading")))]
23+
#[derive(Debug, Clone, Default)]
24+
pub struct DisplayList;
25+
2026
/// Represents a series of containers that content flows into during layout.
2127
///
2228
/// This is the core abstraction for fragmentation support. Different media types

layout/src/text3/cache.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,31 @@ use azul_css::{
2121
corety::LayoutDebugMessage, props::basic::ColorU, props::style::StyleBackgroundContent,
2222
};
2323
#[cfg(feature = "text_layout_hyphenation")]
24-
use hyphenation::{Hyphenator, Language, Load, Standard};
24+
use hyphenation::{Hyphenator, Language as HyphenationLanguage, Load, Standard};
2525
use rust_fontconfig::{FcFontCache, FcPattern, FcWeight, FontId, PatternMatch, UnicodeRange};
2626
use unicode_bidi::{BidiInfo, Level, TextSource};
2727
use unicode_segmentation::UnicodeSegmentation;
2828

29+
// Stub type when hyphenation is disabled
2930
#[cfg(not(feature = "text_layout_hyphenation"))]
30-
use crate::text3::script::Language;
31-
use crate::text3::script::{script_to_language, Script};
31+
pub struct Standard;
32+
33+
#[cfg(not(feature = "text_layout_hyphenation"))]
34+
impl Standard {
35+
/// Stub hyphenate method that returns no breaks
36+
pub fn hyphenate<'a>(&'a self, _word: &'a str) -> StubHyphenationBreaks {
37+
StubHyphenationBreaks { breaks: Vec::new() }
38+
}
39+
}
40+
41+
/// Result of hyphenation (stub when feature is disabled)
42+
#[cfg(not(feature = "text_layout_hyphenation"))]
43+
pub struct StubHyphenationBreaks {
44+
pub breaks: alloc::vec::Vec<usize>,
45+
}
46+
47+
// Always import Language from script module
48+
use crate::text3::script::{script_to_language, Language, Script};
3249

3350
/// Available space for layout, similar to Taffy's AvailableSpace.
3451
///
@@ -6586,10 +6603,17 @@ fn polygon_line_intersection(
65866603
// ADDITION: A helper function to get a hyphenator.
65876604
/// Helper to get a hyphenator for a given language.
65886605
/// TODO: In a real app, this would be cached.
6589-
fn get_hyphenator(language: Language) -> Result<Standard, LayoutError> {
6606+
#[cfg(feature = "text_layout_hyphenation")]
6607+
fn get_hyphenator(language: HyphenationLanguage) -> Result<Standard, LayoutError> {
65906608
Standard::from_embedded(language).map_err(|e| LayoutError::HyphenationError(e.to_string()))
65916609
}
65926610

6611+
/// Stub when hyphenation is disabled - always returns an error
6612+
#[cfg(not(feature = "text_layout_hyphenation"))]
6613+
fn get_hyphenator(_language: Language) -> Result<Standard, LayoutError> {
6614+
Err(LayoutError::HyphenationError("Hyphenation feature not enabled".to_string()))
6615+
}
6616+
65936617
fn is_break_opportunity(item: &ShapedItem) -> bool {
65946618
// Break after spaces or explicit break items.
65956619
if is_word_separator(item) {

layout/src/text3/knuth_plass.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use std::sync::Arc;
55

66
#[cfg(feature = "text_layout_hyphenation")]
77
use hyphenation::{Hyphenator, Standard};
8+
#[cfg(not(feature = "text_layout_hyphenation"))]
9+
use crate::text3::cache::Standard;
810

911
use crate::text3::cache::{
1012
get_base_direction_from_logical, get_item_measure, is_word_separator, AvailableSpace,

layout/src/thread.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,26 @@ impl Clone for ThreadSendCallback {
231231
}
232232
}
233233

234+
impl PartialEq for ThreadSendCallback {
235+
fn eq(&self, other: &Self) -> bool {
236+
self.cb as usize == other.cb as usize
237+
}
238+
}
239+
240+
impl Eq for ThreadSendCallback {}
241+
242+
impl PartialOrd for ThreadSendCallback {
243+
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
244+
Some(self.cmp(other))
245+
}
246+
}
247+
248+
impl Ord for ThreadSendCallback {
249+
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
250+
(self.cb as usize).cmp(&(other.cb as usize))
251+
}
252+
}
253+
234254
/// Destructor callback for ThreadSender
235255
pub type ThreadSenderDestructorCallbackType = extern "C" fn(*mut ThreadSenderInner);
236256

@@ -255,6 +275,26 @@ impl Clone for ThreadSenderDestructorCallback {
255275
}
256276
}
257277

278+
impl PartialEq for ThreadSenderDestructorCallback {
279+
fn eq(&self, other: &Self) -> bool {
280+
self.cb as usize == other.cb as usize
281+
}
282+
}
283+
284+
impl Eq for ThreadSenderDestructorCallback {}
285+
286+
impl PartialOrd for ThreadSenderDestructorCallback {
287+
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
288+
Some(self.cmp(other))
289+
}
290+
}
291+
292+
impl Ord for ThreadSenderDestructorCallback {
293+
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
294+
(self.cb as usize).cmp(&(other.cb as usize))
295+
}
296+
}
297+
258298
/// Callback that runs when a thread receives a `WriteBack` message
259299
///
260300
/// This callback runs on the main UI thread and has access dir_to:

0 commit comments

Comments
 (0)