/* * Copyright (c) 2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include namespace Web::SVG { class SVGDecodedImageData final : public HTML::DecodedImageData { JS_CELL(SVGDecodedImageData, Cell); JS_DECLARE_ALLOCATOR(SVGDecodedImageData); public: class SVGPageClient; static ErrorOr> create(JS::Realm&, JS::NonnullGCPtr, URL::URL const&, ByteBuffer encoded_svg); virtual ~SVGDecodedImageData() override; virtual RefPtr bitmap(size_t frame_index, Gfx::IntSize) const override; virtual Optional intrinsic_width() const override; virtual Optional intrinsic_height() const override; virtual Optional intrinsic_aspect_ratio() const override; // FIXME: Support SVG animations. :^) virtual int frame_duration(size_t) const override { return 0; } virtual size_t frame_count() const override { return 1; } virtual size_t loop_count() const override { return 0; } virtual bool is_animated() const override { return false; } DOM::Document const& svg_document() const { return *m_document; } virtual void visit_edges(Cell::Visitor& visitor) override; private: SVGDecodedImageData(JS::NonnullGCPtr, JS::NonnullGCPtr, JS::NonnullGCPtr, JS::NonnullGCPtr); RefPtr render(Gfx::IntSize) const; mutable HashMap> m_cached_rendered_bitmaps; JS::NonnullGCPtr m_page; JS::NonnullGCPtr m_page_client; JS::NonnullGCPtr m_document; JS::NonnullGCPtr m_root_element; }; class SVGDecodedImageData::SVGPageClient final : public PageClient { JS_CELL(SVGDecodedImageData::SVGPageClient, PageClient); JS_DECLARE_ALLOCATOR(SVGDecodedImageData::SVGPageClient); public: static JS::NonnullGCPtr create(JS::VM& vm, Page& page) { return vm.heap().allocate_without_realm(page); } virtual ~SVGPageClient() override = default; JS::NonnullGCPtr m_host_page; JS::GCPtr m_svg_page; virtual Page& page() override { return *m_svg_page; } virtual Page const& page() const override { return *m_svg_page; } virtual bool is_connection_open() const override { return false; } virtual Gfx::Palette palette() const override { return m_host_page->client().palette(); } virtual DevicePixelRect screen_rect() const override { return {}; } virtual double device_pixels_per_css_pixel() const override { return 1.0; } virtual CSS::PreferredColorScheme preferred_color_scheme() const override { return m_host_page->client().preferred_color_scheme(); } virtual void request_file(FileRequest) override { } virtual void paint(DevicePixelRect const&, Gfx::Bitmap&, Web::PaintOptions = {}) override { } virtual void schedule_repaint() override { } virtual bool is_ready_to_paint() const override { return true; } private: explicit SVGPageClient(Page& host_page) : m_host_page(host_page) { } virtual void visit_edges(Visitor&) override; }; }