/* * Copyright (c) 2020-2024, Andreas Kling * Copyright (c) 2021-2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Web::HTML { class CanvasRenderingContext2D : public Bindings::PlatformObject , public CanvasPath , public CanvasState , public CanvasTransform , public CanvasFillStrokeStyles , public CanvasShadowStyles , public CanvasFilters , public CanvasRect , public CanvasDrawPath , public CanvasText , public CanvasDrawImage , public CanvasImageData , public CanvasImageSmoothing , public CanvasCompositing , public CanvasPathDrawingStyles , public CanvasTextDrawingStyles { WEB_PLATFORM_OBJECT(CanvasRenderingContext2D, Bindings::PlatformObject); GC_DECLARE_ALLOCATOR(CanvasRenderingContext2D); public: [[nodiscard]] static GC::Ref create(JS::Realm&, HTMLCanvasElement&); virtual ~CanvasRenderingContext2D() override; virtual void fill_rect(float x, float y, float width, float height) override; virtual void stroke_rect(float x, float y, float width, float height) override; virtual void clear_rect(float x, float y, float width, float height) override; virtual WebIDL::ExceptionOr 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; virtual void begin_path() override; virtual void stroke() override; virtual void stroke(Path2D const& path) override; virtual void fill_text(StringView, float x, float y, Optional max_width) override; virtual void stroke_text(StringView, float x, float y, Optional max_width) override; virtual void fill(StringView fill_rule) override; virtual void fill(Path2D& path, StringView fill_rule) override; virtual WebIDL::ExceptionOr> create_image_data(int width, int height, Optional const& settings = {}) const override; virtual WebIDL::ExceptionOr> create_image_data(ImageData const& image_data) const override; virtual WebIDL::ExceptionOr> get_image_data(int x, int y, int width, int height, Optional const& settings = {}) const override; virtual void put_image_data(ImageData const&, float x, float y) override; virtual void reset_to_default_state() override; GC::Ref canvas_for_binding() const; virtual GC::Ref measure_text(StringView text) override; virtual void clip(StringView fill_rule) override; virtual void clip(Path2D& path, StringView fill_rule) override; virtual bool is_point_in_path(double x, double y, StringView fill_rule) override; virtual bool is_point_in_path(Path2D const& path, double x, double y, StringView fill_rule) override; virtual bool image_smoothing_enabled() const override; virtual void set_image_smoothing_enabled(bool) override; virtual Bindings::ImageSmoothingQuality image_smoothing_quality() const override; virtual void set_image_smoothing_quality(Bindings::ImageSmoothingQuality) override; virtual float global_alpha() const override; virtual void set_global_alpha(float) override; virtual String filter() const override; virtual void set_filter(String) override; virtual float shadow_offset_x() const override; virtual void set_shadow_offset_x(float) override; virtual float shadow_offset_y() const override; virtual void set_shadow_offset_y(float) override; virtual float shadow_blur() const override; virtual void set_shadow_blur(float) override; virtual String shadow_color() const override; virtual void set_shadow_color(String) override; HTMLCanvasElement& canvas_element(); HTMLCanvasElement const& canvas_element() const; [[nodiscard]] Gfx::Painter* painter(); void set_size(Gfx::IntSize const&); RefPtr surface() { return m_surface; } void allocate_painting_surface_if_needed(); private: explicit CanvasRenderingContext2D(JS::Realm&, HTMLCanvasElement&); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; virtual Gfx::Painter* painter_for_canvas_state() override { return painter(); } virtual Gfx::Path& path_for_canvas_state() override { return path(); } struct PreparedText { RefPtr glyph_run; Gfx::TextAlignment physical_alignment; Gfx::IntRect bounding_box; }; void did_draw(Gfx::FloatRect const&); RefPtr current_font(); PreparedText prepare_text(ByteString const& text, float max_width = INFINITY); [[nodiscard]] Gfx::Path rect_path(float x, float y, float width, float height); [[nodiscard]] Gfx::Path text_path(StringView text, float x, float y, Optional max_width); void stroke_internal(Gfx::Path const&); void fill_internal(Gfx::Path const&, Gfx::WindingRule); void clip_internal(Gfx::Path&, Gfx::WindingRule); void paint_shadow_for_fill_internal(Gfx::Path const&, Gfx::WindingRule); void paint_shadow_for_stroke_internal(Gfx::Path const&); GC::Ref m_element; OwnPtr m_painter; // https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-origin-clean bool m_origin_clean { true }; Gfx::IntSize m_size; RefPtr m_surface; }; enum class CanvasImageSourceUsability { Bad, Good, }; WebIDL::ExceptionOr check_usability_of_image(CanvasImageSource const&); bool image_is_not_origin_clean(CanvasImageSource const&); }