mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-27 10:07:15 +02:00
Previously, the LibWeb bindings generator would output multiple per interface files like Prototype/Constructor/Namespace/GlobalMixin depending on the contents of that IDL file. This complicates the build system as it means that it does not know what files will be generated without knowledge of the contents of that IDL file. Instead, for each IDL file only generate a single Bindings/<IDLFile>.h and Bindings/<IDLFile>.cpp.
150 lines
5.0 KiB
C++
150 lines
5.0 KiB
C++
/*
|
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
|
* Copyright (c) 2023, MacDue <macdue@dueutil.tech>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Variant.h>
|
|
#include <AK/Vector.h>
|
|
#include <LibGfx/AffineTransform.h>
|
|
#include <LibGfx/Color.h>
|
|
#include <LibGfx/CompositingAndBlendingOperator.h>
|
|
#include <LibGfx/Filter.h>
|
|
#include <LibGfx/FontCascadeList.h>
|
|
#include <LibGfx/PaintStyle.h>
|
|
#include <LibWeb/Bindings/CanvasRenderingContext2D.h>
|
|
#include <LibWeb/CSS/Length.h>
|
|
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
|
#include <LibWeb/HTML/CanvasGradient.h>
|
|
#include <LibWeb/HTML/CanvasPattern.h>
|
|
|
|
namespace Web::HTML {
|
|
|
|
// https://html.spec.whatwg.org/multipage/canvas.html#canvasstate
|
|
class CanvasState {
|
|
public:
|
|
virtual ~CanvasState() = default;
|
|
|
|
virtual Gfx::Painter* painter_for_canvas_state() = 0;
|
|
virtual Gfx::Path& path_for_canvas_state() = 0;
|
|
|
|
void save();
|
|
void restore();
|
|
void reset();
|
|
bool is_context_lost();
|
|
|
|
using FillOrStrokeVariant = Variant<Gfx::Color, GC::Ref<CanvasGradient>, GC::Ref<CanvasPattern>>;
|
|
|
|
struct FillOrStrokeStyle {
|
|
FillOrStrokeStyle(Gfx::Color color)
|
|
: m_fill_or_stroke_style(color)
|
|
{
|
|
}
|
|
|
|
FillOrStrokeStyle(GC::Ref<CanvasGradient> gradient)
|
|
: m_fill_or_stroke_style(gradient)
|
|
{
|
|
}
|
|
|
|
FillOrStrokeStyle(GC::Ref<CanvasPattern> pattern)
|
|
: m_fill_or_stroke_style(pattern)
|
|
{
|
|
}
|
|
|
|
NonnullRefPtr<Gfx::PaintStyle> to_gfx_paint_style();
|
|
|
|
Optional<Gfx::Color> as_color() const;
|
|
Gfx::Color to_color_but_fixme_should_accept_any_paint_style() const;
|
|
|
|
using JsFillOrStrokeStyle = Variant<String, GC::Root<CanvasGradient>, GC::Root<CanvasPattern>>;
|
|
|
|
JsFillOrStrokeStyle to_js_fill_or_stroke_style() const
|
|
{
|
|
return m_fill_or_stroke_style.visit(
|
|
[&](Gfx::Color color) -> JsFillOrStrokeStyle {
|
|
return color.to_string(Gfx::Color::HTMLCompatibleSerialization::Yes);
|
|
},
|
|
[&](auto handle) -> JsFillOrStrokeStyle {
|
|
return GC::make_root(handle);
|
|
});
|
|
}
|
|
|
|
void visit_edges(GC::Cell::Visitor& visitor)
|
|
{
|
|
m_fill_or_stroke_style.visit([&](Gfx::Color) {},
|
|
[&](auto& handle) {
|
|
visitor.visit(handle);
|
|
});
|
|
}
|
|
|
|
private:
|
|
FillOrStrokeVariant m_fill_or_stroke_style;
|
|
RefPtr<Gfx::PaintStyle> m_color_paint_style { nullptr };
|
|
};
|
|
|
|
// https://html.spec.whatwg.org/multipage/canvas.html#drawing-state
|
|
struct DrawingState {
|
|
Gfx::AffineTransform transform;
|
|
FillOrStrokeStyle fill_style { Gfx::Color::Black };
|
|
FillOrStrokeStyle stroke_style { Gfx::Color::Black };
|
|
float shadow_offset_x { 0.0f };
|
|
float shadow_offset_y { 0.0f };
|
|
float shadow_blur { 0.0f };
|
|
Gfx::Color shadow_color { Gfx::Color::Transparent };
|
|
Optional<Gfx::Filter> filter;
|
|
Optional<String> filter_string;
|
|
float line_width { 1 };
|
|
Bindings::CanvasLineCap line_cap { Bindings::CanvasLineCap::Butt };
|
|
Bindings::CanvasLineJoin line_join { Bindings::CanvasLineJoin::Miter };
|
|
float miter_limit { 10 };
|
|
Vector<double> dash_list;
|
|
float line_dash_offset { 0 };
|
|
bool image_smoothing_enabled { true };
|
|
Bindings::ImageSmoothingQuality image_smoothing_quality { Bindings::ImageSmoothingQuality::Low };
|
|
float global_alpha = { 1 };
|
|
Gfx::CompositingAndBlendingOperator current_compositing_and_blending_operator = Gfx::CompositingAndBlendingOperator::SourceOver;
|
|
RefPtr<CSS::StyleValue const> font_style_value { nullptr };
|
|
RefPtr<Gfx::FontCascadeList const> current_font_cascade_list { nullptr };
|
|
Bindings::CanvasTextAlign text_align { Bindings::CanvasTextAlign::Start };
|
|
Bindings::CanvasTextBaseline text_baseline { Bindings::CanvasTextBaseline::Alphabetic };
|
|
Bindings::CanvasDirection direction { Bindings::CanvasDirection::Inherit };
|
|
CSS::Length letter_spacing { CSS::Length::make_px(0) };
|
|
|
|
void visit_edges(GC::Cell::Visitor& visitor)
|
|
{
|
|
fill_style.visit_edges(visitor);
|
|
stroke_style.visit_edges(visitor);
|
|
}
|
|
};
|
|
DrawingState& drawing_state() { return m_drawing_state; }
|
|
DrawingState const& drawing_state() const { return m_drawing_state; }
|
|
|
|
void clear_drawing_state_stack() { m_drawing_state_stack.clear(); }
|
|
void reset_drawing_state() { m_drawing_state = {}; }
|
|
|
|
virtual void reset_to_default_state() = 0;
|
|
|
|
void visit_edges(GC::Cell::Visitor& visitor)
|
|
{
|
|
m_drawing_state.visit_edges(visitor);
|
|
for (auto& state : m_drawing_state_stack) {
|
|
state.visit_edges(visitor);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
CanvasState() = default;
|
|
|
|
private:
|
|
DrawingState m_drawing_state;
|
|
Vector<DrawingState> m_drawing_state_stack;
|
|
|
|
// https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-context-lost
|
|
bool m_context_lost { false };
|
|
};
|
|
|
|
}
|