| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-10-04 13:19:50 +02:00
										 |  |  |  * Copyright (c) 2020-2022, Andreas Kling <andreas@ladybird.org> | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |  * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org> | 
					
						
							|  |  |  |  * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> | 
					
						
							| 
									
										
										
										
											2023-01-18 20:10:00 +01:00
										 |  |  |  * Copyright (c) 2023, MacDue <macdue@dueutil.tech> | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-06 19:41:48 +12:00
										 |  |  | #include <AK/String.h>
 | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  | #include <LibWeb/CSS/Parser/Parser.h>
 | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  | #include <LibWeb/HTML/Canvas/CanvasState.h>
 | 
					
						
							| 
									
										
										
										
											2022-08-12 17:52:43 +01:00
										 |  |  | #include <LibWeb/HTML/CanvasGradient.h>
 | 
					
						
							| 
									
										
										
										
											2023-02-02 20:47:46 +00:00
										 |  |  | #include <LibWeb/HTML/CanvasPattern.h>
 | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Web::HTML { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // https://html.spec.whatwg.org/multipage/canvas.html#canvasfillstrokestyles
 | 
					
						
							|  |  |  | template<typename IncludingClass> | 
					
						
							|  |  |  | class CanvasFillStrokeStyles { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     ~CanvasFillStrokeStyles() = default; | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |     using FillOrStrokeStyleVariant = Variant<String, GC::Root<CanvasGradient>, GC::Root<CanvasPattern>>; | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |     void set_fill_style(FillOrStrokeStyleVariant style) | 
					
						
							| 
									
										
										
										
											2023-01-18 20:10:00 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |         // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fillstyle
 | 
					
						
							|  |  |  |         style.visit( | 
					
						
							|  |  |  |             // 1. If the given value is a string, then:
 | 
					
						
							|  |  |  |             [&](String const& string) { | 
					
						
							|  |  |  |                 // 1. Let context be this's canvas attribute's value, if that is an element; otherwise null.
 | 
					
						
							| 
									
										
										
										
											2023-11-18 21:08:25 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |                 // 2. Let parsedValue be the result of parsing the given value with context if non-null.
 | 
					
						
							|  |  |  |                 // FIXME: Parse a color value
 | 
					
						
							|  |  |  |                 // https://drafts.csswg.org/css-color/#parse-a-css-color-value
 | 
					
						
							| 
									
										
										
										
											2024-12-05 11:52:43 +00:00
										 |  |  |                 auto style_value = parse_css_value(CSS::Parser::ParsingContext(), string, CSS::PropertyID::Color); | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |                 if (style_value && style_value->has_color()) { | 
					
						
							|  |  |  |                     auto parsedValue = style_value->to_color(OptionalNone()); | 
					
						
							| 
									
										
										
										
											2023-11-18 21:08:25 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |                     // 4. Set this's fill style to parsedValue.
 | 
					
						
							|  |  |  |                     my_drawing_state().fill_style = parsedValue; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     // 3. If parsedValue is failure, then return.
 | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // 5. Return.
 | 
					
						
							|  |  |  |                 return; | 
					
						
							| 
									
										
										
										
											2023-01-18 20:10:00 +01:00
										 |  |  |             }, | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |             [&](auto fill_or_stroke_style) { | 
					
						
							|  |  |  |                 // FIXME: 2. If the given value is a CanvasPattern object that is marked as not origin-clean, then set this's origin-clean flag to false.
 | 
					
						
							| 
									
										
										
										
											2023-01-18 20:10:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |                 // 3. Set this's fill style to the given value.
 | 
					
						
							|  |  |  |                 my_drawing_state().fill_style = fill_or_stroke_style; | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-18 20:10:00 +01:00
										 |  |  |     FillOrStrokeStyleVariant fill_style() const | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-02-02 20:41:03 +00:00
										 |  |  |         return my_drawing_state().fill_style.to_js_fill_or_stroke_style(); | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-18 20:10:00 +01:00
										 |  |  |     void set_stroke_style(FillOrStrokeStyleVariant style) | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |         // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-strokestyle
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         style.visit( | 
					
						
							|  |  |  |             // 1. If the given value is a string, then:
 | 
					
						
							|  |  |  |             [&](String const& string) { | 
					
						
							|  |  |  |                 // 1. Let context be this's canvas attribute's value, if that is an element; otherwise null.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // 2. Let parsedValue be the result of parsing the given value with context if non-null.
 | 
					
						
							|  |  |  |                 // FIXME: Parse a color value
 | 
					
						
							|  |  |  |                 // https://drafts.csswg.org/css-color/#parse-a-css-color-value
 | 
					
						
							| 
									
										
										
										
											2024-12-05 11:52:43 +00:00
										 |  |  |                 auto style_value = parse_css_value(CSS::Parser::ParsingContext(), string, CSS::PropertyID::Color); | 
					
						
							| 
									
										
										
										
											2024-07-22 18:59:29 -07:00
										 |  |  |                 if (style_value && style_value->has_color()) { | 
					
						
							|  |  |  |                     auto parsedValue = style_value->to_color(OptionalNone()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     // 4. Set this's stroke style to parsedValue.
 | 
					
						
							|  |  |  |                     my_drawing_state().stroke_style = parsedValue; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     // 3. If parsedValue is failure, then return.
 | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // 5. Return.
 | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             [&](auto fill_or_stroke_style) { | 
					
						
							|  |  |  |                 // FIXME: 2. If the given value is a CanvasPattern object that is marked as not origin-clean, then set this's origin-clean flag to false.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // 3. Set this's stroke style to the given value.
 | 
					
						
							|  |  |  |                 my_drawing_state().fill_style = fill_or_stroke_style; | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-18 20:10:00 +01:00
										 |  |  |     FillOrStrokeStyleVariant stroke_style() const | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-02-02 20:41:03 +00:00
										 |  |  |         return my_drawing_state().stroke_style.to_js_fill_or_stroke_style(); | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |     WebIDL::ExceptionOr<GC::Ref<CanvasGradient>> create_radial_gradient(double x0, double y0, double r0, double x1, double y1, double r1) | 
					
						
							| 
									
										
										
										
											2022-08-12 17:52:43 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-25 16:38:21 -06:00
										 |  |  |         auto& realm = static_cast<IncludingClass&>(*this).realm(); | 
					
						
							|  |  |  |         return CanvasGradient::create_radial(realm, x0, y0, r0, x1, y1, r1); | 
					
						
							| 
									
										
										
										
											2022-08-12 17:52:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |     GC::Ref<CanvasGradient> create_linear_gradient(double x0, double y0, double x1, double y1) | 
					
						
							| 
									
										
										
										
											2022-08-12 17:52:43 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-25 16:38:21 -06:00
										 |  |  |         auto& realm = static_cast<IncludingClass&>(*this).realm(); | 
					
						
							| 
									
										
										
										
											2023-02-15 08:46:39 +01:00
										 |  |  |         return CanvasGradient::create_linear(realm, x0, y0, x1, y1).release_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2022-08-12 17:52:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |     GC::Ref<CanvasGradient> create_conic_gradient(double start_angle, double x, double y) | 
					
						
							| 
									
										
										
										
											2022-08-12 17:52:43 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-25 16:38:21 -06:00
										 |  |  |         auto& realm = static_cast<IncludingClass&>(*this).realm(); | 
					
						
							| 
									
										
										
										
											2023-02-15 08:46:39 +01:00
										 |  |  |         return CanvasGradient::create_conic(realm, start_angle, x, y).release_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2022-08-12 17:52:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |     WebIDL::ExceptionOr<GC::Ptr<CanvasPattern>> create_pattern(CanvasImageSource const& image, StringView repetition) | 
					
						
							| 
									
										
										
										
											2023-02-02 20:47:46 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         auto& realm = static_cast<IncludingClass&>(*this).realm(); | 
					
						
							|  |  |  |         return CanvasPattern::create(realm, image, repetition); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 15:46:31 +01:00
										 |  |  | protected: | 
					
						
							|  |  |  |     CanvasFillStrokeStyles() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     CanvasState::DrawingState& my_drawing_state() { return reinterpret_cast<IncludingClass&>(*this).drawing_state(); } | 
					
						
							|  |  |  |     CanvasState::DrawingState const& my_drawing_state() const { return reinterpret_cast<IncludingClass const&>(*this).drawing_state(); } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |