Bug 1760439 [wpt PR 33220] - Implement FedCM permission delegates in content_shell...
[gecko.git] / layout / generic / AspectRatio.h
blob2a2139fa9c346e22f48a065f8579d75f02579525
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_AspectRatio_h
8 #define mozilla_AspectRatio_h
10 /* The aspect ratio of a box, in a "width / height" format. */
12 #include "mozilla/Attributes.h"
13 #include "mozilla/gfx/BaseSize.h"
14 #include "nsCoord.h"
15 #include <algorithm>
16 #include <limits>
18 namespace IPC {
19 template <typename T>
20 struct ParamTraits;
21 } // namespace IPC
23 namespace mozilla {
25 enum LogicalAxis : uint8_t;
26 class LogicalSize;
27 class WritingMode;
29 enum class UseBoxSizing : uint8_t {
30 // The aspect ratio works with content box dimensions always.
31 No,
32 // The aspect ratio works with the dimensions of the box specified by
33 // box-sizing.
34 Yes,
37 struct AspectRatio {
38 friend struct IPC::ParamTraits<mozilla::AspectRatio>;
40 AspectRatio() = default;
41 explicit AspectRatio(float aRatio,
42 UseBoxSizing aUseBoxSizing = UseBoxSizing::No)
43 : mRatio(std::max(aRatio, 0.0f)), mUseBoxSizing(aUseBoxSizing) {}
45 static AspectRatio FromSize(float aWidth, float aHeight,
46 UseBoxSizing aUseBoxSizing = UseBoxSizing::No) {
47 if (aWidth == 0.0f || aHeight == 0.0f) {
48 // For the degenerate ratio, we don't care about which box sizing we are
49 // using, so using default constructor is fine.
50 return AspectRatio();
52 return AspectRatio(aWidth / aHeight, aUseBoxSizing);
55 template <typename T, typename Sub>
56 static AspectRatio FromSize(const gfx::BaseSize<T, Sub>& aSize) {
57 return FromSize(aSize.Width(), aSize.Height());
60 explicit operator bool() const { return mRatio != 0.0f; }
62 nscoord ApplyTo(nscoord aCoord) const {
63 MOZ_DIAGNOSTIC_ASSERT(*this);
64 return NSCoordSaturatingNonnegativeMultiply(aCoord, mRatio);
67 float ApplyToFloat(float aFloat) const {
68 MOZ_DIAGNOSTIC_ASSERT(*this);
69 return mRatio * aFloat;
72 // Inverts the ratio, in order to get the height / width ratio.
73 [[nodiscard]] AspectRatio Inverted() const {
74 if (!*this) {
75 return AspectRatio();
77 // Clamp to a small epsilon, in case mRatio is absurdly large & produces
78 // 0.0f in the division here (so that valid ratios always generate other
79 // valid ratios when inverted).
80 return AspectRatio(
81 std::max(std::numeric_limits<float>::epsilon(), 1.0f / mRatio),
82 mUseBoxSizing);
85 [[nodiscard]] inline AspectRatio ConvertToWritingMode(
86 const WritingMode& aWM) const;
88 /**
89 * This method computes the ratio-dependent size by the ratio-determining size
90 * and aspect-ratio (i.e. preferred aspect ratio). Basically this function
91 * will be used in the calculation of 'auto' sizes when the preferred
92 * aspect ratio is not 'auto'.
94 * @param aRatioDependentAxis The ratio depenedent axis of the box.
95 * @param aWM The writing mode of the box.
96 * @param aRatioDetermingSize The content-box size on the ratio determining
97 * axis. Basically, we use this size and |mRatio|
98 * to compute the size on the ratio-dependent
99 * axis.
100 * @param aContentBoxSizeToBoxSizingAdjust The border padding box size
101 * adjustment. We need this because
102 * aspect-ratio should take the
103 * box-sizing into account if its
104 * style is '<ratio>'. If its style
105 * is 'auto & <ratio>', we should use
106 * content-box dimensions always.
107 * If the callers want the ratio to
108 * apply to the content-box size, we
109 * should pass a zero LogicalSize.
110 * If mUseBoxSizing is No, we ignore
111 * this parameter because we should
112 * use content box dimensions always.
114 * The return value is the content-box size on the ratio-dependent axis.
115 * Plese see the definition of the ratio-dependent axis and the
116 * ratio-determining axis in the spec:
117 * https://drafts.csswg.org/css-sizing-4/#aspect-ratio
119 [[nodiscard]] nscoord ComputeRatioDependentSize(
120 LogicalAxis aRatioDependentAxis, const WritingMode& aWM,
121 nscoord aRatioDeterminingSize,
122 const LogicalSize& aContentBoxSizeToBoxSizingAdjust) const;
124 bool operator==(const AspectRatio& aOther) const {
125 return mRatio == aOther.mRatio;
128 bool operator!=(const AspectRatio& aOther) const {
129 return !(*this == aOther);
132 bool operator<(const AspectRatio& aOther) const {
133 return mRatio < aOther.mRatio;
136 private:
137 // 0.0f represents no aspect ratio.
138 float mRatio = 0.0f;
139 UseBoxSizing mUseBoxSizing = UseBoxSizing::No;
142 } // namespace mozilla
144 #endif // mozilla_AspectRatio_h