1pub mod block;
6pub mod engine;
7pub mod inline;
8pub mod knuth_plass;
9pub mod list;
10pub mod page_break;
11pub mod page_number_resolver;
12pub mod properties;
13pub mod streaming;
14pub mod table;
15
16pub use block::BlockLayoutContext;
17pub use engine::{LayoutEngine, MultiColumnLayout};
18pub use inline::{InlineArea, InlineLayoutContext, LineBreaker, TextAlign};
19pub use knuth_plass::KnuthPlassBreaker;
20pub use list::{ListLayout, ListMarkerStyle};
21pub use page_break::PageBreaker;
22pub use page_number_resolver::PageNumberResolver;
23pub use properties::{
24 extract_break_after, extract_break_before, extract_clear, extract_column_count,
25 extract_column_gap, extract_end_indent, extract_keep_constraint, extract_letter_spacing,
26 extract_line_height, extract_opacity, extract_orphans, extract_overflow, extract_space_after,
27 extract_space_before, extract_start_indent, extract_text_indent, extract_traits,
28 extract_widows, extract_word_spacing, BreakValue, Keep, KeepConstraint, OverflowBehavior,
29};
30pub use streaming::{StreamingConfig, StreamingLayoutEngine, StreamingLayoutIterator};
31pub use table::{
32 BorderCollapse, CellCollapsedBorders, CollapsedBorder, ColumnInfo, ColumnWidth, TableLayout,
33 TableLayoutMode,
34};
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use fop_types::{Length, Point, Rect, Size};
40
41 fn make_rect(w: f64, h: f64) -> Rect {
42 Rect::from_point_size(
43 Point::ZERO,
44 Size::new(Length::from_pt(w), Length::from_pt(h)),
45 )
46 }
47
48 #[test]
51 fn test_block_layout_context_new() {
52 let ctx = BlockLayoutContext::new(Length::from_pt(400.0));
53 assert_eq!(ctx.total_height(), Length::ZERO);
54 }
55
56 #[test]
57 fn test_block_layout_context_allocate() {
58 let mut ctx = BlockLayoutContext::new(Length::from_pt(400.0));
59 let rect = ctx.allocate(Length::from_pt(400.0), Length::from_pt(20.0));
60 assert_eq!(rect.width, Length::from_pt(400.0));
61 assert_eq!(rect.height, Length::from_pt(20.0));
62 assert_eq!(ctx.total_height(), Length::from_pt(20.0));
63 }
64
65 #[test]
66 fn test_block_layout_context_allocate_multiple() {
67 let mut ctx = BlockLayoutContext::new(Length::from_pt(400.0));
68 ctx.allocate(Length::from_pt(400.0), Length::from_pt(20.0));
69 ctx.allocate(Length::from_pt(400.0), Length::from_pt(30.0));
70 assert_eq!(ctx.total_height(), Length::from_pt(50.0));
71 }
72
73 #[test]
74 fn test_block_layout_context_add_space() {
75 let mut ctx = BlockLayoutContext::new(Length::from_pt(400.0));
76 ctx.add_space(Length::from_pt(10.0));
77 assert_eq!(ctx.total_height(), Length::from_pt(10.0));
78 }
79
80 #[test]
81 fn test_block_layout_context_allocate_with_spacing() {
82 let mut ctx = BlockLayoutContext::new(Length::from_pt(400.0));
83 let rect = ctx.allocate_with_spacing(
84 Length::from_pt(400.0),
85 Length::from_pt(12.0),
86 Length::from_pt(6.0),
87 Length::from_pt(6.0),
88 );
89 assert_eq!(rect.width, Length::from_pt(400.0));
91 }
92
93 #[test]
96 fn test_text_align_display_left() {
97 let align = TextAlign::Left;
98 let s = format!("{}", align);
99 assert!(!s.is_empty());
100 }
101
102 #[test]
103 fn test_text_align_display_center() {
104 let align = TextAlign::Center;
105 let s = format!("{}", align);
106 assert!(!s.is_empty());
107 }
108
109 #[test]
110 fn test_text_align_display_right() {
111 let align = TextAlign::Right;
112 let s = format!("{}", align);
113 assert!(!s.is_empty());
114 }
115
116 #[test]
119 fn test_inline_layout_context_new() {
120 let ctx = InlineLayoutContext::new(Length::from_pt(400.0), Length::from_pt(12.0));
121 assert!(ctx.is_empty());
122 assert_eq!(ctx.used_width(), Length::ZERO);
123 }
124
125 #[test]
126 fn test_inline_layout_context_fits() {
127 let ctx = InlineLayoutContext::new(Length::from_pt(400.0), Length::from_pt(12.0));
128 assert!(ctx.fits(Length::from_pt(100.0)));
129 assert!(!ctx.fits(Length::from_pt(500.0)));
130 }
131
132 #[test]
133 fn test_inline_layout_context_remaining_width() {
134 let ctx = InlineLayoutContext::new(Length::from_pt(400.0), Length::from_pt(12.0));
135 assert_eq!(ctx.remaining_width(), Length::from_pt(400.0));
136 }
137
138 #[test]
139 fn test_inline_layout_context_with_text_align() {
140 let ctx = InlineLayoutContext::new(Length::from_pt(400.0), Length::from_pt(12.0))
141 .with_text_align(TextAlign::Center);
142 let _ = ctx;
144 }
145
146 #[test]
149 fn test_line_breaker_new() {
150 let breaker = LineBreaker::new(Length::from_pt(400.0));
151 let _ = breaker;
152 }
153
154 #[test]
155 fn test_line_breaker_break_into_words_empty() {
156 let breaker = LineBreaker::new(Length::from_pt(400.0));
157 let words = breaker.break_into_words("");
158 assert!(words.is_empty());
159 }
160
161 #[test]
162 fn test_line_breaker_break_into_words_single() {
163 let breaker = LineBreaker::new(Length::from_pt(400.0));
164 let words = breaker.break_into_words("hello");
165 assert_eq!(words.len(), 1);
166 assert_eq!(words[0], "hello");
167 }
168
169 #[test]
170 fn test_line_breaker_break_into_words_multiple() {
171 let breaker = LineBreaker::new(Length::from_pt(400.0));
172 let words = breaker.break_into_words("hello world foo");
173 assert_eq!(words.len(), 3);
174 }
175
176 #[test]
177 fn test_line_breaker_measure_text() {
178 let breaker = LineBreaker::new(Length::from_pt(400.0));
179 let width = breaker.measure_text("hello", Length::from_pt(12.0));
180 assert!(width > Length::ZERO);
181 }
182
183 #[test]
184 fn test_line_breaker_break_lines() {
185 let breaker = LineBreaker::new(Length::from_pt(400.0));
186 let lines = breaker.break_lines("short text", Length::from_pt(12.0));
187 assert!(!lines.is_empty());
188 }
189
190 #[test]
193 fn test_page_number_resolver_new() {
194 let resolver = PageNumberResolver::new();
195 assert_eq!(resolver.current_page(), 1);
196 }
197
198 #[test]
199 fn test_page_number_resolver_set_current_page() {
200 let mut resolver = PageNumberResolver::new();
201 resolver.set_current_page(5);
202 assert_eq!(resolver.current_page(), 5);
203 }
204
205 #[test]
206 fn test_page_number_resolver_register_element() {
207 use crate::area::{Area, AreaTree, AreaType};
208 let mut resolver = PageNumberResolver::new();
209 let mut tree = AreaTree::new();
210 let id = tree.add_area(Area::new(AreaType::Block, make_rect(100.0, 50.0)));
211 resolver.register_element("my-id".to_string(), id);
212 let format = resolver.get_format_for_id("my-id");
214 let _ = format;
216 }
217
218 #[test]
219 fn test_page_number_resolver_format() {
220 let mut resolver = PageNumberResolver::new();
221 resolver.set_current_format("1".to_string());
222 assert_eq!(resolver.current_format(), "1");
223 }
224
225 #[test]
228 fn test_break_value_forces_break_auto() {
229 let bv = BreakValue::Auto;
230 assert!(!bv.forces_break());
231 }
232
233 #[test]
234 fn test_break_value_forces_break_page() {
235 let bv = BreakValue::Page;
236 assert!(bv.forces_break());
237 }
238
239 #[test]
240 fn test_break_value_forces_page_break_column() {
241 let bv = BreakValue::Column;
242 assert!(!bv.forces_page_break());
243 }
244
245 #[test]
248 fn test_streaming_config_re_exported() {
249 let config = StreamingConfig::default();
250 assert_eq!(config.max_memory_pages, 10);
251 }
252
253 #[test]
254 fn test_streaming_layout_engine_re_exported() {
255 let engine = StreamingLayoutEngine::new();
256 let _ = engine;
257 }
258}