types.pp 38 KB

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