summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2023-05-20 17:19:11 +0200
committerAndreas Kling <kling@serenityos.org>2023-05-21 07:44:29 +0200
commit41ab0837fa50f8fe32d727e447672fefb37a9434 (patch)
tree696afd9dd8e9c1a682883ef8606913dacabacb17 /Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
parente63f68661f8d31bf195f801b3f82ad57da1e8237 (diff)
downloadserenity-41ab0837fa50f8fe32d727e447672fefb37a9434.zip
LibWeb: Render SVG-as-image into an isolated top-level browsing context
In order to separate the SVG content from the rest of the engine, it gets its very own Page, PageClient, top-level browsing context, etc. Unfortunately, we do have to get the palette and CSS/device pixel ratios from the host Page for now, maybe that's something we could refactor in the future. Note that this doesn't work visually yet, since we don't calculate the intrinsic sizes & ratio for SVG images. That comes next. :^)
Diffstat (limited to 'Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp')
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp44
1 files changed, 31 insertions, 13 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
index 56537cd7ed..02b1b5b8da 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
@@ -29,6 +29,7 @@
#include <LibWeb/Loader/ResourceLoader.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Platform/ImageCodecPlugin.h>
+#include <LibWeb/SVG/SVGDecodedImageData.h>
namespace Web::HTML {
@@ -545,21 +546,38 @@ void HTMLImageElement::handle_successful_fetch(AK::URL const& url_string, ImageR
m_load_event_delayer.clear();
};
- auto result = Web::Platform::ImageCodecPlugin::the().decode_image(data.bytes());
- if (!result.has_value()) {
- dispatch_event(DOM::Event::create(realm(), HTML::EventNames::error).release_value_but_fixme_should_propagate_errors());
- return;
- }
+ // FIXME: Look at the MIME type instead!
+ bool is_svg_image = url_string.basename().ends_with(".svg"sv);
- Vector<AnimatedBitmapDecodedImageData::Frame> frames;
- for (auto& frame : result.value().frames) {
- frames.append(AnimatedBitmapDecodedImageData::Frame {
- .bitmap = frame.bitmap,
- .duration = static_cast<int>(frame.duration),
- });
+ RefPtr<DecodedImageData> image_data;
+
+ if (is_svg_image) {
+ VERIFY(document().page());
+ auto result = SVG::SVGDecodedImageData::create(*document().page(), url_string, data);
+ if (result.is_error()) {
+ dbgln("Failed to decode SVG image: {}", result.error());
+ dispatch_event(DOM::Event::create(realm(), HTML::EventNames::error).release_value_but_fixme_should_propagate_errors());
+ return;
+ }
+
+ image_data = result.release_value();
+ } else {
+ auto result = Web::Platform::ImageCodecPlugin::the().decode_image(data.bytes());
+ if (!result.has_value()) {
+ dispatch_event(DOM::Event::create(realm(), HTML::EventNames::error).release_value_but_fixme_should_propagate_errors());
+ return;
+ }
+
+ Vector<AnimatedBitmapDecodedImageData::Frame> frames;
+ for (auto& frame : result.value().frames) {
+ frames.append(AnimatedBitmapDecodedImageData::Frame {
+ .bitmap = frame.bitmap,
+ .duration = static_cast<int>(frame.duration),
+ });
+ }
+ image_data = AnimatedBitmapDecodedImageData::create(move(frames), result.value().loop_count, result.value().is_animated).release_value_but_fixme_should_propagate_errors();
}
- auto image_data = AnimatedBitmapDecodedImageData::create(move(frames), result.value().loop_count, result.value().is_animated).release_value_but_fixme_should_propagate_errors();
image_request.set_image_data(image_data);
ListOfAvailableImages::Key key;
@@ -580,7 +598,7 @@ void HTMLImageElement::handle_successful_fetch(AK::URL const& url_string, ImageR
image_request.set_state(ImageRequest::State::CompletelyAvailable);
// 3. Add the image to the list of available images using the key key, with the ignore higher-layer caching flag set.
- document().list_of_available_images().add(key, image_data, true).release_value_but_fixme_should_propagate_errors();
+ document().list_of_available_images().add(key, *image_data, true).release_value_but_fixme_should_propagate_errors();
// 4. Fire an event named load at the img element.
dispatch_event(DOM::Event::create(realm(), HTML::EventNames::load).release_value_but_fixme_should_propagate_errors());