Implements non-native regions with support for managing their Z-order.

lazregions.pas contains classes, types, and routines used to implement clipping regions in TLazCanvas, and regions used in custom-drawn LCL controls.

Author: Felipe Monteiro de Carvalho

Represents region fill modes used for polygons in Lazarus regions.

Adheres to the nomenclature used in the Windows GDI API.

Use the alternate fill mode (fills the area between odd-numbered and even-numbered polygon sides on each scan line). Use the winding fill mode (fills any region with a non-zero winding value). Defines an array type used for TPoint values.

TPointArray is an array type used for TPoint instances which define the vertices in a polygon. It is used to implement the Points member in TLazRegionPolygon, and passed as an argument to the AddPolygon method in TLazRegion.

Base class used for rectangular areas in a region.

TLazRegionPart defines the base class used to represent a rectangular area in a region. TLazRegionPart is used as the ancestor for the TLazRegionRect class.

Gets the rectangle with the Bounds for an area in a region.

GetBoundingRect is a TRect function used to get the rectangle with the Bounds for a rectangular area in a region. In TLazRegionPart, the return value contains an empty rectangle (with zero assigned to its Left, Top, Right, Bottom, Width, and Height members).

Indicates if a point with the specified coordinates is within the bounds for the rectangular area.

Always returns False in TLazRegionPart; it uses an empty rectangle as its Bounds (Left, Top, Bottom, and Right set to zero).

True when the coordinates are located in the bounds for the rectangular area. Horizontal coordinate for the point. Vertical coordinate for the point. Implements a region defined by a TRect structure.

TLazRegionRect is a TLazRegionPart descendant which implements a region as a rectangular area. It includes a Rect member used to store the TRect with the bounds for the region. It also provides an overridden IsPointInPart method to examine the Rect member when locating a point in the region. Instances of TLazRegionRect are created when the AddRectangle method in TLazRegion is called.

Rectangle with the bounds that defines the region.

Rect is a TRect member which contains the rectangular area that is the bounds for the region.

Indicates if a point with the specified coordinates is within the rectangle used as the bounds for the region.

Overrides the method in the ancestor class to use the Rect member as the bounds for the region.

True when the coordinates are located in the bounds rectangle for the region. Horizontal coordinate for the point. Vertical coordinate for the point. Represents a region defined as a series of vertices for a polygon.

TLazRegionPolygon is a TLazRegionPart descendant which implements a region as a polygonal area defined by a series of vertices.

The Points member contains the TPoint values that define the vertices for the polygon. FillMode defines how the interior of the polygon is filled, and uses values like those defined for the Windows GDI API. An overridden IsPointInPart is provided to determine if a point is within the bounds for the polygonal area.

Instances of TLazRegionPolygon are created when the AddPolygon method in TLazRegion is called.

Array of TPoint values that define the vertices for the polygonal region. Fill mode used for the polygon. Indicates if a point with the specified coordinates is within the vertices for the polygonal region.

IsPointInPart is an overridden Boolean function which indicates if a point with the specified coordinates is within the vertices for the polygonal region.

IsPointInPart calls the IsPointInPolygon routine to get the return value for the method. The return value is True when the point in AX and AY is located inside the polygon vertices defined in the Points member.

True when the point occurs inside the vertices for the polygonal region. Horizontal coordinate for the point. Vertical coordinate for the point. Implements a region defined as an Ellipse.

TLazRegionEllipse is a TLazRegionPart descendant which implements a region defined as an elliptical area with the specified vertex and co-vertex. The X1, X2, Y1, and Y2 members are provided to represent the horizontal and vertical coordinates for the vertex and co-vertex points.

Instances of TLazRegionEllipse are created when the AddEllipse method in TLazRegion is called.

Horizontal coordinate for the vertex. Vertical coordinate for the vertex. Horizontal coordinate for the co-vertex. Vertical coordinate for the co-vertex. Indicates if the specified point is located inside the elliptical area for the region.

The equation for the inner area of an axis aligned ellipse is:

(X/a)^2 + (Y/b)^2 <= 1
True when the specified point is located inside the area for the ellipse. Horizontal coordinate for the point. Vertical coordinate for the point. Defined for FPC version 2.6 or older. Defined in fpcanvas.pp in the FCL for later FPC versions. Defined for FPC version 2.6. Defined in fpcanvas.pp for later FPC versions. Defined for FPC version 2.6. Defined in fpcanvas.pp for later FPC versions. Defined for FPC version 2.6. Defined in fpcanvas.pp for later FPC versions. Defined for FPC version 2.6. Defined in fpcanvas.pp for later FPC versions. Defined for FPC version 2.6. Defined in fpcanvas.pp for later FPC versions. Defined for FPC version 2.6. Defined in fpcanvas.pp for later FPC versions. Represents a custom region in the Lazarus LCL.

