/**************************************************************************\ * * 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 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