summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-08-12 13:47:55 +0200
committerAndreas Kling <kling@serenityos.org>2020-08-12 13:49:43 +0200
commit305e2ef69cae0ed43dfddb95ec22c6d5a37c5dd6 (patch)
tree2f255001e7ab62f166dfbb9b499c5495cb253930 /Libraries
parentbd54854c64bd4f0281d2e3c80819f25140acbd3c (diff)
downloadserenity-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.cpp29
-rw-r--r--Libraries/LibWeb/Loader/ImageLoader.cpp5
-rw-r--r--Libraries/LibWeb/Loader/ImageLoader.h10
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;
};