TLazRegion is a TFPCustomRegion descendant which represents a region as used in the Lazarus LCL. It is used to implement the clipping region in TLazCanvas, and in custom-drawn windowed LCL controls. The region is composed of TLazRegionPart descendants representing the rectangles, polygons, and ellipses that define the display area on a device. TLazRegion provides overridden methods to query information for the composite display area.

The parts of a region should all be inside valid areas for the region. If a combine operation removes an area in the region, then the area should be removed from all parts for the region. There is no z-order for the Parts, they are all validly inside the region area.

TLazCanvas TLazCanvasState.ClipRegion
List with the Rectangles, Polygons, and Ellipses that define the display area for the region. Indicates whether this region is composed of a single rectangular part.

Use Rect to access the TRect structure with the bounds for the rectangular region.

TRect instance with the bounds for the region. Constructor for the class instance.

Create is the constructor for the class instance. Create calls the inherited constructor to initialize the class instance. Create allocates resources needed for the Parts member, and sets the default value for IsSimpleRectRegion to True.

Destructor for the class instance.

Destroy is the overridden destructor for the class instance. Destroy ensures that resource allocated for the Parts member are freed. Destroy calls the inherited destructor prior to exiting from the method.

Destroy does not call Parts.Clear prior to freeing the Parts member; that action is performed in the destructor for the TFPList class instance.
Stores values from ASrcRegion in the current class instance.

Calls Clear to remove any items stored in Parts. Calls AddPartsFromRegion to capture the values from the source region.

Region with the values stored in the method. Frees all of the TLazRegionPart instances in Parts, and clears the list.

Frees all of the TLazRegionPart instances in the Parts member, and clears the list.

Combines the specified source region using the given region operation.

ASrcRegion is the source region with the Parts applied in the method.

AOperation can contain a Combine Region flag that includes:

  • RGN_AND (1)
  • RGN_OR (2)
  • RGN_XOR (3)
  • RGN_DIFF (4)
  • RGN_COPY(5)
In the current LCL version, only RGN_COPY and RGN_OR are implemented; all other values are ignored and no actions are performed in the method. RGN_COPY causes the Parts in ASrcRegion to be assigned to the Parts in the current class instance. RGN_OR cause the Parts in ASrcRegion to the be added to the Parts in the current class instance.
Source region with values applied in the method. Combine region flag with the operation to perform for the subregions. Gets the type of region represented in the class instance.

GetRegionKind is a Longint function used to get the type of region represented in the class instance. The return value adheres to the region flag values used in the Windows GDI API, and can include one of the following:

COMPLEXREGION (3)
The region has more than one rectangle, polygon, or ellipse. Used when IsSimpleRectRegion is False.
SIMPLEREGION (2)
The region is a simple rectangle defined using the Rect member. Used when IsSimpleRectRegion is True, and Rect is not an empty rectangle (Left, Top, Bottom, and Right all contain zero).
NULLREGION (1)
The region has an empty value in its Rect member (Left, Top, Width, and Height all contain zero).
REGION_ERROR (0)
An error occurred. Not used in GetRegionKind.
Region flag value for the class instance. Indicates whether the Rect member contains empty or invalid rectangle coordinates. True when the dimensions for the rectangle are invalid. Adds the specified part as a subregion in the Parts member.

AddPart is a procedure used to add the specified TLazRegionPart in APart to the Parts member in the class instance. AddPart calls the TFPList.Add method to store the value in APart in the list. AddPart calls DoChangeToComplexRegion to update IsSimpleRectRegion to reflect the current composition for the region.

AddPart is used in the implementation of the AddRectangle, AddPolygon, and AddEllipse methods.

TLazRegionPart (or descendant) added in the method. Adds the specified TRect instance to the Parts member.

AddRectangle is a procedure used to add a rectangular region defined by the TRect instance in ARect to the Parts member. AddRectangle creates a TLazRegionRect instance and assigns ARect to its Rect member. AddRectangle calls AddPart to store the TLazRegionRect instance in Parts.

TRect instance with the rectangular region added in the method. Adds a polygonal area with the specified vertices to the region.

AddPolygon is a procedure used to add a polygonal area with the specified vertices to the region. APoints is an array with TPoint instances that define each of the vertices for the polygon. AFillMode is a TLazRegionFillMode value that defines the fill mode for the polygonal area.

