зеркало из https://github.com/mozilla/pjs.git
Bug 641426. Part 7: Create Rect template. r=joe,sr=cjones
This commit is contained in:
Родитель
1ed92bdb3e
Коммит
d729b7c290
|
@ -0,0 +1,314 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert O'Callahan <robert@ocallahan.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MOZILLA_BASERECT_H_
|
||||
#define MOZILLA_BASERECT_H_
|
||||
|
||||
#include "nsAlgorithm.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* Rectangles have two interpretations: a set of (zero-size) points,
|
||||
* and a rectangular area of the plane. Most rectangle operations behave
|
||||
* the same no matter what interpretation is being used, but some operations
|
||||
* differ:
|
||||
* -- Equality tests behave differently. When a rectangle represents an area,
|
||||
* all zero-width and zero-height rectangles are equal to each other since they
|
||||
* represent the empty area. But when a rectangle represents a set of
|
||||
* mathematical points, zero-width and zero-height rectangles can be unequal.
|
||||
* -- The union operation can behave differently. When rectangles represent
|
||||
* areas, taking the union of a zero-width or zero-height rectangle with
|
||||
* another rectangle can just ignore the empty rectangle. But when rectangles
|
||||
* represent sets of mathematical points, we may need to extend the latter
|
||||
* rectangle to include the points of a zero-width or zero-height rectangle.
|
||||
*
|
||||
* To ensure that these interpretations are explicitly disambiguated, we
|
||||
* deny access to the == and != operators and require use of IsEqualEdges and
|
||||
* IsEqualInterior instead. Similarly we provide separate Union and UnionEdges
|
||||
* methods.
|
||||
*
|
||||
* Do not use this class directly. Subclass it, pass that subclass as the
|
||||
* Sub parameter, and only use that subclass.
|
||||
*/
|
||||
template <class T, class Sub, class Point, class SizeT, class Margin>
|
||||
struct BaseRect {
|
||||
T x, y, width, height;
|
||||
|
||||
// Constructors
|
||||
BaseRect() : x(0), y(0), width(0), height(0) {}
|
||||
BaseRect(const Point& aOrigin, const SizeT &aSize) :
|
||||
x(aOrigin.x), y(aOrigin.y), width(aSize.width), height(aSize.height)
|
||||
{
|
||||
}
|
||||
BaseRect(T aX, T aY, T aWidth, T aHeight) :
|
||||
x(aX), y(aY), width(aWidth), height(aHeight)
|
||||
{
|
||||
}
|
||||
|
||||
// Emptiness. An empty rect is one that has no area, i.e. its height or width
|
||||
// is <= 0
|
||||
bool IsEmpty() const { return height <= 0 || width <= 0; }
|
||||
void SetEmpty() { width = height = 0; }
|
||||
|
||||
// Returns true if this rectangle contains the interior of aRect. Always
|
||||
// returns true if aRect is empty, and always returns false is aRect is
|
||||
// nonempty but this rect is empty.
|
||||
bool Contains(const Sub& aRect) const
|
||||
{
|
||||
return aRect.IsEmpty() ||
|
||||
(x <= aRect.x && aRect.XMost() <= XMost() &&
|
||||
y <= aRect.y && aRect.YMost() <= YMost());
|
||||
}
|
||||
// Returns true if this rectangle contains the rectangle (aX,aY,1,1).
|
||||
bool Contains(T aX, T aY) const
|
||||
{
|
||||
return x <= aX && aX + 1 <= XMost() &&
|
||||
y <= aY && aY + 1 <= YMost();
|
||||
}
|
||||
// Returns true if this rectangle contains the rectangle (aPoint.x,aPoint.y,1,1).
|
||||
bool Contains(const Point& aPoint) const { return Contains(aPoint.x, aPoint.y); }
|
||||
|
||||
// Intersection. Returns TRUE if the receiver's area has non-empty
|
||||
// intersection with aRect's area, and FALSE otherwise.
|
||||
// Always returns false if aRect is empty or 'this' is empty.
|
||||
bool Intersects(const Sub& aRect) const
|
||||
{
|
||||
return x < aRect.XMost() && aRect.x < XMost() &&
|
||||
y < aRect.YMost() && aRect.y < YMost();
|
||||
}
|
||||
// Returns the rectangle containing the intersection of the points
|
||||
// (including edges) of *this and aRect. If there are no points in that
|
||||
// intersection, returns an empty rectangle with x/y set to the max of the x/y
|
||||
// of *this and aRect.
|
||||
Sub Intersect(const Sub& aRect) const
|
||||
{
|
||||
Sub result;
|
||||
result.x = NS_MAX(x, aRect.x);
|
||||
result.y = NS_MAX(y, aRect.y);
|
||||
result.width = NS_MIN(XMost(), aRect.XMost()) - result.x;
|
||||
result.height = NS_MIN(YMost(), aRect.YMost()) - result.y;
|
||||
if (result.width < 0 || result.height < 0) {
|
||||
result.SizeTo(0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Sets *this to be the rectangle containing the intersection of the points
|
||||
// (including edges) of *this and aRect. If there are no points in that
|
||||
// intersection, sets *this to be an empty rectangle with x/y set to the max
|
||||
// of the x/y of *this and aRect.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
bool IntersectRect(const Sub& aRect1, const Sub& aRect2)
|
||||
{
|
||||
*static_cast<Sub*>(this) = aRect1.Intersect(aRect2);
|
||||
return !IsEmpty();
|
||||
}
|
||||
|
||||
// Returns the smallest rectangle that contains both the area of both
|
||||
// this and aRect2.
|
||||
// Thus, empty input rectangles are ignored.
|
||||
// If both rectangles are empty, returns this.
|
||||
Sub Union(const Sub& aRect) const
|
||||
{
|
||||
if (IsEmpty()) {
|
||||
return aRect;
|
||||
} else if (aRect.IsEmpty()) {
|
||||
return *static_cast<const Sub*>(this);
|
||||
} else {
|
||||
return UnionEdges(aRect);
|
||||
}
|
||||
}
|
||||
// Returns the smallest rectangle that contains both the points (including
|
||||
// edges) of both aRect1 and aRect2.
|
||||
// Thus, empty input rectangles are allowed to affect the result.
|
||||
Sub UnionEdges(const Sub& aRect) const
|
||||
{
|
||||
Sub result;
|
||||
result.x = NS_MIN(x, aRect.x);
|
||||
result.y = NS_MIN(y, aRect.y);
|
||||
result.width = NS_MAX(XMost(), aRect.XMost()) - result.x;
|
||||
result.height = NS_MAX(YMost(), aRect.YMost()) - result.y;
|
||||
return result;
|
||||
}
|
||||
// Computes the smallest rectangle that contains both the area of both
|
||||
// aRect1 and aRect2, and fills 'this' with the result.
|
||||
// Thus, empty input rectangles are ignored.
|
||||
// If both rectangles are empty, sets 'this' to aRect2.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
void UnionRect(const Sub& aRect1, const Sub& aRect2)
|
||||
{
|
||||
*static_cast<Sub*>(this) = aRect1.Union(aRect2);
|
||||
}
|
||||
|
||||
// Computes the smallest rectangle that contains both the points (including
|
||||
// edges) of both aRect1 and aRect2.
|
||||
// Thus, empty input rectangles are allowed to affect the result.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
void UnionRectEdges(const Sub& aRect1, const Sub& aRect2)
|
||||
{
|
||||
*static_cast<Sub*>(this) = aRect1.UnionEdges(aRect2);
|
||||
}
|
||||
|
||||
void SetRect(T aX, T aY, T aWidth, T aHeight)
|
||||
{
|
||||
x = aX; y = aY; width = aWidth; height = aHeight;
|
||||
}
|
||||
void SetRect(const Point& aPt, const SizeT& aSize)
|
||||
{
|
||||
SetRect(aPt.x, aPt.y, aSize.width, aSize.height);
|
||||
}
|
||||
void MoveTo(T aX, T aY) { x = aX; y = aY; }
|
||||
void MoveTo(const Point& aPoint) { x = aPoint.x; y = aPoint.y; }
|
||||
void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; }
|
||||
void MoveBy(const Point& aPoint) { x += aPoint.x; y += aPoint.y; }
|
||||
void SizeTo(T aWidth, T aHeight) { width = aWidth; height = aHeight; }
|
||||
void SizeTo(const SizeT& aSize) { width = aSize.width; height = aSize.height; }
|
||||
|
||||
void Inflate(T aDx, T aDy)
|
||||
{
|
||||
x -= aDx;
|
||||
y -= aDy;
|
||||
width += 2 * aDx;
|
||||
height += 2 * aDy;
|
||||
}
|
||||
void Inflate(const Margin& aMargin)
|
||||
{
|
||||
x -= aMargin.left;
|
||||
y -= aMargin.top;
|
||||
width += aMargin.LeftRight();
|
||||
height += aMargin.TopBottom();
|
||||
}
|
||||
|
||||
void Deflate(T aDx, T aDy)
|
||||
{
|
||||
x += aDx;
|
||||
y += aDy;
|
||||
width = NS_MAX(T(0), width - 2 * aDx);
|
||||
height = NS_MAX(T(0), height - 2 * aDy);
|
||||
}
|
||||
void Deflate(const Margin& aMargin)
|
||||
{
|
||||
x += aMargin.left;
|
||||
y += aMargin.top;
|
||||
width = NS_MAX(T(0), width - aMargin.LeftRight());
|
||||
height = NS_MAX(T(0), height - aMargin.TopBottom());
|
||||
}
|
||||
|
||||
// Return true if the rectangles contain the same set of points, including
|
||||
// points on the edges.
|
||||
// Use when we care about the exact x/y/width/height values being
|
||||
// equal (i.e. we care about differences in empty rectangles).
|
||||
bool IsEqualEdges(const Sub& aRect) const
|
||||
{
|
||||
return x == aRect.x && y == aRect.y &&
|
||||
width == aRect.width && height == aRect.height;
|
||||
}
|
||||
// Return true if the rectangles contain the same area of the plane.
|
||||
// Use when we do not care about differences in empty rectangles.
|
||||
bool IsEqualInterior(const Sub& aRect) const
|
||||
{
|
||||
return IsEqualEdges(aRect) || (IsEmpty() && aRect.IsEmpty());
|
||||
}
|
||||
|
||||
Sub operator+(const Point& aPoint) const
|
||||
{
|
||||
return Sub(x + aPoint.x, y + aPoint.y, width, height);
|
||||
}
|
||||
Sub operator-(const Point& aPoint) const
|
||||
{
|
||||
return Sub(x - aPoint.x, y - aPoint.y, width, height);
|
||||
}
|
||||
Sub& operator+=(const Point& aPoint)
|
||||
{
|
||||
MoveBy(aPoint);
|
||||
return *static_cast<Sub*>(this);
|
||||
}
|
||||
Sub& operator-=(const Point& aPoint)
|
||||
{
|
||||
MoveBy(-aPoint);
|
||||
return *static_cast<Sub*>(this);
|
||||
}
|
||||
|
||||
// Find difference as a Margin
|
||||
Margin operator-(const Sub& aRect) const
|
||||
{
|
||||
return Margin(aRect.x - x, aRect.y - y,
|
||||
XMost() - aRect.XMost(), YMost() - aRect.YMost());
|
||||
}
|
||||
|
||||
// Helpers for accessing the vertices
|
||||
Point TopLeft() const { return Point(x, y); }
|
||||
Point TopRight() const { return Point(XMost(), y); }
|
||||
Point BottomLeft() const { return Point(x, YMost()); }
|
||||
Point BottomRight() const { return Point(XMost(), YMost()); }
|
||||
Point Center() const { return Point(x, y) + Point(width, height)/2; }
|
||||
SizeT Size() const { return SizeT(width, height); }
|
||||
|
||||
// Helper methods for computing the extents
|
||||
T X() const { return x; }
|
||||
T Y() const { return y; }
|
||||
T Width() const { return width; }
|
||||
T Height() const { return height; }
|
||||
T XMost() const { return x + width; }
|
||||
T YMost() const { return y + height; }
|
||||
|
||||
// Scale 'this' by aScale, converting coordinates to integers so that the result is
|
||||
// the smallest integer-coordinate rectangle containing the unrounded result.
|
||||
void ScaleRoundOut(double aScale) { ScaleRoundOut(aScale, aScale); }
|
||||
void ScaleRoundOut(double aXScale, double aYScale)
|
||||
{
|
||||
T right = static_cast<T>(NS_ceil(double(XMost()) * aXScale));
|
||||
T bottom = static_cast<T>(NS_ceil(double(YMost()) * aYScale));
|
||||
x = static_cast<T>(NS_floor(double(x) * aXScale));
|
||||
y = static_cast<T>(NS_floor(double(y) * aYScale));
|
||||
width = right - x;
|
||||
height = bottom - y;
|
||||
}
|
||||
|
||||
private:
|
||||
// Do not use the default operator== or operator!= !
|
||||
// Use IsEqualEdges or IsEqualInterior explicitly.
|
||||
bool operator==(const Sub& aRect) const { return false; }
|
||||
bool operator!=(const Sub& aRect) const { return false; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_BASERECT_H_ */
|
|
@ -64,6 +64,7 @@ EXPORTS_NAMESPACES = mozilla
|
|||
EXPORTS_mozilla = \
|
||||
BaseMargin.h \
|
||||
BasePoint.h \
|
||||
BaseRect.h \
|
||||
BaseSize.h \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -44,167 +44,9 @@
|
|||
// the mozilla::css::Side sequence must match the nsMargin nscoord sequence
|
||||
PR_STATIC_ASSERT((NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3));
|
||||
|
||||
|
||||
/* static */
|
||||
const nsIntRect nsIntRect::kMaxSizedIntRect(0, 0, INT_MAX, INT_MAX);
|
||||
|
||||
// Containment
|
||||
PRBool nsRect::Contains(nscoord aX, nscoord aY) const
|
||||
{
|
||||
return (PRBool) ((aX >= x) && (aY >= y) &&
|
||||
(aX < XMost()) && (aY < YMost()));
|
||||
}
|
||||
|
||||
//Also Returns true if aRect is Empty
|
||||
PRBool nsRect::Contains(const nsRect &aRect) const
|
||||
{
|
||||
return aRect.IsEmpty() ||
|
||||
((PRBool) ((aRect.x >= x) && (aRect.y >= y) &&
|
||||
(aRect.XMost() <= XMost()) && (aRect.YMost() <= YMost())));
|
||||
}
|
||||
|
||||
// Intersection. Returns TRUE if the receiver overlaps aRect and
|
||||
// FALSE otherwise
|
||||
PRBool nsRect::Intersects(const nsRect &aRect) const
|
||||
{
|
||||
return (PRBool) ((x < aRect.XMost()) && (y < aRect.YMost()) &&
|
||||
(aRect.x < XMost()) && (aRect.y < YMost()));
|
||||
}
|
||||
|
||||
// Computes the area in which aRect1 and aRect2 overlap and fills 'this' with
|
||||
// the result. Returns FALSE if the rectangles don't intersect.
|
||||
PRBool nsRect::IntersectRect(const nsRect &aRect1, const nsRect &aRect2)
|
||||
{
|
||||
nscoord xmost1 = aRect1.XMost();
|
||||
nscoord ymost1 = aRect1.YMost();
|
||||
nscoord xmost2 = aRect2.XMost();
|
||||
nscoord ymost2 = aRect2.YMost();
|
||||
nscoord temp;
|
||||
|
||||
x = PR_MAX(aRect1.x, aRect2.x);
|
||||
y = PR_MAX(aRect1.y, aRect2.y);
|
||||
|
||||
// Compute the destination width
|
||||
temp = PR_MIN(xmost1, xmost2);
|
||||
if (temp <= x) {
|
||||
width = 0;
|
||||
} else {
|
||||
width = temp - x;
|
||||
}
|
||||
|
||||
// Compute the destination height
|
||||
temp = PR_MIN(ymost1, ymost2);
|
||||
if (temp <= y) {
|
||||
height = 0;
|
||||
} else {
|
||||
height = temp - y;
|
||||
}
|
||||
|
||||
return !IsEmpty();
|
||||
}
|
||||
|
||||
// Computes the smallest rectangle that contains both aRect1 and aRect2 and
|
||||
// fills 'this' with the result. Returns FALSE if both aRect1 and aRect2 are
|
||||
// empty and TRUE otherwise
|
||||
PRBool nsRect::UnionRect(const nsRect &aRect1, const nsRect &aRect2)
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
// Is aRect1 empty?
|
||||
if (aRect1.IsEmpty()) {
|
||||
if (aRect2.IsEmpty()) {
|
||||
// Both rectangles are empty which is an error
|
||||
Empty();
|
||||
result = PR_FALSE;
|
||||
} else {
|
||||
// aRect1 is empty so set the result to aRect2
|
||||
*this = aRect2;
|
||||
}
|
||||
} else if (aRect2.IsEmpty()) {
|
||||
// aRect2 is empty so set the result to aRect1
|
||||
*this = aRect1;
|
||||
} else {
|
||||
UnionRectEdges(aRect1, aRect2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void nsRect::UnionRectEdges(const nsRect &aRect1, const nsRect &aRect2)
|
||||
{
|
||||
nscoord xmost1 = aRect1.XMost();
|
||||
nscoord xmost2 = aRect2.XMost();
|
||||
nscoord ymost1 = aRect1.YMost();
|
||||
nscoord ymost2 = aRect2.YMost();
|
||||
|
||||
// Compute the origin
|
||||
x = PR_MIN(aRect1.x, aRect2.x);
|
||||
y = PR_MIN(aRect1.y, aRect2.y);
|
||||
|
||||
// Compute the size
|
||||
width = PR_MAX(xmost1, xmost2) - x;
|
||||
height = PR_MAX(ymost1, ymost2) - y;
|
||||
}
|
||||
|
||||
// Inflate the rect by the specified width and height
|
||||
void nsRect::Inflate(nscoord aDx, nscoord aDy)
|
||||
{
|
||||
x -= aDx;
|
||||
y -= aDy;
|
||||
width += 2 * aDx;
|
||||
height += 2 * aDy;
|
||||
}
|
||||
|
||||
// Inflate the rect by the specified margin
|
||||
void nsRect::Inflate(const nsMargin &aMargin)
|
||||
{
|
||||
x -= aMargin.left;
|
||||
y -= aMargin.top;
|
||||
width += aMargin.left + aMargin.right;
|
||||
height += aMargin.top + aMargin.bottom;
|
||||
}
|
||||
|
||||
// Deflate the rect by the specified width and height
|
||||
void nsRect::Deflate(nscoord aDx, nscoord aDy)
|
||||
{
|
||||
x += aDx;
|
||||
y += aDy;
|
||||
width = PR_MAX(0, width - 2 * aDx);
|
||||
height = PR_MAX(0, height - 2 * aDy);
|
||||
}
|
||||
|
||||
// Deflate the rect by the specified margin
|
||||
void nsRect::Deflate(const nsMargin &aMargin)
|
||||
{
|
||||
x += aMargin.left;
|
||||
y += aMargin.top;
|
||||
width = PR_MAX(0, width - aMargin.LeftRight());
|
||||
height = PR_MAX(0, height - aMargin.TopBottom());
|
||||
}
|
||||
|
||||
// Find difference between rects as an nsMargin
|
||||
nsMargin nsRect::operator-(const nsRect& aRect) const
|
||||
{
|
||||
nsMargin margin;
|
||||
margin.left = aRect.x - x;
|
||||
margin.right = XMost() - aRect.XMost();
|
||||
margin.top = aRect.y - y;
|
||||
margin.bottom = YMost() - aRect.YMost();
|
||||
return margin;
|
||||
}
|
||||
|
||||
// scale the rect but round to smallest containing rect
|
||||
nsRect& nsRect::ScaleRoundOut(float aXScale, float aYScale)
|
||||
{
|
||||
nscoord right = NSToCoordCeil(float(XMost()) * aXScale);
|
||||
nscoord bottom = NSToCoordCeil(float(YMost()) * aYScale);
|
||||
x = NSToCoordFloor(float(x) * aXScale);
|
||||
y = NSToCoordFloor(float(y) * aYScale);
|
||||
width = (right - x);
|
||||
height = (bottom - y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static bool IsFloatInteger(float aFloat)
|
||||
{
|
||||
|
@ -259,85 +101,3 @@ FILE* operator<<(FILE* out, const nsRect& rect)
|
|||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
// Computes the area in which aRect1 and aRect2 overlap and fills 'this' with
|
||||
// the result. Returns FALSE if the rectangles don't intersect.
|
||||
PRBool nsIntRect::IntersectRect(const nsIntRect &aRect1, const nsIntRect &aRect2)
|
||||
{
|
||||
PRInt32 xmost1 = aRect1.XMost();
|
||||
PRInt32 ymost1 = aRect1.YMost();
|
||||
PRInt32 xmost2 = aRect2.XMost();
|
||||
PRInt32 ymost2 = aRect2.YMost();
|
||||
PRInt32 temp;
|
||||
|
||||
x = PR_MAX(aRect1.x, aRect2.x);
|
||||
y = PR_MAX(aRect1.y, aRect2.y);
|
||||
|
||||
// Compute the destination width
|
||||
temp = PR_MIN(xmost1, xmost2);
|
||||
if (temp <= x) {
|
||||
Empty();
|
||||
return PR_FALSE;
|
||||
}
|
||||
width = temp - x;
|
||||
|
||||
// Compute the destination height
|
||||
temp = PR_MIN(ymost1, ymost2);
|
||||
if (temp <= y) {
|
||||
Empty();
|
||||
return PR_FALSE;
|
||||
}
|
||||
height = temp - y;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Computes the smallest rectangle that contains both aRect1 and aRect2 and
|
||||
// fills 'this' with the result. Returns FALSE if both aRect1 and aRect2 are
|
||||
// empty and TRUE otherwise
|
||||
PRBool nsIntRect::UnionRect(const nsIntRect &aRect1, const nsIntRect &aRect2)
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
// Is aRect1 empty?
|
||||
if (aRect1.IsEmpty()) {
|
||||
if (aRect2.IsEmpty()) {
|
||||
// Both rectangles are empty which is an error
|
||||
Empty();
|
||||
result = PR_FALSE;
|
||||
} else {
|
||||
// aRect1 is empty so set the result to aRect2
|
||||
*this = aRect2;
|
||||
}
|
||||
} else if (aRect2.IsEmpty()) {
|
||||
// aRect2 is empty so set the result to aRect1
|
||||
*this = aRect1;
|
||||
} else {
|
||||
PRInt32 xmost1 = aRect1.XMost();
|
||||
PRInt32 xmost2 = aRect2.XMost();
|
||||
PRInt32 ymost1 = aRect1.YMost();
|
||||
PRInt32 ymost2 = aRect2.YMost();
|
||||
|
||||
// Compute the origin
|
||||
x = PR_MIN(aRect1.x, aRect2.x);
|
||||
y = PR_MIN(aRect1.y, aRect2.y);
|
||||
|
||||
// Compute the size
|
||||
width = PR_MAX(xmost1, xmost2) - x;
|
||||
height = PR_MAX(ymost1, ymost2) - y;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// scale the rect but round to smallest containing rect
|
||||
nsIntRect& nsIntRect::ScaleRoundOut(float aXScale, float aYScale)
|
||||
{
|
||||
nscoord right = NSToCoordCeil(float(XMost()) * aXScale);
|
||||
nscoord bottom = NSToCoordCeil(float(YMost()) * aYScale);
|
||||
x = NSToCoordFloor(float(x) * aXScale);
|
||||
y = NSToCoordFloor(float(y) * aYScale);
|
||||
width = (right - x);
|
||||
height = (bottom - y);
|
||||
return *this;
|
||||
}
|
||||
|
|
296
gfx/src/nsRect.h
296
gfx/src/nsRect.h
|
@ -46,30 +46,33 @@
|
|||
#include "nsMargin.h"
|
||||
#include "gfxCore.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "mozilla/BaseRect.h"
|
||||
|
||||
struct nsIntRect;
|
||||
|
||||
struct NS_GFX nsRect {
|
||||
nscoord x, y;
|
||||
nscoord width, height;
|
||||
struct NS_GFX nsRect :
|
||||
public mozilla::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
|
||||
typedef mozilla::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
|
||||
|
||||
static void VERIFY_COORD(nscoord aValue) { ::VERIFY_COORD(aValue); }
|
||||
|
||||
// Constructors
|
||||
nsRect() : x(0), y(0), width(0), height(0) {
|
||||
nsRect() : Super()
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsRect);
|
||||
}
|
||||
nsRect(const nsRect& aRect) {
|
||||
nsRect(const nsRect& aRect) : Super(aRect)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsRect);
|
||||
*this = aRect;
|
||||
}
|
||||
nsRect(const nsPoint& aOrigin, const nsSize &aSize) {
|
||||
nsRect(const nsPoint& aOrigin, const nsSize &aSize) : Super(aOrigin, aSize)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsRect);
|
||||
x = aOrigin.x; y = aOrigin.y;
|
||||
width = aSize.width; height = aSize.height;
|
||||
}
|
||||
nsRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) {
|
||||
nsRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) :
|
||||
Super(aX, aY, aWidth, aHeight)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsRect);
|
||||
x = aX; y = aY; width = aWidth; height = aHeight;
|
||||
VERIFY_COORD(x); VERIFY_COORD(y); VERIFY_COORD(width); VERIFY_COORD(height);
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
|
@ -77,114 +80,8 @@ struct NS_GFX nsRect {
|
|||
MOZ_COUNT_DTOR(nsRect);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Emptiness. An empty rect is one that has no area, i.e. its height or width
|
||||
// is <= 0
|
||||
PRBool IsEmpty() const {
|
||||
return (PRBool) ((height <= 0) || (width <= 0));
|
||||
}
|
||||
void SetEmpty() {width = height = 0;}
|
||||
|
||||
// Returns true if this rectangle contains the interior of aRect. Always
|
||||
// returns true if aRect is empty, and always returns false is aRect is
|
||||
// nonempty but this rect is empty.
|
||||
PRBool Contains(const nsRect& aRect) const;
|
||||
// Returns true if this rectangle contains the given point; if the point
|
||||
// is on the edge of the rectangle, this returns true.
|
||||
PRBool Contains(nscoord aX, nscoord aY) const;
|
||||
PRBool Contains(const nsPoint& aPoint) const {return Contains(aPoint.x, aPoint.y);}
|
||||
|
||||
// Intersection. Returns TRUE if the receiver's area has non-empty
|
||||
// intersection with aRect's area, and FALSE otherwise.
|
||||
// Always returns false if aRect is empty or 'this' is empty.
|
||||
PRBool Intersects(const nsRect& aRect) const;
|
||||
|
||||
// Sets 'this' to be a rectangle containing the intersection of the points
|
||||
// (including edges) of aRect1 and aRect2, or 0,0,0,0 if that intersection is
|
||||
// empty. Returns false if the resulting rectangle is empty.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
PRBool IntersectRect(const nsRect& aRect1, const nsRect& aRect2);
|
||||
|
||||
// Computes the smallest rectangle that contains both the area of both
|
||||
// aRect1 and aRect2, and fills 'this' with the result.
|
||||
// Thus, empty input rectangles are ignored.
|
||||
// Returns FALSE and sets 'this' rect to be an empty rect if both aRect1
|
||||
// and aRect2 are empty.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
PRBool UnionRect(const nsRect& aRect1, const nsRect& aRect2);
|
||||
|
||||
// Computes the smallest rectangle that contains both the points (including
|
||||
// edges) of both aRect1 and aRect2.
|
||||
// Thus, empty input rectangles are allowed to affect the result.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
void UnionRectEdges(const nsRect& aRect1, const nsRect& aRect2);
|
||||
|
||||
// Accessors
|
||||
void SetRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) {
|
||||
x = aX; y = aY; width = aWidth; height = aHeight;
|
||||
}
|
||||
void SetRect(const nsPoint& aPt, const nsSize& aSize) {
|
||||
SetRect(aPt.x, aPt.y, aSize.width, aSize.height);
|
||||
}
|
||||
void MoveTo(nscoord aX, nscoord aY) {x = aX; y = aY;}
|
||||
void MoveTo(const nsPoint& aPoint) {x = aPoint.x; y = aPoint.y;}
|
||||
void MoveBy(nscoord aDx, nscoord aDy) {x += aDx; y += aDy;}
|
||||
void MoveBy(const nsPoint& aPoint) {x += aPoint.x; y += aPoint.y;}
|
||||
void SizeTo(nscoord aWidth, nscoord aHeight) {width = aWidth; height = aHeight;}
|
||||
void SizeTo(const nsSize& aSize) {SizeTo(aSize.width, aSize.height);}
|
||||
void SizeBy(nscoord aDeltaWidth, nscoord aDeltaHeight) {width += aDeltaWidth;
|
||||
height += aDeltaHeight;}
|
||||
|
||||
// Inflate the rect by the specified width/height or margin
|
||||
void Inflate(nscoord aDx, nscoord aDy);
|
||||
void Inflate(const nsSize& aSize) {Inflate(aSize.width, aSize.height);}
|
||||
void Inflate(const nsMargin& aMargin);
|
||||
|
||||
// Deflate the rect by the specified width/height or margin
|
||||
void Deflate(nscoord aDx, nscoord aDy);
|
||||
void Deflate(const nsSize& aSize) {Deflate(aSize.width, aSize.height);}
|
||||
void Deflate(const nsMargin& aMargin);
|
||||
|
||||
// Return true if the rectangles contain the same set of points, including
|
||||
// points on the edges.
|
||||
// Use when we care about the exact x/y/width/height values being
|
||||
// equal (i.e. we care about differences in empty rectangles).
|
||||
PRBool IsEqualEdges(const nsRect& aRect) const {
|
||||
return x == aRect.x && y == aRect.y &&
|
||||
width == aRect.width && height == aRect.height;
|
||||
}
|
||||
// Return true if the rectangles contain the same area of the plane.
|
||||
// Use when we do not care about differences in empty rectangles.
|
||||
PRBool IsEqualInterior(const nsRect& aRect) const {
|
||||
return IsEqualEdges(aRect) || (IsEmpty() && aRect.IsEmpty());
|
||||
}
|
||||
|
||||
// Arithmetic with nsPoints
|
||||
nsRect operator+(const nsPoint& aPoint) const {
|
||||
return nsRect(x + aPoint.x, y + aPoint.y, width, height);
|
||||
}
|
||||
nsRect operator-(const nsPoint& aPoint) const {
|
||||
return nsRect(x - aPoint.x, y - aPoint.y, width, height);
|
||||
}
|
||||
nsRect& operator+=(const nsPoint& aPoint) {x += aPoint.x; y += aPoint.y; return *this;}
|
||||
nsRect& operator-=(const nsPoint& aPoint) {x -= aPoint.x; y -= aPoint.y; return *this;}
|
||||
|
||||
// Arithmetic with nsMargins
|
||||
nsMargin operator-(const nsRect& aRect) const; // Find difference as nsMargin
|
||||
nsRect& operator+=(const nsMargin& aMargin) { Inflate(aMargin); return *this; }
|
||||
nsRect& operator-=(const nsMargin& aMargin) { Deflate(aMargin); return *this; }
|
||||
nsRect operator+(const nsMargin& aMargin) const { return nsRect(*this) += aMargin; }
|
||||
nsRect operator-(const nsMargin& aMargin) const { return nsRect(*this) -= aMargin; }
|
||||
|
||||
// Scale by aScale, converting coordinates to integers so that the result is
|
||||
// the smallest integer-coordinate rectangle containing the unrounded result.
|
||||
nsRect& ScaleRoundOut(float aScale) { return ScaleRoundOut(aScale, aScale); }
|
||||
nsRect& ScaleRoundOut(float aXScale, float aYScale);
|
||||
|
||||
// Extend the rect outwards such that the edges are on integer boundaries
|
||||
// Extend the rect outwards such that the edges are on integer boundaries
|
||||
// and the edges scaled by aXMult/aYMult are also on integer boundaries.
|
||||
// aXMult/aYMult must be N or 1/N for integer N.
|
||||
nsRect& ExtendForScaling(float aXMult, float aYMult);
|
||||
|
@ -196,169 +93,42 @@ struct NS_GFX nsRect {
|
|||
inline nsRect ConvertAppUnitsRoundOut(PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
inline nsRect ConvertAppUnitsRoundIn(PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
|
||||
// Helpers for accessing the vertices
|
||||
nsPoint TopLeft() const { return nsPoint(x, y); }
|
||||
nsPoint TopRight() const { return nsPoint(XMost(), y); }
|
||||
nsPoint BottomLeft() const { return nsPoint(x, YMost()); }
|
||||
nsPoint BottomRight() const { return nsPoint(XMost(), YMost()); }
|
||||
|
||||
nsSize Size() const { return nsSize(width, height); }
|
||||
|
||||
// Helper methods for computing the extents
|
||||
nscoord XMost() const {return x + width;}
|
||||
nscoord YMost() const {return y + height;}
|
||||
|
||||
inline nsIntRect ToNearestPixels(nscoord aAppUnitsPerPixel) const;
|
||||
inline nsIntRect ToOutsidePixels(nscoord aAppUnitsPerPixel) const;
|
||||
inline nsIntRect ToInsidePixels(nscoord aAppUnitsPerPixel) const;
|
||||
};
|
||||
|
||||
struct NS_GFX nsIntRect {
|
||||
PRInt32 x, y;
|
||||
PRInt32 width, height;
|
||||
struct NS_GFX nsIntRect :
|
||||
public mozilla::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> {
|
||||
typedef mozilla::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> Super;
|
||||
|
||||
// Constructors
|
||||
nsIntRect() : x(0), y(0), width(0), height(0) {}
|
||||
nsIntRect(const nsIntRect& aRect) {*this = aRect;}
|
||||
nsIntRect(const nsIntPoint& aOrigin, const nsIntSize &aSize) {
|
||||
x = aOrigin.x; y = aOrigin.y;
|
||||
width = aSize.width; height = aSize.height;
|
||||
}
|
||||
nsIntRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) {
|
||||
x = aX; y = aY; width = aWidth; height = aHeight;
|
||||
}
|
||||
|
||||
// Emptiness. An empty rect is one that has no area, i.e. its height or width
|
||||
// is <= 0
|
||||
PRBool IsEmpty() const {
|
||||
return (PRBool) ((height <= 0) || (width <= 0));
|
||||
}
|
||||
void Empty() {width = height = 0;}
|
||||
|
||||
// Inflate the rect by the specified width/height or margin
|
||||
void Inflate(PRInt32 aDx, PRInt32 aDy) {
|
||||
x -= aDx;
|
||||
y -= aDy;
|
||||
width += aDx*2;
|
||||
height += aDy*2;
|
||||
}
|
||||
void Inflate(const nsIntMargin &aMargin) {
|
||||
x -= aMargin.left;
|
||||
y -= aMargin.top;
|
||||
width += aMargin.left + aMargin.right;
|
||||
height += aMargin.top + aMargin.bottom;
|
||||
}
|
||||
|
||||
// Deflate the rect by the specified width/height or margin
|
||||
void Deflate(PRInt32 aDx, PRInt32 aDy) {
|
||||
x += aDx;
|
||||
y += aDy;
|
||||
width -= aDx*2;
|
||||
height -= aDy*2;
|
||||
}
|
||||
void Deflate(const nsIntMargin &aMargin) {
|
||||
x += aMargin.left;
|
||||
y += aMargin.top;
|
||||
width -= (aMargin.left + aMargin.right);
|
||||
height -= (aMargin.top + aMargin.bottom);
|
||||
}
|
||||
|
||||
// Overloaded operators. Note that '=' isn't defined so we'll get the
|
||||
// compiler generated default assignment operator.
|
||||
PRBool operator==(const nsIntRect& aRect) const {
|
||||
return IsEqualEdges(aRect);
|
||||
}
|
||||
|
||||
// Return true if the rectangles contain the same set of points, including
|
||||
// points on the edges.
|
||||
// Use when we care about the exact x/y/width/height values being
|
||||
// equal (i.e. we care about differences in empty rectangles).
|
||||
PRBool IsEqualEdges(const nsIntRect& aRect) const {
|
||||
return x == aRect.x && y == aRect.y &&
|
||||
width == aRect.width && height == aRect.height;
|
||||
}
|
||||
// Return true if the rectangles contain the same area of the plane.
|
||||
// Use when we do not care about differences in empty rectangles.
|
||||
PRBool IsEqualInterior(const nsIntRect& aRect) const {
|
||||
return IsEqualEdges(aRect) || (IsEmpty() && aRect.IsEmpty());
|
||||
}
|
||||
|
||||
nsIntRect operator+(const nsIntPoint& aPoint) const {
|
||||
return nsIntRect(x + aPoint.x, y + aPoint.y, width, height);
|
||||
}
|
||||
nsIntRect operator-(const nsIntPoint& aPoint) const {
|
||||
return nsIntRect(x - aPoint.x, y - aPoint.y, width, height);
|
||||
}
|
||||
nsIntRect& operator+=(const nsIntPoint& aPoint) {x += aPoint.x; y += aPoint.y; return *this;}
|
||||
nsIntRect& operator-=(const nsIntPoint& aPoint) {x -= aPoint.x; y -= aPoint.y; return *this;}
|
||||
|
||||
void SetRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) {
|
||||
x = aX; y = aY; width = aWidth; height = aHeight;
|
||||
}
|
||||
|
||||
void MoveTo(PRInt32 aX, PRInt32 aY) {x = aX; y = aY;}
|
||||
void MoveTo(const nsIntPoint& aPoint) {x = aPoint.x; y = aPoint.y;}
|
||||
void MoveBy(PRInt32 aDx, PRInt32 aDy) {x += aDx; y += aDy;}
|
||||
void MoveBy(const nsIntPoint& aPoint) {x += aPoint.x; y += aPoint.y;}
|
||||
void SizeTo(PRInt32 aWidth, PRInt32 aHeight) {width = aWidth; height = aHeight;}
|
||||
void SizeTo(const nsIntSize& aSize) {SizeTo(aSize.width, aSize.height);}
|
||||
void SizeBy(PRInt32 aDeltaWidth, PRInt32 aDeltaHeight) {width += aDeltaWidth;
|
||||
height += aDeltaHeight;}
|
||||
|
||||
PRBool Contains(const nsIntRect& aRect) const
|
||||
nsIntRect() : Super()
|
||||
{
|
||||
return aRect.IsEmpty() ||
|
||||
(PRBool) ((aRect.x >= x) && (aRect.y >= y) &&
|
||||
(aRect.XMost() <= XMost()) && (aRect.YMost() <= YMost()));
|
||||
}
|
||||
PRBool Contains(PRInt32 aX, PRInt32 aY) const
|
||||
nsIntRect(const nsIntRect& aRect) : Super(aRect)
|
||||
{
|
||||
return (PRBool) ((aX >= x) && (aY >= y) &&
|
||||
(aX < XMost()) && (aY < YMost()));
|
||||
}
|
||||
PRBool Contains(const nsIntPoint& aPoint) const { return Contains(aPoint.x, aPoint.y); }
|
||||
|
||||
// Intersection. Returns TRUE if the receiver overlaps aRect and
|
||||
// FALSE otherwise
|
||||
PRBool Intersects(const nsIntRect& aRect) const {
|
||||
return (PRBool) ((x < aRect.XMost()) && (y < aRect.YMost()) &&
|
||||
(aRect.x < XMost()) && (aRect.y < YMost()));
|
||||
nsIntRect(const nsIntPoint& aOrigin, const nsIntSize &aSize) : Super(aOrigin, aSize)
|
||||
{
|
||||
}
|
||||
nsIntRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) :
|
||||
Super(aX, aY, aWidth, aHeight)
|
||||
{
|
||||
}
|
||||
|
||||
// Computes the area in which aRect1 and aRect2 overlap, and fills 'this' with
|
||||
// the result. Returns FALSE if the rectangles don't intersect, and sets 'this'
|
||||
// rect to be an empty rect.
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
PRBool IntersectRect(const nsIntRect& aRect1, const nsIntRect& aRect2);
|
||||
|
||||
// Computes the smallest rectangle that contains both aRect1 and aRect2 and
|
||||
// fills 'this' with the result. Returns FALSE and sets 'this' rect to be an
|
||||
// empty rect if both aRect1 and aRect2 are empty
|
||||
//
|
||||
// 'this' can be the same object as either aRect1 or aRect2
|
||||
PRBool UnionRect(const nsIntRect& aRect1, const nsIntRect& aRect2);
|
||||
|
||||
// Helpers for accessing the vertices
|
||||
nsIntPoint TopLeft() const { return nsIntPoint(x, y); }
|
||||
nsIntPoint TopRight() const { return nsIntPoint(XMost(), y); }
|
||||
nsIntPoint BottomLeft() const { return nsIntPoint(x, YMost()); }
|
||||
nsIntPoint BottomRight() const { return nsIntPoint(XMost(), YMost()); }
|
||||
|
||||
nsIntSize Size() const { return nsIntSize(width, height); }
|
||||
|
||||
// Helper methods for computing the extents
|
||||
PRInt32 XMost() const {return x + width;}
|
||||
PRInt32 YMost() const {return y + height;}
|
||||
|
||||
inline nsRect ToAppUnits(nscoord aAppUnitsPerPixel) const;
|
||||
|
||||
nsIntRect& ScaleRoundOut(float aXScale, float aYScale);
|
||||
|
||||
// Returns a special nsIntRect that's used in some places to signify
|
||||
// "all available space".
|
||||
static const nsIntRect& GetMaxSizedIntRect() { return kMaxSizedIntRect; }
|
||||
|
||||
// This is here only to keep IPDL-generated code happy. DO NOT USE.
|
||||
bool operator==(const nsIntRect& aRect) const
|
||||
{
|
||||
return IsEqualEdges(aRect);
|
||||
}
|
||||
|
||||
protected:
|
||||
static const nsIntRect kMaxSizedIntRect;
|
||||
};
|
||||
|
|
|
@ -39,54 +39,6 @@
|
|||
|
||||
#include "nsMathUtils.h"
|
||||
|
||||
gfxRect
|
||||
gfxRect::Intersect(const gfxRect& aRect) const
|
||||
{
|
||||
gfxRect result(0,0,0,0);
|
||||
|
||||
gfxFloat x = PR_MAX(aRect.X(), X());
|
||||
gfxFloat xmost = PR_MIN(aRect.XMost(), XMost());
|
||||
if (x >= xmost)
|
||||
return result;
|
||||
|
||||
gfxFloat y = PR_MAX(aRect.Y(), Y());
|
||||
gfxFloat ymost = PR_MIN(aRect.YMost(), YMost());
|
||||
if (y >= ymost)
|
||||
return result;
|
||||
|
||||
result = gfxRect(x, y, xmost - x, ymost - y);
|
||||
return result;
|
||||
}
|
||||
|
||||
gfxRect
|
||||
gfxRect::Union(const gfxRect& aRect) const
|
||||
{
|
||||
if (IsEmpty())
|
||||
return aRect;
|
||||
if (aRect.IsEmpty())
|
||||
return *this;
|
||||
|
||||
gfxFloat x = PR_MIN(aRect.X(), X());
|
||||
gfxFloat xmost = PR_MAX(aRect.XMost(), XMost());
|
||||
gfxFloat y = PR_MIN(aRect.Y(), Y());
|
||||
gfxFloat ymost = PR_MAX(aRect.YMost(), YMost());
|
||||
return gfxRect(x, y, xmost - x, ymost - y);
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxRect::Contains(const gfxRect& aRect) const
|
||||
{
|
||||
return aRect.X() >= X() && aRect.XMost() <= XMost() &&
|
||||
aRect.Y() >= Y() && aRect.YMost() <= YMost();
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxRect::Contains(const gfxPoint& aPoint) const
|
||||
{
|
||||
return aPoint.x >= X() && aPoint.x <= XMost() &&
|
||||
aPoint.y >= Y() && aPoint.y <= YMost();
|
||||
}
|
||||
|
||||
static PRBool
|
||||
WithinEpsilonOfInteger(gfxFloat aX, gfxFloat aEpsilon)
|
||||
{
|
||||
|
|
|
@ -41,7 +41,19 @@
|
|||
#include "gfxTypes.h"
|
||||
#include "gfxPoint.h"
|
||||
#include "gfxCore.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsDebug.h"
|
||||
#include "mozilla/BaseMargin.h"
|
||||
#include "mozilla/BaseRect.h"
|
||||
|
||||
struct gfxMargin : public mozilla::BaseMargin<gfxFloat, gfxMargin> {
|
||||
typedef mozilla::BaseMargin<gfxFloat, gfxMargin> Super;
|
||||
|
||||
// Constructors
|
||||
gfxMargin() : Super() {}
|
||||
gfxMargin(const gfxMargin& aMargin) : Super(aMargin) {}
|
||||
gfxMargin(gfxFloat aLeft, gfxFloat aTop, gfxFloat aRight, gfxFloat aBottom)
|
||||
: Super(aLeft, aTop, aRight, aBottom) {}
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
@ -73,77 +85,15 @@ static inline mozilla::css::Corner operator++(mozilla::css::Corner& corner, int)
|
|||
return corner;
|
||||
}
|
||||
|
||||
struct THEBES_API gfxRect
|
||||
{
|
||||
gfxFloat x, y;
|
||||
gfxFloat width, height;
|
||||
struct THEBES_API gfxRect :
|
||||
public mozilla::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> {
|
||||
typedef mozilla::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super;
|
||||
|
||||
gfxRect() {}
|
||||
gfxRect(const gfxPoint& _pos, const gfxSize& _size) :
|
||||
x(_pos.x), y(_pos.y), width(_size.width), height(_size.height) {}
|
||||
gfxRect(gfxFloat _x, gfxFloat _y, gfxFloat _width, gfxFloat _height) :
|
||||
x(_x), y(_y), width(_width), height(_height) {}
|
||||
|
||||
int operator==(const gfxRect& s) const {
|
||||
return x == s.x && y == s.y && width == s.width && height == s.height;
|
||||
}
|
||||
PRBool IsEqualEdges(const gfxRect& aRect) const {
|
||||
return x == aRect.x && y == aRect.y &&
|
||||
width == aRect.width && height == aRect.height;
|
||||
}
|
||||
// Return true if the rectangles contain the same area of the plane.
|
||||
// Use when we do not care about differences in empty rectangles.
|
||||
PRBool IsEqualInterior(const gfxRect& aRect) const {
|
||||
return IsEqualEdges(aRect) || (IsEmpty() && aRect.IsEmpty());
|
||||
}
|
||||
|
||||
void MoveTo(const gfxPoint& aPt) { x = aPt.x; y = aPt.y; }
|
||||
const gfxRect& MoveBy(const gfxPoint& aPt) {
|
||||
x += aPt.x;
|
||||
y += aPt.y;
|
||||
return *this;
|
||||
}
|
||||
void SizeTo(const gfxSize& aSize) { width = aSize.width; height = aSize.height; }
|
||||
|
||||
gfxRect operator+(const gfxPoint& aPt) const {
|
||||
return gfxRect(x + aPt.x, y + aPt.y, width, height);
|
||||
}
|
||||
gfxRect operator-(const gfxPoint& aPt) const {
|
||||
return gfxRect(x - aPt.x, y - aPt.y, width, height);
|
||||
}
|
||||
gfxRect operator+(const gfxSize& aSize) const {
|
||||
return gfxRect(x + aSize.width, y + aSize.height, width, height);
|
||||
}
|
||||
gfxRect operator-(const gfxSize& aSize) const {
|
||||
return gfxRect(x - aSize.width, y - aSize.height, width, height);
|
||||
}
|
||||
gfxRect operator*(const gfxFloat aScale) const {
|
||||
return gfxRect(x * aScale, y * aScale, width * aScale, height * aScale);
|
||||
}
|
||||
|
||||
const gfxRect& operator+=(const gfxPoint& aPt) {
|
||||
x += aPt.x;
|
||||
y += aPt.y;
|
||||
return *this;
|
||||
}
|
||||
const gfxRect& operator-=(const gfxPoint& aPt) {
|
||||
x -= aPt.x;
|
||||
y -= aPt.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
gfxFloat Width() const { return width; }
|
||||
gfxFloat Height() const { return height; }
|
||||
gfxFloat X() const { return x; }
|
||||
gfxFloat Y() const { return y; }
|
||||
gfxFloat XMost() const { return x + width; }
|
||||
gfxFloat YMost() const { return y + height; }
|
||||
|
||||
PRBool IsEmpty() const { return width <= 0 || height <= 0; }
|
||||
gfxRect Intersect(const gfxRect& aRect) const;
|
||||
gfxRect Union(const gfxRect& aRect) const;
|
||||
PRBool Contains(const gfxRect& aRect) const;
|
||||
PRBool Contains(const gfxPoint& aPoint) const;
|
||||
gfxRect() : Super() {}
|
||||
gfxRect(const gfxPoint& aPos, const gfxSize& aSize) :
|
||||
Super(aPos, aSize) {}
|
||||
gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) :
|
||||
Super(aX, aY, aWidth, aHeight) {}
|
||||
|
||||
/**
|
||||
* Return true if all components of this rect are within
|
||||
|
@ -153,20 +103,12 @@ struct THEBES_API gfxRect
|
|||
*/
|
||||
PRBool WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const;
|
||||
|
||||
gfxSize Size() const { return gfxSize(width, height); }
|
||||
|
||||
void Inset(gfxFloat k) {
|
||||
x += k;
|
||||
y += k;
|
||||
width = PR_MAX(0.0, width - k * 2.0);
|
||||
height = PR_MAX(0.0, height - k * 2.0);
|
||||
Deflate(k, k);
|
||||
}
|
||||
|
||||
void Inset(gfxFloat top, gfxFloat right, gfxFloat bottom, gfxFloat left) {
|
||||
x += left;
|
||||
y += top;
|
||||
width = PR_MAX(0.0, width - (right+left));
|
||||
height = PR_MAX(0.0, height - (bottom+top));
|
||||
Deflate(gfxMargin(left, top, right, bottom));
|
||||
}
|
||||
|
||||
void Inset(const gfxFloat *sides) {
|
||||
|
@ -174,25 +116,15 @@ struct THEBES_API gfxRect
|
|||
}
|
||||
|
||||
void Inset(const gfxIntSize& aSize) {
|
||||
Inset(aSize.height, aSize.width, aSize.height, aSize.width);
|
||||
Deflate(aSize.width, aSize.height);
|
||||
}
|
||||
|
||||
void Outset(gfxFloat k) {
|
||||
x -= k;
|
||||
y -= k;
|
||||
width = PR_MAX(0.0, width + k * 2.0);
|
||||
height = PR_MAX(0.0, height + k * 2.0);
|
||||
Inflate(k, k);
|
||||
}
|
||||
|
||||
void Outset(gfxFloat top, gfxFloat right, gfxFloat bottom, gfxFloat left) {
|
||||
x -= left;
|
||||
y -= top;
|
||||
width = PR_MAX(0.0, width + (right+left));
|
||||
height = PR_MAX(0.0, height + (bottom+top));
|
||||
}
|
||||
|
||||
void Outset(const gfxFloat *sides) {
|
||||
Outset(sides[0], sides[1], sides[2], sides[3]);
|
||||
Inflate(gfxMargin(left, top, right, bottom));
|
||||
}
|
||||
|
||||
void Outset(const gfxIntSize& aSize) {
|
||||
|
@ -220,13 +152,6 @@ struct THEBES_API gfxRect
|
|||
// resulting rectangle contains the original rectangle.
|
||||
void RoundOut();
|
||||
|
||||
// grabbing specific points
|
||||
gfxPoint TopLeft() const { return gfxPoint(x, y); }
|
||||
gfxPoint TopRight() const { return gfxPoint(x, y) + gfxPoint(width, 0.0); }
|
||||
gfxPoint BottomLeft() const { return gfxPoint(x, y) + gfxPoint(0.0, height); }
|
||||
gfxPoint BottomRight() const { return gfxPoint(x, y) + gfxPoint(width, height); }
|
||||
gfxPoint Center() const { return gfxPoint(x, y) + gfxPoint(width, height)/2.0; }
|
||||
|
||||
gfxPoint AtCorner(mozilla::css::Corner corner) const {
|
||||
switch (corner) {
|
||||
case NS_CORNER_TOP_LEFT: return TopLeft();
|
||||
|
|
|
@ -1009,10 +1009,8 @@ nsRect
|
|||
nsLayoutUtils::RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor)
|
||||
{
|
||||
/* Get a new gfxRect whose units are app units by scaling by the specified factor. */
|
||||
gfxRect scaledRect = aRect * aFactor;
|
||||
|
||||
/* Round outward. */
|
||||
scaledRect.RoundOut();
|
||||
gfxRect scaledRect = aRect;
|
||||
scaledRect.ScaleRoundOut(aFactor);
|
||||
|
||||
/* We now need to constrain our results to the max and min values for coords. */
|
||||
ConstrainToCoordValues(scaledRect.x);
|
||||
|
|
|
@ -1746,7 +1746,7 @@ nsObjectFrame::PrintPlugin(nsRenderingContext& aRenderingContext,
|
|||
window.clipRect.bottom = window.height;
|
||||
window.type = NPWindowTypeDrawable;
|
||||
|
||||
Rect gwBounds;
|
||||
::Rect gwBounds;
|
||||
::SetRect(&gwBounds, 0, 0, window.width, window.height);
|
||||
|
||||
nsTArray<char> buffer(window.width * window.height * 4);
|
||||
|
|
|
@ -1356,7 +1356,7 @@ nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect,
|
|||
}
|
||||
|
||||
// keep a 3 pixel margin to the right and bottom of the screen for the WinXP dropshadow
|
||||
screenRectPixels.SizeBy(-3, -3);
|
||||
screenRectPixels.SizeTo(screenRectPixels.width - 3, screenRectPixels.height - 3);
|
||||
|
||||
nsRect screenRect = screenRectPixels.ToAppUnits(presContext->AppUnitsPerDevPixel());
|
||||
if (mInContentShell) {
|
||||
|
|
|
@ -112,9 +112,9 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
nsRect rect = frameToResize->GetScreenRectInAppUnits();
|
||||
switch (frameToResize->GetStylePosition()->mBoxSizing) {
|
||||
case NS_STYLE_BOX_SIZING_CONTENT:
|
||||
rect -= frameToResize->GetUsedPadding();
|
||||
rect.Deflate(frameToResize->GetUsedPadding());
|
||||
case NS_STYLE_BOX_SIZING_PADDING:
|
||||
rect -= frameToResize->GetUsedBorder();
|
||||
rect.Deflate(frameToResize->GetUsedBorder());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче