Browse Source

* Patch from Ondrej Pokorny to make Trect methods more Delphi compatible (Bug ID 29479)

git-svn-id: trunk@32998 -
michael 9 years ago
parent
commit
e7a722cdd9
2 changed files with 284 additions and 3 deletions
  1. 239 2
      rtl/inc/typshrd.inc
  2. 45 1
      rtl/inc/typshrdh.inc

+ 239 - 2
rtl/inc/typshrd.inc

@@ -164,6 +164,125 @@ end;
 
 { TRect }
 
+class operator TRect. * (L, R: TRect): TRect;
+begin
+  Result := TRect.Intersect(L, R);
+end;
+
+class operator TRect. + (L, R: TRect): TRect;
+begin
+  Result := TRect.Union(L, R);
+end;
+
+class operator TRect. <> (L, R: TRect): Boolean;
+begin
+  Result := not(L=R);
+end;
+
+class operator TRect. = (L, R: TRect): Boolean;
+begin
+  Result :=
+    (L.Left = R.Left) and (L.Right = R.Right) and
+    (L.Top = R.Top) and (L.Bottom = R.Bottom);
+end;
+
+{$IFDEF VER3_0_0}
+class function TRect.Create(ALeft, ATop, ARight, ABottom: Longint): TRect;
+begin
+  Result.Left := ALeft;
+  Result.Top := ATop;
+  Result.Right := ARight;
+  Result.Bottom := ABottom;
+end;
+
+class function TRect.Create(P1, P2: TPoint; Normalize: Boolean): TRect;
+begin
+  Result.TopLeft := P1;
+  Result.BottomRight := P2;
+  if Normalize then
+    Result.NormalizeRect;
+end;
+
+class function TRect.Create(Origin: TPoint): TRect;
+begin
+  Result.TopLeft := Origin;
+  Result.BottomRight := Origin;
+end;
+
+class function TRect.Create(Origin: TPoint; AWidth, AHeight: Longint): TRect;
+begin
+  Result.TopLeft := Origin;
+  Result.Width := AWidth;
+  Result.Height := AHeight;
+end;
+
+class function TRect.Create(R: TRect; Normalize: Boolean): TRect;
+begin
+  Result := R;
+  if Normalize then
+    Result.NormalizeRect;
+end;
+
+{$ELSE}
+
+constructor TRect.Create(ALeft, ATop, ARight, ABottom: Longint);
+begin
+  Left := ALeft;
+  Top := ATop;
+  Right := ARight;
+  Bottom := ABottom;
+end;
+
+constructor TRect.Create(P1, P2: TPoint; Normalize: Boolean);
+begin
+  TopLeft := P1;
+  BottomRight := P2;
+  if Normalize then
+    NormalizeRect;
+end;
+
+constructor TRect.Create(Origin: TPoint);
+begin
+  TopLeft := Origin;
+  BottomRight := Origin;
+end;
+
+constructor TRect.Create(Origin: TPoint; AWidth, AHeight: Longint);
+begin
+  TopLeft := Origin;
+  Width := AWidth;
+  Height := AHeight;
+end;
+
+constructor TRect.Create(R: TRect; Normalize: Boolean);
+begin
+  Self := R;
+  if Normalize then
+    NormalizeRect;
+end;
+{$ENDIF}
+
+function TRect.CenterPoint: TPoint;
+begin
+  Result.X := (Right-Left) div 2 + Left;
+  Result.Y := (Bottom-Top) div 2 + Top;
+end;
+
+function TRect.Contains(Pt: TPoint): Boolean;
+begin
+  Result := (Left <= Pt.X) and (Pt.X <= Right) and (Top <= Pt.Y) and (Pt.Y <= Bottom);
+end;
+
+function TRect.Contains(R: TRect): Boolean;
+begin
+  Result := (Left <= R.Left) and (R.Right <= Right) and (Top <= R.Top) and (R.Bottom <= Bottom);
+end;
+
+class function TRect.Empty: TRect;
+begin
+  Result := TRect.Create(0,0,0,0);
+end;
+
 function TRect.getHeight: Longint;
 begin
   result:=bottom-top;
@@ -184,14 +303,80 @@ begin
   result:=right-left;
 end;
 
+procedure TRect.Inflate(DX, DY: Longint);
+begin
+  InflateRect(Self, DX, DY);
+end;
+
+procedure TRect.Intersect(R: TRect);
+begin
+  Self := Intersect(Self, R);
+end;
+
+class function TRect.Intersect(R1: TRect; R2: TRect): TRect;
+begin
+  IntersectRect(Result, R1, R2);
+end;
+
+function TRect.IntersectsWith(R: TRect): Boolean;
+begin
+  Result := (Left < R.Right) and (R.Left < Right) and (Top < R.Bottom) and (R.Top < Bottom);
+end;
+
+function TRect.IsEmpty: Boolean;
+begin
+  Result := (Right <= Left) or (Bottom <= Top);
+end;
+
+procedure TRect.NormalizeRect;
+var
+  x: LongInt;
+begin
+  if Top>Bottom then
+  begin
+    x := Top;
+    Top := Bottom;
+    Bottom := x;
+  end;
+  if Left>Right then
+  begin
+    x := Left;
+    Left := Right;
+    Right := x;
+  end
+end;
+
+procedure TRect.Inflate(DL, DT, DR, DB: Longint);
+begin
+  Dec(Left, DL);
+  Dec(Top, DT);
+  Inc(Right, DR);
+  Inc(Bottom, DB);
+end;
+
+procedure TRect.Offset(DX, DY: Longint);
+begin
+  OffsetRect(Self, DX, DY);
+end;
+
+procedure TRect.Offset(DP: TPoint);
+begin
+  OffsetRect(Self, DP.X, DP.Y);
+end;
+
 procedure TRect.setHeight(AValue: Longint);
 begin
   right:=left+avalue;
 end;
 
