You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
8.3 KiB
311 lines
8.3 KiB
/**************************************************************************\
|
|
*
|
|
* Copyright (c) 1999 Microsoft Corporation
|
|
*
|
|
* Module Name:
|
|
*
|
|
* Region.hpp
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Region API related declarations
|
|
*
|
|
* Created:
|
|
*
|
|
* 2/3/1999 DCurtis
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifndef _REGION_HPP
|
|
#define _REGION_HPP
|
|
|
|
// Specifies that a RegionData node is a leaf node, rather than a node that
|
|
// combines 2 children nodes.
|
|
#define REGIONTYPE_LEAF 0x10000000
|
|
|
|
// A RegionData node can be empty or infinite or it can contain a rect,
|
|
// a path, or two children nodes (left and right) that are combined with a
|
|
// boolean operator. Children nodes are specified by their index into the
|
|
// dynamic array called CombineData of GpRegion.
|
|
struct RegionData
|
|
{
|
|
friend class GpRegion;
|
|
|
|
public:
|
|
enum NodeType
|
|
{
|
|
TypeAnd = CombineModeIntersect,
|
|
TypeOr = CombineModeUnion,
|
|
TypeXor = CombineModeXor,
|
|
TypeExclude = CombineModeExclude,
|
|
TypeComplement = CombineModeComplement,
|
|
TypeRect = REGIONTYPE_LEAF | 0,
|
|
TypePath = REGIONTYPE_LEAF | 1,
|
|
TypeEmpty = REGIONTYPE_LEAF | 2,
|
|
TypeInfinite = REGIONTYPE_LEAF | 3,
|
|
TypeNotValid = 0xFFFFFFFF,
|
|
};
|
|
|
|
protected:
|
|
NodeType Type;
|
|
|
|
union
|
|
{
|
|
struct // rect data (can't be GpRectF cause of constructor)
|
|
{
|
|
REAL X;
|
|
REAL Y;
|
|
REAL Width;
|
|
REAL Height;
|
|
};
|
|
struct
|
|
{
|
|
GpPath * Path; // copy of path
|
|
BOOL Lazy; // if the path is a lazy copy or not
|
|
};
|
|
struct
|
|
{
|
|
INT Left; // index of left child
|
|
INT Right; // index of right child
|
|
};
|
|
};
|
|
};
|
|
|
|
typedef DynArray<RegionData> DynRegionDataArray;
|
|
|
|
class GpRegion : public GpObject, public RegionData
|
|
{
|
|
friend class GpGraphics;
|
|
protected:
|
|
mutable GpLockable Lockable;
|
|
mutable BOOL RegionOk; // if DeviceRegion is valid
|
|
mutable DpRegion DeviceRegion; // region coverage, in device units
|
|
mutable GpMatrix Matrix; // last matrix used for DeviceRegion
|
|
|
|
DynRegionDataArray CombineData; // combined region data, if any
|
|
|
|
protected:
|
|
VOID SetValid(BOOL valid)
|
|
{
|
|
GpObject::SetValid(valid ? ObjectTagRegion : ObjectTagInvalid);
|
|
}
|
|
|
|
protected:
|
|
// doesn't change the region itself, just the device region
|
|
GpStatus
|
|
UpdateDeviceRegion(
|
|
GpMatrix * matrix
|
|
) const;
|
|
|
|
// doesn't change the region itself, just the device region
|
|
GpStatus
|
|
CreateLeafDeviceRegion(
|
|
const RegionData * regionData,
|
|
DpRegion * region
|
|
) const;
|
|
|
|
// doesn't change the region itself, just the device region
|
|
GpStatus
|
|
CreateDeviceRegion(
|
|
const RegionData * regionData,
|
|
DpRegion * region
|
|
) const;
|
|
|
|
GpStatus
|
|
TransformLeaf(
|
|
GpMatrix * matrix,
|
|
RegionData * data
|
|
);
|
|
|
|
INT
|
|
GetRegionDataSize(
|
|
const RegionData * regionData
|
|
) const;
|
|
|
|
GpStatus
|
|
GetRegionData(
|
|
IStream * stream,
|
|
const RegionData * regionData
|
|
) const;
|
|
|
|
GpStatus
|
|
SetRegionData(
|
|
const BYTE * & regionDataBuffer,
|
|
UINT & regionDataSize,
|
|
RegionData * regionData,
|
|
RegionData * regionDataArray,
|
|
INT & nextArrayIndex,
|
|
INT arraySize
|
|
);
|
|
|
|
public:
|
|
GpRegion();
|
|
GpRegion(const GpRectF * rect);
|
|
GpRegion(const GpPath * path);
|
|
GpRegion(const GpRegion * region, BOOL lazy = FALSE);
|
|
GpRegion(const BYTE * regionDataBuffer, UINT size);
|
|
GpRegion(HRGN hRgn);
|
|
~GpRegion();
|
|
|
|
virtual BOOL IsValid() const
|
|
{
|
|
// If the region came from a different version of GDI+, its tag
|
|
// will not match, and it won't be considered valid.
|
|
return ((Type != TypeNotValid) && GpObject::IsValid(ObjectTagRegion));
|
|
}
|
|
|
|
VOID FreePathData();
|
|
|
|
GpLockable *GetObjectLock() // Get the lock object
|
|
{
|
|
return &Lockable;
|
|
}
|
|
|
|
virtual ObjectType GetObjectType() const { return ObjectTypeRegion; }
|
|
virtual UINT GetDataSize() const;
|
|
virtual GpStatus GetData(IStream * stream) const;
|
|
virtual GpStatus SetData(const BYTE * dataBuffer, UINT size);
|
|
|
|
VOID Set(const GpRectF * rect)
|
|
{
|
|
Set(rect->X, rect->Y, rect->Width, rect->Height);
|
|
}
|
|
VOID Set(REAL x, REAL y, REAL width, REAL height);
|
|
GpStatus Set(const GpPath * path);
|
|
GpStatus Set(const GpRegion * region, BOOL lazy = FALSE);
|
|
GpStatus Set(
|
|
const BYTE * regionDataBuffer, // NULL means set to empty
|
|
UINT regionDataSize
|
|
);
|
|
|
|
VOID SetInfinite();
|
|
VOID SetEmpty();
|
|
|
|
GpStatus GetBounds(GpGraphics * graphics, GpRectF * bounds,
|
|
BOOL device = FALSE) const;
|
|
GpStatus GetBounds(GpMatrix * matrix, GpRect * bounds) const;
|
|
|
|
GpStatus GetHRgn(GpGraphics * graphics, HRGN * hRgn) const;
|
|
|
|
GpStatus GetRegionScans(GpRect *rects, INT *count, const GpMatrix *matrix) const;
|
|
GpStatus GetRegionScans(GpRectF *rects, INT *count, const GpMatrix *matrix) const;
|
|
|
|
GpStatus IsVisible(GpPointF * point, GpMatrix * matrix, BOOL * isVisible) const;
|
|
GpStatus IsVisible(GpRectF * rect, GpMatrix * matrix, BOOL * isVisible) const;
|
|
GpStatus IsVisible(GpRegion * region, GpMatrix * matrix, BOOL * isVisible) const;
|
|
|
|
GpStatus IsEmpty (GpMatrix * matrix, BOOL * isEmpty) const;
|
|
GpStatus IsInfinite(GpMatrix * matrix, BOOL * isInfinite) const;
|
|
GpStatus IsEqual (GpRegion * region, GpMatrix * matrix, BOOL * isEqual) const;
|
|
BOOL IsOnePath () const
|
|
{
|
|
ASSERT(IsValid());
|
|
|
|
return ((Type & REGIONTYPE_LEAF) != 0);
|
|
}
|
|
BOOL IsRect () const
|
|
{
|
|
return (IsOnePath() && (Type != TypePath));
|
|
}
|
|
const GpPath * GetPath() const
|
|
{
|
|
ASSERT(Type == TypePath);
|
|
return Path;
|
|
}
|
|
|
|
GpStatus Transform(GpMatrix * matrix);
|
|
GpStatus Offset (REAL xOffset, REAL yOffset);
|
|
|
|
GpStatus Combine(
|
|
const GpRectF * rect,
|
|
CombineMode combineMode
|
|
);
|
|
|
|
GpStatus Combine(
|
|
const GpPath * path,
|
|
CombineMode combineMode
|
|
);
|
|
|
|
GpStatus Combine(
|
|
GpRegion * region,
|
|
CombineMode combineMode
|
|
);
|
|
|
|
GpStatus And (GpRectF * rect)
|
|
{
|
|
return Combine (rect, CombineModeIntersect);
|
|
}
|
|
|
|
GpStatus And (GpPath * path)
|
|
{
|
|
return Combine (path, CombineModeIntersect);
|
|
}
|
|
|
|
GpStatus And (GpRegion * region)
|
|
{
|
|
return Combine (region, CombineModeIntersect);
|
|
}
|
|
|
|
GpStatus Or (GpRectF * rect)
|
|
{
|
|
return Combine (rect, CombineModeUnion);
|
|
}
|
|
|
|
GpStatus Or (GpPath * path)
|
|
{
|
|
return Combine (path, CombineModeUnion);
|
|
}
|
|
|
|
GpStatus Or (GpRegion * region)
|
|
{
|
|
return Combine (region, CombineModeUnion);
|
|
}
|
|
|
|
GpStatus Xor (GpRectF * rect)
|
|
{
|
|
return Combine (rect, CombineModeXor);
|
|
}
|
|
|
|
GpStatus Xor (GpPath * path)
|
|
{
|
|
return Combine (path, CombineModeXor);
|
|
}
|
|
|
|
GpStatus Xor (GpRegion * region)
|
|
{
|
|
return Combine (region, CombineModeXor);
|
|
}
|
|
|
|
GpStatus Exclude (GpRectF * rect)
|
|
{
|
|
return Combine (rect, CombineModeExclude);
|
|
}
|
|
|
|
GpStatus Exclude (GpPath * path)
|
|
{
|
|
return Combine (path, CombineModeExclude);
|
|
}
|
|
|
|
GpStatus Exclude (GpRegion * region)
|
|
{
|
|
return Combine (region, CombineModeExclude);
|
|
}
|
|
|
|
GpStatus Complement (GpRectF * rect)
|
|
{
|
|
return Combine (rect, CombineModeComplement);
|
|
}
|
|
|
|
GpStatus Complement (GpPath * path)
|
|
{
|
|
return Combine (path, CombineModeComplement);
|
|
}
|
|
|
|
GpStatus Complement (GpRegion * region)
|
|
{
|
|
return Combine (region, CombineModeComplement);
|
|
}
|
|
|
|
};
|
|
|
|
#endif _REGION_HPP
|