/src/serenity/Userland/Libraries/LibGfx/Rect.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> |
3 | | * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> |
4 | | * Copyright (c) 2022-2023, Jelle Raaijmakers <jelle@gmta.nl> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | */ |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include <AK/Format.h> |
12 | | #include <AK/Vector.h> |
13 | | #include <LibGfx/AffineTransform.h> |
14 | | #include <LibGfx/Line.h> |
15 | | #include <LibGfx/Orientation.h> |
16 | | #include <LibGfx/Point.h> |
17 | | #include <LibGfx/Size.h> |
18 | | #include <LibGfx/TextAlignment.h> |
19 | | #include <math.h> |
20 | | |
21 | | namespace Gfx { |
22 | | |
23 | | template<typename T> |
24 | | class Rect { |
25 | | public: |
26 | 32.6M | Rect() = default; Line | Count | Source | 26 | 32.6M | Rect() = default; |
Unexecuted instantiation: Gfx::Rect<float>::Rect() Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::Rect() Unexecuted instantiation: Gfx::Rect<double>::Rect() Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::Rect() |
27 | | |
28 | | Rect(T x, T y, T width, T height) |
29 | 17.4M | : m_location(x, y) |
30 | 17.4M | , m_size(width, height) |
31 | 17.4M | { |
32 | 17.4M | } Gfx::Rect<int>::Rect(int, int, int, int) Line | Count | Source | 29 | 15.0M | : m_location(x, y) | 30 | 15.0M | , m_size(width, height) | 31 | 15.0M | { | 32 | 15.0M | } |
Gfx::Rect<float>::Rect(float, float, float, float) Line | Count | Source | 29 | 2.40M | : m_location(x, y) | 30 | 2.40M | , m_size(width, height) | 31 | 2.40M | { | 32 | 2.40M | } |
Unexecuted instantiation: Gfx::Rect<double>::Rect(double, double, double, double) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::Rect(Web::CSSPixels, Web::CSSPixels, Web::CSSPixels, Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::Rect(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
33 | | |
34 | | template<typename U> |
35 | | Rect(U x, U y, U width, U height) |
36 | 15.1k | : m_location(x, y) |
37 | 15.1k | , m_size(width, height) |
38 | 15.1k | { |
39 | 15.1k | } Gfx::Rect<int>::Rect<unsigned short>(unsigned short, unsigned short, unsigned short, unsigned short) Line | Count | Source | 36 | 15.1k | : m_location(x, y) | 37 | 15.1k | , m_size(width, height) | 38 | 15.1k | { | 39 | 15.1k | } |
Unexecuted instantiation: Gfx::Rect<int>::Rect<AK::BigEndian<unsigned int> >(AK::BigEndian<unsigned int>, AK::BigEndian<unsigned int>, AK::BigEndian<unsigned int>, AK::BigEndian<unsigned int>) Unexecuted instantiation: Gfx::Rect<int>::Rect<unsigned int>(unsigned int, unsigned int, unsigned int, unsigned int) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::Rect<double>(double, double, double, double) Unexecuted instantiation: Gfx::Rect<float>::Rect<double>(double, double, double, double) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::Rect<double>(double, double, double, double) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::Rect<float>(float, float, float, float) Unexecuted instantiation: Gfx::Rect<float>::Rect<int>(int, int, int, int) |
40 | | |
41 | | Rect(Point<T> const& location, Size<T> const& size) |
42 | 244M | : m_location(location) |
43 | 244M | , m_size(size) |
44 | 244M | { |
45 | 244M | } Gfx::Rect<int>::Rect(Gfx::Point<int> const&, Gfx::Size<int> const&) Line | Count | Source | 42 | 244M | : m_location(location) | 43 | 244M | , m_size(size) | 44 | 244M | { | 45 | 244M | } |
Gfx::Rect<float>::Rect(Gfx::Point<float> const&, Gfx::Size<float> const&) Line | Count | Source | 42 | 730 | : m_location(location) | 43 | 730 | , m_size(size) | 44 | 730 | { | 45 | 730 | } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::Rect(Gfx::Point<Web::CSSPixels> const&, Gfx::Size<Web::CSSPixels> const&) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::Rect(Gfx::Point<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> > const&, Gfx::Size<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> > const&) |
46 | | |
47 | | template<typename U> |
48 | | Rect(Point<U> const& location, Size<U> const& size) |
49 | 730 | : m_location(location) |
50 | 730 | , m_size(size) |
51 | 730 | { |
52 | 730 | } Gfx::Rect<float>::Rect<int>(Gfx::Point<int> const&, Gfx::Size<int> const&) Line | Count | Source | 49 | 730 | : m_location(location) | 50 | 730 | , m_size(size) | 51 | 730 | { | 52 | 730 | } |
Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::Rect<double>(Gfx::Point<double> const&, Gfx::Size<double> const&) Unexecuted instantiation: Gfx::Rect<int>::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >(Gfx::Point<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> > const&, Gfx::Size<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> > const&) |
53 | | |
54 | | template<typename U> |
55 | | explicit Rect(Rect<U> const& other) |
56 | 730 | : m_location(other.location()) |
57 | 730 | , m_size(other.size()) |
58 | 730 | { |
59 | 730 | } Gfx::Rect<float>::Rect<int>(Gfx::Rect<int> const&) Line | Count | Source | 56 | 730 | : m_location(other.location()) | 57 | 730 | , m_size(other.size()) | 58 | 730 | { | 59 | 730 | } |
Unexecuted instantiation: Gfx::Rect<int>::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >(Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> > const&) Unexecuted instantiation: Gfx::Rect<float>::Rect<double>(Gfx::Rect<double> const&) Unexecuted instantiation: Gfx::Rect<float>::Rect<Web::CSSPixels>(Gfx::Rect<Web::CSSPixels> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::Rect<float>(Gfx::Rect<float> const&) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::Rect<int>(Gfx::Rect<int> const&) Unexecuted instantiation: Gfx::Rect<int>::Rect<float>(Gfx::Rect<float> const&) |
60 | | |
61 | 839M | [[nodiscard]] ALWAYS_INLINE T x() const { return location().x(); } Gfx::Rect<float>::x() const Line | Count | Source | 61 | 9.50M | [[nodiscard]] ALWAYS_INLINE T x() const { return location().x(); } |
Gfx::Rect<int>::x() const Line | Count | Source | 61 | 830M | [[nodiscard]] ALWAYS_INLINE T x() const { return location().x(); } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::x() const Unexecuted instantiation: Gfx::Rect<double>::x() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::x() const |
62 | 835M | [[nodiscard]] ALWAYS_INLINE T y() const { return location().y(); } Gfx::Rect<float>::y() const Line | Count | Source | 62 | 9.50M | [[nodiscard]] ALWAYS_INLINE T y() const { return location().y(); } |
Gfx::Rect<int>::y() const Line | Count | Source | 62 | 825M | [[nodiscard]] ALWAYS_INLINE T y() const { return location().y(); } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::y() const Unexecuted instantiation: Gfx::Rect<double>::y() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::y() const |
63 | 514M | [[nodiscard]] ALWAYS_INLINE T width() const { return m_size.width(); } Gfx::Rect<float>::width() const Line | Count | Source | 63 | 4.75M | [[nodiscard]] ALWAYS_INLINE T width() const { return m_size.width(); } |
Gfx::Rect<int>::width() const Line | Count | Source | 63 | 509M | [[nodiscard]] ALWAYS_INLINE T width() const { return m_size.width(); } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::width() const Unexecuted instantiation: Gfx::Rect<double>::width() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::width() const |
64 | 503M | [[nodiscard]] ALWAYS_INLINE T height() const { return m_size.height(); } Gfx::Rect<float>::height() const Line | Count | Source | 64 | 4.75M | [[nodiscard]] ALWAYS_INLINE T height() const { return m_size.height(); } |
Gfx::Rect<int>::height() const Line | Count | Source | 64 | 498M | [[nodiscard]] ALWAYS_INLINE T height() const { return m_size.height(); } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::height() const Unexecuted instantiation: Gfx::Rect<double>::height() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::height() const |
65 | | |
66 | 20.9M | ALWAYS_INLINE void set_x(T x) { m_location.set_x(x); } Gfx::Rect<int>::set_x(int) Line | Count | Source | 66 | 20.9M | ALWAYS_INLINE void set_x(T x) { m_location.set_x(x); } |
Gfx::Rect<float>::set_x(float) Line | Count | Source | 66 | 730 | ALWAYS_INLINE void set_x(T x) { m_location.set_x(x); } |
Unexecuted instantiation: Gfx::Rect<double>::set_x(double) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_x(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_x(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
67 | 20.9M | ALWAYS_INLINE void set_y(T y) { m_location.set_y(y); } Gfx::Rect<int>::set_y(int) Line | Count | Source | 67 | 20.9M | ALWAYS_INLINE void set_y(T y) { m_location.set_y(y); } |
Gfx::Rect<float>::set_y(float) Line | Count | Source | 67 | 730 | ALWAYS_INLINE void set_y(T y) { m_location.set_y(y); } |
Unexecuted instantiation: Gfx::Rect<double>::set_y(double) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_y(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_y(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
68 | 20.9M | ALWAYS_INLINE void set_width(T width) { m_size.set_width(width); } Gfx::Rect<int>::set_width(int) Line | Count | Source | 68 | 20.9M | ALWAYS_INLINE void set_width(T width) { m_size.set_width(width); } |
Unexecuted instantiation: Gfx::Rect<float>::set_width(float) Unexecuted instantiation: Gfx::Rect<double>::set_width(double) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_width(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_width(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
69 | 20.9M | ALWAYS_INLINE void set_height(T height) { m_size.set_height(height); } Gfx::Rect<int>::set_height(int) Line | Count | Source | 69 | 20.9M | ALWAYS_INLINE void set_height(T height) { m_size.set_height(height); } |
Unexecuted instantiation: Gfx::Rect<float>::set_height(float) Unexecuted instantiation: Gfx::Rect<double>::set_height(double) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_height(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_height(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
70 | | |
71 | 1.79G | [[nodiscard]] ALWAYS_INLINE Point<T> const& location() const { return m_location; } Gfx::Rect<float>::location() const Line | Count | Source | 71 | 19.0M | [[nodiscard]] ALWAYS_INLINE Point<T> const& location() const { return m_location; } |
Gfx::Rect<int>::location() const Line | Count | Source | 71 | 1.77G | [[nodiscard]] ALWAYS_INLINE Point<T> const& location() const { return m_location; } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::location() const Unexecuted instantiation: Gfx::Rect<double>::location() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::location() const |
72 | 1.71M | [[nodiscard]] ALWAYS_INLINE Size<T> const& size() const { return m_size; } Gfx::Rect<int>::size() const Line | Count | Source | 72 | 1.71M | [[nodiscard]] ALWAYS_INLINE Size<T> const& size() const { return m_size; } |
Gfx::Rect<float>::size() const Line | Count | Source | 72 | 730 | [[nodiscard]] ALWAYS_INLINE Size<T> const& size() const { return m_size; } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::size() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::size() const Unexecuted instantiation: Gfx::Rect<double>::size() const |
73 | | |
74 | 528k | [[nodiscard]] ALWAYS_INLINE bool is_empty() const { return width() <= 0 || height() <= 0; } Gfx::Rect<int>::is_empty() const Line | Count | Source | 74 | 528k | [[nodiscard]] ALWAYS_INLINE bool is_empty() const { return width() <= 0 || height() <= 0; } |
Unexecuted instantiation: Gfx::Rect<double>::is_empty() const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::is_empty() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::is_empty() const |
75 | | |
76 | 0 | ALWAYS_INLINE void translate_by(T dx, T dy) { m_location.translate_by(dx, dy); } Unexecuted instantiation: Gfx::Rect<float>::translate_by(float, float) Unexecuted instantiation: Gfx::Rect<int>::translate_by(int, int) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::translate_by(Web::CSSPixels, Web::CSSPixels) |
77 | | ALWAYS_INLINE void translate_by(T dboth) { m_location.translate_by(dboth); } |
78 | 1.08M | ALWAYS_INLINE void translate_by(Point<T> const& delta) { m_location.translate_by(delta); } Gfx::Rect<int>::translate_by(Gfx::Point<int> const&) Line | Count | Source | 78 | 540k | ALWAYS_INLINE void translate_by(Point<T> const& delta) { m_location.translate_by(delta); } |
Gfx::Rect<float>::translate_by(Gfx::Point<float> const&) Line | Count | Source | 78 | 540k | ALWAYS_INLINE void translate_by(Point<T> const& delta) { m_location.translate_by(delta); } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::translate_by(Gfx::Point<Web::CSSPixels> const&) |
79 | | |
80 | | ALWAYS_INLINE void scale_by(T dx, T dy) |
81 | | { |
82 | | m_location.scale_by(dx, dy); |
83 | | m_size.scale_by(dx, dy); |
84 | | } |
85 | | ALWAYS_INLINE void scale_by(T dboth) { scale_by(dboth, dboth); } |
86 | | ALWAYS_INLINE void scale_by(Point<T> const& delta) { scale_by(delta.x(), delta.y()); } |
87 | | |
88 | | void transform_by(AffineTransform const& transform) { *this = transform.map(*this); } |
89 | | |
90 | | [[nodiscard]] Point<T> center() const |
91 | 1.46k | { |
92 | 1.46k | return { x() + width() / 2, y() + height() / 2 }; |
93 | 1.46k | } Unexecuted instantiation: Gfx::Rect<int>::center() const Gfx::Rect<float>::center() const Line | Count | Source | 91 | 1.46k | { | 92 | 1.46k | return { x() + width() / 2, y() + height() / 2 }; | 93 | 1.46k | } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::center() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::center() const |
94 | | |
95 | | ALWAYS_INLINE void set_location(Point<T> const& location) |
96 | 27.3M | { |
97 | 27.3M | m_location = location; |
98 | 27.3M | } Gfx::Rect<int>::set_location(Gfx::Point<int> const&) Line | Count | Source | 96 | 27.3M | { | 97 | 27.3M | m_location = location; | 98 | 27.3M | } |
Unexecuted instantiation: Gfx::Rect<float>::set_location(Gfx::Point<float> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_location(Gfx::Point<Web::CSSPixels> const&) |
99 | | |
100 | | ALWAYS_INLINE void set_size(Size<T> const& size) |
101 | 0 | { |
102 | 0 | m_size = size; |
103 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::set_size(Gfx::Size<int> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_size(Gfx::Size<Web::CSSPixels> const&) |
104 | | |
105 | | void set_size(T width, T height) |
106 | 0 | { |
107 | 0 | m_size.set_width(width); |
108 | 0 | m_size.set_height(height); |
109 | 0 | } |
110 | | |
111 | | void inflate(T w, T h) |
112 | 0 | { |
113 | 0 | set_x(x() - w / 2); |
114 | 0 | set_width(width() + w); |
115 | 0 | set_y(y() - h / 2); |
116 | 0 | set_height(height() + h); |
117 | 0 | } Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::inflate(Web::CSSPixels, Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<int>::inflate(int, int) |
118 | | |
119 | | void inflate(T top, T right, T bottom, T left) |
120 | 0 | { |
121 | 0 | set_x(x() - left); |
122 | 0 | set_width(width() + left + right); |
123 | 0 | set_y(y() - top); |
124 | 0 | set_height(height() + top + bottom); |
125 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::inflate(int, int, int, int) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::inflate(Web::CSSPixels, Web::CSSPixels, Web::CSSPixels, Web::CSSPixels) |
126 | | |
127 | | void inflate(Size<T> const& size) |
128 | 0 | { |
129 | 0 | set_x(x() - size.width() / 2); |
130 | 0 | set_width(width() + size.width()); |
131 | 0 | set_y(y() - size.height() / 2); |
132 | 0 | set_height(height() + size.height()); |
133 | 0 | } |
134 | | |
135 | | void shrink(T w, T h) |
136 | 0 | { |
137 | 0 | set_x(x() + w / 2); |
138 | 0 | set_width(width() - w); |
139 | 0 | set_y(y() + h / 2); |
140 | 0 | set_height(height() - h); |
141 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::shrink(int, int) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::shrink(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
142 | | |
143 | | void shrink(T top, T right, T bottom, T left) |
144 | 0 | { |
145 | 0 | set_x(x() + left); |
146 | 0 | set_width(width() - (left + right)); |
147 | 0 | set_y(y() + top); |
148 | 0 | set_height(height() - (top + bottom)); |
149 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::shrink(int, int, int, int) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::shrink(Web::CSSPixels, Web::CSSPixels, Web::CSSPixels, Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::shrink(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
150 | | |
151 | | void shrink(Size<T> const& size) |
152 | | { |
153 | | set_x(x() + size.width() / 2); |
154 | | set_width(width() - size.width()); |
155 | | set_y(y() + size.height() / 2); |
156 | | set_height(height() - size.height()); |
157 | | } |
158 | | |
159 | | [[nodiscard]] Rect<T> translated(T dx, T dy) const |
160 | 0 | { |
161 | 0 | Rect<T> rect = *this; |
162 | 0 | rect.translate_by(dx, dy); |
163 | 0 | return rect; |
164 | 0 | } Unexecuted instantiation: Gfx::Rect<float>::translated(float, float) const Unexecuted instantiation: Gfx::Rect<int>::translated(int, int) const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::translated(Web::CSSPixels, Web::CSSPixels) const |
165 | | |
166 | | [[nodiscard]] Rect<T> translated(T dboth) const |
167 | | { |
168 | | Rect<T> rect = *this; |
169 | | rect.translate_by(dboth); |
170 | | return rect; |
171 | | } |
172 | | |
173 | | [[nodiscard]] Rect<T> translated(Point<T> const& delta) const |
174 | 1.08M | { |
175 | 1.08M | Rect<T> rect = *this; |
176 | 1.08M | rect.translate_by(delta); |
177 | 1.08M | return rect; |
178 | 1.08M | } Gfx::Rect<int>::translated(Gfx::Point<int> const&) const Line | Count | Source | 174 | 540k | { | 175 | 540k | Rect<T> rect = *this; | 176 | 540k | rect.translate_by(delta); | 177 | 540k | return rect; | 178 | 540k | } |
Gfx::Rect<float>::translated(Gfx::Point<float> const&) const Line | Count | Source | 174 | 540k | { | 175 | 540k | Rect<T> rect = *this; | 176 | 540k | rect.translate_by(delta); | 177 | 540k | return rect; | 178 | 540k | } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::translated(Gfx::Point<Web::CSSPixels> const&) const |
179 | | |
180 | | [[nodiscard]] Rect<T> scaled(T dboth) const |
181 | | { |
182 | | Rect<T> rect = *this; |
183 | | rect.scale_by(dboth); |
184 | | return rect; |
185 | | } |
186 | | |
187 | | [[nodiscard]] Rect<T> scaled(T sx, T sy) const |
188 | | { |
189 | | Rect<T> rect = *this; |
190 | | rect.scale_by(sx, sy); |
191 | | return rect; |
192 | | } |
193 | | |
194 | | [[nodiscard]] Rect<T> scaled(Point<T> const& s) const |
195 | | { |
196 | | Rect<T> rect = *this; |
197 | | rect.scale_by(s); |
198 | | return rect; |
199 | | } |
200 | | |
201 | | [[nodiscard]] Rect<T> transformed(AffineTransform const& transform) const |
202 | | { |
203 | | Rect<T> rect = *this; |
204 | | rect.transform_by(transform); |
205 | | return rect; |
206 | | } |
207 | | |
208 | | [[nodiscard]] Rect<T> shrunken(T w, T h) const |
209 | 0 | { |
210 | 0 | Rect<T> rect = *this; |
211 | 0 | rect.shrink(w, h); |
212 | 0 | return rect; |
213 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::shrunken(int, int) const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::shrunken(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) const |
214 | | |
215 | | [[nodiscard]] Rect<T> shrunken(T top, T right, T bottom, T left) const |
216 | 0 | { |
217 | 0 | Rect<T> rect = *this; |
218 | 0 | rect.shrink(top, right, bottom, left); |
219 | 0 | return rect; |
220 | 0 | } |
221 | | |
222 | | [[nodiscard]] Rect<T> shrunken(Size<T> const& size) const |
223 | | { |
224 | | Rect<T> rect = *this; |
225 | | rect.shrink(size); |
226 | | return rect; |
227 | | } |
228 | | |
229 | | [[nodiscard]] Rect<T> inflated(T w, T h) const |
230 | 0 | { |
231 | 0 | Rect<T> rect = *this; |
232 | 0 | rect.inflate(w, h); |
233 | 0 | return rect; |
234 | 0 | } |
235 | | |
236 | | [[nodiscard]] Rect<T> inflated(T top, T right, T bottom, T left) const |
237 | 0 | { |
238 | 0 | Rect<T> rect = *this; |
239 | 0 | rect.inflate(top, right, bottom, left); |
240 | 0 | return rect; |
241 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::inflated(int, int, int, int) const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::inflated(Web::CSSPixels, Web::CSSPixels, Web::CSSPixels, Web::CSSPixels) const |
242 | | |
243 | | [[nodiscard]] Rect<T> inflated(Size<T> const& size) const |
244 | 0 | { |
245 | 0 | Rect<T> rect = *this; |
246 | 0 | rect.inflate(size); |
247 | 0 | return rect; |
248 | 0 | } |
249 | | |
250 | | Rect<T> take_from_right(T w) |
251 | 0 | { |
252 | 0 | if (w > width()) |
253 | 0 | w = width(); |
254 | 0 | Rect<T> rect = *this; |
255 | 0 | set_width(width() - w); |
256 | 0 | rect.set_x(x() + width()); |
257 | 0 | rect.set_width(w); |
258 | 0 | return rect; |
259 | 0 | } |
260 | | |
261 | | Rect<T> take_from_left(T w) |
262 | 0 | { |
263 | 0 | if (w > width()) |
264 | 0 | w = width(); |
265 | 0 | Rect<T> rect = *this; |
266 | 0 | set_x(x() + w); |
267 | 0 | set_width(width() - w); |
268 | 0 | rect.set_width(w); |
269 | 0 | return rect; |
270 | 0 | } |
271 | | |
272 | | Rect<T> take_from_top(T h) |
273 | 0 | { |
274 | 0 | if (h > height()) |
275 | 0 | h = height(); |
276 | 0 | Rect<T> rect = *this; |
277 | 0 | set_y(y() + h); |
278 | 0 | set_height(height() - h); |
279 | 0 | rect.set_height(h); |
280 | 0 | return rect; |
281 | 0 | } |
282 | | |
283 | | Rect<T> take_from_bottom(T h) |
284 | | { |
285 | | if (h > height()) |
286 | | h = height(); |
287 | | Rect<T> rect = *this; |
288 | | set_height(height() - h); |
289 | | rect.set_y(y() + height()); |
290 | | rect.set_height(h); |
291 | | return rect; |
292 | | } |
293 | | |
294 | | [[nodiscard]] bool contains_vertically(T y) const |
295 | 219M | { |
296 | 219M | return y >= top() && y < bottom(); |
297 | 219M | } Gfx::Rect<int>::contains_vertically(int) const Line | Count | Source | 295 | 219M | { | 296 | 219M | return y >= top() && y < bottom(); | 297 | 219M | } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::contains_vertically(Web::CSSPixels) const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::contains_vertically(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) const |
298 | | |
299 | | [[nodiscard]] bool contains_horizontally(T x) const |
300 | 220M | { |
301 | 220M | return x >= left() && x < right(); |
302 | 220M | } Gfx::Rect<int>::contains_horizontally(int) const Line | Count | Source | 300 | 220M | { | 301 | 220M | return x >= left() && x < right(); | 302 | 220M | } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::contains_horizontally(Web::CSSPixels) const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::contains_horizontally(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) const |
303 | | |
304 | | [[nodiscard]] bool contains(T x, T y) const |
305 | 220M | { |
306 | 220M | return contains_horizontally(x) && contains_vertically(y); |
307 | 220M | } Gfx::Rect<int>::contains(int, int) const Line | Count | Source | 305 | 220M | { | 306 | 220M | return contains_horizontally(x) && contains_vertically(y); | 307 | 220M | } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::contains(Web::CSSPixels, Web::CSSPixels) const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::contains(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>, AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) const |
308 | | |
309 | | [[nodiscard]] ALWAYS_INLINE bool contains(Point<T> const& point) const |
310 | 0 | { |
311 | 0 | return contains(point.x(), point.y()); |
312 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::contains(Gfx::Point<int> const&) const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::contains(Gfx::Point<Web::CSSPixels> const&) const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::contains(Gfx::Point<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> > const&) const |
313 | | |
314 | | [[nodiscard]] bool contains(Rect<T> const& other) const |
315 | 0 | { |
316 | 0 | return left() <= other.left() |
317 | 0 | && right() >= other.right() |
318 | 0 | && top() <= other.top() |
319 | 0 | && bottom() >= other.bottom(); |
320 | 0 | } Unexecuted instantiation: Gfx::Rect<int>::contains(Gfx::Rect<int> const&) const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::contains(Gfx::Rect<Web::CSSPixels> const&) const |
321 | | |
322 | | template<typename Container> |
323 | | [[nodiscard]] bool contains(Container const& others) const |
324 | | { |
325 | | bool have_any = false; |
326 | | for (auto const& other : others) { |
327 | | if (!contains(other)) |
328 | | return false; |
329 | | have_any = true; |
330 | | } |
331 | | return have_any; |
332 | | } |
333 | | |
334 | | [[nodiscard]] ALWAYS_INLINE T primary_offset_for_orientation(Orientation orientation) const { return m_location.primary_offset_for_orientation(orientation); } |
335 | | ALWAYS_INLINE void set_primary_offset_for_orientation(Orientation orientation, T value) { m_location.set_primary_offset_for_orientation(orientation, value); } |
336 | | [[nodiscard]] ALWAYS_INLINE T secondary_offset_for_orientation(Orientation orientation) const { return m_location.secondary_offset_for_orientation(orientation); } |
337 | | ALWAYS_INLINE void set_secondary_offset_for_orientation(Orientation orientation, T value) { m_location.set_secondary_offset_for_orientation(orientation, value); } |
338 | | |
339 | | [[nodiscard]] ALWAYS_INLINE T primary_size_for_orientation(Orientation orientation) const { return m_size.primary_size_for_orientation(orientation); } |
340 | | [[nodiscard]] ALWAYS_INLINE T secondary_size_for_orientation(Orientation orientation) const { return m_size.secondary_size_for_orientation(orientation); } |
341 | | ALWAYS_INLINE void set_primary_size_for_orientation(Orientation orientation, T value) { m_size.set_primary_size_for_orientation(orientation, value); } |
342 | | ALWAYS_INLINE void set_secondary_size_for_orientation(Orientation orientation, T value) { m_size.set_secondary_size_for_orientation(orientation, value); } |
343 | | |
344 | | [[nodiscard]] T first_edge_for_orientation(Orientation orientation) const |
345 | | { |
346 | | if (orientation == Orientation::Vertical) |
347 | | return top(); |
348 | | return left(); |
349 | | } |
350 | | |
351 | | [[nodiscard]] T last_edge_for_orientation(Orientation orientation) const |
352 | | { |
353 | | if (orientation == Orientation::Vertical) |
354 | | return bottom(); |
355 | | return right(); |
356 | | } |
357 | | |
358 | 312M | [[nodiscard]] ALWAYS_INLINE T left() const { return x(); } Gfx::Rect<int>::left() const Line | Count | Source | 358 | 312M | [[nodiscard]] ALWAYS_INLINE T left() const { return x(); } |
Unexecuted instantiation: Gfx::Rect<float>::left() const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::left() const Unexecuted instantiation: Gfx::Rect<double>::left() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::left() const |
359 | 491M | [[nodiscard]] ALWAYS_INLINE T right() const { return x() + width(); } Gfx::Rect<float>::right() const Line | Count | Source | 359 | 1.33M | [[nodiscard]] ALWAYS_INLINE T right() const { return x() + width(); } |
Gfx::Rect<int>::right() const Line | Count | Source | 359 | 490M | [[nodiscard]] ALWAYS_INLINE T right() const { return x() + width(); } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::right() const Unexecuted instantiation: Gfx::Rect<double>::right() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::right() const |
360 | 309M | [[nodiscard]] ALWAYS_INLINE T top() const { return y(); } Gfx::Rect<int>::top() const Line | Count | Source | 360 | 309M | [[nodiscard]] ALWAYS_INLINE T top() const { return y(); } |
Unexecuted instantiation: Gfx::Rect<float>::top() const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::top() const Unexecuted instantiation: Gfx::Rect<double>::top() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::top() const |
361 | 489M | [[nodiscard]] ALWAYS_INLINE T bottom() const { return y() + height(); } Gfx::Rect<float>::bottom() const Line | Count | Source | 361 | 1.33M | [[nodiscard]] ALWAYS_INLINE T bottom() const { return y() + height(); } |
Gfx::Rect<int>::bottom() const Line | Count | Source | 361 | 488M | [[nodiscard]] ALWAYS_INLINE T bottom() const { return y() + height(); } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::bottom() const Unexecuted instantiation: Gfx::Rect<double>::bottom() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::bottom() const |
362 | | |
363 | 0 | ALWAYS_INLINE void set_left(T left) { set_x(left); } Unexecuted instantiation: Gfx::Rect<double>::set_left(double) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_left(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_left(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
364 | 0 | ALWAYS_INLINE void set_top(T top) { set_y(top); } Unexecuted instantiation: Gfx::Rect<double>::set_top(double) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_top(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_top(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
365 | 20.9M | ALWAYS_INLINE void set_right(T right) { set_width(right - x()); } Gfx::Rect<int>::set_right(int) Line | Count | Source | 365 | 20.9M | ALWAYS_INLINE void set_right(T right) { set_width(right - x()); } |
Unexecuted instantiation: Gfx::Rect<float>::set_right(float) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_right(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<double>::set_right(double) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_right(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
366 | 20.9M | ALWAYS_INLINE void set_bottom(T bottom) { set_height(bottom - y()); } Gfx::Rect<int>::set_bottom(int) Line | Count | Source | 366 | 20.9M | ALWAYS_INLINE void set_bottom(T bottom) { set_height(bottom - y()); } |
Unexecuted instantiation: Gfx::Rect<float>::set_bottom(float) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::set_bottom(Web::CSSPixels) Unexecuted instantiation: Gfx::Rect<double>::set_bottom(double) Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::set_bottom(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>) |
367 | | |
368 | | void set_right_without_resize(T new_right) |
369 | 0 | { |
370 | 0 | auto delta = new_right - right(); |
371 | 0 | translate_by(delta, 0); |
372 | 0 | } |
373 | | |
374 | | void set_bottom_without_resize(T new_bottom) |
375 | 0 | { |
376 | 0 | auto delta = new_bottom - bottom(); |
377 | 0 | translate_by(0, delta); |
378 | 0 | } |
379 | | |
380 | | [[nodiscard]] bool intersects_vertically(Rect<T> const& other) const |
381 | | { |
382 | | return top() < other.bottom() && other.top() < bottom(); |
383 | | } |
384 | | |
385 | | [[nodiscard]] bool intersects_horizontally(Rect<T> const& other) const |
386 | | { |
387 | | return left() < other.right() && other.left() < right(); |
388 | | } |
389 | | |
390 | | [[nodiscard]] bool intersects(Rect<T> const& other) const |
391 | 0 | { |
392 | 0 | return left() < other.right() |
393 | 0 | && other.left() < right() |
394 | 0 | && top() < other.bottom() |
395 | 0 | && other.top() < bottom(); |
396 | 0 | } Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::intersects(Gfx::Rect<Web::CSSPixels> const&) const Unexecuted instantiation: Gfx::Rect<int>::intersects(Gfx::Rect<int> const&) const |
397 | | |
398 | | template<typename Container> |
399 | | [[nodiscard]] bool intersects(Container const& others) const |
400 | | { |
401 | | for (auto const& other : others) { |
402 | | if (intersects(other)) |
403 | | return true; |
404 | | } |
405 | | return false; |
406 | | } |
407 | | |
408 | | template<typename Container, typename Function> |
409 | | IterationDecision for_each_intersected(Container const& others, Function f) const |
410 | | { |
411 | | if (is_empty()) |
412 | | return IterationDecision::Continue; |
413 | | for (auto const& other : others) { |
414 | | auto intersected_rect = intersected(other); |
415 | | if (!intersected_rect.is_empty()) { |
416 | | IterationDecision decision = f(intersected_rect); |
417 | | if (decision != IterationDecision::Continue) |
418 | | return decision; |
419 | | } |
420 | | } |
421 | | return IterationDecision::Continue; |
422 | | } |
423 | | |
424 | | [[nodiscard]] Vector<Rect<T>, 4> shatter(Rect<T> const& hammer) const |
425 | 0 | { |
426 | 0 | Vector<Rect<T>, 4> pieces; |
427 | 0 | if (!intersects(hammer)) { |
428 | 0 | pieces.unchecked_append(*this); |
429 | 0 | return pieces; |
430 | 0 | } |
431 | 0 | Rect<T> top_shard { |
432 | 0 | x(), |
433 | 0 | y(), |
434 | 0 | width(), |
435 | 0 | hammer.y() - y(), |
436 | 0 | }; |
437 | 0 | Rect<T> bottom_shard { |
438 | 0 | x(), |
439 | 0 | hammer.bottom(), |
440 | 0 | width(), |
441 | 0 | bottom() - hammer.bottom(), |
442 | 0 | }; |
443 | 0 | Rect<T> left_shard { |
444 | 0 | x(), |
445 | 0 | max(hammer.y(), y()), |
446 | 0 | hammer.x() - x(), |
447 | 0 | min(hammer.bottom(), bottom()) - max(hammer.y(), y()), |
448 | 0 | }; |
449 | 0 | Rect<T> right_shard { |
450 | 0 | hammer.right(), |
451 | 0 | max(hammer.y(), y()), |
452 | 0 | right() - hammer.right(), |
453 | 0 | min(hammer.bottom(), bottom()) - max(hammer.y(), y()), |
454 | 0 | }; |
455 | 0 | if (!top_shard.is_empty()) |
456 | 0 | pieces.unchecked_append(top_shard); |
457 | 0 | if (!bottom_shard.is_empty()) |
458 | 0 | pieces.unchecked_append(bottom_shard); |
459 | 0 | if (!left_shard.is_empty()) |
460 | 0 | pieces.unchecked_append(left_shard); |
461 | 0 | if (!right_shard.is_empty()) |
462 | 0 | pieces.unchecked_append(right_shard); |
463 | |
|
464 | 0 | return pieces; |
465 | 0 | } |
466 | | |
467 | | template<class U> |
468 | | [[nodiscard]] bool operator==(Rect<U> const& other) const |
469 | 25.3k | { |
470 | 25.3k | return location() == other.location() && size() == other.size(); |
471 | 25.3k | } bool Gfx::Rect<int>::operator==<int>(Gfx::Rect<int> const&) const Line | Count | Source | 469 | 25.3k | { | 470 | 25.3k | return location() == other.location() && size() == other.size(); | 471 | 25.3k | } |
Unexecuted instantiation: bool Gfx::Rect<float>::operator==<int>(Gfx::Rect<int> const&) const Unexecuted instantiation: bool Gfx::Rect<int>::operator==<float>(Gfx::Rect<float> const&) const Unexecuted instantiation: bool Gfx::Rect<Web::CSSPixels>::operator==<Web::CSSPixels>(Gfx::Rect<Web::CSSPixels> const&) const Unexecuted instantiation: bool Gfx::Rect<float>::operator==<float>(Gfx::Rect<float> const&) const |
472 | | |
473 | 317 | [[nodiscard]] Rect<T> operator*(T factor) const { return { m_location * factor, m_size * factor }; } Gfx::Rect<int>::operator*(int) const Line | Count | Source | 473 | 317 | [[nodiscard]] Rect<T> operator*(T factor) const { return { m_location * factor, m_size * factor }; } |
Unexecuted instantiation: Gfx::Rect<float>::operator*(float) const |
474 | | |
475 | | Rect<T>& operator*=(T factor) |
476 | 198 | { |
477 | 198 | m_location *= factor; |
478 | 198 | m_size *= factor; |
479 | 198 | return *this; |
480 | 198 | } |
481 | | |
482 | | [[nodiscard]] Rect<T> operator/(T factor) const { return { m_location / factor, m_size / factor }; } |
483 | | |
484 | | Rect<T>& operator/=(T factor) |
485 | | { |
486 | | m_location /= factor; |
487 | | m_size /= factor; |
488 | | return *this; |
489 | | } |
490 | | |
491 | | void intersect(Rect<T> const& other) |
492 | 28.2M | { |
493 | 28.2M | T l = max(left(), other.left()); |
494 | 28.2M | T r = min(right(), other.right()); |
495 | 28.2M | T t = max(top(), other.top()); |
496 | 28.2M | T b = min(bottom(), other.bottom()); |
497 | | |
498 | 28.2M | if (l > r || t > b) { |
499 | 7.30M | m_location = {}; |
500 | 7.30M | m_size = {}; |
501 | 7.30M | return; |
502 | 7.30M | } |
503 | | |
504 | 20.9M | set_x(l); |
505 | 20.9M | set_y(t); |
506 | 20.9M | set_right(r); |
507 | 20.9M | set_bottom(b); |
508 | 20.9M | } Gfx::Rect<int>::intersect(Gfx::Rect<int> const&) Line | Count | Source | 492 | 28.2M | { | 493 | 28.2M | T l = max(left(), other.left()); | 494 | 28.2M | T r = min(right(), other.right()); | 495 | 28.2M | T t = max(top(), other.top()); | 496 | 28.2M | T b = min(bottom(), other.bottom()); | 497 | | | 498 | 28.2M | if (l > r || t > b) { | 499 | 7.30M | m_location = {}; | 500 | 7.30M | m_size = {}; | 501 | 7.30M | return; | 502 | 7.30M | } | 503 | | | 504 | 20.9M | set_x(l); | 505 | 20.9M | set_y(t); | 506 | 20.9M | set_right(r); | 507 | 20.9M | set_bottom(b); | 508 | 20.9M | } |
Unexecuted instantiation: Gfx::Rect<float>::intersect(Gfx::Rect<float> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::intersect(Gfx::Rect<Web::CSSPixels> const&) |
509 | | |
510 | | [[nodiscard]] static Rect<T> centered_on(Point<T> const& center, Size<T> const& size) |
511 | 0 | { |
512 | 0 | return { { center.x() - size.width() / 2, center.y() - size.height() / 2 }, size }; |
513 | 0 | } |
514 | | |
515 | | [[nodiscard]] static Rect<T> from_two_points(Point<T> const& a, Point<T> const& b) |
516 | 4.77M | { |
517 | 4.77M | return { min(a.x(), b.x()), min(a.y(), b.y()), AK::abs(a.x() - b.x()), AK::abs(a.y() - b.y()) }; |
518 | 4.77M | } Gfx::Rect<int>::from_two_points(Gfx::Point<int> const&, Gfx::Point<int> const&) Line | Count | Source | 516 | 4.77M | { | 517 | 4.77M | return { min(a.x(), b.x()), min(a.y(), b.y()), AK::abs(a.x() - b.x()), AK::abs(a.y() - b.y()) }; | 518 | 4.77M | } |
Unexecuted instantiation: Gfx::Rect<float>::from_two_points(Gfx::Point<float> const&, Gfx::Point<float> const&) |
519 | | |
520 | | [[nodiscard]] static Rect<T> intersection(Rect<T> const& a, Rect<T> const& b) |
521 | 28.2M | { |
522 | 28.2M | Rect<T> r = a; |
523 | 28.2M | r.intersect(b); |
524 | 28.2M | return r; |
525 | 28.2M | } Gfx::Rect<int>::intersection(Gfx::Rect<int> const&, Gfx::Rect<int> const&) Line | Count | Source | 521 | 28.2M | { | 522 | 28.2M | Rect<T> r = a; | 523 | 28.2M | r.intersect(b); | 524 | 28.2M | return r; | 525 | 28.2M | } |
Unexecuted instantiation: Gfx::Rect<float>::intersection(Gfx::Rect<float> const&, Gfx::Rect<float> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::intersection(Gfx::Rect<Web::CSSPixels> const&, Gfx::Rect<Web::CSSPixels> const&) |
526 | | |
527 | | [[nodiscard]] ALWAYS_INLINE Rect<T> intersected(Rect<T> const& other) const |
528 | 24.7M | { |
529 | 24.7M | return intersection(*this, other); |
530 | 24.7M | } Gfx::Rect<int>::intersected(Gfx::Rect<int> const&) const Line | Count | Source | 528 | 24.7M | { | 529 | 24.7M | return intersection(*this, other); | 530 | 24.7M | } |
Unexecuted instantiation: Gfx::Rect<float>::intersected(Gfx::Rect<float> const&) const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::intersected(Gfx::Rect<Web::CSSPixels> const&) const |
531 | | |
532 | | [[nodiscard]] Vector<Point<T>, 2> intersected(Line<T> const& line) const |
533 | | { |
534 | | if (is_empty()) |
535 | | return {}; |
536 | | Vector<Point<T>, 2> points; |
537 | | if (auto point = line.intersected({ top_left(), top_right() }); point.has_value()) |
538 | | points.append({ point.value().x(), y() }); |
539 | | if (auto point = line.intersected({ bottom_left(), bottom_right() }); point.has_value()) { |
540 | | points.append({ point.value().x(), bottom() - 1 }); |
541 | | if (points.size() == 2) |
542 | | return points; |
543 | | } |
544 | | if (height() > 2) { |
545 | | if (auto point = line.intersected({ { x(), y() + 1 }, { x(), bottom() - 2 } }); point.has_value()) { |
546 | | points.append({ x(), point.value().y() }); |
547 | | if (points.size() == 2) |
548 | | return points; |
549 | | } |
550 | | if (auto point = line.intersected({ { right() - 1, y() + 1 }, { right() - 1, bottom() - 2 } }); point.has_value()) |
551 | | points.append({ right() - 1, point.value().y() }); |
552 | | } |
553 | | return points; |
554 | | } |
555 | | |
556 | | template<typename U = T> |
557 | | [[nodiscard]] Gfx::Rect<U> interpolated_to(Gfx::Rect<T> const& to, float factor) const |
558 | | { |
559 | | VERIFY(factor >= 0.f); |
560 | | VERIFY(factor <= 1.f); |
561 | | if (factor == 0.f) |
562 | | return *this; |
563 | | if (factor == 1.f) |
564 | | return to; |
565 | | if (this == &to) |
566 | | return *this; |
567 | | auto interpolated_left = round_to<U>(mix<float>(x(), to.x(), factor)); |
568 | | auto interpolated_top = round_to<U>(mix<float>(y(), to.y(), factor)); |
569 | | auto interpolated_right = round_to<U>(mix<float>(right(), to.right(), factor)); |
570 | | auto interpolated_bottom = round_to<U>(mix<float>(bottom(), to.bottom(), factor)); |
571 | | return { interpolated_left, interpolated_top, interpolated_right - interpolated_left, interpolated_bottom - interpolated_top }; |
572 | | } |
573 | | |
574 | | [[nodiscard]] float center_point_distance_to(Rect<T> const& other) const |
575 | | { |
576 | | return Line { center(), other.center() }.length(); |
577 | | } |
578 | | |
579 | | [[nodiscard]] Vector<Point<T>, 2> closest_outside_center_points(Rect<T> const& other) const |
580 | | { |
581 | | if (intersects(other)) |
582 | | return {}; |
583 | | Line centers_line { center(), other.center() }; |
584 | | auto points_this = intersected(centers_line); |
585 | | VERIFY(points_this.size() == 1); |
586 | | auto points_other = other.intersected(centers_line); |
587 | | VERIFY(points_other.size() == 1); |
588 | | return { points_this[0], points_other[0] }; |
589 | | } |
590 | | |
591 | | [[nodiscard]] float outside_center_point_distance_to(Rect<T> const& other) const |
592 | | { |
593 | | auto points = closest_outside_center_points(other); |
594 | | if (points.is_empty()) |
595 | | return 0.f; |
596 | | return Line { points[0], points[0] }.length(); |
597 | | } |
598 | | |
599 | | [[nodiscard]] Rect<T> constrained_to(Rect<T> const& constrain_rect) const |
600 | | { |
601 | | if (constrain_rect.contains(*this)) |
602 | | return *this; |
603 | | T move_x = 0, move_y = 0; |
604 | | if (right() > constrain_rect.right()) |
605 | | move_x = constrain_rect.right() - right(); |
606 | | if (bottom() > constrain_rect.bottom()) |
607 | | move_y = constrain_rect.bottom() - bottom(); |
608 | | if (x() < constrain_rect.x()) |
609 | | move_x = constrain_rect.x() - x(); |
610 | | if (y() < constrain_rect.y()) |
611 | | move_y = constrain_rect.y() - y(); |
612 | | auto rect = *this; |
613 | | if (move_x != 0 || move_y != 0) |
614 | | rect.translate_by(move_x, move_y); |
615 | | return rect; |
616 | | } |
617 | | |
618 | | [[nodiscard]] Point<T> closest_to(Point<T> const& point) const |
619 | | { |
620 | | if (is_empty()) |
621 | | return {}; |
622 | | Optional<Point<T>> closest_point; |
623 | | float closest_distance = 0.0; |
624 | | auto check_distance = [&](Line<T> const& line) { |
625 | | auto point_on_line = line.closest_to(point); |
626 | | auto distance = Line { point_on_line, point }.length(); |
627 | | if (!closest_point.has_value() || distance < closest_distance) { |
628 | | closest_point = point_on_line; |
629 | | closest_distance = distance; |
630 | | } |
631 | | }; |
632 | | |
633 | | check_distance({ top_left(), top_right().moved_left(1) }); |
634 | | check_distance({ bottom_left().moved_up(1), bottom_right().translated(-1) }); |
635 | | if (height() > 2) { |
636 | | check_distance({ { x(), y() + 1 }, { x(), bottom() - 2 } }); |
637 | | check_distance({ { right() - 1, y() + 1 }, { right() - 1, bottom() - 2 } }); |
638 | | } |
639 | | VERIFY(closest_point.has_value()); |
640 | | VERIFY(side(closest_point.value()) != Side::None); |
641 | | return closest_point.value(); |
642 | | } |
643 | | |
644 | | class RelativeLocation { |
645 | | friend class Rect<T>; |
646 | | |
647 | | RelativeLocation(Rect<T> const& base_rect, Rect<T> const& other_rect) |
648 | | { |
649 | | if (base_rect.is_empty() || other_rect.is_empty()) |
650 | | return; |
651 | | auto parts = base_rect.shatter(other_rect); |
652 | | for (auto& part : parts) { |
653 | | if (part.x() < other_rect.x()) { |
654 | | if (part.y() < other_rect.y()) |
655 | | m_top_left = true; |
656 | | if ((part.y() >= other_rect.y() && part.y() < other_rect.bottom() - 1) || (part.y() < other_rect.bottom() && part.bottom() - 1 > other_rect.y())) |
657 | | m_left = true; |
658 | | if (part.y() >= other_rect.bottom() - 1 || part.bottom() - 1 > other_rect.y()) |
659 | | m_bottom_left = true; |
660 | | } |
661 | | if (part.x() >= other_rect.x() || part.right() - 1 > other_rect.x()) { |
662 | | if (part.y() < other_rect.y()) |
663 | | m_top = true; |
664 | | if (part.y() >= other_rect.bottom() - 1 || part.bottom() > other_rect.bottom()) |
665 | | m_bottom = true; |
666 | | } |
667 | | if (part.x() >= other_rect.right() - 1 || part.right() > other_rect.right()) { |
668 | | if (part.y() < other_rect.y()) |
669 | | m_top_right = true; |
670 | | if ((part.y() >= other_rect.y() && part.y() < other_rect.bottom() - 1) || (part.y() < other_rect.bottom() && part.bottom() - 1 > other_rect.y())) |
671 | | m_right = true; |
672 | | if (part.y() >= other_rect.bottom() - 1 || part.bottom() - 1 > other_rect.y()) |
673 | | m_bottom_right = true; |
674 | | } |
675 | | } |
676 | | } |
677 | | |
678 | | public: |
679 | | RelativeLocation() = default; |
680 | | |
681 | | bool top_left() const { return m_top_left; } |
682 | | bool top() const { return m_top; } |
683 | | bool top_right() const { return m_top_right; } |
684 | | bool left() const { return m_left; } |
685 | | bool right() const { return m_right; } |
686 | | bool bottom_left() const { return m_bottom_left; } |
687 | | bool bottom() const { return m_bottom; } |
688 | | bool bottom_right() const { return m_bottom_right; } |
689 | | bool anywhere_above() const { return m_top_left || m_top || m_top_right; } |
690 | | bool anywhere_below() const { return m_bottom_left || m_bottom || m_bottom_right; } |
691 | | bool anywhere_left() const { return m_top_left || m_left || m_bottom_left; } |
692 | | bool anywhere_right() const { return m_top_right || m_right || m_bottom_right; } |
693 | | |
694 | | private: |
695 | | bool m_top_left : 1 { false }; |
696 | | bool m_top : 1 { false }; |
697 | | bool m_top_right : 1 { false }; |
698 | | bool m_left : 1 { false }; |
699 | | bool m_right : 1 { false }; |
700 | | bool m_bottom_left : 1 { false }; |
701 | | bool m_bottom : 1 { false }; |
702 | | bool m_bottom_right : 1 { false }; |
703 | | }; |
704 | | [[nodiscard]] RelativeLocation relative_location_to(Rect<T> const& other) const |
705 | | { |
706 | | return RelativeLocation(*this, other); |
707 | | } |
708 | | |
709 | | enum class Side { |
710 | | None = 0, |
711 | | Left, |
712 | | Top, |
713 | | Right, |
714 | | Bottom |
715 | | }; |
716 | | [[nodiscard]] Side side(Point<T> const& point) const |
717 | | { |
718 | | if (is_empty()) |
719 | | return Side::None; |
720 | | if (point.y() == y() || point.y() == bottom() - 1) |
721 | | return (point.x() >= x() && point.x() < right()) ? (point.y() == y() ? Side::Top : Side::Bottom) : Side::None; |
722 | | if (point.x() == x() || point.x() == right() - 1) |
723 | | return (point.y() > y() && point.y() < bottom()) ? (point.x() == x() ? Side::Left : Side::Right) : Side::None; |
724 | | return Side::None; |
725 | | } |
726 | | |
727 | | [[nodiscard]] Rect<T> rect_on_side(Side side, Rect<T> const& other) const |
728 | | { |
729 | | switch (side) { |
730 | | case Side::None: |
731 | | break; |
732 | | case Side::Left: |
733 | | // Return the area in other that is to the left of this rect |
734 | | if (other.x() < x()) { |
735 | | if (other.right() > x()) |
736 | | return { other.location(), { x() - other.x(), other.height() } }; |
737 | | else |
738 | | return other; |
739 | | } |
740 | | break; |
741 | | case Side::Top: |
742 | | // Return the area in other that is above this rect |
743 | | if (other.y() < y()) { |
744 | | if (other.bottom() > y()) |
745 | | return { other.location(), { other.width(), y() - other.y() } }; |
746 | | else |
747 | | return other; |
748 | | } |
749 | | break; |
750 | | case Side::Right: |
751 | | // Return the area in other that is to the right of this rect |
752 | | if (other.right() > x()) { |
753 | | if (other.x() < right()) |
754 | | return { { right(), other.y() }, { other.width() - (right() - 1 - other.x()), other.height() } }; |
755 | | else |
756 | | return other; |
757 | | } |
758 | | break; |
759 | | case Side::Bottom: |
760 | | // Return the area in other that is below this rect |
761 | | if (other.bottom() > y()) { |
762 | | if (other.y() < bottom()) |
763 | | return { { other.x(), bottom() }, { other.width(), other.height() - (bottom() - 1 - other.y()) } }; |
764 | | else |
765 | | return other; |
766 | | } |
767 | | break; |
768 | | } |
769 | | return {}; |
770 | | } |
771 | | |
772 | | template<typename Container> |
773 | | static bool disperse(Container& rects) |
774 | | { |
775 | | auto has_intersecting = [&]() { |
776 | | for (auto& rect : rects) { |
777 | | for (auto& other_rect : rects) { |
778 | | if (&rect == &other_rect) |
779 | | continue; |
780 | | if (rect.intersects(other_rect)) |
781 | | return true; |
782 | | } |
783 | | } |
784 | | return false; |
785 | | }; |
786 | | |
787 | | if (!has_intersecting()) |
788 | | return false; |
789 | | |
790 | | auto calc_delta = [&](Rect<T> const& rect) -> Point<T> { |
791 | | auto rect_center = rect.center(); |
792 | | Point<T> center_sum; |
793 | | for (auto& other_rect : rects) { |
794 | | if (&other_rect == &rect) |
795 | | continue; |
796 | | if (rect.intersects(other_rect)) |
797 | | center_sum += rect_center - other_rect.center(); |
798 | | } |
799 | | double m = sqrt((double)center_sum.x() * (double)center_sum.x() + (double)center_sum.y() * (double)center_sum.y()); |
800 | | if (m != 0.0) |
801 | | return { (double)center_sum.x() / m + 0.5, (double)center_sum.y() / m + 0.5 }; |
802 | | return {}; |
803 | | }; |
804 | | |
805 | | Vector<Point<T>, 8> deltas; |
806 | | do { |
807 | | bool changes = false; |
808 | | |
809 | | deltas.clear_with_capacity(); |
810 | | for (auto& rect : rects) { |
811 | | auto delta = calc_delta(rect); |
812 | | if (!delta.is_zero()) |
813 | | changes = true; |
814 | | deltas.append(delta); |
815 | | } |
816 | | |
817 | | // TODO: If we have no changes we would loop infinitely! |
818 | | // Figure out some way to resolve this. Maybe randomly moving an intersecting rect? |
819 | | VERIFY(changes); |
820 | | |
821 | | size_t i = 0; |
822 | | for (auto& rect : rects) |
823 | | rect.translate_by(deltas[i++]); |
824 | | |
825 | | } while (has_intersecting()); |
826 | | return true; |
827 | | } |
828 | | |
829 | | [[nodiscard]] bool is_adjacent(Rect<T> const& other) const |
830 | | { |
831 | | if (is_empty() || other.is_empty()) |
832 | | return false; |
833 | | if (intersects(other)) |
834 | | return false; |
835 | | if (other.right() == x() || other.x() == right()) |
836 | | return max(top(), other.top()) < min(bottom(), other.bottom()); |
837 | | if (other.bottom() == y() || other.y() == bottom()) |
838 | | return max(left(), other.left()) < min(right(), other.right()); |
839 | | return false; |
840 | | } |
841 | | |
842 | | void unite_horizontally(Rect<T> const& other) |
843 | 0 | { |
844 | 0 | auto new_left = min(left(), other.left()); |
845 | 0 | auto new_right = max(right(), other.right()); |
846 | 0 | set_left(new_left); |
847 | 0 | set_right(new_right); |
848 | 0 | } |
849 | | |
850 | | void unite_vertically(Rect<T> const& other) |
851 | 0 | { |
852 | 0 | auto new_top = min(top(), other.top()); |
853 | 0 | auto new_bottom = max(bottom(), other.bottom()); |
854 | 0 | set_top(new_top); |
855 | 0 | set_bottom(new_bottom); |
856 | 0 | } |
857 | | |
858 | | [[nodiscard]] Rect<T> united(Rect<T> const& other) const |
859 | 0 | { |
860 | 0 | if (is_empty()) |
861 | 0 | return other; |
862 | 0 | if (other.is_empty()) |
863 | 0 | return *this; |
864 | 0 | Rect<T> rect; |
865 | 0 | rect.set_left(min(left(), other.left())); |
866 | 0 | rect.set_top(min(top(), other.top())); |
867 | 0 | rect.set_right(max(right(), other.right())); |
868 | 0 | rect.set_bottom(max(bottom(), other.bottom())); |
869 | 0 | return rect; |
870 | 0 | } Unexecuted instantiation: Gfx::Rect<double>::united(Gfx::Rect<double> const&) const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::united(Gfx::Rect<Web::CSSPixels> const&) const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::united(Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> > const&) const |
871 | | |
872 | 1.08M | [[nodiscard]] Point<T> top_left() const { return { left(), top() }; } Unexecuted instantiation: Gfx::Rect<float>::top_left() const Gfx::Rect<int>::top_left() const Line | Count | Source | 872 | 1.08M | [[nodiscard]] Point<T> top_left() const { return { left(), top() }; } |
Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::top_left() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::top_left() const |
873 | 0 | [[nodiscard]] Point<T> top_right() const { return { right(), top() }; } Unexecuted instantiation: Gfx::Rect<float>::top_right() const Unexecuted instantiation: Gfx::Rect<int>::top_right() const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::top_right() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::top_right() const |
874 | 0 | [[nodiscard]] Point<T> bottom_left() const { return { left(), bottom() }; } Unexecuted instantiation: Gfx::Rect<float>::bottom_left() const Unexecuted instantiation: Gfx::Rect<int>::bottom_left() const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::bottom_left() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::bottom_left() const |
875 | 0 | [[nodiscard]] Point<T> bottom_right() const { return { right(), bottom() }; } Unexecuted instantiation: Gfx::Rect<float>::bottom_right() const Unexecuted instantiation: Gfx::Rect<int>::bottom_right() const Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::bottom_right() const Unexecuted instantiation: Gfx::Rect<AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::bottom_right() const |
876 | | |
877 | | void align_within(Rect<T> const& other, TextAlignment alignment) |
878 | 0 | { |
879 | 0 | switch (alignment) { |
880 | 0 | case TextAlignment::Center: |
881 | 0 | center_within(other); |
882 | 0 | return; |
883 | 0 | case TextAlignment::TopCenter: |
884 | 0 | center_horizontally_within(other); |
885 | 0 | set_y(other.y()); |
886 | 0 | return; |
887 | 0 | case TextAlignment::TopLeft: |
888 | 0 | set_location(other.location()); |
889 | 0 | return; |
890 | 0 | case TextAlignment::TopRight: |
891 | 0 | set_x(other.right() - width()); |
892 | 0 | set_y(other.y()); |
893 | 0 | return; |
894 | 0 | case TextAlignment::CenterLeft: |
895 | 0 | set_x(other.x()); |
896 | 0 | center_vertically_within(other); |
897 | 0 | return; |
898 | 0 | case TextAlignment::CenterRight: |
899 | 0 | set_x(other.right() - width()); |
900 | 0 | center_vertically_within(other); |
901 | 0 | return; |
902 | 0 | case TextAlignment::BottomCenter: |
903 | 0 | center_horizontally_within(other); |
904 | 0 | set_y(other.bottom() - height()); |
905 | 0 | return; |
906 | 0 | case TextAlignment::BottomLeft: |
907 | 0 | set_x(other.x()); |
908 | 0 | set_y(other.bottom() - height()); |
909 | 0 | return; |
910 | 0 | case TextAlignment::BottomRight: |
911 | 0 | set_x(other.right() - width()); |
912 | 0 | set_y(other.bottom() - height()); |
913 | 0 | return; |
914 | 0 | } |
915 | 0 | } Unexecuted instantiation: Gfx::Rect<float>::align_within(Gfx::Rect<float> const&, Gfx::TextAlignment) Unexecuted instantiation: Gfx::Rect<int>::align_within(Gfx::Rect<int> const&, Gfx::TextAlignment) |
916 | | |
917 | | void center_within(Rect<T> const& other) |
918 | 0 | { |
919 | 0 | center_horizontally_within(other); |
920 | 0 | center_vertically_within(other); |
921 | 0 | } Unexecuted instantiation: Gfx::Rect<float>::center_within(Gfx::Rect<float> const&) Unexecuted instantiation: Gfx::Rect<int>::center_within(Gfx::Rect<int> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::center_within(Gfx::Rect<Web::CSSPixels> const&) |
922 | | |
923 | | [[nodiscard]] Rect centered_within(Rect const& other) const |
924 | 730 | { |
925 | 730 | Rect rect { *this }; |
926 | 730 | rect.center_horizontally_within(other); |
927 | 730 | rect.center_vertically_within(other); |
928 | 730 | return rect; |
929 | 730 | } |
930 | | |
931 | | void center_horizontally_within(Rect<T> const& other) |
932 | 730 | { |
933 | 730 | set_x(other.center().x() - width() / 2); |
934 | 730 | } Gfx::Rect<float>::center_horizontally_within(Gfx::Rect<float> const&) Line | Count | Source | 932 | 730 | { | 933 | 730 | set_x(other.center().x() - width() / 2); | 934 | 730 | } |
Unexecuted instantiation: Gfx::Rect<int>::center_horizontally_within(Gfx::Rect<int> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::center_horizontally_within(Gfx::Rect<Web::CSSPixels> const&) |
935 | | |
936 | | void center_vertically_within(Rect<T> const& other) |
937 | 730 | { |
938 | 730 | set_y(other.center().y() - height() / 2); |
939 | 730 | } Gfx::Rect<float>::center_vertically_within(Gfx::Rect<float> const&) Line | Count | Source | 937 | 730 | { | 938 | 730 | set_y(other.center().y() - height() / 2); | 939 | 730 | } |
Unexecuted instantiation: Gfx::Rect<int>::center_vertically_within(Gfx::Rect<int> const&) Unexecuted instantiation: Gfx::Rect<Web::CSSPixels>::center_vertically_within(Gfx::Rect<Web::CSSPixels> const&) |
940 | | |
941 | | template<typename U> |
942 | | requires(!IsSame<T, U>) |
943 | | [[nodiscard]] ALWAYS_INLINE Rect<U> to_type() const |
944 | 730 | { |
945 | 730 | return Rect<U>(*this); |
946 | 730 | } _ZNK3Gfx4RectIiE7to_typeIfQnt6IsSameIT_TL0__EEENS0_IS3_EEv Line | Count | Source | 944 | 730 | { | 945 | 730 | return Rect<U>(*this); | 946 | 730 | } |
Unexecuted instantiation: _ZNK3Gfx4RectIN2AK15DistinctNumericIiN3Web18__DevicePixels_tagEJNS1_22DistinctNumericFeature10ArithmeticENS5_16CastToUnderlyingENS5_10ComparisonENS5_9IncrementEEEEE7to_typeIiQnt6IsSameIT_TL0__EEENS0_ISD_EEv Unexecuted instantiation: _ZNK3Gfx4RectIdE7to_typeIfQnt6IsSameIT_TL0__EEENS0_IS3_EEv Unexecuted instantiation: _ZNK3Gfx4RectIN3Web9CSSPixelsEE7to_typeIfQnt6IsSameIT_TL0__EEENS0_IS5_EEv Unexecuted instantiation: _ZNK3Gfx4RectIfE7to_typeIN3Web9CSSPixelsEQnt6IsSameIT_TL0__EEENS0_IS5_EEv Unexecuted instantiation: _ZNK3Gfx4RectIiE7to_typeIN2AK15DistinctNumericIiN3Web18__DevicePixels_tagEJNS3_22DistinctNumericFeature10ArithmeticENS7_16CastToUnderlyingENS7_10ComparisonENS7_9IncrementEEEEQnt6IsSameIT_TL0__EEENS0_ISD_EEv Unexecuted instantiation: _ZNK3Gfx4RectIfE7to_typeIiQnt6IsSameIT_TL0__EEENS0_IS3_EEv |
947 | | |
948 | | // For extern specialization, like CSSPixels |
949 | | template<typename U> |
950 | | [[nodiscard]] Rect<U> to_rounded() const = delete; |
951 | | |
952 | | template<FloatingPoint U> |
953 | | [[nodiscard]] ALWAYS_INLINE Rect<U> to_rounded() const |
954 | | { |
955 | | // FIXME: We may get away with `rint[lf]?()` here. |
956 | | // This would even give us some more control of these internals, |
957 | | // while the break-tie algorithm does not really matter |
958 | | if constexpr (IsSame<T, float>) { |
959 | | return { |
960 | | static_cast<U>(roundf(x())), |
961 | | static_cast<U>(roundf(y())), |
962 | | static_cast<U>(roundf(width())), |
963 | | static_cast<U>(roundf(height())), |
964 | | }; |
965 | | } |
966 | | if constexpr (IsSame<T, double>) { |
967 | | return { |
968 | | static_cast<U>(round(x())), |
969 | | static_cast<U>(round(y())), |
970 | | static_cast<U>(round(width())), |
971 | | static_cast<U>(round(height())), |
972 | | }; |
973 | | } |
974 | | |
975 | | return { |
976 | | static_cast<U>(roundl(x())), |
977 | | static_cast<U>(roundl(y())), |
978 | | static_cast<U>(roundl(width())), |
979 | | static_cast<U>(roundl(height())), |
980 | | }; |
981 | | } |
982 | | |
983 | | template<Integral I> |
984 | | ALWAYS_INLINE Rect<I> to_rounded() const |
985 | 0 | { |
986 | 0 | return { |
987 | 0 | round_to<I>(x()), |
988 | 0 | round_to<I>(y()), |
989 | 0 | round_to<I>(width()), |
990 | 0 | round_to<I>(height()), |
991 | 0 | }; |
992 | 0 | } |
993 | | |
994 | | [[nodiscard]] ByteString to_byte_string() const; |
995 | | |
996 | | private: |
997 | | Point<T> m_location; |
998 | | Size<T> m_size; |
999 | | }; |
1000 | | |
1001 | | using IntRect = Rect<int>; |
1002 | | using FloatRect = Rect<float>; |
1003 | | using DoubleRect = Rect<double>; |
1004 | | |
1005 | | [[nodiscard]] ALWAYS_INLINE IntRect enclosing_int_rect(FloatRect const& float_rect) |
1006 | 1.33M | { |
1007 | 1.33M | int x1 = floorf(float_rect.x()); |
1008 | 1.33M | int y1 = floorf(float_rect.y()); |
1009 | 1.33M | int x2 = ceilf(float_rect.right()); |
1010 | 1.33M | int y2 = ceilf(float_rect.bottom()); |
1011 | 1.33M | return Gfx::IntRect::from_two_points({ x1, y1 }, { x2, y2 }); |
1012 | 1.33M | } |
1013 | | |
1014 | | } |
1015 | | |
1016 | | namespace AK { |
1017 | | |
1018 | | template<typename T> |
1019 | | struct Formatter<Gfx::Rect<T>> : Formatter<FormatString> { |
1020 | | ErrorOr<void> format(FormatBuilder& builder, Gfx::Rect<T> const& value) |
1021 | 0 | { |
1022 | 0 | return Formatter<FormatString>::format(builder, "[{},{} {}x{}]"sv, value.x(), value.y(), value.width(), value.height()); |
1023 | 0 | } Unexecuted instantiation: AK::Formatter<Gfx::Rect<Web::CSSPixels>, void>::format(AK::FormatBuilder&, Gfx::Rect<Web::CSSPixels> const&) Unexecuted instantiation: AK::Formatter<Gfx::Rect<int>, void>::format(AK::FormatBuilder&, Gfx::Rect<int> const&) |
1024 | | }; |
1025 | | |
1026 | | } |
1027 | | |
1028 | | namespace IPC { |
1029 | | |
1030 | | template<> |
1031 | | ErrorOr<void> encode(Encoder&, Gfx::IntRect const&); |
1032 | | |
1033 | | template<> |
1034 | | ErrorOr<Gfx::IntRect> decode(Decoder&); |
1035 | | |
1036 | | } |