744 lines
14 KiB
C++
744 lines
14 KiB
C++
/***************************************************************************\
|
|
*
|
|
* File: Geom2D.h
|
|
*
|
|
* Description:
|
|
* Geom2D defines a standard lightweight objects for 2D space, including
|
|
* size, point, and rect.
|
|
*
|
|
*
|
|
* History:
|
|
* 2/10/2001: JStall: Copied from \windows\AdvCore\Gdiplus\sdkinc\GdiplusTypes.h
|
|
*
|
|
* Copyright (C) 2001 by Microsoft Corporation. All rights reserved.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
|
|
#if !defined(DUSERX___Types_h__INCLUDED)
|
|
#define DUSERX___Types_h__INCLUDED
|
|
#pragma once
|
|
|
|
namespace DirectUser
|
|
{
|
|
namespace Geometry
|
|
{
|
|
typedef float REAL;
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Primitive data types
|
|
//
|
|
// NOTE:
|
|
// Types already defined in standard header files:
|
|
// INT8
|
|
// UINT8
|
|
// INT16
|
|
// UINT16
|
|
// INT32
|
|
// UINT32
|
|
// INT64
|
|
// UINT64
|
|
//
|
|
// Avoid using the following types:
|
|
// LONG - use INT
|
|
// ULONG - use UINT
|
|
// DWORD - use UINT32
|
|
//--------------------------------------------------------------------------
|
|
|
|
// Forward declarations
|
|
class Size;
|
|
class SizeF;
|
|
class Point;
|
|
class PointF;
|
|
class Rect;
|
|
class RectF;
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Represents a dimension in a 2D coordinate system
|
|
// (floating-point coordinates)
|
|
//--------------------------------------------------------------------------
|
|
|
|
class SizeF
|
|
{
|
|
public:
|
|
|
|
// Default constructor
|
|
SizeF()
|
|
{
|
|
|
|
}
|
|
|
|
SizeF(bool fInit)
|
|
{
|
|
if (fInit) {
|
|
Width = Height = 0.0f;
|
|
}
|
|
}
|
|
|
|
SizeF(IN const SizeF& size)
|
|
{
|
|
Width = size.Width;
|
|
Height = size.Height;
|
|
}
|
|
|
|
SizeF(IN REAL width,
|
|
IN REAL height)
|
|
{
|
|
Width = width;
|
|
Height = height;
|
|
}
|
|
|
|
SizeF operator+(IN const SizeF& sz) const
|
|
{
|
|
return SizeF(Width + sz.Width,
|
|
Height + sz.Height);
|
|
}
|
|
|
|
SizeF operator-(IN const SizeF& sz) const
|
|
{
|
|
return SizeF(Width - sz.Width,
|
|
Height - sz.Height);
|
|
}
|
|
|
|
BOOL Equals(IN const SizeF& sz) const
|
|
{
|
|
return (Width == sz.Width) && (Height == sz.Height);
|
|
}
|
|
|
|
BOOL Empty() const
|
|
{
|
|
return (Width == 0.0f && Height == 0.0f);
|
|
}
|
|
|
|
public:
|
|
|
|
REAL Width;
|
|
REAL Height;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Represents a dimension in a 2D coordinate system
|
|
// (integer coordinates)
|
|
//--------------------------------------------------------------------------
|
|
|
|
class Size
|
|
{
|
|
public:
|
|
|
|
// Default constructor
|
|
Size()
|
|
{
|
|
|
|
}
|
|
|
|
Size(bool fInit)
|
|
{
|
|
if (fInit) {
|
|
Width = Height = 0;
|
|
}
|
|
}
|
|
|
|
Size(IN const Size& size)
|
|
{
|
|
Width = size.Width;
|
|
Height = size.Height;
|
|
}
|
|
|
|
Size(IN INT width,
|
|
IN INT height)
|
|
{
|
|
Width = width;
|
|
Height = height;
|
|
}
|
|
|
|
Size operator+(IN const Size& sz) const
|
|
{
|
|
return Size(Width + sz.Width,
|
|
Height + sz.Height);
|
|
}
|
|
|
|
Size operator-(IN const Size& sz) const
|
|
{
|
|
return Size(Width - sz.Width,
|
|
Height - sz.Height);
|
|
}
|
|
|
|
BOOL Equals(IN const Size& sz) const
|
|
{
|
|
return (Width == sz.Width) && (Height == sz.Height);
|
|
}
|
|
|
|
BOOL Empty() const
|
|
{
|
|
return (Width == 0 && Height == 0);
|
|
}
|
|
|
|
public:
|
|
|
|
INT Width;
|
|
INT Height;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Represents a location in a 2D coordinate system
|
|
// (floating-point coordinates)
|
|
//--------------------------------------------------------------------------
|
|
|
|
class PointF
|
|
{
|
|
public:
|
|
PointF()
|
|
{
|
|
|
|
}
|
|
|
|
PointF(bool fInit)
|
|
{
|
|
if (fInit) {
|
|
X = Y = 0.0f;
|
|
}
|
|
}
|
|
|
|
PointF(IN const PointF &point)
|
|
{
|
|
X = point.X;
|
|
Y = point.Y;
|
|
}
|
|
|
|
PointF(IN const SizeF &size)
|
|
{
|
|
X = size.Width;
|
|
Y = size.Height;
|
|
}
|
|
|
|
PointF(IN REAL x,
|
|
IN REAL y)
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
}
|
|
|
|
PointF operator+(IN const PointF& point) const
|
|
{
|
|
return PointF(X + point.X,
|
|
Y + point.Y);
|
|
}
|
|
|
|
PointF operator-(IN const PointF& point) const
|
|
{
|
|
return PointF(X - point.X,
|
|
Y - point.Y);
|
|
}
|
|
|
|
BOOL Equals(IN const PointF& point)
|
|
{
|
|
return (X == point.X) && (Y == point.Y);
|
|
}
|
|
|
|
public:
|
|
|
|
REAL X;
|
|
REAL Y;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Represents a location in a 2D coordinate system
|
|
// (integer coordinates)
|
|
//--------------------------------------------------------------------------
|
|
|
|
class Point
|
|
{
|
|
public:
|
|
Point()
|
|
{
|
|
|
|
}
|
|
|
|
Point(bool fInit)
|
|
{
|
|
if (fInit) {
|
|
X = Y = 0;
|
|
}
|
|
}
|
|
|
|
Point(IN const Point &point)
|
|
{
|
|
X = point.X;
|
|
Y = point.Y;
|
|
}
|
|
|
|
Point(IN const Size &size)
|
|
{
|
|
X = size.Width;
|
|
Y = size.Height;
|
|
}
|
|
|
|
Point(IN INT x,
|
|
IN INT y)
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
}
|
|
|
|
Point operator+(IN const Point& point) const
|
|
{
|
|
return Point(X + point.X,
|
|
Y + point.Y);
|
|
}
|
|
|
|
Point operator-(IN const Point& point) const
|
|
{
|
|
return Point(X - point.X,
|
|
Y - point.Y);
|
|
}
|
|
|
|
BOOL Equals(IN const Point& point)
|
|
{
|
|
return (X == point.X) && (Y == point.Y);
|
|
}
|
|
|
|
public:
|
|
|
|
INT X;
|
|
INT Y;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Represents a rectangle in a 2D coordinate system
|
|
// (floating-point coordinates)
|
|
//--------------------------------------------------------------------------
|
|
|
|
class RectF
|
|
{
|
|
public:
|
|
|
|
// Default constructor
|
|
|
|
RectF()
|
|
{
|
|
|
|
}
|
|
|
|
RectF(bool fInit)
|
|
{
|
|
if (fInit) {
|
|
X = Y = Width = Height = 0.0f;
|
|
}
|
|
}
|
|
|
|
RectF(IN REAL x,
|
|
IN REAL y,
|
|
IN REAL width,
|
|
IN REAL height)
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
Width = width;
|
|
Height = height;
|
|
}
|
|
|
|
RectF(IN const PointF& location,
|
|
IN const SizeF& size)
|
|
{
|
|
X = location.X;
|
|
Y = location.Y;
|
|
Width = size.Width;
|
|
Height = size.Height;
|
|
}
|
|
|
|
RectF* Clone() const
|
|
{
|
|
return new RectF(X, Y, Width, Height);
|
|
}
|
|
|
|
VOID GetLocation(OUT PointF* point) const
|
|
{
|
|
point->X = X;
|
|
point->Y = Y;
|
|
}
|
|
|
|
VOID GetSize(OUT SizeF* size) const
|
|
{
|
|
size->Width = Width;
|
|
size->Height = Height;
|
|
}
|
|
|
|
VOID GetBounds(OUT RectF* rect) const
|
|
{
|
|
rect->X = X;
|
|
rect->Y = Y;
|
|
rect->Width = Width;
|
|
rect->Height = Height;
|
|
}
|
|
|
|
// Return the left, top, right, and bottom
|
|
// coordinates of the rectangle
|
|
|
|
REAL GetLeft() const
|
|
{
|
|
return X;
|
|
}
|
|
|
|
void SetLeft(REAL x)
|
|
{
|
|
X = x;
|
|
}
|
|
|
|
REAL GetTop() const
|
|
{
|
|
return Y;
|
|
}
|
|
|
|
void SetTop(REAL y)
|
|
{
|
|
Y = y;
|
|
}
|
|
|
|
REAL GetRight() const
|
|
{
|
|
return X+Width;
|
|
}
|
|
|
|
REAL GetBottom() const
|
|
{
|
|
return Y+Height;
|
|
}
|
|
|
|
// Determine if the rectangle is empty
|
|
BOOL IsEmptyArea() const
|
|
{
|
|
REAL epsilon = 1.192092896e-07F; /* FLT_EPSILON */
|
|
|
|
return (Width <= epsilon) || (Height <= epsilon);
|
|
}
|
|
|
|
BOOL Equals(IN const RectF & rect) const
|
|
{
|
|
return X == rect.X &&
|
|
Y == rect.Y &&
|
|
Width == rect.Width &&
|
|
Height == rect.Height;
|
|
}
|
|
|
|
BOOL Contains(IN REAL x,
|
|
IN REAL y) const
|
|
{
|
|
return x >= X && x < X+Width &&
|
|
y >= Y && y < Y+Height;
|
|
}
|
|
|
|
BOOL Contains(IN const PointF& pt) const
|
|
{
|
|
return Contains(pt.X, pt.Y);
|
|
}
|
|
|
|
BOOL Contains(IN const RectF& rect) const
|
|
{
|
|
return (X <= rect.X) && (rect.GetRight() <= GetRight()) &&
|
|
(Y <= rect.Y) && (rect.GetBottom() <= GetBottom());
|
|
}
|
|
|
|
VOID Inflate(IN REAL dx,
|
|
IN REAL dy)
|
|
{
|
|
X -= dx;
|
|
Y -= dy;
|
|
Width += 2*dx;
|
|
Height += 2*dy;
|
|
}
|
|
|
|
VOID Inflate(IN const PointF& point)
|
|
{
|
|
Inflate(point.X, point.Y);
|
|
}
|
|
|
|
// Intersect the current rect with the specified object
|
|
|
|
BOOL Intersect(IN const RectF& rect)
|
|
{
|
|
return Intersect(*this, *this, rect);
|
|
}
|
|
|
|
// Intersect rect a and b and save the result into c
|
|
// Notice that c may be the same object as a or b.
|
|
|
|
static BOOL Intersect(OUT RectF& c,
|
|
IN const RectF& a,
|
|
IN const RectF& b)
|
|
{
|
|
REAL right = min(a.GetRight(), b.GetRight());
|
|
REAL bottom = min(a.GetBottom(), b.GetBottom());
|
|
REAL left = max(a.GetLeft(), b.GetLeft());
|
|
REAL top = max(a.GetTop(), b.GetTop());
|
|
|
|
c.X = left;
|
|
c.Y = top;
|
|
c.Width = right - left;
|
|
c.Height = bottom - top;
|
|
return !c.IsEmptyArea();
|
|
}
|
|
|
|
// Determine if the specified rect intersects with the
|
|
// current rect object.
|
|
|
|
BOOL IntersectsWith(IN const RectF& rect) const
|
|
{
|
|
return (GetLeft() < rect.GetRight() &&
|
|
GetTop() < rect.GetBottom() &&
|
|
GetRight() > rect.GetLeft() &&
|
|
GetBottom() > rect.GetTop());
|
|
}
|
|
|
|
static BOOL Union(OUT RectF& c,
|
|
IN const RectF& a,
|
|
IN const RectF& b)
|
|
{
|
|
REAL right = max(a.GetRight(), b.GetRight());
|
|
REAL bottom = max(a.GetBottom(), b.GetBottom());
|
|
REAL left = min(a.GetLeft(), b.GetLeft());
|
|
REAL top = min(a.GetTop(), b.GetTop());
|
|
|
|
c.X = left;
|
|
c.Y = top;
|
|
c.Width = right - left;
|
|
c.Height = bottom - top;
|
|
return !c.IsEmptyArea();
|
|
}
|
|
|
|
VOID Offset(IN const PointF& point)
|
|
{
|
|
Offset(point.X, point.Y);
|
|
}
|
|
|
|
VOID Offset(IN REAL dx,
|
|
IN REAL dy)
|
|
{
|
|
X += dx;
|
|
Y += dy;
|
|
}
|
|
|
|
public:
|
|
|
|
REAL X;
|
|
REAL Y;
|
|
REAL Width;
|
|
REAL Height;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Represents a rectangle in a 2D coordinate system
|
|
// (integer coordinates)
|
|
//--------------------------------------------------------------------------
|
|
|
|
class Rect
|
|
{
|
|
public:
|
|
|
|
// Default constructor
|
|
|
|
Rect()
|
|
{
|
|
|
|
}
|
|
|
|
Rect(bool fInit)
|
|
{
|
|
if (fInit) {
|
|
X = Y = Width = Height = 0;
|
|
}
|
|
}
|
|
|
|
Rect(IN INT x,
|
|
IN INT y,
|
|
IN INT width,
|
|
IN INT height)
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
Width = width;
|
|
Height = height;
|
|
}
|
|
|
|
Rect(IN const Point& location,
|
|
IN const Size& size)
|
|
{
|
|
X = location.X;
|
|
Y = location.Y;
|
|
Width = size.Width;
|
|
Height = size.Height;
|
|
}
|
|
|
|
Rect* Clone() const
|
|
{
|
|
return new Rect(X, Y, Width, Height);
|
|
}
|
|
|
|
VOID GetLocation(OUT Point* point) const
|
|
{
|
|
point->X = X;
|
|
point->Y = Y;
|
|
}
|
|
|
|
VOID GetSize(OUT Size* size) const
|
|
{
|
|
size->Width = Width;
|
|
size->Height = Height;
|
|
}
|
|
|
|
VOID GetBounds(OUT Rect* rect) const
|
|
{
|
|
rect->X = X;
|
|
rect->Y = Y;
|
|
rect->Width = Width;
|
|
rect->Height = Height;
|
|
}
|
|
|
|
// Return the left, top, right, and bottom
|
|
// coordinates of the rectangle
|
|
|
|
INT GetLeft() const
|
|
{
|
|
return X;
|
|
}
|
|
|
|
INT GetTop() const
|
|
{
|
|
return Y;
|
|
}
|
|
|
|
INT GetRight() const
|
|
{
|
|
return X+Width;
|
|
}
|
|
|
|
INT GetBottom() const
|
|
{
|
|
return Y+Height;
|
|
}
|
|
|
|
// Determine if the rectangle is empty
|
|
BOOL IsEmptyArea() const
|
|
{
|
|
return (Width <= 0) || (Height <= 0);
|
|
}
|
|
|
|
BOOL Equals(IN const Rect & rect) const
|
|
{
|
|
return X == rect.X &&
|
|
Y == rect.Y &&
|
|
Width == rect.Width &&
|
|
Height == rect.Height;
|
|
}
|
|
|
|
BOOL Contains(IN INT x,
|
|
IN INT y) const
|
|
{
|
|
return x >= X && x < X+Width &&
|
|
y >= Y && y < Y+Height;
|
|
}
|
|
|
|
BOOL Contains(IN const Point& pt) const
|
|
{
|
|
return Contains(pt.X, pt.Y);
|
|
}
|
|
|
|
BOOL Contains(IN Rect& rect) const
|
|
{
|
|
return (X <= rect.X) && (rect.GetRight() <= GetRight()) &&
|
|
(Y <= rect.Y) && (rect.GetBottom() <= GetBottom());
|
|
}
|
|
|
|
VOID Inflate(IN INT dx,
|
|
IN INT dy)
|
|
{
|
|
X -= dx;
|
|
Y -= dy;
|
|
Width += 2*dx;
|
|
Height += 2*dy;
|
|
}
|
|
|
|
VOID Inflate(IN const Point& point)
|
|
{
|
|
Inflate(point.X, point.Y);
|
|
}
|
|
|
|
// Intersect the current rect with the specified object
|
|
|
|
BOOL Intersect(IN const Rect& rect)
|
|
{
|
|
return Intersect(*this, *this, rect);
|
|
}
|
|
|
|
// Intersect rect a and b and save the result into c
|
|
// Notice that c may be the same object as a or b.
|
|
|
|
static BOOL Intersect(OUT Rect& c,
|
|
IN const Rect& a,
|
|
IN const Rect& b)
|
|
{
|
|
INT right = min(a.GetRight(), b.GetRight());
|
|
INT bottom = min(a.GetBottom(), b.GetBottom());
|
|
INT left = max(a.GetLeft(), b.GetLeft());
|
|
INT top = max(a.GetTop(), b.GetTop());
|
|
|
|
c.X = left;
|
|
c.Y = top;
|
|
c.Width = right - left;
|
|
c.Height = bottom - top;
|
|
return !c.IsEmptyArea();
|
|
}
|
|
|
|
// Determine if the specified rect intersects with the
|
|
// current rect object.
|
|
|
|
BOOL IntersectsWith(IN const Rect& rect) const
|
|
{
|
|
return (GetLeft() < rect.GetRight() &&
|
|
GetTop() < rect.GetBottom() &&
|
|
GetRight() > rect.GetLeft() &&
|
|
GetBottom() > rect.GetTop());
|
|
}
|
|
|
|
static BOOL Union(OUT Rect& c,
|
|
IN const Rect& a,
|
|
IN const Rect& b)
|
|
{
|
|
INT right = max(a.GetRight(), b.GetRight());
|
|
INT bottom = max(a.GetBottom(), b.GetBottom());
|
|
INT left = min(a.GetLeft(), b.GetLeft());
|
|
INT top = min(a.GetTop(), b.GetTop());
|
|
|
|
c.X = left;
|
|
c.Y = top;
|
|
c.Width = right - left;
|
|
c.Height = bottom - top;
|
|
return !c.IsEmptyArea();
|
|
}
|
|
|
|
VOID Offset(IN const Point& point)
|
|
{
|
|
Offset(point.X, point.Y);
|
|
}
|
|
|
|
VOID Offset(IN INT dx,
|
|
IN INT dy)
|
|
{
|
|
X += dx;
|
|
Y += dy;
|
|
}
|
|
|
|
public:
|
|
|
|
INT X;
|
|
INT Y;
|
|
INT Width;
|
|
INT Height;
|
|
};
|
|
|
|
} // namespace Geometry
|
|
} // namespace DirectUser
|
|
|
|
#endif // DUSERX___Types_h__INCLUDED
|