@live-codes/pascal-wasm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +501 -0
  2. package/README.md +278 -0
  3. package/THIRD-PARTY-NOTICES.md +48 -0
  4. package/assets/pas2js.wasm +0 -0
  5. package/assets/rtl/Rtl.BrowserLoadHelper.pas +179 -0
  6. package/assets/rtl/browserconsole.pas +190 -0
  7. package/assets/rtl/classes.pas +11371 -0
  8. package/assets/rtl/js.pas +2211 -0
  9. package/assets/rtl/manifest.json +19 -0
  10. package/assets/rtl/math.pas +903 -0
  11. package/assets/rtl/p2jsres.pp +334 -0
  12. package/assets/rtl/rtl.js +1563 -0
  13. package/assets/rtl/rtlconsts.pas +97 -0
  14. package/assets/rtl/simplelinkedlist.pas +152 -0
  15. package/assets/rtl/system.pas +1166 -0
  16. package/assets/rtl/sysutils.pas +8959 -0
  17. package/assets/rtl/types.pas +2296 -0
  18. package/assets/rtl/typinfo.pas +1680 -0
  19. package/assets/rtl/web.pas +3586 -0
  20. package/assets/rtl/weborworker.pas +2101 -0
  21. package/dist/pascal-wasm.iife.min.js +6 -0
  22. package/dist/pascal-wasm.iife.min.js.map +7 -0
  23. package/package.json +54 -0
  24. package/src/assets.js +119 -0
  25. package/src/compiler.js +142 -0
  26. package/src/config.js +24 -0
  27. package/src/iife.js +27 -0
  28. package/src/index.js +130 -0
  29. package/src/vendor/browser_wasi_shim/debug.js +1 -0
  30. package/src/vendor/browser_wasi_shim/fd.js +1 -0
  31. package/src/vendor/browser_wasi_shim/fs_mem.js +1 -0
  32. package/src/vendor/browser_wasi_shim/fs_opfs.js +1 -0
  33. package/src/vendor/browser_wasi_shim/index.js +1 -0
  34. package/src/vendor/browser_wasi_shim/strace.js +1 -0
  35. package/src/vendor/browser_wasi_shim/wasi.js +1 -0
  36. package/src/vendor/browser_wasi_shim/wasi_defs.js +1 -0
  37. package/types/index.d.ts +89 -0
