Bug 1320014 Part 14 - Convert NS_SIDE_TO_HALF_CORNER to a constexpr function.
MozReview-Commit-ID: 4MQu8omCdcg
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -464,16 +464,19 @@ enum HalfCorner {
static inline HalfCorner operator++(HalfCorner& aHalfCorner) {
MOZ_ASSERT(aHalfCorner >= eCornerTopLeftX && aHalfCorner <= eCornerBottomLeftY,
"Out of range half corner!");
aHalfCorner = HalfCorner(aHalfCorner + 1);
return aHalfCorner;
}
+// The result of these conversion functions are exhaustively checked in
+// nsStyleCoord.cpp, which also serves as usage examples.
+
constexpr bool HalfCornerIsX(HalfCorner aHalfCorner)
{
return !(aHalfCorner % 2);
}
constexpr Corner HalfToFullCorner(HalfCorner aHalfCorner)
{
return Corner(aHalfCorner / 2);
@@ -493,11 +496,24 @@ constexpr bool SideIsVertical(Side aSide
// corners associated with aSide. For example, with aSide = eSideBottom the
// result is eCornerBottomRight when aIsSecond is false, and
// eCornerBottomLeft when aIsSecond is true.
constexpr Corner SideToFullCorner(Side aSide, bool aIsSecond)
{
return Corner((aSide + aIsSecond) % 4);
}
+// @param aIsSecond see SideToFullCorner.
+// @param aIsParallel return the half-corner that is parallel with aSide
+// when aIsParallel is true. For example with aSide=eSideTop, aIsSecond=true
+// the result is eCornerTopRightX when aIsParallel is true, and
+// eCornerTopRightY when aIsParallel is false (because "X" is parallel with
+// eSideTop/eSideBottom, similarly "Y" is parallel with
+// eSideLeft/eSideRight)
+constexpr HalfCorner SideToHalfCorner(Side aSide, bool aIsSecond,
+ bool aIsParallel)
+{
+ return HalfCorner(((aSide + aIsSecond) * 2 + (aSide + !aIsParallel) % 2) % 8);
+}
+
} // namespace mozilla
#endif /* MOZILLA_GFX_TYPES_H_ */
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -617,23 +617,23 @@ nsFloatManager::FloatInfo::LineLeft(Writ
return ShapeBoxRect().x;
}
// Get the physical side for line-left since border-radii are in
// the physical axis.
mozilla::Side lineLeftSide =
aWM.PhysicalSide(aWM.LogicalSideForLineRelativeDir(eLineRelativeDirLeft));
nscoord blockStartCornerRadiusL =
- radii[NS_SIDE_TO_HALF_CORNER(lineLeftSide, true, false)];
+ radii[SideToHalfCorner(lineLeftSide, true, false)];
nscoord blockStartCornerRadiusB =
- radii[NS_SIDE_TO_HALF_CORNER(lineLeftSide, true, true)];
+ radii[SideToHalfCorner(lineLeftSide, true, true)];
nscoord blockEndCornerRadiusL =
- radii[NS_SIDE_TO_HALF_CORNER(lineLeftSide, false, false)];
+ radii[SideToHalfCorner(lineLeftSide, false, false)];
nscoord blockEndCornerRadiusB =
- radii[NS_SIDE_TO_HALF_CORNER(lineLeftSide, false, true)];
+ radii[SideToHalfCorner(lineLeftSide, false, true)];
if (aWM.IsLineInverted()) {
// This happens only when aWM is vertical-lr. Need to swap blockStart
// and blockEnd corners.
std::swap(blockStartCornerRadiusL, blockEndCornerRadiusL);
std::swap(blockStartCornerRadiusB, blockEndCornerRadiusB);
}
@@ -675,23 +675,23 @@ nsFloatManager::FloatInfo::LineRight(Wri
return ShapeBoxRect().XMost();
}
// Get the physical side for line-right since border-radii are in
// the physical axis.
mozilla::Side lineRightSide =
aWM.PhysicalSide(aWM.LogicalSideForLineRelativeDir(eLineRelativeDirRight));
nscoord blockStartCornerRadiusL =
- radii[NS_SIDE_TO_HALF_CORNER(lineRightSide, false, false)];
+ radii[SideToHalfCorner(lineRightSide, false, false)];
nscoord blockStartCornerRadiusB =
- radii[NS_SIDE_TO_HALF_CORNER(lineRightSide, false, true)];
+ radii[SideToHalfCorner(lineRightSide, false, true)];
nscoord blockEndCornerRadiusL =
- radii[NS_SIDE_TO_HALF_CORNER(lineRightSide, true, false)];
+ radii[SideToHalfCorner(lineRightSide, true, false)];
nscoord blockEndCornerRadiusB =
- radii[NS_SIDE_TO_HALF_CORNER(lineRightSide, true, true)];
+ radii[SideToHalfCorner(lineRightSide, true, true)];
if (aWM.IsLineInverted()) {
// This happens only when aWM is vertical-lr. Need to swap blockStart
// and blockEnd corners.
std::swap(blockStartCornerRadiusL, blockEndCornerRadiusL);
std::swap(blockStartCornerRadiusB, blockEndCornerRadiusB);
}
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1298,18 +1298,18 @@ nsIFrame::ComputeBorderRadii(const nsSty
aRadii[eCornerTopLeftY] = 0;
}
// css3-background specifies this algorithm for reducing
// corner radii when they are too big.
bool haveRadius = false;
double ratio = 1.0f;
NS_FOR_CSS_SIDES(side) {
- uint32_t hc1 = NS_SIDE_TO_HALF_CORNER(side, false, true);
- uint32_t hc2 = NS_SIDE_TO_HALF_CORNER(side, true, true);
+ uint32_t hc1 = SideToHalfCorner(side, false, true);
+ uint32_t hc2 = SideToHalfCorner(side, true, true);
nscoord length =
SideIsVertical(side) ? aBorderArea.height : aBorderArea.width;
nscoord sum = aRadii[hc1] + aRadii[hc2];
if (sum)
haveRadius = true;
// avoid floating point division in the normal case
if (length < sum)
@@ -1324,18 +1324,18 @@ nsIFrame::ComputeBorderRadii(const nsSty
return haveRadius;
}
/* static */ void
nsIFrame::InsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets)
{
NS_FOR_CSS_SIDES(side) {
nscoord offset = aOffsets.Side(side);
- uint32_t hc1 = NS_SIDE_TO_HALF_CORNER(side, false, false);
- uint32_t hc2 = NS_SIDE_TO_HALF_CORNER(side, true, false);
+ uint32_t hc1 = SideToHalfCorner(side, false, false);
+ uint32_t hc2 = SideToHalfCorner(side, true, false);
aRadii[hc1] = std::max(0, aRadii[hc1] - offset);
aRadii[hc2] = std::max(0, aRadii[hc2] - offset);
}
}
/* static */ void
nsIFrame::OutsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets)
{
@@ -1349,18 +1349,18 @@ nsIFrame::OutsetBorderRadii(nscoord aRad
return nscoord(aOffset * (1.0 + std::pow(ratio - 1, 3)));
}
}
return aOffset;
};
NS_FOR_CSS_SIDES(side) {
const nscoord offset = aOffsets.Side(side);
- const uint32_t hc1 = NS_SIDE_TO_HALF_CORNER(side, false, false);
- const uint32_t hc2 = NS_SIDE_TO_HALF_CORNER(side, true, false);
+ const uint32_t hc1 = SideToHalfCorner(side, false, false);
+ const uint32_t hc2 = SideToHalfCorner(side, true, false);
if (aRadii[hc1] > 0) {
const nscoord offset1 = AdjustOffset(aRadii[hc1], offset);
aRadii[hc1] = std::max(0, aRadii[hc1] + offset1);
}
if (aRadii[hc2] > 0) {
const nscoord offset2 = AdjustOffset(aRadii[hc2], offset);
aRadii[hc2] = std::max(0, aRadii[hc2] + offset2);
}
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -11,23 +11,16 @@
#include "gfxRect.h"
#include "nsFont.h"
#include "X11UndefineNone.h"
// XXX fold this into nsStyleContext and group by nsStyleXXX struct
namespace mozilla {
-// The results of these conversion macros are exhaustively checked in
-// nsStyleCoord.cpp.
-// Arguments must not have side effects.
-
-#define NS_SIDE_TO_HALF_CORNER(side_, second_, parallel_) \
- ((((side_) + !!(second_))*2 + ((side_) + !(parallel_))%2) % 8)
-
// Basic shapes
enum class StyleBasicShapeType : uint8_t {
Polygon,
Circle,
Ellipse,
Inset,
};
--- a/layout/style/nsStyleCoord.cpp
+++ b/layout/style/nsStyleCoord.cpp
@@ -394,19 +394,20 @@ CASE(eSideRight, true, eCornerBottomRi
CASE(eSideBottom, false, eCornerBottomRight);
CASE(eSideBottom, true, eCornerBottomLeft);
CASE(eSideLeft, false, eCornerBottomLeft);
CASE(eSideLeft, true, eCornerTopLeft);
#undef CASE
+// Validation of SideToHalfCorner.
#define CASE(side, second, parallel, result) \
- static_assert(NS_SIDE_TO_HALF_CORNER(side, second, parallel) == result, \
- "NS_SIDE_TO_HALF_CORNER is wrong")
+ static_assert(SideToHalfCorner(side, second, parallel) == result, \
+ "SideToHalfCorner is wrong")
CASE(eSideTop, false, true, eCornerTopLeftX);
CASE(eSideTop, false, false, eCornerTopLeftY);
CASE(eSideTop, true, true, eCornerTopRightX);
CASE(eSideTop, true, false, eCornerTopRightY);
CASE(eSideRight, false, false, eCornerTopRightX);
CASE(eSideRight, false, true, eCornerTopRightY);
CASE(eSideRight, true, false, eCornerBottomRightX);