mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 18:28:10 +00:00
LibWeb: Start fleshing out HTML "image requests" and "image data"
This patch adds HTML::ImageRequest and HTML::DecodedImageData. The latter had to use a different name than "ImageData", as there is already an IDL-exposed ImageData class in HTML.
This commit is contained in:
parent
420952a433
commit
596eabe9e6
6 changed files with 281 additions and 0 deletions
|
@ -223,6 +223,7 @@ set(SOURCES
|
||||||
HTML/CustomElements/CustomElementName.cpp
|
HTML/CustomElements/CustomElementName.cpp
|
||||||
HTML/CustomElements/CustomElementReactionNames.cpp
|
HTML/CustomElements/CustomElementReactionNames.cpp
|
||||||
HTML/CustomElements/CustomElementRegistry.cpp
|
HTML/CustomElements/CustomElementRegistry.cpp
|
||||||
|
HTML/DecodedImageData.cpp
|
||||||
HTML/DocumentState.cpp
|
HTML/DocumentState.cpp
|
||||||
HTML/DOMParser.cpp
|
HTML/DOMParser.cpp
|
||||||
HTML/DOMStringMap.cpp
|
HTML/DOMStringMap.cpp
|
||||||
|
@ -313,6 +314,7 @@ set(SOURCES
|
||||||
HTML/HTMLUnknownElement.cpp
|
HTML/HTMLUnknownElement.cpp
|
||||||
HTML/HTMLVideoElement.cpp
|
HTML/HTMLVideoElement.cpp
|
||||||
HTML/ImageData.cpp
|
HTML/ImageData.cpp
|
||||||
|
HTML/ImageRequest.cpp
|
||||||
HTML/Location.cpp
|
HTML/Location.cpp
|
||||||
HTML/MediaError.cpp
|
HTML/MediaError.cpp
|
||||||
HTML/MessageChannel.cpp
|
HTML/MessageChannel.cpp
|
||||||
|
|
|
@ -288,6 +288,7 @@ class ClassicScript;
|
||||||
class CloseEvent;
|
class CloseEvent;
|
||||||
class CustomElementDefinition;
|
class CustomElementDefinition;
|
||||||
class CustomElementRegistry;
|
class CustomElementRegistry;
|
||||||
|
class DecodedImageData;
|
||||||
class DocumentState;
|
class DocumentState;
|
||||||
class DOMParser;
|
class DOMParser;
|
||||||
class DOMStringMap;
|
class DOMStringMap;
|
||||||
|
@ -371,6 +372,7 @@ class HTMLUListElement;
|
||||||
class HTMLUnknownElement;
|
class HTMLUnknownElement;
|
||||||
class HTMLVideoElement;
|
class HTMLVideoElement;
|
||||||
class ImageData;
|
class ImageData;
|
||||||
|
class ImageRequest;
|
||||||
class Location;
|
class Location;
|
||||||
class MediaError;
|
class MediaError;
|
||||||
class MessageChannel;
|
class MessageChannel;
|
||||||
|
|
50
Userland/Libraries/LibWeb/HTML/DecodedImageData.cpp
Normal file
50
Userland/Libraries/LibWeb/HTML/DecodedImageData.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibGfx/Bitmap.h>
|
||||||
|
#include <LibWeb/HTML/DecodedImageData.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
ErrorOr<NonnullRefPtr<DecodedImageData>> DecodedImageData::create(Vector<Frame>&& frames, size_t loop_count, bool animated)
|
||||||
|
{
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) DecodedImageData(move(frames), loop_count, animated));
|
||||||
|
}
|
||||||
|
|
||||||
|
DecodedImageData::DecodedImageData(Vector<Frame>&& frames, size_t loop_count, bool animated)
|
||||||
|
: m_frames(move(frames))
|
||||||
|
, m_loop_count(loop_count)
|
||||||
|
, m_animated(animated)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DecodedImageData::~DecodedImageData() = default;
|
||||||
|
|
||||||
|
RefPtr<Gfx::Bitmap const> DecodedImageData::bitmap(size_t frame_index) const
|
||||||
|
{
|
||||||
|
if (frame_index >= m_frames.size())
|
||||||
|
return nullptr;
|
||||||
|
return m_frames[frame_index].bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DecodedImageData::frame_duration(size_t frame_index) const
|
||||||
|
{
|
||||||
|
if (frame_index >= m_frames.size())
|
||||||
|
return 0;
|
||||||
|
return m_frames[frame_index].duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<int> DecodedImageData::natural_width() const
|
||||||
|
{
|
||||||
|
return m_frames.first().bitmap->width();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<int> DecodedImageData::natural_height() const
|
||||||
|
{
|
||||||
|
return m_frames.first().bitmap->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
Userland/Libraries/LibWeb/HTML/DecodedImageData.h
Normal file
44
Userland/Libraries/LibWeb/HTML/DecodedImageData.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/RefCounted.h>
|
||||||
|
#include <LibGfx/Forward.h>
|
||||||
|
#include <LibJS/Heap/Cell.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#img-req-data
|
||||||
|
class DecodedImageData final : public RefCounted<DecodedImageData> {
|
||||||
|
public:
|
||||||
|
struct Frame {
|
||||||
|
RefPtr<Gfx::Bitmap const> bitmap;
|
||||||
|
int duration { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
static ErrorOr<NonnullRefPtr<DecodedImageData>> create(Vector<Frame>&&, size_t loop_count, bool animated);
|
||||||
|
~DecodedImageData();
|
||||||
|
|
||||||
|
RefPtr<Gfx::Bitmap const> bitmap(size_t frame_index) const;
|
||||||
|
int frame_duration(size_t frame_index) const;
|
||||||
|
|
||||||
|
size_t frame_count() const { return m_frames.size(); }
|
||||||
|
size_t loop_count() const { return m_loop_count; }
|
||||||
|
bool is_animated() const { return m_animated; }
|
||||||
|
|
||||||
|
Optional<int> natural_width() const;
|
||||||
|
Optional<int> natural_height() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DecodedImageData(Vector<Frame>&&, size_t loop_count, bool animated);
|
||||||
|
|
||||||
|
Vector<Frame> m_frames;
|
||||||
|
size_t m_loop_count { 0 };
|
||||||
|
bool m_animated { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
100
Userland/Libraries/LibWeb/HTML/ImageRequest.cpp
Normal file
100
Userland/Libraries/LibWeb/HTML/ImageRequest.cpp
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibGfx/Bitmap.h>
|
||||||
|
#include <LibWeb/Fetch/Infrastructure/FetchController.h>
|
||||||
|
#include <LibWeb/HTML/DecodedImageData.h>
|
||||||
|
#include <LibWeb/HTML/ImageRequest.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
ErrorOr<NonnullRefPtr<ImageRequest>> ImageRequest::create()
|
||||||
|
{
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) ImageRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageRequest::ImageRequest() = default;
|
||||||
|
|
||||||
|
ImageRequest::~ImageRequest() = default;
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#img-available
|
||||||
|
bool ImageRequest::is_available() const
|
||||||
|
{
|
||||||
|
// When an image request's state is either partially available or completely available, the image request is said to be available.
|
||||||
|
return m_state == State::PartiallyAvailable || m_state == State::CompletelyAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageRequest::State ImageRequest::state() const
|
||||||
|
{
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageRequest::set_state(State state)
|
||||||
|
{
|
||||||
|
m_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
AK::URL const& ImageRequest::current_url() const
|
||||||
|
{
|
||||||
|
return m_current_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageRequest::set_current_url(AK::URL url)
|
||||||
|
{
|
||||||
|
m_current_url = move(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#abort-the-image-request
|
||||||
|
void ImageRequest::abort(JS::Realm& realm)
|
||||||
|
{
|
||||||
|
// 1. Forget image request's image data, if any.
|
||||||
|
m_image_data = nullptr;
|
||||||
|
|
||||||
|
// 2. Abort any instance of the fetching algorithm for image request,
|
||||||
|
// discarding any pending tasks generated by that algorithm.
|
||||||
|
if (m_fetch_controller)
|
||||||
|
m_fetch_controller->abort(realm, {});
|
||||||
|
|
||||||
|
m_fetch_controller = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<DecodedImageData const> ImageRequest::image_data() const
|
||||||
|
{
|
||||||
|
return m_image_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageRequest::set_image_data(RefPtr<DecodedImageData const> data)
|
||||||
|
{
|
||||||
|
m_image_data = move(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#prepare-an-image-for-presentation
|
||||||
|
void ImageRequest::prepare_for_presentation(HTMLImageElement&)
|
||||||
|
{
|
||||||
|
// FIXME: 1. Let exifTagMap be the EXIF tags obtained from req's image data, as defined by the relevant codec. [EXIF]
|
||||||
|
// FIXME: 2. Let physicalWidth and physicalHeight be the width and height obtained from req's image data, as defined by the relevant codec.
|
||||||
|
// FIXME: 3. Let dimX be the value of exifTagMap's tag 0xA002 (PixelXDimension).
|
||||||
|
// FIXME: 4. Let dimY be the value of exifTagMap's tag 0xA003 (PixelYDimension).
|
||||||
|
// FIXME: 5. Let resX be the value of exifTagMap's tag 0x011A (XResolution).
|
||||||
|
// FIXME: 6. Let resY be the value of exifTagMap's tag 0x011B (YResolution).
|
||||||
|
// FIXME: 7. Let resUnit be the value of exifTagMap's tag 0x0128 (ResolutionUnit).
|
||||||
|
// FIXME: 8. If either dimX or dimY is not a positive integer, then return.
|
||||||
|
// FIXME: 9. If either resX or resY is not a positive floating-point number, then return.
|
||||||
|
// FIXME: 10. If resUnit is not equal to 2 (Inch), then return.
|
||||||
|
// FIXME: 11. Let widthFromDensity be the value of physicalWidth, multiplied by 72 and divided by resX.
|
||||||
|
// FIXME: 12. Let heightFromDensity be the value of physicalHeight, multiplied by 72 and divided by resY.
|
||||||
|
// FIXME: 13. If widthFromDensity is not equal to dimX or heightFromDensity is not equal to dimY, then return.
|
||||||
|
// FIXME: 14. If req's image data is CORS-cross-origin, then set img's intrinsic dimensions to dimX and dimY, scale img's pixel data accordingly, and return.
|
||||||
|
// FIXME: 15. Set req's preferred density-corrected dimensions to a struct with its width set to dimX and its height set to dimY.
|
||||||
|
// FIXME: 16. Update req's img element's presentation appropriately.
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageRequest::set_fetch_controller(JS::GCPtr<Fetch::Infrastructure::FetchController> fetch_controller)
|
||||||
|
{
|
||||||
|
m_fetch_controller = move(fetch_controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
83
Userland/Libraries/LibWeb/HTML/ImageRequest.h
Normal file
83
Userland/Libraries/LibWeb/HTML/ImageRequest.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Error.h>
|
||||||
|
#include <AK/OwnPtr.h>
|
||||||
|
#include <AK/URL.h>
|
||||||
|
#include <LibGfx/Size.h>
|
||||||
|
#include <LibJS/Heap/Handle.h>
|
||||||
|
#include <LibWeb/Forward.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#image-request
|
||||||
|
class ImageRequest : public RefCounted<ImageRequest> {
|
||||||
|
public:
|
||||||
|
static ErrorOr<NonnullRefPtr<ImageRequest>> create();
|
||||||
|
~ImageRequest();
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#img-req-state
|
||||||
|
enum class State {
|
||||||
|
Unavailable,
|
||||||
|
PartiallyAvailable,
|
||||||
|
CompletelyAvailable,
|
||||||
|
Broken,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool is_available() const;
|
||||||
|
|
||||||
|
State state() const;
|
||||||
|
void set_state(State);
|
||||||
|
|
||||||
|
AK::URL const& current_url() const;
|
||||||
|
void set_current_url(AK::URL);
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#abort-the-image-request
|
||||||
|
void abort(JS::Realm&);
|
||||||
|
|
||||||
|
[[nodiscard]] RefPtr<DecodedImageData const> image_data() const;
|
||||||
|
void set_image_data(RefPtr<DecodedImageData const>);
|
||||||
|
|
||||||
|
[[nodiscard]] float current_pixel_density() const { return m_current_pixel_density; }
|
||||||
|
void set_current_pixel_density(float density) { m_current_pixel_density = density; }
|
||||||
|
|
||||||
|
[[nodiscard]] Optional<Gfx::FloatSize> const& preferred_density_corrected_dimensions() const { return m_preferred_density_corrected_dimensions; }
|
||||||
|
void set_preferred_density_corrected_dimensions(Optional<Gfx::FloatSize> dimensions) { m_preferred_density_corrected_dimensions = move(dimensions); }
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#prepare-an-image-for-presentation
|
||||||
|
void prepare_for_presentation(HTMLImageElement&);
|
||||||
|
|
||||||
|
void set_fetch_controller(JS::GCPtr<Fetch::Infrastructure::FetchController>);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageRequest();
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#img-req-state
|
||||||
|
// An image request's state is initially unavailable.
|
||||||
|
State m_state { State::Unavailable };
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#img-req-url
|
||||||
|
// An image request's current URL is initially the empty string.
|
||||||
|
AK::URL m_current_url;
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#img-req-data
|
||||||
|
RefPtr<DecodedImageData const> m_image_data;
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#current-pixel-density
|
||||||
|
// Each image request has a current pixel density, which must initially be 1.
|
||||||
|
float m_current_pixel_density { 1 };
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/images.html#preferred-density-corrected-dimensions
|
||||||
|
// Each image request has preferred density-corrected dimensions,
|
||||||
|
// which is either a struct consisting of a width and a height or is null. It must initially be null.
|
||||||
|
Optional<Gfx::FloatSize> m_preferred_density_corrected_dimensions;
|
||||||
|
|
||||||
|
JS::Handle<Fetch::Infrastructure::FetchController> m_fetch_controller;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue