types.pp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2002 by Florian Klaempfl,
  4. member of the Free Pascal development team.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$MODE OBJFPC}
  12. unit Types;
  13. interface
  14. {$modeswitch advancedrecords}
  15. {$modeswitch class}
  16. {$if defined(win32) or defined(win64) or defined(wince)}
  17. uses
  18. Windows;
  19. {$elseif defined(win16)}
  20. uses
  21. WinTypes;
  22. {$endif}
  23. {$if defined(win32) or defined(win64)}
  24. const
  25. RT_RCDATA = Windows.RT_RCDATA deprecated 'Use Windows.RT_RCDATA instead';
  26. {$elseif defined(win16)}
  27. const
  28. RT_RCDATA = WinTypes.RT_RCDATA deprecated 'Use WinTypes.RT_RCDATA instead';
  29. {$endif}
  30. type
  31. TEndian = Objpas.TEndian;
  32. TDirection = (FromBeginning, FromEnd);
  33. TValueRelationship = -1..1;
  34. DWORD = LongWord;
  35. PLongint = System.PLongint;
  36. PSmallInt = System.PSmallInt;
  37. {$ifndef FPUNONE}
  38. PDouble = System.PDouble;
  39. {$endif}
  40. PByte = System.PByte;
  41. Largeint = int64;
  42. LARGE_INT = LargeInt;
  43. PLargeInt = ^LargeInt;
  44. LargeUint = qword;
  45. LARGE_UINT= LargeUInt;
  46. PLargeuInt = ^LargeuInt;
  47. TBooleanDynArray = array of Boolean;
  48. TByteDynArray = array of Byte;
  49. TCardinalDynArray = array of Cardinal;
  50. TInt64DynArray = array of Int64;
  51. TIntegerDynArray = array of Integer;
  52. TLongWordDynArray = array of LongWord;
  53. TPointerDynArray = array of Pointer;
  54. TQWordDynArray = array of QWord;
  55. TShortIntDynArray = array of ShortInt;
  56. TSmallIntDynArray = array of SmallInt;
  57. TStringDynArray = array of AnsiString;
  58. TObjectDynArray = array of TObject;
  59. TWideStringDynArray = array of WideString;
  60. TWordDynArray = array of Word;
  61. TCurrencyArray = Array of currency;
  62. {$ifndef FPUNONE}
  63. TSingleDynArray = array of Single;
  64. TDoubleDynArray = array of Double;
  65. TExtendedDynArray = array of Extended;
  66. TCompDynArray = array of Comp;
  67. {$endif}
  68. {$if defined(win32) or defined(win64) or defined(wince)}
  69. TArray4IntegerType = Windows.TArray4IntegerType;
  70. TSmallPoint = Windows.TSmallPoint;
  71. PSmallPoint = Windows.PSmallPoint;
  72. TSize = Windows.TSize;
  73. TagSize = Windows.tagSize deprecated;
  74. PSize = Windows.PSize;
  75. TPoint = Windows.TPoint;
  76. TagPoint = Windows.TagPoint deprecated;
  77. PPoint = Windows.PPoint;
  78. TRect = Windows.TRect;
  79. PRect = Windows.PRect;
  80. TSplitRectType = Windows.TSplitRectType;
  81. const
  82. srLeft = TSplitRectType.srLeft;
  83. srRight = TSplitRectType.srRight;
  84. srTop = TSplitRectType.srTop;
  85. srBottom = TSplitRectType.srBottom;
  86. type
  87. {$else}
  88. {$i typshrdh.inc}
  89. TagSize = tSize deprecated;
  90. TagPoint = TPoint deprecated;
  91. {$endif}
  92. { TPointF }
  93. PPointF = ^TPointF;
  94. TPointF =
  95. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  96. packed
  97. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  98. record
  99. x,y : Single;
  100. public
  101. function Add(const apt: TPoint): TPointF;
  102. function Add(const apt: TPointF): TPointF;
  103. function Distance(const apt : TPointF) : Single;
  104. function DotProduct(const apt : TPointF) : Single;
  105. function IsZero : Boolean;
  106. function Subtract(const apt : TPointF): TPointF;
  107. function Subtract(const apt : TPoint): TPointF;
  108. procedure SetLocation(const apt :TPointF);
  109. procedure SetLocation(const apt :TPoint);
  110. procedure SetLocation(ax,ay : Longint);
  111. procedure Offset(const apt :TPointF);
  112. procedure Offset(const apt :TPoint);
  113. procedure Offset(dx,dy : Longint);
  114. function Scale (afactor:Single) : TPointF;
  115. function Ceiling : TPoint;
  116. function Truncate: TPoint;
  117. function Floor : TPoint;
  118. function Round : TPoint;
  119. function Length : Single;
  120. class function Create(const ax, ay: Single): TPointF; overload; static; inline;
  121. class function Create(const apt: TPoint): TPointF; overload; static; inline;
  122. class operator = (const apt1, apt2 : TPointF) : Boolean;
  123. class operator <> (const apt1, apt2 : TPointF): Boolean;
  124. class operator + (const apt1, apt2 : TPointF): TPointF;
  125. class operator - (const apt1, apt2 : TPointF): TPointF;
  126. class operator - (const apt1 : TPointF): TPointF;
  127. class operator * (const apt1, apt2: TPointF): TPointF;
  128. class operator * (const apt1: TPointF; afactor: single): TPointF;
  129. class operator * (afactor: single; const apt1: TPointF): TPointF;
  130. class operator / (const apt1: TPointF; afactor: single): TPointF;
  131. class operator := (const apt: TPoint): TPointF;
  132. class operator ** (const apt1, apt2: TPointF): Single; // scalar product
  133. end;
  134. { TSizeF }
  135. PSizeF = ^TSizeF;
  136. TSizeF =
  137. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  138. packed
  139. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  140. record
  141. cx,cy : Single;
  142. public
  143. function Add(const asz: TSize): TSizeF;
  144. function Add(const asz: TSizeF): TSizeF;
  145. function Distance(const asz : TSizeF) : Single;
  146. function IsZero : Boolean;
  147. function Subtract(const asz : TSizeF): TSizeF;
  148. function Subtract(const asz : TSize): TSizeF;
  149. function Scale (afactor:Single) : TSizeF;
  150. function Ceiling : TSize;
  151. function Truncate: TSize;
  152. function Floor : TSize;
  153. function Round : TSize;
  154. function Length : Single;
  155. class function Create(const ax, ay: Single): TSizeF; overload; static; inline;
  156. class function Create(const asz: TSize): TSizeF; overload; static; inline;
  157. class operator = (const asz1, asz2 : TSizeF) : Boolean;
  158. class operator <> (const asz1, asz2 : TSizeF): Boolean;
  159. class operator + (const asz1, asz2 : TSizeF): TSizeF;
  160. class operator - (const asz1, asz2 : TSizeF): TSizeF;
  161. class operator - (const asz1 : TSizeF): TSizeF;
  162. class operator * (const asz1: TSizeF; afactor: single): TSizeF;
  163. class operator * (afactor: single; const asz1: TSizeF): TSizeF;
  164. class operator := (const apt: TPointF): TSizeF;
  165. class operator := (const asz: TSize): TSizeF;
  166. class operator := (const asz: TSizeF): TPointF;
  167. property Width: Single read cx write cx;
  168. property Height: Single read cy write cy;
  169. end;
  170. { TRectF }
  171. PRectF = ^TRectF;
  172. TRectF =
  173. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  174. packed
  175. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  176. record
  177. private
  178. function GetLocation: TPointF;
  179. function GetSize: TSizeF;
  180. procedure SetSize(AValue: TSizeF);
  181. function GetHeight: Single; inline;
  182. function GetWidth: Single; inline;
  183. procedure SetHeight(AValue: Single);
  184. procedure SetWidth (AValue: Single);
  185. public
  186. constructor Create(Origin: TPointF); // empty rect at given origin
  187. constructor Create(Origin: TPointF; AWidth, AHeight: Single);
  188. constructor Create(ALeft, ATop, ARight, ABottom: Single);
  189. constructor Create(P1, P2: TPointF; Normalize: Boolean = False);
  190. constructor Create(R: TRectF; Normalize: Boolean = False);
  191. constructor Create(R: TRect; Normalize: Boolean = False);
  192. class operator = (L, R: TRectF): Boolean;
  193. class operator <> (L, R: TRectF): Boolean;
  194. class operator + (L, R: TRectF): TRectF; // union
  195. class operator * (L, R: TRectF): TRectF; // intersection
  196. class operator := (const arc: TRect): TRectF;
  197. class function Empty: TRectF; static;
  198. procedure NormalizeRect;
  199. function IsEmpty: Boolean;
  200. function Contains(Pt: TPointF): Boolean;
  201. function Contains(R: TRectF): Boolean;
  202. function IntersectsWith(R: TRectF): Boolean;
  203. class function Intersect(R1: TRectF; R2: TRectF): TRectF; static;
  204. procedure Intersect(R: TRectF);
  205. class function Union(R1, R2: TRectF): TRectF; static;
  206. class function Union(const Points: array of TPointF): TRectF; static;
  207. procedure SetLocation(X, Y: Single);
  208. procedure SetLocation(P: TPointF);
  209. procedure Inflate(DX, DY: Single);
  210. procedure Inflate(DL, DT, DR, DB: Single);
  211. function CenterPoint: TPointF;
  212. procedure Union (const r: TRectF); inline;
  213. procedure Offset (const dx,dy : Single); inline;
  214. procedure Offset (DP: TPointF); inline;
  215. property Width : Single read GetWidth write SetWidth;
  216. property Height : Single read GetHeight write SetHeight;
  217. property Size : TSizeF read getSize write SetSize;
  218. property Location: TPointF read getLocation write setLocation;
  219. case Integer of
  220. 0: (Left, Top, Right, Bottom: Single);
  221. 1: (TopLeft, BottomRight: TPointF);
  222. end;
  223. TDuplicates = (dupIgnore, dupAccept, dupError);
  224. TPoint3D =
  225. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  226. packed
  227. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  228. record
  229. public
  230. Type TSingle3Array = array[0..2] of single;
  231. constructor Create(const ax,ay,az:single);
  232. procedure Offset(const adeltax,adeltay,adeltaz:single); inline;
  233. procedure Offset(const adelta:TPoint3D); inline;
  234. public
  235. case Integer of
  236. 0: (data:TSingle3Array);
  237. 1: (x,y,z : single);
  238. end;
  239. type
  240. TOleChar = WideChar;
  241. POleStr = PWideChar;
  242. PPOleStr = ^POleStr;
  243. TListCallback = procedure(data,arg:pointer) of object;
  244. TListStaticCallback = procedure(data,arg:pointer);
  245. const
  246. GUID_NULL: TGUID = '{00000000-0000-0000-0000-000000000000}';
  247. STGTY_STORAGE = 1;
  248. STGTY_STREAM = 2;
  249. STGTY_LOCKBYTES = 3;
  250. STGTY_PROPERTY = 4;
  251. STREAM_SEEK_SET = 0;
  252. STREAM_SEEK_CUR = 1;
  253. STREAM_SEEK_END = 2;
  254. LOCK_WRITE = 1;
  255. LOCK_EXCLUSIVE = 2;
  256. LOCK_ONLYONCE = 4;
  257. STATFLAG_DEFAULT = 0;
  258. STATFLAG_NONAME = 1;
  259. STATFLAG_NOOPEN = 2;
  260. {$ifndef Wince}
  261. // in Wince these are in unit windows. Under 32/64 in ActiveX.
  262. // for now duplicate them. Not that bad for untyped constants.
  263. E_FAIL = HRESULT($80004005);
  264. E_INVALIDARG = HRESULT($80070057);
  265. STG_E_INVALIDFUNCTION = HRESULT($80030001);
  266. STG_E_FILENOTFOUND = HRESULT($80030002);
  267. STG_E_PATHNOTFOUND = HRESULT($80030003);
  268. STG_E_TOOMANYOPENFILES = HRESULT($80030004);
  269. STG_E_ACCESSDENIED = HRESULT($80030005);
  270. STG_E_INVALIDHANDLE = HRESULT($80030006);
  271. STG_E_INSUFFICIENTMEMORY = HRESULT($80030008);
  272. STG_E_INVALIDPOINTER = HRESULT($80030009);
  273. STG_E_NOMOREFILES = HRESULT($80030012);
  274. STG_E_DISKISWRITEPROTECTED = HRESULT($80030013);
  275. STG_E_SEEKERROR = HRESULT($80030019);
  276. STG_E_WRITEFAULT = HRESULT($8003001D);
  277. STG_E_READFAULT = HRESULT($8003001E);
  278. STG_E_SHAREVIOLATION = HRESULT($80030020);
  279. STG_E_LOCKVIOLATION = HRESULT($80030021);
  280. STG_E_FILEALREADYEXISTS = HRESULT($80030050);
  281. STG_E_INVALIDPARAMETER = HRESULT($80030057);
  282. STG_E_MEDIUMFULL = HRESULT($80030070);
  283. STG_E_PROPSETMISMATCHED = HRESULT($800300F0);
  284. STG_E_ABNORMALAPIEXIT = HRESULT($800300FA);
  285. STG_E_INVALIDHEADER = HRESULT($800300FB);
  286. STG_E_INVALIDNAME = HRESULT($800300FC);
  287. STG_E_UNKNOWN = HRESULT($800300FD);
  288. STG_E_UNIMPLEMENTEDFUNCTION = HRESULT($800300FE);
  289. STG_E_INVALIDFLAG = HRESULT($800300FF);
  290. STG_E_INUSE = HRESULT($80030100);
  291. STG_E_NOTCURRENT = HRESULT($80030101);
  292. STG_E_REVERTED = HRESULT($80030102);
  293. STG_E_CANTSAVE = HRESULT($80030103);
  294. STG_E_OLDFORMAT = HRESULT($80030104);
  295. STG_E_OLDDLL = HRESULT($80030105);
  296. STG_E_SHAREREQUIRED = HRESULT($80030106);
  297. STG_E_EXTANTMARSHALLINGS = HRESULT($80030108);
  298. STG_E_DOCFILECORRUPT = HRESULT($80030109);
  299. STG_E_BADBASEADDRESS = HRESULT($80030110);
  300. STG_E_INCOMPLETE = HRESULT($80030201);
  301. STG_E_TERMINATED = HRESULT($80030202);
  302. STG_S_CONVERTED = $00030200;
  303. STG_S_BLOCK = $00030201;
  304. STG_S_RETRYNOW = $00030202;
  305. STG_S_MONITORING = $00030203;
  306. {$endif}
  307. {$if (not defined(win32)) and (not defined(win64)) and (not defined(wince))}
  308. type
  309. PCLSID = PGUID;
  310. TCLSID = TGUID;
  311. PDWord = ^DWord;
  312. PDisplay = Pointer;
  313. PEvent = Pointer;
  314. TXrmOptionDescRec = record
  315. end;
  316. XrmOptionDescRec = TXrmOptionDescRec;
  317. PXrmOptionDescRec = ^TXrmOptionDescRec;
  318. Widget = Pointer;
  319. WidgetClass = Pointer;
  320. ArgList = Pointer;
  321. Region = Pointer;
  322. _FILETIME =
  323. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  324. packed
  325. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  326. record
  327. dwLowDateTime : DWORD;
  328. dwHighDateTime : DWORD;
  329. end;
  330. TFileTime = _FILETIME;
  331. FILETIME = _FILETIME;
  332. PFileTime = ^TFileTime;
  333. {$else}
  334. type
  335. PCLSID = Windows.PCLSID;
  336. TCLSID = Windows.CLSID;
  337. TFiletime = Windows.TFileTime;
  338. Filetime = Windows.FileTime;
  339. PFiletime = Windows.PFileTime;
  340. {$endif Windows}
  341. type
  342. tagSTATSTG = record
  343. pwcsName : POleStr;
  344. dwType : DWord;
  345. cbSize : Large_uint;
  346. mtime : TFileTime;
  347. ctime : TFileTime;
  348. atime : TFileTime;
  349. grfMode : DWord;
  350. grfLocksSupported : DWord;
  351. clsid : TCLSID;
  352. grfStateBits : DWord;
  353. reserved : DWord;
  354. end;
  355. TStatStg = tagSTATSTG;
  356. STATSTG = TStatStg;
  357. PStatStg = ^TStatStg;
  358. { classes depends on these interfaces, we can't use the activex unit in classes though }
  359. IClassFactory = Interface(IUnknown) ['{00000001-0000-0000-C000-000000000046}']
  360. Function CreateInstance(Const unkOuter : IUnknown;Const riid : TGUID;Out vObject) : HResult;StdCall;
  361. Function LockServer(fLock : LongBool) : HResult;StdCall;
  362. End;
  363. ISequentialStream = interface(IUnknown)
  364. ['{0c733a30-2a1c-11ce-ade5-00aa0044773d}']
  365. function Read(pv : Pointer;cb : DWORD;pcbRead : PDWORD) : HRESULT;stdcall;
  366. function Write(pv : Pointer;cb : DWORD;pcbWritten : PDWORD): HRESULT;stdcall;
  367. end;
  368. IStream = interface(ISequentialStream) ['{0000000C-0000-0000-C000-000000000046}']
  369. function Seek(dlibMove : LargeInt; dwOrigin : DWORD; out libNewPosition : LargeUInt) : HResult;stdcall;
  370. function SetSize(libNewSize : LargeUInt) : HRESULT;stdcall;
  371. function CopyTo(stm: IStream;cb : LargeUInt;out cbRead : LargeUInt; out cbWritten : LargeUInt) : HRESULT;stdcall;
  372. function Commit(grfCommitFlags : DWORD) : HRESULT;stdcall;
  373. function Revert : HRESULT;stdcall;
  374. function LockRegion(libOffset : LargeUInt;cb : LargeUInt; dwLockType : DWORD) : HRESULT;stdcall;
  375. function UnlockRegion(libOffset : LargeUInt;cb : LargeUInt; dwLockType : DWORD) : HRESULT;stdcall;
  376. Function Stat(out statstg : TStatStg;grfStatFlag : DWORD) : HRESULT;stdcall;
  377. function Clone(out stm : IStream) : HRESULT;stdcall;
  378. end;
  379. function EqualRect(const r1,r2 : TRect) : Boolean;
  380. function Rect(Left,Top,Right,Bottom : Integer) : TRect; inline;
  381. function RectF(Left,Top,Right,Bottom : Single) : TRectF; inline;
  382. function Bounds(ALeft,ATop,AWidth,AHeight : Integer) : TRect; inline;
  383. function Point(x,y : Integer) : TPoint; inline;
  384. function PointF(x,y: Single) : TPointF; inline;
  385. function PtInRect(const Rect : TRect; const p : TPoint) : Boolean;
  386. function IntersectRect(var Rect : TRect; const R1,R2 : TRect) : Boolean;
  387. function UnionRect(var Rect : TRect; const R1,R2 : TRect) : Boolean;
  388. function IsRectEmpty(const Rect : TRect) : Boolean;
  389. function OffsetRect(var Rect : TRect;DX : Integer;DY : Integer) : Boolean;
  390. function CenterPoint(const Rect: TRect): TPoint;
  391. function InflateRect(var Rect: TRect; dx: Integer; dy: Integer): Boolean;
  392. function Size(AWidth, AHeight: Integer): TSize; inline;
  393. function Size(const ARect: TRect): TSize;
  394. {$ifndef VER3_0}
  395. type
  396. TBitConverter = class
  397. generic class procedure UnsafeFrom<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0); static; {inline;}
  398. generic class procedure From<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0); static;
  399. generic class function UnsafeInTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T; static; {inline;}
  400. generic class function InTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T; static;
  401. end;
  402. {$endif}
  403. implementation
  404. Uses Math;
  405. {$if (not defined(win32)) and (not defined(win64)) and (not defined(wince))}
  406. {$i typshrd.inc}
  407. {$endif}
  408. function EqualRect(const r1,r2 : TRect) : Boolean;
  409. begin
  410. EqualRect:=(r1.left=r2.left) and (r1.right=r2.right) and (r1.top=r2.top) and (r1.bottom=r2.bottom);
  411. end;
  412. function Rect(Left,Top,Right,Bottom : Integer) : TRect; inline;
  413. begin
  414. Rect.Left:=Left;
  415. Rect.Top:=Top;
  416. Rect.Right:=Right;
  417. Rect.Bottom:=Bottom;
  418. end;
  419. function RectF(Left,Top,Right,Bottom : Single) : TRectF; inline;
  420. begin
  421. RectF.Left:=Left;
  422. RectF.Top:=Top;
  423. RectF.Right:=Right;
  424. RectF.Bottom:=Bottom;
  425. end;
  426. function Bounds(ALeft,ATop,AWidth,AHeight : Integer) : TRect; inline;
  427. begin
  428. Bounds.Left:=ALeft;
  429. Bounds.Top:=ATop;
  430. Bounds.Right:=ALeft+AWidth;
  431. Bounds.Bottom:=ATop+AHeight;
  432. end;
  433. function Point(x,y : Integer) : TPoint; inline;
  434. begin
  435. Point.x:=x;
  436. Point.y:=y;
  437. end;
  438. function PointF(x,y: Single) : TPointF; inline;
  439. begin
  440. PointF.x:=x;
  441. PointF.y:=y;
  442. end;
  443. function PtInRect(const Rect : TRect;const p : TPoint) : Boolean;
  444. begin
  445. PtInRect:=(p.y>=Rect.Top) and
  446. (p.y<Rect.Bottom) and
  447. (p.x>=Rect.Left) and
  448. (p.x<Rect.Right);
  449. end;
  450. function IntersectRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
  451. var
  452. lRect: TRect;
  453. begin
  454. lRect := R1;
  455. if R2.Left > R1.Left then
  456. lRect.Left := R2.Left;
  457. if R2.Top > R1.Top then
  458. lRect.Top := R2.Top;
  459. if R2.Right < R1.Right then
  460. lRect.Right := R2.Right;
  461. if R2.Bottom < R1.Bottom then
  462. lRect.Bottom := R2.Bottom;
  463. // The var parameter is only assigned in the end to avoid problems
  464. // when passing the same rectangle in the var and const parameters.
  465. // See http://bugs.freepascal.org/view.php?id=17722
  466. if IsRectEmpty(lRect) then
  467. begin
  468. FillChar(Rect,SizeOf(Rect),0);
  469. IntersectRect:=false;
  470. end
  471. else
  472. begin
  473. IntersectRect:=true;
  474. Rect := lRect;
  475. end;
  476. end;
  477. function UnionRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
  478. var
  479. lRect: TRect;
  480. begin
  481. lRect:=R1;
  482. if R2.Left<R1.Left then
  483. lRect.Left:=R2.Left;
  484. if R2.Top<R1.Top then
  485. lRect.Top:=R2.Top;
  486. if R2.Right>R1.Right then
  487. lRect.Right:=R2.Right;
  488. if R2.Bottom>R1.Bottom then
  489. lRect.Bottom:=R2.Bottom;
  490. if IsRectEmpty(lRect) then
  491. begin
  492. FillChar(Rect,SizeOf(Rect),0);
  493. UnionRect:=false;
  494. end
  495. else
  496. begin
  497. Rect:=lRect;
  498. UnionRect:=true;
  499. end;
  500. end;
  501. function IsRectEmpty(const Rect : TRect) : Boolean;
  502. begin
  503. IsRectEmpty:=(Rect.Right<=Rect.Left) or (Rect.Bottom<=Rect.Top);
  504. end;
  505. function OffsetRect(var Rect : TRect;DX : Integer;DY : Integer) : Boolean;
  506. begin
  507. if assigned(@Rect) then
  508. begin
  509. with Rect do
  510. begin
  511. inc(Left,dx);
  512. inc(Top,dy);
  513. inc(Right,dx);
  514. inc(Bottom,dy);
  515. end;
  516. OffsetRect:=true;
  517. end
  518. else
  519. OffsetRect:=false;
  520. end;
  521. function Avg(a, b: Longint): Longint;
  522. begin
  523. if a < b then
  524. Result := a + ((b - a) shr 1)
  525. else
  526. Result := b + ((a - b) shr 1);
  527. end;
  528. function CenterPoint(const Rect: TRect): TPoint;
  529. begin
  530. with Rect do
  531. begin
  532. Result.X := Avg(Left, Right);
  533. Result.Y := Avg(Top, Bottom);
  534. end;
  535. end;
  536. function InflateRect(var Rect: TRect; dx: Integer; dy: Integer): Boolean;
  537. begin
  538. if Assigned(@Rect) then
  539. begin
  540. with Rect do
  541. begin
  542. dec(Left, dx);
  543. dec(Top, dy);
  544. inc(Right, dx);
  545. inc(Bottom, dy);
  546. end;
  547. Result := True;
  548. end
  549. else
  550. Result := False;
  551. end;
  552. function Size(AWidth, AHeight: Integer): TSize; inline;
  553. begin
  554. Result.cx := AWidth;
  555. Result.cy := AHeight;
  556. end;
  557. function Size(const ARect: TRect): TSize; inline;
  558. begin
  559. Result.cx := ARect.Right - ARect.Left;
  560. Result.cy := ARect.Bottom - ARect.Top;
  561. end;
  562. { TPointF}
  563. function TPointF.Add(const apt: TPoint): TPointF;
  564. begin
  565. result.x:=x+apt.x;
  566. result.y:=y+apt.y;
  567. end;
  568. function TPointF.Add(const apt: TPointF): TPointF;
  569. begin
  570. result.x:=x+apt.x;
  571. result.y:=y+apt.y;
  572. end;
  573. function TPointF.Subtract(const apt : TPointF): TPointF;
  574. begin
  575. result.x:=x-apt.x;
  576. result.y:=y-apt.y;
  577. end;
  578. function TPointF.Subtract(const apt: TPoint): TPointF;
  579. begin
  580. result.x:=x-apt.x;
  581. result.y:=y-apt.y;
  582. end;
  583. function TPointF.Distance(const apt : TPointF) : Single;
  584. begin
  585. result:=sqrt(sqr(apt.x-x)+sqr(apt.y-y));
  586. end;
  587. function TPointF.DotProduct(const apt: TPointF): Single;
  588. begin
  589. result:=x*apt.x+y*apt.y;
  590. end;
  591. function TPointF.IsZero : Boolean;
  592. begin
  593. result:=SameValue(x,0.0) and SameValue(y,0.0);
  594. end;
  595. procedure TPointF.Offset(const apt :TPointF);
  596. begin
  597. x:=x+apt.x;
  598. y:=y+apt.y;
  599. end;
  600. procedure TPointF.Offset(const apt: TPoint);
  601. begin
  602. x:=x+apt.x;
  603. y:=y+apt.y;
  604. end;
  605. procedure TPointF.Offset(dx,dy : Longint);
  606. begin
  607. x:=x+dx;
  608. y:=y+dy;
  609. end;
  610. function TPointF.Scale(afactor: Single): TPointF;
  611. begin
  612. result.x:=afactor*x;
  613. result.y:=afactor*y;
  614. end;
  615. function TPointF.Ceiling: TPoint;
  616. begin
  617. result.x:=ceil(x);
  618. result.y:=ceil(y);
  619. end;
  620. function TPointF.Truncate: TPoint;
  621. begin
  622. result.x:=trunc(x);
  623. result.y:=trunc(y);
  624. end;
  625. function TPointF.Floor: TPoint;
  626. begin
  627. result.x:=Math.floor(x);
  628. result.y:=Math.floor(y);
  629. end;
  630. function TPointF.Round: TPoint;
  631. begin
  632. result.x:=System.round(x);
  633. result.y:=System.round(y);
  634. end;
  635. function TPointF.Length: Single;
  636. begin //distance(self) ?
  637. result:=sqrt(sqr(x)+sqr(y));
  638. end;
  639. class operator TPointF.= (const apt1, apt2 : TPointF) : Boolean;
  640. begin
  641. result:=SameValue(apt1.x,apt2.x) and SameValue(apt1.y,apt2.y);
  642. end;
  643. class operator TPointF.<> (const apt1, apt2 : TPointF): Boolean;
  644. begin
  645. result:=NOT (SameValue(apt1.x,apt2.x) and Samevalue(apt1.y,apt2.y));
  646. end;
  647. class operator TPointF. * (const apt1, apt2: TPointF): TPointF;
  648. begin
  649. result.x:=apt1.x*apt2.x;
  650. result.y:=apt1.y*apt2.y;
  651. end;
  652. class operator TPointF. * (afactor: single; const apt1: TPointF): TPointF;
  653. begin
  654. result:=apt1.Scale(afactor);
  655. end;
  656. class operator TPointF. * (const apt1: TPointF; afactor: single): TPointF;
  657. begin
  658. result:=apt1.Scale(afactor);
  659. end;
  660. class operator TPointF. ** (const apt1, apt2: TPointF): Single;
  661. begin
  662. result:=apt1.x*apt2.x + apt1.y*apt2.y;
  663. end;
  664. class operator TPointF.+ (const apt1, apt2 : TPointF): TPointF;
  665. begin
  666. result.x:=apt1.x+apt2.x;
  667. result.y:=apt1.y+apt2.y;
  668. end;
  669. class operator TPointF.- (const apt1, apt2 : TPointF): TPointF;
  670. begin
  671. result.x:=apt1.x-apt2.x;
  672. result.y:=apt1.y-apt2.y;
  673. end;
  674. class operator TPointF. - (const apt1: TPointF): TPointF;
  675. begin
  676. Result.x:=-apt1.x;
  677. Result.y:=-apt1.y;
  678. end;
  679. class operator TPointF. / (const apt1: TPointF; afactor: single): TPointF;
  680. begin
  681. result:=apt1.Scale(1/afactor);
  682. end;
  683. class operator TPointF. := (const apt: TPoint): TPointF;
  684. begin
  685. Result.x:=apt.x;
  686. Result.y:=apt.y;
  687. end;
  688. procedure TPointF.SetLocation(const apt :TPointF);
  689. begin
  690. x:=apt.x; y:=apt.y;
  691. end;
  692. procedure TPointF.SetLocation(const apt: TPoint);
  693. begin
  694. x:=apt.x; y:=apt.y;
  695. end;
  696. procedure TPointF.SetLocation(ax,ay : Longint);
  697. begin
  698. x:=ax; y:=ay;
  699. end;
  700. class function TPointF.Create(const ax, ay: Single): TPointF;
  701. begin
  702. Result.x := ax;
  703. Result.y := ay;
  704. end;
  705. class function TPointF.Create(const apt: TPoint): TPointF;
  706. begin
  707. Result.x := apt.X;
  708. Result.y := apt.Y;
  709. end;
  710. { TSizeF }
  711. function TSizeF.Add(const asz: TSize): TSizeF;
  712. begin
  713. result.cx:=cx+asz.cx;
  714. result.cy:=cy+asz.cy;
  715. end;
  716. function TSizeF.Add(const asz: TSizeF): TSizeF;
  717. begin
  718. result.cx:=cx+asz.cx;
  719. result.cy:=cy+asz.cy;
  720. end;
  721. function TSizeF.Subtract(const asz : TSizeF): TSizeF;
  722. begin
  723. result.cx:=cx-asz.cx;
  724. result.cy:=cy-asz.cy;
  725. end;
  726. function TSizeF.Subtract(const asz: TSize): TSizeF;
  727. begin
  728. result.cx:=cx-asz.cx;
  729. result.cy:=cy-asz.cy;
  730. end;
  731. function TSizeF.Distance(const asz : TSizeF) : Single;
  732. begin
  733. result:=sqrt(sqr(asz.cx-cx)+sqr(asz.cy-cy));
  734. end;
  735. function TSizeF.IsZero : Boolean;
  736. begin
  737. result:=SameValue(cx,0.0) and SameValue(cy,0.0);
  738. end;
  739. function TSizeF.Scale(afactor: Single): TSizeF;
  740. begin
  741. result.cx:=afactor*cx;
  742. result.cy:=afactor*cy;
  743. end;
  744. function TSizeF.Ceiling: TSize;
  745. begin
  746. result.cx:=ceil(cx);
  747. result.cy:=ceil(cy);
  748. end;
  749. function TSizeF.Truncate: TSize;
  750. begin
  751. result.cx:=trunc(cx);
  752. result.cy:=trunc(cy);
  753. end;
  754. function TSizeF.Floor: TSize;
  755. begin
  756. result.cx:=Math.floor(cx);
  757. result.cy:=Math.floor(cy);
  758. end;
  759. function TSizeF.Round: TSize;
  760. begin
  761. result.cx:=System.round(cx);
  762. result.cy:=System.round(cy);
  763. end;
  764. function TSizeF.Length: Single;
  765. begin //distance(self) ?
  766. result:=sqrt(sqr(cx)+sqr(cy));
  767. end;
  768. class operator TSizeF.= (const asz1, asz2 : TSizeF) : Boolean;
  769. begin
  770. result:=SameValue(asz1.cx,asz2.cx) and SameValue(asz1.cy,asz2.cy);
  771. end;
  772. class operator TSizeF.<> (const asz1, asz2 : TSizeF): Boolean;
  773. begin
  774. result:=NOT (SameValue(asz1.cx,asz2.cx) and Samevalue(asz1.cy,asz2.cy));
  775. end;
  776. class operator TSizeF. * (afactor: single; const asz1: TSizeF): TSizeF;
  777. begin
  778. result:=asz1.Scale(afactor);
  779. end;
  780. class operator TSizeF. * (const asz1: TSizeF; afactor: single): TSizeF;
  781. begin
  782. result:=asz1.Scale(afactor);
  783. end;
  784. class operator TSizeF.+ (const asz1, asz2 : TSizeF): TSizeF;
  785. begin
  786. result.cx:=asz1.cx+asz2.cx;
  787. result.cy:=asz1.cy+asz2.cy;
  788. end;
  789. class operator TSizeF.- (const asz1, asz2 : TSizeF): TSizeF;
  790. begin
  791. result.cx:=asz1.cx-asz2.cx;
  792. result.cy:=asz1.cy-asz2.cy;
  793. end;
  794. class operator TSizeF. - (const asz1: TSizeF): TSizeF;
  795. begin
  796. Result.cx:=-asz1.cx;
  797. Result.cy:=-asz1.cy;
  798. end;
  799. class operator TSizeF. := (const apt: TPointF): TSizeF;
  800. begin
  801. Result.cx:=apt.x;
  802. Result.cy:=apt.y;
  803. end;
  804. class operator TSizeF. := (const asz: TSize): TSizeF;
  805. begin
  806. Result.cx := asz.cx;
  807. Result.cy := asz.cy;
  808. end;
  809. class operator TSizeF. := (const asz: TSizeF): TPointF;
  810. begin
  811. Result.x := asz.cx;
  812. Result.y := asz.cy;
  813. end;
  814. class function TSizeF.Create(const ax, ay: Single): TSizeF;
  815. begin
  816. Result.cx := ax;
  817. Result.cy := ay;
  818. end;
  819. class function TSizeF.Create(const asz: TSize): TSizeF;
  820. begin
  821. Result.cx := asz.cX;
  822. Result.cy := asz.cY;
  823. end;
  824. { TRectF }
  825. class operator TRectF. * (L, R: TRectF): TRectF;
  826. begin
  827. Result := TRectF.Intersect(L, R);
  828. end;
  829. class operator TRectF. + (L, R: TRectF): TRectF;
  830. begin
  831. Result := TRectF.Union(L, R);
  832. end;
  833. class operator TRectF. := (const arc: TRect): TRectF;
  834. begin
  835. Result.Left:=arc.Left;
  836. Result.Top:=arc.Top;
  837. Result.Right:=arc.Right;
  838. Result.Bottom:=arc.Bottom;
  839. end;
  840. class operator TRectF. <> (L, R: TRectF): Boolean;
  841. begin
  842. Result := not(L=R);
  843. end;
  844. class operator TRectF. = (L, R: TRectF): Boolean;
  845. begin
  846. Result :=
  847. SameValue(L.Left,R.Left) and SameValue(L.Right,R.Right) and
  848. SameValue(L.Top,R.Top) and SameValue(L.Bottom,R.Bottom);
  849. end;
  850. constructor TRectF.Create(ALeft, ATop, ARight, ABottom: Single);
  851. begin
  852. Left := ALeft;
  853. Top := ATop;
  854. Right := ARight;
  855. Bottom := ABottom;
  856. end;
  857. constructor TRectF.Create(P1, P2: TPointF; Normalize: Boolean);
  858. begin
  859. TopLeft := P1;
  860. BottomRight := P2;
  861. if Normalize then
  862. NormalizeRect;
  863. end;
  864. constructor TRectF.Create(Origin: TPointF);
  865. begin
  866. TopLeft := Origin;
  867. BottomRight := Origin;
  868. end;
  869. constructor TRectF.Create(Origin: TPointF; AWidth, AHeight: Single);
  870. begin
  871. TopLeft := Origin;
  872. Width := AWidth;
  873. Height := AHeight;
  874. end;
  875. constructor TRectF.Create(R: TRectF; Normalize: Boolean);
  876. begin
  877. Self := R;
  878. if Normalize then
  879. NormalizeRect;
  880. end;
  881. constructor TRectF.Create(R: TRect; Normalize: Boolean);
  882. begin
  883. Self := R;
  884. if Normalize then
  885. NormalizeRect;
  886. end;
  887. function TRectF.CenterPoint: TPointF;
  888. begin
  889. Result.X := (Right-Left) / 2 + Left;
  890. Result.Y := (Bottom-Top) / 2 + Top;
  891. end;
  892. function TRectF.Contains(Pt: TPointF): Boolean;
  893. begin
  894. Result := (Left <= Pt.X) and (Pt.X < Right) and (Top <= Pt.Y) and (Pt.Y < Bottom);
  895. end;
  896. function TRectF.Contains(R: TRectF): Boolean;
  897. begin
  898. Result := (Left <= R.Left) and (R.Right <= Right) and (Top <= R.Top) and (R.Bottom <= Bottom);
  899. end;
  900. class function TRectF.Empty: TRectF;
  901. begin
  902. Result := TRectF.Create(0,0,0,0);
  903. end;
  904. function TRectF.GetHeight: Single;
  905. begin
  906. result:=bottom-top;
  907. end;
  908. function TRectF.GetLocation: TPointF;
  909. begin
  910. result.x:=Left; result.y:=top;
  911. end;
  912. function TRectF.GetSize: TSizeF;
  913. begin
  914. result.cx:=width; result.cy:=height;
  915. end;
  916. function TRectF.GetWidth: Single;
  917. begin
  918. result:=right-left;
  919. end;
  920. procedure TRectF.Inflate(DX, DY: Single);
  921. begin
  922. Left:=Left-dx;
  923. Top:=Top-dy;
  924. Right:=Right+dx;
  925. Bottom:=Bottom+dy;
  926. end;
  927. procedure TRectF.Intersect(R: TRectF);
  928. begin
  929. Self := Intersect(Self, R);
  930. end;
  931. class function TRectF.Intersect(R1: TRectF; R2: TRectF): TRectF;
  932. begin
  933. Result := R1;
  934. if R2.Left > R1.Left then
  935. Result.Left := R2.Left;
  936. if R2.Top > R1.Top then
  937. Result.Top := R2.Top;
  938. if R2.Right < R1.Right then
  939. Result.Right := R2.Right;
  940. if R2.Bottom < R1.Bottom then
  941. Result.Bottom := R2.Bottom;
  942. end;
  943. function TRectF.IntersectsWith(R: TRectF): Boolean;
  944. begin
  945. Result := (Left < R.Right) and (R.Left < Right) and (Top < R.Bottom) and (R.Top < Bottom);
  946. end;
  947. function TRectF.IsEmpty: Boolean;
  948. begin
  949. Result := (CompareValue(Right,Left)<=0) or (CompareValue(Bottom,Top)<=0);
  950. end;
  951. procedure TRectF.NormalizeRect;
  952. var
  953. x: Single;
  954. begin
  955. if Top>Bottom then
  956. begin
  957. x := Top;
  958. Top := Bottom;
  959. Bottom := x;
  960. end;
  961. if Left>Right then
  962. begin
  963. x := Left;
  964. Left := Right;
  965. Right := x;
  966. end
  967. end;
  968. procedure TRectF.Inflate(DL, DT, DR, DB: Single);
  969. begin
  970. Left:=Left-dl;
  971. Top:=Top-dt;
  972. Right:=Right+dr;
  973. Bottom:=Bottom+db;
  974. end;
  975. procedure TRectF.Offset(const dx, dy: Single);
  976. begin
  977. left:=left+dx; right:=right+dx;
  978. bottom:=bottom+dy; top:=top+dy;
  979. end;
  980. procedure TRectF.Offset(DP: TPointF);
  981. begin
  982. left:=left+DP.x; right:=right+DP.x;
  983. bottom:=bottom+DP.y; top:=top+DP.y;
  984. end;
  985. procedure TRectF.SetHeight(AValue: Single);
  986. begin
  987. bottom:=top+avalue;
  988. end;
  989. procedure TRectF.SetLocation(X, Y: Single);
  990. begin
  991. Offset(X-Left, Y-Top);
  992. end;
  993. procedure TRectF.SetLocation(P: TPointF);
  994. begin
  995. SetLocation(P.X, P.Y);
  996. end;
  997. procedure TRectF.SetSize(AValue: TSizeF);
  998. begin
  999. bottom:=top+avalue.cy;
  1000. right:=left+avalue.cx;
  1001. end;
  1002. procedure TRectF.SetWidth(AValue: Single);
  1003. begin
  1004. right:=left+avalue;
  1005. end;
  1006. class function TRectF.Union(const Points: array of TPointF): TRectF;
  1007. var
  1008. i: Integer;
  1009. begin
  1010. if Length(Points) > 0 then
  1011. begin
  1012. Result.TopLeft := Points[Low(Points)];
  1013. Result.BottomRight := Points[Low(Points)];
  1014. for i := Low(Points)+1 to High(Points) do
  1015. begin
  1016. if Points[i].X < Result.Left then Result.Left := Points[i].X;
  1017. if Points[i].X > Result.Right then Result.Right := Points[i].X;
  1018. if Points[i].Y < Result.Top then Result.Top := Points[i].Y;
  1019. if Points[i].Y > Result.Bottom then Result.Bottom := Points[i].Y;
  1020. end;
  1021. end else
  1022. Result := Empty;
  1023. end;
  1024. procedure TRectF.Union(const r: TRectF);
  1025. begin
  1026. left:=min(r.left,left);
  1027. top:=min(r.top,top);
  1028. right:=max(r.right,right);
  1029. bottom:=max(r.bottom,bottom);
  1030. end;
  1031. class function TRectF.Union(R1, R2: TRectF): TRectF;
  1032. begin
  1033. Result:=R1;
  1034. Result.Union(R2);
  1035. end;
  1036. { TPoint3D }
  1037. constructor TPoint3D.Create(const ax,ay,az:single);
  1038. begin
  1039. x:=ax; y:=ay; z:=az;
  1040. end;
  1041. procedure TPoint3D.Offset(const adeltax,adeltay,adeltaz:single);
  1042. begin
  1043. x:=x+adeltax; y:=y+adeltay; z:=z+adeltaz;
  1044. end;
  1045. procedure TPoint3D.Offset(const adelta:TPoint3D);
  1046. begin
  1047. x:=x+adelta.x; y:=y+adelta.y; z:=z+adelta.z;
  1048. end;
  1049. {$ifndef VER3_0}
  1050. generic class procedure TBitConverter.UnsafeFrom<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0);
  1051. begin
  1052. move(ASrcValue, ADestination[AOffset], SizeOf(T));
  1053. end;
  1054. generic class procedure TBitConverter.From<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0);
  1055. begin
  1056. if AOffset < 0 then
  1057. System.Error(reRangeError);
  1058. if IsManagedType(T) then
  1059. System.Error(reInvalidCast);
  1060. if Length(ADestination) < (SizeOf(T) + AOffset) then
  1061. System.Error(reRangeError);
  1062. TBitConverter.specialize UnsafeFrom<T>(ASrcValue, ADestination, AOffset);
  1063. end;
  1064. generic class function TBitConverter.UnsafeInTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T;
  1065. begin
  1066. move(ASource[AOffset], Result, SizeOf(T));
  1067. end;
  1068. generic class function TBitConverter.InTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T;
  1069. begin
  1070. if AOffset < 0 then
  1071. System.Error(reRangeError);
  1072. if IsManagedType(T) then
  1073. System.Error(reInvalidCast);
  1074. if Length(ASource) < (SizeOf(T) + AOffset) then
  1075. System.Error(reRangeError);
  1076. Result := TBitConverter.specialize UnsafeInTo<T>(ASource, AOffset);
  1077. end;
  1078. {$endif}
  1079. end.