michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef GFX_RECT_H michael@0: #define GFX_RECT_H michael@0: michael@0: #include "gfxTypes.h" michael@0: #include "gfxPoint.h" michael@0: #include "nsDebug.h" michael@0: #include "nsRect.h" michael@0: #include "mozilla/gfx/BaseMargin.h" michael@0: #include "mozilla/gfx/BaseRect.h" michael@0: #include "mozilla/Assertions.h" michael@0: michael@0: struct gfxMargin : public mozilla::gfx::BaseMargin { michael@0: typedef mozilla::gfx::BaseMargin Super; michael@0: michael@0: // Constructors michael@0: gfxMargin() : Super() {} michael@0: gfxMargin(const gfxMargin& aMargin) : Super(aMargin) {} michael@0: gfxMargin(gfxFloat aTop, gfxFloat aRight, gfxFloat aBottom, gfxFloat aLeft) michael@0: : Super(aTop, aRight, aBottom, aLeft) {} michael@0: }; michael@0: michael@0: namespace mozilla { michael@0: namespace css { michael@0: enum Corner { michael@0: // this order is important! michael@0: eCornerTopLeft = 0, michael@0: eCornerTopRight = 1, michael@0: eCornerBottomRight = 2, michael@0: eCornerBottomLeft = 3, michael@0: eNumCorners = 4 michael@0: }; michael@0: } michael@0: } michael@0: #define NS_CORNER_TOP_LEFT mozilla::css::eCornerTopLeft michael@0: #define NS_CORNER_TOP_RIGHT mozilla::css::eCornerTopRight michael@0: #define NS_CORNER_BOTTOM_RIGHT mozilla::css::eCornerBottomRight michael@0: #define NS_CORNER_BOTTOM_LEFT mozilla::css::eCornerBottomLeft michael@0: #define NS_NUM_CORNERS mozilla::css::eNumCorners michael@0: michael@0: #define NS_FOR_CSS_CORNERS(var_) \ michael@0: for (mozilla::css::Corner var_ = NS_CORNER_TOP_LEFT; \ michael@0: var_ <= NS_CORNER_BOTTOM_LEFT; \ michael@0: var_++) michael@0: michael@0: static inline mozilla::css::Corner operator++(mozilla::css::Corner& corner, int) { michael@0: NS_PRECONDITION(corner >= NS_CORNER_TOP_LEFT && michael@0: corner < NS_NUM_CORNERS, "Out of range corner"); michael@0: corner = mozilla::css::Corner(corner + 1); michael@0: return corner; michael@0: } michael@0: michael@0: struct gfxRect : michael@0: public mozilla::gfx::BaseRect { michael@0: typedef mozilla::gfx::BaseRect Super; michael@0: michael@0: gfxRect() : Super() {} michael@0: gfxRect(const gfxPoint& aPos, const gfxSize& aSize) : michael@0: Super(aPos, aSize) {} michael@0: gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) : michael@0: Super(aX, aY, aWidth, aHeight) {} michael@0: gfxRect(const nsIntRect& aRect) : michael@0: Super(aRect.x, aRect.y, aRect.width, aRect.height) {} michael@0: michael@0: /** michael@0: * Return true if all components of this rect are within michael@0: * aEpsilon of integer coordinates, defined as michael@0: * |round(coord) - coord| <= |aEpsilon| michael@0: * for x,y,width,height. michael@0: */ michael@0: bool WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const; michael@0: michael@0: gfxPoint AtCorner(mozilla::css::Corner corner) const { michael@0: switch (corner) { michael@0: case NS_CORNER_TOP_LEFT: return TopLeft(); michael@0: case NS_CORNER_TOP_RIGHT: return TopRight(); michael@0: case NS_CORNER_BOTTOM_RIGHT: return BottomRight(); michael@0: case NS_CORNER_BOTTOM_LEFT: return BottomLeft(); michael@0: default: michael@0: NS_ERROR("Invalid corner!"); michael@0: break; michael@0: } michael@0: return gfxPoint(0.0, 0.0); michael@0: } michael@0: michael@0: gfxPoint CCWCorner(mozilla::css::Side side) const { michael@0: switch (side) { michael@0: case NS_SIDE_TOP: return TopLeft(); michael@0: case NS_SIDE_RIGHT: return TopRight(); michael@0: case NS_SIDE_BOTTOM: return BottomRight(); michael@0: case NS_SIDE_LEFT: return BottomLeft(); michael@0: } michael@0: MOZ_CRASH("Incomplete switch"); michael@0: } michael@0: michael@0: gfxPoint CWCorner(mozilla::css::Side side) const { michael@0: switch (side) { michael@0: case NS_SIDE_TOP: return TopRight(); michael@0: case NS_SIDE_RIGHT: return BottomRight(); michael@0: case NS_SIDE_BOTTOM: return BottomLeft(); michael@0: case NS_SIDE_LEFT: return TopLeft(); michael@0: } michael@0: MOZ_CRASH("Incomplete switch"); michael@0: } michael@0: michael@0: /* Conditions this border to Cairo's max coordinate space. michael@0: * The caller can check IsEmpty() after Condition() -- if it's TRUE, michael@0: * the caller can possibly avoid doing any extra rendering. michael@0: */ michael@0: void Condition(); michael@0: michael@0: void Scale(gfxFloat k) { michael@0: NS_ASSERTION(k >= 0.0, "Invalid (negative) scale factor"); michael@0: x *= k; michael@0: y *= k; michael@0: width *= k; michael@0: height *= k; michael@0: } michael@0: michael@0: void Scale(gfxFloat sx, gfxFloat sy) { michael@0: NS_ASSERTION(sx >= 0.0, "Invalid (negative) scale factor"); michael@0: NS_ASSERTION(sy >= 0.0, "Invalid (negative) scale factor"); michael@0: x *= sx; michael@0: y *= sy; michael@0: width *= sx; michael@0: height *= sy; michael@0: } michael@0: michael@0: void ScaleInverse(gfxFloat k) { michael@0: NS_ASSERTION(k > 0.0, "Invalid (negative) scale factor"); michael@0: x /= k; michael@0: y /= k; michael@0: width /= k; michael@0: height /= k; michael@0: } michael@0: }; michael@0: michael@0: struct gfxCornerSizes { michael@0: gfxSize sizes[NS_NUM_CORNERS]; michael@0: michael@0: gfxCornerSizes () { } michael@0: michael@0: gfxCornerSizes (gfxFloat v) { michael@0: for (int i = 0; i < NS_NUM_CORNERS; i++) michael@0: sizes[i].SizeTo(v, v); michael@0: } michael@0: michael@0: gfxCornerSizes (gfxFloat tl, gfxFloat tr, gfxFloat br, gfxFloat bl) { michael@0: sizes[NS_CORNER_TOP_LEFT].SizeTo(tl, tl); michael@0: sizes[NS_CORNER_TOP_RIGHT].SizeTo(tr, tr); michael@0: sizes[NS_CORNER_BOTTOM_RIGHT].SizeTo(br, br); michael@0: sizes[NS_CORNER_BOTTOM_LEFT].SizeTo(bl, bl); michael@0: } michael@0: michael@0: gfxCornerSizes (const gfxSize& tl, const gfxSize& tr, const gfxSize& br, const gfxSize& bl) { michael@0: sizes[NS_CORNER_TOP_LEFT] = tl; michael@0: sizes[NS_CORNER_TOP_RIGHT] = tr; michael@0: sizes[NS_CORNER_BOTTOM_RIGHT] = br; michael@0: sizes[NS_CORNER_BOTTOM_LEFT] = bl; michael@0: } michael@0: michael@0: const gfxSize& operator[] (mozilla::css::Corner index) const { michael@0: return sizes[index]; michael@0: } michael@0: michael@0: gfxSize& operator[] (mozilla::css::Corner index) { michael@0: return sizes[index]; michael@0: } michael@0: michael@0: void Scale(gfxFloat aXScale, gfxFloat aYScale) michael@0: { michael@0: for (int i = 0; i < NS_NUM_CORNERS; i++) michael@0: sizes[i].Scale(aXScale, aYScale); michael@0: } michael@0: michael@0: const gfxSize TopLeft() const { return sizes[NS_CORNER_TOP_LEFT]; } michael@0: gfxSize& TopLeft() { return sizes[NS_CORNER_TOP_LEFT]; } michael@0: michael@0: const gfxSize TopRight() const { return sizes[NS_CORNER_TOP_RIGHT]; } michael@0: gfxSize& TopRight() { return sizes[NS_CORNER_TOP_RIGHT]; } michael@0: michael@0: const gfxSize BottomLeft() const { return sizes[NS_CORNER_BOTTOM_LEFT]; } michael@0: gfxSize& BottomLeft() { return sizes[NS_CORNER_BOTTOM_LEFT]; } michael@0: michael@0: const gfxSize BottomRight() const { return sizes[NS_CORNER_BOTTOM_RIGHT]; } michael@0: gfxSize& BottomRight() { return sizes[NS_CORNER_BOTTOM_RIGHT]; } michael@0: }; michael@0: #endif /* GFX_RECT_H */