/* * Copyright (c) 2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace Web::SVG { class SVGDecodedImageData final : public HTML::DecodedImageData { GC_CELL(SVGDecodedImageData, HTML::DecodedImageData); GC_DECLARE_ALLOCATOR(SVGDecodedImageData); public: class SVGPageClient; static ErrorOr> create(JS::Realm&, GC::Ref, 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(GC::Ref, GC::Ref, GC::Ref, GC::Ref); RefPtr render(Gfx::IntSize) const; mutable HashMap> m_cached_rendered_bitmaps; GC::Ref m_page; GC::Ref m_page_client; GC::Ref m_document; GC::Ref m_root_element; }; class SVGDecodedImageData::SVGPageClient final : public PageClient { GC_CELL(SVGDecodedImageData::SVGPageClient, PageClient); GC_DECLARE_ALLOCATOR(SVGDecodedImageData::SVGPageClient); public: static GC::Ref create(JS::VM& vm, Page& page) { return vm.heap().allocate(page); } virtual ~SVGPageClient() override = default; GC::Ref m_host_page; GC::Ptr 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 CSS::PreferredContrast preferred_contrast() const override { return m_host_page->client().preferred_contrast(); } virtual CSS::PreferredMotion preferred_motion() const override { return m_host_page->client().preferred_motion(); } virtual void request_file(FileRequest) override { } virtual void paint_next_frame() override { } virtual void process_screenshot_requests() override { } virtual void paint(DevicePixelRect const&, Painting::BackingStore&, Web::PaintOptions = {}) override { } virtual bool is_ready_to_paint() const override { return true; } virtual DisplayListPlayerType display_list_player_type() const override { return m_host_page->client().display_list_player_type(); } private: explicit SVGPageClient(Page& host_page) : m_host_page(host_page) { } virtual void visit_edges(Visitor&) override; }; }