@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.
- package/LICENSE +501 -0
- package/README.md +278 -0
- package/THIRD-PARTY-NOTICES.md +48 -0
- package/assets/pas2js.wasm +0 -0
- package/assets/rtl/Rtl.BrowserLoadHelper.pas +179 -0
- package/assets/rtl/browserconsole.pas +190 -0
- package/assets/rtl/classes.pas +11371 -0
- package/assets/rtl/js.pas +2211 -0
- package/assets/rtl/manifest.json +19 -0
- package/assets/rtl/math.pas +903 -0
- package/assets/rtl/p2jsres.pp +334 -0
- package/assets/rtl/rtl.js +1563 -0
- package/assets/rtl/rtlconsts.pas +97 -0
- package/assets/rtl/simplelinkedlist.pas +152 -0
- package/assets/rtl/system.pas +1166 -0
- package/assets/rtl/sysutils.pas +8959 -0
- package/assets/rtl/types.pas +2296 -0
- package/assets/rtl/typinfo.pas +1680 -0
- package/assets/rtl/web.pas +3586 -0
- package/assets/rtl/weborworker.pas +2101 -0
- package/dist/pascal-wasm.iife.min.js +6 -0
- package/dist/pascal-wasm.iife.min.js.map +7 -0
- package/package.json +54 -0
- package/src/assets.js +119 -0
- package/src/compiler.js +142 -0
- package/src/config.js +24 -0
- package/src/iife.js +27 -0
- package/src/index.js +130 -0
- package/src/vendor/browser_wasi_shim/debug.js +1 -0
- package/src/vendor/browser_wasi_shim/fd.js +1 -0
- package/src/vendor/browser_wasi_shim/fs_mem.js +1 -0
- package/src/vendor/browser_wasi_shim/fs_opfs.js +1 -0
- package/src/vendor/browser_wasi_shim/index.js +1 -0
- package/src/vendor/browser_wasi_shim/strace.js +1 -0
- package/src/vendor/browser_wasi_shim/wasi.js +1 -0
- package/src/vendor/browser_wasi_shim/wasi_defs.js +1 -0
- 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
|
+
|