types.pp 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139
  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. CurveKappa = 0.5522847498;
  36. CurveKappaInv = 1 - CurveKappa;
  37. type
  38. TEndian = Objpas.TEndian;
  39. TDirection = (FromBeginning, FromEnd);
  40. TValueRelationship = -1..1;
  41. const
  42. LessThanValue = Low(TValueRelationship);
  43. EqualsValue = 0;
  44. GreaterThanValue = High(TValueRelationship);
  45. type
  46. DWORD = LongWord;
  47. PLongint = System.PLongint;
  48. PSmallInt = System.PSmallInt;
  49. {$ifndef FPUNONE}
  50. PDouble = System.PDouble;
  51. {$endif}
  52. PByte = System.PByte;
  53. Largeint = int64;
  54. LARGE_INT = LargeInt;
  55. PLargeInt = ^LargeInt;
  56. LargeUint = qword;
  57. LARGE_UINT= LargeUInt;
  58. PLargeuInt = ^LargeuInt;
  59. { Null dummy type, for compile time null passing }
  60. TNullPtr = record
  61. { Some operators to make it (more or less) nil compatible }
  62. class operator :=(None: TNullPtr): Pointer; inline;
  63. class operator :=(None: TNullPtr): TObject; inline;
  64. class operator =(LHS: TNullPtr; RHS: Pointer): Boolean; inline;
  65. class operator =(LHS: TNullPtr; RHS: TObject): Boolean; inline;
  66. class operator =(LHS: Pointer; RHS: TNullPtr): Boolean; inline;
  67. class operator =(LHS: TObject; RHS: TNullPtr): Boolean; inline;
  68. class operator <>(LHS: TNullPtr; RHS: Pointer): Boolean; inline;
  69. class operator <>(LHS: TNullPtr; RHS: TObject): Boolean; inline;
  70. class operator <>(LHS: Pointer; RHS: TNullPtr): Boolean; inline;
  71. class operator <>(LHS: TObject; RHS: TNullPtr): Boolean; inline;
  72. end;
  73. {$Push}
  74. {$WriteableConst Off}
  75. const
  76. NullPtr: TNullPtr = ();
  77. {$Pop}
  78. type
  79. TBooleanDynArray = array of Boolean;
  80. TByteDynArray = array of Byte;
  81. TClassicByteDynArray = TByteDynArray;
  82. TCardinalDynArray = array of Cardinal;
  83. TInt64DynArray = array of Int64;
  84. TIntegerDynArray = array of Integer;
  85. TLongWordDynArray = array of LongWord;
  86. TPointerDynArray = array of Pointer;
  87. TQWordDynArray = array of QWord;
  88. TShortIntDynArray = array of ShortInt;
  89. TSmallIntDynArray = array of SmallInt;
  90. TRTLStringDynArray = array of RTLString;
  91. TAnsiStringDynArray = Array of AnsiString;
  92. TWideStringDynArray = array of WideString;
  93. TUnicodeStringDynArray = array of UnicodeString;
  94. {$if SIZEOF(CHAR)=2}
  95. TStringDynArray = Array of UnicodeString;
  96. {$ELSE}
  97. TStringDynArray = Array of AnsiString;
  98. {$ENDIF}
  99. TClassicStringDynArray = TStringDynArray;
  100. TObjectDynArray = array of TObject;
  101. TWordDynArray = array of Word;
  102. TCurrencyArray = Array of currency;
  103. {$ifndef FPUNONE}
  104. TSingleDynArray = array of Single;
  105. TDoubleDynArray = array of Double;
  106. TExtendedDynArray = array of Extended;
  107. TCompDynArray = array of Comp;
  108. {$endif}
  109. {$if defined(win32) or defined(win64) or defined(wince)}
  110. TArray4IntegerType = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TArray4IntegerType;
  111. TSmallPoint = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TSmallPoint;
  112. PSmallPoint = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.PSmallPoint;
  113. TSize = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TSize;
  114. TagSize = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.tagSize deprecated;
  115. PSize = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.PSize;
  116. TPoint = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TPoint;
  117. TagPoint = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TagPoint deprecated;
  118. PPoint = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.PPoint;
  119. TRect = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TRect;
  120. PRect = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.PRect;
  121. TSplitRectType = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TSplitRectType;
  122. const
  123. srLeft = TSplitRectType.srLeft;
  124. srRight = TSplitRectType.srRight;
  125. srTop = TSplitRectType.srTop;
  126. srBottom = TSplitRectType.srBottom;
  127. type
  128. {$else}
  129. {$i typshrdh.inc}
  130. TagSize = tSize deprecated;
  131. TagPoint = TPoint deprecated;
  132. {$endif}
  133. { TPointF }
  134. PPointF = ^TPointF;
  135. TPointF =
  136. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  137. packed
  138. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  139. record
  140. x,y : Single;
  141. public
  142. function Add(const apt: TPoint): TPointF;
  143. function Add(const apt: TPointF): TPointF;
  144. function Distance(const apt : TPointF) : Single;
  145. function DotProduct(const apt : TPointF) : Single;
  146. function IsZero : Boolean;
  147. function Subtract(const apt : TPointF): TPointF;
  148. function Subtract(const apt : TPoint): TPointF;
  149. procedure SetLocation(const apt :TPointF);
  150. procedure SetLocation(const apt :TPoint);
  151. procedure SetLocation(ax,ay : Single);
  152. procedure Offset(const apt :TPointF);
  153. procedure Offset(const apt :TPoint);
  154. procedure Offset(dx,dy : Single);
  155. function EqualsTo(const apt: TPointF; const aEpsilon : Single): Boolean; overload;
  156. function EqualsTo(const apt: TPointF): Boolean; overload;
  157. function Scale (afactor:Single) : TPointF;
  158. function Ceiling : TPoint;
  159. function Truncate: TPoint;
  160. function Floor : TPoint;
  161. function Round : TPoint;
  162. function Length : Single;
  163. function Rotate(angle: single): TPointF;
  164. function Reflect(const normal: TPointF): TPointF;
  165. function MidPoint(const b: TPointF): TPointF;
  166. class function PointInCircle(const pt, center: TPointF; radius: single): Boolean; static;
  167. class function PointInCircle(const pt, center: TPointF; radius: integer): Boolean; static;
  168. class function Zero: TPointF; inline; static;
  169. function Angle(const b: TPointF): Single;
  170. function AngleCosine(const b: TPointF): single;
  171. function CrossProduct(const apt: TPointF): Single;
  172. function Normalize: TPointF;
  173. function ToString(aSize,aDecimals : Byte) : RTLString; overload;
  174. function ToString : RTLString; overload; inline;
  175. class function Create(const ax, ay: Single): TPointF; overload; static; inline;
  176. class function Create(const apt: TPoint): TPointF; overload; static; inline;
  177. class operator = (const apt1, apt2 : TPointF) : Boolean;
  178. class operator <> (const apt1, apt2 : TPointF): Boolean;
  179. class operator + (const apt1, apt2 : TPointF): TPointF;
  180. class operator - (const apt1, apt2 : TPointF): TPointF;
  181. class operator - (const apt1 : TPointF): TPointF;
  182. class operator * (const apt1, apt2: TPointF): TPointF;
  183. class operator * (const apt1: TPointF; afactor: single): TPointF;
  184. class operator * (afactor: single; const apt1: TPointF): TPointF;
  185. class operator / (const apt1: TPointF; afactor: single): TPointF;
  186. class operator := (const apt: TPoint): TPointF;
  187. class operator ** (const apt1, apt2: TPointF): Single; // scalar product
  188. end;
  189. { TSizeF }
  190. PSizeF = ^TSizeF;
  191. TSizeF =
  192. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  193. packed
  194. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  195. record
  196. cx,cy : Single;
  197. public
  198. function Add(const asz: TSize): TSizeF;
  199. function Add(const asz: TSizeF): TSizeF;
  200. function Distance(const asz : TSizeF) : Single;
  201. function IsZero : Boolean;
  202. function Subtract(const asz : TSizeF): TSizeF;
  203. function Subtract(const asz : TSize): TSizeF;
  204. function SwapDimensions:TSizeF;
  205. function Scale (afactor:Single) : TSizeF;
  206. function Ceiling : TSize;
  207. function Truncate: TSize;
  208. function Floor : TSize;
  209. function Round : TSize;
  210. function Length : Single;
  211. function ToString(aSize,aDecimals : Byte) : RTLString; overload;
  212. function ToString : RTLString; overload; inline;
  213. class function Create(const ax, ay: Single): TSizeF; overload; static; inline;
  214. class function Create(const asz: TSize): TSizeF; overload; static; inline;
  215. class function Zero: TSizeF; static;
  216. class operator = (const asz1, asz2 : TSizeF) : Boolean;
  217. class operator <> (const asz1, asz2 : TSizeF): Boolean;
  218. class operator + (const asz1, asz2 : TSizeF): TSizeF;
  219. class operator - (const asz1, asz2 : TSizeF): TSizeF;
  220. class operator - (const asz1 : TSizeF): TSizeF;
  221. class operator * (const asz1: TSizeF; afactor: single): TSizeF;
  222. class operator * (afactor: single; const asz1: TSizeF): TSizeF;
  223. class operator := (const apt: TPointF): TSizeF;
  224. class operator := (const asz: TSize): TSizeF;
  225. class operator := (const asz: TSizeF): TPointF;
  226. property Width: Single read cx write cx;
  227. property Height: Single read cy write cy;
  228. end;
  229. {$SCOPEDENUMS ON}
  230. TVertRectAlign = (Center, Top, Bottom);
  231. THorzRectAlign = (Center, Left, Right);
  232. {$SCOPEDENUMS OFF}
  233. { TRectF }
  234. PRectF = ^TRectF;
  235. TRectF =
  236. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  237. packed
  238. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  239. record
  240. private
  241. function GetLocation: TPointF;
  242. function GetSize: TSizeF;
  243. procedure SetSize(AValue: TSizeF);
  244. function GetHeight: Single; inline;
  245. function GetWidth: Single; inline;
  246. procedure SetHeight(AValue: Single);
  247. procedure SetWidth (AValue: Single);
  248. public
  249. constructor Create(Origin: TPointF); // empty rect at given origin
  250. constructor Create(Origin: TPointF; AWidth, AHeight: Single);
  251. constructor Create(ALeft, ATop, ARight, ABottom: Single);
  252. constructor Create(P1, P2: TPointF; Normalize: Boolean = False);
  253. constructor Create(R: TRectF; Normalize: Boolean = False);
  254. constructor Create(R: TRect; Normalize: Boolean = False);
  255. class operator = (L, R: TRectF): Boolean;
  256. class operator <> (L, R: TRectF): Boolean;
  257. class operator + (L, R: TRectF): TRectF; // union
  258. class operator * (L, R: TRectF): TRectF; // intersection
  259. class operator := (const arc: TRect): TRectF;
  260. class function Empty: TRectF; static;
  261. class function Intersect(R1: TRectF; R2: TRectF): TRectF; static;
  262. class function Union(const Points: array of TPointF): TRectF; static;
  263. class function Union(R1, R2: TRectF): TRectF; static;
  264. Function Ceiling : TRectF;
  265. function CenterAt(const Dest: TRectF): TRectF;
  266. function CenterPoint: TPointF;
  267. function Contains(Pt: TPointF): Boolean;
  268. function Contains(R: TRectF): Boolean;
  269. function EqualsTo(const R: TRectF; const Epsilon: Single = 0): Boolean;
  270. function Fit(const Dest: TRectF): Single; deprecated 'Use FitInto';
  271. function FitInto(const Dest: TRectF): TRectF; overload;
  272. function FitInto(const Dest: TRectF; out Ratio: Single): TRectF; overload;
  273. function IntersectsWith(R: TRectF): Boolean;
  274. function IsEmpty: Boolean;
  275. function PlaceInto(const Dest: TRectF; const AHorzAlign: THorzRectAlign = THorzRectAlign.Center; const AVertAlign: TVertRectAlign = TVertRectAlign.Center): TRectF;
  276. function Round: TRect;
  277. function SnapToPixel(AScale: Single; APlaceBetweenPixels: Boolean = True): TRectF;
  278. function Truncate: TRect;
  279. procedure Inflate(DL, DT, DR, DB: Single);
  280. procedure Inflate(DX, DY: Single);
  281. procedure Intersect(R: TRectF);
  282. procedure Normalize;
  283. procedure NormalizeRect;
  284. procedure Offset (const dx,dy : Single); inline;
  285. procedure Offset (DP: TPointF); inline;
  286. procedure SetLocation(P: TPointF);
  287. procedure SetLocation(X, Y: Single);
  288. function ToString(aSize,aDecimals : Byte; aUseSize : Boolean = False) : RTLString; overload;
  289. function ToString(aUseSize : Boolean = False) : RTLString; overload; inline;
  290. procedure Union (const r: TRectF); inline;
  291. property Width : Single read GetWidth write SetWidth;
  292. property Height : Single read GetHeight write SetHeight;
  293. property Size : TSizeF read getSize write SetSize;
  294. property Location: TPointF read getLocation write setLocation;
  295. case Integer of
  296. 0: (Left, Top, Right, Bottom: Single);
  297. 1: (TopLeft, BottomRight: TPointF);
  298. end;
  299. TDuplicates = (dupIgnore, dupAccept, dupError);
  300. TPoint3D =
  301. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  302. packed
  303. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  304. record
  305. public
  306. Type TSingle3Array = array[0..2] of single;
  307. constructor Create(const ax,ay,az:single);
  308. procedure Offset(const adeltax,adeltay,adeltaz:single); inline;
  309. procedure Offset(const adelta:TPoint3D); inline;
  310. function ToString(aSize,aDecimals : Byte) : RTLString; overload;
  311. function ToString : RTLString; overload; inline;
  312. public
  313. case Integer of
  314. 0: (data:TSingle3Array);
  315. 1: (x,y,z : single);
  316. end;
  317. type
  318. TOleChar = WideChar;
  319. POleStr = PWideChar;
  320. PPOleStr = ^POleStr;
  321. TListCallback = procedure(data,arg:pointer) of object;
  322. TListStaticCallback = procedure(data,arg:pointer);
  323. const
  324. GUID_NULL: TGUID = '{00000000-0000-0000-0000-000000000000}';
  325. STGTY_STORAGE = 1;
  326. STGTY_STREAM = 2;
  327. STGTY_LOCKBYTES = 3;
  328. STGTY_PROPERTY = 4;
  329. STREAM_SEEK_SET = 0;
  330. STREAM_SEEK_CUR = 1;
  331. STREAM_SEEK_END = 2;
  332. LOCK_WRITE = 1;
  333. LOCK_EXCLUSIVE = 2;
  334. LOCK_ONLYONCE = 4;
  335. STATFLAG_DEFAULT = 0;
  336. STATFLAG_NONAME = 1;
  337. STATFLAG_NOOPEN = 2;
  338. {$ifndef Wince}
  339. // in Wince these are in unit windows. Under 32/64 in ActiveX.
  340. // for now duplicate them. Not that bad for untyped constants.
  341. E_FAIL = HRESULT($80004005);
  342. E_INVALIDARG = HRESULT($80070057);
  343. STG_E_INVALIDFUNCTION = HRESULT($80030001);
  344. STG_E_FILENOTFOUND = HRESULT($80030002);
  345. STG_E_PATHNOTFOUND = HRESULT($80030003);
  346. STG_E_TOOMANYOPENFILES = HRESULT($80030004);
  347. STG_E_ACCESSDENIED = HRESULT($80030005);
  348. STG_E_INVALIDHANDLE = HRESULT($80030006);
  349. STG_E_INSUFFICIENTMEMORY = HRESULT($80030008);
  350. STG_E_INVALIDPOINTER = HRESULT($80030009);
  351. STG_E_NOMOREFILES = HRESULT($80030012);
  352. STG_E_DISKISWRITEPROTECTED = HRESULT($80030013);
  353. STG_E_SEEKERROR = HRESULT($80030019);
  354. STG_E_WRITEFAULT = HRESULT($8003001D);
  355. STG_E_READFAULT = HRESULT($8003001E);
  356. STG_E_SHAREVIOLATION = HRESULT($80030020);
  357. STG_E_LOCKVIOLATION = HRESULT($80030021);
  358. STG_E_FILEALREADYEXISTS = HRESULT($80030050);
  359. STG_E_INVALIDPARAMETER = HRESULT($80030057);
  360. STG_E_MEDIUMFULL = HRESULT($80030070);
  361. STG_E_PROPSETMISMATCHED = HRESULT($800300F0);
  362. STG_E_ABNORMALAPIEXIT = HRESULT($800300FA);
  363. STG_E_INVALIDHEADER = HRESULT($800300FB);
  364. STG_E_INVALIDNAME = HRESULT($800300FC);
  365. STG_E_UNKNOWN = HRESULT($800300FD);
  366. STG_E_UNIMPLEMENTEDFUNCTION = HRESULT($800300FE);
  367. STG_E_INVALIDFLAG = HRESULT($800300FF);
  368. STG_E_INUSE = HRESULT($80030100);
  369. STG_E_NOTCURRENT = HRESULT($80030101);
  370. STG_E_REVERTED = HRESULT($80030102);
  371. STG_E_CANTSAVE = HRESULT($80030103);
  372. STG_E_OLDFORMAT = HRESULT($80030104);
  373. STG_E_OLDDLL = HRESULT($80030105);
  374. STG_E_SHAREREQUIRED = HRESULT($80030106);
  375. STG_E_EXTANTMARSHALLINGS = HRESULT($80030108);
  376. STG_E_DOCFILECORRUPT = HRESULT($80030109);
  377. STG_E_BADBASEADDRESS = HRESULT($80030110);
  378. STG_E_INCOMPLETE = HRESULT($80030201);
  379. STG_E_TERMINATED = HRESULT($80030202);
  380. STG_S_CONVERTED = $00030200;
  381. STG_S_BLOCK = $00030201;
  382. STG_S_RETRYNOW = $00030202;
  383. STG_S_MONITORING = $00030203;
  384. {$endif}
  385. {$if (not defined(win32)) and (not defined(win64)) and (not defined(wince))}
  386. type
  387. PCLSID = PGUID;
  388. TCLSID = TGUID;
  389. PDWord = ^DWord;
  390. PDisplay = Pointer;
  391. PEvent = Pointer;
  392. TXrmOptionDescRec = record
  393. end;
  394. XrmOptionDescRec = TXrmOptionDescRec;
  395. PXrmOptionDescRec = ^TXrmOptionDescRec;
  396. Widget = Pointer;
  397. WidgetClass = Pointer;
  398. ArgList = Pointer;
  399. Region = Pointer;
  400. _FILETIME =
  401. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  402. packed
  403. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  404. record
  405. dwLowDateTime : DWORD;
  406. dwHighDateTime : DWORD;
  407. end;
  408. TFileTime = _FILETIME;
  409. FILETIME = _FILETIME;
  410. PFileTime = ^TFileTime;
  411. {$else}
  412. type
  413. PCLSID = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.PCLSID;
  414. TCLSID = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.CLSID;
  415. TFiletime = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.TFileTime;
  416. Filetime = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.FileTime;
  417. PFiletime = {$IFDEF FPC_DOTTEDUNITS}WinApi.{$ENDIF}Windows.PFileTime;
  418. {$endif Windows}
  419. type
  420. tagSTATSTG = record
  421. pwcsName : POleStr;
  422. dwType : DWord;
  423. cbSize : Large_uint;
  424. mtime : TFileTime;
  425. ctime : TFileTime;
  426. atime : TFileTime;
  427. grfMode : DWord;
  428. grfLocksSupported : DWord;
  429. clsid : TCLSID;
  430. grfStateBits : DWord;
  431. reserved : DWord;
  432. end;
  433. TStatStg = tagSTATSTG;
  434. STATSTG = TStatStg;
  435. PStatStg = ^TStatStg;
  436. { classes depends on these interfaces, we can't use the activex unit in classes though }
  437. IClassFactory = Interface(IUnknown) ['{00000001-0000-0000-C000-000000000046}']
  438. Function CreateInstance(Const unkOuter : IUnknown;Const riid : TGUID;Out vObject) : HResult;StdCall;
  439. Function LockServer(fLock : LongBool) : HResult;StdCall;
  440. End;
  441. ISequentialStream = interface(IUnknown)
  442. ['{0c733a30-2a1c-11ce-ade5-00aa0044773d}']
  443. function Read(pv : Pointer;cb : DWORD;pcbRead : PDWORD) : HRESULT;stdcall;
  444. function Write(pv : Pointer;cb : DWORD;pcbWritten : PDWORD): HRESULT;stdcall;
  445. end;
  446. IStream = interface(ISequentialStream) ['{0000000C-0000-0000-C000-000000000046}']
  447. function Seek(dlibMove : LargeInt; dwOrigin : DWORD; out libNewPosition : LargeUInt) : HResult;stdcall;
  448. function SetSize(libNewSize : LargeUInt) : HRESULT;stdcall;
  449. function CopyTo(stm: IStream;cb : LargeUInt;out cbRead : LargeUInt; out cbWritten : LargeUInt) : HRESULT;stdcall;
  450. function Commit(grfCommitFlags : DWORD) : HRESULT;stdcall;
  451. function Revert : HRESULT;stdcall;
  452. function LockRegion(libOffset : LargeUInt;cb : LargeUInt; dwLockType : DWORD) : HRESULT;stdcall;
  453. function UnlockRegion(libOffset : LargeUInt;cb : LargeUInt; dwLockType : DWORD) : HRESULT;stdcall;
  454. Function Stat(out statstg : TStatStg;grfStatFlag : DWORD) : HRESULT;stdcall;
  455. function Clone(out stm : IStream) : HRESULT;stdcall;
  456. end;
  457. { TScoped }
  458. generic TScoped<T:class> = record
  459. private
  460. obj: T;
  461. public
  462. class operator Initialize(var hdl: TScoped);
  463. class operator Finalize(var hdl: TScoped);
  464. class operator :=(aObj : T) : TScoped;
  465. class operator :=(const aObj : TScoped) : T;
  466. procedure Assign(aObj : T); inline;
  467. function Swap(AObj: T): T;
  468. function Get : T;
  469. end;
  470. function EqualRect(const r1,r2 : TRect) : Boolean;
  471. function EqualRect(const r1,r2 : TRectF) : Boolean;
  472. function NormalizeRectF(const Pts: array of TPointF): TRectF; overload;
  473. function NormalizeRect(const ARect: TRectF): TRectF; overload;
  474. function Rect(Left,Top,Right,Bottom : Integer) : TRect; inline;
  475. function RectF(Left,Top,Right,Bottom : Single) : TRectF; inline;
  476. function Bounds(ALeft,ATop,AWidth,AHeight : Integer) : TRect; inline;
  477. function Point(x,y : Integer) : TPoint; inline;
  478. function PointF(x,y: Single) : TPointF; inline;
  479. function PtInRect(const Rect : TRect; const p : TPoint) : Boolean;
  480. function PtInRect(const Rect : TRectF; const p : TPointF) : Boolean;
  481. function IntersectRect(const Rect1, Rect2: TRect): Boolean;
  482. function IntersectRect(const Rect1, Rect2: TRectF): Boolean;
  483. function IntersectRect(var Rect : TRect; const R1,R2 : TRect) : Boolean;
  484. function IntersectRect(var Rect : TRectF; const R1,R2 : TRectF) : Boolean;
  485. function RectCenter(var R: TRect; const Bounds: TRect): TRect;
  486. function RectCenter(var R: TRectF; const Bounds: TRectF): TRectF;
  487. function RectHeight(const Rect: TRect): Integer; inline;
  488. function RectHeight(const Rect: TRectF): Single; inline;
  489. function RectWidth(const Rect: TRect): Integer; inline;
  490. function RectWidth(const Rect: TRectF): Single; inline;
  491. function UnionRect(var Rect : TRect; const R1,R2 : TRect) : Boolean;
  492. function UnionRect(var Rect : TRectF; const R1,R2 : TRectF) : Boolean;
  493. function UnionRect(const R1,R2 : TRect) : TRect;
  494. function UnionRect(const R1,R2 : TRectF) : TRectF;
  495. function IsRectEmpty(const Rect : TRectF) : Boolean;
  496. function IsRectEmpty(const Rect : TRect) : Boolean;
  497. function OffsetRect(var Rect : TRect;DX : Integer;DY : Integer) : Boolean;
  498. function OffsetRect(var Rect : TRectF;DX : Single;DY : Single) : Boolean;
  499. procedure MultiplyRect(var R: TRectF; const DX, DY: Single);
  500. function CenterPoint(const Rect: TRect): TPoint;
  501. function InflateRect(var Rect: TRect; dx: Integer; dy: Integer): Boolean;
  502. function InflateRect(var Rect: TRectF; dx: single; dy: Single): Boolean;
  503. function Size(AWidth, AHeight: Integer): TSize; inline;
  504. function Size(const ARect: TRect): TSize; inline;
  505. function ScalePoint(const P: TPointF; dX, dY: Single): TPointF; overload;
  506. function ScalePoint(const P: TPoint; dX, dY: Single): TPoint; overload;
  507. function MinPoint(const P1, P2: TPointF): TPointF; overload;
  508. function MinPoint(const P1, P2: TPoint): TPoint; overload;
  509. function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Size: Integer): TRect; overload;
  510. function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Percent: Double): TRect; overload;
  511. function CenteredRect(const SourceRect: TRect; const aCenteredRect: TRect): TRect;
  512. function IntersectRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
  513. function UnionRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
  514. type
  515. TBitConverter = class
  516. generic class procedure UnsafeFrom<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0); static; {inline;}
  517. generic class procedure From<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0); static;
  518. generic class function UnsafeInTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T; static; {inline;}
  519. generic class function InTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T; static;
  520. end;
  521. Const
  522. cPI: Single = 3.141592654;
  523. cPIdiv180: Single = 0.017453292;
  524. cPIdiv2: Single = 1.570796326;
  525. cPIdiv4: Single = 0.785398163;
  526. implementation
  527. {$IFDEF FPC_DOTTEDUNITS}
  528. Uses System.Math;
  529. {$ELSE FPC_DOTTEDUNITS}
  530. Uses Math;
  531. {$ENDIF FPC_DOTTEDUNITS}
  532. {$if (not defined(win32)) and (not defined(win64)) and (not defined(wince))}
  533. {$i typshrd.inc}
  534. {$endif}
  535. function SmallPoint(X, Y: Integer): TSmallPoint; inline; overload;
  536. begin
  537. Result.X:=X;
  538. Result.Y:=Y;
  539. end;
  540. function SmallPoint(XY: LongWord): TSmallPoint; overload;
  541. begin
  542. Result.X:=SmallInt(XY and $0000FFFF);
  543. Result.Y:=SmallInt(XY shr 16);
  544. end;
  545. function MinPoint(const P1, P2: TPointF): TPointF; overload;
  546. begin
  547. Result:=P1;
  548. if (P2.Y<P1.Y)
  549. or ((P2.Y=P1.Y) and (P2.X<P1.X)) then
  550. Result:=P2;
  551. end;
  552. function MinPoint(const P1, P2: TPoint): TPoint; overload;
  553. begin
  554. Result:=P1;
  555. if (P2.Y<P1.Y)
  556. or ((P2.Y=P1.Y) and (P2.X<P1.X)) then
  557. Result:=P2;
  558. end;
  559. function ScalePoint(const P: TPointF; dX, dY: Single): TPointF; overload;
  560. begin
  561. Result.X:=P.X*dX;
  562. Result.Y:=P.Y*dY;
  563. end;
  564. function ScalePoint(const P: TPoint; dX, dY: Single): TPoint; overload;
  565. begin
  566. Result.X:=Round(P.X*dX);
  567. Result.Y:=Round(P.Y*dY);
  568. end;
  569. function NormalizeRectF(const Pts: array of TPointF): TRectF;
  570. var
  571. Pt: TPointF;
  572. begin
  573. Result.Left:=$FFFF;
  574. Result.Top:=$FFFF;
  575. Result.Right:=-$FFFF;
  576. Result.Bottom:=-$FFFF;
  577. for Pt in Pts do
  578. begin
  579. Result.Left:=Min(Pt.X,Result.left);
  580. Result.Top:=Min(Pt.Y,Result.Top);
  581. Result.Right:=Max(Pt.X,Result.Right);
  582. Result.Bottom:=Max(Pt.Y,Result.Bottom);
  583. end;
  584. end;
  585. function NormalizeRect(const aRect : TRectF): TRectF;
  586. begin
  587. With aRect do
  588. Result:=NormalizeRectF([PointF(Left,Top),
  589. PointF(Right,Top),
  590. PointF(Right,Bottom),
  591. PointF(Left,Bottom)]);
  592. end;
  593. function EqualRect(const r1,r2 : TRect) : Boolean;
  594. begin
  595. EqualRect:=(r1.left=r2.left) and (r1.right=r2.right) and (r1.top=r2.top) and (r1.bottom=r2.bottom);
  596. end;
  597. function EqualRect(const r1,r2 : TRectF) : Boolean;
  598. begin
  599. EqualRect:=r1.EqualsTo(r2);
  600. end;
  601. function Rect(Left,Top,Right,Bottom : Integer) : TRect; inline;
  602. begin
  603. Rect.Left:=Left;
  604. Rect.Top:=Top;
  605. Rect.Right:=Right;
  606. Rect.Bottom:=Bottom;
  607. end;
  608. function RectF(Left,Top,Right,Bottom : Single) : TRectF; inline;
  609. begin
  610. RectF.Left:=Left;
  611. RectF.Top:=Top;
  612. RectF.Right:=Right;
  613. RectF.Bottom:=Bottom;
  614. end;
  615. function Bounds(ALeft,ATop,AWidth,AHeight : Integer) : TRect; inline;
  616. begin
  617. Bounds.Left:=ALeft;
  618. Bounds.Top:=ATop;
  619. Bounds.Right:=ALeft+AWidth;
  620. Bounds.Bottom:=ATop+AHeight;
  621. end;
  622. function Point(x,y : Integer) : TPoint; inline;
  623. begin
  624. Point.x:=x;
  625. Point.y:=y;
  626. end;
  627. function PointF(x,y: Single) : TPointF; inline;
  628. begin
  629. PointF.x:=x;
  630. PointF.y:=y;
  631. end;
  632. function PtInRect(const Rect : TRect;const p : TPoint) : Boolean;
  633. begin
  634. PtInRect:=(p.y>=Rect.Top) and
  635. (p.y<Rect.Bottom) and
  636. (p.x>=Rect.Left) and
  637. (p.x<Rect.Right);
  638. end;
  639. function PtInRect(const Rect : TRectF;const p : TPointF) : Boolean;
  640. begin
  641. PtInRect:=(p.y>=Rect.Top) and
  642. (p.y<Rect.Bottom) and
  643. (p.x>=Rect.Left) and
  644. (p.x<Rect.Right);
  645. end;
  646. function IntersectRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
  647. begin
  648. Result:=IntersectRect(Rect,R1,R2);
  649. end;
  650. function UnionRectF(out Rect: TRectF; const R1, R2: TRectF): Boolean;
  651. begin
  652. Result:=UnionRect(Rect,R1,R2);
  653. end;
  654. function IntersectRect(const Rect1, Rect2: TRect): Boolean;
  655. begin
  656. Result:=(Rect1.Left<Rect2.Right)
  657. and (Rect1.Right>Rect2.Left)
  658. and (Rect1.Top<Rect2.Bottom)
  659. and (Rect1.Bottom>Rect2.Top);
  660. end;
  661. function IntersectRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
  662. var
  663. lRect: TRect;
  664. begin
  665. lRect := R1;
  666. if R2.Left > R1.Left then
  667. lRect.Left := R2.Left;
  668. if R2.Top > R1.Top then
  669. lRect.Top := R2.Top;
  670. if R2.Right < R1.Right then
  671. lRect.Right := R2.Right;
  672. if R2.Bottom < R1.Bottom then
  673. lRect.Bottom := R2.Bottom;
  674. // The var parameter is only assigned in the end to avoid problems
  675. // when passing the same rectangle in the var and const parameters.
  676. // See http://bugs.freepascal.org/view.php?id=17722
  677. Result:=not IsRectEmpty(lRect);
  678. if Result then
  679. Rect := lRect
  680. else
  681. FillChar(Rect,SizeOf(Rect),0);
  682. end;
  683. function IntersectRect(const Rect1, Rect2: TRectF): Boolean;
  684. begin
  685. Result:=(Rect1.Left<Rect2.Right)
  686. and (Rect1.Right>Rect2.Left)
  687. and (Rect1.Top<Rect2.Bottom)
  688. and (Rect1.Bottom>Rect2.Top);
  689. end;
  690. function IntersectRect(var Rect : TRectF;const R1,R2 : TRectF) : Boolean;
  691. var
  692. lRect: TRectF;
  693. begin
  694. lRect := R1;
  695. if R2.Left > R1.Left then
  696. lRect.Left := R2.Left;
  697. if R2.Top > R1.Top then
  698. lRect.Top := R2.Top;
  699. if R2.Right < R1.Right then
  700. lRect.Right := R2.Right;
  701. if R2.Bottom < R1.Bottom then
  702. lRect.Bottom := R2.Bottom;
  703. // The var parameter is only assigned in the end to avoid problems
  704. // when passing the same rectangle in the var and const parameters.
  705. // See http://bugs.freepascal.org/view.php?id=17722
  706. Result:=not IsRectEmpty(lRect);
  707. if Result then
  708. Rect := lRect
  709. else
  710. FillChar(Rect,SizeOf(Rect),0);
  711. end;
  712. function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Size: Integer): TRect; overload;
  713. begin
  714. Result:=Rect.SplitRect(SplitType,Size);
  715. end;
  716. function SplitRect(const Rect: TRect; SplitType: TSplitRectType; Percent: Double): TRect; overload;
  717. begin
  718. Result:=Rect.SplitRect(SplitType,Percent);
  719. end;
  720. function CenteredRect(const SourceRect: TRect; const aCenteredRect: TRect): TRect;
  721. var
  722. W,H: Integer;
  723. Center : TPoint;
  724. begin
  725. W:=aCenteredRect.Width;
  726. H:=aCenteredRect.Height;
  727. Center:=SourceRect.CenterPoint;
  728. With Center do
  729. Result:= Rect(X-(W div 2),Y-(H div 2),X+((W+1) div 2),Y+((H+1) div 2));
  730. end;
  731. function RectWidth(const Rect: TRect): Integer;
  732. begin
  733. Result:=Rect.Width;
  734. end;
  735. function RectWidth(const Rect: TRectF): Single;
  736. begin
  737. Result:=Rect.Width;
  738. end;
  739. function RectHeight(const Rect: TRect): Integer; inline;
  740. begin
  741. Result:=Rect.Height;
  742. end;
  743. function RectHeight(const Rect: TRectF): Single; inline;
  744. begin
  745. Result:=Rect.Height
  746. end;
  747. function RectCenter(var R: TRect; const Bounds: TRect): TRect;
  748. var
  749. C : TPoint;
  750. CS : TPoint;
  751. begin
  752. C:=Bounds.CenterPoint;
  753. CS:=R.CenterPoint;
  754. OffsetRect(R,C.X-CS.X,C.Y-CS.Y);
  755. Result:=R;
  756. end;
  757. function RectCenter(var R: TRectF; const Bounds: TRectF): TRectF;
  758. Var
  759. C,CS : TPointF;
  760. begin
  761. C:=Bounds.CenterPoint;
  762. CS:=R.CenterPoint;
  763. OffsetRect(R,C.X-CS.X,C.Y-CS.Y);
  764. Result:=R;
  765. end;
  766. procedure MultiplyRect(var R: TRectF; const DX, DY: Single);
  767. begin
  768. R.Left:=DX*R.Left;
  769. R.Right:=DX*R.Right;
  770. R.Top:=DY*R.Top;
  771. R.Bottom:=DY*R.Bottom;
  772. end;
  773. function UnionRect(const R1,R2 : TRect) : TRect;
  774. begin
  775. Result:=Default(TRect);
  776. UnionRect(Result,R1,R2);
  777. end;
  778. function UnionRect(const R1,R2 : TRectF) : TRectF;
  779. begin
  780. Result:=Default(TRectF);
  781. UnionRect(Result,R1,R2);
  782. end;
  783. function UnionRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
  784. var
  785. lRect: TRect;
  786. begin
  787. if IsRectEmpty(R1) then
  788. lRect:=R2
  789. else if IsRectEmpty(R2) then
  790. lRect:=R1
  791. else
  792. begin
  793. lRect:=R1;
  794. if R2.Left<R1.Left then
  795. lRect.Left:=R2.Left;
  796. if R2.Top<R1.Top then
  797. lRect.Top:=R2.Top;
  798. if R2.Right>R1.Right then
  799. lRect.Right:=R2.Right;
  800. if R2.Bottom>R1.Bottom then
  801. lRect.Bottom:=R2.Bottom;
  802. end;
  803. Result:=not IsRectEmpty(lRect);
  804. if Result then
  805. Rect:=lRect
  806. else
  807. FillChar(Rect,SizeOf(Rect),0);
  808. end;
  809. function UnionRect(var Rect : TRectF;const R1,R2 : TRectF) : Boolean;
  810. var
  811. lRect: TRectF;
  812. begin
  813. lRect:=R1;
  814. if R2.Left<R1.Left then
  815. lRect.Left:=R2.Left;
  816. if R2.Top<R1.Top then
  817. lRect.Top:=R2.Top;
  818. if R2.Right>R1.Right then
  819. lRect.Right:=R2.Right;
  820. if R2.Bottom>R1.Bottom then
  821. lRect.Bottom:=R2.Bottom;
  822. Result:=not IsRectEmpty(lRect);
  823. if Result then
  824. Rect := lRect
  825. else
  826. FillChar(Rect,SizeOf(Rect),0);
  827. end;
  828. function IsRectEmpty(const Rect : TRect) : Boolean;
  829. begin
  830. IsRectEmpty:=(Rect.Right<=Rect.Left) or (Rect.Bottom<=Rect.Top);
  831. end;
  832. function IsRectEmpty(const Rect : TRectF) : Boolean;
  833. begin
  834. IsRectEmpty:=(Rect.Right<=Rect.Left) or (Rect.Bottom<=Rect.Top);
  835. end;
  836. function OffsetRect(var Rect : TRect;DX : Integer;DY : Integer) : Boolean;
  837. begin
  838. Result:=assigned(@Rect);
  839. if Result then
  840. with Rect do
  841. begin
  842. inc(Left,dx);
  843. inc(Top,dy);
  844. inc(Right,dx);
  845. inc(Bottom,dy);
  846. end;
  847. end;
  848. function Avg(a, b: Longint): Longint;
  849. begin
  850. if a < b then
  851. Result := a + ((b - a) shr 1)
  852. else
  853. Result := b + ((a - b) shr 1);
  854. end;
  855. function OffsetRect(var Rect: TRectF; DX: Single; DY: Single): Boolean;
  856. begin
  857. Result:=assigned(@Rect);
  858. if Result then
  859. with Rect do
  860. begin
  861. Left:=Left+dx;
  862. Right:=Right+dx;
  863. Top:=Top+dy;
  864. Bottom:=Bottom+dy;
  865. end;
  866. end;
  867. function CenterPoint(const Rect: TRect): TPoint;
  868. begin
  869. with Rect do
  870. begin
  871. Result.X := Avg(Left, Right);
  872. Result.Y := Avg(Top, Bottom);
  873. end;
  874. end;
  875. function InflateRect(var Rect: TRect; dx: Integer; dy: Integer): Boolean;
  876. begin
  877. Result:=assigned(@Rect);
  878. if Result then
  879. with Rect do
  880. begin
  881. dec(Left, dx);
  882. dec(Top, dy);
  883. inc(Right, dx);
  884. inc(Bottom, dy);
  885. end;
  886. end;
  887. function InflateRect(var Rect: TRectF; dx: Single; dy: Single): Boolean;
  888. begin
  889. Result:=assigned(@Rect);
  890. if Result then
  891. with Rect do
  892. begin
  893. Left:=Left-dx;
  894. Top:=Top-dy;
  895. Right:=Right+dx;
  896. Bottom:=Bottom+dy;
  897. end;
  898. end;
  899. function Size(AWidth, AHeight: Integer): TSize; inline;
  900. begin
  901. Result.cx := AWidth;
  902. Result.cy := AHeight;
  903. end;
  904. function Size(const ARect: TRect): TSize; inline;
  905. begin
  906. Result.cx := ARect.Right - ARect.Left;
  907. Result.cy := ARect.Bottom - ARect.Top;
  908. end;
  909. Function SingleToStr(aValue : Single; aSize,aDecimals : Byte) : ShortString; inline;
  910. var
  911. S : ShortString;
  912. Len,P : Byte;
  913. begin
  914. Str(aValue:aSize:aDecimals,S);
  915. Len:=Length(S);
  916. P:=1;
  917. While (P<=Len) and (S[P]=' ') do
  918. Inc(P);
  919. if P>1 then
  920. Delete(S,1,P-1);
  921. Result:=S;
  922. end;
  923. { TNullPtr }
  924. class operator TNullPtr.:=(None: TNullPtr): Pointer;
  925. begin
  926. Result := nil;
  927. end;
  928. class operator TNullPtr.:=(None: TNullPtr): TObject;
  929. begin
  930. Result := nil;
  931. end;
  932. class operator TNullPtr.=(LHS: TNullPtr; RHS: Pointer): Boolean;
  933. begin
  934. Result := not Assigned(RHS);
  935. end;
  936. class operator TNullPtr.=(LHS: TNullPtr; RHS: TObject): Boolean;
  937. begin
  938. Result := not Assigned(RHS);
  939. end;
  940. class operator TNullPtr.=(LHS: Pointer; RHS: TNullPtr): Boolean;
  941. begin
  942. Result := not Assigned(LHS);
  943. end;
  944. class operator TNullPtr.=(LHS: TObject; RHS: TNullPtr): Boolean;
  945. begin
  946. Result := not Assigned(LHS);
  947. end;
  948. class operator TNullPtr.<>(LHS: TNullPtr; RHS: Pointer): Boolean;
  949. begin
  950. Result := Assigned(RHS);
  951. end;
  952. class operator TNullPtr.<>(LHS: TNullPtr; RHS: TObject): Boolean;
  953. begin
  954. Result := Assigned(RHS);
  955. end;
  956. class operator TNullPtr.<>(LHS: Pointer; RHS: TNullPtr): Boolean;
  957. begin
  958. Result := Assigned(LHS);
  959. end;
  960. class operator TNullPtr.<>(LHS: TObject; RHS: TNullPtr): Boolean;
  961. begin
  962. Result := Assigned(LHS);
  963. end;
  964. { TPointF}
  965. function TPointF.ToString : RTLString;
  966. begin
  967. Result:=ToString(8,2);
  968. end;
  969. function TPointF.ToString(aSize,aDecimals : Byte) : RTLString;
  970. var
  971. Sx,Sy : shortstring;
  972. begin
  973. Sx:=SingleToStr(X,aSize,aDecimals);
  974. Sy:=SingleToStr(Y,aSize,aDecimals);
  975. Result:='('+Sx+','+Sy+')';
  976. end;
  977. function TPointF.Add(const apt: TPoint): TPointF;
  978. begin
  979. result.x:=x+apt.x;
  980. result.y:=y+apt.y;
  981. end;
  982. function TPointF.Add(const apt: TPointF): TPointF;
  983. begin
  984. result.x:=x+apt.x;
  985. result.y:=y+apt.y;
  986. end;
  987. function TPointF.Subtract(const apt : TPointF): TPointF;
  988. begin
  989. result.x:=x-apt.x;
  990. result.y:=y-apt.y;
  991. end;
  992. function TPointF.Subtract(const apt: TPoint): TPointF;
  993. begin
  994. result.x:=x-apt.x;
  995. result.y:=y-apt.y;
  996. end;
  997. function TPointF.Distance(const apt : TPointF) : Single;
  998. begin
  999. result:=sqrt(sqr(apt.x-x)+sqr(apt.y-y));
  1000. end;
  1001. function TPointF.DotProduct(const apt: TPointF): Single;
  1002. begin
  1003. result:=x*apt.x+y*apt.y;
  1004. end;
  1005. function TPointF.IsZero : Boolean;
  1006. begin
  1007. result:=SameValue(x,0.0) and SameValue(y,0.0);
  1008. end;
  1009. procedure TPointF.Offset(const apt :TPointF);
  1010. begin
  1011. x:=x+apt.x;
  1012. y:=y+apt.y;
  1013. end;
  1014. procedure TPointF.Offset(const apt: TPoint);
  1015. begin
  1016. x:=x+apt.x;
  1017. y:=y+apt.y;
  1018. end;
  1019. procedure TPointF.Offset(dx,dy : Single);
  1020. begin
  1021. x:=x+dx;
  1022. y:=y+dy;
  1023. end;
  1024. function TPointF.EqualsTo(const apt: TPointF): Boolean;
  1025. begin
  1026. Result:=EqualsTo(apt,0);
  1027. end;
  1028. function TPointF.EqualsTo(const apt: TPointF; const aEpsilon: Single): Boolean;
  1029. function Eq(a,b : single) : boolean; inline;
  1030. begin
  1031. result:=abs(a-b)<=aEpsilon;
  1032. end;
  1033. begin
  1034. Result:=Eq(X,apt.X) and Eq(Y,apt.Y);
  1035. end;
  1036. function TPointF.Scale(afactor: Single): TPointF;
  1037. begin
  1038. result.x:=afactor*x;
  1039. result.y:=afactor*y;
  1040. end;
  1041. function TPointF.Ceiling: TPoint;
  1042. begin
  1043. result.x:=ceil(x);
  1044. result.y:=ceil(y);
  1045. end;
  1046. function TPointF.Truncate: TPoint;
  1047. begin
  1048. result.x:=trunc(x);
  1049. result.y:=trunc(y);
  1050. end;
  1051. function TPointF.Floor: TPoint;
  1052. begin
  1053. result.x:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(x);
  1054. result.y:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(y);
  1055. end;
  1056. function TPointF.Round: TPoint;
  1057. begin
  1058. result.x:=System.round(x);
  1059. result.y:=System.round(y);
  1060. end;
  1061. function TPointF.Length: Single;
  1062. begin
  1063. result:=sqrt(sqr(x)+sqr(y));
  1064. end;
  1065. function TPointF.Rotate(angle: single): TPointF;
  1066. var
  1067. sina, cosa: single;
  1068. begin
  1069. sincos(angle, sina, cosa);
  1070. result.x := x * cosa - y * sina;
  1071. result.y := x * sina + y * cosa;
  1072. end;
  1073. function TPointF.Reflect(const normal: TPointF): TPointF;
  1074. begin
  1075. result := self + (-2 * normal ** self) * normal;
  1076. end;
  1077. function TPointF.MidPoint(const b: TPointF): TPointF;
  1078. begin
  1079. result.x := 0.5 * (x + b.x);
  1080. result.y := 0.5 * (y + b.y);
  1081. end;
  1082. class function TPointF.Zero: TPointF;
  1083. begin
  1084. Result.X:=0;
  1085. Result.Y:=0;
  1086. end;
  1087. class function TPointF.PointInCircle(const pt, center: TPointF; radius: single): Boolean;
  1088. begin
  1089. result := sqr(center.x - pt.x) + sqr(center.y - pt.y) < sqr(radius);
  1090. end;
  1091. class function TPointF.PointInCircle(const pt, center: TPointF; radius: integer): Boolean;
  1092. begin
  1093. result := sqr(center.x - pt.x) + sqr(center.y - pt.y) < sqr(single(radius));
  1094. end;
  1095. function TPointF.Angle(const b: TPointF): Single;
  1096. begin
  1097. result := ArcTan2(y - b.y, x - b.x);
  1098. end;
  1099. function TPointF.AngleCosine(const b: TPointF): single;
  1100. begin
  1101. result := EnsureRange((self ** b) / sqrt((sqr(x) + sqr(y)) * (sqr(b.x) + sqr(b.y))), -1, 1);
  1102. end;
  1103. class operator TPointF.= (const apt1, apt2 : TPointF) : Boolean;
  1104. begin
  1105. result:=SameValue(apt1.x,apt2.x) and SameValue(apt1.y,apt2.y);
  1106. end;
  1107. class operator TPointF.<> (const apt1, apt2 : TPointF): Boolean;
  1108. begin
  1109. result:=NOT (SameValue(apt1.x,apt2.x) and Samevalue(apt1.y,apt2.y));
  1110. end;
  1111. class operator TPointF. * (const apt1, apt2: TPointF): TPointF;
  1112. begin
  1113. result.x:=apt1.x*apt2.x;
  1114. result.y:=apt1.y*apt2.y;
  1115. end;
  1116. class operator TPointF. * (afactor: single; const apt1: TPointF): TPointF;
  1117. begin
  1118. result:=apt1.Scale(afactor);
  1119. end;
  1120. class operator TPointF. * (const apt1: TPointF; afactor: single): TPointF;
  1121. begin
  1122. result:=apt1.Scale(afactor);
  1123. end;
  1124. class operator TPointF. ** (const apt1, apt2: TPointF): Single;
  1125. begin
  1126. result:=apt1.x*apt2.x + apt1.y*apt2.y;
  1127. end;
  1128. class operator TPointF.+ (const apt1, apt2 : TPointF): TPointF;
  1129. begin
  1130. result.x:=apt1.x+apt2.x;
  1131. result.y:=apt1.y+apt2.y;
  1132. end;
  1133. class operator TPointF.- (const apt1, apt2 : TPointF): TPointF;
  1134. begin
  1135. result.x:=apt1.x-apt2.x;
  1136. result.y:=apt1.y-apt2.y;
  1137. end;
  1138. class operator TPointF. - (const apt1: TPointF): TPointF;
  1139. begin
  1140. Result.x:=-apt1.x;
  1141. Result.y:=-apt1.y;
  1142. end;
  1143. class operator TPointF. / (const apt1: TPointF; afactor: single): TPointF;
  1144. begin
  1145. result:=apt1.Scale(1/afactor);
  1146. end;
  1147. class operator TPointF. := (const apt: TPoint): TPointF;
  1148. begin
  1149. Result.x:=apt.x;
  1150. Result.y:=apt.y;
  1151. end;
  1152. procedure TPointF.SetLocation(const apt :TPointF);
  1153. begin
  1154. x:=apt.x; y:=apt.y;
  1155. end;
  1156. procedure TPointF.SetLocation(const apt: TPoint);
  1157. begin
  1158. x:=apt.x; y:=apt.y;
  1159. end;
  1160. procedure TPointF.SetLocation(ax,ay : Single);
  1161. begin
  1162. x:=ax; y:=ay;
  1163. end;
  1164. class function TPointF.Create(const ax, ay: Single): TPointF;
  1165. begin
  1166. Result.x := ax;
  1167. Result.y := ay;
  1168. end;
  1169. class function TPointF.Create(const apt: TPoint): TPointF;
  1170. begin
  1171. Result.x := apt.X;
  1172. Result.y := apt.Y;
  1173. end;
  1174. function TPointF.CrossProduct(const apt: TPointF): Single;
  1175. begin
  1176. Result:=X*apt.Y-Y*apt.X;
  1177. end;
  1178. function TPointF.Normalize: TPointF;
  1179. var
  1180. L: Single;
  1181. begin
  1182. L:=Sqrt(Sqr(X)+Sqr(Y));
  1183. if SameValue(L,0,Epsilon) then
  1184. Result:=Self
  1185. else
  1186. begin
  1187. Result.X:=X/L;
  1188. Result.Y:=Y/L;
  1189. end;
  1190. end;
  1191. { TSizeF }
  1192. function TSizeF.ToString(aSize,aDecimals : Byte) : RTLString;
  1193. var
  1194. Sx,Sy : shortstring;
  1195. begin
  1196. Sx:=SingleToStr(cx,aSize,aDecimals);
  1197. Sy:=SingleToStr(cy,aSize,aDecimals);
  1198. Result:='('+Sx+'x'+Sy+')';
  1199. end;
  1200. function TSizeF.ToString : RTLString;
  1201. begin
  1202. Result:=ToString(8,2);
  1203. end;
  1204. function TSizeF.Add(const asz: TSize): TSizeF;
  1205. begin
  1206. result.cx:=cx+asz.cx;
  1207. result.cy:=cy+asz.cy;
  1208. end;
  1209. function TSizeF.Add(const asz: TSizeF): TSizeF;
  1210. begin
  1211. result.cx:=cx+asz.cx;
  1212. result.cy:=cy+asz.cy;
  1213. end;
  1214. function TSizeF.Subtract(const asz : TSizeF): TSizeF;
  1215. begin
  1216. result.cx:=cx-asz.cx;
  1217. result.cy:=cy-asz.cy;
  1218. end;
  1219. function TSizeF.SwapDimensions:TSizeF;
  1220. begin
  1221. result.cx:=cy;
  1222. result.cy:=cx;
  1223. end;
  1224. function TSizeF.Subtract(const asz: TSize): TSizeF;
  1225. begin
  1226. result.cx:=cx-asz.cx;
  1227. result.cy:=cy-asz.cy;
  1228. end;
  1229. function TSizeF.Distance(const asz : TSizeF) : Single;
  1230. begin
  1231. result:=sqrt(sqr(asz.cx-cx)+sqr(asz.cy-cy));
  1232. end;
  1233. function TSizeF.IsZero : Boolean;
  1234. begin
  1235. result:=SameValue(cx,0.0) and SameValue(cy,0.0);
  1236. end;
  1237. function TSizeF.Scale(afactor: Single): TSizeF;
  1238. begin
  1239. result.cx:=afactor*cx;
  1240. result.cy:=afactor*cy;
  1241. end;
  1242. function TSizeF.Ceiling: TSize;
  1243. begin
  1244. result.cx:=ceil(cx);
  1245. result.cy:=ceil(cy);
  1246. end;
  1247. function TSizeF.Truncate: TSize;
  1248. begin
  1249. result.cx:=trunc(cx);
  1250. result.cy:=trunc(cy);
  1251. end;
  1252. function TSizeF.Floor: TSize;
  1253. begin
  1254. result.cx:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(cx);
  1255. result.cy:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}Math.floor(cy);
  1256. end;
  1257. function TSizeF.Round: TSize;
  1258. begin
  1259. result.cx:=System.round(cx);
  1260. result.cy:=System.round(cy);
  1261. end;
  1262. function TSizeF.Length: Single;
  1263. begin //distance(self) ?
  1264. result:=sqrt(sqr(cx)+sqr(cy));
  1265. end;
  1266. class operator TSizeF.= (const asz1, asz2 : TSizeF) : Boolean;
  1267. begin
  1268. result:=SameValue(asz1.cx,asz2.cx) and SameValue(asz1.cy,asz2.cy);
  1269. end;
  1270. class operator TSizeF.<> (const asz1, asz2 : TSizeF): Boolean;
  1271. begin
  1272. result:=NOT (SameValue(asz1.cx,asz2.cx) and Samevalue(asz1.cy,asz2.cy));
  1273. end;
  1274. class operator TSizeF. * (afactor: single; const asz1: TSizeF): TSizeF;
  1275. begin
  1276. result:=asz1.Scale(afactor);
  1277. end;
  1278. class operator TSizeF. * (const asz1: TSizeF; afactor: single): TSizeF;
  1279. begin
  1280. result:=asz1.Scale(afactor);
  1281. end;
  1282. class operator TSizeF.+ (const asz1, asz2 : TSizeF): TSizeF;
  1283. begin
  1284. result.cx:=asz1.cx+asz2.cx;
  1285. result.cy:=asz1.cy+asz2.cy;
  1286. end;
  1287. class operator TSizeF.- (const asz1, asz2 : TSizeF): TSizeF;
  1288. begin
  1289. result.cx:=asz1.cx-asz2.cx;
  1290. result.cy:=asz1.cy-asz2.cy;
  1291. end;
  1292. class operator TSizeF. - (const asz1: TSizeF): TSizeF;
  1293. begin
  1294. Result.cx:=-asz1.cx;
  1295. Result.cy:=-asz1.cy;
  1296. end;
  1297. class operator TSizeF. := (const apt: TPointF): TSizeF;
  1298. begin
  1299. Result.cx:=apt.x;
  1300. Result.cy:=apt.y;
  1301. end;
  1302. class operator TSizeF. := (const asz: TSize): TSizeF;
  1303. begin
  1304. Result.cx := asz.cx;
  1305. Result.cy := asz.cy;
  1306. end;
  1307. class operator TSizeF. := (const asz: TSizeF): TPointF;
  1308. begin
  1309. Result.x := asz.cx;
  1310. Result.y := asz.cy;
  1311. end;
  1312. class function TSizeF.Zero: TSizeF;
  1313. begin
  1314. Result.cx := 0.0;
  1315. Result.cy := 0.0;
  1316. end;
  1317. class function TSizeF.Create(const ax, ay: Single): TSizeF;
  1318. begin
  1319. Result.cx := ax;
  1320. Result.cy := ay;
  1321. end;
  1322. class function TSizeF.Create(const asz: TSize): TSizeF;
  1323. begin
  1324. Result.cx := asz.cX;
  1325. Result.cy := asz.cY;
  1326. end;
  1327. { TRectF }
  1328. function TRectF.ToString(aSize,aDecimals : Byte; aUseSize : Boolean = False) : RTLString;
  1329. var
  1330. S : RTLString;
  1331. begin
  1332. if aUseSize then
  1333. S:=Size.ToString(aSize,aDecimals)
  1334. else
  1335. S:=BottomRight.ToString(aSize,aDecimals);
  1336. Result:='['+TopLeft.ToString(aSize,aDecimals)+' - '+S+']';
  1337. end;
  1338. function TRectF.ToString(aUseSize: Boolean = False) : RTLString;
  1339. begin
  1340. Result:=ToString(8,2,aUseSize);
  1341. end;
  1342. class operator TRectF. * (L, R: TRectF): TRectF;
  1343. begin
  1344. Result := TRectF.Intersect(L, R);
  1345. end;
  1346. class operator TRectF. + (L, R: TRectF): TRectF;
  1347. begin
  1348. Result := TRectF.Union(L, R);
  1349. end;
  1350. class operator TRectF. := (const arc: TRect): TRectF;
  1351. begin
  1352. Result.Left:=arc.Left;
  1353. Result.Top:=arc.Top;
  1354. Result.Right:=arc.Right;
  1355. Result.Bottom:=arc.Bottom;
  1356. end;
  1357. class operator TRectF. <> (L, R: TRectF): Boolean;
  1358. begin
  1359. Result := not(L=R);
  1360. end;
  1361. class operator TRectF. = (L, R: TRectF): Boolean;
  1362. begin
  1363. Result :=
  1364. SameValue(L.Left,R.Left) and SameValue(L.Right,R.Right) and
  1365. SameValue(L.Top,R.Top) and SameValue(L.Bottom,R.Bottom);
  1366. end;
  1367. constructor TRectF.Create(ALeft, ATop, ARight, ABottom: Single);
  1368. begin
  1369. Left := ALeft;
  1370. Top := ATop;
  1371. Right := ARight;
  1372. Bottom := ABottom;
  1373. end;
  1374. constructor TRectF.Create(P1, P2: TPointF; Normalize: Boolean);
  1375. begin
  1376. TopLeft := P1;
  1377. BottomRight := P2;
  1378. if Normalize then
  1379. NormalizeRect;
  1380. end;
  1381. constructor TRectF.Create(Origin: TPointF);
  1382. begin
  1383. TopLeft := Origin;
  1384. BottomRight := Origin;
  1385. end;
  1386. constructor TRectF.Create(Origin: TPointF; AWidth, AHeight: Single);
  1387. begin
  1388. TopLeft := Origin;
  1389. Width := AWidth;
  1390. Height := AHeight;
  1391. end;
  1392. constructor TRectF.Create(R: TRectF; Normalize: Boolean);
  1393. begin
  1394. Self := R;
  1395. if Normalize then
  1396. NormalizeRect;
  1397. end;
  1398. constructor TRectF.Create(R: TRect; Normalize: Boolean);
  1399. begin
  1400. Self := R;
  1401. if Normalize then
  1402. NormalizeRect;
  1403. end;
  1404. function TRectF.CenterPoint: TPointF;
  1405. begin
  1406. Result.X := (Right-Left) / 2 + Left;
  1407. Result.Y := (Bottom-Top) / 2 + Top;
  1408. end;
  1409. function TRectF.Ceiling: TRectF;
  1410. begin
  1411. Result.BottomRight:=BottomRight.Ceiling;
  1412. Result.TopLeft:=TopLeft.Ceiling;
  1413. end;
  1414. function TRectF.CenterAt(const Dest: TRectF): TRectF;
  1415. begin
  1416. Result:=Self;
  1417. RectCenter(Result,Dest);
  1418. end;
  1419. function TRectF.Fit(const Dest: TRectF): Single;
  1420. var
  1421. R : TRectF;
  1422. begin
  1423. R:=FitInto(Dest,Result);
  1424. Self:=R;
  1425. end;
  1426. function TRectF.FitInto(const Dest: TRectF; out Ratio: Single): TRectF;
  1427. var
  1428. dw, dh, w, h : Single;
  1429. begin
  1430. dw := Dest.Width;
  1431. dh := Dest.Height;
  1432. if (dw <= 0) or (dh <= 0) then
  1433. begin
  1434. Ratio := 1.0;
  1435. exit(Self);
  1436. end;
  1437. w := Self.Width;
  1438. h := Self.Height;
  1439. if w * dh > h * dw then
  1440. Ratio := w / dw
  1441. else
  1442. Ratio := h / dh;
  1443. if Ratio = 0 then
  1444. exit(Self);
  1445. w := w / Ratio;
  1446. h := h / Ratio;
  1447. // Center the result within the Dest rectangle
  1448. Result.Left := (Dest.Left + Dest.Right - w) * 0.5;
  1449. Result.Right := Result.Left + w;
  1450. Result.Top := (Dest.Top + Dest.Bottom - h) * 0.5;
  1451. Result.Bottom := Result.Top + h;
  1452. end;
  1453. function TRectF.FitInto(const Dest: TRectF): TRectF;
  1454. var
  1455. Ratio: Single;
  1456. begin
  1457. Result:=FitInto(Dest,Ratio);
  1458. end;
  1459. function TRectF.PlaceInto(const Dest: TRectF; const AHorzAlign: THorzRectAlign = THorzRectAlign.Center; const AVertAlign: TVertRectAlign = TVertRectAlign.Center): TRectF;
  1460. var
  1461. R : TRectF;
  1462. X,Y : Single;
  1463. D : TRectF absolute dest;
  1464. begin
  1465. if (Height>Dest.Height) or (Width>Dest.Width) then
  1466. R:=FitInto(Dest)
  1467. else
  1468. R:=Self;
  1469. case AHorzAlign of
  1470. THorzRectAlign.Left:
  1471. X:=D.Left;
  1472. THorzRectAlign.Center:
  1473. X:=(D.Left+D.Right-R.Width)/2;
  1474. THorzRectAlign.Right:
  1475. X:=D.Right-R.Width;
  1476. end;
  1477. case AVertAlign of
  1478. TVertRectAlign.Top:
  1479. Y:=D.Top;
  1480. TVertRectAlign.Center:
  1481. Y:=(D.Top+D.Bottom-R.Height)/2;
  1482. TVertRectAlign.Bottom:
  1483. Y:=D.Bottom-R.Height;
  1484. end;
  1485. R.SetLocation(PointF(X,Y));
  1486. Result:=R;
  1487. end;
  1488. function TRectF.SnapToPixel(AScale: Single; APlaceBetweenPixels: Boolean): TRectF;
  1489. function sc (S : single) : single; inline;
  1490. begin
  1491. Result:=System.Trunc(S*AScale)/AScale;
  1492. end;
  1493. var
  1494. R : TRectF;
  1495. Off: Single;
  1496. begin
  1497. if AScale<=0 then
  1498. AScale := 1;
  1499. R.Top:=Sc(Top);
  1500. R.Left:=Sc(Left);
  1501. R.Width:=Sc(Width);
  1502. R.Height:=Sc(Height);
  1503. if APlaceBetweenPixels then
  1504. begin
  1505. Off:=1/(2*aScale);
  1506. R.Offset(Off,Off);
  1507. end;
  1508. Result:=R;
  1509. end;
  1510. function TRectF.Contains(Pt: TPointF): Boolean;
  1511. begin
  1512. Result := (Left <= Pt.X) and (Pt.X < Right) and (Top <= Pt.Y) and (Pt.Y < Bottom);
  1513. end;
  1514. function TRectF.Contains(R: TRectF): Boolean;
  1515. begin
  1516. Result := (Left <= R.Left) and (R.Right <= Right) and (Top <= R.Top) and (R.Bottom <= Bottom);
  1517. end;
  1518. class function TRectF.Empty: TRectF;
  1519. begin
  1520. Result := TRectF.Create(0,0,0,0);
  1521. end;
  1522. function TRectF.EqualsTo(const R: TRectF; const Epsilon: Single): Boolean;
  1523. begin
  1524. Result:=TopLeft.EqualsTo(R.TopLeft,Epsilon);
  1525. Result:=Result and BottomRight.EqualsTo(R.BottomRight,Epsilon);
  1526. end;
  1527. function TRectF.GetHeight: Single;
  1528. begin
  1529. result:=bottom-top;
  1530. end;
  1531. function TRectF.GetLocation: TPointF;
  1532. begin
  1533. result.x:=Left; result.y:=top;
  1534. end;
  1535. function TRectF.GetSize: TSizeF;
  1536. begin
  1537. result.cx:=width; result.cy:=height;
  1538. end;
  1539. function TRectF.GetWidth: Single;
  1540. begin
  1541. result:=right-left;
  1542. end;
  1543. procedure TRectF.Inflate(DX, DY: Single);
  1544. begin
  1545. Left:=Left-dx;
  1546. Top:=Top-dy;
  1547. Right:=Right+dx;
  1548. Bottom:=Bottom+dy;
  1549. end;
  1550. procedure TRectF.Intersect(R: TRectF);
  1551. begin
  1552. Self := Intersect(Self, R);
  1553. end;
  1554. class function TRectF.Intersect(R1: TRectF; R2: TRectF): TRectF;
  1555. begin
  1556. Result := R1;
  1557. if R2.Left > R1.Left then
  1558. Result.Left := R2.Left;
  1559. if R2.Top > R1.Top then
  1560. Result.Top := R2.Top;
  1561. if R2.Right < R1.Right then
  1562. Result.Right := R2.Right;
  1563. if R2.Bottom < R1.Bottom then
  1564. Result.Bottom := R2.Bottom;
  1565. end;
  1566. function TRectF.IntersectsWith(R: TRectF): Boolean;
  1567. begin
  1568. Result := (Left < R.Right) and (R.Left < Right) and (Top < R.Bottom) and (R.Top < Bottom);
  1569. end;
  1570. function TRectF.IsEmpty: Boolean;
  1571. begin
  1572. Result := (CompareValue(Right,Left)<=0) or (CompareValue(Bottom,Top)<=0);
  1573. end;
  1574. procedure TRectF.Normalize;
  1575. var
  1576. x: Single;
  1577. begin
  1578. if Top>Bottom then
  1579. begin
  1580. x := Top;
  1581. Top := Bottom;
  1582. Bottom := x;
  1583. end;
  1584. if Left>Right then
  1585. begin
  1586. x := Left;
  1587. Left := Right;
  1588. Right := x;
  1589. end
  1590. end;
  1591. procedure TRectF.NormalizeRect;
  1592. var
  1593. x: Single;
  1594. begin
  1595. if Top>Bottom then
  1596. begin
  1597. x := Top;
  1598. Top := Bottom;
  1599. Bottom := x;
  1600. end;
  1601. if Left>Right then
  1602. begin
  1603. x := Left;
  1604. Left := Right;
  1605. Right := x;
  1606. end
  1607. end;
  1608. procedure TRectF.Inflate(DL, DT, DR, DB: Single);
  1609. begin
  1610. Left:=Left-dl;
  1611. Top:=Top-dt;
  1612. Right:=Right+dr;
  1613. Bottom:=Bottom+db;
  1614. end;
  1615. procedure TRectF.Offset(const dx, dy: Single);
  1616. begin
  1617. left:=left+dx; right:=right+dx;
  1618. bottom:=bottom+dy; top:=top+dy;
  1619. end;
  1620. procedure TRectF.Offset(DP: TPointF);
  1621. begin
  1622. left:=left+DP.x; right:=right+DP.x;
  1623. bottom:=bottom+DP.y; top:=top+DP.y;
  1624. end;
  1625. function TRectF.Truncate: TRect;
  1626. begin
  1627. Result.BottomRight:=BottomRight.Truncate;
  1628. Result.TopLeft:=TopLeft.Truncate;
  1629. end;
  1630. function TRectF.Round: TRect;
  1631. begin
  1632. Result.BottomRight:=BottomRight.Round;
  1633. Result.TopLeft:=TopLeft.Round;
  1634. end;
  1635. procedure TRectF.SetHeight(AValue: Single);
  1636. begin
  1637. bottom:=top+avalue;
  1638. end;
  1639. procedure TRectF.SetLocation(X, Y: Single);
  1640. begin
  1641. Offset(X-Left, Y-Top);
  1642. end;
  1643. procedure TRectF.SetLocation(P: TPointF);
  1644. begin
  1645. SetLocation(P.X, P.Y);
  1646. end;
  1647. procedure TRectF.SetSize(AValue: TSizeF);
  1648. begin
  1649. bottom:=top+avalue.cy;
  1650. right:=left+avalue.cx;
  1651. end;
  1652. procedure TRectF.SetWidth(AValue: Single);
  1653. begin
  1654. right:=left+avalue;
  1655. end;
  1656. class function TRectF.Union(const Points: array of TPointF): TRectF;
  1657. var
  1658. i: Integer;
  1659. begin
  1660. if Length(Points) > 0 then
  1661. begin
  1662. Result.TopLeft := Points[Low(Points)];
  1663. Result.BottomRight := Points[Low(Points)];
  1664. for i := Low(Points)+1 to High(Points) do
  1665. begin
  1666. if Points[i].X < Result.Left then Result.Left := Points[i].X;
  1667. if Points[i].X > Result.Right then Result.Right := Points[i].X;
  1668. if Points[i].Y < Result.Top then Result.Top := Points[i].Y;
  1669. if Points[i].Y > Result.Bottom then Result.Bottom := Points[i].Y;
  1670. end;
  1671. end else
  1672. Result := Empty;
  1673. end;
  1674. procedure TRectF.Union(const r: TRectF);
  1675. begin
  1676. left:=min(r.left,left);
  1677. top:=min(r.top,top);
  1678. right:=max(r.right,right);
  1679. bottom:=max(r.bottom,bottom);
  1680. end;
  1681. class function TRectF.Union(R1, R2: TRectF): TRectF;
  1682. begin
  1683. Result:=R1;
  1684. Result.Union(R2);
  1685. end;
  1686. { TPoint3D }
  1687. function TPoint3D.ToString(aSize,aDecimals : Byte) : RTLString;
  1688. var
  1689. Sx,Sy,Sz : shortstring;
  1690. P : integer;
  1691. begin
  1692. Sx:=SingleToStr(X,aSize,aDecimals);
  1693. Sy:=SingleToStr(Y,aSize,aDecimals);
  1694. Sz:=SingleToStr(Z,aSize,aDecimals);
  1695. Result:='('+Sx+','+Sy+','+Sz+')';
  1696. end;
  1697. function TPoint3D.ToString : RTLString;
  1698. begin
  1699. Result:=ToString(8,2);
  1700. end;
  1701. constructor TPoint3D.Create(const ax,ay,az:single);
  1702. begin
  1703. x:=ax; y:=ay; z:=az;
  1704. end;
  1705. procedure TPoint3D.Offset(const adeltax,adeltay,adeltaz:single);
  1706. begin
  1707. x:=x+adeltax; y:=y+adeltay; z:=z+adeltaz;
  1708. end;
  1709. procedure TPoint3D.Offset(const adelta:TPoint3D);
  1710. begin
  1711. x:=x+adelta.x; y:=y+adelta.y; z:=z+adelta.z;
  1712. end;
  1713. generic class procedure TBitConverter.UnsafeFrom<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0);
  1714. begin
  1715. move(ASrcValue, ADestination[AOffset], SizeOf(T));
  1716. end;
  1717. generic class procedure TBitConverter.From<T>(const ASrcValue: T; var ADestination: Array of Byte; AOffset: Integer = 0);
  1718. begin
  1719. if AOffset < 0 then
  1720. System.Error(reRangeError);
  1721. if IsManagedType(T) then
  1722. System.Error(reInvalidCast);
  1723. if Length(ADestination) < (SizeOf(T) + AOffset) then
  1724. System.Error(reRangeError);
  1725. TBitConverter.specialize UnsafeFrom<T>(ASrcValue, ADestination, AOffset);
  1726. end;
  1727. generic class function TBitConverter.UnsafeInTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T;
  1728. begin
  1729. move(ASource[AOffset], Result, SizeOf(T));
  1730. end;
  1731. generic class function TBitConverter.InTo<T>(const ASource: Array of Byte; AOffset: Integer = 0): T;
  1732. begin
  1733. if AOffset < 0 then
  1734. System.Error(reRangeError);
  1735. if IsManagedType(T) then
  1736. System.Error(reInvalidCast);
  1737. if Length(ASource) < (SizeOf(T) + AOffset) then
  1738. System.Error(reRangeError);
  1739. Result := TBitConverter.specialize UnsafeInTo<T>(ASource, AOffset);
  1740. end;
  1741. { TScoped }
  1742. class operator TScoped.Initialize(var hdl: TScoped);
  1743. begin
  1744. hdl.obj := nil;
  1745. end;
  1746. class operator TScoped.Finalize(var hdl: TScoped);
  1747. begin
  1748. hdl.obj.free;
  1749. hdl.obj:=nil;
  1750. end;
  1751. procedure TScoped.Assign(aObj : T);
  1752. begin
  1753. Self.Obj:=aObj;
  1754. end;
  1755. function TScoped.Swap(AObj:T):T;
  1756. var
  1757. LCurrent:T;
  1758. begin
  1759. LCurrent := self.obj;
  1760. Assign(AObj);
  1761. Result := LCurrent;
  1762. end;
  1763. function TScoped.Get() : T;
  1764. begin
  1765. Result := self.obj;
  1766. end;
  1767. class operator TScoped.:=(aObj : T) : TScoped;
  1768. begin
  1769. result.assign(aObj);
  1770. end;
  1771. class operator TScoped.:=(const aObj : TScoped) : T;
  1772. begin
  1773. Result:=aObj.Get();
  1774. end;
  1775. end.