mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 18:28:12 +00:00
LibWeb: Use CSSPixelFraction
to represent aspect ratios
This allows us to retain perfect precision for aspect ratios derived from either the intrinsic sizes of replaced elements, or the `aspect-ratio` CSS property.
This commit is contained in:
parent
4fb209d25f
commit
34c5043cbe
22 changed files with 57 additions and 55 deletions
|
@ -1,11 +1,11 @@
|
||||||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
BlockContainer <html> at (1,1) content-size 798x70 [BFC] children: not-inline
|
BlockContainer <html> at (1,1) content-size 798x69.96875 [BFC] children: not-inline
|
||||||
Box <body> at (10,10) content-size 780x52 flex-container(row) [FFC] children: not-inline
|
Box <body> at (10,10) content-size 780x51.96875 flex-container(row) [FFC] children: not-inline
|
||||||
ImageBox <img> at (11,11) content-size 66.671875x50 flex-item children: not-inline
|
ImageBox <img> at (11,11) content-size 66.65625x49.984375 flex-item children: not-inline
|
||||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
|
|
||||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x72]
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x71.96875]
|
||||||
PaintableBox (Box<BODY>) [9,9 782x54]
|
PaintableBox (Box<BODY>) [9,9 782x53.96875] overflow: [10,10 780x51.984375]
|
||||||
ImagePaintable (ImageBox<IMG>) [10,10 68.671875x52]
|
ImagePaintable (ImageBox<IMG>) [10,10 68.65625x51.984375]
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
||||||
BlockContainer <body> at (8,8) content-size 784x24.015625 children: not-inline
|
BlockContainer <body> at (8,8) content-size 784x24 children: not-inline
|
||||||
Box <div.grid-container> at (8,8) content-size 784x24.015625 [GFC] children: not-inline
|
Box <div.grid-container> at (8,8) content-size 784x24 [GFC] children: not-inline
|
||||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
BlockContainer <div.wrapper> at (8,8) content-size 64.03125x24.015625 [BFC] children: inline
|
BlockContainer <div.wrapper> at (8,8) content-size 64.03125x24 [BFC] children: inline
|
||||||
line 0 width: 64.03125, height: 24.015625, bottom: 24.015625, baseline: 24.015625
|
line 0 width: 64.03125, height: 24, bottom: 24, baseline: 24
|
||||||
frag 0 from ImageBox start: 0, length: 0, rect: [8,8 64.03125x24.015625]
|
frag 0 from ImageBox start: 0, length: 0, rect: [8,8 64.03125x24]
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
ImageBox <img> at (8,8) content-size 64.03125x24.015625 children: not-inline
|
ImageBox <img> at (8,8) content-size 64.03125x24 children: not-inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
|
|
||||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
|
||||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x24.015625]
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x24]
|
||||||
PaintableBox (Box<DIV>.grid-container) [8,8 784x24.015625]
|
PaintableBox (Box<DIV>.grid-container) [8,8 784x24]
|
||||||
PaintableWithLines (BlockContainer<DIV>.wrapper) [8,8 64.03125x24.015625]
|
PaintableWithLines (BlockContainer<DIV>.wrapper) [8,8 64.03125x24]
|
||||||
ImagePaintable (ImageBox<IMG>) [8,8 64.03125x24.015625]
|
ImagePaintable (ImageBox<IMG>) [8,8 64.03125x24]
|
||||||
|
|
|
@ -14,6 +14,8 @@ namespace Web::CSS {
|
||||||
class Ratio {
|
class Ratio {
|
||||||
public:
|
public:
|
||||||
Ratio(double first, double second = 1);
|
Ratio(double first, double second = 1);
|
||||||
|
double numerator() const { return m_first_value; }
|
||||||
|
double denominator() const { return m_second_value; }
|
||||||
double value() const { return m_first_value / m_second_value; }
|
double value() const { return m_first_value / m_second_value; }
|
||||||
bool is_degenerate() const;
|
bool is_degenerate() const;
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,9 @@ Optional<CSSPixels> AnimatedBitmapDecodedImageData::intrinsic_height() const
|
||||||
return m_frames.first().bitmap->height();
|
return m_frames.first().bitmap->height();
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> AnimatedBitmapDecodedImageData::intrinsic_aspect_ratio() const
|
Optional<CSSPixelFraction> AnimatedBitmapDecodedImageData::intrinsic_aspect_ratio() const
|
||||||
{
|
{
|
||||||
return static_cast<float>(m_frames.first().bitmap->width()) / static_cast<float>(m_frames.first().bitmap->height());
|
return CSSPixels(m_frames.first().bitmap->width()) / CSSPixels(m_frames.first().bitmap->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
virtual Optional<CSSPixels> intrinsic_width() const override;
|
virtual Optional<CSSPixels> intrinsic_width() const override;
|
||||||
virtual Optional<CSSPixels> intrinsic_height() const override;
|
virtual Optional<CSSPixels> intrinsic_height() const override;
|
||||||
virtual Optional<float> intrinsic_aspect_ratio() const override;
|
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AnimatedBitmapDecodedImageData(Vector<Frame>&&, size_t loop_count, bool animated);
|
AnimatedBitmapDecodedImageData(Vector<Frame>&&, size_t loop_count, bool animated);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
|
|
||||||
virtual Optional<CSSPixels> intrinsic_width() const = 0;
|
virtual Optional<CSSPixels> intrinsic_width() const = 0;
|
||||||
virtual Optional<CSSPixels> intrinsic_height() const = 0;
|
virtual Optional<CSSPixels> intrinsic_height() const = 0;
|
||||||
virtual Optional<float> intrinsic_aspect_ratio() const = 0;
|
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DecodedImageData();
|
DecodedImageData();
|
||||||
|
|
|
@ -140,7 +140,7 @@ Optional<CSSPixels> HTMLImageElement::intrinsic_height() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> HTMLImageElement::intrinsic_aspect_ratio() const
|
Optional<CSSPixelFraction> HTMLImageElement::intrinsic_aspect_ratio() const
|
||||||
{
|
{
|
||||||
if (auto image_data = m_current_request->image_data())
|
if (auto image_data = m_current_request->image_data())
|
||||||
return image_data->intrinsic_aspect_ratio();
|
return image_data->intrinsic_aspect_ratio();
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
// ^Layout::ImageProvider
|
// ^Layout::ImageProvider
|
||||||
virtual Optional<CSSPixels> intrinsic_width() const override;
|
virtual Optional<CSSPixels> intrinsic_width() const override;
|
||||||
virtual Optional<CSSPixels> intrinsic_height() const override;
|
virtual Optional<CSSPixels> intrinsic_height() const override;
|
||||||
virtual Optional<float> intrinsic_aspect_ratio() const override;
|
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const override;
|
||||||
virtual RefPtr<Gfx::Bitmap const> current_image_bitmap(Gfx::IntSize = {}) const override;
|
virtual RefPtr<Gfx::Bitmap const> current_image_bitmap(Gfx::IntSize = {}) const override;
|
||||||
virtual void set_visible_in_viewport(bool) override;
|
virtual void set_visible_in_viewport(bool) override;
|
||||||
|
|
||||||
|
|
|
@ -381,7 +381,7 @@ Optional<CSSPixels> HTMLObjectElement::intrinsic_height() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> HTMLObjectElement::intrinsic_aspect_ratio() const
|
Optional<CSSPixelFraction> HTMLObjectElement::intrinsic_aspect_ratio() const
|
||||||
{
|
{
|
||||||
if (auto image_data = this->image_data())
|
if (auto image_data = this->image_data())
|
||||||
return image_data->intrinsic_aspect_ratio();
|
return image_data->intrinsic_aspect_ratio();
|
||||||
|
|
|
@ -74,7 +74,7 @@ private:
|
||||||
// ^Layout::ImageProvider
|
// ^Layout::ImageProvider
|
||||||
virtual Optional<CSSPixels> intrinsic_width() const override;
|
virtual Optional<CSSPixels> intrinsic_width() const override;
|
||||||
virtual Optional<CSSPixels> intrinsic_height() const override;
|
virtual Optional<CSSPixels> intrinsic_height() const override;
|
||||||
virtual Optional<float> intrinsic_aspect_ratio() const override;
|
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const override;
|
||||||
virtual RefPtr<Gfx::Bitmap const> current_image_bitmap(Gfx::IntSize = {}) const override;
|
virtual RefPtr<Gfx::Bitmap const> current_image_bitmap(Gfx::IntSize = {}) const override;
|
||||||
virtual void set_visible_in_viewport(bool) override;
|
virtual void set_visible_in_viewport(bool) override;
|
||||||
|
|
||||||
|
|
|
@ -87,12 +87,12 @@ Painting::PaintableBox const* Box::paintable_box() const
|
||||||
return static_cast<Painting::PaintableBox const*>(Node::paintable());
|
return static_cast<Painting::PaintableBox const*>(Node::paintable());
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> Box::preferred_aspect_ratio() const
|
Optional<CSSPixelFraction> Box::preferred_aspect_ratio() const
|
||||||
{
|
{
|
||||||
auto computed_aspect_ratio = computed_values().aspect_ratio();
|
auto computed_aspect_ratio = computed_values().aspect_ratio();
|
||||||
if (computed_aspect_ratio.use_natural_aspect_ratio_if_available && natural_aspect_ratio().has_value())
|
if (computed_aspect_ratio.use_natural_aspect_ratio_if_available && natural_aspect_ratio().has_value())
|
||||||
return natural_aspect_ratio();
|
return natural_aspect_ratio();
|
||||||
return computed_aspect_ratio.preferred_ratio.map([](CSS::Ratio const& ratio) { return static_cast<float>(ratio.value()); });
|
return computed_aspect_ratio.preferred_ratio.map([](CSS::Ratio const& ratio) { return CSSPixelFraction(CSSPixels(ratio.numerator()), CSSPixels(ratio.denominator())); });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
// https://www.w3.org/TR/css-images-3/#natural-dimensions
|
// https://www.w3.org/TR/css-images-3/#natural-dimensions
|
||||||
Optional<CSSPixels> natural_width() const { return m_natural_width; }
|
Optional<CSSPixels> natural_width() const { return m_natural_width; }
|
||||||
Optional<CSSPixels> natural_height() const { return m_natural_height; }
|
Optional<CSSPixels> natural_height() const { return m_natural_height; }
|
||||||
Optional<float> natural_aspect_ratio() const { return m_natural_aspect_ratio; }
|
Optional<CSSPixelFraction> natural_aspect_ratio() const { return m_natural_aspect_ratio; }
|
||||||
|
|
||||||
bool has_natural_width() const { return natural_width().has_value(); }
|
bool has_natural_width() const { return natural_width().has_value(); }
|
||||||
bool has_natural_height() const { return natural_height().has_value(); }
|
bool has_natural_height() const { return natural_height().has_value(); }
|
||||||
|
@ -40,10 +40,10 @@ public:
|
||||||
|
|
||||||
void set_natural_width(Optional<CSSPixels> width) { m_natural_width = width; }
|
void set_natural_width(Optional<CSSPixels> width) { m_natural_width = width; }
|
||||||
void set_natural_height(Optional<CSSPixels> height) { m_natural_height = height; }
|
void set_natural_height(Optional<CSSPixels> height) { m_natural_height = height; }
|
||||||
void set_natural_aspect_ratio(Optional<float> ratio) { m_natural_aspect_ratio = ratio; }
|
void set_natural_aspect_ratio(Optional<CSSPixelFraction> ratio) { m_natural_aspect_ratio = ratio; }
|
||||||
|
|
||||||
// https://www.w3.org/TR/css-sizing-4/#preferred-aspect-ratio
|
// https://www.w3.org/TR/css-sizing-4/#preferred-aspect-ratio
|
||||||
Optional<float> preferred_aspect_ratio() const;
|
Optional<CSSPixelFraction> preferred_aspect_ratio() const;
|
||||||
bool has_preferred_aspect_ratio() const { return preferred_aspect_ratio().has_value(); }
|
bool has_preferred_aspect_ratio() const { return preferred_aspect_ratio().has_value(); }
|
||||||
|
|
||||||
virtual ~Box() override;
|
virtual ~Box() override;
|
||||||
|
@ -65,7 +65,7 @@ private:
|
||||||
|
|
||||||
Optional<CSSPixels> m_natural_width;
|
Optional<CSSPixels> m_natural_width;
|
||||||
Optional<CSSPixels> m_natural_height;
|
Optional<CSSPixels> m_natural_height;
|
||||||
Optional<float> m_natural_aspect_ratio;
|
Optional<CSSPixelFraction> m_natural_aspect_ratio;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -537,18 +537,18 @@ CSS::FlexBasis FlexFormattingContext::used_flex_basis_for_item(FlexItem const& i
|
||||||
return flex_basis;
|
return flex_basis;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSSPixels FlexFormattingContext::calculate_main_size_from_cross_size_and_aspect_ratio(CSSPixels cross_size, double aspect_ratio) const
|
CSSPixels FlexFormattingContext::calculate_main_size_from_cross_size_and_aspect_ratio(CSSPixels cross_size, CSSPixelFraction aspect_ratio) const
|
||||||
{
|
{
|
||||||
if (is_row_layout())
|
if (is_row_layout())
|
||||||
return CSSPixels::nearest_value_for(cross_size * aspect_ratio);
|
return cross_size * aspect_ratio;
|
||||||
return CSSPixels::nearest_value_for(cross_size / aspect_ratio);
|
return cross_size / aspect_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSSPixels FlexFormattingContext::calculate_cross_size_from_main_size_and_aspect_ratio(CSSPixels main_size, double aspect_ratio) const
|
CSSPixels FlexFormattingContext::calculate_cross_size_from_main_size_and_aspect_ratio(CSSPixels main_size, CSSPixelFraction aspect_ratio) const
|
||||||
{
|
{
|
||||||
if (is_row_layout())
|
if (is_row_layout())
|
||||||
return CSSPixels::nearest_value_for(main_size / aspect_ratio);
|
return main_size / aspect_ratio;
|
||||||
return CSSPixels::nearest_value_for(main_size * aspect_ratio);
|
return main_size * aspect_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function takes a size in the main axis and adjusts it according to the aspect ratio of the box
|
// This function takes a size in the main axis and adjusts it according to the aspect ratio of the box
|
||||||
|
|
|
@ -35,8 +35,8 @@ private:
|
||||||
[[nodiscard]] bool should_treat_cross_size_as_auto(Box const&) const;
|
[[nodiscard]] bool should_treat_cross_size_as_auto(Box const&) const;
|
||||||
|
|
||||||
[[nodiscard]] CSSPixels adjust_main_size_through_aspect_ratio_for_cross_size_min_max_constraints(Box const&, CSSPixels main_size, CSS::Size const& min_cross_size, CSS::Size const& max_cross_size) const;
|
[[nodiscard]] CSSPixels adjust_main_size_through_aspect_ratio_for_cross_size_min_max_constraints(Box const&, CSSPixels main_size, CSS::Size const& min_cross_size, CSS::Size const& max_cross_size) const;
|
||||||
[[nodiscard]] CSSPixels calculate_main_size_from_cross_size_and_aspect_ratio(CSSPixels cross_size, double aspect_ratio) const;
|
[[nodiscard]] CSSPixels calculate_main_size_from_cross_size_and_aspect_ratio(CSSPixels cross_size, CSSPixelFraction aspect_ratio) const;
|
||||||
[[nodiscard]] CSSPixels calculate_cross_size_from_main_size_and_aspect_ratio(CSSPixels main_size, double aspect_ratio) const;
|
[[nodiscard]] CSSPixels calculate_cross_size_from_main_size_and_aspect_ratio(CSSPixels main_size, CSSPixelFraction aspect_ratio) const;
|
||||||
|
|
||||||
void dump_items() const;
|
void dump_items() const;
|
||||||
|
|
||||||
|
|
|
@ -404,7 +404,7 @@ CSSPixels FormattingContext::tentative_width_for_replaced_element(Box const& box
|
||||||
// (used height) * (intrinsic ratio)
|
// (used height) * (intrinsic ratio)
|
||||||
if ((computed_height.is_auto() && computed_width.is_auto() && !box.has_natural_width() && box.has_natural_height() && box.has_preferred_aspect_ratio())
|
if ((computed_height.is_auto() && computed_width.is_auto() && !box.has_natural_width() && box.has_natural_height() && box.has_preferred_aspect_ratio())
|
||||||
|| (computed_width.is_auto() && !computed_height.is_auto() && box.has_preferred_aspect_ratio())) {
|
|| (computed_width.is_auto() && !computed_height.is_auto() && box.has_preferred_aspect_ratio())) {
|
||||||
return compute_height_for_replaced_element(box, available_space).scaled(static_cast<double>(box.preferred_aspect_ratio().value()));
|
return compute_height_for_replaced_element(box, available_space) * box.preferred_aspect_ratio().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
|
// If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
|
||||||
|
@ -498,7 +498,7 @@ CSSPixels FormattingContext::tentative_height_for_replaced_element(Box const& bo
|
||||||
//
|
//
|
||||||
// (used width) / (intrinsic ratio)
|
// (used width) / (intrinsic ratio)
|
||||||
if (computed_height.is_auto() && box.has_preferred_aspect_ratio())
|
if (computed_height.is_auto() && box.has_preferred_aspect_ratio())
|
||||||
return CSSPixels::nearest_value_for(m_state.get(box).content_width() / static_cast<double>(box.preferred_aspect_ratio().value()));
|
return m_state.get(box).content_width() / box.preferred_aspect_ratio().value();
|
||||||
|
|
||||||
// Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
|
// Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
|
||||||
if (computed_height.is_auto() && box.has_natural_height())
|
if (computed_height.is_auto() && box.has_natural_height())
|
||||||
|
@ -1407,7 +1407,7 @@ CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box
|
||||||
CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box, CSSPixels width) const
|
CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box, CSSPixels width) const
|
||||||
{
|
{
|
||||||
if (box.has_preferred_aspect_ratio())
|
if (box.has_preferred_aspect_ratio())
|
||||||
return CSSPixels::nearest_value_for(width / static_cast<double>(*box.preferred_aspect_ratio()));
|
return width / *box.preferred_aspect_ratio();
|
||||||
|
|
||||||
if (box.has_natural_height())
|
if (box.has_natural_height())
|
||||||
return *box.natural_height();
|
return *box.natural_height();
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
|
|
||||||
virtual Optional<CSSPixels> intrinsic_width() const = 0;
|
virtual Optional<CSSPixels> intrinsic_width() const = 0;
|
||||||
virtual Optional<CSSPixels> intrinsic_height() const = 0;
|
virtual Optional<CSSPixels> intrinsic_height() const = 0;
|
||||||
virtual Optional<float> intrinsic_aspect_ratio() const = 0;
|
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const = 0;
|
||||||
|
|
||||||
virtual RefPtr<Gfx::Bitmap const> current_image_bitmap(Gfx::IntSize) const = 0;
|
virtual RefPtr<Gfx::Bitmap const> current_image_bitmap(Gfx::IntSize) const = 0;
|
||||||
virtual void set_visible_in_viewport(bool) = 0;
|
virtual void set_visible_in_viewport(bool) = 0;
|
||||||
|
|
|
@ -42,7 +42,7 @@ void SVGSVGBox::prepare_for_replaced_layout()
|
||||||
set_natural_aspect_ratio(calculate_intrinsic_aspect_ratio());
|
set_natural_aspect_ratio(calculate_intrinsic_aspect_ratio());
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> SVGSVGBox::calculate_intrinsic_aspect_ratio() const
|
Optional<CSSPixelFraction> SVGSVGBox::calculate_intrinsic_aspect_ratio() const
|
||||||
{
|
{
|
||||||
// https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
|
// https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
|
||||||
// The intrinsic aspect ratio must be calculated using the following algorithm. If the algorithm returns null, then there is no intrinsic aspect ratio.
|
// The intrinsic aspect ratio must be calculated using the following algorithm. If the algorithm returns null, then there is no intrinsic aspect ratio.
|
||||||
|
@ -57,7 +57,7 @@ Optional<float> SVGSVGBox::calculate_intrinsic_aspect_ratio() const
|
||||||
|
|
||||||
if (width != 0 && height != 0) {
|
if (width != 0 && height != 0) {
|
||||||
// 1. return width / height
|
// 1. return width / height
|
||||||
return width.to_double() / height.to_double();
|
return width / height;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -73,7 +73,7 @@ Optional<float> SVGSVGBox::calculate_intrinsic_aspect_ratio() const
|
||||||
auto const& viewbox = dom_node().view_box().value();
|
auto const& viewbox = dom_node().view_box().value();
|
||||||
|
|
||||||
// 2. return viewbox.width / viewbox.height
|
// 2. return viewbox.width / viewbox.height
|
||||||
return viewbox.width / viewbox.height;
|
return CSSPixels::nearest_value_for(viewbox.width) / CSSPixels::nearest_value_for(viewbox.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. return null
|
// 4. return null
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
private:
|
private:
|
||||||
virtual bool is_svg_svg_box() const final { return true; }
|
virtual bool is_svg_svg_box() const final { return true; }
|
||||||
|
|
||||||
[[nodiscard]] Optional<float> calculate_intrinsic_aspect_ratio() const;
|
[[nodiscard]] Optional<CSSPixelFraction> calculate_intrinsic_aspect_ratio() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -37,11 +37,11 @@ HTML::HTMLVideoElement const& VideoBox::dom_node() const
|
||||||
|
|
||||||
void VideoBox::prepare_for_replaced_layout()
|
void VideoBox::prepare_for_replaced_layout()
|
||||||
{
|
{
|
||||||
auto width = static_cast<float>(dom_node().video_width());
|
CSSPixels width = dom_node().video_width();
|
||||||
set_natural_width(CSSPixels(width));
|
set_natural_width(width);
|
||||||
|
|
||||||
auto height = static_cast<float>(dom_node().video_height());
|
CSSPixels height = dom_node().video_height();
|
||||||
set_natural_height(CSSPixels(height));
|
set_natural_height(height);
|
||||||
|
|
||||||
if (width != 0 && height != 0)
|
if (width != 0 && height != 0)
|
||||||
set_natural_aspect_ratio(width / height);
|
set_natural_aspect_ratio(width / height);
|
||||||
|
|
|
@ -287,7 +287,7 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr CSSPixelFraction(CSSPixels value)
|
explicit constexpr CSSPixelFraction(CSSPixels value)
|
||||||
: m_numerator(value)
|
: m_numerator(value)
|
||||||
, m_denominator(1)
|
, m_denominator(1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -140,16 +140,16 @@ Optional<CSSPixels> SVGDecodedImageData::intrinsic_height() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> SVGDecodedImageData::intrinsic_aspect_ratio() const
|
Optional<CSSPixelFraction> SVGDecodedImageData::intrinsic_aspect_ratio() const
|
||||||
{
|
{
|
||||||
// https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
|
// https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
|
||||||
auto width = intrinsic_width();
|
auto width = intrinsic_width();
|
||||||
auto height = intrinsic_height();
|
auto height = intrinsic_height();
|
||||||
if (width.has_value() && height.has_value())
|
if (width.has_value() && height.has_value())
|
||||||
return width->to_float() / height->to_float();
|
return *width / *height;
|
||||||
|
|
||||||
if (auto const& viewbox = m_root_element->view_box(); viewbox.has_value())
|
if (auto const& viewbox = m_root_element->view_box(); viewbox.has_value())
|
||||||
return viewbox->width / viewbox->height;
|
return CSSPixels::nearest_value_for(viewbox->width) / CSSPixels::nearest_value_for(viewbox->height);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
|
|
||||||
virtual Optional<CSSPixels> intrinsic_width() const override;
|
virtual Optional<CSSPixels> intrinsic_width() const override;
|
||||||
virtual Optional<CSSPixels> intrinsic_height() const override;
|
virtual Optional<CSSPixels> intrinsic_height() const override;
|
||||||
virtual Optional<float> intrinsic_aspect_ratio() const override;
|
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const override;
|
||||||
|
|
||||||
// FIXME: Support SVG animations. :^)
|
// FIXME: Support SVG animations. :^)
|
||||||
virtual int frame_duration(size_t) const override { return 0; }
|
virtual int frame_duration(size_t) const override { return 0; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue