2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2022 - 2023 ,  MacDue  < macdue @ dueutil . tech > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/Math.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibGfx/Gradients.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibGfx/PaintStyle.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibGfx/Painter.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# if defined(AK_COMPILER_GCC) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								#     pragma GCC optimize("O3") 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Gfx  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// Note: This file implements the CSS/Canvas gradients for LibWeb according to the spec.
  
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// Please do not make ad-hoc changes that may break spec compliance!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  float  color_stop_step ( ColorStop  const &  previous_stop ,  ColorStop  const &  next_stop ,  float  position )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( position  <  previous_stop . position ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( position  >  next_stop . position ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // For any given point between the two color stops,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // determine the point’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Let this percentage be P.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  stop_length  =  next_stop . position  -  previous_stop . position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Avoids NaNs... Still not quite correct?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( stop_length  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  p  =  ( position  -  previous_stop . position )  /  stop_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! next_stop . transition_hint . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( * next_stop . transition_hint  > =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( * next_stop . transition_hint  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Let C, the color weighting at that point, be equal to P^(logH(.5)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  c  =  AK : : pow ( p ,  AK : : log < float > ( 0.5 )  /  AK : : log ( * next_stop . transition_hint ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The color at that point is then a linear blend between the colors of the two color stops,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // blending (1 - C) of the first stop and C of the second stop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								enum  class  UsePremultipliedAlpha  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Yes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    No 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								class  GradientLine  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								public :  
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GradientLine ( int  gradient_length ,  ReadonlySpan < ColorStop >  color_stops ,  Optional < float >  repeat_length ,  UsePremultipliedAlpha  use_premultiplied_alpha  =  UsePremultipliedAlpha : : Yes ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        :  m_repeat_mode ( repeat_length . has_value ( )  ?  RepeatMode : : Repeat  :  RepeatMode : : None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ,  m_start_offset ( round_to < int > ( ( repeating ( )  ?  color_stops . first ( ) . position  :  0.0f )  *  gradient_length ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-29 13:29:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        ,  m_color_stops ( color_stops ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ,  m_use_premultiplied_alpha ( use_premultiplied_alpha ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Avoid generating excessive amounts of colors when the not enough shades to fill that length.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  necessary_length  =  min < int > ( ( color_stops . size ( )  -  1 )  *  255 ,  gradient_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_sample_scale  =  float ( necessary_length )  /  gradient_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Note: color_count will be < gradient_length for repeating gradients.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  color_count  =  round_to < int > ( repeat_length . value_or ( 1.0f )  *  necessary_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_gradient_line_colors . resize ( color_count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( int  loc  =  0 ;  loc  <  color_count ;  loc + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  relative_loc  =  float ( loc  +  m_start_offset )  /  necessary_length ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Color  gradient_color  =  color_blend ( color_stops [ 0 ] . color ,  color_stops [ 1 ] . color , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                color_stop_step ( color_stops [ 0 ] ,  color_stops [ 1 ] ,  relative_loc ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( size_t  i  =  1 ;  i  <  color_stops . size ( )  -  1 ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                gradient_color  =  color_blend ( gradient_color ,  color_stops [ i  +  1 ] . color , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    color_stop_step ( color_stops [ i ] ,  color_stops [ i  +  1 ] ,  relative_loc ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            m_gradient_line_colors [ loc ]  =  gradient_color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( gradient_color . alpha ( )  <  255 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                m_requires_blending  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Color  color_blend ( Color  a ,  Color  b ,  float  amount )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Note: color.mixed_with() performs premultiplied alpha mixing when necessary as defined in:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://drafts.csswg.org/css-images/#coloring-gradient-line
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( m_use_premultiplied_alpha  = =  UsePremultipliedAlpha : : Yes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  a . mixed_with ( b ,  amount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  a . interpolate ( b ,  amount ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-07 22:48:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Color  get_color ( i64  index )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( index  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  m_color_stops . first ( ) . color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( index  > =  static_cast < i64 > ( m_gradient_line_colors . size ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  m_color_stops . last ( ) . color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_gradient_line_colors [ index ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Color  sample_color ( float  loc )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! isfinite ( loc ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Color ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( m_sample_scale  ! =  1.0f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            loc  * =  m_sample_scale ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  repeat_wrap_if_required  =  [ & ] ( i64  loc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( m_repeat_mode  ! =  RepeatMode : : None )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  current_loc  =  loc  +  m_start_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  gradient_len  =  static_cast < i64 > ( m_gradient_line_colors . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( m_repeat_mode  = =  RepeatMode : : Repeat )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  color_loc  =  current_loc  %  gradient_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  color_loc  <  0  ?  gradient_len  +  color_loc  :  color_loc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( m_repeat_mode  = =  RepeatMode : : Reflect )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  color_loc  =  AK : : abs ( current_loc  %  gradient_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  repeats  =  current_loc  /  gradient_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  ( repeats  &  1 )  ?  gradient_len  -  color_loc  :  color_loc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  loc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  int_loc  =  static_cast < i64 > ( floor ( loc ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  blend  =  loc  -  int_loc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  color  =  get_color ( repeat_wrap_if_required ( int_loc ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-06 16:28:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Blend between the two neighboring colors (this fixes some nasty aliasing issues at small angles)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( blend  > =  0.004f ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            color  =  color_blend ( color ,  get_color ( repeat_wrap_if_required ( int_loc  +  1 ) ) ,  blend ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    void  paint_into_physical_rect ( Painter &  painter ,  IntRect  rect ,  auto  location_transform ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  clipped_rect  =  rect . intersected ( painter . clip_rect ( )  *  painter . scale ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  start_offset  =  clipped_rect . location ( )  -  rect . location ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( int  y  =  0 ;  y  <  clipped_rect . height ( ) ;  y + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( int  x  =  0 ;  x  <  clipped_rect . width ( ) ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  pixel  =  sample_color ( location_transform ( x  +  start_offset . x ( ) ,  y  +  start_offset . y ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                painter . set_physical_pixel ( clipped_rect . location ( ) . translated ( x ,  y ) ,  pixel ,  m_requires_blending ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  repeating ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_repeat_mode  ! =  RepeatMode : : None ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    enum  class  RepeatMode  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        None , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Repeat , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Reflect 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    void  set_repeat_mode ( RepeatMode  repeat_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Note: A gradient can be set to repeating without a repeat length.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The repeat length is used for CSS gradients but not for SVG gradients.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_repeat_mode  =  repeat_mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								private :  
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RepeatMode  m_repeat_mode  {  RepeatMode : : None  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    int  m_start_offset  {  0  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    float  m_sample_scale  {  1  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    ReadonlySpan < ColorStop >  m_color_stops  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    UsePremultipliedAlpha  m_use_premultiplied_alpha  {  UsePremultipliedAlpha : : Yes  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Color ,  1024 >  m_gradient_line_colors ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  m_requires_blending  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  TransformFunction >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								struct  Gradient  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Gradient ( GradientLine  gradient_line ,  TransformFunction  transform_function ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        :  m_gradient_line ( move ( gradient_line ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ,  m_transform_function ( move ( transform_function ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    void  paint ( Painter &  painter ,  IntRect  rect ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_gradient_line . paint_into_physical_rect ( painter ,  rect ,  m_transform_function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    template < typename  CoordinateType  =  int > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  sample_function ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  [ this ] ( Point < CoordinateType >  point )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  m_gradient_line . sample_color ( m_transform_function ( point . x ( ) ,  point . y ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GradientLine &  gradient_line ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_gradient_line ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    GradientLine  m_gradient_line ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TransformFunction  m_transform_function ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  auto  create_linear_gradient ( IntRect  const &  physical_rect ,  ReadonlySpan < ColorStop >  color_stops ,  float  angle ,  Optional < float >  repeat_length )  
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    float  normalized_angle  =  normalized_gradient_angle_radians ( angle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    float  sin_angle ,  cos_angle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    AK : : sincos ( normalized_angle ,  sin_angle ,  cos_angle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Full length of the gradient
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  gradient_length  =  calculate_gradient_length ( physical_rect . size ( ) ,  sin_angle ,  cos_angle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    IntPoint  offset  {  cos_angle  *  ( gradient_length  /  2 ) ,  sin_angle  *  ( gradient_length  /  2 )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  center  =  physical_rect . translated ( - physical_rect . location ( ) ) . center ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  start_point  =  center  -  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Rotate gradient line to be horizontal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  rotated_start_point_x  =  start_point . x ( )  *  cos_angle  -  start_point . y ( )  *  - sin_angle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    GradientLine  gradient_line ( gradient_length ,  color_stops ,  repeat_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Gradient  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        move ( gradient_line ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ = ] ( int  x ,  int  y )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ( x  *  cos_angle  -  ( physical_rect . height ( )  -  y )  *  - sin_angle )  -  rotated_start_point_x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  auto  create_conic_gradient ( ReadonlySpan < ColorStop >  color_stops ,  FloatPoint  center_point ,  float  start_angle ,  Optional < float >  repeat_length ,  UsePremultipliedAlpha  use_premultiplied_alpha  =  UsePremultipliedAlpha : : Yes )  
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Do we need/want sub-degree accuracy for the gradient line?
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GradientLine  gradient_line ( 360 ,  color_stops ,  repeat_length ,  use_premultiplied_alpha ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    float  normalized_start_angle  =  ( 360.0f  -  start_angle )  +  90.0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The flooring can make gradients that want soft edges look worse, so only floor if we have hard edges.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Which makes sure the hard edge stay hard edges :^)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  should_floor_angles  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  color_stops . size ( )  -  1 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( color_stops [ i  +  1 ] . position  -  color_stops [ i ] . position  < =  0.01f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            should_floor_angles  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Gradient  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        move ( gradient_line ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ = ] ( int  x ,  int  y )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  point  =  FloatPoint  {  x ,  y  }  -  center_point ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: We could probably get away with some approximation here:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  loc  =  fmod ( ( AK : : atan2 ( point . y ( ) ,  point . x ( ) )  *  180.0f  /  AK : : Pi < float >  +  360.0f  +  normalized_start_angle ) ,  360.0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  should_floor_angles  ?  floor ( loc )  :  loc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 17:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  auto  create_radial_gradient ( IntRect  const &  physical_rect ,  ReadonlySpan < ColorStop >  color_stops ,  IntPoint  center ,  IntSize  size ,  Optional < float >  repeat_length ,  Optional < float >  rotation_angle  =  { } )  
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A conservative guesstimate on how many colors we need to generate:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  max_dimension  =  max ( physical_rect . width ( ) ,  physical_rect . height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  max_visible_gradient  =  max ( max_dimension  /  2 ,  min ( size . width ( ) ,  max_dimension ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    GradientLine  gradient_line ( max_visible_gradient ,  color_stops ,  repeat_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  center_point  =  FloatPoint  {  center  } . translated ( 0.5 ,  0.5 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 17:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    AffineTransform  rotation_transform ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( rotation_angle . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  angle_as_radians  =  rotation_angle . value ( )  *  ( AK : : Pi < float >  /  180 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        rotation_transform . rotate_radians ( angle_as_radians ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Gradient  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        move ( gradient_line ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ = ] ( int  x ,  int  y )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: See if there's a more efficient calculation we do there :^)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  point  =  FloatPoint ( x ,  y )  -  center_point ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 17:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( rotation_angle . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                point . transform_by ( rotation_transform ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  gradient_x  =  point . x ( )  /  size . width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  gradient_y  =  point . y ( )  /  size . height ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  AK : : sqrt ( gradient_x  *  gradient_x  +  gradient_y  *  gradient_y )  *  max_visible_gradient ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  Painter : : fill_rect_with_linear_gradient ( IntRect  const &  rect ,  ReadonlySpan < ColorStop >  color_stops ,  float  angle ,  Optional < float >  repeat_length )  
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  a_rect  =  to_physical ( rect ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( a_rect . intersected ( clip_rect ( )  *  scale ( ) ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  linear_gradient  =  create_linear_gradient ( a_rect ,  color_stops ,  angle ,  repeat_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    linear_gradient . paint ( * this ,  a_rect ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  FloatPoint  pixel_center ( IntPoint  point )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  point . to_type < float > ( ) . translated ( 0.5f ,  0.5f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  Painter : : fill_rect_with_conic_gradient ( IntRect  const &  rect ,  ReadonlySpan < ColorStop >  color_stops ,  IntPoint  center ,  float  start_angle ,  Optional < float >  repeat_length )  
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  a_rect  =  to_physical ( rect ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( a_rect . intersected ( clip_rect ( )  *  scale ( ) ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Translate position/center to the center of the pixel (avoids some funky painting)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  center_point  =  pixel_center ( center  *  scale ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  conic_gradient  =  create_conic_gradient ( color_stops ,  center_point ,  start_angle ,  repeat_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    conic_gradient . paint ( * this ,  a_rect ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 17:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  Painter : : fill_rect_with_radial_gradient ( IntRect  const &  rect ,  ReadonlySpan < ColorStop >  color_stops ,  IntPoint  center ,  IntSize  size ,  Optional < float >  repeat_length ,  Optional < float >  rotation_angle )  
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  a_rect  =  to_physical ( rect ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( a_rect . intersected ( clip_rect ( )  *  scale ( ) ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 17:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  radial_gradient  =  create_radial_gradient ( a_rect ,  color_stops ,  center  *  scale ( ) ,  size  *  scale ( ) ,  repeat_length ,  rotation_angle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    radial_gradient . paint ( * this ,  a_rect ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 22:10:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// TODO: Figure out how to handle scale() here... Not important while not supported by fill_path()
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  LinearGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY ( color_stops ( ) . size ( )  >  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  linear_gradient  =  create_linear_gradient ( physical_bounding_box ,  color_stops ( ) ,  m_angle ,  repeat_length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( linear_gradient . sample_function ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  ConicGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY ( color_stops ( ) . size ( )  >  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ( void ) physical_bounding_box ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  conic_gradient  =  create_conic_gradient ( color_stops ( ) ,  pixel_center ( m_center ) ,  m_start_angle ,  repeat_length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( conic_gradient . sample_function ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  RadialGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY ( color_stops ( ) . size ( )  >  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  radial_gradient  =  create_radial_gradient ( physical_bounding_box ,  color_stops ( ) ,  m_center ,  m_size ,  repeat_length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( radial_gradient . sample_function ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// The following implements the gradient fill/stoke styles for the HTML canvas: https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  auto  make_sample_non_relative ( IntPoint  draw_location ,  auto  sample )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  [ = ,  sample  =  move ( sample ) ] ( IntPoint  point )  {  return  sample ( point . translated ( draw_location ) ) ;  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-22 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  auto  make_linear_gradient_between_two_points ( FloatPoint  p0 ,  FloatPoint  p1 ,  ReadonlySpan < ColorStop >  color_stops ,  Optional < float >  repeat_length )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  delta  =  p1  -  p0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  angle  =  AK : : atan2 ( delta . y ( ) ,  delta . x ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    float  sin_angle ,  cos_angle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    AK : : sincos ( angle ,  sin_angle ,  cos_angle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    int  gradient_length  =  ceilf ( p1 . distance_from ( p0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  rotated_start_point_x  =  p0 . x ( )  *  cos_angle  -  p0 . y ( )  *  - sin_angle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Gradient  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        GradientLine ( gradient_length ,  color_stops ,  repeat_length ,  UsePremultipliedAlpha : : No ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ = ] ( int  x ,  int  y )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ( x  *  cos_angle  -  y  *  - sin_angle )  -  rotated_start_point_x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  CanvasLinearGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_p0  = =  m_p1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . size ( )  <  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  paint ( [ this ] ( IntPoint )  {  return  color_stops ( ) . first ( ) . color ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-22 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  linear_gradient  =  make_linear_gradient_between_two_points ( m_p0 ,  m_p1 ,  color_stops ( ) ,  repeat_length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( make_sample_non_relative ( physical_bounding_box . location ( ) ,  linear_gradient . sample_function ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  GradientLine : : RepeatMode  svg_spread_method_to_repeat_mode ( SVGGradientPaintStyle : : SpreadMethod  spread_method )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( spread_method )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  SVGGradientPaintStyle : : SpreadMethod : : Pad : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  GradientLine : : RepeatMode : : None ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  SVGGradientPaintStyle : : SpreadMethod : : Reflect : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  GradientLine : : RepeatMode : : Reflect ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  SVGGradientPaintStyle : : SpreadMethod : : Repeat : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  GradientLine : : RepeatMode : : Repeat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  SVGGradientPaintStyle : : set_gradient_transform ( AffineTransform  transform )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: The scaling is removed so enough points on the gradient line are generated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise, if you scale a tiny path the gradient looks pixelated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    m_scale  =  1.0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  inverse  =  transform . inverse ( ) ;  inverse . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transform_scale  =  transform . scale ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_scale  =  max ( transform_scale . x ( ) ,  transform_scale . y ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_inverse_transform  =  AffineTransform  { } . scale ( m_scale ,  m_scale ) . multiply ( * inverse ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_inverse_transform  =  OptionalNone  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-22 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  SVGLinearGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // If ‘ ’ ‘ ’ ‘ ’ ‘ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // a single color using the color and opacity of the last gradient stop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_p0  = =  m_p1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  paint ( [ this ] ( IntPoint )  {  return  color_stops ( ) . last ( ) . color ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . size ( )  <  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  paint ( [ this ] ( IntPoint )  {  return  color_stops ( ) . first ( ) . color ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    float  scale  =  gradient_transform_scale ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  linear_gradient  =  make_linear_gradient_between_two_points ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_p0 . scaled ( scale ,  scale ) ,  m_p1 . scaled ( scale ,  scale ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        color_stops ( ) ,  repeat_length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    linear_gradient . gradient_line ( ) . set_repeat_mode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        svg_spread_method_to_repeat_mode ( spread_method ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-22 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( [ & ,  sampler  =  linear_gradient . sample_function < float > ( ) ] ( IntPoint  target_point )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  point  =  target_point . translated ( physical_bounding_box . location ( ) ) . to_type < float > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  inverse_transform  =  scale_adjusted_inverse_gradient_transform ( ) ;  inverse_transform . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            point  =  inverse_transform - > map ( point ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-22 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  sampler ( point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  CanvasConicGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . size ( )  <  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  paint ( [ this ] ( IntPoint )  {  return  color_stops ( ) . first ( ) . color ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Follows the same rendering rule as CSS 'conic-gradient' and it is equivalent to CSS
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 'conic-gradient(from adjustedStartAnglerad at xpx ypx, angularColorStopList)'.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  Here:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      adjustedStartAngle is given by startAngle + π/2;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  conic_gradient  =  create_conic_gradient ( color_stops ( ) ,  m_center ,  m_start_angle  +  90.0f ,  repeat_length ( ) ,  UsePremultipliedAlpha : : No ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( make_sample_non_relative ( physical_bounding_box . location ( ) ,  conic_gradient . sample_function ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  auto  create_radial_gradient_between_two_circles ( Gfx : : FloatPoint  start_center ,  float  start_radius ,  Gfx : : FloatPoint  end_center ,  float  end_radius ,  ReadonlySpan < ColorStop >  color_stops ,  Optional < float >  repeat_length )  
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  reverse_gradient  =  end_radius  <  start_radius ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( reverse_gradient )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        swap ( end_radius ,  start_radius ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        swap ( end_center ,  start_center ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Handle the start_radius == end_radius special case separately.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // This hack is not quite correct.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( end_radius  -  start_radius  <  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        end_radius  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Spec steps: Useless for writing an actual implementation (give it a go :P):
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let x(ω) = (x1-x0)ω + x0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Let y(ω) = (y1-y0)ω + y0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Let r(ω) = (r1-r0)ω + r0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Let the color at ω be the color at that position on the gradient
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // (with the colors coming from the interpolation and extrapolation described above).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. For all values of ω where r(ω) > 0, starting with the value of ω nearest to positive infinity and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // ending with the value of ω nearest to negative infinity, draw the circumference of the circle with
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // radius r(ω) at position (x(ω), y(ω)), with the color at ω, but only painting on the parts of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // bitmap that have not yet been painted on by earlier circles in this step for this rendering of the gradient.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  center_dist  =  end_center . distance_from ( start_center ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  inner_contained  =  ( ( center_dist  +  start_radius )  <  end_radius ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  start_point  =  start_center ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( start_radius  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Set the start point to the focal point.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  f  =  end_radius  /  ( end_radius  -  start_radius ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  one_minus_f  =  1  -  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        start_point  =  start_center . scaled ( f )  +  end_center . scaled ( one_minus_f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // This is just an approximate upperbound (the gradient line class will shorten this if necessary).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 00:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    int  gradient_length  =  AK : : ceil ( center_dist  +  end_radius  +  start_radius ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GradientLine  gradient_line ( gradient_length ,  color_stops ,  repeat_length ,  UsePremultipliedAlpha : : No ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If you can simplify this please do, this is "best guess" implementation due to lack of specification.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // It was implemented to visually match chrome/firefox in all cases:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      - Start circle inside end circle
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      - Start circle outside end circle
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      - Start circle radius == end circle radius
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      - Start circle larger than end circle (inside end circle)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      - Start circle larger than end circle (outside end circle)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-12 13:32:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    //      - Start circle or end circle radius == 0
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  circle_distance_finder  =  [ = ] ( auto  radius ,  auto  center )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  radius2  =  radius  *  radius ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  delta  =  center  -  start_point ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  delta_xy  =  delta . x ( )  *  delta . y ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  dx2_factor  =  radius2  -  delta . y ( )  *  delta . y ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  dy2_factor  =  radius2  -  delta . x ( )  *  delta . x ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  [ = ] ( bool  positive_root ,  auto  vec )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // This works out the distance to the nearest point on the circle
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // in the direction of the "vec" vector.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dx2  =  vec . x ( )  *  vec . x ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dy2  =  vec . y ( )  *  vec . y ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  root  =  sqrtf ( dx2  *  dx2_factor  +  dy2  *  dy2_factor 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                +  2  *  vec . x ( )  *  vec . y ( )  *  delta_xy ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dot  =  vec . x ( )  *  delta . x ( )  +  vec . y ( )  *  delta . y ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ( ( positive_root  ?  root  :  - root )  +  dot )  /  ( dx2  +  dy2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  end_circle_dist  =  circle_distance_finder ( end_radius ,  end_center ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  start_circle_dist  =  [ = ,  dist  =  circle_distance_finder ( start_radius ,  start_center ) ] ( bool  positive_root ,  auto  vec )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( start_center  = =  start_point ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  start_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  dist ( positive_root ,  vec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:24:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Gradient  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        move ( gradient_line ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        [ = ] ( float  x ,  float  y )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  loc  =  [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                FloatPoint  point  {  x ,  y  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  dist  =  point . distance_from ( start_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( dist  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  0.0f ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // The "vec" (unit) vector points from the focal point to the current point.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  dist  =  point . distance_from ( start_point ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  vec  =  ( point  -  start_point )  /  dist ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                bool  use_positive_root  =  inner_contained  | |  reverse_gradient ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  dist_end  =  end_circle_dist ( use_positive_root ,  vec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  dist_start  =  start_circle_dist ( use_positive_root ,  vec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // FIXME: Returning nan is a hack for "Don't paint me!"
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( dist_end  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  AK : : NaN < float > ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( dist_end  -  dist_start  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  float ( gradient_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-21 23:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ( dist  -  dist_start )  /  ( dist_end  -  dist_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 22:29:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( reverse_gradient ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                loc  =  1.0f  -  loc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  loc  *  gradient_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  CanvasRadialGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint nothing. Return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_start_center  = =  m_end_center  & &  m_start_radius  = =  m_end_radius ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . size ( )  <  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  paint ( [ this ] ( IntPoint )  {  return  color_stops ( ) . first ( ) . color ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_end_radius  = =  0  & &  m_start_radius  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  radial_gradient  =  create_radial_gradient_between_two_circles ( m_start_center ,  m_start_radius ,  m_end_center ,  m_end_radius ,  color_stops ( ) ,  repeat_length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 19:52:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( make_sample_non_relative ( physical_bounding_box . location ( ) ,  radial_gradient . sample_function ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  SVGRadialGradientPaintStyle : : paint ( IntRect  physical_bounding_box ,  PaintFunction  paint )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Ensure this handles all the edge cases of SVG gradients.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color_stops ( ) . size ( )  <  2  | |  ( m_end_radius  = =  0  & &  m_start_radius  = =  0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  paint ( [ this ] ( IntPoint )  {  return  color_stops ( ) . last ( ) . color ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    float  scale  =  gradient_transform_scale ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  radial_gradient  =  create_radial_gradient_between_two_circles ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_start_center . scaled ( scale ,  scale ) ,  m_start_radius  *  scale ,  m_end_center . scaled ( scale ,  scale ) ,  m_end_radius  *  scale , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        color_stops ( ) ,  repeat_length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-19 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    radial_gradient . gradient_line ( ) . set_repeat_mode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        svg_spread_method_to_repeat_mode ( spread_method ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:43:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    paint ( [ & ,  sampler  =  radial_gradient . sample_function < float > ( ) ] ( IntPoint  target_point )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  point  =  target_point . translated ( physical_bounding_box . location ( ) ) . to_type < float > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  inverse_transform  =  scale_adjusted_inverse_gradient_transform ( ) ;  inverse_transform . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            point  =  inverse_transform - > map ( point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  sampler ( point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 01:07:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}