2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:39:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020 - 2022 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 15:18:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2022 ,  Sam  Atkins  < atkinssj @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Debug.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ExtraMathConstants.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <AK/QuickSort.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-01-01 16:42:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibGfx/AffineTransform.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibGfx/Matrix4x4.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibGfx/Painter.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibGfx/Rect.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/Box.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-08 11:27:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/InitialContainingBlock.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:39:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/ReplacedBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-10 23:13:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Painting/PaintableBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-18 22:01:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Painting/StackingContext.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 02:13:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  Web : : Painting  {  
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  paint_node ( Layout : : Node  const &  layout_node ,  PaintContext &  context ,  PaintPhase  phase )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-10 15:38:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( auto  const *  paintable  =  layout_node . paintable ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paintable - > paint ( context ,  phase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 02:13:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StackingContext : : StackingContext ( Layout : : Box &  box ,  StackingContext *  parent )  
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    :  m_box ( box ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 15:18:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_transform ( combine_transformations ( m_box . computed_values ( ) . transformations ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-24 20:36:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_transform_origin ( compute_transform_origin ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    ,  m_parent ( parent ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( m_parent  ! =  this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:19:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_parent ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        m_parent - > m_children . append ( this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:19:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:19:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  StackingContext : : sort ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    quick_sort ( m_children ,  [ ] ( auto &  a ,  auto &  b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  a_z_index  =  a - > m_box . computed_values ( ) . z_index ( ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  b_z_index  =  b - > m_box . computed_values ( ) . z_index ( ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( a_z_index  = =  b_z_index ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  a - > m_box . is_before ( b - > m_box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  a_z_index  <  b_z_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  child  :  m_children ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        child - > sort ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:02:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  PaintPhase  to_paint_phase ( StackingContext : : StackingContextPaintPhase  phase )  
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-09-09 14:53:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // There are not a fully correct mapping since some stacking context phases are combined.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:02:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( phase )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  StackingContext : : StackingContextPaintPhase : : Floats : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  StackingContext : : StackingContextPaintPhase : : BackgroundAndBordersForInlineLevelAndReplaced : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  StackingContext : : StackingContextPaintPhase : : BackgroundAndBorders : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  PaintPhase : : Background ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  StackingContext : : StackingContextPaintPhase : : Foreground : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  PaintPhase : : Foreground ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  StackingContext : : StackingContextPaintPhase : : FocusAndOverlay : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  PaintPhase : : Overlay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:02:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:59:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  StackingContext : : paint_descendants ( PaintContext &  context ,  Layout : : Node  const &  box ,  StackingContextPaintPhase  phase )  const  
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:02:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  paintable  =  box . paintable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-12 00:07:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        paintable - > before_children_paint ( context ,  to_paint_phase ( phase ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-01 16:24:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    box . for_each_child ( [ & ] ( auto &  child )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 19:02:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // If `child` establishes its own stacking context, skip over it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < Layout : : Box > ( child )  & &  child . paintable ( )  & &  static_cast < Layout : : Box  const & > ( child ) . paint_box ( ) - > stacking_context ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:16:04 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 23:31:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // If `child` is positioned with a z-index of `0` or `auto`, skip over it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( child . is_positioned ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  const &  z_index  =  child . computed_values ( ) . z_index ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! z_index . has_value ( )  | |  z_index . value ( )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 02:13:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  child_is_inline_or_replaced  =  child . is_inline ( )  | |  is < Layout : : ReplacedBox > ( child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( phase )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  StackingContextPaintPhase : : BackgroundAndBorders : 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:15:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! child_is_inline_or_replaced  & &  ! child . is_floating ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                paint_node ( child ,  context ,  PaintPhase : : Background ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_node ( child ,  context ,  PaintPhase : : Border ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                paint_descendants ( context ,  child ,  phase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  StackingContextPaintPhase : : Floats : 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:15:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( child . is_floating ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_node ( child ,  context ,  PaintPhase : : Background ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_node ( child ,  context ,  PaintPhase : : Border ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_descendants ( context ,  child ,  StackingContextPaintPhase : : BackgroundAndBorders ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:15:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paint_descendants ( context ,  child ,  phase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:39:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  StackingContextPaintPhase : : BackgroundAndBordersForInlineLevelAndReplaced : 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:15:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( child_is_inline_or_replaced )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_node ( child ,  context ,  PaintPhase : : Background ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_node ( child ,  context ,  PaintPhase : : Border ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_descendants ( context ,  child ,  StackingContextPaintPhase : : BackgroundAndBorders ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:39:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:15:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paint_descendants ( context ,  child ,  phase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:39:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  StackingContextPaintPhase : : Foreground : 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:15:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paint_node ( child ,  context ,  PaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            paint_descendants ( context ,  child ,  phase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  StackingContextPaintPhase : : FocusAndOverlay : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( context . has_focus ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                paint_node ( child ,  context ,  PaintPhase : : FocusOutline ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paint_node ( child ,  context ,  PaintPhase : : Overlay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paint_descendants ( context ,  child ,  phase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-01 16:24:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:02:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( auto *  paintable  =  box . paintable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-12 00:07:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        paintable - > after_children_paint ( context ,  to_paint_phase ( phase ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 15:44:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  StackingContext : : paint_internal ( PaintContext &  context )  const  
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // For a more elaborate description of the algorithm, see CSS 2.1 Appendix E
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Draw the background and borders for the context root (steps 1, 2)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    paint_node ( m_box ,  context ,  PaintPhase : : Background ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    paint_node ( m_box ,  context ,  PaintPhase : : Border ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:06:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  paint_child  =  [ & ] ( auto *  child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  parent  =  child - > m_box . parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  paintable  =  parent  ?  parent - > paintable ( )  :  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( paintable ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-12 00:07:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paintable - > before_children_paint ( context ,  PaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:06:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        child - > paint ( context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( paintable ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-12 00:07:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paintable - > after_children_paint ( context ,  PaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:06:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Draw positioned descendants with negative z-indices (step 3)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  child  :  m_children )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( child - > m_box . computed_values ( ) . z_index ( ) . has_value ( )  & &  child - > m_box . computed_values ( ) . z_index ( ) . value ( )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:06:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            paint_child ( child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 11:06:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Draw the background and borders for block-level children (step 4)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    paint_descendants ( context ,  m_box ,  StackingContextPaintPhase : : BackgroundAndBorders ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Draw the non-positioned floats (step 5)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    paint_descendants ( context ,  m_box ,  StackingContextPaintPhase : : Floats ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Draw inline content, replaced content, etc. (steps 6, 7)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:39:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    paint_descendants ( context ,  m_box ,  StackingContextPaintPhase : : BackgroundAndBordersForInlineLevelAndReplaced ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    paint_node ( m_box ,  context ,  PaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    paint_descendants ( context ,  m_box ,  StackingContextPaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:18:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Draw positioned descendants with z-index `0` or `auto` in tree order. (step 8)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 20:56:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: Non-positioned descendants that establish stacking contexts with z-index `0` or `auto` are also painted here.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:18:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: There's more to this step that we have yet to understand and implement.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_box . paint_box ( ) - > for_each_in_subtree_of_type < PaintableBox > ( [ & ] ( PaintableBox  const &  paint_box )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  z_index  =  paint_box . computed_values ( ) . z_index ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto *  child  =  paint_box . stacking_context ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 20:56:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! z_index . has_value ( )  | |  z_index . value ( )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                paint_child ( child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:18:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  TraversalDecision : : SkipChildrenAndContinue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 20:56:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( z_index . has_value ( )  & &  z_index . value ( )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! paint_box . layout_box ( ) . is_positioned ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:18:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // At this point, `paint_box` is a positioned descendant with z-index: auto
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // but no stacking context of its own.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: This is basically duplicating logic found elsewhere in this same function. Find a way to make this more elegant.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-12 17:45:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  parent  =  paint_box . layout_node ( ) . parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  paintable  =  parent  ?  parent - > paintable ( )  :  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( paintable ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            paintable - > before_children_paint ( context ,  PaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:18:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        paint_node ( paint_box . layout_box ( ) ,  context ,  PaintPhase : : Background ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_node ( paint_box . layout_box ( ) ,  context ,  PaintPhase : : Border ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_descendants ( context ,  paint_box . layout_box ( ) ,  StackingContextPaintPhase : : BackgroundAndBorders ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_descendants ( context ,  paint_box . layout_box ( ) ,  StackingContextPaintPhase : : Floats ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_descendants ( context ,  paint_box . layout_box ( ) ,  StackingContextPaintPhase : : BackgroundAndBordersForInlineLevelAndReplaced ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_node ( paint_box . layout_box ( ) ,  context ,  PaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_descendants ( context ,  paint_box . layout_box ( ) ,  StackingContextPaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_node ( paint_box . layout_box ( ) ,  context ,  PaintPhase : : FocusOutline ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_node ( paint_box . layout_box ( ) ,  context ,  PaintPhase : : Overlay ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_descendants ( context ,  paint_box . layout_box ( ) ,  StackingContextPaintPhase : : FocusAndOverlay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-12 17:45:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( paintable ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            paintable - > after_children_paint ( context ,  PaintPhase : : Foreground ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:18:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Draw other positioned descendants (step 9)
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  child  :  m_children )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 18:18:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( child - > m_box . computed_values ( ) . z_index ( ) . has_value ( )  & &  child - > m_box . computed_values ( ) . z_index ( ) . value ( )  > =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            paint_child ( child ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 14:02:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    paint_node ( m_box ,  context ,  PaintPhase : : FocusOutline ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    paint_node ( m_box ,  context ,  PaintPhase : : Overlay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:03:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    paint_descendants ( context ,  m_box ,  StackingContextPaintPhase : : FocusAndOverlay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Gfx : : FloatMatrix4x4  StackingContext : : get_transformation_matrix ( CSS : : Transformation  const &  transformation )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  count  =  transformation . values . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  value  =  [ this ,  transformation ] ( size_t  index ,  Optional < CSS : : Length  const & >  reference_length  =  { } )  - >  float  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  transformation . values [ index ] . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ this ,  reference_length ] ( CSS : : LengthPercentage  const &  value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 02:46:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( reference_length . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 17:29:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  value . resolved ( m_box ,  reference_length . value ( ) ) . to_px ( m_box ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 02:46:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 17:29:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  value . length ( ) . to_px ( m_box ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ ] ( CSS : : Angle  const &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  value . to_degrees ( )  *  static_cast < float > ( M_DEG2RAD ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ ] ( float  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  reference_box  =  paintable ( ) . absolute_rect ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  width  =  CSS : : Length : : make_px ( reference_box . width ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  height  =  CSS : : Length : : make_px ( reference_box . height ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( transformation . function )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : Matrix : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  6 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( value ( 0 ) ,  value ( 2 ) ,  0 ,  value ( 4 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                value ( 1 ) ,  value ( 3 ) ,  0 ,  value ( 5 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 01:57:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : Matrix3d : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( count  = =  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( value ( 0 ) ,  value ( 4 ) ,  value ( 8 ) ,  value ( 12 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                value ( 1 ) ,  value ( 5 ) ,  value ( 9 ) ,  value ( 13 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                value ( 2 ) ,  value ( 6 ) ,  value ( 10 ) ,  value ( 14 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                value ( 3 ) ,  value ( 7 ) ,  value ( 11 ) ,  value ( 15 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : Translate : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( 1 ,  0 ,  0 ,  value ( 0 ,  width ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  1 ,  0 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( 1 ,  0 ,  0 ,  value ( 0 ,  width ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  1 ,  0 ,  value ( 1 ,  height ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 02:46:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : Translate3d : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Gfx : : FloatMatrix4x4 ( 1 ,  0 ,  0 ,  value ( 0 ,  width ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            0 ,  1 ,  0 ,  value ( 1 ,  height ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            0 ,  0 ,  1 ,  value ( 2 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : TranslateX : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( 1 ,  0 ,  0 ,  value ( 0 ,  width ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  1 ,  0 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : TranslateY : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( 1 ,  0 ,  0 ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  1 ,  0 ,  value ( 0 ,  height ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : Scale : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( value ( 0 ) ,  0 ,  0 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  value ( 0 ) ,  0 ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( value ( 0 ) ,  0 ,  0 ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 01:47:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  value ( 1 ) ,  0 ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : ScaleX : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( value ( 0 ) ,  0 ,  0 ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  1 ,  0 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : ScaleY : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 23:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Gfx : : FloatMatrix4x4 ( 1 ,  0 ,  0 ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-14 17:45:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  value ( 0 ) ,  0 ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                0 ,  0 ,  1 ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                0 ,  0 ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 01:57:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : RotateX : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Gfx : : rotation_matrix ( {  1.0f ,  0.0f ,  0.0f  } ,  value ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : RotateY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Gfx : : rotation_matrix ( {  0.0f ,  1.0f ,  0.0f  } ,  value ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-21 14:29:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : Rotate : 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 01:57:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TransformFunction : : RotateZ : 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-21 14:29:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( count  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Gfx : : rotation_matrix ( {  0.0f ,  0.0f ,  1.0f  } ,  value ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 19:02:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dbgln_if ( LIBWEB_CSS_DEBUG ,  " FIXME: Unhandled transformation function {} " ,  CSS : : TransformationStyleValue : : create ( transformation . function ,  { } ) - > to_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  Gfx : : FloatMatrix4x4 : : identity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Gfx : : FloatMatrix4x4  StackingContext : : combine_transformations ( Vector < CSS : : Transformation >  const &  transformations )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  matrix  =  Gfx : : FloatMatrix4x4 : : identity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const &  transform  :  transformations ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        matrix  =  matrix  *  get_transformation_matrix ( transform ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  matrix ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// FIXME: This extracts the affine 2D part of the full transformation matrix.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  Use the whole matrix when we get better transformation support in LibGfx or use LibGL for drawing the bitmap
  
						 
					
						
							
								
									
										
										
										
											2022-07-19 15:18:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Gfx : : AffineTransform  StackingContext : : affine_transform_matrix ( )  const  
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-07-19 15:18:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  m  =  m_transform . elements ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Gfx : : AffineTransform ( m [ 0 ] [ 0 ] ,  m [ 1 ] [ 0 ] ,  m [ 0 ] [ 1 ] ,  m [ 1 ] [ 1 ] ,  m [ 0 ] [ 3 ] ,  m [ 1 ] [ 3 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 15:44:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  StackingContext : : paint ( PaintContext &  context )  const  
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-14 23:49:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Gfx : : PainterStateSaver  saver ( context . painter ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_box . is_fixed_position ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 14:04:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        context . painter ( ) . translate ( - context . painter ( ) . translation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 23:49:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  opacity  =  m_box . computed_values ( ) . opacity ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 15:27:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( opacity  = =  0.0f ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 15:18:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  affine_transform  =  affine_transform_matrix ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-29 01:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( opacity  <  1.0f  | |  ! affine_transform . is_identity_or_translation ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 15:24:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  transform_origin  =  this - > transform_origin ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-31 19:46:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  source_rect  =  paintable ( ) . absolute_paint_rect ( ) . to_type < float > ( ) . translated ( - transform_origin ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 15:24:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  transformed_destination_rect  =  affine_transform . map ( source_rect ) . translated ( transform_origin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  destination_rect  =  transformed_destination_rect . to_rounded < int > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: We should find a way to scale the paintable, rather than paint into a separate bitmap,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // then scale it. This snippet now copies the background at the destination, then scales it down/up
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // to the size of the source (which could add some artefacts, though just scaling the bitmap already does that).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We need to copy the background at the destination because a bunch of our rendering effects now rely on
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // being able to sample the painter (see border radii, shadows, filters, etc).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-31 19:46:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        CSSPixelPoint  destination_clipped_fixup  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 15:24:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  try_get_scaled_destination_bitmap  =  [ & ] ( )  - >  ErrorOr < NonnullRefPtr < Gfx : : Bitmap > >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 00:01:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Gfx : : IntRect  actual_destination_rect ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  bitmap  =  TRY ( context . painter ( ) . get_region_bitmap ( destination_rect ,  Gfx : : BitmapFormat : : BGRA8888 ,  actual_destination_rect ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // get_region_bitmap() may clip to a smaller region if the requested rect goes outside the painter, so we need to account for that.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-31 19:46:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            destination_clipped_fixup  =  CSSPixelPoint  {  destination_rect . location ( )  -  actual_destination_rect . location ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 00:01:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            destination_rect  =  actual_destination_rect ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 15:24:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( source_rect . size ( )  ! =  transformed_destination_rect . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 00:01:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  sx  =  static_cast < float > ( source_rect . width ( ) )  /  transformed_destination_rect . width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  sy  =  static_cast < float > ( source_rect . height ( ) )  /  transformed_destination_rect . height ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bitmap  =  TRY ( bitmap - > scaled ( sx ,  sy ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                destination_clipped_fixup . scale_by ( sx ,  sy ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 15:24:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  bitmap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  bitmap_or_error  =  try_get_scaled_destination_bitmap ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-06 19:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( bitmap_or_error . is_error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-06 19:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  bitmap  =  bitmap_or_error . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Gfx : : Painter  painter ( bitmap ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-31 19:46:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . translate ( context . rounded_device_point ( - paintable ( ) . absolute_paint_rect ( ) . location ( )  +  destination_clipped_fixup ) . to_type < int > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 19:42:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  paint_context  =  context . clone ( painter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        paint_internal ( paint_context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 00:01:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( destination_rect . size ( )  = =  bitmap - > size ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            context . painter ( ) . blit ( destination_rect . location ( ) ,  * bitmap ,  bitmap - > rect ( ) ,  opacity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 22:02:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 15:24:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            context . painter ( ) . draw_scaled_bitmap ( destination_rect ,  * bitmap ,  bitmap - > rect ( ) ,  opacity ,  Gfx : : Painter : : ScalingMode : : BilinearBlend ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-29 01:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Gfx : : PainterStateSaver  saver ( context . painter ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        context . painter ( ) . translate ( affine_transform . translation ( ) . to_rounded < int > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:19:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        paint_internal ( context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-24 20:36:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Gfx : : FloatPoint  StackingContext : : compute_transform_origin ( )  const  
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:38:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  style_value  =  m_box . computed_values ( ) . transform_origin ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: respect transform-box property
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  reference_box  =  paintable ( ) . absolute_border_box_rect ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:38:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  x  =  reference_box . left ( )  +  style_value . x . resolved ( m_box ,  CSS : : Length : : make_px ( reference_box . width ( ) ) ) . to_px ( m_box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  y  =  reference_box . top ( )  +  style_value . y . resolved ( m_box ,  CSS : : Length : : make_px ( reference_box . height ( ) ) ) . to_px ( m_box ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  {  x ,  y  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								template < typename  U ,  typename  Callback >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  TraversalDecision  for_each_in_inclusive_subtree_of_type_within_same_stacking_context_in_reverse ( Paintable  const &  paintable ,  Callback  callback )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < PaintableBox > ( paintable )  & &  static_cast < PaintableBox  const & > ( paintable ) . stacking_context ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  TraversalDecision : : SkipChildrenAndContinue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  child  =  paintable . last_child ( ) ;  child ;  child  =  child - > previous_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( for_each_in_inclusive_subtree_of_type_within_same_stacking_context_in_reverse < U > ( * child ,  callback )  = =  TraversalDecision : : Break ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < U > ( paintable ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  decision  =  callback ( static_cast < U  const & > ( paintable ) ) ;  decision  ! =  TraversalDecision : : Continue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  decision ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template < typename  U ,  typename  Callback >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  TraversalDecision  for_each_in_subtree_of_type_within_same_stacking_context_in_reverse ( Paintable  const &  paintable ,  Callback  callback )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  child  =  paintable . last_child ( ) ;  child ;  child  =  child - > previous_sibling ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( for_each_in_inclusive_subtree_of_type_within_same_stacking_context_in_reverse < U > ( * child ,  callback )  = =  TraversalDecision : : Break ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 17:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Optional < HitTestResult >  StackingContext : : hit_test ( CSSPixelPoint  position ,  HitTestType  type )  const  
						 
					
						
							
								
									
										
										
										
											2020-07-01 19:02:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_box . is_visible ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 17:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  transform_origin  =  this - > transform_origin ( ) . to_type < CSSPixels > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: This CSSPixels -> Float -> CSSPixels conversion is because we can't AffineTransform::map() a CSSPixelPoint.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Gfx : : FloatPoint  offset_position  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        position . x ( ) . value ( )  -  transform_origin . x ( ) . value ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        position . y ( ) . value ( )  -  transform_origin . y ( ) . value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  transformed_position  =  affine_transform_matrix ( ) . inverse ( ) . value_or ( { } ) . map ( offset_position ) . to_type < CSSPixels > ( )  +  transform_origin ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:32:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: Support more overflow variations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( paintable ( ) . computed_values ( ) . overflow_x ( )  = =  CSS : : Overflow : : Hidden  & &  paintable ( ) . computed_values ( ) . overflow_y ( )  = =  CSS : : Overflow : : Hidden )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 17:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! paintable ( ) . absolute_border_box_rect ( ) . contains ( transformed_position . x ( ) . value ( ) ,  transformed_position . y ( ) . value ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: Hit testing basically happens in reverse painting order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://www.w3.org/TR/CSS22/visuren.html#z-index
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. the child stacking contexts with positive stack levels (least positive first).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-07 11:51:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( ssize_t  i  =  m_children . size ( )  -  1 ;  i  > =  0 ;  - - i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  child  =  * m_children [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( child . m_box . computed_values ( ) . z_index ( ) . value_or ( 0 )  < =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-07 11:51:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:32:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  result  =  child . hit_test ( transformed_position ,  type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 01:43:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( result . has_value ( )  & &  result - > paintable - > visible_for_hit_testing ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 11:11:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Optional < HitTestResult >  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_in_subtree_of_type_within_same_stacking_context_in_reverse < PaintableBox > ( paintable ( ) ,  [ & ] ( PaintableBox  const &  paint_box )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: Support more overflow variations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( paint_box . computed_values ( ) . overflow_x ( )  = =  CSS : : Overflow : : Hidden  & &  paint_box . computed_values ( ) . overflow_y ( )  = =  CSS : : Overflow : : Hidden )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 17:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! paint_box . absolute_border_box_rect ( ) . contains ( transformed_position . x ( ) . value ( ) ,  transformed_position . y ( ) . value ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  TraversalDecision : : SkipChildrenAndContinue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( paint_box . stacking_context ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  const &  z_index  =  paint_box . computed_values ( ) . z_index ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! z_index . has_value ( )  | |  z_index . value ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  candidate  =  paint_box . stacking_context ( ) - > hit_test ( transformed_position ,  type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( candidate . has_value ( )  & &  candidate - > paintable - > visible_for_hit_testing ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    result  =  move ( candidate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  layout_box  =  paint_box . layout_box ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( layout_box . is_positioned ( )  & &  ! paint_box . stacking_context ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( auto  candidate  =  paint_box . hit_test ( transformed_position ,  type ) ;  candidate . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 12:12:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                result  =  move ( candidate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 01:43:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( result . has_value ( )  & &  result - > paintable - > visible_for_hit_testing ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 19:04:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // "child stacking contexts with stack level 0" is first in the step, so last here to match reverse order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( ssize_t  i  =  m_children . size ( )  -  1 ;  i  > =  0 ;  - - i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  child  =  * m_children [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( child . m_box . computed_values ( ) . z_index ( ) . value_or ( 0 )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  result  =  child . hit_test ( transformed_position ,  type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( result . has_value ( )  & &  result - > paintable - > visible_for_hit_testing ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 02:13:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_box . children_are_inline ( )  & &  is < Layout : : BlockContainer > ( m_box ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  result  =  paintable ( ) . hit_test ( transformed_position ,  type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 01:43:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( result . has_value ( )  & &  result - > paintable - > visible_for_hit_testing ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-01 19:02:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. the non-positioned floats.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_in_subtree_of_type_within_same_stacking_context_in_reverse < PaintableBox > ( paintable ( ) ,  [ & ] ( auto  const &  paint_box )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: Support more overflow variations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( paint_box . computed_values ( ) . overflow_x ( )  = =  CSS : : Overflow : : Hidden  & &  paint_box . computed_values ( ) . overflow_y ( )  = =  CSS : : Overflow : : Hidden )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 17:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! paint_box . absolute_border_box_rect ( ) . contains ( transformed_position . x ( ) . value ( ) ,  transformed_position . y ( ) . value ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  TraversalDecision : : SkipChildrenAndContinue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  layout_box  =  paint_box . layout_box ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( layout_box . is_floating ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( auto  candidate  =  paint_box . hit_test ( transformed_position ,  type ) ;  candidate . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 12:12:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                result  =  move ( candidate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 01:43:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( result . has_value ( )  & &  result - > paintable - > visible_for_hit_testing ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 11:11:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. the in-flow, non-inline-level, non-positioned descendants.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_box . children_are_inline ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for_each_in_subtree_of_type_within_same_stacking_context_in_reverse < PaintableBox > ( paintable ( ) ,  [ & ] ( auto  const &  paint_box )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // FIXME: Support more overflow variations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( paint_box . computed_values ( ) . overflow_x ( )  = =  CSS : : Overflow : : Hidden  & &  paint_box . computed_values ( ) . overflow_y ( )  = =  CSS : : Overflow : : Hidden )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 17:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! paint_box . absolute_border_box_rect ( ) . contains ( transformed_position . x ( ) . value ( ) ,  transformed_position . y ( ) . value ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  TraversalDecision : : SkipChildrenAndContinue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  layout_box  =  paint_box . layout_box ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! layout_box . is_absolutely_positioned ( )  & &  ! layout_box . is_floating ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( auto  candidate  =  paint_box . hit_test ( transformed_position ,  type ) ;  candidate . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 12:12:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    result  =  move ( candidate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 19:08:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  TraversalDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-03 18:34:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  TraversalDecision : : Continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 01:43:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( result . has_value ( )  & &  result - > paintable - > visible_for_hit_testing ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 10:26:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. the child stacking contexts with negative stack levels (most negative first).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-07 11:51:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( ssize_t  i  =  m_children . size ( )  -  1 ;  i  > =  0 ;  - - i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  child  =  * m_children [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-07 11:51:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( child . m_box . computed_values ( ) . z_index ( ) . value_or ( 0 )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:32:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  result  =  child . hit_test ( transformed_position ,  type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 01:43:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( result . has_value ( )  & &  result - > paintable - > visible_for_hit_testing ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 10:26:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. the background and borders of the element forming the stacking context.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 17:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( paintable ( ) . absolute_border_box_rect ( ) . contains ( transformed_position . x ( ) . value ( ) ,  transformed_position . y ( ) . value ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  HitTestResult  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            . paintable  =  paintable ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-01 19:02:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:02:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-01 19:02:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  StackingContext : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-01-01 16:42:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    for  ( int  i  =  0 ;  i  <  indent ;  + + i ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 16:42:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        builder . append ( '   ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 15:56:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    builder . appendff ( " SC for {} {} [children: {}] (z-index:  " ,  m_box . debug_description ( ) ,  paintable ( ) . absolute_rect ( ) ,  m_children . size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:03:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_box . computed_values ( ) . z_index ( ) . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . appendff ( " {} " ,  m_box . computed_values ( ) . z_index ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        builder . append ( " auto " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 15:03:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    builder . append ( ' ) ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 15:18:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  affine_transform  =  affine_transform_matrix ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 01:29:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! affine_transform . is_identity ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . appendff ( " , transform: {} " ,  affine_transform ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 16:42:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dbgln ( " {} " ,  builder . string_view ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-15 17:29:35 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  child  :  m_children ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        child - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}