Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef GFX_RECT_H |
michael@0 | 7 | #define GFX_RECT_H |
michael@0 | 8 | |
michael@0 | 9 | #include "gfxTypes.h" |
michael@0 | 10 | #include "gfxPoint.h" |
michael@0 | 11 | #include "nsDebug.h" |
michael@0 | 12 | #include "nsRect.h" |
michael@0 | 13 | #include "mozilla/gfx/BaseMargin.h" |
michael@0 | 14 | #include "mozilla/gfx/BaseRect.h" |
michael@0 | 15 | #include "mozilla/Assertions.h" |
michael@0 | 16 | |
michael@0 | 17 | struct gfxMargin : public mozilla::gfx::BaseMargin<gfxFloat, gfxMargin> { |
michael@0 | 18 | typedef mozilla::gfx::BaseMargin<gfxFloat, gfxMargin> Super; |
michael@0 | 19 | |
michael@0 | 20 | // Constructors |
michael@0 | 21 | gfxMargin() : Super() {} |
michael@0 | 22 | gfxMargin(const gfxMargin& aMargin) : Super(aMargin) {} |
michael@0 | 23 | gfxMargin(gfxFloat aTop, gfxFloat aRight, gfxFloat aBottom, gfxFloat aLeft) |
michael@0 | 24 | : Super(aTop, aRight, aBottom, aLeft) {} |
michael@0 | 25 | }; |
michael@0 | 26 | |
michael@0 | 27 | namespace mozilla { |
michael@0 | 28 | namespace css { |
michael@0 | 29 | enum Corner { |
michael@0 | 30 | // this order is important! |
michael@0 | 31 | eCornerTopLeft = 0, |
michael@0 | 32 | eCornerTopRight = 1, |
michael@0 | 33 | eCornerBottomRight = 2, |
michael@0 | 34 | eCornerBottomLeft = 3, |
michael@0 | 35 | eNumCorners = 4 |
michael@0 | 36 | }; |
michael@0 | 37 | } |
michael@0 | 38 | } |
michael@0 | 39 | #define NS_CORNER_TOP_LEFT mozilla::css::eCornerTopLeft |
michael@0 | 40 | #define NS_CORNER_TOP_RIGHT mozilla::css::eCornerTopRight |
michael@0 | 41 | #define NS_CORNER_BOTTOM_RIGHT mozilla::css::eCornerBottomRight |
michael@0 | 42 | #define NS_CORNER_BOTTOM_LEFT mozilla::css::eCornerBottomLeft |
michael@0 | 43 | #define NS_NUM_CORNERS mozilla::css::eNumCorners |
michael@0 | 44 | |
michael@0 | 45 | #define NS_FOR_CSS_CORNERS(var_) \ |
michael@0 | 46 | for (mozilla::css::Corner var_ = NS_CORNER_TOP_LEFT; \ |
michael@0 | 47 | var_ <= NS_CORNER_BOTTOM_LEFT; \ |
michael@0 | 48 | var_++) |
michael@0 | 49 | |
michael@0 | 50 | static inline mozilla::css::Corner operator++(mozilla::css::Corner& corner, int) { |
michael@0 | 51 | NS_PRECONDITION(corner >= NS_CORNER_TOP_LEFT && |
michael@0 | 52 | corner < NS_NUM_CORNERS, "Out of range corner"); |
michael@0 | 53 | corner = mozilla::css::Corner(corner + 1); |
michael@0 | 54 | return corner; |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | struct gfxRect : |
michael@0 | 58 | public mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> { |
michael@0 | 59 | typedef mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super; |
michael@0 | 60 | |
michael@0 | 61 | gfxRect() : Super() {} |
michael@0 | 62 | gfxRect(const gfxPoint& aPos, const gfxSize& aSize) : |
michael@0 | 63 | Super(aPos, aSize) {} |
michael@0 | 64 | gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) : |
michael@0 | 65 | Super(aX, aY, aWidth, aHeight) {} |
michael@0 | 66 | gfxRect(const nsIntRect& aRect) : |
michael@0 | 67 | Super(aRect.x, aRect.y, aRect.width, aRect.height) {} |
michael@0 | 68 | |
michael@0 | 69 | /** |
michael@0 | 70 | * Return true if all components of this rect are within |
michael@0 | 71 | * aEpsilon of integer coordinates, defined as |
michael@0 | 72 | * |round(coord) - coord| <= |aEpsilon| |
michael@0 | 73 | * for x,y,width,height. |
michael@0 | 74 | */ |
michael@0 | 75 | bool WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const; |
michael@0 | 76 | |
michael@0 | 77 | gfxPoint AtCorner(mozilla::css::Corner corner) const { |
michael@0 | 78 | switch (corner) { |
michael@0 | 79 | case NS_CORNER_TOP_LEFT: return TopLeft(); |
michael@0 | 80 | case NS_CORNER_TOP_RIGHT: return TopRight(); |
michael@0 | 81 | case NS_CORNER_BOTTOM_RIGHT: return BottomRight(); |
michael@0 | 82 | case NS_CORNER_BOTTOM_LEFT: return BottomLeft(); |
michael@0 | 83 | default: |
michael@0 | 84 | NS_ERROR("Invalid corner!"); |
michael@0 | 85 | break; |
michael@0 | 86 | } |
michael@0 | 87 | return gfxPoint(0.0, 0.0); |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | gfxPoint CCWCorner(mozilla::css::Side side) const { |
michael@0 | 91 | switch (side) { |
michael@0 | 92 | case NS_SIDE_TOP: return TopLeft(); |
michael@0 | 93 | case NS_SIDE_RIGHT: return TopRight(); |
michael@0 | 94 | case NS_SIDE_BOTTOM: return BottomRight(); |
michael@0 | 95 | case NS_SIDE_LEFT: return BottomLeft(); |
michael@0 | 96 | } |
michael@0 | 97 | MOZ_CRASH("Incomplete switch"); |
michael@0 | 98 | } |
michael@0 | 99 | |
michael@0 | 100 | gfxPoint CWCorner(mozilla::css::Side side) const { |
michael@0 | 101 | switch (side) { |
michael@0 | 102 | case NS_SIDE_TOP: return TopRight(); |
michael@0 | 103 | case NS_SIDE_RIGHT: return BottomRight(); |
michael@0 | 104 | case NS_SIDE_BOTTOM: return BottomLeft(); |
michael@0 | 105 | case NS_SIDE_LEFT: return TopLeft(); |
michael@0 | 106 | } |
michael@0 | 107 | MOZ_CRASH("Incomplete switch"); |
michael@0 | 108 | } |
michael@0 | 109 | |
michael@0 | 110 | /* Conditions this border to Cairo's max coordinate space. |
michael@0 | 111 | * The caller can check IsEmpty() after Condition() -- if it's TRUE, |
michael@0 | 112 | * the caller can possibly avoid doing any extra rendering. |
michael@0 | 113 | */ |
michael@0 | 114 | void Condition(); |
michael@0 | 115 | |
michael@0 | 116 | void Scale(gfxFloat k) { |
michael@0 | 117 | NS_ASSERTION(k >= 0.0, "Invalid (negative) scale factor"); |
michael@0 | 118 | x *= k; |
michael@0 | 119 | y *= k; |
michael@0 | 120 | width *= k; |
michael@0 | 121 | height *= k; |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | void Scale(gfxFloat sx, gfxFloat sy) { |
michael@0 | 125 | NS_ASSERTION(sx >= 0.0, "Invalid (negative) scale factor"); |
michael@0 | 126 | NS_ASSERTION(sy >= 0.0, "Invalid (negative) scale factor"); |
michael@0 | 127 | x *= sx; |
michael@0 | 128 | y *= sy; |
michael@0 | 129 | width *= sx; |
michael@0 | 130 | height *= sy; |
michael@0 | 131 | } |
michael@0 | 132 | |
michael@0 | 133 | void ScaleInverse(gfxFloat k) { |
michael@0 | 134 | NS_ASSERTION(k > 0.0, "Invalid (negative) scale factor"); |
michael@0 | 135 | x /= k; |
michael@0 | 136 | y /= k; |
michael@0 | 137 | width /= k; |
michael@0 | 138 | height /= k; |
michael@0 | 139 | } |
michael@0 | 140 | }; |
michael@0 | 141 | |
michael@0 | 142 | struct gfxCornerSizes { |
michael@0 | 143 | gfxSize sizes[NS_NUM_CORNERS]; |
michael@0 | 144 | |
michael@0 | 145 | gfxCornerSizes () { } |
michael@0 | 146 | |
michael@0 | 147 | gfxCornerSizes (gfxFloat v) { |
michael@0 | 148 | for (int i = 0; i < NS_NUM_CORNERS; i++) |
michael@0 | 149 | sizes[i].SizeTo(v, v); |
michael@0 | 150 | } |
michael@0 | 151 | |
michael@0 | 152 | gfxCornerSizes (gfxFloat tl, gfxFloat tr, gfxFloat br, gfxFloat bl) { |
michael@0 | 153 | sizes[NS_CORNER_TOP_LEFT].SizeTo(tl, tl); |
michael@0 | 154 | sizes[NS_CORNER_TOP_RIGHT].SizeTo(tr, tr); |
michael@0 | 155 | sizes[NS_CORNER_BOTTOM_RIGHT].SizeTo(br, br); |
michael@0 | 156 | sizes[NS_CORNER_BOTTOM_LEFT].SizeTo(bl, bl); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | gfxCornerSizes (const gfxSize& tl, const gfxSize& tr, const gfxSize& br, const gfxSize& bl) { |
michael@0 | 160 | sizes[NS_CORNER_TOP_LEFT] = tl; |
michael@0 | 161 | sizes[NS_CORNER_TOP_RIGHT] = tr; |
michael@0 | 162 | sizes[NS_CORNER_BOTTOM_RIGHT] = br; |
michael@0 | 163 | sizes[NS_CORNER_BOTTOM_LEFT] = bl; |
michael@0 | 164 | } |
michael@0 | 165 | |
michael@0 | 166 | const gfxSize& operator[] (mozilla::css::Corner index) const { |
michael@0 | 167 | return sizes[index]; |
michael@0 | 168 | } |
michael@0 | 169 | |
michael@0 | 170 | gfxSize& operator[] (mozilla::css::Corner index) { |
michael@0 | 171 | return sizes[index]; |
michael@0 | 172 | } |
michael@0 | 173 | |
michael@0 | 174 | void Scale(gfxFloat aXScale, gfxFloat aYScale) |
michael@0 | 175 | { |
michael@0 | 176 | for (int i = 0; i < NS_NUM_CORNERS; i++) |
michael@0 | 177 | sizes[i].Scale(aXScale, aYScale); |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | const gfxSize TopLeft() const { return sizes[NS_CORNER_TOP_LEFT]; } |
michael@0 | 181 | gfxSize& TopLeft() { return sizes[NS_CORNER_TOP_LEFT]; } |
michael@0 | 182 | |
michael@0 | 183 | const gfxSize TopRight() const { return sizes[NS_CORNER_TOP_RIGHT]; } |
michael@0 | 184 | gfxSize& TopRight() { return sizes[NS_CORNER_TOP_RIGHT]; } |
michael@0 | 185 | |
michael@0 | 186 | const gfxSize BottomLeft() const { return sizes[NS_CORNER_BOTTOM_LEFT]; } |
michael@0 | 187 | gfxSize& BottomLeft() { return sizes[NS_CORNER_BOTTOM_LEFT]; } |
michael@0 | 188 | |
michael@0 | 189 | const gfxSize BottomRight() const { return sizes[NS_CORNER_BOTTOM_RIGHT]; } |
michael@0 | 190 | gfxSize& BottomRight() { return sizes[NS_CORNER_BOTTOM_RIGHT]; } |
michael@0 | 191 | }; |
michael@0 | 192 | #endif /* GFX_RECT_H */ |