diff options
-rw-r--r-- | Libraries/LibWeb/DOM/HTMLImageElement.cpp | 44 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/HTMLImageElement.h | 5 | ||||
-rw-r--r-- | Libraries/LibWeb/Loader/ImageLoader.cpp | 38 | ||||
-rw-r--r-- | Libraries/LibWeb/Loader/ImageLoader.h | 8 |
4 files changed, 51 insertions, 44 deletions
diff --git a/Libraries/LibWeb/DOM/HTMLImageElement.cpp b/Libraries/LibWeb/DOM/HTMLImageElement.cpp index 096af7a834..91d48622d1 100644 --- a/Libraries/LibWeb/DOM/HTMLImageElement.cpp +++ b/Libraries/LibWeb/DOM/HTMLImageElement.cpp @@ -38,15 +38,8 @@ namespace Web { HTMLImageElement::HTMLImageElement(Document& document, const FlyString& tag_name) : HTMLElement(document, tag_name) - , m_timer(Core::Timer::construct()) { m_image_loader.on_load = [this] { - if (image_decoder() && image_decoder()->is_animated() && image_decoder()->frame_count() > 1) { - const auto& first_frame = image_decoder()->frame(0); - m_timer->set_interval(first_frame.duration); - m_timer->on_timeout = [this] { animate(); }; - m_timer->start(); - } this->document().update_layout(); dispatch_event(Event::create("load")); }; @@ -56,6 +49,11 @@ HTMLImageElement::HTMLImageElement(Document& document, const FlyString& tag_name this->document().update_layout(); dispatch_event(Event::create("error")); }; + + m_image_loader.on_animate = [this] { + if (layout_node()) + layout_node()->set_needs_display(); + }; } HTMLImageElement::~HTMLImageElement() @@ -70,31 +68,6 @@ void HTMLImageElement::parse_attribute(const FlyString& name, const String& valu m_image_loader.load(document().complete_url(value)); } -void HTMLImageElement::animate() -{ - if (!layout_node()) - return; - - auto* decoder = image_decoder(); - ASSERT(decoder); - - m_current_frame_index = (m_current_frame_index + 1) % decoder->frame_count(); - const auto& current_frame = decoder->frame(m_current_frame_index); - - if (current_frame.duration != m_timer->interval()) { - m_timer->restart(current_frame.duration); - } - - if (m_current_frame_index == decoder->frame_count() - 1) { - ++m_loops_completed; - if (m_loops_completed > 0 && m_loops_completed == decoder->loop_count()) { - m_timer->stop(); - } - } - - layout_node()->set_needs_display(); -} - RefPtr<LayoutNode> HTMLImageElement::create_layout_node(const StyleProperties* parent_style) const { auto style = document().style_resolver().resolve_style(*this, parent_style); @@ -111,12 +84,7 @@ const Gfx::ImageDecoder* HTMLImageElement::image_decoder() const const Gfx::Bitmap* HTMLImageElement::bitmap() const { - auto* decoder = image_decoder(); - if (!decoder) - return nullptr; - if (decoder->is_animated()) - return decoder->frame(m_current_frame_index).image; - return decoder->bitmap(); + return m_image_loader.bitmap(); } void HTMLImageElement::set_visible_in_viewport(Badge<LayoutDocument>, bool visible_in_viewport) diff --git a/Libraries/LibWeb/DOM/HTMLImageElement.h b/Libraries/LibWeb/DOM/HTMLImageElement.h index 6eae9d4874..aa14947f9e 100644 --- a/Libraries/LibWeb/DOM/HTMLImageElement.h +++ b/Libraries/LibWeb/DOM/HTMLImageElement.h @@ -28,7 +28,6 @@ #include <AK/ByteBuffer.h> #include <AK/OwnPtr.h> -#include <LibCore/Forward.h> #include <LibGfx/Forward.h> #include <LibWeb/DOM/HTMLElement.h> #include <LibWeb/Loader/ImageLoader.h> @@ -60,10 +59,6 @@ private: virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; ImageLoader m_image_loader; - - size_t m_current_frame_index { 0 }; - size_t m_loops_completed { 0 }; - NonnullRefPtr<Core::Timer> m_timer; }; template<> diff --git a/Libraries/LibWeb/Loader/ImageLoader.cpp b/Libraries/LibWeb/Loader/ImageLoader.cpp index df992e5483..e3e3502805 100644 --- a/Libraries/LibWeb/Loader/ImageLoader.cpp +++ b/Libraries/LibWeb/Loader/ImageLoader.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <LibCore/Timer.h> #include <LibGfx/Bitmap.h> #include <LibGfx/ImageDecoder.h> #include <LibWeb/Loader/ImageLoader.h> @@ -32,6 +33,7 @@ namespace Web { ImageLoader::ImageLoader() + : m_timer(Core::Timer::construct()) { } @@ -72,10 +74,40 @@ void ImageLoader::resource_did_load() } m_decoder = resource()->ensure_decoder(); + if (m_decoder->is_animated() && m_decoder->frame_count() > 1) { + const auto& first_frame = m_decoder->frame(0); + m_timer->set_interval(first_frame.duration); + m_timer->on_timeout = [this] { animate(); }; + m_timer->start(); + } + if (on_load) on_load(); } +void ImageLoader::animate() +{ + auto* decoder = image_decoder(); + ASSERT(decoder); + + m_current_frame_index = (m_current_frame_index + 1) % decoder->frame_count(); + const auto& current_frame = decoder->frame(m_current_frame_index); + + if (current_frame.duration != m_timer->interval()) { + m_timer->restart(current_frame.duration); + } + + if (m_current_frame_index == decoder->frame_count() - 1) { + ++m_loops_completed; + if (m_loops_completed > 0 && m_loops_completed == decoder->loop_count()) { + m_timer->stop(); + } + } + + if (on_animate) + on_animate(); +} + void ImageLoader::resource_did_fail() { dbg() << "ImageLoader: Resource did fail. URL: " << resource()->url(); @@ -90,7 +122,11 @@ void ImageLoader::resource_did_replace_decoder() const Gfx::Bitmap* ImageLoader::bitmap() const { - return m_decoder ? m_decoder->bitmap() : nullptr; + if (!m_decoder) + return nullptr; + if (m_decoder->is_animated()) + return m_decoder->frame(m_current_frame_index).image; + return m_decoder->bitmap(); } const Gfx::ImageDecoder* ImageLoader::image_decoder() const diff --git a/Libraries/LibWeb/Loader/ImageLoader.h b/Libraries/LibWeb/Loader/ImageLoader.h index 4b0e15ab59..14c8cd3288 100644 --- a/Libraries/LibWeb/Loader/ImageLoader.h +++ b/Libraries/LibWeb/Loader/ImageLoader.h @@ -27,6 +27,7 @@ #pragma once #include <AK/Function.h> +#include <LibCore/Timer.h> #include <LibWeb/Loader/ImageResource.h> namespace Web { @@ -44,6 +45,7 @@ public: Function<void()> on_load; Function<void()> on_fail; + Function<void()> on_animate; private: // ^ImageResourceClient @@ -52,8 +54,14 @@ private: virtual void resource_did_replace_decoder() override; virtual bool is_visible_in_viewport() const override { return m_visible_in_viewport; } + void animate(); + RefPtr<Gfx::ImageDecoder> m_decoder; bool m_visible_in_viewport { false }; + + size_t m_current_frame_index { 0 }; + size_t m_loops_completed { 0 }; + NonnullRefPtr<Core::Timer> m_timer; }; } |