/src/serenity/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org> |
3 | | * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org> |
4 | | * |
5 | | * SPDX-License-Identifier: BSD-2-Clause |
6 | | */ |
7 | | |
8 | | #pragma once |
9 | | |
10 | | #include <AK/String.h> |
11 | | #include <AK/Variant.h> |
12 | | #include <LibGfx/AffineTransform.h> |
13 | | #include <LibGfx/AntiAliasingPainter.h> |
14 | | #include <LibGfx/Color.h> |
15 | | #include <LibGfx/Forward.h> |
16 | | #include <LibGfx/Path.h> |
17 | | #include <LibGfx/PathClipper.h> |
18 | | #include <LibWeb/Bindings/PlatformObject.h> |
19 | | #include <LibWeb/HTML/Canvas/CanvasCompositing.h> |
20 | | #include <LibWeb/HTML/Canvas/CanvasDrawImage.h> |
21 | | #include <LibWeb/HTML/Canvas/CanvasDrawPath.h> |
22 | | #include <LibWeb/HTML/Canvas/CanvasFillStrokeStyles.h> |
23 | | #include <LibWeb/HTML/Canvas/CanvasImageData.h> |
24 | | #include <LibWeb/HTML/Canvas/CanvasImageSmoothing.h> |
25 | | #include <LibWeb/HTML/Canvas/CanvasPath.h> |
26 | | #include <LibWeb/HTML/Canvas/CanvasPathDrawingStyles.h> |
27 | | #include <LibWeb/HTML/Canvas/CanvasRect.h> |
28 | | #include <LibWeb/HTML/Canvas/CanvasState.h> |
29 | | #include <LibWeb/HTML/Canvas/CanvasText.h> |
30 | | #include <LibWeb/HTML/Canvas/CanvasTextDrawingStyles.h> |
31 | | #include <LibWeb/HTML/Canvas/CanvasTransform.h> |
32 | | #include <LibWeb/HTML/CanvasGradient.h> |
33 | | #include <LibWeb/Layout/InlineNode.h> |
34 | | #include <LibWeb/Layout/LineBox.h> |
35 | | #include <LibWeb/WebIDL/ExceptionOr.h> |
36 | | |
37 | | namespace Web::HTML { |
38 | | |
39 | | class CanvasRenderingContext2D |
40 | | : public Bindings::PlatformObject |
41 | | , public CanvasPath |
42 | | , public CanvasState |
43 | | , public CanvasTransform<CanvasRenderingContext2D> |
44 | | , public CanvasFillStrokeStyles<CanvasRenderingContext2D> |
45 | | , public CanvasRect |
46 | | , public CanvasDrawPath |
47 | | , public CanvasText |
48 | | , public CanvasDrawImage |
49 | | , public CanvasImageData |
50 | | , public CanvasImageSmoothing |
51 | | , public CanvasCompositing |
52 | | , public CanvasPathDrawingStyles<CanvasRenderingContext2D> |
53 | | , public CanvasTextDrawingStyles<CanvasRenderingContext2D> { |
54 | | |
55 | | WEB_PLATFORM_OBJECT(CanvasRenderingContext2D, Bindings::PlatformObject); |
56 | | JS_DECLARE_ALLOCATOR(CanvasRenderingContext2D); |
57 | | |
58 | | public: |
59 | | [[nodiscard]] static JS::NonnullGCPtr<CanvasRenderingContext2D> create(JS::Realm&, HTMLCanvasElement&); |
60 | | virtual ~CanvasRenderingContext2D() override; |
61 | | |
62 | | virtual void fill_rect(float x, float y, float width, float height) override; |
63 | | virtual void stroke_rect(float x, float y, float width, float height) override; |
64 | | virtual void clear_rect(float x, float y, float width, float height) override; |
65 | | |
66 | | virtual WebIDL::ExceptionOr<void> draw_image_internal(CanvasImageSource const&, float source_x, float source_y, float source_width, float source_height, float destination_x, float destination_y, float destination_width, float destination_height) override; |
67 | | |
68 | | virtual void begin_path() override; |
69 | | virtual void stroke() override; |
70 | | virtual void stroke(Path2D const& path) override; |
71 | | |
72 | | virtual void fill_text(StringView, float x, float y, Optional<double> max_width) override; |
73 | | virtual void stroke_text(StringView, float x, float y, Optional<double> max_width) override; |
74 | | |
75 | | virtual void fill(StringView fill_rule) override; |
76 | | virtual void fill(Path2D& path, StringView fill_rule) override; |
77 | | |
78 | | virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<ImageData>> create_image_data(int width, int height, Optional<ImageDataSettings> const& settings = {}) const override; |
79 | | virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<ImageData>> create_image_data(ImageData const& image_data) const override; |
80 | | virtual WebIDL::ExceptionOr<JS::GCPtr<ImageData>> get_image_data(int x, int y, int width, int height, Optional<ImageDataSettings> const& settings = {}) const override; |
81 | | virtual void put_image_data(ImageData const&, float x, float y) override; |
82 | | |
83 | | virtual void reset_to_default_state() override; |
84 | | |
85 | | JS::NonnullGCPtr<HTMLCanvasElement> canvas_for_binding() const; |
86 | | |
87 | | virtual JS::NonnullGCPtr<TextMetrics> measure_text(StringView text) override; |
88 | | |
89 | | virtual void clip(StringView fill_rule) override; |
90 | | virtual void clip(Path2D& path, StringView fill_rule) override; |
91 | | |
92 | | virtual bool image_smoothing_enabled() const override; |
93 | | virtual void set_image_smoothing_enabled(bool) override; |
94 | | virtual Bindings::ImageSmoothingQuality image_smoothing_quality() const override; |
95 | | virtual void set_image_smoothing_quality(Bindings::ImageSmoothingQuality) override; |
96 | | |
97 | | virtual float global_alpha() const override; |
98 | | virtual void set_global_alpha(float) override; |
99 | | |
100 | | HTMLCanvasElement& canvas_element(); |
101 | | HTMLCanvasElement const& canvas_element() const; |
102 | | |
103 | | private: |
104 | | explicit CanvasRenderingContext2D(JS::Realm&, HTMLCanvasElement&); |
105 | | |
106 | | virtual void initialize(JS::Realm&) override; |
107 | | virtual void visit_edges(Cell::Visitor&) override; |
108 | | |
109 | | struct PreparedTextGlyph { |
110 | | String glyph; |
111 | | Gfx::IntPoint position; |
112 | | }; |
113 | | |
114 | | struct PreparedText { |
115 | | Vector<PreparedTextGlyph> glyphs; |
116 | | Gfx::TextAlignment physical_alignment; |
117 | | Gfx::IntRect bounding_box; |
118 | | }; |
119 | | |
120 | | void did_draw(Gfx::FloatRect const&); |
121 | | |
122 | | template<typename TDrawFunction> |
123 | | void draw_clipped(TDrawFunction draw_function) |
124 | 0 | { |
125 | 0 | auto painter = this->antialiased_painter(); |
126 | 0 | if (!painter.has_value()) |
127 | 0 | return; |
128 | 0 | Gfx::ScopedPathClip clipper(painter->underlying_painter(), drawing_state().clip); |
129 | 0 | auto draw_rect = draw_function(*painter); |
130 | 0 | if (drawing_state().clip.has_value()) |
131 | 0 | draw_rect.intersect(drawing_state().clip->path.bounding_box()); |
132 | 0 | did_draw(draw_rect); |
133 | 0 | } Unexecuted instantiation: CanvasRenderingContext2D.cpp:void Web::HTML::CanvasRenderingContext2D::draw_clipped<Web::HTML::CanvasRenderingContext2D::clear_rect(float, float, float, float)::$_0>(Web::HTML::CanvasRenderingContext2D::clear_rect(float, float, float, float)::$_0) Unexecuted instantiation: CanvasRenderingContext2D.cpp:void Web::HTML::CanvasRenderingContext2D::draw_clipped<Web::HTML::CanvasRenderingContext2D::draw_image_internal(AK::Variant<JS::Handle<Web::HTML::HTMLImageElement>, JS::Handle<Web::SVG::SVGImageElement>, JS::Handle<Web::HTML::HTMLCanvasElement>, JS::Handle<Web::HTML::ImageBitmap>, JS::Handle<Web::HTML::HTMLVideoElement> > const&, float, float, float, float, float, float, float, float)::$_1>(Web::HTML::CanvasRenderingContext2D::draw_image_internal(AK::Variant<JS::Handle<Web::HTML::HTMLImageElement>, JS::Handle<Web::SVG::SVGImageElement>, JS::Handle<Web::HTML::HTMLCanvasElement>, JS::Handle<Web::HTML::ImageBitmap>, JS::Handle<Web::HTML::HTMLVideoElement> > const&, float, float, float, float, float, float, float, float)::$_1) Unexecuted instantiation: CanvasRenderingContext2D.cpp:void Web::HTML::CanvasRenderingContext2D::draw_clipped<Web::HTML::CanvasRenderingContext2D::bitmap_font_fill_text(AK::StringView, float, float, AK::Optional<double>)::$_0>(Web::HTML::CanvasRenderingContext2D::bitmap_font_fill_text(AK::StringView, float, float, AK::Optional<double>)::$_0) Unexecuted instantiation: CanvasRenderingContext2D.cpp:void Web::HTML::CanvasRenderingContext2D::draw_clipped<Web::HTML::CanvasRenderingContext2D::stroke_internal(Gfx::Path const&)::$_0>(Web::HTML::CanvasRenderingContext2D::stroke_internal(Gfx::Path const&)::$_0) Unexecuted instantiation: CanvasRenderingContext2D.cpp:void Web::HTML::CanvasRenderingContext2D::draw_clipped<Web::HTML::CanvasRenderingContext2D::fill_internal(Gfx::Path const&, Gfx::WindingRule)::$_0>(Web::HTML::CanvasRenderingContext2D::fill_internal(Gfx::Path const&, Gfx::WindingRule)::$_0) Unexecuted instantiation: CanvasRenderingContext2D.cpp:void Web::HTML::CanvasRenderingContext2D::draw_clipped<Web::HTML::CanvasRenderingContext2D::put_image_data(Web::HTML::ImageData const&, float, float)::$_0>(Web::HTML::CanvasRenderingContext2D::put_image_data(Web::HTML::ImageData const&, float, float)::$_0) |
134 | | |
135 | | RefPtr<Gfx::Font const> current_font(); |
136 | | |
137 | | PreparedText prepare_text(ByteString const& text, float max_width = INFINITY); |
138 | | |
139 | | Gfx::Painter* painter(); |
140 | | Optional<Gfx::AntiAliasingPainter> antialiased_painter(); |
141 | | |
142 | | Gfx::Path rect_path(float x, float y, float width, float height); |
143 | | |
144 | | Gfx::Path text_path(StringView text, float x, float y, Optional<double> max_width); |
145 | | void bitmap_font_fill_text(StringView text, float x, float y, Optional<double> max_width); |
146 | | |
147 | | void stroke_internal(Gfx::Path const&); |
148 | | void fill_internal(Gfx::Path const&, Gfx::WindingRule); |
149 | | void clip_internal(Gfx::Path&, Gfx::WindingRule); |
150 | | |
151 | | JS::NonnullGCPtr<HTMLCanvasElement> m_element; |
152 | | OwnPtr<Gfx::Painter> m_painter; |
153 | | |
154 | | // https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-origin-clean |
155 | | bool m_origin_clean { true }; |
156 | | }; |
157 | | |
158 | | enum class CanvasImageSourceUsability { |
159 | | Bad, |
160 | | Good, |
161 | | }; |
162 | | |
163 | | WebIDL::ExceptionOr<CanvasImageSourceUsability> check_usability_of_image(CanvasImageSource const&); |
164 | | bool image_is_not_origin_clean(CanvasImageSource const&); |
165 | | |
166 | | } |