@@ -42,6 +42,7 @@ struct LineState {
4242 /// Of the line currently being built, the maximum line height seen so far.
4343 /// This represents a lower-bound on the eventual line height of the line.
4444 running_line_height : f32 ,
45+ max_height_exceeded : bool ,
4546
4647 /// We lag the text-wrap-mode by one cluster due to line-breaking boundaries only
4748 /// being triggered on the cluster after the linebreak.
@@ -184,6 +185,7 @@ impl BreakerState {
184185 #[ inline( always) ]
185186 fn add_line_height ( & mut self , height : f32 ) {
186187 self . line . running_line_height = self . line . running_line_height . max ( height) ;
188+ self . line . max_height_exceeded = self . line . running_line_height > self . line_max_height ;
187189 }
188190
189191 pub fn set_layout_max_advance ( & mut self , advance : f32 ) {
@@ -259,6 +261,13 @@ impl<'a, B: Brush> BreakLines<'a, B> {
259261 }
260262 }
261263
264+ fn max_height_break_data ( & self , line_height : f32 ) -> Option < YieldData > {
265+ Some ( YieldData :: MaxHeightExceeded ( MaxHeightBreakData {
266+ advance : self . state . line . x ,
267+ line_height,
268+ } ) )
269+ }
270+
262271 pub fn state ( & self ) -> & BreakerState {
263272 & self . state
264273 }
@@ -374,6 +383,11 @@ impl<'a, B: Brush> BreakLines<'a, B> {
374383
375384 // println!("BOX next_x: {}", next_x);
376385
386+ let box_will_be_appended = next_x <= max_advance || self . state . line . x == 0.0 ;
387+ if height_contribution > self . state . line_max_height && box_will_be_appended {
388+ return self . max_height_break_data ( height_contribution) ;
389+ }
390+
377391 // If the box fits on the current line (or we are at the start of the current line)
378392 // then simply move on to the next item
379393 if next_x <= max_advance || self . state . line . text_wrap_mode != TextWrapMode :: Wrap
@@ -425,6 +439,8 @@ impl<'a, B: Brush> BreakLines<'a, B> {
425439 let is_newline = whitespace == Whitespace :: Newline ;
426440 let is_space = whitespace. is_space_or_nbsp ( ) ;
427441 let boundary = cluster. info ( ) . boundary ( ) ;
442+ let line_height = run. metrics ( ) . line_height ;
443+ let max_height_exceeded = self . state . line . max_height_exceeded ;
428444 let style = & self . layout . data . styles [ cluster. data . style_index as usize ] ;
429445
430446 // Lag text_wrap_mode style by one cluster
@@ -441,10 +457,11 @@ impl<'a, B: Brush> BreakLines<'a, B> {
441457 // break_opportunity = true;
442458 }
443459 } else if is_newline {
444- self . state . append_cluster_to_line (
445- self . state . line . x ,
446- run. metrics ( ) . line_height ,
447- ) ;
460+ if max_height_exceeded {
461+ return self . max_height_break_data ( line_height) ;
462+ }
463+ self . state
464+ . append_cluster_to_line ( self . state . line . x , line_height) ;
448465 if try_commit_line ! ( BreakReason :: Explicit ) {
449466 // TODO: can this be hoisted out of the conditional?
450467 self . state . cluster_idx += 1 ;
@@ -483,7 +500,9 @@ impl<'a, B: Brush> BreakLines<'a, B> {
483500 //
484501 // We simply append the cluster(s) to the current line
485502 if next_x <= max_advance {
486- let line_height = run. metrics ( ) . line_height ;
503+ if max_height_exceeded {
504+ return self . max_height_break_data ( line_height) ;
505+ }
487506 self . state . append_cluster_to_line ( next_x, line_height) ;
488507 self . state . cluster_idx += 1 ;
489508 if is_space {
@@ -500,7 +519,9 @@ impl<'a, B: Brush> BreakLines<'a, B> {
500519 //
501520 // We hang any overflowing whitespace and then line-break.
502521 if is_space && text_wrap_mode == TextWrapMode :: Wrap {
503- let line_height = run. metrics ( ) . line_height ;
522+ if max_height_exceeded {
523+ return self . max_height_break_data ( line_height) ;
524+ }
504525 self . state . append_cluster_to_line ( next_x, line_height) ;
505526 if try_commit_line ! ( BreakReason :: Regular ) {
506527 // TODO: can this be hoisted out of the conditional?
@@ -551,7 +572,9 @@ impl<'a, B: Brush> BreakLines<'a, B> {
551572 //
552573 // We fall back to appending the content to the line.
553574 else {
554- let line_height = run. metrics ( ) . line_height ;
575+ if max_height_exceeded {
576+ return self . max_height_break_data ( line_height) ;
577+ }
555578 self . state . append_cluster_to_line ( next_x, line_height) ;
556579 self . state . cluster_idx += 1 ;
557580 }
@@ -597,7 +620,7 @@ impl<'a, B: Brush> BreakLines<'a, B> {
597620 self . state . line_y += line_break_data. line_height as f64 ;
598621 continue ;
599622 }
600- YieldData :: MaxHeightExceeded ( _) => continue ,
623+ YieldData :: MaxHeightExceeded ( _) => continue , // unreachable because max_height is set to f32::MAX
601624 YieldData :: InlineBoxBreak ( _) => continue ,
602625 }
603626 }
0 commit comments