2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2020 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  All  rights  reserved . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Redistribution  and  use  in  source  and  binary  forms ,  with  or  without 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  modification ,  are  permitted  provided  that  the  following  conditions  are  met : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  1.  Redistributions  of  source  code  must  retain  the  above  copyright  notice ,  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     list  of  conditions  and  the  following  disclaimer . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  2.  Redistributions  in  binary  form  must  reproduce  the  above  copyright  notice , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     this  list  of  conditions  and  the  following  disclaimer  in  the  documentation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     and / or  other  materials  provided  with  the  distribution . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  THIS  SOFTWARE  IS  PROVIDED  BY  THE  COPYRIGHT  HOLDERS  AND  CONTRIBUTORS  " AS IS " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES ,  INCLUDING ,  BUT  NOT  LIMITED  TO ,  THE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  IMPLIED  WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR  PURPOSE  ARE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  DISCLAIMED .  IN  NO  EVENT  SHALL  THE  COPYRIGHT  HOLDER  OR  CONTRIBUTORS  BE  LIABLE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  FOR  ANY  DIRECT ,  INDIRECT ,  INCIDENTAL ,  SPECIAL ,  EXEMPLARY ,  OR  CONSEQUENTIAL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  DAMAGES  ( INCLUDING ,  BUT  NOT  LIMITED  TO ,  PROCUREMENT  OF  SUBSTITUTE  GOODS  OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SERVICES ;  LOSS  OF  USE ,  DATA ,  OR  PROFITS ;  OR  BUSINESS  INTERRUPTION )  HOWEVER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY ,  WHETHER  IN  CONTRACT ,  STRICT  LIABILITY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  OR  TORT  ( INCLUDING  NEGLIGENCE  OR  OTHERWISE )  ARISING  IN  ANY  WAY  OUT  OF  THE  USE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  OF  THIS  SOFTWARE ,  EVEN  IF  ADVISED  OF  THE  POSSIBILITY  OF  SUCH  DAMAGE . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-06 20:33:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibGUI/Painter.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleResolver.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/Element.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Dump.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/LayoutBlock.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-12 14:19:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/LayoutDocument.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/LayoutInline.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/LayoutReplaced.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/LayoutText.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-05 19:13:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/LayoutWidget.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <math.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  Web  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-07 09:23:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								LayoutBlock : : LayoutBlock ( const  Node *  node ,  NonnullRefPtr < StyleProperties >  style )  
						 
					
						
							
								
									
										
										
										
											2019-10-15 16:48:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :  LayoutBox ( node ,  move ( style ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								LayoutBlock : : ~ LayoutBlock ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-06-20 23:00:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-08 17:42:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								LayoutNode &  LayoutBlock : : inline_wrapper ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-09-25 11:56:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! last_child ( )  | |  ! last_child ( ) - > is_block ( )  | |  last_child ( ) - > node ( )  ! =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-05 23:47:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        append_child ( adopt ( * new  LayoutBlock ( nullptr ,  style_for_anonymous_block ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 23:32:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        last_child ( ) - > set_children_are_inline ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-08 17:42:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  * last_child ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : layout ( LayoutMode  layout_mode )  
						 
					
						
							
								
									
										
										
										
											2019-06-20 23:00:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-07-01 07:28:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    compute_width ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    layout_inside ( layout_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    compute_height ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    layout_absolutely_positioned_descendants ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : layout_absolutely_positioned_descendant ( LayoutBox &  box )  
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    box . layout ( LayoutMode : : Default ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  box_model  =  box . box_model ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  style  =  box . style ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  zero_value  =  Length ( 0 ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  specified_width  =  style . length_or_fallback ( CSS : : PropertyID : : Width ,  Length ( ) ,  width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    box_model . margin ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : MarginTop ,  { } ,  height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model . margin ( ) . right  =  style . length_or_fallback ( CSS : : PropertyID : : MarginRight ,  { } ,  width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model . margin ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : MarginBottom ,  { } ,  height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model . margin ( ) . left  =  style . length_or_fallback ( CSS : : PropertyID : : MarginLeft ,  { } ,  width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    box_model . offset ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : Top ,  { } ,  height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model . offset ( ) . right  =  style . length_or_fallback ( CSS : : PropertyID : : Right ,  { } ,  width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model . offset ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : Bottom ,  { } ,  height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model . offset ( ) . left  =  style . length_or_fallback ( CSS : : PropertyID : : Left ,  { } ,  width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( box_model . offset ( ) . left . is_auto ( )  & &  specified_width . is_auto ( )  & &  box_model . offset ( ) . right . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( box_model . margin ( ) . left . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            box_model . margin ( ) . left  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( box_model . margin ( ) . right . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            box_model . margin ( ) . right  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Gfx : : FloatPoint  used_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  x_offset  =  box_model . offset ( ) . left . to_px ( box ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  box_model . border_box ( box ) . left 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -  box_model . offset ( ) . right . to_px ( box ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -  box_model . border_box ( box ) . right ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  y_offset  =  box_model . offset ( ) . top . to_px ( box ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  box_model . border_box ( box ) . top 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -  box_model . offset ( ) . bottom . to_px ( box ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -  box_model . border_box ( box ) . bottom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! box_model . offset ( ) . left . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        used_offset . set_x ( x_offset  +  box_model . margin ( ) . left . to_px ( box ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( ! box_model . offset ( ) . right . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        used_offset . set_x ( width ( )  +  x_offset  -  box . width ( )  -  box_model . margin ( ) . right . to_px ( box ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! box_model . offset ( ) . top . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        used_offset . set_y ( y_offset  +  box_model . margin ( ) . top . to_px ( box ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( ! box_model . offset ( ) . bottom . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        used_offset . set_y ( height ( )  +  y_offset  -  box . height ( )  -  box_model . margin ( ) . bottom . to_px ( box ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box . set_offset ( used_offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : layout_inside ( LayoutMode  layout_mode )  
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( children_are_inline ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_inline_children ( layout_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        layout_contained_boxes ( layout_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : layout_absolutely_positioned_descendants ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_subtree_of_type < LayoutBox > ( [ & ] ( auto &  box )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( box . is_absolutely_positioned ( )  & &  box . containing_block ( )  = =  this )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            layout_absolutely_positioned_descendant ( box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  LayoutBlock : : layout_contained_boxes ( LayoutMode  layout_mode )  
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-11-18 16:25:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  content_height  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  content_width  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_subtree_of_type < LayoutBox > ( [ & ] ( auto &  box )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( box . is_absolutely_positioned ( )  | |  box . containing_block ( )  ! =  this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        box . layout ( layout_mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( box . is_replaced ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            place_block_level_replaced_element_in_normal_flow ( to < LayoutReplaced > ( box ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( box . is_block ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            place_block_level_non_replaced_element_in_normal_flow ( to < LayoutBlock > ( box ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-14 22:07:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbg ( )  < <  " FIXME: LayoutBlock::layout_contained_boxes doesn't know how to place a  "  < <  box . class_name ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        content_height  =  max ( content_height ,  box . effective_offset ( ) . y ( )  +  box . height ( )  +  box . box_model ( ) . margin_box ( * this ) . bottom ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        content_width  =  max ( content_width ,  to < LayoutBox > ( box ) . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-18 08:37:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( layout_mode  ! =  LayoutMode : : Default ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_width ( content_width ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_height ( content_height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-06-20 23:00:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : layout_inline_children ( LayoutMode  layout_mode )  
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASSERT ( children_are_inline ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_line_boxes . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_child ( [ & ] ( auto &  child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ASSERT ( child . is_inline ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( child . is_absolutely_positioned ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 15:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        child . split_into_lines ( * this ,  layout_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 17:18:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  line_box  :  m_line_boxes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_box . trim_trailing_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 10:54:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  text_align  =  style ( ) . text_align ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  min_line_height  =  style ( ) . line_height ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-25 18:12:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  line_spacing  =  min_line_height  -  style ( ) . font ( ) . glyph_height ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 16:25:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  content_height  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  max_linebox_width  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  line_box  :  m_line_boxes )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 16:25:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  max_height  =  min_line_height ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  fragment  :  line_box . fragments ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            max_height  =  max ( max_height ,  fragment . height ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 20:32:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  x_offset  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 17:18:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  excess_horizontal_space  =  ( float ) width ( )  -  line_box . width ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 20:32:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( text_align )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : ValueID : : Center : 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 10:54:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  CSS : : ValueID : : VendorSpecificCenter : 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            x_offset  + =  excess_horizontal_space  /  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 20:32:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : ValueID : : Right : 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            x_offset  + =  excess_horizontal_space ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 20:32:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : ValueID : : Left : 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  CSS : : ValueID : : Justify : 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 20:32:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 17:18:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  excess_horizontal_space_including_whitespace  =  excess_horizontal_space ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        int  whitespace_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( text_align  = =  CSS : : ValueID : : Justify )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  fragment  :  line_box . fragments ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( fragment . is_justifiable_whitespace ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    + + whitespace_count ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    excess_horizontal_space_including_whitespace  + =  fragment . width ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 17:18:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  justified_space_width  =  whitespace_count  ?  ( excess_horizontal_space_including_whitespace  /  ( float ) whitespace_count )  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 14:49:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  line_box . fragments ( ) . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  fragment  =  line_box . fragments ( ) [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-05 19:13:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Vertically align everyone's bottom to the line.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: Support other kinds of vertical alignment.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fragment . set_offset ( {  roundf ( x_offset  +  fragment . offset ( ) . x ( ) ) ,  content_height  +  ( max_height  -  fragment . height ( ) )  -  ( line_spacing  /  2 )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-05 23:20:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( text_align  = =  CSS : : ValueID : : Justify )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( fragment . is_justifiable_whitespace ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( fragment . width ( )  ! =  justified_space_width )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        float  diff  =  justified_space_width  -  fragment . width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        fragment . set_width ( justified_space_width ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        // Shift subsequent sibling fragments to the right to adjust for change in width.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 14:49:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        for  ( size_t  j  =  i  +  1 ;  j  <  line_box . fragments ( ) . size ( ) ;  + + j )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            auto  offset  =  line_box . fragments ( ) [ j ] . offset ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            offset . move_by ( diff ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            line_box . fragments ( ) [ j ] . set_offset ( offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 12:30:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 16:06:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( fragment . layout_node ( ) . is_inline_block ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  inline_block  =  const_cast < LayoutBlock & > ( to < LayoutBlock > ( fragment . layout_node ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                inline_block . set_size ( fragment . size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                inline_block . layout ( layout_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 16:06:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 17:18:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            float  final_line_box_width  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  fragment  :  line_box . fragments ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                final_line_box_width  + =  fragment . width ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-20 17:18:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            line_box . m_width  =  final_line_box_width ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            max_linebox_width  =  max ( max_linebox_width ,  final_line_box_width ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        content_height  + =  max_height ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( layout_mode  ! =  LayoutMode : : Default )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        set_width ( max_linebox_width ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_height ( content_height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-01 07:28:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-18 18:28:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : compute_width_for_absolutely_positioned_block ( )  
						 
					
						
							
								
									
										
										
										
											2019-07-01 07:28:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-07 09:23:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  style  =  this - > style ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-18 18:28:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  containing_block  =  * this - > containing_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  zero_value  =  Length ( 0 ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  margin_left  =  style . length_or_fallback ( CSS : : PropertyID : : MarginLeft ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  margin_right  =  style . length_or_fallback ( CSS : : PropertyID : : MarginRight ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  border_left  =  style . length_or_fallback ( CSS : : PropertyID : : BorderLeftWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  border_right  =  style . length_or_fallback ( CSS : : PropertyID : : BorderRightWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  padding_left  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingLeft ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  padding_right  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingRight ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  left  =  style . length_or_fallback ( CSS : : PropertyID : : Left ,  { } ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  right  =  style . length_or_fallback ( CSS : : PropertyID : : Right ,  { } ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  width  =  style . length_or_fallback ( CSS : : PropertyID : : Width ,  { } ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  solve_for_left  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        left  =  Length ( containing_block . width ( )  -  margin_left . to_px ( * this )  -  border_left . to_px ( * this )  -  padding_left . to_px ( * this )  -  width . to_px ( * this )  -  padding_right . to_px ( * this )  -  border_right . to_px ( * this )  -  margin_right . to_px ( * this )  -  right . to_px ( * this ) ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  solve_for_width  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        width  =  Length ( containing_block . width ( )  -  left . to_px ( * this )  -  margin_left . to_px ( * this )  -  border_left . to_px ( * this )  -  padding_left . to_px ( * this )  -  padding_right . to_px ( * this )  -  border_right . to_px ( * this )  -  margin_right . to_px ( * this )  -  right . to_px ( * this ) ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  solve_for_right  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        left  =  Length ( containing_block . width ( )  -  left . to_px ( * this )  -  margin_left . to_px ( * this )  -  border_left . to_px ( * this )  -  padding_left . to_px ( * this )  -  width . to_px ( * this )  -  padding_right . to_px ( * this )  -  border_right . to_px ( * this )  -  margin_right . to_px ( * this ) ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto',
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    then the width is shrink-to-fit. Then solve for 'left'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( left . is_auto ( )  & &  width . is_auto ( )  & &  ! right . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        width  =  Length ( calculate_shrink_to_fit_width ( margin_left ,  border_left ,  padding_left ,  padding_right ,  border_right ,  margin_right ) ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        solve_for_left ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-24 07:34:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-18 18:28:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto',
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    then if the 'direction' property of the element establishing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    the static-position containing block is 'ltr' set 'left'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    to the static position, otherwise set 'right' to the static position.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( left . is_auto ( )  & &  right . is_auto ( )  & &  ! width . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Check direction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Use the static-position containing block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        left  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        solve_for_right ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto',
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    then the width is shrink-to-fit. Then solve for 'right'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( width . is_auto ( )  & &  right . is_auto ( )  & &  ! left . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        width  =  Length ( calculate_shrink_to_fit_width ( margin_left ,  border_left ,  padding_left ,  padding_right ,  border_right ,  margin_right ) ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        solve_for_right ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( left . is_auto ( )  & &  ! width . is_auto ( )  & &  ! right . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        solve_for_left ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( width . is_auto ( )  & &  ! left . is_auto ( )  & &  ! right . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        solve_for_width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( right . is_auto ( )  & &  ! left . is_auto ( )  & &  ! width . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        solve_for_right ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_width ( width . to_px ( * this ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  LayoutBlock : : compute_width ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_absolutely_positioned ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  compute_width_for_absolutely_positioned_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  style  =  this - > style ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-18 08:09:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  auto_value  =  Length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  zero_value  =  Length ( 0 ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-24 07:34:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Length  margin_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Length  margin_right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Length  border_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Length  border_right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Length  padding_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Length  padding_right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  containing_block  =  * this - > containing_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  try_compute_width  =  [ & ] ( const  auto &  a_width )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Length  width  =  a_width ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:42:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef HTML_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dbg ( )  < <  "  Left:  "  < <  margin_left  < <  " + "  < <  border_left  < <  " + "  < <  padding_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbg ( )  < <  " Right:  "  < <  margin_right  < <  " + "  < <  border_right  < <  " + "  < <  padding_right ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:42:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2020-05-11 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        margin_left  =  style . length_or_fallback ( CSS : : PropertyID : : MarginLeft ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        margin_right  =  style . length_or_fallback ( CSS : : PropertyID : : MarginRight ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        border_left  =  style . length_or_fallback ( CSS : : PropertyID : : BorderLeftWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        border_right  =  style . length_or_fallback ( CSS : : PropertyID : : BorderRightWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        padding_left  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingLeft ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        padding_right  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingRight ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 16:25:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  total_px  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  value  :  {  margin_left ,  border_left ,  padding_left ,  width ,  padding_right ,  border_right ,  margin_right  } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            total_px  + =  value . to_px ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-26 08:05:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:42:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef HTML_DEBUG 
  
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dbg ( )  < <  " Total:  "  < <  total_px ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:42:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2019-07-26 08:05:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is_replaced ( )  & &  ! is_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 10.3.3 Block-level, non-replaced elements in normal flow
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // If 'width' is not 'auto' and 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' (plus any of 'margin-left' or 'margin-right' that are not 'auto') is larger than the width of the containing block, then any 'auto' values for 'margin-left' or 'margin-right' are, for the following rules, treated as zero.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( width . is_auto ( )  & &  total_px  >  containing_block . width ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( margin_left . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    margin_left  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( margin_right . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    margin_right  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-18 08:09:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // 10.3.3 cont'd.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  underflow_px  =  containing_block . width ( )  -  total_px ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( width . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( margin_left . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    margin_left  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( margin_right . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    margin_right  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( underflow_px  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    width  =  Length ( underflow_px ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    width  =  zero_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    margin_right  =  Length ( margin_right . to_px ( * this )  +  underflow_px ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! margin_left . is_auto ( )  & &  ! margin_right . is_auto ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    margin_right  =  Length ( margin_right . to_px ( * this )  +  underflow_px ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  if  ( ! margin_left . is_auto ( )  & &  margin_right . is_auto ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    margin_right  =  Length ( underflow_px ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  if  ( margin_left . is_auto ( )  & &  ! margin_right . is_auto ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    margin_left  =  Length ( underflow_px ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  {  // margin_left.is_auto() && margin_right.is_auto()
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto  half_of_the_underflow  =  Length ( underflow_px  /  2 ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    margin_left  =  half_of_the_underflow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    margin_right  =  half_of_the_underflow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ! is_replaced ( )  & &  is_inline_block ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 10.3.9 'Inline-block', non-replaced elements in normal flow
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( margin_left . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                margin_left  =  zero_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( margin_right . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                margin_right  =  zero_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // If 'width' is 'auto', the used value is the shrink-to-fit width as for floating elements.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-18 18:28:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( width . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                width  =  Length ( calculate_shrink_to_fit_width ( margin_left ,  border_left ,  padding_left ,  padding_right ,  border_right ,  margin_right ) ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 21:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  specified_width  =  style . length_or_fallback ( CSS : : PropertyID : : Width ,  auto_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. The tentative used width is calculated (without 'min-width' and 'max-width')
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  used_width  =  try_compute_width ( specified_width ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. The tentative used width is greater than 'max-width', the rules above are applied again,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    but this time using the computed value of 'max-width' as the computed value for 'width'.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  specified_max_width  =  style . length_or_fallback ( CSS : : PropertyID : : MaxWidth ,  auto_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! specified_max_width . is_auto ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( used_width . to_px ( * this )  >  specified_max_width . to_px ( * this ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            used_width  =  try_compute_width ( specified_max_width ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-18 08:09:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. If the resulting width is smaller than 'min-width', the rules above are applied again,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    but this time using the value of 'min-width' as the computed value for 'width'.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  specified_min_width  =  style . length_or_fallback ( CSS : : PropertyID : : MinWidth ,  auto_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! specified_min_width . is_auto ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( used_width . to_px ( * this )  <  specified_min_width . to_px ( * this ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 12:21:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            used_width  =  try_compute_width ( specified_min_width ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-18 08:09:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_width ( used_width . to_px ( * this ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-04 15:50:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    box_model ( ) . margin ( ) . left  =  margin_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model ( ) . margin ( ) . right  =  margin_right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model ( ) . border ( ) . left  =  border_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model ( ) . border ( ) . right  =  border_right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model ( ) . padding ( ) . left  =  padding_left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box_model ( ) . padding ( ) . right  =  padding_right ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-01 07:28:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : place_block_level_replaced_element_in_normal_flow ( LayoutReplaced &  box )  
						 
					
						
							
								
									
										
										
										
											2019-08-18 08:37:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ASSERT ( ! is_absolutely_positioned ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  style  =  box . style ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 17:55:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  zero_value  =  Length ( 0 ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  containing_block  =  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  replaced_element_box_model  =  box . box_model ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    replaced_element_box_model . margin ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : MarginTop ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    replaced_element_box_model . margin ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : MarginBottom ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    replaced_element_box_model . border ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : BorderTopWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    replaced_element_box_model . border ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : BorderBottomWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    replaced_element_box_model . padding ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingTop ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    replaced_element_box_model . padding ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingBottom ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  x  =  replaced_element_box_model . margin ( ) . left . to_px ( * this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  replaced_element_box_model . border ( ) . left . to_px ( * this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  replaced_element_box_model . padding ( ) . left . to_px ( * this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  replaced_element_box_model . offset ( ) . left . to_px ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  y  =  replaced_element_box_model . margin_box ( * this ) . top  +  box_model ( ) . offset ( ) . top . to_px ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    box . set_offset ( x ,  y ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-18 18:28:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								float  LayoutBlock : : calculate_shrink_to_fit_width ( const  Length &  margin_left ,  const  Length &  border_left ,  const  Length &  padding_left ,  const  Length &  padding_right ,  const  Length &  border_right ,  const  Length &  margin_right )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  greatest_child_width  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        float  max_width  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( children_are_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  box  :  line_boxes ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                max_width  =  max ( max_width ,  box . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for_each_child ( [ & ] ( auto &  child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( child . is_box ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    max_width  =  max ( max_width ,  to < LayoutBox > ( child ) . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  max_width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Find the available width: in this case, this is the width of the containing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // block minus the used values of 'margin-left', 'border-left-width', 'padding-left',
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  available_width  =  containing_block ( ) - > width ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -  margin_left . to_px ( * this )  -  border_left . to_px ( * this )  -  padding_left . to_px ( * this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -  padding_right . to_px ( * this )  -  border_right . to_px ( * this )  -  margin_right . to_px ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Calculate the preferred width by formatting the content without breaking lines
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // other than where explicit line breaks occur.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    layout_inside ( LayoutMode : : OnlyRequiredLineBreaks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  preferred_width  =  greatest_child_width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Also calculate the preferred minimum width, e.g., by trying all possible line breaks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // CSS 2.2 does not define the exact algorithm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    layout_inside ( LayoutMode : : AllPossibleLineBreaks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  preferred_minimum_width  =  greatest_child_width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  min ( max ( preferred_minimum_width ,  available_width ) ,  preferred_width ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : place_block_level_non_replaced_element_in_normal_flow ( LayoutBlock &  block )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  style  =  block . style ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  zero_value  =  Length ( 0 ,  Length : : Type : : Px ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  containing_block  =  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  box  =  block . box_model ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box . margin ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : MarginTop ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box . margin ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : MarginBottom ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box . border ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : BorderTopWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box . border ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : BorderBottomWidth ,  zero_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box . padding ( ) . top  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingTop ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    box . padding ( ) . bottom  =  style . length_or_fallback ( CSS : : PropertyID : : PaddingBottom ,  zero_value ,  containing_block . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  x  =  box . margin ( ) . left . to_px ( * this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  box . border ( ) . left . to_px ( * this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  box . padding ( ) . left . to_px ( * this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  box . offset ( ) . left . to_px ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( this - > style ( ) . text_align ( )  = =  CSS : : ValueID : : VendorSpecificCenter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        x  =  ( containing_block . width ( )  /  2 )  -  block . width ( )  /  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 10:54:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  y  =  box . margin_box ( * this ) . top 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        +  box . offset ( ) . top . to_px ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  relevant_sibling  =  block . previous_sibling ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( relevant_sibling  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( relevant_sibling - > style ( ) . position ( )  ! =  CSS : : Position : : Absolute ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        relevant_sibling  =  relevant_sibling - > previous_sibling ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 13:27:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( relevant_sibling )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  sibling_box  =  relevant_sibling - > box_model ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        y  + =  relevant_sibling - > effective_offset ( ) . y ( )  +  relevant_sibling - > height ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 17:41:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Collapse top margin with bottom margin of previous sibling if necessary
 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  previous_sibling_margin_bottom  =  sibling_box . margin ( ) . bottom . to_px ( * relevant_sibling ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        float  my_margin_top  =  box . margin ( ) . top . to_px ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 18:09:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( my_margin_top  <  0  | |  previous_sibling_margin_bottom  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Negative margins present.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            float  largest_negative_margin  =  - min ( my_margin_top ,  previous_sibling_margin_bottom ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            float  largest_positive_margin  =  ( my_margin_top  <  0  & &  previous_sibling_margin_bottom  <  0 )  ?  0  :  max ( my_margin_top ,  previous_sibling_margin_bottom ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            float  final_margin  =  largest_positive_margin  -  largest_negative_margin ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            y  + =  final_margin  -  my_margin_top ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 18:09:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( previous_sibling_margin_bottom  >  my_margin_top )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 17:41:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Sibling's margin is larger than mine, adjust so we use sibling's.
 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            y  + =  previous_sibling_margin_bottom  -  my_margin_top ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-12 17:41:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:28:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):
1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants
However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:
1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants
Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.
Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.
This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
											 
										 
										
											2020-06-14 18:48:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    block . set_offset ( x ,  y ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-18 08:37:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-01 07:28:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : compute_height ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-07 09:23:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  style  =  this - > style ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 15:28:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  specified_height  =  style . length_or_fallback ( CSS : : PropertyID : : Height ,  Length ( ) ,  containing_block ( ) - > height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  specified_max_height  =  style . length_or_fallback ( CSS : : PropertyID : : MaxHeight ,  Length ( ) ,  containing_block ( ) - > height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! specified_height . is_auto ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        float  used_height  =  specified_height . to_px ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! specified_max_height . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            used_height  =  min ( used_height ,  specified_max_height . to_px ( * this ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_height ( used_height ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-20 23:00:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:40:37 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  LayoutBlock : : render ( RenderingContext &  context )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-09 21:25:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! is_visible ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 19:12:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    LayoutBox : : render ( context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:40:37 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( children_are_inline ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  line_box  :  m_line_boxes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  fragment  :  line_box . fragments ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-12 15:02:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( context . should_show_line_box_borders ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    context . painter ( ) . draw_rect ( enclosing_int_rect ( fragment . absolute_rect ( ) ) ,  Color : : Green ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                fragment . render ( context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:57:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								HitTestResult  LayoutBlock : : hit_test ( const  Gfx : : IntPoint &  position )  const  
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! children_are_inline ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 22:02:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  LayoutBox : : hit_test ( position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HitTestResult  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  line_box  :  m_line_boxes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  fragment  :  line_box . fragments ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( enclosing_int_rect ( fragment . absolute_rect ( ) ) . contains ( position ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 21:06:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( fragment . layout_node ( ) . is_block ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  to < LayoutBlock > ( fragment . layout_node ( ) ) . hit_test ( position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-05 22:13:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  {  fragment . layout_node ( ) ,  fragment . text_index_at ( position . x ( ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 12:41:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: This should be smarter about the text position if we're hitting a block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        that has text inside it, but `position` is to the right of the text box.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 10:42:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  {  absolute_rect ( ) . contains ( position . x ( ) ,  position . y ( ) )  ?  this  :  nullptr  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:40:37 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-10-05 23:47:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullRefPtr < StyleProperties >  LayoutBlock : : style_for_anonymous_block ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  new_style  =  StyleProperties : : create ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 15:34:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    style ( ) . for_each_property ( [ & ] ( auto  property_id ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( StyleResolver : : is_inherited_property ( property_id ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            new_style - > set_property ( property_id ,  value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-05 23:47:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  new_style ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-10-13 17:24:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								LineBox &  LayoutBlock : : ensure_last_line_box ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_line_boxes . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_line_boxes . append ( LineBox ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  m_line_boxes . last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								LineBox &  LayoutBlock : : add_line_box ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_line_boxes . append ( LineBox ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  m_line_boxes . last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LayoutBlock : : split_into_lines ( LayoutBlock &  container ,  LayoutMode  layout_mode )  
						 
					
						
							
								
									
										
										
										
											2020-05-05 16:06:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-27 19:20:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    layout ( layout_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 16:06:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  line_box  =  & container . ensure_last_line_box ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( line_box - > width ( )  >  0  & &  line_box - > width ( )  +  width ( )  >  container . width ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_box  =  & container . add_line_box ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    line_box - > add_fragment ( * this ,  0 ,  0 ,  width ( ) ,  height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}