2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2018 - 2020 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 23:47:29 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <AK/Base64.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 16:55:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <AK/Checked.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:26:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <AK/MemoryStream.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibGfx/Bitmap.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:26:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibGfx/ImageFormats/JPEGWriter.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-21 14:58:06 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibGfx/ImageFormats/PNGWriter.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 01:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/Bindings/ExceptionOrUtils.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 13:49:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/CSS/StyleComputer.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-31 19:22:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/CSS/StyleValues/IdentifierStyleValue.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibWeb/CSS/StyleValues/RatioStyleValue.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibWeb/CSS/StyleValues/StyleValueList.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibWeb/DOM/Document.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 15:08:16 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/HTML/CanvasRenderingContext2D.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibWeb/HTML/HTMLCanvasElement.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-31 22:12:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/HTML/Numbers.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 01:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/HTML/Scripting/ExceptionReporter.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/Layout/CanvasBox.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 01:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibWeb/Platform/EventLoopPlugin.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibWeb/WebIDL/AbstractOperations.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-28 18:20:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								namespace  Web : : HTML  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-19 19:47:52 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								JS_DEFINE_ALLOCATOR ( HTMLCanvasElement ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 12:12:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  constexpr  auto  max_canvas_area  =  16384  *  16384 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 21:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								HTMLCanvasElement : : HTMLCanvasElement ( DOM : : Document &  document ,  DOM : : QualifiedName  qualified_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-07 11:20:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    :  HTMLElement ( document ,  move ( qualified_name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 13:21:51 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								HTMLCanvasElement : : ~ HTMLCanvasElement ( )  =  default ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-07 08:41:28 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  HTMLCanvasElement : : initialize ( JS : : Realm &  realm ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 06:28:20 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-07 08:41:28 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    Base : : initialize ( realm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-22 12:55:21 +13:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    set_prototype ( & Bindings : : ensure_web_prototype < Bindings : : HTMLCanvasElementPrototype > ( realm ,  " HTMLCanvasElement " _fly_string ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 06:28:20 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  HTMLCanvasElement : : visit_edges ( Cell : : Visitor &  visitor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_context . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ & ] ( JS : : NonnullGCPtr < CanvasRenderingContext2D > &  context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-19 16:18:00 +13:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            visitor . visit ( context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ & ] ( JS : : NonnullGCPtr < WebGL : : WebGLRenderingContext > &  context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-19 16:18:00 +13:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            visitor . visit ( context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ ] ( Empty )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-31 19:22:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  HTMLCanvasElement : : apply_presentational_hints ( CSS : : StyleProperties &  style )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // The width and height attributes map to the aspect-ratio property on canvas elements.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // FIXME: Multiple elements have aspect-ratio presentational hints, make this into a helper function
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // https://html.spec.whatwg.org/multipage/rendering.html#map-to-the-aspect-ratio-property
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // if element has both attributes w and h, and parsing those attributes' values using the rules for parsing non-negative integers doesn't generate an error for either
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 14:58:18 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  w  =  parse_non_negative_integer ( deprecated_attribute ( HTML : : AttributeNames : : width ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  h  =  parse_non_negative_integer ( deprecated_attribute ( HTML : : AttributeNames : : height ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-31 19:22:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( w . has_value ( )  & &  h . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // then the user agent is expected to use the parsed integers as a presentational hint for the 'aspect-ratio' property of the form auto w / h.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        style . set_property ( CSS : : PropertyID : : AspectRatio , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            CSS : : StyleValueList : : create ( CSS : : StyleValueVector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                            CSS : : IdentifierStyleValue : : create ( CSS : : ValueID : : Auto ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                            CSS : : RatioStyleValue : : create ( CSS : : Ratio  {  static_cast < double > ( w . value ( ) ) ,  static_cast < double > ( h . value ( ) )  } )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                CSS : : StyleValueList : : Separator : : Space ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								unsigned  HTMLCanvasElement : : width ( )  const 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-31 22:12:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // https://html.spec.whatwg.org/multipage/canvas.html#obtain-numeric-values
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // The rules for parsing non-negative integers must be used to obtain their numeric values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // If an attribute is missing, or if parsing its value returns an error, then the default value must be used instead.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // The width attribute defaults to 300
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 14:58:18 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  parse_non_negative_integer ( deprecated_attribute ( HTML : : AttributeNames : : width ) ) . value_or ( 300 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								unsigned  HTMLCanvasElement : : height ( )  const 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-31 22:12:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // https://html.spec.whatwg.org/multipage/canvas.html#obtain-numeric-values
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // The rules for parsing non-negative integers must be used to obtain their numeric values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // If an attribute is missing, or if parsing its value returns an error, then the default value must be used instead.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // the height attribute defaults to 150
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 14:58:18 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  parse_non_negative_integer ( deprecated_attribute ( HTML : : AttributeNames : : height ) ) . value_or ( 150 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  HTMLCanvasElement : : reset_context_to_default_state ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_context . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        [ ] ( JS : : NonnullGCPtr < CanvasRenderingContext2D > &  context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            context - > reset_to_default_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        [ ] ( JS : : NonnullGCPtr < WebGL : : WebGLRenderingContext > & )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            TODO ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ ] ( Empty )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // Do nothing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 20:37:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								WebIDL : : ExceptionOr < void >  HTMLCanvasElement : : set_width ( unsigned  value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-13 00:54:21 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-08 11:42:00 +13:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TRY ( set_attribute ( HTML : : AttributeNames : : width ,  MUST ( String : : number ( value ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-11 03:05:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_bitmap  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    reset_context_to_default_state ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 20:37:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-13 00:54:21 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 20:37:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								WebIDL : : ExceptionOr < void >  HTMLCanvasElement : : set_height ( unsigned  value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-13 00:54:21 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-08 11:42:00 +13:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TRY ( set_attribute ( HTML : : AttributeNames : : height ,  MUST ( String : : number ( value ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-11 03:05:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_bitmap  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    reset_context_to_default_state ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 20:37:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-13 00:54:21 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								JS : : GCPtr < Layout : : Node >  HTMLCanvasElement : : create_layout_node ( NonnullRefPtr < CSS : : StyleProperties >  style ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 14:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  heap ( ) . allocate_without_realm < Layout : : CanvasBox > ( document ( ) ,  * this ,  move ( style ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								HTMLCanvasElement : : HasOrCreatedContext  HTMLCanvasElement : : create_2d_context ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! m_context . has < Empty > ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  m_context . has < JS : : NonnullGCPtr < CanvasRenderingContext2D > > ( )  ?  HasOrCreatedContext : : Yes  :  HasOrCreatedContext : : No ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-13 13:05:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_context  =  CanvasRenderingContext2D : : create ( realm ( ) ,  * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  HasOrCreatedContext : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								JS : : ThrowCompletionOr < HTMLCanvasElement : : HasOrCreatedContext >  HTMLCanvasElement : : create_webgl_context ( JS : : Value  options ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! m_context . has < Empty > ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  m_context . has < JS : : NonnullGCPtr < WebGL : : WebGLRenderingContext > > ( )  ?  HasOrCreatedContext : : Yes  :  HasOrCreatedContext : : No ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 18:12:50 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  maybe_context  =  TRY ( WebGL : : WebGLRenderingContext : : create ( realm ( ) ,  * this ,  options ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! maybe_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  HasOrCreatedContext : : No ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_context  =  JS : : NonnullGCPtr < WebGL : : WebGLRenderingContext > ( * maybe_context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  HasOrCreatedContext : : Yes ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// https://html.spec.whatwg.org/multipage/canvas.html#dom-canvas-getcontext
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 15:58:55 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								JS : : ThrowCompletionOr < HTMLCanvasElement : : RenderingContext >  HTMLCanvasElement : : get_context ( String  const &  type ,  JS : : Value  options ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 12:12:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 1. If options is not an object, then set options to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! options . is_object ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        options  =  JS : : js_null ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Set options to the result of converting options to a JavaScript value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: No-op.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Run the steps in the cell of the following table whose column header matches this canvas element's canvas context mode and whose row header matches contextId:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: See the spec for the full table.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( type  = =  " 2d " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( create_2d_context ( )  = =  HasOrCreatedContext : : Yes ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return  JS : : make_handle ( * m_context . get < JS : : NonnullGCPtr < HTML : : CanvasRenderingContext2D > > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: The WebGL spec says "experimental-webgl" is also acceptable and must be equivalent to "webgl". Other engines accept this, so we do too.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( type . is_one_of ( " webgl " sv ,  " experimental-webgl " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( TRY ( create_webgl_context ( options ) )  = =  HasOrCreatedContext : : Yes ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return  JS : : make_handle ( * m_context . get < JS : : NonnullGCPtr < WebGL : : WebGLRenderingContext > > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  Gfx : : IntSize  bitmap_size_for_canvas ( HTMLCanvasElement  const &  canvas ,  size_t  minimum_width ,  size_t  minimum_height ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  width  =  max ( canvas . width ( ) ,  minimum_width ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  height  =  max ( canvas . height ( ) ,  minimum_height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 16:55:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Checked < size_t >  area  =  width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    area  * =  height ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( area . has_overflow ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 14:02:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        dbgln ( " Refusing to create {}x{} canvas (overflow) " ,  width ,  height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 12:12:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 16:55:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( area . value ( )  >  max_canvas_area )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 14:02:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        dbgln ( " Refusing to create {}x{} canvas (exceeds maximum size) " ,  width ,  height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 12:12:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  Gfx : : IntSize ( width ,  height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 12:12:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  HTMLCanvasElement : : create_bitmap ( size_t  minimum_width ,  size_t  minimum_height ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  size  =  bitmap_size_for_canvas ( * this ,  minimum_width ,  minimum_height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 12:12:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( size . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_bitmap  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-06 19:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! m_bitmap  | |  m_bitmap - > size ( )  ! =  size )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-20 20:06:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        auto  bitmap_or_error  =  Gfx : : Bitmap : : create ( Gfx : : BitmapFormat : : BGRA8888 ,  size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-06 19:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( bitmap_or_error . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_bitmap  =  bitmap_or_error . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 16:55:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  m_bitmap ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:12:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  SerializeBitmapResult  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ByteBuffer  buffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    StringView  mime_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// https://html.spec.whatwg.org/multipage/canvas.html#a-serialisation-of-the-bitmap-as-a-file
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:26:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  ErrorOr < SerializeBitmapResult >  serialize_bitmap ( Gfx : : Bitmap  const &  bitmap ,  StringView  type ,  Optional < double >  quality ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:12:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:26:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // If type is an image format that supports variable quality (such as "image/jpeg"), quality is given, and type is not "image/png", then,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // if Type(quality) is Number, and quality is in the range 0.0 to 1.0 inclusive, the user agent must treat quality as the desired quality level.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Otherwise, the user agent must use its default quality value, as if the quality argument had not been given.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( quality . has_value ( )  & &  ! ( * quality  > =  0.0  & &  * quality  < =  1.0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        quality  =  OptionalNone  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( type . equals_ignoring_ascii_case ( " image/jpeg " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        AllocatingMemoryStream  file ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        Gfx : : JPEGWriter : : Options  jpeg_options ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( quality . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            jpeg_options . quality  =  static_cast < int > ( quality . value ( )  *  100 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        TRY ( Gfx : : JPEGWriter : : encode ( file ,  bitmap ,  jpeg_options ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  SerializeBitmapResult  {  TRY ( file . read_until_eof ( ) ) ,  " image/jpeg " sv  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:12:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // User agents must support PNG ("image/png"). User agents may support other types.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // If the user agent does not support the requested type, then it must create the file using the PNG format. [PNG]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  SerializeBitmapResult  {  TRY ( Gfx : : PNGWriter : : encode ( bitmap ) ) ,  " image/png " sv  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// https://html.spec.whatwg.org/multipage/canvas.html#dom-canvas-todataurl
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-16 22:00:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								String  HTMLCanvasElement : : to_data_url ( StringView  type ,  Optional < double >  quality ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 23:47:29 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-16 22:00:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // It is possible the the canvas doesn't have a associated bitmap so create one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! bitmap ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        create_bitmap ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:12:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // FIXME: 1. If this canvas element's bitmap's origin-clean flag is set to false, then throw a "SecurityError" DOMException.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. If this canvas element's bitmap has no pixels (i.e. either its horizontal dimension or its vertical dimension is zero)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //    then return the string "data:,". (This is the shortest data: URL; it represents the empty string in a text/plain resource.)
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 23:47:29 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! m_bitmap ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 15:58:55 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  " data:, " _string ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:12:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Let file be a serialization of this canvas element's bitmap as a file, passing type and quality if given.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  file  =  serialize_bitmap ( * m_bitmap ,  type ,  move ( quality ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. If file is null then return "data:,".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( file . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        dbgln ( " HTMLCanvasElement: Failed to encode canvas bitmap to {}: {} " ,  type ,  file . error ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 15:58:55 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  " data:, " _string ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-05 20:34:27 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 10:12:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Return a data: URL representing file. [RFC2397]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  base64_encoded_or_error  =  encode_base64 ( file . value ( ) . buffer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-19 00:23:47 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( base64_encoded_or_error . is_error ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 15:58:55 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  " data:, " _string ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-19 00:23:47 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 15:58:55 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  MUST ( AK : : URL : : create_with_data ( file . value ( ) . mime_type ,  base64_encoded_or_error . release_value ( ) ,  true ) . to_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 23:47:29 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 01:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// https://html.spec.whatwg.org/multipage/canvas.html#dom-canvas-toblob
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-03 15:58:55 +12:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								WebIDL : : ExceptionOr < void >  HTMLCanvasElement : : to_blob ( JS : : NonnullGCPtr < WebIDL : : CallbackType >  callback ,  StringView  type ,  Optional < double >  quality ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 01:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-16 22:00:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // It is possible the the canvas doesn't have a associated bitmap so create one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! bitmap ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        create_bitmap ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 01:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // FIXME: 1. If this canvas element's bitmap's origin-clean flag is set to false, then throw a "SecurityError" DOMException.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Let result be null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    RefPtr < Gfx : : Bitmap >  bitmap_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. If this canvas element's bitmap has pixels (i.e., neither its horizontal dimension nor its vertical dimension is zero),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //    then set result to a copy of this canvas element's bitmap.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( m_bitmap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bitmap_result  =  TRY_OR_THROW_OOM ( vm ( ) ,  m_bitmap - > clone ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. Run these steps in parallel:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Platform : : EventLoopPlugin : : the ( ) . deferred_invoke ( [ this ,  callback ,  bitmap_result ,  type ,  quality ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 1. If result is non-null, then set result to a serialization of result as a file with type and quality if given.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        Optional < SerializeBitmapResult >  file_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( bitmap_result )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( auto  result  =  serialize_bitmap ( * bitmap_result ,  type ,  move ( quality ) ) ;  ! result . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                file_result  =  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 2. Queue an element task on the canvas blob serialization task source given the canvas element to run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        queue_an_element_task ( Task : : Source : : CanvasBlobSerializationTask ,  [ this ,  callback ,  file_result  =  move ( file_result ) ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  maybe_error  =  Bindings : : throw_dom_exception_if_needed ( vm ( ) ,  [ & ] ( )  - >  WebIDL : : ExceptionOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // 1. If result is non-null, then set result to a new Blob object, created in the relevant realm of this canvas element, representing result. [FILEAPI]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                JS : : GCPtr < FileAPI : : Blob >  blob_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( file_result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-13 13:05:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    blob_result  =  FileAPI : : Blob : : create ( realm ( ) ,  file_result - > buffer ,  TRY_OR_THROW_OOM ( vm ( ) ,  String : : from_utf8 ( file_result - > mime_type ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-03 01:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // 2. Invoke callback with « result ».
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                TRY ( WebIDL : : invoke_callback ( * callback ,  { } ,  move ( blob_result ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( maybe_error . is_throw_completion ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                report_exception ( maybe_error . throw_completion ( ) ,  realm ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  HTMLCanvasElement : : present ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_context . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        [ ] ( JS : : NonnullGCPtr < CanvasRenderingContext2D > & )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            // Do nothing, CRC2D writes directly to the canvas bitmap.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 15:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        [ ] ( JS : : NonnullGCPtr < WebGL : : WebGLRenderingContext > &  context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-04 04:22:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            context - > present ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ ] ( Empty )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // Do nothing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 19:07:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}