unit uRect; interface uses windows; { type PPoint = ^TPoint; TPoint = packed record X: Longint; Y: Longint; end; PSmallPoint = ^TSmallPoint; TSmallPoint = packed record x: SmallInt; y: SmallInt; end; PRect = ^TRect; TRect = packed record case integer of 0: (Left, Top, Right, Bottom: Longint); 1: (TopLeft, BottomRight: TPoint); end; } { -function SetRect(var lprc: TRect; xLeft, yTop, xRight, yBottom: integer): bool; stdcall; -function CopyRect(var lprcDst: TRect; const lprcSrc: TRect): bool; stdcall; -function InflateRect(var lprc: TRect; dx, dy: integer): bool; stdcall; function SubtractRect(var lprcDst: TRect; const lprcSrc1, lprcSrc2: TRect): bool; stdcall; -function SetRectEmpty(var lprc: TRect): bool; stdcall; -function IntersectRect(var lprcDst: TRect; const lprcSrc1, lprcSrc2: TRect): bool; stdcall; -function UnionRect(var lprcDst: TRect; const lprcSrc1, lprcSrc2: TRect): bool; stdcall; -function OffsetRect(var lprc: TRect; dx, dy: integer): bool; stdcall; -function IsRectEmpty(const lprc: TRect): bool; stdcall; -function EqualRect(const lprc1, lprc2: TRect): bool; stdcall; -function PtInRect(const lprc: TRect; pt: TPoint): bool; stdcall; } function Point(X, Y: integer): TPoint; overload; procedure Point(var pt:TPoint; X, Y: integer); overload; function SmallPoint(X, Y: integer): TSmallPoint; overload; function SmallPoint(XY: longword): TSmallPoint; overload; function CenterPoint(const Rect: TRect): TPoint; overload; procedure CenterPoint(const Rect: TRect; var pt:TPoint); overload; function PointInRect(const P: TPoint; const Rect: TRect): Boolean; function PtInRect (const Rect: TRect; const P: TPoint): Boolean; function Rect (Left, Top, Right, Bottom: integer): TRect; overload; procedure Rect (var Rect:TRect; Left, Top, Right, Bottom: integer); overload; procedure SetRect(var Rect:TRect; Left, Top, Right, Bottom: integer); function CopyRect(var Rect: TRect; const R1: TRect):Boolean; function SetRectEmpty(var Rect: TRect): Boolean; function Bounds(ALeft, ATop, AWidth, AHeight: integer): TRect; overload; procedure Bounds(var Rect:TRect; ALeft, ATop, AWidth, AHeight: integer); overload; function EqualRect(const R1, R2: TRect): Boolean; function IsRectInside(const R1, R2: TRect): Boolean; function IsRectEmpty(const Rect: TRect): Boolean; function InflateRect(var Rect: TRect; dx, dy: integer): Boolean; function OffsetRect(var Rect: TRect; DX: integer; DY: integer): Boolean; function IntersectRect(var Rect: TRect; const R1, R2: TRect): Boolean; overload; function IntersectRect(const R1, R2: TRect): Boolean; overload; function UnionRect(var Rect: TRect; const R1, R2: TRect): Boolean; implementation function Point(X, Y: integer): TPoint; begin Result.X := X; Result.Y := Y; end; procedure Point(var pt:TPoint; X, Y: integer); begin pt.X := X; pt.Y := Y; end; function SmallPoint(X, Y: integer): TSmallPoint; begin Result.X := X; Result.Y := Y; end; function SmallPoint(XY: longword): TSmallPoint; begin Result.X := SmallInt(XY and $0000FFFF); Result.Y := SmallInt(XY shr 16); end; function PointInRect(const P: TPoint; const Rect: TRect): Boolean; begin Result := (P.X >= Rect.Left) and (P.X < Rect.Right) and (P.Y >= Rect.Top) and (P.Y < Rect.Bottom); end; function PtInRect(const Rect: TRect; const P: TPoint): Boolean; begin Result := (P.X >= Rect.Left) and (P.X < Rect.Right) and (P.Y >= Rect.Top) and (P.Y < Rect.Bottom); end; function CenterPoint(const Rect: TRect): TPoint; begin with Rect do begin Result.X := (Right - Left) div 2 + Left; Result.Y := (Bottom - Top ) div 2 + Top; end; end; procedure CenterPoint(const Rect: TRect; var pt:TPoint); begin with Rect do begin pt.X := (Right - Left) div 2 + Left; pt.Y := (Bottom - Top ) div 2 + Top; end; end; //----- TRect ----- function Rect(Left, Top, Right, Bottom: integer): TRect; begin Result.Left := Left; Result.Top := Top; Result.Bottom := Bottom; Result.Right := Right; end; procedure Rect(var Rect:TRect; Left, Top, Right, Bottom: integer); begin Rect.Left := Left; Rect.Top := Top; Rect.Bottom := Bottom; Rect.Right := Right; end; procedure SetRect(var Rect:TRect; Left, Top, Right, Bottom: integer); begin Rect.Left := Left; Rect.Top := Top; Rect.Bottom := Bottom; Rect.Right := Right; end; function CopyRect(var Rect: TRect; const R1: TRect): Boolean; begin Rect := R1; Result := not IsRectEmpty(Rect); end; function SetRectEmpty(var Rect: TRect): Boolean; begin FillChar(Rect,SizeOf(Rect),0); Result := True; end; function EqualRect(const R1, R2: TRect): Boolean; begin Result := (R1.Left = R2.Left) and (R1.Right = R2.Right) and (R1.Top = R2.Top) and (R1.Bottom = R2.Bottom); end; function IsRectInside(const R1, R2: TRect): Boolean; begin Result := (R1.Left >= R2.Left) and (R1.Right <= R2.Right) and (R1.Top >= R2.Top) and (R1.Bottom <= R2.Bottom); end; function IsRectEmpty(const Rect: TRect): Boolean; begin Result := (Rect.Right <= Rect.Left) or (Rect.Bottom <= Rect.Top); end; function IntersectRect(const R1, R2: TRect): Boolean; var ml,mr,mt,mb:longint; begin if R1.Left > R2.Left then ml := R1.Left else ml := R2.Left; if R1.Right < R2.Right then mr := R1.Right else mr := R2.Right; if R1.Top > R2.Top then mt := R1.Top else mt := R2.Top; if R1.Bottom < R2.Bottom then mb := R1.Bottom else mb := R2.Bottom; Result := (ml < mr) and (mt < mb); end; function IntersectRect(var Rect: TRect; const R1, R2: TRect): Boolean; var lRect:TRect; begin lRect := R1; if R2.Left > R1.Left then lRect.Left := R2.Left; if R2.Top > R1.Top then lRect.Top := R2.Top; if R2.Right < R1.Right then lRect.Right := R2.Right; if R2.Bottom < R1.Bottom then lRect.Bottom := R2.Bottom; Result := not IsRectEmpty(lRect); if not Result then FillChar(lRect, SizeOf(lRect), 0); Rect:=lRect; end; function UnionRect(var Rect: TRect; const R1, R2: TRect): Boolean; begin Rect := R1; if not IsRectEmpty(R2) then begin if R2.Left < R1.Left then Rect.Left := R2.Left; if R2.Top < R1.Top then Rect.Top := R2.Top; if R2.Right > R1.Right then Rect.Right := R2.Right; if R2.Bottom > R1.Bottom then Rect.Bottom := R2.Bottom; end; Result := not IsRectEmpty(Rect); if not Result then FillChar(Rect, SizeOf(Rect), 0); end; function InflateRect(var Rect: TRect; dx, dy: integer): Boolean; begin with Rect do begin Left := Left - dx; Right := Right + dx; Top := Top - dy; Bottom := Bottom + dy; end; Result := not IsRectEmpty(Rect); end; function OffsetRect(var Rect: TRect; DX: integer; DY: integer): Boolean; begin if @Rect <> nil then // Test to increase compatiblity with Windows begin Inc(Rect.Left , DX); Inc(Rect.Right , DX); Inc(Rect.Top , DY); Inc(Rect.Bottom, DY); Result := True; end else Result := False; end; function Bounds(ALeft, ATop, AWidth, AHeight: integer): TRect; begin with Result do begin Left := ALeft; Top := ATop; Right := ALeft + AWidth; Bottom := ATop + AHeight; end; end; procedure Bounds(var Rect:TRect; ALeft, ATop, AWidth, AHeight: integer); begin with Rect do begin Left := ALeft; Top := ATop; Right := ALeft + AWidth; Bottom := ATop + AHeight; end; end; end.