@@ -0,0 +1,2296 @@
1
+ {
2
+ This file is part of the Pas2JS run time library.
3
+ Copyright (c) 2018 by Mattias Gaertner
4
+
5
+ See the file COPYING.FPC, included in this distribution,
6
+ for details about the copyright.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
+
12
+ **********************************************************************}
13
+ {$IFNDEF FPC_DOTTEDUNITS}
14
+ unit Types;
15
+ {$ENDIF}
16
+
17
+ {$mode objfpc}
18
+ {$modeswitch advancedrecords}
19
+
20
+ interface
21
+
22
+ Type
23
+ Single = Double; // Avoid warning.
24
+
25
+ const
26
+ Epsilon: Single = 1E-40;
27
+ Epsilon2: Single = 1E-30;
28
+
29
+ cPI: Single = 3.141592654;
30
+ cPIdiv180: Single = 0.017453292;
31
+ cPIdiv2: Single = 1.570796326;
32
+ cPIdiv4: Single = 0.785398163;
33
+
34
+ type
35
+ RTLString = string; // Compatibility with FPC
36
+
37
+ THandle = NativeInt;
38
+ TDirection = (FromBeginning, FromEnd);
39
+
40
+ TBooleanDynArray = array of Boolean;
41
+ TWordDynArray = array of Word;
42
+ TIntegerDynArray = array of Integer;
43
+ TNativeIntDynArray = array of NativeInt;
44
+ TStringDynArray = array of String;
45
+ TDoubleDynArray = array of Double;
46
+ TSingleDynArray = TDoubleDynArray; //Avoid warning
47
+ TJSValueDynArray = array of JSValue;
48
+ TObjectDynArray = array of TObject;
49
+ TByteDynArray = array of Byte;
50
+
51
+ TSplitRectType = (
52
+ srLeft,
53
+ srRight,
54
+ srTop,
55
+ srBottom
56
+ );
57
+ TDuplicates = (dupIgnore, dupAccept, dupError);
58
+ TProc = Reference to Procedure;
59
+ TProcString = Reference to Procedure(Const aString : String);
60
+
61
+ TListCallback = procedure(data, arg: JSValue) of object;
62
+ TListStaticCallback = procedure(data, arg: JSValue);
63
+
64
+ TSize = record
65
+ cx : Longint; cy : Longint;
66
+ public
67
+ constructor Create(ax,ay:Longint); overload;
68
+ constructor Create(asz :TSize); overload;
69
+ function Add(const asz: TSize): TSize;
70
+ function Distance(const asz : TSize) : Double;
71
+ function IsZero : Boolean;
72
+ function Subtract(const asz : TSize): TSize;
73
+ (*
74
+ class operator = (const asz1, asz2 : TSize) : Boolean;
75
+ class operator <> (const asz1, asz2 : TSize): Boolean;
76
+ class operator + (const asz1, asz2 : TSize): TSize;
77
+ class operator - (const asz1, asz2 : TSize): TSize;
78
+ *)
79
+ property Width : Longint read cx write cx;
80
+ property Height: Longint read cy write cy;
81
+ end;
82
+
83
+ { TPoint }
84
+
85
+ TPoint =
86
+ {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
87
+ packed
88
+ {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
89
+ record
90
+ X : Longint; Y : Longint;
91
+ public
92
+ {$ifdef VER3}
93
+ constructor Create(ax,ay:Longint); overload;
94
+ constructor Create(apt :TPoint); overload;
95
+ {$endif}
96
+ class function Zero: TPoint; static; inline;
97
+ function Add(const apt: TPoint): TPoint;
98
+ function Distance(const apt: TPoint) : ValReal;
99
+ function IsZero : Boolean;
100
+ function Subtract(const apt : TPoint): TPoint;
101
+ procedure SetLocation(const apt :TPoint);
102
+ procedure SetLocation(ax,ay : Longint);
103
+ procedure Offset(const apt :TPoint);
104
+ procedure Offset(dx,dy : Longint);
105
+ function Angle(const pt : TPoint):Single;
106
+ class function PointInCircle(const apt, acenter: TPoint; const aradius: Integer): Boolean; static; inline;
107
+ (*
108
+ class operator = (const apt1, apt2 : TPoint) : Boolean; static;
109
+ class operator <> (const apt1, apt2 : TPoint): Boolean; static;
110
+ class operator + (const apt1, apt2 : TPoint): TPoint;static;
111
+ class operator - (const apt1, apt2 : TPoint): TPoint;static;
112
+ class operator := (const aspt : TSmallPoint) : TPoint;static;
113
+ class operator Explicit (Const apt : TPoint) : TSmallPoint;static;
114
+ *)
115
+ end;
116
+ PPoint = ^TPoint;
117
+
118
+ { TRect }
119
+
120
+ TRect =
121
+ {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
122
+ packed
123
+ {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
124
+ record
125
+ private
126
+ function GetBottomRight: TPoint;
127
+ function getHeight: Longint; inline;
128
+ function getLocation: TPoint;
129
+ function getSize: TSize;
130
+ function GetTopLeft: TPoint;
131
+ function getWidth : Longint; inline;
132
+ procedure SetBottomRight(const aValue: TPoint);
133
+ procedure setHeight(AValue: Longint);
134
+ procedure setSize(AValue: TSize);
135
+ procedure SetTopLeft(const aValue: TPoint);
136
+ procedure setWidth (AValue: Longint);
137
+ public
138
+ constructor Create(Origin: TPoint); // empty rect at given origin
139
+ constructor Create(Origin: TPoint; AWidth, AHeight: Longint);
140
+ constructor Create(ALeft, ATop, ARight, ABottom: Longint);
141
+ constructor Create(P1, P2: TPoint; Normalize: Boolean = False);
142
+ constructor Create(R: TRect; Normalize: Boolean = False);
143
+ (*
144
+ class operator = (L, R: TRect): Boolean; static;
145
+ class operator <> (L, R: TRect): Boolean; static;
146
+ class operator + (L, R: TRect): TRect; static; // union
147
+ class operator * (L, R: TRect): TRect; static; // intersection
148
+ *)
149
+ class function Empty: TRect; static;
150
+ procedure NormalizeRect;
151
+ function IsEmpty: Boolean;
152
+ function Contains(Pt: TPoint): Boolean;
153
+ function Contains(R: TRect): Boolean;
154
+ function IntersectsWith(R: TRect): Boolean;
155
+ class function Intersect(R1: TRect; R2: TRect): TRect; static;
156
+ procedure Intersect(R: TRect);
157
+ class function Union(R1, R2: TRect): TRect; static;
158
+ procedure Union(R: TRect);
159
+ class function Union(const Points: array of TPoint): TRect; static;
160
+ procedure Offset(DX, DY: Longint);
161
+ procedure Offset(DP: TPoint);
162
+ procedure SetLocation(X, Y: Longint);
163
+ procedure SetLocation(P: TPoint);
164
+ procedure Inflate(DX, DY: Longint);
165
+ procedure Inflate(DL, DT, DR, DB: Longint);
166
+ function CenterPoint: TPoint;
167
+ function SplitRect(SplitType: TSplitRectType; ASize: Longint): TRect;
168
+ function SplitRect(SplitType: TSplitRectType; Percent: Double): TRect;
169
+ public
170
+ Left,Top,Right,Bottom : Longint;
171
+ property Height: Longint read getHeight write setHeight;
172
+ property Width : Longint read getWidth write setWidth;
173
+ property Size : TSize read getSize write setSize;
174
+ property Location : TPoint read getLocation write setLocation;
175
+ property TopLeft : TPoint read GetTopLeft Write SetTopLeft;
176
+ property BottomRight : TPoint Read GetBottomRight Write SetBottomRight;
177
+ // 2: (Vector:TArray4IntegerType);
178
+ end;
179
+ PRect = ^TRect;
180
+
181
+ { TPointF }
182
+ PPointF = ^TPointF;
183
+ TPointF =
184
+ {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
185
+ packed
186
+ {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
187
+ record
188
+ x,y : Single;
189
+ public
190
+ function Add(const apt: TPoint): TPointF;
191
+ function Add(const apt: TPointF): TPointF;
192
+ function Distance(const apt : TPointF) : Single;
193
+ function DotProduct(const apt : TPointF) : Single;
194
+ function IsZero : Boolean;
195
+ function Subtract(const apt : TPointF): TPointF;
196
+ function Subtract(const apt : TPoint): TPointF;
197
+ procedure SetLocation(const apt :TPointF);
198
+ procedure SetLocation(const apt :TPoint);
199
+ procedure SetLocation(ax,ay : Single);
200
+ procedure Offset(const apt :TPointF);
201
+ procedure Offset(const apt :TPoint);
202
+ procedure Offset(dx,dy : Single);
203
+ function EqualsTo(const apt: TPointF; const aEpsilon : Single): Boolean; overload;
204
+ function EqualsTo(const apt: TPointF): Boolean; overload;
205
+
206
+ function Scale (afactor:Single) : TPointF;
207
+ function Ceiling : TPoint;
208
+ function Truncate: TPoint;
209
+ function Floor : TPoint;
210
+ function Round : TPoint;
211
+ function Length : Single;
212
+
213
+ function Rotate(angle: single): TPointF;
214
+ function Reflect(const normal: TPointF): TPointF;
215
+ function MidPoint(const b: TPointF): TPointF;
216
+ class function PointInCircle(const pt, center: TPointF; radius: single): Boolean; static;
217
+ class function PointInCircle(const pt, center: TPointF; radius: integer): Boolean; static;
218
+ class function Zero: TPointF; inline; static;
219
+ function Angle(const b: TPointF): Single;
220
+ function AngleCosine(const b: TPointF): single;
221
+ function CrossProduct(const apt: TPointF): Single;
222
+ function Normalize: TPointF;
223
+ function ToString(aSize,aDecimals : Byte) : RTLString; overload;
224
+ function ToString : RTLString; overload; inline;
225
+
226
+ class function Create(const ax, ay: Single): TPointF; overload; static; inline;
227
+ class function Create(const apt: TPoint): TPointF; overload; static; inline;
228
+ (*
229
+ class operator equals(const apt1, apt2 : TPointF) : Boolean; static;
230
+ class operator <> (const apt1, apt2 : TPointF): Boolean; static;
231
+ class operator + (const apt1, apt2 : TPointF): TPointF;static;
232
+ class operator - (const apt1, apt2 : TPointF): TPointF;static;
233
+ class operator - (const apt1 : TPointF): TPointF;static;
234
+ class operator * (const apt1, apt2: TPointF): TPointF;static;
235
+ class operator * (const apt1: TPointF; afactor: single): TPointF;static;
236
+ class operator * (afactor: single; const apt1: TPointF): TPointF;static;
237
+ class operator / (const apt1: TPointF; afactor: single): TPointF;static;
238
+ class operator := (const apt: TPoint): TPointF;static;
239
+ class operator ** (const apt1, apt2: TPointF): Single;static; // scalar product
240
+ *)
241
+ end;
242
+
243
+ { TSizeF }
244
+ PSizeF = ^TSizeF;
245
+ TSizeF =
246
+ {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
247
+ packed
248
+ {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
249
+ record
250
+ cx,cy : Single;
251
+ public
252
+ function Add(const asz: TSize): TSizeF;
253
+ function Add(const asz: TSizeF): TSizeF;
254
+ function Distance(const asz : TSizeF) : Single;
255
+ function IsZero : Boolean;
256
+ function Subtract(const asz : TSizeF): TSizeF;
257
+ function Subtract(const asz : TSize): TSizeF;
258
+ function SwapDimensions:TSizeF;
259
+
260
+ function Scale (afactor:Single) : TSizeF;
261
+ function Ceiling : TSize;
262
+ function Truncate: TSize;
263
+ function Floor : TSize;
264
+ function Round : TSize;
265
+ function Length : Single;
266
+ function ToString(aSize,aDecimals : Byte) : RTLString; overload;
267
+ function ToString : RTLString; overload; inline;
268
+
269
+ class function Create(const ax, ay: Single): TSizeF; overload; static; inline;
270
+ class function Create(const asz: TSize): TSizeF; overload; static; inline;
271
+ (*
272
+ class operator = (const asz1, asz2 : TSizeF) : Boolean;static;
273
+ class operator <> (const asz1, asz2 : TSizeF): Boolean;static;
274
+ class operator + (const asz1, asz2 : TSizeF): TSizeF;static;
275
+ class operator - (const asz1, asz2 : TSizeF): TSizeF;static;
276
+ class operator - (const asz1 : TSizeF): TSizeF;static;
277
+ class operator * (const asz1: TSizeF; afactor: single): TSizeF;static;
278
+ class operator * (afactor: single; const asz1: TSizeF): TSizeF;static;
279
+ class operator := (const apt: TPointF): TSizeF;static;
280
+ class operator := (const asz: TSize): TSizeF;static;
281
+ class operator := (const asz: TSizeF): TPointF;static;
282
+ *)
283
+ property Width: Single read cx write cx;
284
+ property Height: Single read cy write cy;
285
+ end;
286
+
287
+ {$SCOPEDENUMS ON}
288
+ TVertRectAlign = (Center, Top, Bottom);
289
+ THorzRectAlign = (Center, Left, Right);
290
+ {$SCOPEDENUMS OFF}
291
+
292
+ { TRectF }
293
+ PRectF = ^TRectF;
294
+ TRectF =
295
+ {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
296
+ packed
297
+ {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
298
+ record
299
+ private
300
+ function GetBottomRight: TPointF;
301
+ function GetLocation: TPointF;
302
+ function GetSize: TSizeF;
303
+ function GetTopLeft: TPointF;
304
+ procedure SetBottomRight(const aValue: TPointF);
305
+ procedure SetSize(AValue: TSizeF);
306
+ function GetHeight: Single; inline;
307
+ function GetWidth: Single; inline;
308
+ procedure SetHeight(AValue: Single);
309
+ procedure SetTopLeft(const aValue: TPointF);
310
+ procedure SetWidth (AValue: Single);
311
+ public
312
+ Left, Top, Right, Bottom: Single;
313
+ constructor Create(Origin: TPointF); // empty rect at given origin
314
+ constructor Create(Origin: TPointF; AWidth, AHeight: Single);
315
+ constructor Create(ALeft, ATop, ARight, ABottom: Single);
316
+ constructor Create(P1, P2: TPointF; Normalize: Boolean = False);
317
+ constructor Create(R: TRectF; Normalize: Boolean = False);
318
+ constructor Create(R: TRect; Normalize: Boolean = False);
319
+
320
+ (*
321
+ class operator = (L, R: TRectF): Boolean;static;
322
+ class operator <> (L, R: TRectF): Boolean;static;
323
+ class operator + (L, R: TRectF): TRectF; static;// union
324
+ class operator * (L, R: TRectF): TRectF; static;// intersection
325
+ class operator := (const arc: TRect): TRectF; static;
326
+ *)
327
+ class function Empty: TRectF; static;
328
+
329
+ class function Intersect(R1: TRectF; R2: TRectF): TRectF; static;
330
+ class function Union(const Points: array of TPointF): TRectF; static;
331
+ class function Union(R1, R2: TRectF): TRectF; static;
332
+ Function Ceiling : TRectF;
333
+ function CenterAt(const Dest: TRectF): TRectF;
334
+ function CenterPoint: TPointF;
335
+ function Contains(Pt: TPointF): Boolean;
336
+ function Contains(R: TRectF): Boolean;
337
+ function EqualsTo(const R: TRectF; const Epsilon: Single = 0): Boolean;
338
+ function Fit(const Dest: TRectF): Single; deprecated 'Use FitInto';
339
+ function FitInto(const Dest: TRectF): TRectF; overload;
340
+ function FitInto(const Dest: TRectF; out Ratio: Single): TRectF; overload;
341
+ function IntersectsWith(R: TRectF): Boolean;
342
+ function IsEmpty: Boolean;
343
+ function PlaceInto(const Dest: TRectF; const AHorzAlign: THorzRectAlign = THorzRectAlign.Center; const AVertAlign: TVertRectAlign = TVertRectAlign.Center): TRectF;
344
+ function Round: TRect;
345
+ function SnapToPixel(AScale: Single; APlaceBetweenPixels: Boolean = True): TRectF;
346
+ function Truncate: TRect;
347
+ procedure Inflate(DL, DT, DR, DB: Single);
348
+ procedure Inflate(DX, DY: Single);
349
+ procedure Intersect(R: TRectF);
350
+ procedure NormalizeRect;
351
+ procedure Offset (const dx,dy : Single); inline;
352
+ procedure Offset (DP: TPointF); inline;
353
+ procedure SetLocation(P: TPointF);
354
+ // procedure SetLocation(X, Y: Single);
355
+ function ToString(aSize,aDecimals : Byte; aUseSize : Boolean = False) : RTLString; overload;
356
+ function ToString(aUseSize : Boolean = False) : RTLString; overload; inline;
357
+ procedure Union (const r: TRectF); inline;
358
+ property Width : Single read GetWidth write SetWidth;
359
+ property Height : Single read GetHeight write SetHeight;
360
+ property Size : TSizeF read getSize write SetSize;
361
+ property Location: TPointF read getLocation write setLocation;
362
+ property TopLeft : TPointF Read GetTopLeft Write SetTopLeft;
363
+ property BottomRight : TPointF Read GetBottomRight Write SetBottomRight;
364
+ end;
365
+
366
+
367
+
368
+ { TPoint3D }
369
+
370
+ TPoint3D = record
371
+ Public
372
+ Type TSingle3Array = array[0..2] of single;
373
+
374
+ private
375
+ function GetSingle3Array: TSingle3Array;
376
+ procedure SetSingle3Array(const aValue: TSingle3Array);
377
+ public
378
+ constructor Create(const ax,ay,az:single);
379
+ procedure Offset(const adeltax,adeltay,adeltaz:single); inline;
380
+ procedure Offset(const adelta:TPoint3D); inline;
381
+ function ToString(aSize,aDecimals : Byte) : RTLString; overload;
382
+ function ToString : RTLString; overload; inline;
383
+ public
384
+ Property Data : TSingle3Array Read GetSingle3Array Write SetSingle3Array;
385
+ x,y,z : single;
386
+ end;
387
+
388
+
389
+ function EqualRect(const r1,r2 : TRect) : Boolean;
390
+ function EqualRect(const r1,r2 : TRectF) : Boolean;
391
+ function Rect(Left, Top, Right, Bottom : Integer) : TRect;
392
+ function RectF(Left,Top,Right,Bottom : Single) : TRectF; inline;
393
+ function Bounds(ALeft, ATop, AWidth, AHeight : Integer) : TRect;
394
+ function Point(x,y : Integer): TPoint; {$IFDEF Has_Inline}inline;{$ENDIF}
395
+ function PointF(x,y : single) : TPointF; {$IFDEF Has_Inline}inline;{$ENDIF}
396
+ function PtInRect(const aRect: TRect; const p: TPoint) : Boolean;
397
+ function IntersectRect(out aRect: TRect; const R1,R2: TRect) : Boolean;
398
+ function IntersectRect(const Rect1, Rect2: TRect): Boolean;
399
+ function IntersectRect(const Rect1, Rect2: TRectF): Boolean;
400
+ //function IntersectRect(var Rect : TRect; const R1,R2 : TRect) : Boolean;
401
+ function IntersectRect(var aRect : TRectF; const R1,R2 : TRectF) : Boolean;
402
+
403
+ function UnionRect(out aRect: TRect; const R1,R2: TRect) : Boolean;
404
+ function UnionRect(out aRectF: TRectF; const R1,R2: TRectF) : Boolean;
405
+ function UnionRect(const R1,R2 : TRect) : TRect;
406
+ function UnionRect(const R1,R2 : TRectF) : TRectF;
407
+
408
+ function IsRectEmpty(const aRect: TRect) : Boolean;
409
+ function OffsetRect(var aRect: TRect; DX, DY: Integer) : Boolean;
410
+ function OffsetRect(var aRect: TRectF; DX, DY: single) : Boolean;
411
+ function CenterPoint(const aRect: TRect): TPoint;
412
+ function InflateRect(var aRect: TRect; dx, dy: Integer): Boolean;
413
+ function Size(AWidth, AHeight: Integer): TSize;
414
+ function Size(const aRect: TRect): TSize;
415
+ function RectCenter(var R: TRect; const Bounds: TRect): TRect;
416
+ function RectCenter(var R: TRectF; const Bounds: TRectF): TRectF;
417
+
418
+ function NormalizeRectF(const Pts: array of TPointF): TRectF; overload;
419
+ function NormalizeRect(const ARect: TRectF): TRectF; overload;
420
+
421
+ function PtInRect(const Rect : TRectF; const p : TPointF) : Boolean;
422
+
423
+ function RectHeight(const Rect: TRect): Integer; inline;
424
+ function RectHeight(const Rect: TRectF): Single; inline;
425
+ function RectWidth(const Rect: TRect): Integer; inline;
426
+ function RectWidth(const Rect: TRectF): Single; inline;
427
+ function IsRectEmpty(const Rect : TRectF) : Boolean;
428
+ procedure MultiplyRect(var R: TRectF; const DX, DY: Single);
429
+ function InflateRect(var Rect: TRectF; dx: single; dy: Single): Boolean;
430
+ function Size(const ARect: TRectF): TSizeF; inline;
431
+ function ScalePoint(const P: TPointF; dX, dY: Single): TPointF; overload;
432
+ function ScalePoint(const P: TPoint; dX, dY: Single): TPoint; overload;
433
+ function MinPoint(const P1, P2: TPointF): TPointF; overload;
434
+ function MinPoint(const P1, P2: TPoint): TPoint; overload;
435
+ function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Size: Integer): TRect; overload;
436
+ function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Percent: Double): TRect; overload;
437
+ function CenteredRect(const SourceRect: TRect; const aCenteredRect: TRect): TRect;
438
+ function IntersectRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
439
+ function UnionRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
440
+
441
+
442
+ implementation
443
+
444
+ {$IFDEF FPC_DOTTEDUNITS}
445
+ uses System.Math;
446
+ {$ELSE FPC_DOTTEDUNITS}
447
+ uses math;
448
+ {$ENDIF FPC_DOTTEDUNITS}
449
+
450
+ function RectCenter(var R: TRect; const Bounds: TRect): TRect;
451
+
452
+ var
453
+ C : TPoint;
454
+ CS : TPoint;
455
+
456
+ begin
457
+ C:=Bounds.CenterPoint;
458
+ CS:=R.CenterPoint;
459
+ OffsetRect(R,C.X-CS.X,C.Y-CS.Y);
460
+ Result:=R;
461
+ end;
462
+
463
+ function RectCenter(var R: TRectF; const Bounds: TRectF): TRectF;
464
+
465
+ Var
466
+ C,CS : TPointF;
467
+
468
+ begin
469
+ C:=Bounds.CenterPoint;
470
+ CS:=R.CenterPoint;
471
+ OffsetRect(R,C.X-CS.X,C.Y-CS.Y);
472
+ Result:=R;
473
+ end;
474
+
475
+ function NormalizeRectF(const Pts: array of TPointF): TRectF;
476
+ var
477
+ Pt: TPointF;
478
+
479
+ begin
480
+ Result.Left:=$FFFF;
481
+ Result.Top:=$FFFF;
482
+ Result.Right:=-$FFFF;
483
+ Result.Bottom:=-$FFFF;
484
+ for Pt in Pts do
485
+ begin
486
+ Result.Left:=Min(Pt.X,Result.left);
487
+ Result.Top:=Min(Pt.Y,Result.Top);
488
+ Result.Right:=Max(Pt.X,Result.Right);
489
+ Result.Bottom:=Max(Pt.Y,Result.Bottom);
490
+ end;
491
+ end;
492
+
493
+ function NormalizeRect(const ARect: TRectF): TRectF;
494
+
495
+ begin
496
+ With aRect do
497
+ Result:=NormalizeRectF([PointF(Left,Top),
498
+ PointF(Right,Top),
499
+ PointF(Right,Bottom),
500
+ PointF(Left,Bottom)]);
501
+ end;
502
+
503
+ function PtInRect(const Rect: TRectF; const p: TPointF): Boolean;
504
+
505
+ begin
506
+ Result:=(p.y>=Rect.Top) and
507
+ (p.y<Rect.Bottom) and
508
+ (p.x>=Rect.Left) and
509
+ (p.x<Rect.Right);
510
+ end;
511
+
512
+ function RectHeight(const Rect: TRect): Integer;
513
+ begin
514
+ Result:=Rect.Height;
515
+ end;
516
+
517
+ function RectHeight(const Rect: TRectF): Single;
518
+ begin
519
+ Result:=Rect.Height;
520
+ end;
521
+
522
+ function RectWidth(const Rect: TRect): Integer;
523
+ begin
524
+ Result:=Rect.Width;
525
+
526
+ end;
527
+
528
+ function RectWidth(const Rect: TRectF): Single;
529
+ begin
530
+ Result:=Rect.Width;
531
+ end;
532
+
533
+ function IsRectEmpty(const Rect: TRectF): Boolean;
534
+ begin
535
+ Result:=Rect.IsEmpty;
536
+ end;
537
+
538
+ procedure MultiplyRect(var R: TRectF; const DX, DY: Single);
539
+ begin
540
+ R.Left:=DX*R.Left;
541
+ R.Right:=DX*R.Right;
542
+ R.Top:=DY*R.Top;
543
+ R.Bottom:=DY*R.Bottom;
544
+ end;
545
+
546
+ function InflateRect(var Rect: TRectF; dx: single; dy: Single): Boolean;
547
+ begin
548
+ Result:=True;
549
+ with Rect do
550
+ begin
551
+ Left:=Left-dx;
552
+ Top:=Top-dy;
553
+ Right:=Right+dx;
554
+ Bottom:=Bottom+dy;
555
+ end;
556
+ end;
557
+
558
+ function Size(const ARect: TRectF): TSizeF;
559
+ begin
560
+ Result.cx := ARect.Right - ARect.Left;
561
+ Result.cy := ARect.Bottom - ARect.Top;
562
+ end;
563
+
564
+ function ScalePoint(const P: TPointF; dX, dY: Single): TPointF;
565
+ begin
566
+ Result.X:=P.X*dX;
567
+ Result.Y:=P.Y*dY;
568
+ end;
569
+
570
+ function ScalePoint(const P: TPoint; dX, dY: Single): TPoint;
571
+ begin
572
+ Result.X:=Round(P.X*dX);
573
+ Result.Y:=Round(P.Y*dY);
574
+ end;
575
+
576
+ function MinPoint(const P1, P2: TPointF): TPointF;
577
+ begin
578
+ Result:=P1;
579
+ if (P2.Y<P1.Y)
580
+ or ((P2.Y=P1.Y) and (P2.X<P1.X)) then
581
+ Result:=P2;
582
+ end;
583
+
584
+ function MinPoint(const P1, P2: TPoint): TPoint;
585
+ begin
586
+ Result:=P1;
587
+ if (P2.Y<P1.Y)
588
+ or ((P2.Y=P1.Y) and (P2.X<P1.X)) then
589
+ Result:=P2;
590
+ end;
591
+
592
+ function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Size: Integer): TRect;
593
+ begin
594
+ Result:=Rect.SplitRect(SplitType,Size);
595
+ end;
596
+
597
+ function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Percent: Double): TRect;
598
+ begin
599
+ Result:=Rect.SplitRect(SplitType,Percent);
600
+ end;
601
+
602
+ function CenteredRect(const SourceRect: TRect; const aCenteredRect: TRect): TRect;
603
+ var
604
+ W,H: Integer;
605
+ Center : TPoint;
606
+ begin
607
+ W:=aCenteredRect.Width;
608
+ H:=aCenteredRect.Height;
609
+ Center:=SourceRect.CenterPoint;
610
+ With Center do
611
+ Result:= Rect(X-(W div 2),Y-(H div 2),X+((W+1) div 2),Y+((H+1) div 2));
612
+ end;
613
+
614
+ function IntersectRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
615
+ begin
616
+ Result:=IntersectRect(Rect,R1,R2);
617
+ end;
618
+
619
+ function UnionRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
620
+ begin
621
+ Result:=UnionRect(Rect,R1,R2);
622
+ end;
623
+
624
+ function EqualRect(const r1, r2: TRect): Boolean;
625
+ begin
626
+ Result:=(r1.left=r2.left) and (r1.right=r2.right) and (r1.top=r2.top) and (r1.bottom=r2.bottom);
627
+ end;
628
+
629
+ function EqualRect(const r1, r2: TRectF): Boolean;
630
+ begin
631
+ EqualRect:=r1.EqualsTo(r2);
632
+ end;
633
+
634
+ function Rect(Left, Top, Right, Bottom: Integer): TRect;
635
+ begin
636
+ Result.Left:=Left;
637
+ Result.Top:=Top;
638
+ Result.Right:=Right;
639
+ Result.Bottom:=Bottom;
640
+ end;
641
+
642
+ function RectF(Left,Top,Right,Bottom : Single) : TRectF; inline;
643
+
644
+ begin
645
+ Result.Left:=Left;
646
+ Result.Top:=Top;
647
+ Result.Right:=Right;
648
+ Result.Bottom:=Bottom;
649
+ end;
650
+
651
+
652
+ function Bounds(ALeft, ATop, AWidth, AHeight: Integer): TRect;
653
+ begin
654
+ Result.Left:=ALeft;
655
+ Result.Top:=ATop;
656
+ Result.Right:=ALeft+AWidth;
657
+ Result.Bottom:=ATop+AHeight;
658
+ end;
659
+
660
+ function Point(x, y: Integer): TPoint;
661
+ begin
662
+ Result.x:=x;
663
+ Result.y:=y;
664
+ end;
665
+
666
+ function PointF(x, y: single): TPointF;
667
+ begin
668
+ Result.X:=X;
669
+ Result.Y:=Y;
670
+ end;
671
+
672
+ function PtInRect(const aRect: TRect; const p: TPoint): Boolean;
673
+ begin
674
+ Result:=(p.y>=aRect.Top) and
675
+ (p.y<aRect.Bottom) and
676
+ (p.x>=aRect.Left) and
677
+ (p.x<aRect.Right);
678
+ end;
679
+
680
+ function IntersectRect(out aRect: TRect; const R1, R2: TRect): Boolean;
681
+ var
682
+ lRect: TRect;
683
+ begin
684
+ lRect := R1;
685
+ if R2.Left > R1.Left then
686
+ lRect.Left := R2.Left;
687
+ if R2.Top > R1.Top then
688
+ lRect.Top := R2.Top;
689
+ if R2.Right < R1.Right then
690
+ lRect.Right := R2.Right;
691
+ if R2.Bottom < R1.Bottom then
692
+ lRect.Bottom := R2.Bottom;
693
+
694
+ // The var parameter is only assigned in the end to avoid problems
695
+ // when passing the same rectangle in the var and const parameters.
696
+ if IsRectEmpty(lRect) then
697
+ begin
698
+ aRect:=Rect(0,0,0,0);
699
+ Result:=false;
700
+ end
701
+ else
702
+ begin
703
+ Result:=true;
704
+ aRect := lRect;
705
+ end;
706
+ end;
707
+
708
+ function IntersectRect(const Rect1, Rect2: TRect): Boolean;
709
+
710
+ begin
711
+ Result:=(Rect1.Left<Rect2.Right)
712
+ and (Rect1.Right>Rect2.Left)
713
+ and (Rect1.Top<Rect2.Bottom)
714
+ and (Rect1.Bottom>Rect2.Top);
715
+ end;
716
+
717
+ function IntersectRect(const Rect1, Rect2: TRectF): Boolean;
718
+ begin
719
+ Result:=(Rect1.Left<Rect2.Right)
720
+ and (Rect1.Right>Rect2.Left)
721
+ and (Rect1.Top<Rect2.Bottom)
722
+ and (Rect1.Bottom>Rect2.Top);
723
+ end;
724
+
725
+ function IntersectRect(var aRect: TRectF; const R1, R2: TRectF): Boolean;
726
+ var
727
+ lRect: TRectF;
728
+ begin
729
+ lRect := R1;
730
+ if R2.Left > R1.Left then
731
+ lRect.Left := R2.Left;
732
+ if R2.Top > R1.Top then
733
+ lRect.Top := R2.Top;
734
+ if R2.Right < R1.Right then
735
+ lRect.Right := R2.Right;
736
+ if R2.Bottom < R1.Bottom then
737
+ lRect.Bottom := R2.Bottom;
738
+
739
+ // The var parameter is only assigned in the end to avoid problems
740
+ // when passing the same rectangle in the var and const parameters.
741
+ if IsRectEmpty(lRect) then
742
+ begin
743
+ aRect:=RectF(0.0,0.0,0.0,0.0);
744
+ Result:=false;
745
+ end
746
+ else
747
+ begin
748
+ Result:=true;
749
+ aRect := lRect;
750
+ end;
751
+ end;
752
+
753
+ function UnionRect(out aRect: TRect; const R1, R2: TRect): Boolean;
754
+ var
755
+ lRect: TRect;
756
+ begin
757
+ lRect:=R1;
758
+ if R2.Left<R1.Left then
759
+ lRect.Left:=R2.Left;
760
+ if R2.Top<R1.Top then
761
+ lRect.Top:=R2.Top;
762
+ if R2.Right>R1.Right then
763
+ lRect.Right:=R2.Right;
764
+ if R2.Bottom>R1.Bottom then
765
+ lRect.Bottom:=R2.Bottom;
766
+
767
+ if IsRectEmpty(lRect) then
768
+ begin
769
+ aRect:=Rect(0,0,0,0);
770
+ Result:=false;
771
+ end
772
+ else
773
+ begin
774
+ aRect:=lRect;
775
+ Result:=true;
776
+ end;
777
+ end;
778
+
779
+ function UnionRect(out aRectF: TRectF; const R1, R2: TRectF): Boolean;
780
+ var
781
+ lRect: TRectF;
782
+ begin
783
+ lRect:=R1;
784
+ if R2.Left<R1.Left then
785
+ lRect.Left:=R2.Left;
786
+ if R2.Top<R1.Top then
787
+ lRect.Top:=R2.Top;
788
+ if R2.Right>R1.Right then
789
+ lRect.Right:=R2.Right;
790
+ if R2.Bottom>R1.Bottom then
791
+ lRect.Bottom:=R2.Bottom;
792
+
793
+ if IsRectEmpty(lRect) then
794
+ begin
795
+ aRectF:=RectF(0.0,0.0,0.0,0.0);
796
+ Result:=false;
797
+ end
798
+ else
799
+ begin
800
+ aRectF:=lRect;
801
+ Result:=true;
802
+ end;
803
+ end;
804
+
805
+ function UnionRect(const R1, R2: TRect): TRect;
806
+ begin
807
+ Result:=Default(TRect);
808
+ UnionRect(Result,R1,R2);
809
+ end;
810
+
811
+ function UnionRect(const R1, R2: TRectF): TRectF;
812
+ begin
813
+ Result:=Default(TRectF);
814
+ UnionRect(Result,R1,R2);
815
+ end;
816
+
817
+ function IsRectEmpty(const aRect: TRect): Boolean;
818
+ begin
819
+ Result:=(aRect.Right<=aRect.Left) or (aRect.Bottom<=aRect.Top);
820
+ end;
821
+
822
+ function OffsetRect(var aRect: TRectF; DX, DY: single) : Boolean;
823
+
824
+ begin
825
+ with aRect do
826
+ begin
827
+ Left:=Left+dx;
828
+ Top:=Top+dy;
829
+ Right:=Right+dx;
830
+ Bottom:=Bottom+dy;
831
+ end;
832
+ Result:=true;
833
+ end;
834
+
835
+ function OffsetRect(var aRect: TRect; DX, DY: Integer): Boolean;
836
+ begin
837
+ with aRect do
838
+ begin
839
+ inc(Left,dx);
840
+ inc(Top,dy);
841
+ inc(Right,dx);
842
+ inc(Bottom,dy);
843
+ end;
844
+ Result:=true;
845
+ end;
846
+
847
+ function CenterPoint(const aRect: TRect): TPoint;
848
+
849
+ function Avg(a, b: Longint): Longint;
850
+ begin
851
+ if a < b then
852
+ Result := a + ((b - a) shr 1)
853
+ else
854
+ Result := b + ((a - b) shr 1);
855
+ end;
856
+
857
+ begin
858
+ with aRect do
859
+ begin
860
+ Result.X := Avg(Left, Right);
861
+ Result.Y := Avg(Top, Bottom);
862
+ end;
863
+ end;
864
+
865
+ function InflateRect(var aRect: TRect; dx, dy: Integer): Boolean;
866
+ begin
867
+ with aRect do
868
+ begin
869
+ dec(Left, dx);
870
+ dec(Top, dy);
871
+ inc(Right, dx);
872
+ inc(Bottom, dy);
873
+ end;
874
+ Result := True;
875
+ end;
876
+
877
+ function Size(AWidth, AHeight: Integer): TSize;
878
+ begin
879
+ Result.cx := AWidth;
880
+ Result.cy := AHeight;
881
+ end;
882
+
883
+ function Size(const aRect: TRect): TSize;
884
+ begin
885
+ Result.cx := aRect.Right - aRect.Left;
886
+ Result.cy := aRect.Bottom - aRect.Top;
887
+ end;
888
+
889
+ { TPointF}
890
+
891
+ Function SingleToStr(aValue : Single; aSize,aDecimals : Byte) : String; inline;
892
+
893
+ var
894
+ S : String;
895
+ Len,P : Byte;
896
+
897
+ begin
898
+ Str(aValue:aSize:aDecimals,S);
899
+ Len:=Length(S);
900
+ P:=1;
901
+ While (P<=Len) and (S[P]=' ') do
902
+ Inc(P);
903
+ if P>1 then
904
+ Delete(S,1,P-1);
905
+ Result:=S;
906
+ end;
907
+
908
+ { TRect }
909
+
910
+ { TRect }
911
+
912
+ (*
913
+ class operator TRect. * (L, R: TRect): TRect;
914
+ begin
915
+ Result := TRect.Intersect(L, R);
916
+ end;
917
+
918
+ class operator TRect. + (L, R: TRect): TRect;
919
+ begin
920
+ Result := TRect.Union(L, R);
921
+ end;
922
+
923
+ class operator TRect. <> (L, R: TRect): Boolean;
924
+ begin
925
+ Result := not(L=R);
926
+ end;
927
+
928
+ class operator TRect. = (L, R: TRect): Boolean;
929
+ begin
930
+ Result :=
931
+ (L.Left = R.Left) and (L.Right = R.Right) and
932
+ (L.Top = R.Top) and (L.Bottom = R.Bottom);
933
+ end;
934
+ *)
935
+ constructor TRect.Create(ALeft, ATop, ARight, ABottom: Longint);
936
+ begin
937
+ Left := ALeft;
938
+ Top := ATop;
939
+ Right := ARight;
940
+ Bottom := ABottom;
941
+ end;
942
+
943
+ constructor TRect.Create(P1, P2: TPoint; Normalize: Boolean);
944
+ begin
945
+ TopLeft := P1;
946
+ BottomRight := P2;
947
+ if Normalize then
948
+ NormalizeRect;
949
+ end;
950
+
951
+ constructor TRect.Create(Origin: TPoint);
952
+ begin
953
+ TopLeft := Origin;
954
+ BottomRight := Origin;
955
+ end;
956
+
957
+ constructor TRect.Create(Origin: TPoint; AWidth, AHeight: Longint);
958
+ begin
959
+ TopLeft := Origin;
960
+ Width := AWidth;
961
+ Height := AHeight;
962
+ end;
963
+
964
+ constructor TRect.Create(R: TRect; Normalize: Boolean);
965
+ begin
966
+ Self := R;
967
+ if Normalize then
968
+ NormalizeRect;
969
+ end;
970
+
971
+ function TRect.CenterPoint: TPoint;
972
+ begin
973
+ Result.X := (Right-Left) div 2 + Left;
974
+ Result.Y := (Bottom-Top) div 2 + Top;
975
+ end;
976
+
977
+ function TRect.Contains(Pt: TPoint): Boolean;
978
+ begin
979
+ Result := (Left <= Pt.X) and (Pt.X < Right) and (Top <= Pt.Y) and (Pt.Y < Bottom);
980
+ end;
981
+
982
+ function TRect.Contains(R: TRect): Boolean;
983
+ begin
984
+ Result := (Left <= R.Left) and (R.Right <= Right) and (Top <= R.Top) and (R.Bottom <= Bottom);
985
+ end;
986
+
987
+ class function TRect.Empty: TRect;
988
+ begin
989
+ Result := TRect.Create(0,0,0,0);
990
+ end;
991
+
992
+ function TRect.GetBottomRight: TPoint;
993
+ begin
994
+ Result:=Point(Right,Bottom);
995
+ end;
996
+
997
+ function TRect.getHeight: Longint;
998
+ begin
999
+ result:=bottom-top;
1000
+ end;
1001
+
1002
+ function TRect.getLocation: TPoint;
1003
+ begin
1004
+ result.x:=Left; result.y:=top;
1005
+ end;
1006
+
1007
+ function TRect.getSize: TSize;
1008
+ begin
1009
+ result.cx:=width; result.cy:=height;
1010
+ end;
1011
+
1012
+ function TRect.GetTopLeft: TPoint;
1013
+ begin
1014
+ Result:=Point(Left,Top);
1015
+ end;
1016
+
1017
+ function TRect.getWidth: Longint;
1018
+ begin
1019
+ result:=right-left;
1020
+ end;
1021
+
1022
+ procedure TRect.SetBottomRight(const aValue: TPoint);
1023
+ begin
1024
+ Bottom:=aValue.Y;
1025
+ Right:=aValue.X;
1026
+ end;
1027
+
1028
+ procedure TRect.Inflate(DX, DY: Longint);
1029
+ begin
1030
+ InflateRect(Self, DX, DY);
1031
+ end;
1032
+
1033
+ procedure TRect.Intersect(R: TRect);
1034
+ begin
1035
+ Self := Intersect(Self, R);
1036
+ end;
1037
+
1038
+ class function TRect.Intersect(R1: TRect; R2: TRect): TRect;
1039
+ begin
1040
+ IntersectRect(Result, R1, R2);
1041
+ end;
1042
+
1043
+ function TRect.IntersectsWith(R: TRect): Boolean;
1044
+ begin
1045
+ Result := (Left < R.Right) and (R.Left < Right) and (Top < R.Bottom) and (R.Top < Bottom);
1046
+ end;
1047
+
1048
+ function TRect.IsEmpty: Boolean;
1049
+ begin
1050
+ Result := (Right <= Left) or (Bottom <= Top);
1051
+ end;
1052
+
1053
+ procedure TRect.NormalizeRect;
1054
+ var
1055
+ x: LongInt;
1056
+ begin
1057
+ if Top>Bottom then
1058
+ begin
1059
+ x := Top;
1060
+ Top := Bottom;
1061
+ Bottom := x;
1062
+ end;
1063
+ if Left>Right then
1064
+ begin
1065
+ x := Left;
1066
+ Left := Right;
1067
+ Right := x;
1068
+ end
1069
+ end;
1070
+
1071
+ procedure TRect.Inflate(DL, DT, DR, DB: Longint);
1072
+ begin
1073
+ Dec(Left, DL);
1074
+ Dec(Top, DT);
1075
+ Inc(Right, DR);
1076
+ Inc(Bottom, DB);
1077
+ end;
1078
+
1079
+ procedure TRect.Offset(DX, DY: Longint);
1080
+ begin
1081
+ OffsetRect(Self, DX, DY);
1082
+ end;
1083
+
1084
+ procedure TRect.Offset(DP: TPoint);
1085
+ begin
1086
+ OffsetRect(Self, DP.X, DP.Y);
1087
+ end;
1088
+
1089
+ procedure TRect.setHeight(AValue: Longint);
1090
+ begin
1091
+ bottom:=top+avalue;
1092
+ end;
1093
+
1094
+ procedure TRect.SetLocation(X, Y: Longint);
1095
+ begin
1096
+ Offset(X-Left, Y-Top);
1097
+ end;
1098
+
1099
+ procedure TRect.SetLocation(P: TPoint);
1100
+ begin
1101
+ SetLocation(P.X, P.Y);
1102
+ end;
1103
+
1104
+ procedure TRect.setSize(AValue: TSize);
1105
+ begin
1106
+ bottom:=top+avalue.cy;
1107
+ right:=left+avalue.cx;
1108
+ end;
1109
+
1110
+ procedure TRect.SetTopLeft(const aValue: TPoint);
1111
+ begin
1112
+ Top:=aValue.y;
1113
+ Left:=aValue.x;
1114
+ end;
1115
+
1116
+ procedure TRect.setWidth(AValue: Longint);
1117
+ begin
1118
+ right:=left+avalue;
1119
+ end;
1120
+
1121
+ function TRect.SplitRect(SplitType: TSplitRectType; Percent: Double): TRect;
1122
+ begin
1123
+ Result := Self;
1124
+ case SplitType of
1125
+ srLeft: Result.Right := Left + Trunc(Percent*Width);
1126
+ srRight: Result.Left := Right - Trunc(Percent*Width);
1127
+ srTop: Result.Bottom := Top + Trunc(Percent*Height);
1128
+ srBottom: Result.Top := Bottom - Trunc(Percent*Height);
1129
+ end;
1130
+ end;
1131
+
1132
+ function TRect.SplitRect(SplitType: TSplitRectType; ASize: Longint): TRect;
1133
+ begin
1134
+ Result := Self;
1135
+ case SplitType of
1136
+ srLeft: Result.Right := Left + ASize;
1137
+ srRight: Result.Left := Right - ASize;
1138
+ srTop: Result.Bottom := Top + ASize;
1139
+ srBottom: Result.Top := Bottom - ASize;
1140
+ end;
1141
+ end;
1142
+
1143
+ class function TRect.Union(const Points: array of TPoint): TRect;
1144
+ var
1145
+ i: Integer;
1146
+ begin
1147
+ if Length(Points) > 0 then
1148
+ begin
1149
+ Result.TopLeft := Points[Low(Points)];
1150
+ Result.BottomRight := Points[Low(Points)];
1151
+
1152
+ for i := Low(Points)+1 to High(Points) do
1153
+ begin
1154
+ if Points[i].X < Result.Left then Result.Left := Points[i].X;
1155
+ if Points[i].X > Result.Right then Result.Right := Points[i].X;
1156
+ if Points[i].Y < Result.Top then Result.Top := Points[i].Y;
1157
+ if Points[i].Y > Result.Bottom then Result.Bottom := Points[i].Y;
1158
+ end;
1159
+ end else
1160
+ Result := Empty;
1161
+ end;
1162
+
1163
+ procedure TRect.Union(R: TRect);
1164
+ begin
1165
+ Self := Union(Self, R);
1166
+ end;
1167
+
1168
+ class function TRect.Union(R1, R2: TRect): TRect;
1169
+ begin
1170
+ UnionRect(Result, R1, R2);
1171
+ end;
1172
+
1173
+ { TPointF}
1174
+
1175
+ function TPointF.ToString : RTLString;
1176
+
1177
+ begin
1178
+ Result:=ToString(8,2);
1179
+ end;
1180
+
1181
+ function TPointF.ToString(aSize,aDecimals : Byte) : RTLString;
1182
+
1183
+ var
1184
+ Sx,Sy : string;
1185
+
1186
+ begin
1187
+ Sx:=SingleToStr(X,aSize,aDecimals);
1188
+ Sy:=SingleToStr(Y,aSize,aDecimals);
1189
+ Result:='('+Sx+','+Sy+')';
1190
+ end;
1191
+
1192
+ function TPointF.Add(const apt: TPoint): TPointF;
1193
+ begin
1194
+ result.x:=x+apt.x;
1195
+ result.y:=y+apt.y;
1196
+ end;
1197
+
1198
+ function TPointF.Add(const apt: TPointF): TPointF;
1199
+ begin
1200
+ result.x:=x+apt.x;
1201
+ result.y:=y+apt.y;
1202
+ end;
1203
+
1204
+ function TPointF.Subtract(const apt : TPointF): TPointF;
1205
+ begin
1206
+ result.x:=x-apt.x;
1207
+ result.y:=y-apt.y;
1208
+ end;
1209
+
1210
+ function TPointF.Subtract(const apt: TPoint): TPointF;
1211
+ begin
1212
+ result.x:=x-apt.x;
1213
+ result.y:=y-apt.y;
1214
+ end;
1215
+
1216
+ function TPointF.Distance(const apt : TPointF) : Single;
1217
+ begin
1218
+ result:=sqrt(sqr(apt.x-x)+sqr(apt.y-y));
1219
+ end;
1220
+
1221
+ function TPointF.DotProduct(const apt: TPointF): Single;
1222
+ begin
1223
+ result:=x*apt.x+y*apt.y;
1224
+ end;
1225
+
1226
+ function TPointF.IsZero : Boolean;
1227
+ begin
1228
+ result:=SameValue(x,0.0) and SameValue(y,0.0);
1229
+ end;
1230
+
1231
+ procedure TPointF.Offset(const apt :TPointF);
1232
+ begin
1233
+ x:=x+apt.x;
1234
+ y:=y+apt.y;
1235
+ end;
1236
+
1237
+ procedure TPointF.Offset(const apt: TPoint);
1238
+ begin
1239
+ x:=x+apt.x;
1240
+ y:=y+apt.y;
1241
+ end;
1242
+
1243
+ procedure TPointF.Offset(dx,dy : Single);
1244
+ begin
1245
+ x:=x+dx;
1246
+ y:=y+dy;
1247
+ end;
1248
+
1249
+ function TPointF.EqualsTo(const apt: TPointF): Boolean;
1250
+
1251
+ begin
1252
+ Result:=EqualsTo(apt,0);
1253
+ end;
1254
+
1255
+ function TPointF.EqualsTo(const apt: TPointF; const aEpsilon: Single): Boolean;
1256
+
1257
+ function Eq(a,b : single) : boolean; inline;
1258
+
1259
+ begin
1260
+ result:=abs(a-b)<=aEpsilon;
1261
+ end;
1262
+
1263
+ begin
1264
+ Result:=Eq(X,apt.X) and Eq(Y,apt.Y);
1265
+ end;
1266
+
1267
+ function TPointF.Scale(afactor: Single): TPointF;
1268
+ begin
1269
+ result.x:=afactor*x;
1270
+ result.y:=afactor*y;
1271
+ end;
1272
+
1273
+ function TPointF.Ceiling: TPoint;
1274
+ begin
1275
+ result.x:=ceil(x);
1276
+ result.y:=ceil(y);
1277
+ end;
1278
+
1279
+ function TPointF.Truncate: TPoint;
1280
+ begin
1281
+ result.x:=trunc(x);
1282
+ result.y:=trunc(y);
1283
+ end;
1284
+
1285
+ function TPointF.Floor: TPoint;
1286
+ begin
1287
+ result.x:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(x);
1288
+ result.y:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(y);
1289
+ end;
1290
+
1291
+ function TPointF.Round: TPoint;
1292
+ begin
1293
+ result.x:=System.round(x);
1294
+ result.y:=System.round(y);
1295
+ end;
1296
+
1297
+ function TPointF.Length: Single;
1298
+ begin
1299
+ result:=sqrt(sqr(x)+sqr(y));
1300
+ end;
1301
+
1302
+ function TPointF.Rotate(angle: single): TPointF;
1303
+ var
1304
+ sina, cosa: single;
1305
+ begin
1306
+ sincos(angle, sina, cosa);
1307
+ result.x := x * cosa - y * sina;
1308
+ result.y := x * sina + y * cosa;
1309
+ end;
1310
+
1311
+ function TPointF.Reflect(const normal: TPointF): TPointF;
1312
+ var
1313
+ lCross : single;
1314
+ lTmp : TPointF;
1315
+
1316
+ begin
1317
+ //result := self + (-2 * normal ** self) * normal;
1318
+ lCross:=x*normal.x + y*normal.y;
1319
+ lCross:=lCross * (-2);
1320
+ lTmp.x:=normal.x*lCross;
1321
+ lTmp.y:=normal.y*lCross;
1322
+ Result.X:=X+lTmp.x;
1323
+ Result.Y:=Y+lTmp.Y;
1324
+ end;
1325
+
1326
+ function TPointF.MidPoint(const b: TPointF): TPointF;
1327
+ begin
1328
+ result.x := 0.5 * (x + b.x);
1329
+ result.y := 0.5 * (y + b.y);
1330
+ end;
1331
+
1332
+ class function TPointF.Zero: TPointF;
1333
+
1334
+ begin
1335
+ Result.X:=0;
1336
+ Result.Y:=0;
1337
+ end;
1338
+
1339
+ class function TPointF.PointInCircle(const pt, center: TPointF; radius: single): Boolean;
1340
+ begin
1341
+ result := sqr(center.x - pt.x) + sqr(center.y - pt.y) < sqr(radius);
1342
+ end;
1343
+
1344
+ class function TPointF.PointInCircle(const pt, center: TPointF; radius: integer): Boolean;
1345
+ begin
1346
+ result := sqr(center.x - pt.x) + sqr(center.y - pt.y) < sqr(single(radius));
1347
+ end;
1348
+
1349
+ function TPointF.Angle(const b: TPointF): Single;
1350
+ begin
1351
+ result := ArcTan2(y - b.y, x - b.x);
1352
+ end;
1353
+
1354
+ function TPointF.AngleCosine(const b: TPointF): single;
1355
+ var
1356
+ lCross : single;
1357
+ begin
1358
+ lCross:=x*b.x + y*b.y;
1359
+ result := EnsureRange(lCross / sqrt((sqr(x) + sqr(y)) * (sqr(b.x) + sqr(b.y))), -1, 1);
1360
+ end;
1361
+
1362
+ (*
1363
+ class operator TPointF.= (const apt1, apt2 : TPointF) : Boolean; static;
1364
+ begin
1365
+ result:=SameValue(apt1.x,apt2.x) and SameValue(apt1.y,apt2.y);
1366
+ end;
1367
+
1368
+ class operator TPointF.<> (const apt1, apt2 : TPointF): Boolean;
1369
+ begin
1370
+ result:=NOT (SameValue(apt1.x,apt2.x) and Samevalue(apt1.y,apt2.y));
1371
+ end;
1372
+
1373
+ class operator TPointF. * (const apt1, apt2: TPointF): TPointF;
1374
+ begin
1375
+ result.x:=apt1.x*apt2.x;
1376
+ result.y:=apt1.y*apt2.y;
1377
+ end;
1378
+
1379
+ class operator TPointF. * (afactor: single; const apt1: TPointF): TPointF;
1380
+ begin
1381
+ result:=apt1.Scale(afactor);
1382
+ end;
1383
+
1384
+ class operator TPointF. * (const apt1: TPointF; afactor: single): TPointF;
1385
+ begin
1386
+ result:=apt1.Scale(afactor);
1387
+ end;
1388
+
1389
+ class operator TPointF. ** (const apt1, apt2: TPointF): Single;
1390
+ begin
1391
+ result:=apt1.x*apt2.x + apt1.y*apt2.y;
1392
+ end;
1393
+
1394
+ class operator TPointF.+ (const apt1, apt2 : TPointF): TPointF;
1395
+ begin
1396
+ result.x:=apt1.x+apt2.x;
1397
+ result.y:=apt1.y+apt2.y;
1398
+ end;
1399
+
1400
+ class operator TPointF.- (const apt1, apt2 : TPointF): TPointF;
1401
+ begin
1402
+ result.x:=apt1.x-apt2.x;
1403
+ result.y:=apt1.y-apt2.y;
1404
+ end;
1405
+
1406
+ class operator TPointF. - (const apt1: TPointF): TPointF;
1407
+ begin
1408
+ Result.x:=-apt1.x;
1409
+ Result.y:=-apt1.y;
1410
+ end;
1411
+
1412
+ class operator TPointF. / (const apt1: TPointF; afactor: single): TPointF;
1413
+ begin
1414
+ result:=apt1.Scale(1/afactor);
1415
+ end;
1416
+
1417
+ class operator TPointF. := (const apt: TPoint): TPointF;
1418
+ begin
1419
+ Result.x:=apt.x;
1420
+ Result.y:=apt.y;
1421
+ end;
1422
+ *)
1423
+ procedure TPointF.SetLocation(const apt :TPointF);
1424
+ begin
1425
+ x:=apt.x; y:=apt.y;
1426
+ end;
1427
+
1428
+ procedure TPointF.SetLocation(const apt: TPoint);
1429
+ begin
1430
+ x:=apt.x; y:=apt.y;
1431
+ end;
1432
+
1433
+ procedure TPointF.SetLocation(ax,ay : Single);
1434
+ begin
1435
+ x:=ax; y:=ay;
1436
+ end;
1437
+
1438
+ class function TPointF.Create(const ax, ay: Single): TPointF;
1439
+ begin
1440
+ Result.x := ax;
1441
+ Result.y := ay;
1442
+ end;
1443
+
1444
+ class function TPointF.Create(const apt: TPoint): TPointF;
1445
+ begin
1446
+ Result.x := apt.X;
1447
+ Result.y := apt.Y;
1448
+ end;
1449
+
1450
+
1451
+ function TPointF.CrossProduct(const apt: TPointF): Single;
1452
+ begin
1453
+ Result:=X*apt.Y-Y*apt.X;
1454
+ end;
1455
+
1456
+ function TPointF.Normalize: TPointF;
1457
+
1458
+ var
1459
+ L: Single;
1460
+
1461
+ begin
1462
+ L:=Sqrt(Sqr(X)+Sqr(Y));
1463
+ if SameValue(L,0,Epsilon) then
1464
+ Result:=Self
1465
+ else
1466
+ begin
1467
+ Result.X:=X/L;
1468
+ Result.Y:=Y/L;
1469
+ end;
1470
+ end;
1471
+
1472
+
1473
+ { TSizeF }
1474
+
1475
+ function TSizeF.ToString(aSize,aDecimals : Byte) : RTLString;
1476
+
1477
+ var
1478
+ Sx,Sy : string;
1479
+
1480
+ begin
1481
+ Sx:=SingleToStr(cx,aSize,aDecimals);
1482
+ Sy:=SingleToStr(cy,aSize,aDecimals);
1483
+ Result:='('+Sx+'x'+Sy+')';
1484
+ end;
1485
+
1486
+ function TSizeF.ToString : RTLString;
1487
+
1488
+ begin
1489
+ Result:=ToString(8,2);
1490
+ end;
1491
+
1492
+
1493
+
1494
+ function TSizeF.Add(const asz: TSize): TSizeF;
1495
+ begin
1496
+ result.cx:=cx+asz.cx;
1497
+ result.cy:=cy+asz.cy;
1498
+ end;
1499
+
1500
+ function TSizeF.Add(const asz: TSizeF): TSizeF;
1501
+ begin
1502
+ result.cx:=cx+asz.cx;
1503
+ result.cy:=cy+asz.cy;
1504
+ end;
1505
+
1506
+ function TSizeF.Subtract(const asz : TSizeF): TSizeF;
1507
+ begin
1508
+ result.cx:=cx-asz.cx;
1509
+ result.cy:=cy-asz.cy;
1510
+ end;
1511
+
1512
+ function TSizeF.SwapDimensions:TSizeF;
1513
+ begin
1514
+ result.cx:=cy;
1515
+ result.cy:=cx;
1516
+ end;
1517
+
1518
+ function TSizeF.Subtract(const asz: TSize): TSizeF;
1519
+ begin
1520
+ result.cx:=cx-asz.cx;
1521
+ result.cy:=cy-asz.cy;
1522
+ end;
1523
+
1524
+ function TSizeF.Distance(const asz : TSizeF) : Single;
1525
+ begin
1526
+ result:=sqrt(sqr(asz.cx-cx)+sqr(asz.cy-cy));
1527
+ end;
1528
+
1529
+ function TSizeF.IsZero : Boolean;
1530
+ begin
1531
+ result:=SameValue(cx,0.0) and SameValue(cy,0.0);
1532
+ end;
1533
+
1534
+ function TSizeF.Scale(afactor: Single): TSizeF;
1535
+ begin
1536
+ result.cx:=afactor*cx;
1537
+ result.cy:=afactor*cy;
1538
+ end;
1539
+
1540
+ function TSizeF.Ceiling: TSize;
1541
+ begin
1542
+ result.cx:=ceil(cx);
1543
+ result.cy:=ceil(cy);
1544
+ end;
1545
+
1546
+ function TSizeF.Truncate: TSize;
1547
+ begin
1548
+ result.cx:=trunc(cx);
1549
+ result.cy:=trunc(cy);
1550
+ end;
1551
+
1552
+ function TSizeF.Floor: TSize;
1553
+ begin
1554
+ result.cx:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(cx);
1555
+ result.cy:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(cy);
1556
+ end;
1557
+
1558
+ function TSizeF.Round: TSize;
1559
+ begin
1560
+ result.cx:=System.round(cx);
1561
+ result.cy:=System.round(cy);
1562
+ end;
1563
+
1564
+ function TSizeF.Length: Single;
1565
+ begin //distance(self) ?
1566
+ result:=sqrt(sqr(cx)+sqr(cy));
1567
+ end;
1568
+
1569
+ (*
1570
+ class operator TSizeF.= (const asz1, asz2 : TSizeF) : Boolean;
1571
+ begin
1572
+ result:=SameValue(asz1.cx,asz2.cx) and SameValue(asz1.cy,asz2.cy);
1573
+ end;
1574
+
1575
+ class operator TSizeF.<> (const asz1, asz2 : TSizeF): Boolean;
1576
+ begin
1577
+ result:=NOT (SameValue(asz1.cx,asz2.cx) and Samevalue(asz1.cy,asz2.cy));
1578
+ end;
1579
+
1580
+ class operator TSizeF. * (afactor: single; const asz1: TSizeF): TSizeF;
1581
+ begin
1582
+ result:=asz1.Scale(afactor);
1583
+ end;
1584
+
1585
+ class operator TSizeF. * (const asz1: TSizeF; afactor: single): TSizeF;
1586
+ begin
1587
+ result:=asz1.Scale(afactor);
1588
+ end;
1589
+
1590
+ class operator TSizeF.+ (const asz1, asz2 : TSizeF): TSizeF;
1591
+ begin
1592
+ result.cx:=asz1.cx+asz2.cx;
1593
+ result.cy:=asz1.cy+asz2.cy;
1594
+ end;
1595
+
1596
+ class operator TSizeF.- (const asz1, asz2 : TSizeF): TSizeF;
1597
+ begin
1598
+ result.cx:=asz1.cx-asz2.cx;
1599
+ result.cy:=asz1.cy-asz2.cy;
1600
+ end;
1601
+
1602
+ class operator TSizeF. - (const asz1: TSizeF): TSizeF;
1603
+ begin
1604
+ Result.cx:=-asz1.cx;
1605
+ Result.cy:=-asz1.cy;
1606
+ end;
1607
+
1608
+ class operator TSizeF. := (const apt: TPointF): TSizeF;
1609
+ begin
1610
+ Result.cx:=apt.x;
1611
+ Result.cy:=apt.y;
1612
+ end;
1613
+
1614
+ class operator TSizeF. := (const asz: TSize): TSizeF;
1615
+ begin
1616
+ Result.cx := asz.cx;
1617
+ Result.cy := asz.cy;
1618
+ end;
1619
+
1620
+ class operator TSizeF. := (const asz: TSizeF): TPointF;
1621
+ begin
1622
+ Result.x := asz.cx;
1623
+ Result.y := asz.cy;
1624
+ end;
1625
+ *)
1626
+ class function TSizeF.Create(const ax, ay: Single): TSizeF;
1627
+ begin
1628
+ Result.cx := ax;
1629
+ Result.cy := ay;
1630
+ end;
1631
+
1632
+ class function TSizeF.Create(const asz: TSize): TSizeF;
1633
+ begin
1634
+ Result.cx := asz.cX;
1635
+ Result.cy := asz.cY;
1636
+ end;
1637
+
1638
+ { TRectF }
1639
+
1640
+ function TRectF.ToString(aSize,aDecimals : Byte; aUseSize : Boolean = False) : RTLString;
1641
+
1642
+ var
1643
+ S : RTLString;
1644
+
1645
+ begin
1646
+ if aUseSize then
1647
+ S:=Size.ToString(aSize,aDecimals)
1648
+ else
1649
+ S:=BottomRight.ToString(aSize,aDecimals);
1650
+ Result:='['+TopLeft.ToString(aSize,aDecimals)+' - '+S+']';
1651
+ end;
1652
+
1653
+ function TRectF.ToString(aUseSize: Boolean = False) : RTLString;
1654
+
1655
+ begin
1656
+ Result:=ToString(8,2,aUseSize);
1657
+ end;
1658
+
1659
+ (*
1660
+ class operator TRectF. * (L, R: TRectF): TRectF;
1661
+ begin
1662
+ Result := TRectF.Intersect(L, R);
1663
+ end;
1664
+
1665
+ class operator TRectF. + (L, R: TRectF): TRectF;
1666
+ begin
1667
+ Result := TRectF.Union(L, R);
1668
+ end;
1669
+
1670
+ class operator TRectF. := (const arc: TRect): TRectF;
1671
+ begin
1672
+ Result.Left:=arc.Left;
1673
+ Result.Top:=arc.Top;
1674
+ Result.Right:=arc.Right;
1675
+ Result.Bottom:=arc.Bottom;
1676
+ end;
1677
+
1678
+ class operator TRectF. <> (L, R: TRectF): Boolean;
1679
+ begin
1680
+ Result := not(L=R);
1681
+ end;
1682
+
1683
+ class operator TRectF. = (L, R: TRectF): Boolean;
1684
+ begin
1685
+ Result :=
1686
+ SameValue(L.Left,R.Left) and SameValue(L.Right,R.Right) and
1687
+ SameValue(L.Top,R.Top) and SameValue(L.Bottom,R.Bottom);
1688
+ end;
1689
+ *)
1690
+ constructor TRectF.Create(ALeft, ATop, ARight, ABottom: Single);
1691
+ begin
1692
+ Left := ALeft;
1693
+ Top := ATop;
1694
+ Right := ARight;
1695
+ Bottom := ABottom;
1696
+ end;
1697
+
1698
+ constructor TRectF.Create(P1, P2: TPointF; Normalize: Boolean);
1699
+ begin
1700
+ TopLeft := P1;
1701
+ BottomRight := P2;
1702
+ if Normalize then
1703
+ NormalizeRect;
1704
+ end;
1705
+
1706
+ constructor TRectF.Create(Origin: TPointF);
1707
+ begin
1708
+ TopLeft := Origin;
1709
+ BottomRight := Origin;
1710
+ end;
1711
+
1712
+ constructor TRectF.Create(Origin: TPointF; AWidth, AHeight: Single);
1713
+ begin
1714
+ TopLeft := Origin;
1715
+ Width := AWidth;
1716
+ Height := AHeight;
1717
+ end;
1718
+
1719
+ constructor TRectF.Create(R: TRectF; Normalize: Boolean);
1720
+ begin
1721
+ Self := R;
1722
+ if Normalize then
1723
+ NormalizeRect;
1724
+ end;
1725
+
1726
+ constructor TRectF.Create(R: TRect; Normalize: Boolean);
1727
+ begin
1728
+ Self.Left := R.Left;
1729
+ Self.Top := R.Top;
1730
+ Self.Right := R.Right;
1731
+ Self.Bottom := R.Bottom;
1732
+ if Normalize then
1733
+ NormalizeRect;
1734
+ end;
1735
+
1736
+ function TRectF.CenterPoint: TPointF;
1737
+ begin
1738
+ Result.X := (Right-Left) / 2 + Left;
1739
+ Result.Y := (Bottom-Top) / 2 + Top;
1740
+ end;
1741
+
1742
+ function TRectF.Ceiling: TRectF;
1743
+ begin
1744
+ Result.BottomRight:=TPointF.Create(BottomRight.Ceiling.X,BottomRight.Ceiling.Y);
1745
+ Result.TopLeft:=TPointF.Create(TopLeft.Ceiling.X,TopLeft.Ceiling.Y);
1746
+ end;
1747
+
1748
+ function TRectF.CenterAt(const Dest: TRectF): TRectF;
1749
+ begin
1750
+ Result:=Self;
1751
+ RectCenter(Result,Dest);
1752
+ end;
1753
+
1754
+ function TRectF.Fit(const Dest: TRectF): Single;
1755
+
1756
+ var
1757
+ R : TRectF;
1758
+
1759
+ begin
1760
+ R:=FitInto(Dest,Result);
1761
+ Self:=R;
1762
+ end;
1763
+
1764
+ function TRectF.FitInto(const Dest: TRectF; out Ratio: Single): TRectF;
1765
+ begin
1766
+ if (Dest.Width<=0) or (Dest.Height<=0) then
1767
+ begin
1768
+ Ratio:=1.0;
1769
+ exit(Self);
1770
+ end;
1771
+ Ratio:=Max(Self.Width / Dest.Width, Self.Height / Dest.Height);
1772
+ if Ratio=0 then
1773
+ exit(Self);
1774
+ Result.Width:=Self.Width / Ratio;
1775
+ Result.Height:=Self.Height / Ratio;
1776
+ Result.Left:=Self.Left + (Self.Width - Result.Width) / 2;
1777
+ Result.Top:=Self.Top + (Self.Height - Result.Height) / 2;
1778
+ end;
1779
+
1780
+ function TRectF.FitInto(const Dest: TRectF): TRectF;
1781
+ var
1782
+ Ratio: Single;
1783
+ begin
1784
+ Result:=FitInto(Dest,Ratio);
1785
+ end;
1786
+
1787
+ function TRectF.PlaceInto(const Dest: TRectF; const AHorzAlign: THorzRectAlign = THorzRectAlign.Center; const AVertAlign: TVertRectAlign = TVertRectAlign.Center): TRectF;
1788
+
1789
+ var
1790
+ R : TRectF;
1791
+ X,Y : Single;
1792
+ D : TRectF absolute dest;
1793
+
1794
+ begin
1795
+ if (Height>Dest.Height) or (Width>Dest.Width) then
1796
+ R:=FitInto(Dest)
1797
+ else
1798
+ R:=Self;
1799
+ case AHorzAlign of
1800
+ THorzRectAlign.Left:
1801
+ X:=D.Left;
1802
+ THorzRectAlign.Center:
1803
+ X:=(D.Left+D.Right-R.Width)/2;
1804
+ THorzRectAlign.Right:
1805
+ X:=D.Right-R.Width;
1806
+ end;
1807
+ case AVertAlign of
1808
+ TVertRectAlign.Top:
1809
+ Y:=D.Top;
1810
+ TVertRectAlign.Center:
1811
+ Y:=(D.Top+D.Bottom-R.Height)/2;
1812
+ TVertRectAlign.Bottom:
1813
+ Y:=D.Bottom-R.Height;
1814
+ end;
1815
+ R.SetLocation(PointF(X,Y));
1816
+ Result:=R;
1817
+ end;
1818
+
1819
+ function TRectF.SnapToPixel(AScale: Single; APlaceBetweenPixels: Boolean): TRectF;
1820
+
1821
+ function sc (S : single) : single; inline;
1822
+
1823
+ begin
1824
+ Result:=System.Trunc(S*AScale)/AScale;
1825
+ end;
1826
+
1827
+ var
1828
+ R : TRectF;
1829
+ Off: Single;
1830
+
1831
+ begin
1832
+ if AScale<=0 then
1833
+ AScale := 1;
1834
+ R.Top:=Sc(Top);
1835
+ R.Left:=Sc(Left);
1836
+ R.Width:=Sc(Width);
1837
+ R.Height:=Sc(Height);
1838
+ if APlaceBetweenPixels then
1839
+ begin
1840
+ Off:=1/(2*aScale);
1841
+ R.Offset(Off,Off);
1842
+ end;
1843
+ Result:=R;
1844
+ end;
1845
+
1846
+
1847
+ function TRectF.Contains(Pt: TPointF): Boolean;
1848
+ begin
1849
+ Result := (Left <= Pt.X) and (Pt.X < Right) and (Top <= Pt.Y) and (Pt.Y < Bottom);
1850
+ end;
1851
+
1852
+ function TRectF.Contains(R: TRectF): Boolean;
1853
+ begin
1854
+ Result := (Left <= R.Left) and (R.Right <= Right) and (Top <= R.Top) and (R.Bottom <= Bottom);
1855
+ end;
1856
+
1857
+ class function TRectF.Empty: TRectF;
1858
+ begin
1859
+ Result := TRectF.Create(0,0,0,0);
1860
+ end;
1861
+
1862
+ function TRectF.EqualsTo(const R: TRectF; const Epsilon: Single): Boolean;
1863
+ begin
1864
+ Result:=TopLeft.EqualsTo(R.TopLeft,Epsilon);
1865
+ Result:=Result and BottomRight.EqualsTo(R.BottomRight,Epsilon);
1866
+ end;
1867
+
1868
+ function TRectF.GetHeight: Single;
1869
+ begin
1870
+ result:=bottom-top;
1871
+ end;
1872
+
1873
+ function TRectF.GetBottomRight: TPointF;
1874
+ begin
1875
+ Result:=TPointF.Create(Right,Bottom);
1876
+ end;
1877
+
1878
+ function TRectF.GetLocation: TPointF;
1879
+ begin
1880
+ result.x:=Left; result.y:=top;
1881
+ end;
1882
+
1883
+ function TRectF.GetSize: TSizeF;
1884
+ begin
1885
+ result.cx:=width; result.cy:=height;
1886
+ end;
1887
+
1888
+ function TRectF.GetTopLeft: TPointF;
1889
+ begin
1890
+ Result:=TPointF.Create(Left,Top);
1891
+ end;
1892
+
1893
+ procedure TRectF.SetBottomRight(const aValue: TPointF);
1894
+ begin
1895
+ Right:=aValue.X;
1896
+ Bottom:=aValue.y;
1897
+ end;
1898
+
1899
+ function TRectF.GetWidth: Single;
1900
+ begin
1901
+ result:=right-left;
1902
+ end;
1903
+
1904
+ procedure TRectF.Inflate(DX, DY: Single);
1905
+ begin
1906
+ Left:=Left-dx;
1907
+ Top:=Top-dy;
1908
+ Right:=Right+dx;
1909
+ Bottom:=Bottom+dy;
1910
+ end;
1911
+
1912
+ procedure TRectF.Intersect(R: TRectF);
1913
+ begin
1914
+ Self := Intersect(Self, R);
1915
+ end;
1916
+
1917
+ class function TRectF.Intersect(R1: TRectF; R2: TRectF): TRectF;
1918
+ begin
1919
+ Result := R1;
1920
+ if R2.Left > R1.Left then
1921
+ Result.Left := R2.Left;
1922
+ if R2.Top > R1.Top then
1923
+ Result.Top := R2.Top;
1924
+ if R2.Right < R1.Right then
1925
+ Result.Right := R2.Right;
1926
+ if R2.Bottom < R1.Bottom then
1927
+ Result.Bottom := R2.Bottom;
1928
+ end;
1929
+
1930
+ function TRectF.IntersectsWith(R: TRectF): Boolean;
1931
+ begin
1932
+ Result := (Left < R.Right) and (R.Left < Right) and (Top < R.Bottom) and (R.Top < Bottom);
1933
+ end;
1934
+
1935
+ function TRectF.IsEmpty: Boolean;
1936
+ begin
1937
+ Result := (CompareValue(Right,Left)<=0) or (CompareValue(Bottom,Top)<=0);
1938
+ end;
1939
+
1940
+ procedure TRectF.NormalizeRect;
1941
+ var
1942
+ x: Single;
1943
+ begin
1944
+ if Top>Bottom then
1945
+ begin
1946
+ x := Top;
1947
+ Top := Bottom;
1948
+ Bottom := x;
1949
+ end;
1950
+ if Left>Right then
1951
+ begin
1952
+ x := Left;
1953
+ Left := Right;
1954
+ Right := x;
1955
+ end
1956
+ end;
1957
+
1958
+ procedure TRectF.Inflate(DL, DT, DR, DB: Single);
1959
+ begin
1960
+ Left:=Left-dl;
1961
+ Top:=Top-dt;
1962
+ Right:=Right+dr;
1963
+ Bottom:=Bottom+db;
1964
+ end;
1965
+
1966
+ procedure TRectF.Offset(const dx, dy: Single);
1967
+ begin
1968
+ left:=left+dx; right:=right+dx;
1969
+ bottom:=bottom+dy; top:=top+dy;
1970
+ end;
1971
+
1972
+ procedure TRectF.Offset(DP: TPointF);
1973
+ begin
1974
+ left:=left+DP.x; right:=right+DP.x;
1975
+ bottom:=bottom+DP.y; top:=top+DP.y;
1976
+ end;
1977
+
1978
+ function TRectF.Truncate: TRect;
1979
+ begin
1980
+ Result.BottomRight:=BottomRight.Truncate;
1981
+ Result.TopLeft:=TopLeft.Truncate;
1982
+ end;
1983
+
1984
+ function TRectF.Round: TRect;
1985
+ begin
1986
+ Result.BottomRight:=BottomRight.Round;
1987
+ Result.TopLeft:=TopLeft.Round;
1988
+ end;
1989
+
1990
+ procedure TRectF.SetHeight(AValue: Single);
1991
+ begin
1992
+ bottom:=top+avalue;
1993
+ end;
1994
+
1995
+ procedure TRectF.SetTopLeft(const aValue: TPointF);
1996
+ begin
1997
+ Left:=aValue.X;
1998
+ Top:=aValue.Y;
1999
+ end;
2000
+
2001
+ (*
2002
+ procedure TRectF.SetLocation(const X, Y: Single);
2003
+ begin
2004
+ Offset(X-Left, Y-Top);
2005
+ end;
2006
+ *)
2007
+
2008
+ procedure TRectF.SetLocation(P: TPointF);
2009
+ begin
2010
+ Offset(P.X-Left,P.Y-Top);
2011
+ end;
2012
+
2013
+ procedure TRectF.SetSize(AValue: TSizeF);
2014
+ begin
2015
+ bottom:=top+avalue.cy;
2016
+ right:=left+avalue.cx;
2017
+ end;
2018
+
2019
+ procedure TRectF.SetWidth(AValue: Single);
2020
+ begin
2021
+ right:=left+avalue;
2022
+ end;
2023
+
2024
+ class function TRectF.Union(const Points: array of TPointF): TRectF;
2025
+ var
2026
+ i: Integer;
2027
+ begin
2028
+ if Length(Points) > 0 then
2029
+ begin
2030
+ Result.TopLeft := Points[Low(Points)];
2031
+ Result.BottomRight := Points[Low(Points)];
2032
+
2033
+ for i := Low(Points)+1 to High(Points) do
2034
+ begin
2035
+ if Points[i].X < Result.Left then Result.Left := Points[i].X;
2036
+ if Points[i].X > Result.Right then Result.Right := Points[i].X;
2037
+ if Points[i].Y < Result.Top then Result.Top := Points[i].Y;
2038
+ if Points[i].Y > Result.Bottom then Result.Bottom := Points[i].Y;
2039
+ end;
2040
+ end else
2041
+ Result := Empty;
2042
+ end;
2043
+
2044
+ procedure TRectF.Union(const r: TRectF);
2045
+ begin
2046
+ left:=min(r.left,left);
2047
+ top:=min(r.top,top);
2048
+ right:=max(r.right,right);
2049
+ bottom:=max(r.bottom,bottom);
2050
+ end;
2051
+
2052
+ class function TRectF.Union(R1, R2: TRectF): TRectF;
2053
+ begin
2054
+ Result:=R1;
2055
+ Result.Union(R2);
2056
+ end;
2057
+
2058
+ { TPoint3D }
2059
+
2060
+ function TPoint3D.ToString(aSize,aDecimals : Byte) : RTLString;
2061
+
2062
+ var
2063
+ Sx,Sy,Sz : string;
2064
+ begin
2065
+ Sx:=SingleToStr(X,aSize,aDecimals);
2066
+ Sy:=SingleToStr(Y,aSize,aDecimals);
2067
+ Sz:=SingleToStr(Z,aSize,aDecimals);
2068
+ Result:='('+Sx+','+Sy+','+Sz+')';
2069
+ end;
2070
+
2071
+ function TPoint3D.ToString : RTLString;
2072
+
2073
+ begin
2074
+ Result:=ToString(8,2);
2075
+ end;
2076
+
2077
+ function TPoint3D.GetSingle3Array: TSingle3Array;
2078
+ begin
2079
+ Result:=[x,y,z]
2080
+ end;
2081
+
2082
+ procedure TPoint3D.SetSingle3Array(const aValue: TSingle3Array);
2083
+ begin
2084
+ x:=aValue[0];
2085
+ y:=aValue[1];
2086
+ z:=aValue[2];
2087
+ end;
2088
+
2089
+ constructor TPoint3D.Create(const ax,ay,az:single);
2090
+ begin
2091
+ x:=ax; y:=ay; z:=az;
2092
+ end;
2093
+
2094
+ procedure TPoint3D.Offset(const adeltax,adeltay,adeltaz:single);
2095
+ begin
2096
+ x:=x+adeltax; y:=y+adeltay; z:=z+adeltaz;
2097
+ end;
2098
+
2099
+ procedure TPoint3D.Offset(const adelta:TPoint3D);
2100
+ begin
2101
+ x:=x+adelta.x; y:=y+adelta.y; z:=z+adelta.z;
2102
+ end;
2103
+
2104
+
2105
+ { TSize }
2106
+
2107
+ constructor TSize.Create(ax,ay:Longint);
2108
+ begin
2109
+ cx:=ax; cy:=ay;
2110
+ end;
2111
+
2112
+ constructor TSize.Create(asz :TSize);
2113
+ begin
2114
+ cx:=asz.cx; cy:=asz.cy;
2115
+ // vector:=TSize(asz.vector); ??
2116
+ end;
2117
+
2118
+
2119
+ function TSize.IsZero : Boolean;
2120
+ begin
2121
+ result:=(cx=0) and (cy=0);
2122
+ end;
2123
+
2124
+ function TSize.Distance(const asz : TSize) : Double;
2125
+ begin
2126
+ result:=sqrt(sqr(cx-asz.cx)+sqr(cy-asz.cy));
2127
+ end;
2128
+
2129
+ function TSize.Add(const asz : TSize): TSize;
2130
+ begin
2131
+ result.cx:=cx+asz.cx;
2132
+ result.cy:=cy+asz.cy;
2133
+ end;
2134
+
2135
+ function TSize.Subtract(const asz : TSize): TSize;
2136
+ begin
2137
+ result.cx:=cx-asz.cx;
2138
+ result.cy:=cy-asz.cy;
2139
+ end;
2140
+
2141
+ (*
2142
+ class operator TSize.=(const asz1, asz2 : TSize) : Boolean;
2143
+ begin
2144
+ result:=(asz1.cx=asz2.cx) and (asz1.cy=asz2.cy);
2145
+ end;
2146
+
2147
+ class operator TSize.<> (const asz1, asz2 : TSize): Boolean;
2148
+ begin
2149
+ result:=(asz1.cx<>asz2.cx) or (asz1.cy<>asz2.cy);
2150
+ end;
2151
+
2152
+ class operator TSize.+(const asz1, asz2 : TSize): TSize;
2153
+ begin
2154
+ result.cx:=asz1.cx+asz2.cx;
2155
+ result.cy:=asz1.cy+asz2.cy;
2156
+ end;
2157
+
2158
+ class operator TSize.-(const asz1, asz2 : TSize): TSize;
2159
+ begin
2160
+ result.cx:=asz1.cx-asz2.cx;
2161
+ result.cy:=asz1.cy-asz2.cy;
2162
+ end;
2163
+ *)
2164
+ {$ifdef VER3}
2165
+ constructor TPoint.Create(ax,ay:Longint);
2166
+ begin
2167
+ x:=ax; y:=ay;
2168
+ end;
2169
+
2170
+ constructor TPoint.Create(apt :TPoint);
2171
+ begin
2172
+ x:=apt.x; y:=apt.y;
2173
+ end;
2174
+
2175
+ {$endif}
2176
+ function TPoint.Add(const apt: TPoint): TPoint;
2177
+ begin
2178
+ result.x:=x+apt.x;
2179
+ result.y:=y+apt.y;
2180
+ end;
2181
+
2182
+ function TPoint.Distance(const apt: TPoint): ValReal;
2183
+ begin
2184
+ result:=sqrt(sqr(ValReal(apt.x)-ValReal(x))+sqr(ValReal(apt.y)-ValReal(y))); // convert to ValReal to prevent integer overflows
2185
+ end;
2186
+
2187
+ function TPoint.IsZero : Boolean;
2188
+ begin
2189
+ result:=(x=0) and (y=0);
2190
+ end;
2191
+
2192
+ function TPoint.Subtract(const apt : TPoint): TPoint;
2193
+ begin
2194
+ result.x:=x-apt.x;
2195
+ result.y:=y-apt.y;
2196
+ end;
2197
+
2198
+ class function TPoint.Zero: TPoint;
2199
+ begin
2200
+ Result.x := 0;
2201
+ Result.y := 0;
2202
+ end;
2203
+
2204
+ procedure TPoint.SetLocation(const apt :TPoint);
2205
+ begin
2206
+ x:=apt.x; y:=apt.y;
2207
+ end;
2208
+ procedure TPoint.SetLocation(ax,ay : Longint);
2209
+ begin
2210
+ x:=ax; y:=ay;
2211
+ end;
2212
+
2213
+ procedure TPoint.Offset(const apt :TPoint);
2214
+ begin
2215
+ x:=x+apt.x;
2216
+ y:=y+apt.y;
2217
+ end;
2218
+
2219
+ class function TPoint.PointInCircle(const apt, acenter: TPoint;
2220
+ const aradius: Integer): Boolean;
2221
+ begin
2222
+ Result := apt.Distance(acenter) <= aradius;
2223
+ end;
2224
+
2225
+ procedure TPoint.Offset(dx,dy : Longint);
2226
+ begin
2227
+ x:=x+dx;
2228
+ y:=y+dy;
2229
+ end;
2230
+
2231
+ function TPoint.Angle(const pt: TPoint): Single;
2232
+
2233
+ function arctan2(y,x : Single) : Single;
2234
+ begin
2235
+ if x=0 then
2236
+ begin
2237
+ if y=0 then
2238
+ result:=0.0
2239
+ else if y>0 then
2240
+ result:=pi/2
2241
+ else
2242
+ result:=-pi/2;
2243
+ end
2244
+ else
2245
+ begin
2246
+ result:=ArcTan(y/x);
2247
+ if x<0 then
2248
+ if y<0 then
2249
+ result:=result-pi
2250
+ else
2251
+ result:=result+pi;
2252
+ end;
2253
+ end;
2254
+
2255
+ begin
2256
+ result:=ArcTan2(y-pt.y,x-pt.x);
2257
+ end;
2258
+
2259
+ (*
2260
+ class operator TPoint.= (const apt1, apt2 : TPoint) : Boolean;
2261
+ begin
2262
+ result:=(apt1.x=apt2.x) and (apt1.y=apt2.y);
2263
+ end;
2264
+
2265
+ class operator TPoint.<> (const apt1, apt2 : TPoint): Boolean;
2266
+ begin
2267
+ result:=(apt1.x<>apt2.x) or (apt1.y<>apt2.y);
2268
+ end;
2269
+
2270
+ class operator TPoint.+ (const apt1, apt2 : TPoint): TPoint;
2271
+ begin
2272
+ result.x:=apt1.x+apt2.x;
2273
+ result.y:=apt1.y+apt2.y;
2274
+ end;
2275
+
2276
+ class operator TPoint.- (const apt1, apt2 : TPoint): TPoint;
2277
+ begin
2278
+ result.x:=apt1.x-apt2.x;
2279
+ result.y:=apt1.y-apt2.y;
2280
+ end;
2281
+
2282
+ // warning suppression for the next ones?
2283
+ class operator TPoint.:= (const aspt : TSmallPoint): TPoint;
2284
+ begin
2285
+ result.x:=aspt.x;
2286
+ result.y:=aspt.y;
2287
+ end;
2288
+
2289
+ class operator TPoint.Explicit (const apt: TPoint): TSmallPoint;
2290
+ begin
2291
+ result.x:=apt.x;
2292
+ result.y:=apt.y;
2293
+ end;
2294
+ *)
2295
+ end.
2296
+