From 506fa4497a000cc261150cba878b44b73642560a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Van=20Canneyt?= Date: Fri, 17 Jan 2025 22:04:52 +0100 Subject: [PATCH] * More completions for compatibility with FPC --- packages/rtl/src/types.pas | 307 ++++++++++++++++++++++++++++++++++++- 1 file changed, 304 insertions(+), 3 deletions(-) diff --git a/packages/rtl/src/types.pas b/packages/rtl/src/types.pas index 743539a..3f97e41 100644 --- a/packages/rtl/src/types.pas +++ b/packages/rtl/src/types.pas @@ -19,10 +19,18 @@ unit Types; interface +Type + Single = Double; // Avoid warning. + const Epsilon: Single = 1E-40; Epsilon2: Single = 1E-30; + cPI: Single = 3.141592654; + cPIdiv180: Single = 0.017453292; + cPIdiv2: Single = 1.570796326; + cPIdiv4: Single = 0.785398163; + type RTLString = string; // Compatibility with FPC @@ -379,13 +387,24 @@ type function EqualRect(const r1,r2 : TRect) : Boolean; +function EqualRect(const r1,r2 : TRectF) : Boolean; function Rect(Left, Top, Right, Bottom : Integer) : TRect; +function RectF(Left,Top,Right,Bottom : Single) : TRectF; inline; function Bounds(ALeft, ATop, AWidth, AHeight : Integer) : TRect; function Point(x,y : Integer): TPoint; {$IFDEF Has_Inline}inline;{$ENDIF} function PointF(x,y : single) : TPointF; {$IFDEF Has_Inline}inline;{$ENDIF} function PtInRect(const aRect: TRect; const p: TPoint) : Boolean; function IntersectRect(out aRect: TRect; const R1,R2: TRect) : Boolean; +function IntersectRect(const Rect1, Rect2: TRect): Boolean; +function IntersectRect(const Rect1, Rect2: TRectF): Boolean; +//function IntersectRect(var Rect : TRect; const R1,R2 : TRect) : Boolean; +function IntersectRect(var aRect : TRectF; const R1,R2 : TRectF) : Boolean; + function UnionRect(out aRect: TRect; const R1,R2: TRect) : Boolean; +function UnionRect(out aRectF: TRectF; const R1,R2: TRectF) : Boolean; +function UnionRect(const R1,R2 : TRect) : TRect; +function UnionRect(const R1,R2 : TRectF) : TRectF; + function IsRectEmpty(const aRect: TRect) : Boolean; function OffsetRect(var aRect: TRect; DX, DY: Integer) : Boolean; function OffsetRect(var aRect: TRectF; DX, DY: single) : Boolean; @@ -396,6 +415,30 @@ function Size(const aRect: TRect): TSize; function RectCenter(var R: TRect; const Bounds: TRect): TRect; function RectCenter(var R: TRectF; const Bounds: TRectF): TRectF; +function NormalizeRectF(const Pts: array of TPointF): TRectF; overload; +function NormalizeRect(const ARect: TRectF): TRectF; overload; + +function PtInRect(const Rect : TRectF; const p : TPointF) : Boolean; + +function RectHeight(const Rect: TRect): Integer; inline; +function RectHeight(const Rect: TRectF): Single; inline; +function RectWidth(const Rect: TRect): Integer; inline; +function RectWidth(const Rect: TRectF): Single; inline; +function IsRectEmpty(const Rect : TRectF) : Boolean; +procedure MultiplyRect(var R: TRectF; const DX, DY: Single); +function InflateRect(var Rect: TRectF; dx: single; dy: Single): Boolean; +function Size(const ARect: TRectF): TSizeF; inline; +function ScalePoint(const P: TPointF; dX, dY: Single): TPointF; overload; +function ScalePoint(const P: TPoint; dX, dY: Single): TPoint; overload; +function MinPoint(const P1, P2: TPointF): TPointF; overload; +function MinPoint(const P1, P2: TPoint): TPoint; overload; +function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Size: Integer): TRect; overload; +function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Percent: Double): TRect; overload; +function CenteredRect(const SourceRect: TRect; const aCenteredRect: TRect): TRect; +function IntersectRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean; +function UnionRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean; + + implementation uses math; @@ -425,11 +468,165 @@ begin Result:=R; end; +function NormalizeRectF(const Pts: array of TPointF): TRectF; +var + Pt: TPointF; + +begin + Result.Left:=$FFFF; + Result.Top:=$FFFF; + Result.Right:=-$FFFF; + Result.Bottom:=-$FFFF; + for Pt in Pts do + begin + Result.Left:=Min(Pt.X,Result.left); + Result.Top:=Min(Pt.Y,Result.Top); + Result.Right:=Max(Pt.X,Result.Right); + Result.Bottom:=Max(Pt.Y,Result.Bottom); + end; +end; + +function NormalizeRect(const ARect: TRectF): TRectF; + +begin + With aRect do + Result:=NormalizeRectF([PointF(Left,Top), + PointF(Right,Top), + PointF(Right,Bottom), + PointF(Left,Bottom)]); +end; + +function PtInRect(const Rect: TRectF; const p: TPointF): Boolean; + +begin + Result:=(p.y>=Rect.Top) and + (p.y=Rect.Left) and + (p.xRect2.Left) + and (Rect1.TopRect2.Top); +end; + +function IntersectRect(const Rect1, Rect2: TRectF): Boolean; +begin + Result:=(Rect1.LeftRect2.Left) + and (Rect1.TopRect2.Top); +end; + +function IntersectRect(var aRect: TRectF; const R1, R2: TRectF): Boolean; +var + lRect: TRectF; +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; + + // The var parameter is only assigned in the end to avoid problems + // when passing the same rectangle in the var and const parameters. + if IsRectEmpty(lRect) then + begin + aRect:=RectF(0.0,0.0,0.0,0.0); + Result:=false; + end + else + begin + Result:=true; + aRect := lRect; + end; +end; + function UnionRect(out aRect: TRect; const R1, R2: TRect): Boolean; var lRect: TRect; @@ -520,6 +772,44 @@ begin end; end; +function UnionRect(out aRectF: TRectF; const R1, R2: TRectF): Boolean; +var + lRect: TRectF; +begin + lRect:=R1; + if R2.LeftR1.Right then + lRect.Right:=R2.Right; + if R2.Bottom>R1.Bottom then + lRect.Bottom:=R2.Bottom; + + if IsRectEmpty(lRect) then + begin + aRectF:=RectF(0.0,0.0,0.0,0.0); + Result:=false; + end + else + begin + aRectF:=lRect; + Result:=true; + end; +end; + +function UnionRect(const R1, R2: TRect): TRect; +begin + Result:=Default(TRect); + UnionRect(Result,R1,R2); +end; + +function UnionRect(const R1, R2: TRectF): TRectF; +begin + Result:=Default(TRectF); + UnionRect(Result,R1,R2); +end; + function IsRectEmpty(const aRect: TRect): Boolean; begin Result:=(aRect.Right<=aRect.Left) or (aRect.Bottom<=aRect.Top); @@ -1015,8 +1305,18 @@ begin end; function TPointF.Reflect(const normal: TPointF): TPointF; +var + lCross : single; + lTmp : TPointF; + begin //result := self + (-2 * normal ** self) * normal; + lCross:=x*normal.x + y*normal.y; + lCross:=lCross * (-2); + lTmp.x:=normal.x*lCross; + lTmp.y:=normal.y*lCross; + Result.X:=X+lTmp.x; + Result.Y:=Y+lTmp.Y; end; function TPointF.MidPoint(const b: TPointF): TPointF; @@ -1048,8 +1348,11 @@ begin end; function TPointF.AngleCosine(const b: TPointF): single; +var + lCross : single; begin -// result := EnsureRange((self ** b) / sqrt((sqr(x) + sqr(y)) * (sqr(b.x) + sqr(b.y))), -1, 1); + lCross:=x*b.x + y*b.y; + result := EnsureRange(lCross / sqrt((sqr(x) + sqr(y)) * (sqr(b.x) + sqr(b.y))), -1, 1); end; (* @@ -1754,8 +2057,6 @@ function TPoint3D.ToString(aSize,aDecimals : Byte) : RTLString; var Sx,Sy,Sz : string; - P : integer; - begin Sx:=SingleToStr(X,aSize,aDecimals); Sy:=SingleToStr(Y,aSize,aDecimals);