types.pp 32 KB

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