@@ -23,6 +23,7 @@ use app_units::Au;
23
23
use atomic_refcell:: AtomicRef ;
24
24
use gfx:: text:: text_run:: GlyphRun ;
25
25
use servo_arc:: Arc ;
26
+ use style:: computed_values:: white_space:: T as WhiteSpace ;
26
27
use style:: logical_geometry:: WritingMode ;
27
28
use style:: properties:: ComputedValues ;
28
29
use style:: values:: computed:: { Length , LengthPercentage , Percentage } ;
@@ -74,6 +75,7 @@ struct InlineNestingLevelState<'box_tree> {
74
75
inline_start : Length ,
75
76
max_block_size_of_fragments_so_far : Length ,
76
77
positioning_context : Option < PositioningContext > ,
78
+ white_space : WhiteSpace ,
77
79
/// Indicates whether this nesting level have text decorations in effect.
78
80
/// From https://drafts.csswg.org/css-text-decor/#line-decoration
79
81
// "When specified on or propagated to a block container that establishes
@@ -125,6 +127,34 @@ impl<'box_tree, 'a, 'b> InlineFormattingContextState<'box_tree, 'a, 'b> {
125
127
126
128
self . positioning_context . push ( hoisted_box) ;
127
129
}
130
+
131
+ /// Finish layout of all the partial inline boxes in the current line,
132
+ /// finish current line and start a new one.
133
+ fn finish_line_and_reset ( & mut self , layout_context : & LayoutContext ) {
134
+ self . current_nesting_level . inline_start = Length :: zero ( ) ;
135
+ let mut nesting_level = & mut self . current_nesting_level ;
136
+ for partial in self . partial_inline_boxes_stack . iter_mut ( ) . rev ( ) {
137
+ partial. finish_layout (
138
+ layout_context,
139
+ nesting_level,
140
+ & mut self . inline_position ,
141
+ true ,
142
+ ) ;
143
+ partial. start_corner . inline = Length :: zero ( ) ;
144
+ partial. padding . inline_start = Length :: zero ( ) ;
145
+ partial. border . inline_start = Length :: zero ( ) ;
146
+ partial. margin . inline_start = Length :: zero ( ) ;
147
+ partial. parent_nesting_level . inline_start = Length :: zero ( ) ;
148
+ nesting_level = & mut partial. parent_nesting_level ;
149
+ }
150
+ self . lines . finish_line (
151
+ nesting_level,
152
+ self . containing_block ,
153
+ self . sequential_layout_state . as_mut ( ) . map ( |c| & mut * * c) ,
154
+ self . inline_position ,
155
+ ) ;
156
+ self . inline_position = Length :: zero ( ) ;
157
+ }
128
158
}
129
159
130
160
struct Lines {
@@ -297,6 +327,7 @@ impl InlineFormattingContext {
297
327
inline_start : Length :: zero ( ) ,
298
328
max_block_size_of_fragments_so_far : Length :: zero ( ) ,
299
329
positioning_context : None ,
330
+ white_space : containing_block. style . clone_inherited_text ( ) . white_space ,
300
331
text_decoration_line : self . text_decoration_line ,
301
332
} ,
302
333
sequential_layout_state,
@@ -503,6 +534,7 @@ impl InlineBox {
503
534
start_corner += & relative_adjustement ( & style, ifc. containing_block )
504
535
}
505
536
let positioning_context = PositioningContext :: new_for_style ( & style) ;
537
+ let white_space = style. clone_inherited_text ( ) . white_space ;
506
538
let text_decoration_line =
507
539
ifc. current_nesting_level . text_decoration_line | style. clone_text_decoration_line ( ) ;
508
540
PartialInlineBoxFragment {
@@ -523,6 +555,7 @@ impl InlineBox {
523
555
inline_start : ifc. inline_position ,
524
556
max_block_size_of_fragments_so_far : Length :: zero ( ) ,
525
557
positioning_context,
558
+ white_space,
526
559
text_decoration_line : text_decoration_line,
527
560
} ,
528
561
) ,
@@ -590,16 +623,12 @@ fn layout_atomic(
590
623
let pbm = style. padding_border_margin ( & ifc. containing_block ) ;
591
624
let margin = pbm. margin . auto_is ( Length :: zero) ;
592
625
let pbm_sums = & ( & pbm. padding + & pbm. border ) + & margin;
593
- ifc. inline_position += pbm_sums. inline_start ;
594
- let mut start_corner = Vec2 {
595
- block : pbm_sums. block_start ,
596
- inline : ifc. inline_position - ifc. current_nesting_level . inline_start ,
597
- } ;
598
- if style. clone_position ( ) . is_relative ( ) {
599
- start_corner += & relative_adjustement ( & style, ifc. containing_block )
600
- }
626
+ let position = style. clone_position ( ) ;
601
627
602
- let fragment = match atomic {
628
+ let mut child_positioning_context = None ;
629
+
630
+ // We need to know the inline size of the atomic before deciding whether to do the line break.
631
+ let mut fragment = match atomic {
603
632
IndependentFormattingContext :: Replaced ( replaced) => {
604
633
let size = replaced. contents . used_size_as_if_inline_element (
605
634
ifc. containing_block ,
@@ -610,7 +639,10 @@ fn layout_atomic(
610
639
let fragments = replaced
611
640
. contents
612
641
. make_fragments ( & replaced. style , size. clone ( ) ) ;
613
- let content_rect = Rect { start_corner, size } ;
642
+ let content_rect = Rect {
643
+ start_corner : Vec2 :: zero ( ) ,
644
+ size,
645
+ } ;
614
646
BoxFragment :: new (
615
647
replaced. base_fragment_info ,
616
648
replaced. style . clone ( ) ,
@@ -663,16 +695,14 @@ fn layout_atomic(
663
695
let collects_for_nearest_positioned_ancestor = ifc
664
696
. positioning_context
665
697
. collects_for_nearest_positioned_ancestor ( ) ;
666
- let mut child_positioning_context =
667
- PositioningContext :: new_for_subtree ( collects_for_nearest_positioned_ancestor) ;
698
+ child_positioning_context = Some ( PositioningContext :: new_for_subtree (
699
+ collects_for_nearest_positioned_ancestor,
700
+ ) ) ;
668
701
let independent_layout = non_replaced. layout (
669
702
layout_context,
670
- & mut child_positioning_context,
703
+ child_positioning_context. as_mut ( ) . unwrap ( ) ,
671
704
& containing_block_for_children,
672
705
) ;
673
- child_positioning_context
674
- . adjust_static_position_of_hoisted_fragments_with_offset ( & start_corner) ;
675
- ifc. positioning_context . append ( child_positioning_context) ;
676
706
677
707
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
678
708
let tentative_block_size = box_size
@@ -686,7 +716,7 @@ fn layout_atomic(
686
716
. clamp_between_extremums ( min_box_size. block , max_box_size. block ) ;
687
717
688
718
let content_rect = Rect {
689
- start_corner,
719
+ start_corner : Vec2 :: zero ( ) ,
690
720
size : Vec2 {
691
721
block : block_size,
692
722
inline : inline_size,
@@ -707,6 +737,31 @@ fn layout_atomic(
707
737
} ,
708
738
} ;
709
739
740
+ if fragment. content_rect . size . inline + pbm_sums. inline_sum ( ) >
741
+ ifc. containing_block . inline_size - ifc. inline_position &&
742
+ ifc. current_nesting_level . white_space . allow_wrap ( ) &&
743
+ ifc. current_nesting_level . fragments_so_far . len ( ) != 0
744
+ {
745
+ ifc. finish_line_and_reset ( layout_context) ;
746
+ }
747
+
748
+ ifc. inline_position += pbm_sums. inline_start ;
749
+ let mut start_corner = Vec2 {
750
+ block : pbm_sums. block_start ,
751
+ inline : ifc. inline_position - ifc. current_nesting_level . inline_start ,
752
+ } ;
753
+ if position. is_relative ( ) {
754
+ start_corner += & relative_adjustement ( atomic. style ( ) , ifc. containing_block )
755
+ }
756
+
757
+ if let Some ( mut child_positioning_context) = child_positioning_context. take ( ) {
758
+ child_positioning_context
759
+ . adjust_static_position_of_hoisted_fragments_with_offset ( & start_corner) ;
760
+ ifc. positioning_context . append ( child_positioning_context) ;
761
+ }
762
+
763
+ fragment. content_rect . start_corner = start_corner;
764
+
710
765
ifc. inline_position += pbm_sums. inline_end + fragment. content_rect . size . inline ;
711
766
ifc. current_nesting_level
712
767
. max_block_size_of_fragments_so_far
@@ -888,30 +943,7 @@ impl TextRun {
888
943
if runs. as_slice ( ) . is_empty ( ) && !force_line_break {
889
944
break ;
890
945
} else {
891
- // New line
892
- ifc. current_nesting_level . inline_start = Length :: zero ( ) ;
893
- let mut nesting_level = & mut ifc. current_nesting_level ;
894
- for partial in ifc. partial_inline_boxes_stack . iter_mut ( ) . rev ( ) {
895
- partial. finish_layout (
896
- layout_context,
897
- nesting_level,
898
- & mut ifc. inline_position ,
899
- true ,
900
- ) ;
901
- partial. start_corner . inline = Length :: zero ( ) ;
902
- partial. padding . inline_start = Length :: zero ( ) ;
903
- partial. border . inline_start = Length :: zero ( ) ;
904
- partial. margin . inline_start = Length :: zero ( ) ;
905
- partial. parent_nesting_level . inline_start = Length :: zero ( ) ;
906
- nesting_level = & mut partial. parent_nesting_level ;
907
- }
908
- ifc. lines . finish_line (
909
- nesting_level,
910
- ifc. containing_block ,
911
- ifc. sequential_layout_state . as_mut ( ) . map ( |c| & mut * * c) ,
912
- ifc. inline_position ,
913
- ) ;
914
- ifc. inline_position = Length :: zero ( ) ;
946
+ ifc. finish_line_and_reset ( layout_context) ;
915
947
}
916
948
}
917
949
}
0 commit comments