diff --git a/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt b/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt index 60501fb3a0..5ce0f4dc07 100644 --- a/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt +++ b/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt @@ -1,11 +1,11 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline - BlockContainer at (1,1) content-size 798x70 [BFC] children: not-inline - Box at (10,10) content-size 780x52 flex-container(row) [FFC] children: not-inline - ImageBox at (11,11) content-size 66.671875x50 flex-item children: not-inline + BlockContainer at (1,1) content-size 798x69.96875 [BFC] children: not-inline + Box at (10,10) content-size 780x51.96875 flex-container(row) [FFC] children: not-inline + ImageBox at (11,11) content-size 66.65625x49.984375 flex-item children: not-inline BlockContainer <(anonymous)> (not painted) [BFC] children: inline TextNode <#text> ViewportPaintable (Viewport<#document>) [0,0 800x600] - PaintableWithLines (BlockContainer) [0,0 800x72] - PaintableBox (Box) [9,9 782x54] - ImagePaintable (ImageBox) [10,10 68.671875x52] + PaintableWithLines (BlockContainer) [0,0 800x71.96875] + PaintableBox (Box) [9,9 782x53.96875] overflow: [10,10 780x51.984375] + ImagePaintable (ImageBox) [10,10 68.65625x51.984375] diff --git a/Tests/LibWeb/Layout/expected/grid/image-in-grid.txt b/Tests/LibWeb/Layout/expected/grid/image-in-grid.txt index 876d3d6498..a1cd90e07f 100644 --- a/Tests/LibWeb/Layout/expected/grid/image-in-grid.txt +++ b/Tests/LibWeb/Layout/expected/grid/image-in-grid.txt @@ -1,21 +1,21 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline - BlockContainer at (8,8) content-size 784x24.015625 children: not-inline - Box at (8,8) content-size 784x24.015625 [GFC] children: not-inline + BlockContainer at (8,8) content-size 784x24 children: not-inline + Box at (8,8) content-size 784x24 [GFC] children: not-inline BlockContainer <(anonymous)> (not painted) [BFC] children: inline TextNode <#text> - BlockContainer at (8,8) content-size 64.03125x24.015625 [BFC] children: inline - line 0 width: 64.03125, height: 24.015625, bottom: 24.015625, baseline: 24.015625 - frag 0 from ImageBox start: 0, length: 0, rect: [8,8 64.03125x24.015625] + BlockContainer at (8,8) content-size 64.03125x24 [BFC] children: inline + line 0 width: 64.03125, height: 24, bottom: 24, baseline: 24 + frag 0 from ImageBox start: 0, length: 0, rect: [8,8 64.03125x24] TextNode <#text> - ImageBox at (8,8) content-size 64.03125x24.015625 children: not-inline + ImageBox at (8,8) content-size 64.03125x24 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) [BFC] children: inline TextNode <#text> ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x600] - PaintableWithLines (BlockContainer) [8,8 784x24.015625] - PaintableBox (Box
.grid-container) [8,8 784x24.015625] - PaintableWithLines (BlockContainer
.wrapper) [8,8 64.03125x24.015625] - ImagePaintable (ImageBox) [8,8 64.03125x24.015625] + PaintableWithLines (BlockContainer) [8,8 784x24] + PaintableBox (Box
.grid-container) [8,8 784x24] + PaintableWithLines (BlockContainer
.wrapper) [8,8 64.03125x24] + ImagePaintable (ImageBox) [8,8 64.03125x24] diff --git a/Userland/Libraries/LibWeb/CSS/Ratio.h b/Userland/Libraries/LibWeb/CSS/Ratio.h index 3d77f09e60..1beb1ac9a9 100644 --- a/Userland/Libraries/LibWeb/CSS/Ratio.h +++ b/Userland/Libraries/LibWeb/CSS/Ratio.h @@ -14,6 +14,8 @@ namespace Web::CSS { class Ratio { public: 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; } bool is_degenerate() const; diff --git a/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.cpp b/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.cpp index 5b5c24cb5d..4ad58719d0 100644 --- a/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.cpp +++ b/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.cpp @@ -47,9 +47,9 @@ Optional AnimatedBitmapDecodedImageData::intrinsic_height() const return m_frames.first().bitmap->height(); } -Optional AnimatedBitmapDecodedImageData::intrinsic_aspect_ratio() const +Optional AnimatedBitmapDecodedImageData::intrinsic_aspect_ratio() const { - return static_cast(m_frames.first().bitmap->width()) / static_cast(m_frames.first().bitmap->height()); + return CSSPixels(m_frames.first().bitmap->width()) / CSSPixels(m_frames.first().bitmap->height()); } } diff --git a/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.h b/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.h index 9f7ca8fc31..bb32319bcf 100644 --- a/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.h +++ b/Userland/Libraries/LibWeb/HTML/AnimatedBitmapDecodedImageData.h @@ -29,7 +29,7 @@ public: virtual Optional intrinsic_width() const override; virtual Optional intrinsic_height() const override; - virtual Optional intrinsic_aspect_ratio() const override; + virtual Optional intrinsic_aspect_ratio() const override; private: AnimatedBitmapDecodedImageData(Vector&&, size_t loop_count, bool animated); diff --git a/Userland/Libraries/LibWeb/HTML/DecodedImageData.h b/Userland/Libraries/LibWeb/HTML/DecodedImageData.h index f96b60342e..d0b856be4b 100644 --- a/Userland/Libraries/LibWeb/HTML/DecodedImageData.h +++ b/Userland/Libraries/LibWeb/HTML/DecodedImageData.h @@ -27,7 +27,7 @@ public: virtual Optional intrinsic_width() const = 0; virtual Optional intrinsic_height() const = 0; - virtual Optional intrinsic_aspect_ratio() const = 0; + virtual Optional intrinsic_aspect_ratio() const = 0; protected: DecodedImageData(); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index 22aab62187..e3c0ae7e03 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -140,7 +140,7 @@ Optional HTMLImageElement::intrinsic_height() const return {}; } -Optional HTMLImageElement::intrinsic_aspect_ratio() const +Optional HTMLImageElement::intrinsic_aspect_ratio() const { if (auto image_data = m_current_request->image_data()) return image_data->intrinsic_aspect_ratio(); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h index 6647524805..c9a3c20987 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -86,7 +86,7 @@ public: // ^Layout::ImageProvider virtual Optional intrinsic_width() const override; virtual Optional intrinsic_height() const override; - virtual Optional intrinsic_aspect_ratio() const override; + virtual Optional intrinsic_aspect_ratio() const override; virtual RefPtr current_image_bitmap(Gfx::IntSize = {}) const override; virtual void set_visible_in_viewport(bool) override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp index 0fa3c68e1f..e437189aa4 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp @@ -381,7 +381,7 @@ Optional HTMLObjectElement::intrinsic_height() const return {}; } -Optional HTMLObjectElement::intrinsic_aspect_ratio() const +Optional HTMLObjectElement::intrinsic_aspect_ratio() const { if (auto image_data = this->image_data()) return image_data->intrinsic_aspect_ratio(); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h index ef5e000aaa..24f8220fa2 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h @@ -74,7 +74,7 @@ private: // ^Layout::ImageProvider virtual Optional intrinsic_width() const override; virtual Optional intrinsic_height() const override; - virtual Optional intrinsic_aspect_ratio() const override; + virtual Optional intrinsic_aspect_ratio() const override; virtual RefPtr current_image_bitmap(Gfx::IntSize = {}) const override; virtual void set_visible_in_viewport(bool) override; diff --git a/Userland/Libraries/LibWeb/Layout/Box.cpp b/Userland/Libraries/LibWeb/Layout/Box.cpp index a3be3a9268..d49a8968e2 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.cpp +++ b/Userland/Libraries/LibWeb/Layout/Box.cpp @@ -87,12 +87,12 @@ Painting::PaintableBox const* Box::paintable_box() const return static_cast(Node::paintable()); } -Optional Box::preferred_aspect_ratio() const +Optional Box::preferred_aspect_ratio() const { auto computed_aspect_ratio = computed_values().aspect_ratio(); if (computed_aspect_ratio.use_natural_aspect_ratio_if_available && natural_aspect_ratio().has_value()) return natural_aspect_ratio(); - return computed_aspect_ratio.preferred_ratio.map([](CSS::Ratio const& ratio) { return static_cast(ratio.value()); }); + return computed_aspect_ratio.preferred_ratio.map([](CSS::Ratio const& ratio) { return CSSPixelFraction(CSSPixels(ratio.numerator()), CSSPixels(ratio.denominator())); }); } } diff --git a/Userland/Libraries/LibWeb/Layout/Box.h b/Userland/Libraries/LibWeb/Layout/Box.h index 3b77e032a2..eff78c4b6b 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.h +++ b/Userland/Libraries/LibWeb/Layout/Box.h @@ -32,7 +32,7 @@ public: // https://www.w3.org/TR/css-images-3/#natural-dimensions Optional natural_width() const { return m_natural_width; } Optional natural_height() const { return m_natural_height; } - Optional natural_aspect_ratio() const { return m_natural_aspect_ratio; } + Optional natural_aspect_ratio() const { return m_natural_aspect_ratio; } bool has_natural_width() const { return natural_width().has_value(); } bool has_natural_height() const { return natural_height().has_value(); } @@ -40,10 +40,10 @@ public: void set_natural_width(Optional width) { m_natural_width = width; } void set_natural_height(Optional height) { m_natural_height = height; } - void set_natural_aspect_ratio(Optional ratio) { m_natural_aspect_ratio = ratio; } + void set_natural_aspect_ratio(Optional ratio) { m_natural_aspect_ratio = ratio; } // https://www.w3.org/TR/css-sizing-4/#preferred-aspect-ratio - Optional preferred_aspect_ratio() const; + Optional preferred_aspect_ratio() const; bool has_preferred_aspect_ratio() const { return preferred_aspect_ratio().has_value(); } virtual ~Box() override; @@ -65,7 +65,7 @@ private: Optional m_natural_width; Optional m_natural_height; - Optional m_natural_aspect_ratio; + Optional m_natural_aspect_ratio; }; template<> diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 633e345647..61f67908f6 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -537,18 +537,18 @@ CSS::FlexBasis FlexFormattingContext::used_flex_basis_for_item(FlexItem const& i 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()) - return CSSPixels::nearest_value_for(cross_size * aspect_ratio); - return CSSPixels::nearest_value_for(cross_size / aspect_ratio); + return 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()) - return CSSPixels::nearest_value_for(main_size / aspect_ratio); - return CSSPixels::nearest_value_for(main_size * aspect_ratio); + return 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 diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h index a710256dca..599300b32e 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h @@ -35,8 +35,8 @@ private: [[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 calculate_main_size_from_cross_size_and_aspect_ratio(CSSPixels cross_size, double aspect_ratio) const; - [[nodiscard]] CSSPixels calculate_cross_size_from_main_size_and_aspect_ratio(CSSPixels main_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, CSSPixelFraction aspect_ratio) const; void dump_items() const; diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 6e294513e7..77bae5258b 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -404,7 +404,7 @@ CSSPixels FormattingContext::tentative_width_for_replaced_element(Box const& box // (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()) || (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(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, @@ -498,7 +498,7 @@ CSSPixels FormattingContext::tentative_height_for_replaced_element(Box const& bo // // (used width) / (intrinsic ratio) if (computed_height.is_auto() && box.has_preferred_aspect_ratio()) - return CSSPixels::nearest_value_for(m_state.get(box).content_width() / static_cast(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'. 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 { if (box.has_preferred_aspect_ratio()) - return CSSPixels::nearest_value_for(width / static_cast(*box.preferred_aspect_ratio())); + return width / *box.preferred_aspect_ratio(); if (box.has_natural_height()) return *box.natural_height(); diff --git a/Userland/Libraries/LibWeb/Layout/ImageProvider.h b/Userland/Libraries/LibWeb/Layout/ImageProvider.h index 8d1455d698..878d31f9bd 100644 --- a/Userland/Libraries/LibWeb/Layout/ImageProvider.h +++ b/Userland/Libraries/LibWeb/Layout/ImageProvider.h @@ -17,7 +17,7 @@ public: virtual Optional intrinsic_width() const = 0; virtual Optional intrinsic_height() const = 0; - virtual Optional intrinsic_aspect_ratio() const = 0; + virtual Optional intrinsic_aspect_ratio() const = 0; virtual RefPtr current_image_bitmap(Gfx::IntSize) const = 0; virtual void set_visible_in_viewport(bool) = 0; diff --git a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp index 567e2261f6..3b19d2eec7 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp @@ -42,7 +42,7 @@ void SVGSVGBox::prepare_for_replaced_layout() set_natural_aspect_ratio(calculate_intrinsic_aspect_ratio()); } -Optional SVGSVGBox::calculate_intrinsic_aspect_ratio() const +Optional SVGSVGBox::calculate_intrinsic_aspect_ratio() const { // 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. @@ -57,7 +57,7 @@ Optional SVGSVGBox::calculate_intrinsic_aspect_ratio() const if (width != 0 && height != 0) { // 1. return width / height - return width.to_double() / height.to_double(); + return width / height; } return {}; @@ -73,7 +73,7 @@ Optional SVGSVGBox::calculate_intrinsic_aspect_ratio() const auto const& viewbox = dom_node().view_box().value(); // 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 diff --git a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h index 45bdffc31b..ae57bb4980 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h +++ b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h @@ -30,7 +30,7 @@ public: private: virtual bool is_svg_svg_box() const final { return true; } - [[nodiscard]] Optional calculate_intrinsic_aspect_ratio() const; + [[nodiscard]] Optional calculate_intrinsic_aspect_ratio() const; }; template<> diff --git a/Userland/Libraries/LibWeb/Layout/VideoBox.cpp b/Userland/Libraries/LibWeb/Layout/VideoBox.cpp index ed2b2f79b2..23c8dfa01d 100644 --- a/Userland/Libraries/LibWeb/Layout/VideoBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/VideoBox.cpp @@ -37,11 +37,11 @@ HTML::HTMLVideoElement const& VideoBox::dom_node() const void VideoBox::prepare_for_replaced_layout() { - auto width = static_cast(dom_node().video_width()); - set_natural_width(CSSPixels(width)); + CSSPixels width = dom_node().video_width(); + set_natural_width(width); - auto height = static_cast(dom_node().video_height()); - set_natural_height(CSSPixels(height)); + CSSPixels height = dom_node().video_height(); + set_natural_height(height); if (width != 0 && height != 0) set_natural_aspect_ratio(width / height); diff --git a/Userland/Libraries/LibWeb/PixelUnits.h b/Userland/Libraries/LibWeb/PixelUnits.h index 1ac118def8..e102531c2c 100644 --- a/Userland/Libraries/LibWeb/PixelUnits.h +++ b/Userland/Libraries/LibWeb/PixelUnits.h @@ -287,7 +287,7 @@ public: { } - constexpr CSSPixelFraction(CSSPixels value) + explicit constexpr CSSPixelFraction(CSSPixels value) : m_numerator(value) , m_denominator(1) { diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp index 839a00ad87..2224c38fa6 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp @@ -140,16 +140,16 @@ Optional SVGDecodedImageData::intrinsic_height() const return {}; } -Optional SVGDecodedImageData::intrinsic_aspect_ratio() const +Optional SVGDecodedImageData::intrinsic_aspect_ratio() const { // https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS auto width = intrinsic_width(); auto height = intrinsic_height(); 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()) - return viewbox->width / viewbox->height; + return CSSPixels::nearest_value_for(viewbox->width) / CSSPixels::nearest_value_for(viewbox->height); return {}; } diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h index 7eb8305235..7254832b7d 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h @@ -20,7 +20,7 @@ public: virtual Optional intrinsic_width() const override; virtual Optional intrinsic_height() const override; - virtual Optional intrinsic_aspect_ratio() const override; + virtual Optional intrinsic_aspect_ratio() const override; // FIXME: Support SVG animations. :^) virtual int frame_duration(size_t) const override { return 0; }