@@ -64,11 +64,14 @@ pub struct LineBreakData {
6464}
6565
6666pub struct BoxBreakData {
67- pub inline_box_id : usize ,
67+ /// The user-supplied ID for the inline box
68+ pub inline_box_id : u64 ,
69+ // The index of the inline box within the inline_boxes `Vec`
70+ pub inline_box_index : usize ,
6871}
6972
7073#[ derive( Clone , Default ) ]
71- struct BreakerState {
74+ pub struct BreakerState {
7275 /// The number of items that have been processed (used to revert state)
7376 items : usize ,
7477 /// The number of lines that have been processed (used to revert state)
@@ -81,9 +84,16 @@ struct BreakerState {
8184 /// Iteration state: the current cluster (within the layout)
8285 cluster_idx : usize ,
8386
84- /// The y coordinate of the bottom of the last committed line (or else 0)
87+ /// The x coordinate of the left/start of the current line
88+ line_x : f32 ,
89+ /// The y coordinate of the top/start of the current line
8590 /// Use of f64 here is important. f32 causes test failures due to accumulated error
86- committed_y : f64 ,
91+ line_y : f64 ,
92+
93+ /// The max advance of the entire layout.
94+ layout_max_advance : f32 ,
95+ /// The max advance (max width) of the current line. This must be <= the `layout_max_advance`.
96+ line_max_advance : f32 ,
8797
8898 line : LineState ,
8999 prev_boundary : Option < PrevBoundaryState > ,
@@ -92,7 +102,7 @@ struct BreakerState {
92102
93103impl BreakerState {
94104 /// Add the cluster(s) currently being evaluated to the current line
95- fn append_cluster_to_line ( & mut self , next_x : f32 ) {
105+ pub fn append_cluster_to_line ( & mut self , next_x : f32 ) {
96106 self . line . items . end = self . item_idx + 1 ;
97107 self . line . clusters . end = self . cluster_idx + 1 ;
98108 self . line . x = next_x;
@@ -101,7 +111,7 @@ impl BreakerState {
101111 }
102112
103113 /// Add inline box to line
104- fn append_inline_box_to_line ( & mut self , next_x : f32 ) {
114+ pub fn append_inline_box_to_line ( & mut self , next_x : f32 ) {
105115 // self.item_idx += 1;
106116 self . line . items . end += 1 ;
107117 self . line . x = next_x;
@@ -111,7 +121,7 @@ impl BreakerState {
111121
112122 /// Store the current iteration state so that we can revert to it if we later want to take
113123 /// the line breaking opportunity at this point.
114- fn mark_line_break_opportunity ( & mut self ) {
124+ pub fn mark_line_break_opportunity ( & mut self ) {
115125 self . prev_boundary = Some ( PrevBoundaryState {
116126 item_idx : self . item_idx ,
117127 run_idx : self . run_idx ,
@@ -122,14 +132,36 @@ impl BreakerState {
122132
123133 /// Store the current iteration state so that we can revert to it if we later want to take
124134 /// an *emergency* line breaking opportunity at this point.
125- fn mark_emergency_break_opportunity ( & mut self ) {
135+ pub fn mark_emergency_break_opportunity ( & mut self ) {
126136 self . emergency_boundary = Some ( PrevBoundaryState {
127137 item_idx : self . item_idx ,
128138 run_idx : self . run_idx ,
129139 cluster_idx : self . cluster_idx ,
130140 state : self . line . clone ( ) ,
131141 } ) ;
132142 }
143+
144+ pub fn set_layout_max_advance ( & mut self , advance : f32 ) {
145+ self . layout_max_advance = advance;
146+ }
147+
148+ pub fn set_line_max_advance ( & mut self , advance : f32 ) {
149+ self . line_max_advance = advance;
150+ }
151+
152+ pub fn line_x ( & self ) -> f32 {
153+ self . line_x
154+ }
155+ pub fn set_line_x ( & mut self , x : f32 ) {
156+ self . line_x = x;
157+ }
158+
159+ pub fn line_y ( & self ) -> f64 {
160+ self . line_y
161+ }
162+ pub fn set_line_y ( & mut self , y : f64 ) {
163+ self . line_y = y;
164+ }
133165}
134166
135167/// Line breaking support for a paragraph.
@@ -179,9 +211,35 @@ impl<'a, B: Brush> BreakLines<'a, B> {
179211 }
180212 }
181213
214+ pub fn state ( & self ) -> & BreakerState {
215+ & self . state
216+ }
217+
218+ pub fn state_mut ( & mut self ) -> & mut BreakerState {
219+ & mut self . state
220+ }
221+
222+ /// Reverts the to an externally saved state.
223+ pub fn revert_to ( & mut self , state : BreakerState ) {
224+ self . state = state;
225+ self . lines . lines . truncate ( self . state . lines ) ;
226+ self . lines . line_items . truncate ( self . state . items ) ;
227+ self . done = false ;
228+ }
229+
230+ /// Reverts the last computed line, returning to the previous state.
231+ pub fn revert ( & mut self ) -> bool {
232+ if let Some ( state) = self . prev_state . take ( ) {
233+ self . revert_to ( state) ;
234+ true
235+ } else {
236+ false
237+ }
238+ }
239+
182240 /// Returns the y-coordinate of the top of the current line
183241 pub fn committed_y ( & self ) -> f64 {
184- self . state . committed_y
242+ self . state . line_y
185243 }
186244
187245 /// Returns true if all the text has been placed into lines.
@@ -191,13 +249,13 @@ impl<'a, B: Brush> BreakLines<'a, B> {
191249
192250 /// Computes the next line in the paragraph. Returns the advance and size
193251 /// (width and height for horizontal layouts) of the line.
194- pub fn break_next ( & mut self , max_advance : f32 ) -> Option < YieldData > {
195- self . break_next_line_or_box ( max_advance )
252+ pub fn break_next ( & mut self ) -> Option < YieldData > {
253+ self . break_next_line_or_box ( )
196254 }
197255
198256 /// Computes the next line in the paragraph. Returns the advance and size
199257 /// (width and height for horizontal layouts) of the line.
200- fn break_next_line_or_box ( & mut self , max_advance : f32 ) -> Option < YieldData > {
258+ fn break_next_line_or_box ( & mut self ) -> Option < YieldData > {
201259 // Maintain iterator state
202260 if self . done {
203261 return None ;
@@ -210,7 +268,7 @@ impl<'a, B: Brush> BreakLines<'a, B> {
210268 if self . layout . data . text_len == 0 && self . layout . data . inline_boxes . is_empty ( ) {
211269 f32:: MAX
212270 } else {
213- max_advance
271+ self . state . line_max_advance
214272 } ;
215273
216274 // This macro simply calls the `commit_line` with the provided arguments and some parts of self.
@@ -248,6 +306,15 @@ impl<'a, B: Brush> BreakLines<'a, B> {
248306 LayoutItemKind :: InlineBox => {
249307 let inline_box = & self . layout . data . inline_boxes [ item. index ] ;
250308
309+ // If the box is marked as "break_on_box", then the assumption is that the caller will handle placement of the box.
310+ if inline_box. break_on_box {
311+ self . state . item_idx += 1 ;
312+ return Some ( YieldData :: InlineBoxBreak ( BoxBreakData {
313+ inline_box_id : inline_box. id ,
314+ inline_box_index : item. index ,
315+ } ) ) ;
316+ }
317+
251318 // Compute the x position of the content being currently processed
252319 let next_x = self . state . line . x + inline_box. width ;
253320
@@ -424,19 +491,6 @@ impl<'a, B: Brush> BreakLines<'a, B> {
424491 None
425492 }
426493
427- /// Reverts the last computed line, returning to the previous state.
428- pub fn revert ( & mut self ) -> bool {
429- if let Some ( state) = self . prev_state . take ( ) {
430- self . state = state;
431- self . lines . lines . truncate ( self . state . lines ) ;
432- self . lines . line_items . truncate ( self . state . items ) ;
433- self . done = false ;
434- true
435- } else {
436- false
437- }
438- }
439-
440494 /// Breaks all remaining lines with the specified maximum advance. This
441495 /// consumes the line breaker.
442496 pub fn break_remaining ( mut self , max_advance : f32 ) {
@@ -452,8 +506,17 @@ impl<'a, B: Brush> BreakLines<'a, B> {
452506 // }
453507
454508 // println!("\nBREAK ALL");
455-
456- while self . break_next ( max_advance) . is_some ( ) { }
509+ self . state . layout_max_advance = max_advance;
510+ self . state . line_max_advance = max_advance;
511+ while let Some ( data) = self . break_next ( ) {
512+ match data {
513+ YieldData :: LineBreak ( line_break_data) => {
514+ self . state . line_y += line_break_data. line_height as f64 ;
515+ continue ;
516+ }
517+ YieldData :: InlineBoxBreak ( _) => continue ,
518+ }
519+ }
457520 self . finish ( ) ;
458521 }
459522
@@ -476,7 +539,7 @@ impl<'a, B: Brush> BreakLines<'a, B> {
476539
477540 // Whether metrics should be quantized to pixel boundaries
478541 let quantize = self . layout . data . quantize ;
479- let y = self . state . committed_y ;
542+ let y = self . state . line_y ;
480543
481544 // Reset metrics for line
482545 line. metrics . ascent = 0. ;
@@ -661,7 +724,8 @@ impl<'a, B: Brush> BreakLines<'a, B> {
661724 line. metrics . block_min_coord = line. metrics . baseline - ascent - leading_above. max ( 0. ) ;
662725 line. metrics . block_max_coord = line. metrics . baseline + descent + leading_below. max ( 0. ) ;
663726
664- self . state . committed_y += line. metrics . line_height as f64 ;
727+ line. metrics . inline_min_coord = self . state . line_x ;
728+ line. metrics . inline_max_coord = self . state . line_x + self . state . line_max_advance ;
665729 }
666730}
667731
0 commit comments