AddPolygon creates a TLazRegionPolygon instance that is used to store the area definition in the Parts member. The arguments to the method are assigned to the Points and FillMode members in the new class instance. AddPolygon calls AddPart to store the new TLazRegionPolygon instance in Parts.

Array of TPoint instances representing the vertices for the polygon. TLazRegionFillMode value used for the polygon. Adds an elliptical area with the specified co-vertices to the region.

AddEllipse is a procedure used to add an elliptical area with the specified co-vertices to the region. AX1 and AY1 is the point where the endpoint for the long axis is located. AX2 and AY2 is the point where the endpoint for the short axis is located. Each point is located perpendicular to the opposing axis, and its diameter bisects the opposing axis.

AddEllipse creates an instance of TLazRegionEllipse and assigns the arguments to the corresponding members in the new class instance. AddEllipse calls the AddPart method to store the new TLazRegionEllipse instance in the Parts member.

Horizontal coordinate for the endpoint of the major axis. Vertical coordinate for the endpoint of the major axis. Horizontal coordinate for the endpoint of the minor axis. Vertical coordinate for the endpoint of the minor axis. Sets the area for the region to the specified rectangle. TRect with the bounds for the region. Adds the region (and any subregions) from ASrcRegion to the current class instance.

AddPartsFromRegion is a procedure used to add the region in ASrcRegion to the current class instance. ASrcRegion can be represented as a simple rectangular region, or a complex region using rectangles, polygons, and/or ellipses.

AddPartsFromRegion ensures that the Rect or Parts members from ASrcRegion are combined in the correct manner with the values in Rect or Parts for the current class instance. The value in IsSimpleRectRegion is set to False if it was necessary to add entries to the Parts member in the method.

Region with the values added in the method. Adds the value in Rect to the Parts member, and resets the value in IsSimpleRectRegion.

DoChangeToComplexRegion is a procedure used to change the region from a simple rectangle to a complex region as defined in the Parts member. DoChangeToComplexRegion uses the values from IsSimpleRectRegion and IsSimpleRectEmpty to determine if any actions are required in the method. No actions are performed when IsSimpleRectRegion is False, or when IsSimpleRectEmpty returns True.

DoChangeToComplexRegion changes the value in IsSimpleRectRegion to False, and calls AddRectangle to store the value in Rect in the Parts member.

Gets the bounds for the region as a rectangle.

GetBoundingRect is a TRect function used to get the rectangle structure with the bounds for the region. GetBoundingRect uses the value in the Rect member as the return value for the method.

TRect with the bounds for the region. Checks whether the specified point is inside the region.

Checks if the specified point is inside the display area for the region. Uses the value in IsSimpleRectRegion to determine whether Rect contains the bounds for the region. When it contains False, the values in the Parts member are used to determine the return value.

Returns True when the specified point is located inside the rectangle or one of the subregions.

True when the point is located inside the rectangle or one of the subregions that define the bounds for the region. Horizontal coordinate for the point. Vertical coordinate for the point. Implement a region which can have other regions as children.

TLazRegionWithChilds is a TLazRegion descendant which implements a region which can hold a list of other region holders. Use Parent to access the complex region which owns the current class instance. Use Childs to access the list of subregions for the class instance.

Complex region which hosts the subregions in the current class instance. Parent is not maintain in methods for the class instance; it is available for use in widget set classes which utilize the region. List of subregions for the current class instance.

The order in this list is also the Z-Order of the sub regions inside it. The element with index zero is the bottom-most one.

Contains an available link to another object. Contains an available link to another object. Constructor for the class instance.

Create is the overridden constructor for the class instance. Create calls the inherited constructor to initialize the class instance, and allocates resources needed for the Childs member.

Destructor for the class instance.

Destroy is the overridden destructor for the class instance. Destroy ensures that resources allocated to the Childs member are freed. Destroy calls the inherited destructor prior to exiting from the method.

Indicates if the specified point is within the bounds for the region.

Returns itself or a child, depending on where the point was found, or nil if the point is neither in the region nor in any children.

Part of the behavior is implemented in TLazRegionWithChilds.

True when the point is within the bounds for one of the child areas in the region. Horizontal coordinate for the point. Vertical coordinate for the point. Determines if the specified point is inside the vertices for the specified polygon.

The function will return True if the point at AX, AY is inside the specified polygon. Returns False if it is not.

Original C code: http://www.visibone.com/inpoly/inpoly.c.txt .

Translated from C to Pascal by: Felipe Monteiro de Carvalho.

True when the specified point is located within the polygon using the specified vertices. Horizontal coordinate for the point. Vertical coordinate for the point. Array with the TPoint values that define the vertices for the polygon.