diff options
author | Andreas Kling <kling@serenityos.org> | 2020-08-12 13:47:55 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-12 13:49:43 +0200 |
commit | 305e2ef69cae0ed43dfddb95ec22c6d5a37c5dd6 (patch) | |
tree | 2f255001e7ab62f166dfbb9b499c5495cb253930 /Libraries | |
parent | bd54854c64bd4f0281d2e3c80819f25140acbd3c (diff) | |
download | serenity-305e2ef69cae0ed43dfddb95ec22c6d5a37c5dd6.zip |
LibWeb: Until an image has loaded or failed, don't occupy layout size
This patch makes images have an implicit zero intrinsic size before
they have either loaded or failed to load. This is tracked by the
ImageLoader object.
This fixes a long-standing issue with images occupying empty 150x150
rectangles of space.
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutImage.cpp | 29 | ||||
-rw-r--r-- | Libraries/LibWeb/Loader/ImageLoader.cpp | 5 | ||||
-rw-r--r-- | Libraries/LibWeb/Loader/ImageLoader.h | 10 |
3 files changed, 33 insertions, 11 deletions
diff --git a/Libraries/LibWeb/Layout/LayoutImage.cpp b/Libraries/LibWeb/Layout/LayoutImage.cpp index 061675a8a1..de476897ae 100644 --- a/Libraries/LibWeb/Layout/LayoutImage.cpp +++ b/Libraries/LibWeb/Layout/LayoutImage.cpp @@ -54,20 +54,27 @@ int LayoutImage::preferred_height() const void LayoutImage::layout(LayoutMode layout_mode) { - if (m_image_loader.width()) { + if (!m_image_loader.has_loaded_or_failed()) { set_has_intrinsic_width(true); - set_intrinsic_width(m_image_loader.width()); - } - if (m_image_loader.height()) { set_has_intrinsic_height(true); - set_intrinsic_height(m_image_loader.height()); - } - - if (m_image_loader.width() && m_image_loader.height()) { - set_has_intrinsic_ratio(true); - set_intrinsic_ratio((float)m_image_loader.width() / (float)m_image_loader.height()); + set_intrinsic_width(0); + set_intrinsic_height(0); } else { - set_has_intrinsic_ratio(false); + if (m_image_loader.width()) { + set_has_intrinsic_width(true); + set_intrinsic_width(m_image_loader.width()); + } + if (m_image_loader.height()) { + set_has_intrinsic_height(true); + set_intrinsic_height(m_image_loader.height()); + } + + if (m_image_loader.width() && m_image_loader.height()) { + set_has_intrinsic_ratio(true); + set_intrinsic_ratio((float)m_image_loader.width() / (float)m_image_loader.height()); + } else { + set_has_intrinsic_ratio(false); + } } if (renders_as_alt_text()) { diff --git a/Libraries/LibWeb/Loader/ImageLoader.cpp b/Libraries/LibWeb/Loader/ImageLoader.cpp index 3732326bf5..b56ab98abd 100644 --- a/Libraries/LibWeb/Loader/ImageLoader.cpp +++ b/Libraries/LibWeb/Loader/ImageLoader.cpp @@ -39,6 +39,7 @@ ImageLoader::ImageLoader() void ImageLoader::load(const URL& url) { + m_loading_state = LoadingState::Loading; LoadRequest request; request.set_url(url); set_resource(ResourceLoader::the().load_resource(Resource::Type::Image, request)); @@ -62,11 +63,14 @@ void ImageLoader::resource_did_load() ASSERT(resource()); if (!resource()->mime_type().starts_with("image/")) { + m_loading_state = LoadingState::Failed; if (on_fail) on_fail(); return; } + m_loading_state = LoadingState::Loaded; + #ifdef IMAGE_LOADER_DEBUG if (!resource()->has_encoded_data()) { dbg() << "ImageLoader: Resource did load, no encoded data. URL: " << resource()->url(); @@ -118,6 +122,7 @@ void ImageLoader::animate() void ImageLoader::resource_did_fail() { dbg() << "ImageLoader: Resource did fail. URL: " << resource()->url(); + m_loading_state = LoadingState::Failed; if (on_fail) on_fail(); } diff --git a/Libraries/LibWeb/Loader/ImageLoader.h b/Libraries/LibWeb/Loader/ImageLoader.h index 0ac1bd1f41..f07b6e3055 100644 --- a/Libraries/LibWeb/Loader/ImageLoader.h +++ b/Libraries/LibWeb/Loader/ImageLoader.h @@ -42,6 +42,8 @@ public: bool has_image() const; + bool has_loaded_or_failed() const { return m_loading_state != LoadingState::Loading; } + void set_visible_in_viewport(bool) const; unsigned width() const; @@ -59,10 +61,18 @@ private: void animate(); + enum class LoadingState { + None, + Loading, + Loaded, + Failed, + }; + mutable bool m_visible_in_viewport { false }; size_t m_current_frame_index { 0 }; size_t m_loops_completed { 0 }; + LoadingState m_loading_state { LoadingState::Loading }; NonnullRefPtr<Core::Timer> m_timer; }; |