-procedure TRect.setLocation(AValue: TPoint);
+procedure TRect.SetLocation(X, Y: Longint);
 begin
-  top:=avalue.x; left:=avalue.y;
+  Offset(X-Left, Y-Top);
+end;
+
+procedure TRect.SetLocation(P: TPoint);
+begin
+  SetLocation(P.X, P.Y);
 end;
 
 procedure TRect.setSize(AValue: TSize);
@@ -205,4 +390,56 @@ begin
   bottom:=top+avalue;
 end;
 
+function TRect.SplitRect(SplitType: TSplitRectType; Percent: Double): TRect;
+begin
+  Result := Self;
+  case SplitType of
+    srLeft: Result.Right := Left + Trunc(Percent*Width);
+    srRight: Result.Left := Right - Trunc(Percent*Width);
+    srTop: Result.Bottom := Top + Trunc(Percent*Height);
+    srBottom: Result.Top := Bottom - Trunc(Percent*Height);
+  end;
+end;
+
+function TRect.SplitRect(SplitType: TSplitRectType; ASize: Longint): TRect;
+begin
+  Result := Self;
+  case SplitType of
+    srLeft: Result.Right := Left + ASize;
+    srRight: Result.Left := Right - ASize;
+    srTop: Result.Bottom := Top + ASize;
+    srBottom: Result.Top := Bottom - ASize;
+  end;
+end;
+
+class function TRect.Union(const Points: array of TPoint): TRect;
+var
+  i: Integer;
+begin
+  if Length(Points) > 0 then
+  begin
+    Result.TopLeft := Points[Low(Points)];
+    Result.BottomRight := Points[Low(Points)];
+
+    for i := Low(Points)+1 to High(Points) do
+    begin
+      if Points[i].X < Result.Left then Result.Left := Points[i].X;
+      if Points[i].X > Result.Right then Result.Right := Points[i].X;
+      if Points[i].Y < Result.Top then Result.Top := Points[i].Y;
+      if Points[i].Y > Result.Bottom then Result.Bottom := Points[i].Y;
+    end;
+  end else
+    Result := Empty;
+end;
+
+procedure TRect.Union(R: TRect);
+begin
+  Self := Union(Self, R);
+end;
+
+class function TRect.Union(R1, R2: TRect): TRect;
+begin
+  UnionRect(Result, R1, R2);
+end;
+
 

+ 45 - 1
rtl/inc/typshrdh.inc

@@ -87,6 +87,13 @@
      end;
   PPoint = ^TPoint;
 
+  TSplitRectType = (
+    srLeft,
+    srRight,
+    srTop,
+    srBottom
+  );
+
   { TRect }
 
   TRect =
@@ -100,10 +107,47 @@
        function  getSize: TSize;
        function  getWidth : Longint; inline;
        procedure setHeight(AValue: Longint);
-       procedure setLocation(AValue: TPoint);
        procedure setSize(AValue: TSize);
        procedure setWidth (AValue: Longint);
      public
+{$IFDEF VER3_0_0}
+       class function Create(Origin: TPoint): TRect; static; // empty rect at given origin
+       class function Create(Origin: TPoint; AWidth, AHeight: Longint): TRect; static;
+       class function Create(ALeft, ATop, ARight, ABottom: Longint): TRect; static;   
+       class function Create(P1, P2: TPoint; Normalize: Boolean = False): TRect; static;
+       class function Create(R: TRect; Normalize: Boolean = False): TRect; static;
+{$ELSE}       
+       constructor Create(Origin: TPoint); // empty rect at given origin
+       constructor Create(Origin: TPoint; AWidth, AHeight: Longint);
+       constructor Create(ALeft, ATop, ARight, ABottom: Longint);
+       constructor Create(P1, P2: TPoint; Normalize: Boolean = False);
+       constructor Create(R: TRect; Normalize: Boolean = False);
+{$ENDIF}       
+       class operator = (L, R: TRect): Boolean;
+       class operator <> (L, R: TRect): Boolean;
+       class operator + (L, R: TRect): TRect; // union
+       class operator * (L, R: TRect): TRect; // intersection
+       class function Empty: TRect; static;
+       procedure NormalizeRect;
+       function IsEmpty: Boolean;
+       function Contains(Pt: TPoint): Boolean;
+       function Contains(R: TRect): Boolean;
+       function IntersectsWith(R: TRect): Boolean;
+       class function Intersect(R1: TRect; R2: TRect): TRect; static;
+       procedure Intersect(R: TRect);
+       class function Union(R1, R2: TRect): TRect; static;
+       procedure Union(R: TRect);
+       class function Union(const Points: array of TPoint): TRect; static;
+       procedure Offset(DX, DY: Longint);
+       procedure Offset(DP: TPoint);
+       procedure SetLocation(X, Y: Longint);
+       procedure SetLocation(P: TPoint);
+       procedure Inflate(DX, DY: Longint);
+       procedure Inflate(DL, DT, DR, DB: Longint);
+       function CenterPoint: TPoint;
+       function SplitRect(SplitType: TSplitRectType; ASize: Longint): TRect;
+       function SplitRect(SplitType: TSplitRectType; Percent: Double): TRect;
+     public
        property Height: Longint read getHeight write setHeight;
        property Width : Longint read getWidth  write setWidth;
        property Size  : TSize   read getSize   write setSize;