2022-08-12 15:46:31 +01:00
/*
* Copyright ( c ) 2020 - 2022 , Andreas Kling < kling @ serenityos . org >
* 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>
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 ;
2023-09-06 19:41:48 +12:00
using FillOrStrokeStyleVariant = Variant < String , JS : : Handle < CanvasGradient > , JS : : Handle < CanvasPattern > > ;
2022-08-12 15:46:31 +01:00
2023-02-02 20:41:03 +00:00
static CanvasState : : FillOrStrokeStyle to_canvas_state_fill_or_stroke_style ( auto const & style )
2023-01-18 20:10:00 +01:00
{
return style . visit (
2023-09-06 19:41:48 +12:00
[ & ] ( String const & string ) - > CanvasState : : FillOrStrokeStyle {
2023-11-18 21:08:25 +11:00
// FIXME: This should parse color strings the same as CSS
auto color = Gfx : : Color : : from_string ( string ) ;
if ( ! color . has_value ( ) )
dbgln_if ( CANVAS_RENDERING_CONTEXT_2D_DEBUG , " CanvasFillStrokeStyles: Unsupported canvas fill or stroke style \" {} \" . Defaulting to Color::Black. " , string ) ;
return color . value_or ( Color : : Black ) ;
2023-01-18 20:10:00 +01:00
} ,
2023-02-02 20:41:03 +00:00
[ & ] ( auto fill_or_stroke_style ) - > CanvasState : : FillOrStrokeStyle {
return fill_or_stroke_style ;
2023-01-18 20:10:00 +01:00
} ) ;
}
void set_fill_style ( FillOrStrokeStyleVariant style )
2022-08-12 15:46:31 +01:00
{
// 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-02-02 20:41:03 +00:00
my_drawing_state ( ) . fill_style = to_canvas_state_fill_or_stroke_style ( 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
{
// 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-02-02 20:41:03 +00:00
my_drawing_state ( ) . stroke_style = to_canvas_state_fill_or_stroke_style ( 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
}
2023-01-28 00:05:10 +00:00
WebIDL : : ExceptionOr < JS : : NonnullGCPtr < 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
}
2022-09-02 23:17:45 +02:00
JS : : NonnullGCPtr < 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
}
2022-09-02 23:17:45 +02:00
JS : : NonnullGCPtr < 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
}
2023-02-02 20:47:46 +00:00
WebIDL : : ExceptionOr < JS : : GCPtr < CanvasPattern > > create_pattern ( CanvasImageSource const & image , StringView repetition )
{
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 ( ) ; }
} ;
}