GR32_Polygons.pas 105 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239
  1. unit GR32_Polygons;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is Vectorial Polygon Rasterizer for Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Mattias Andersson <[email protected]>
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2008-2012
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * ***** END LICENSE BLOCK ***** *)
  31. interface
  32. {$include GR32.inc}
  33. uses
  34. {$if not defined(FPC)}
  35. System.Types,
  36. {$else}
  37. Types,
  38. {$ifend}
  39. GR32,
  40. GR32_Bindings,
  41. GR32_Containers,
  42. GR32_VPR,
  43. GR32_Transforms,
  44. GR32_Resamplers;
  45. //------------------------------------------------------------------------------
  46. //
  47. // TJoinStyle
  48. //
  49. //------------------------------------------------------------------------------
  50. // Polygon join style
  51. //------------------------------------------------------------------------------
  52. type
  53. TJoinStyle = (
  54. jsMiter, // jsMiter: Edges are offset and extended to intersect with neighboring
  55. // edges. If an intersection is too far away from its vertice, e.g. if
  56. // the angle of the corner is small, then the corner is beveled instead.
  57. // The MiterLimit parameter specifies the maximum ratio between the
  58. // offset value and the distance from the vertice to the corner.
  59. jsBevel, // jsBevel: Cut corners so the point at the end of an edge is perpendicular
  60. // to the vertex that produced the corner.
  61. jsRound, // jsRound: Rounds convex joins.
  62. jsRoundEx, // jsRoundEx: Rounds both convex and concave joins unlike jsRound which
  63. // only rounds convex joins. The depth of convex join rounding is controlled
  64. // by Grow's MiterLimit parameter.
  65. jsSquare // jsSquare: Cut corners so the distance from the vertice producing the
  66. // corner to the midpoint of the corner is the same as the offset distrance.
  67. );
  68. TJoinStyles = set of TJoinStyle;
  69. //------------------------------------------------------------------------------
  70. //
  71. // TEndStyle
  72. //
  73. //------------------------------------------------------------------------------
  74. // Polyline end style
  75. //------------------------------------------------------------------------------
  76. type
  77. TEndStyle = (esButt, esSquare, esRound);
  78. TEndStyles = set of TEndStyle;
  79. //------------------------------------------------------------------------------
  80. //
  81. // TPolyFillMode
  82. //
  83. //------------------------------------------------------------------------------
  84. // Polygon fill mode
  85. //------------------------------------------------------------------------------
  86. type
  87. TPolyFillMode = (
  88. pfAlternate, // Alternate; aka EvenOdd
  89. pfWinding, // Winding; aka NonZero
  90. pfEvenOdd = 0,
  91. pfNonZero
  92. );
  93. //------------------------------------------------------------------------------
  94. //
  95. // TCustomPolygonRenderer
  96. //
  97. //------------------------------------------------------------------------------
  98. type
  99. TCustomPolygonRenderer = class abstract(TThreadPersistent)
  100. public
  101. procedure PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint; const ClipRect: TFloatRect); overload; virtual; abstract;
  102. procedure PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint; const ClipRect: TFloatRect; Transformation: TTransformation); overload; virtual;
  103. procedure PolygonFS(const Points: TArrayOfFloatPoint; const ClipRect: TFloatRect; Transformation: TTransformation); overload; virtual;
  104. procedure PolygonFS(const Points: TArrayOfFloatPoint; const ClipRect: TFloatRect); overload; virtual;
  105. // procedure PolyPolygonXS(const Points: TArrayOfArrayOfFixedPoint; const ClipRect: TFixedRect; Transformation: TTransformation); virtual; overload;
  106. // procedure PolyPolygonXS(const Points: TArrayOfArrayOfFixedPoint; const ClipRect: TFixedRect); virtual; overload;
  107. end;
  108. TCustomPolygonRendererClass = class of TCustomPolygonRenderer;
  109. //------------------------------------------------------------------------------
  110. //
  111. // TPolygonRenderer32
  112. //
  113. //------------------------------------------------------------------------------
  114. TCustomPolygonFiller = class;
  115. TPolygonRenderer32 = class abstract(TCustomPolygonRenderer)
  116. private
  117. FBitmap: TCustomBitmap32;
  118. FFillMode: TPolyFillMode;
  119. FColor: TColor32;
  120. FFiller: TCustomPolygonFiller;
  121. protected
  122. procedure SetBitmap(const Value: TCustomBitmap32); virtual;
  123. procedure SetColor(const Value: TColor32); virtual;
  124. procedure SetFillMode(const Value: TPolyFillMode); virtual;
  125. procedure SetFiller(const Value: TCustomPolygonFiller); virtual;
  126. public
  127. constructor Create(Bitmap: TCustomBitmap32; Fillmode: TPolyFillMode = pfWinding); reintroduce; overload;
  128. procedure PolygonFS(const Points: TArrayOfFloatPoint); overload; virtual;
  129. procedure PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint); overload; virtual;
  130. property Bitmap: TCustomBitmap32 read FBitmap write SetBitmap;
  131. property FillMode: TPolyFillMode read FFillMode write SetFillMode;
  132. property Color: TColor32 read FColor write SetColor;
  133. property Filler: TCustomPolygonFiller read FFiller write SetFiller;
  134. end;
  135. TPolygonRenderer32Class = class of TPolygonRenderer32;
  136. // IPolygonRendererBatching: A polygon renderer can implement this interface
  137. // if it supports batching.
  138. // Graphics32 itself does not take advantage of the interface but applications
  139. // can do so. See the Benchmark example application for usage.
  140. IPolygonRendererBatching = interface
  141. ['{84DE8135-D134-4A4A-B015-C194FA2469F6}']
  142. procedure BeginDraw;
  143. procedure EndDraw;
  144. end;
  145. //------------------------------------------------------------------------------
  146. //
  147. // TPolygonRenderer32VPR
  148. //
  149. //------------------------------------------------------------------------------
  150. // Polygon renderer based on VPR. Computes exact coverages for optimal anti-aliasing.
  151. //------------------------------------------------------------------------------
  152. TFillProc = procedure(Coverage: PSingleArray; AlphaValues: PColor32Array; Count: Integer; Color: TColor32);
  153. TPolygonRenderer32VPR = class(TPolygonRenderer32)
  154. private
  155. FFillProc: TFillProc;
  156. protected
  157. procedure UpdateFillProc;
  158. procedure GetFillProc(var AFillProc: TFillProc); virtual;
  159. procedure RenderSpan(const Span: TValueSpan; DstY: Integer); virtual;
  160. procedure FillSpan(const Span: TValueSpan; DstY: Integer); virtual;
  161. function GetRenderSpan: TRenderSpanEvent; virtual;
  162. property FillProc: TFillProc read FFillProc;
  163. public
  164. procedure PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint;
  165. const ClipRect: TFloatRect); override;
  166. end;
  167. //------------------------------------------------------------------------------
  168. // TPolygonRenderer32LCD
  169. //------------------------------------------------------------------------------
  170. TPolygonRenderer32LCD = class(TPolygonRenderer32VPR)
  171. protected
  172. procedure RenderSpan(const Span: TValueSpan; DstY: Integer); override;
  173. public
  174. procedure PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint;
  175. const ClipRect: TFloatRect); override;
  176. end;
  177. //------------------------------------------------------------------------------
  178. // TPolygonRenderer32LCD2
  179. //------------------------------------------------------------------------------
  180. TPolygonRenderer32LCD2 = class(TPolygonRenderer32LCD)
  181. public
  182. procedure RenderSpan(const Span: TValueSpan; DstY: Integer); override;
  183. end;
  184. //------------------------------------------------------------------------------
  185. //
  186. // TCustomPolygonFiller
  187. //
  188. //------------------------------------------------------------------------------
  189. TFillLineEvent = procedure(Dst: PColor32; DstX, DstY, Length: Integer;
  190. AlphaValues: PColor32; CombineMode: TCombineMode) of object;
  191. TCustomPolygonFiller = class abstract
  192. protected
  193. function GetFillLine: TFillLineEvent; virtual; abstract;
  194. public
  195. procedure BeginRendering; virtual;
  196. procedure EndRendering; virtual;
  197. property FillLine: TFillLineEvent read GetFillLine;
  198. end;
  199. //------------------------------------------------------------------------------
  200. // TCallbackPolygonFiller
  201. //------------------------------------------------------------------------------
  202. TCallbackPolygonFiller = class(TCustomPolygonFiller)
  203. private
  204. FFillLineEvent: TFillLineEvent;
  205. protected
  206. function GetFillLine: TFillLineEvent; override;
  207. public
  208. procedure BeginRendering; override;
  209. property FillLineEvent: TFillLineEvent read FFillLineEvent write FFillLineEvent;
  210. end;
  211. //------------------------------------------------------------------------------
  212. // TInvertPolygonFiller
  213. //------------------------------------------------------------------------------
  214. TInvertPolygonFiller = class(TCustomPolygonFiller)
  215. protected
  216. function GetFillLine: TFillLineEvent; override;
  217. procedure FillLineBlend(Dst: PColor32; DstX, DstY, Length: Integer;
  218. AlphaValues: PColor32; CombineMode: TCombineMode);
  219. end;
  220. //------------------------------------------------------------------------------
  221. // TClearPolygonFiller
  222. //------------------------------------------------------------------------------
  223. TClearPolygonFiller = class(TCustomPolygonFiller)
  224. private
  225. FColor: TColor32;
  226. protected
  227. function GetFillLine: TFillLineEvent; override;
  228. procedure FillLineClear(Dst: PColor32; DstX, DstY,
  229. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  230. public
  231. constructor Create(Color: TColor32 = $00808080); reintroduce; virtual;
  232. property Color: TColor32 read FColor write FColor;
  233. end;
  234. //------------------------------------------------------------------------------
  235. // TBitmapPolygonFiller
  236. //------------------------------------------------------------------------------
  237. TBitmapPolygonFiller = class(TCustomPolygonFiller)
  238. private
  239. FPattern: TCustomBitmap32;
  240. FOffsetY: Integer;
  241. FOffsetX: Integer;
  242. protected
  243. function GetFillLine: TFillLineEvent; override;
  244. procedure FillLineOpaque(Dst: PColor32; DstX, DstY,
  245. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  246. procedure FillLineBlend(Dst: PColor32; DstX, DstY,
  247. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  248. procedure FillLineBlendMasterAlpha(Dst: PColor32; DstX, DstY,
  249. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  250. procedure FillLineCustomCombine(Dst: PColor32; DstX, DstY,
  251. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  252. public
  253. procedure BeginRendering; override;
  254. property Pattern: TCustomBitmap32 read FPattern write FPattern;
  255. property OffsetX: Integer read FOffsetX write FOffsetX;
  256. property OffsetY: Integer read FOffsetY write FOffsetY;
  257. end;
  258. //------------------------------------------------------------------------------
  259. // TSamplerFiller
  260. //------------------------------------------------------------------------------
  261. TSamplerFiller = class(TCustomPolygonFiller)
  262. private
  263. FSampler: TCustomSampler;
  264. FGetSample: TGetSampleInt;
  265. procedure SetSampler(const Value: TCustomSampler);
  266. protected
  267. procedure SamplerChanged; virtual;
  268. function GetFillLine: TFillLineEvent; override;
  269. procedure SampleLineOpaque(Dst: PColor32; DstX, DstY, Length: Integer;
  270. AlphaValues: PColor32; CombineMode: TCombineMode);
  271. public
  272. constructor Create(Sampler: TCustomSampler = nil); reintroduce; virtual;
  273. procedure BeginRendering; override;
  274. procedure EndRendering; override;
  275. property Sampler: TCustomSampler read FSampler write SetSampler;
  276. end;
  277. //------------------------------------------------------------------------------
  278. //
  279. // PolyPolygon and Polygon wrappers
  280. //
  281. //------------------------------------------------------------------------------
  282. // Float, unclipped versions
  283. //------------------------------------------------------------------------------
  284. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  285. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  286. procedure PolyPolygonFS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  287. procedure PolyPolygonFS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  288. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  289. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  290. procedure PolygonFS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  291. procedure PolygonFS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  292. //------------------------------------------------------------------------------
  293. // Float, clipped versions
  294. //------------------------------------------------------------------------------
  295. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  296. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; ClipRect: TRect; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  297. procedure PolyPolygonFS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  298. procedure PolyPolygonFS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint; ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  299. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  300. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; ClipRect: TRect; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  301. procedure PolygonFS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  302. procedure PolygonFS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint; ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  303. //------------------------------------------------------------------------------
  304. // Fixed, unclipped versions
  305. //------------------------------------------------------------------------------
  306. procedure PolyPolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  307. procedure PolyPolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  308. procedure PolyPolygonXS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  309. procedure PolyPolygonXS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  310. procedure PolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  311. procedure PolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil); overload;
  312. procedure PolygonXS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil);
  313. procedure PolygonXS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint; Color: TColor32; FillMode: TPolyFillMode = pfAlternate; Transformation: TTransformation = nil);
  314. //------------------------------------------------------------------------------
  315. //
  316. // PolyPolyline and Polyline wrappers
  317. //
  318. //------------------------------------------------------------------------------
  319. // Float, PolyPolyline
  320. //------------------------------------------------------------------------------
  321. procedure PolyPolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  322. Color: TColor32; Closed: Boolean = False; StrokeWidth: TFloat = 1.0;
  323. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  324. MiterLimit: TFloat = 4.0; Transformation: TTransformation = nil); overload;
  325. procedure PolyPolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  326. Filler: TCustomPolygonFiller; Closed: Boolean = False; StrokeWidth: TFloat = 1.0;
  327. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  328. MiterLimit: TFloat = 4.0; Transformation: TTransformation = nil); overload;
  329. //------------------------------------------------------------------------------
  330. // Float, Polyline
  331. //------------------------------------------------------------------------------
  332. procedure PolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  333. Color: TColor32; Closed: Boolean = False; StrokeWidth: TFloat = 1.0;
  334. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  335. MiterLimit: TFloat = 4.0; Transformation: TTransformation = nil); overload;
  336. procedure PolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  337. Filler: TCustomPolygonFiller; Closed: Boolean = False; StrokeWidth: TFloat = 1.0;
  338. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  339. MiterLimit: TFloat = 4.0; Transformation: TTransformation = nil); overload;
  340. //------------------------------------------------------------------------------
  341. // Fixed, PolyPolyline
  342. //------------------------------------------------------------------------------
  343. procedure PolyPolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  344. Color: TColor32; Closed: Boolean = False; StrokeWidth: TFixed = $10000;
  345. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  346. MiterLimit: TFixed = $40000; Transformation: TTransformation = nil); overload;
  347. procedure PolyPolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  348. Filler: TCustomPolygonFiller; Closed: Boolean = False; StrokeWidth: TFixed = $10000;
  349. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  350. MiterLimit: TFixed = $40000; Transformation: TTransformation = nil); overload;
  351. //------------------------------------------------------------------------------
  352. // Fixed, Polyline
  353. //------------------------------------------------------------------------------
  354. procedure PolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  355. Color: TColor32; Closed: Boolean = False; StrokeWidth: TFixed = $10000;
  356. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  357. MiterLimit: TFixed = $40000; Transformation: TTransformation = nil); overload;
  358. procedure PolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  359. Filler: TCustomPolygonFiller; Closed: Boolean = False; StrokeWidth: TFixed = $10000;
  360. JoinStyle: TJoinStyle = jsMiter; EndStyle: TEndStyle = esButt;
  361. MiterLimit: TFixed = $40000; Transformation: TTransformation = nil); overload;
  362. //------------------------------------------------------------------------------
  363. //
  364. // Dashed lines
  365. //
  366. //------------------------------------------------------------------------------
  367. // Filled only Dashes ...
  368. //------------------------------------------------------------------------------
  369. // Float
  370. //------------------------------------------------------------------------------
  371. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  372. const Dashes: TArrayOfFloat; Color: TColor32;
  373. Closed: Boolean = False; Width: TFloat = 1.0); overload;
  374. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  375. const Dashes: TArrayOfFloat; FillColor, StrokeColor: TColor32;
  376. Closed: Boolean; Width: TFloat; StrokeWidth: TFloat = 2.0); overload;
  377. //------------------------------------------------------------------------------
  378. // Fixed
  379. //------------------------------------------------------------------------------
  380. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  381. const Dashes: TArrayOfFixed; Color: TColor32;
  382. Closed: Boolean = False; Width: TFixed = $10000); overload;
  383. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  384. const Dashes: TArrayOfFixed; FillColor, StrokeColor: TColor32;
  385. Closed: Boolean; Width: TFixed; StrokeWidth: TFixed = $20000); overload;
  386. //------------------------------------------------------------------------------
  387. // Filled and stroked Dashes ...
  388. //------------------------------------------------------------------------------
  389. // Float
  390. //------------------------------------------------------------------------------
  391. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  392. const Dashes: TArrayOfFloat; Filler: TCustomPolygonFiller;
  393. Closed: Boolean = False; Width: TFloat = 1.0); overload;
  394. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  395. const Dashes: TArrayOfFloat; Filler: TCustomPolygonFiller; StrokeColor: TColor32;
  396. Closed: Boolean; Width: TFloat; StrokeWidth: TFloat = 2.0); overload;
  397. //------------------------------------------------------------------------------
  398. // Fixed
  399. //------------------------------------------------------------------------------
  400. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  401. const Dashes: TArrayOfFixed; Filler: TCustomPolygonFiller;
  402. Closed: Boolean = False; Width: TFixed = $10000); overload;
  403. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  404. const Dashes: TArrayOfFixed; Filler: TCustomPolygonFiller; StrokeColor: TColor32;
  405. Closed: Boolean; Width: TFixed; StrokeWidth: TFixed = $20000); overload;
  406. //------------------------------------------------------------------------------
  407. //
  408. // TCustomPolygonFiller wrapper
  409. //
  410. //------------------------------------------------------------------------------
  411. // Fill entire bitmap with a given polygon filler
  412. //------------------------------------------------------------------------------
  413. procedure FillBitmap(Bitmap: TCustomBitmap32; Filler: TCustomPolygonFiller);
  414. //------------------------------------------------------------------------------
  415. //
  416. // Polygon Renderer registration routines
  417. //
  418. //------------------------------------------------------------------------------
  419. procedure RegisterPolygonRenderer(PolygonRendererClass: TCustomPolygonRendererClass);
  420. procedure UnregisterPolygonRenderer(PolygonRendererClass: TCustomPolygonRendererClass);
  421. var
  422. // CustomPolygonRendererList contains all registered renderers.
  423. // It corresponds to the old PolygonRendererList prior to that
  424. // being changed to only contain TPolygonRenderer32 classes.
  425. CustomPolygonRendererList: TCustomClassList<TCustomPolygonRendererClass>;
  426. // PolygonRendererList contains only renderers that inherit from TPolygonRenderer32
  427. PolygonRendererList: TCustomClassList<TPolygonRenderer32Class>;
  428. DefaultPolygonRendererClass: TPolygonRenderer32Class = TPolygonRenderer32VPR;
  429. //------------------------------------------------------------------------------
  430. //
  431. // Bindings
  432. //
  433. //------------------------------------------------------------------------------
  434. function PolygonsRegistry: TFunctionRegistry;
  435. var
  436. // Coverage builders used internally by TPolygonRenderer32VPR
  437. MakeAlphaEvenOddUP: TFillProc;
  438. MakeAlphaNonZeroUP: TFillProc;
  439. MakeAlphaEvenOddUPF: TFillProc;
  440. MakeAlphaNonZeroUPF: TFillProc;
  441. //------------------------------------------------------------------------------
  442. //------------------------------------------------------------------------------
  443. //------------------------------------------------------------------------------
  444. implementation
  445. uses
  446. {$if not defined(FPC)}
  447. System.Math,
  448. System.SysUtils,
  449. {$else}
  450. Math,
  451. SysUtils,
  452. {$ifend}
  453. GR32_Math,
  454. GR32_LowLevel,
  455. GR32_Blend,
  456. GR32_VectorUtils,
  457. GR32.Types.SIMD;
  458. resourcestring
  459. RCStrNoSamplerSpecified = 'No sampler specified!';
  460. type
  461. TBitmap32Access = class(TCustomBitmap32);
  462. //------------------------------------------------------------------------------
  463. //
  464. // Polygon Renderer registration routines
  465. //
  466. //------------------------------------------------------------------------------
  467. procedure RegisterPolygonRenderer(PolygonRendererClass: TCustomPolygonRendererClass);
  468. begin
  469. if (CustomPolygonRendererList = nil) then
  470. CustomPolygonRendererList := TCustomClassList<TCustomPolygonRendererClass>.Create;
  471. if (PolygonRendererList = nil) then
  472. PolygonRendererList := TCustomClassList<TPolygonRenderer32Class>.Create;
  473. CustomPolygonRendererList.Add(PolygonRendererClass);
  474. if (PolygonRendererClass.InheritsFrom(TPolygonRenderer32)) then
  475. PolygonRendererList.Add(TPolygonRenderer32Class(PolygonRendererClass));
  476. end;
  477. procedure UnregisterPolygonRenderer(PolygonRendererClass: TCustomPolygonRendererClass);
  478. begin
  479. if (CustomPolygonRendererList <> nil) then
  480. CustomPolygonRendererList.Remove(PolygonRendererClass);
  481. if (PolygonRendererList <> nil) and (PolygonRendererClass.InheritsFrom(TPolygonRenderer32)) then
  482. PolygonRendererList.Remove(TPolygonRenderer32Class(PolygonRendererClass));
  483. end;
  484. //------------------------------------------------------------------------------
  485. //
  486. // Make Alpha NonZero UP
  487. //
  488. //------------------------------------------------------------------------------
  489. // Coverage builders used internally by TPolygonRenderer32VPR.
  490. // For use in pfWinding/pfNonZero fill mode with a static color.
  491. //------------------------------------------------------------------------------
  492. //------------------------------------------------------------------------------
  493. // MakeAlphaNonZeroUP_Pas
  494. //------------------------------------------------------------------------------
  495. procedure MakeAlphaNonZeroUP_Pas(Coverage: PSingleArray; AlphaValues: PColor32Array;
  496. Count: Integer; Color: TColor32);
  497. var
  498. I: Integer;
  499. M, V: Cardinal;
  500. Last: TFloat;
  501. C: TColor32Entry absolute Color;
  502. begin
  503. (* Mattias Andersson (from [email protected]):
  504. **
  505. ** What is passed in the Coverage[] array is *not* the actual coverages and I
  506. ** agree that using this terminology is ambiguous. The array contains the
  507. ** "winding numbers" which are then processed according to either the even-odd
  508. ** or non-zero rule.
  509. ** An example of how this works can be seen here:
  510. ** http://www.w3.org/TR/SVG11/painting.html#FillProperties
  511. *)
  512. (*
  513. Compute V = Alpha (A) scaled with coverage value (M).
  514. The range of all values are [0..255].
  515. V = A * M / 255
  516. Since we're operating in integers this becomes:
  517. V = A * M div 255
  518. Divisions are expensive and shifts are cheap, so a normal approximation is:
  519. V = (A * M) div 256 ->
  520. V = (A * M) shr 8
  521. If we use the range [0..256] for the coverage value M instead, this can be
  522. improved with the more precise:
  523. V = (A * M * 257) shr 16
  524. Since the coverage is really a floating point value [0..+/-1] the actual
  525. calculation is this:
  526. M = Abs([Coverage * 256])
  527. V = (A * M * 257) shr 16
  528. We can improve the precision even more by calculating M in 9:8 fixed point
  529. format instead of 9:0
  530. M = Abs([Coverage * 256 * 256])
  531. V = (A * M * 257) shr 24
  532. *)
  533. M := C.A * $101; // $101 = 257
  534. Last := Infinity;
  535. for I := 0 to Count - 1 do
  536. begin
  537. // Reuse last computed value if coverage is the same
  538. // Note: Cast to integer to avoid slower floating point comparison
  539. if PInteger(@Last)^ <> PInteger(@Coverage[I])^ then
  540. begin
  541. Last := Coverage[I];
  542. V := Abs(Round(Last * $10000)); // $10000 = 256 * 256
  543. if V > $10000 then
  544. V := $10000;
  545. V := V * M shr 24;
  546. C.A := V;
  547. end;
  548. AlphaValues[I] := Color;
  549. end;
  550. end;
  551. (*
  552. procedure MakeAlphaNonZeroUP(Coverage: PSingleArray; AlphaValues: PColor32Array;
  553. Count: Integer; Color: TColor32);
  554. var
  555. I: Integer;
  556. M, V, C: Cardinal;
  557. begin
  558. M := Color shr 24 * $101;
  559. C := Color and $00ffffff;
  560. for I := 0 to Count - 1 do
  561. begin
  562. V := Abs(Round(Coverage[I] * $10000));
  563. if V > $10000 then V := $10000;
  564. AlphaValues[I] := (V * M and $ff000000) or C;
  565. end;
  566. end;
  567. *)
  568. //------------------------------------------------------------------------------
  569. // MakeAlphaNonZeroUP_SSE2
  570. //------------------------------------------------------------------------------
  571. // Contributed by Kadaif
  572. //------------------------------------------------------------------------------
  573. {$if (not defined(PUREPASCAL)) and (not defined(OMIT_SSE2))}
  574. procedure MakeAlphaNonZeroUP_SSE2(Coverage: PSingleArray; AlphaValues: PColor32Array; Count: integer; Color: TColor32);
  575. // Note: Don't bother aligning the SSE_FloatOne data so we can use
  576. // MOVAPS; It gives zero performance improvement (and might be slower
  577. // due to instruction size).
  578. {$if defined(TARGET_x64) and defined(FPC)}begin{$ifend}
  579. asm
  580. {$if defined(TARGET_x86)}
  581. // Parameters (x86):
  582. // EAX <- Coverage
  583. // EDX <- AlphaValues
  584. // ECX <- Count
  585. // Stack[0] <- Color
  586. // SSE register usage:
  587. // XMM0: work
  588. // XMM1:
  589. // XMM2: [Alpha * 1.0] x 4
  590. // XMM3: [Color without alpha] x 4
  591. // XMM4: [$7FFFFFFF] x 4
  592. // XMM5: [1.0] x 4
  593. TEST ECX, ECX
  594. JLE @EXIT
  595. PUSH EBX
  596. PUSH ESI
  597. PUSH EDI
  598. MOV EDI, Color // save ARGB
  599. MOV EBX, EDI
  600. // Prepare 0RGB: mask off alpha from Color and replicate into XMM3
  601. AND EBX, $00FFFFFF
  602. MOVD XMM3, EBX
  603. PSHUFD XMM3, XMM3, $0 // save 0RGB
  604. // Load constant 1.0 into XMM5
  605. MOVUPS XMM5, DQWORD PTR [SSE_FloatOne]
  606. // Prepare alpha multiplier: extract alpha from Color, replicate and convert to float
  607. SHR EDI, 24 // alpha
  608. MOVD XMM2, EDI
  609. PSHUFD XMM2, XMM2, $0 // alphas
  610. CVTDQ2PS XMM2, XMM2 // to float
  611. // Prepare mask for absolute value (0x7FFFFFFF) in XMM4
  612. PCMPEQD XMM4, XMM4
  613. PSRLD XMM4, 1
  614. CMP ECX, 4
  615. JL @remainder
  616. // Main loop: process 4 elements per iteration
  617. MOV ESI, ECX
  618. SAR ESI, 2
  619. @Loop:
  620. MOVUPS XMM0, [EAX] // Load coverage
  621. ANDPS XMM0, XMM4 // abs
  622. MINPS XMM0, XMM5 // min (1)
  623. MULPS XMM0, XMM2 // multiply with alpha
  624. CVTPS2DQ XMM0, XMM0 // 4xsingle -> 4xinteger
  625. PSLLD XMM0, 24 // A -> A000
  626. POR XMM0, XMM3 // A000 or 0RGB -> ARGB
  627. MOVDQU [EDX], XMM0 // Save ARGB
  628. ADD EDX, 16
  629. ADD EAX, 16
  630. DEC ESI
  631. JNZ @Loop
  632. AND ECX, 3 // get remainder
  633. JZ @END
  634. @remainder:
  635. // Same as above, just on 1 dword/single at a time instead of 4
  636. MOVSS XMM0, [EAX]
  637. ANDPS XMM0, XMM4
  638. MINSS XMM0, XMM5
  639. MULSS XMM0, XMM2
  640. CVTPS2DQ XMM0, XMM0
  641. PSLLD XMM0, 24
  642. POR XMM0, XMM3
  643. MOVD [EDX], XMM0
  644. ADD EDX, 4
  645. ADD EAX, 4
  646. DEC ECX
  647. JNZ @remainder
  648. @END:
  649. POP EDI
  650. POP ESI
  651. POP EBX
  652. @EXIT:
  653. {$elseif defined(TARGET_x64)}
  654. // Parameters (x64):
  655. // RCX <- Coverage
  656. // RDX <- AlphaValues
  657. // R8D <- Count
  658. // R9D <- Color
  659. // SSE register usage:
  660. // XMM0: work
  661. // XMM1:
  662. // XMM2: [Alpha * 1.0] x 4
  663. // XMM3: [Color without alpha] x 4
  664. // XMM4: [$7FFFFFFF] x 4
  665. // XMM5: [1.0] x 4
  666. {$IFNDEF FPC}
  667. .SAVENV XMM4
  668. .SAVENV XMM5
  669. {$ENDIF}
  670. TEST R8D, R8D
  671. JLE @Exit
  672. // Prepare 0RGB: mask off alpha from Color and replicate into XMM3
  673. MOV EAX, R9D
  674. AND EAX, $00FFFFFF
  675. MOVD XMM3, EAX
  676. PSHUFD XMM3, XMM3, 0 // save 0RGB
  677. // Load constant 1.0 into XMM6
  678. {$if (not defined(FPC))}
  679. MOVUPS XMM5, DQWORD PTR [SSE_FloatOne]
  680. {$else}
  681. MOVUPS XMM5, DQWORD PTR [rip+SSE_FloatOne]
  682. {$ifend}
  683. // Prepare alpha multiplier: extract alpha from Color, replicate and convert to float
  684. SHR R9D, 24
  685. MOVD XMM2, R9D
  686. PSHUFD XMM2, XMM2, 0
  687. CVTDQ2PS XMM2, XMM2
  688. // Prepare mask for absolute value (0x7FFFFFFF) in XMM4
  689. PCMPEQD XMM4, XMM4
  690. PSRLD XMM4, 1
  691. CMP R8D, 4
  692. JL @Remainder
  693. // Main loop: process 4 elements per iteration
  694. MOV R10, R8
  695. SHR R10, 2
  696. @Loop:
  697. MOVUPS XMM0, [RCX]
  698. ANDPS XMM0, XMM4
  699. MINPS XMM0, XMM5
  700. MULPS XMM0, XMM2
  701. CVTPS2DQ XMM0, XMM0
  702. PSLLD XMM0, 24
  703. POR XMM0, XMM3
  704. MOVDQU [RDX], XMM0
  705. ADD RCX, 16
  706. ADD RDX, 16
  707. DEC R10
  708. JNZ @Loop
  709. AND R8D, 3
  710. JZ @Exit
  711. @Remainder:
  712. MOVSS XMM0, [RCX]
  713. ANDPS XMM0, XMM4
  714. MINSS XMM0, XMM5
  715. MULSS XMM0, XMM2
  716. CVTSS2SI EAX, XMM0
  717. SHL EAX, 24
  718. MOVD R11D, XMM3
  719. OR EAX, R11D
  720. MOV [RDX], EAX
  721. ADD RCX, 4
  722. ADD RDX, 4
  723. DEC R8D
  724. JNZ @Remainder
  725. @Exit:
  726. {$if defined(FPC)}end['XMM4', 'XMM5'];{$ifend}
  727. {$else}
  728. {$error 'Missing target'}
  729. {$ifend}
  730. end;
  731. {$ifend}
  732. //------------------------------------------------------------------------------
  733. //
  734. // Make Alpha EvenOdd UP
  735. //
  736. //------------------------------------------------------------------------------
  737. // Coverage builders used internally by TPolygonRenderer32VPR.
  738. // For use in pfAlternate/pfEvenOdd fill mode with a static color.
  739. //------------------------------------------------------------------------------
  740. //------------------------------------------------------------------------------
  741. // MakeAlphaEvenOddUP_Pas
  742. //------------------------------------------------------------------------------
  743. procedure MakeAlphaEvenOddUP_Pas(Coverage: PSingleArray; AlphaValues: PColor32Array;
  744. Count: Integer; Color: TColor32);
  745. var
  746. I: Integer;
  747. M, V: Cardinal;
  748. Last: TFloat;
  749. C: TColor32Entry absolute Color;
  750. begin
  751. M := C.A * $101;
  752. Last := Infinity;
  753. for I := 0 to Count - 1 do
  754. begin
  755. if PInteger(@Last)^ <> PInteger(@Coverage[I])^ then
  756. begin
  757. Last := Coverage[I];
  758. V := Abs(Round(Coverage[I] * $10000));
  759. V := V and $01ffff;
  760. if V >= $10000 then
  761. V := V xor $1ffff;
  762. V := V * M shr 24;
  763. C.A := V;
  764. end;
  765. AlphaValues[I] := Color;
  766. end;
  767. end;
  768. //------------------------------------------------------------------------------
  769. // MakeAlphaEvenOddUP_SSE41
  770. //------------------------------------------------------------------------------
  771. // Contributed by Kadaif
  772. //------------------------------------------------------------------------------
  773. {$if (not defined(PUREPASCAL)) and (not defined(OMIT_SSE2))}
  774. procedure MakeAlphaEvenOddUP_SSE2(Coverage: PSingleArray; AlphaValues: PColor32Array; Count: integer; Color: TColor32);
  775. {$if defined(TARGET_x64) and defined(FPC)}begin{$ifend}
  776. asm
  777. {$if defined(TARGET_x86)}
  778. // Parameters (x86):
  779. // EAX <- Coverage
  780. // EDX <- AlphaValues
  781. // ECX <- Count
  782. // Stack[0] <- Color
  783. // SSE register usage:
  784. // XMM0: work
  785. // XMM1: work
  786. // XMM2: [Alpha * 257] x 4
  787. // XMM3: [Color without alpha] x 4
  788. // XMM4: [$7FFFFFFF] x 4
  789. // XMM5: [256x256] x 4
  790. // XMM6: [$0001FFFF] x 4
  791. // XMM7: work
  792. TEST ECX, ECX
  793. JLE @EXIT
  794. PUSH EBX
  795. PUSH ESI
  796. PUSH EDI
  797. MOV EDI, Color
  798. MOV EBX, EDI
  799. AND EBX, $00FFFFFF
  800. MOVD XMM3, EBX
  801. PSHUFD XMM3, XMM3, $0 // save 0RGB
  802. PCMPEQD XMM6, XMM6
  803. PSRLD XMM6, 15 // 4 x $0001FFFF
  804. MOVUPS XMM5, DQWORD PTR [SSE_Float256x256]
  805. SHR EDI, 24 // alpha
  806. MOVD XMM2, EDI
  807. PUNPCKLBW XMM2, XMM2 // alpha * 257
  808. PSHUFD XMM2, XMM2, $0 // alphas
  809. PCMPEQD XMM4, XMM4 // for abs
  810. PSRLD XMM4, 1
  811. CMP ECX, 4
  812. JL @remainder
  813. MOV ESI, ECX
  814. SAR ESI, 2
  815. @Loop:
  816. MOVUPS XMM0, [EAX] // Load overage
  817. ANDPS XMM0, XMM4 // abs
  818. MULPS XMM0, XMM5
  819. CVTPS2DQ XMM0, XMM0
  820. PAND XMM0, XMM6 // and with $0001FFFF
  821. MOVDQA XMM7, XMM0
  822. PXOR XMM7, XMM6
  823. // PMINUD (SSE4.1) for SSE2
  824. MOVDQA XMM1, XMM7
  825. PCMPGTD XMM1, XMM0
  826. PAND XMM0, XMM1
  827. PANDN XMM1, XMM7
  828. POR XMM0, XMM1
  829. // alpha * 257 * Coverage
  830. PMULHUW XMM0, XMM2
  831. PSRLW XMM0, 8
  832. PSLLD XMM0, 24
  833. POR XMM0, XMM3
  834. MOVDQU [EDX], XMM0 // Save ARGB
  835. ADD EAX, 16
  836. ADD EDX, 16
  837. DEC ESI
  838. JNZ @Loop
  839. AND ECX, 3
  840. JZ @END
  841. @remainder:
  842. MOVSS XMM0, [EAX] // coverage
  843. ANDPS XMM0, XMM4 // abs
  844. MULSS XMM0, XMM5
  845. CVTPS2DQ XMM0, XMM0
  846. PAND XMM0, XMM6 // and with $1FF
  847. MOVDQA XMM7, XMM6
  848. PSUBD XMM7, XMM0
  849. MOVDQA XMM1, XMM7
  850. PCMPGTD XMM1, XMM0
  851. PAND XMM0, XMM1
  852. PANDN XMM1, XMM7
  853. POR XMM0, XMM1
  854. PMULHUW XMM0, XMM2
  855. PSRLW XMM0, 8
  856. PSLLD XMM0, 24
  857. POR XMM0, XMM3
  858. MOVD [EDX], XMM0
  859. ADD EDX, 4
  860. ADD EAX, 4
  861. DEC ECX
  862. JNZ @remainder
  863. @END:
  864. POP EDI
  865. POP ESI
  866. POP EBX
  867. @EXIT:
  868. {$elseif defined(TARGET_x64)}
  869. // Parameters (x64):
  870. // RCX <- Coverage
  871. // RDX <- AlphaValues
  872. // R8D <- Count
  873. // R9D <- Color
  874. // SSE register usage:
  875. // XMM0: work
  876. // XMM1: work
  877. // XMM2: [Alpha * 257] x 4
  878. // XMM3: [Color without alpha] x 4
  879. // XMM4: [$7FFFFFFF] x 4
  880. // XMM5: [256x256] x 4
  881. // XMM6: [$0001FFFF] x 4
  882. // XMM7: work
  883. {$IFNDEF FPC}
  884. .SAVENV XMM4
  885. .SAVENV XMM5
  886. .SAVENV XMM6
  887. .SAVENV XMM7
  888. {$ENDIF}
  889. TEST R8D, R8D
  890. JLE @EXIT
  891. (*
  892. SUB RSP, 32
  893. MOVDQU [RSP], XMM6
  894. MOVDQU [RSP + 16], XMM7
  895. *)
  896. MOV R10D, R9D
  897. AND R10D, $00FFFFFF
  898. MOVD XMM3, R10D
  899. PSHUFD XMM3, XMM3,$0 // save 0RGB
  900. PCMPEQD XMM6, XMM6
  901. PSRLD XMM6, 15 // $0001FFFF
  902. {$if (not defined(FPC))}
  903. MOVUPS XMM5, DQWORD PTR [SSE_Float256x256]
  904. {$else}
  905. MOVUPS XMM5, DQWORD PTR [rip+SSE_Float256x256]
  906. {$ifend}
  907. SHR R9D, 24
  908. MOVD XMM2, R9D
  909. PUNPCKLBW XMM2, XMM2 // alpha * 257
  910. PSHUFD XMM2, XMM2, $0 // alphas
  911. PCMPEQD XMM4, XMM4 // for abs
  912. PSRLD XMM4, 1
  913. CMP R8D, 4
  914. JL @remainder
  915. MOV EAX, R8D
  916. SAR EAX, 2
  917. @Loop:
  918. MOVUPS XMM0, [RCX] // coverage
  919. ANDPS XMM0, XMM4 // abs
  920. MULPS XMM0, XMM5 // multiply
  921. CVTPS2DQ XMM0, XMM0
  922. PAND XMM0, XMM6 // and with $0001FFFF
  923. MOVDQA XMM7, XMM0
  924. PXOR XMM7, XMM6
  925. // PMINUD for SSE2
  926. MOVDQA XMM1, XMM7
  927. PCMPGTD XMM1, XMM0
  928. PAND XMM0, XMM1
  929. PANDN XMM1, XMM7
  930. POR XMM0, XMM1
  931. PMULHUW XMM0, XMM2
  932. PSRLW XMM0, 8
  933. PSLLD XMM0, 24
  934. POR XMM0, XMM3
  935. MOVDQU [RDX], XMM0
  936. ADD RCX, 16
  937. ADD RDX, 16
  938. DEC EAX
  939. JNZ @Loop
  940. AND R8D, 3
  941. JZ @END
  942. @remainder:
  943. MOVSS XMM0, [RCX] // coverage
  944. ANDPS XMM0, XMM4 // abs
  945. MULSS XMM0, XMM5
  946. CVTPS2DQ XMM0, XMM0
  947. PAND XMM0, XMM6
  948. MOVDQA XMM7, XMM6
  949. PSUBD XMM7, XMM0
  950. // PMINUD for SSE2
  951. MOVDQA XMM1, XMM7
  952. PCMPGTD XMM1, XMM0
  953. PAND XMM0, XMM1
  954. PANDN XMM1, XMM7
  955. POR XMM0, XMM1
  956. PMULHUW XMM0, XMM2
  957. PSRLW XMM0, 8
  958. PSLLD XMM0, 24
  959. POR XMM0, XMM3
  960. MOVD [RDX], XMM0
  961. ADD RDX,4
  962. ADD RCX,4
  963. DEC R8D
  964. JNZ @remainder
  965. @END:
  966. (*
  967. MOVDQU XMM7, [RSP + 16]
  968. MOVDQU XMM6, [RSP]
  969. ADD RSP, 32
  970. *)
  971. @EXIT:
  972. {$if defined(FPC)}end['XMM4', 'XMM5', 'XMM6', 'XMM7'];{$ifend}
  973. {$else}
  974. {$error 'Missing target'}
  975. {$ifend}
  976. end;
  977. //------------------------------------------------------------------------------
  978. // MakeAlphaEvenOddUP_SSE41
  979. //------------------------------------------------------------------------------
  980. // Contributed by Kadaif
  981. //------------------------------------------------------------------------------
  982. procedure MakeAlphaEvenOddUP_SSE41(Coverage: PSingleArray; AlphaValues: PColor32Array; Count: integer; Color: TColor32);
  983. {$if defined(TARGET_x64) and defined(FPC)}begin{$ifend}
  984. asm
  985. {$if defined(TARGET_x86)}
  986. // Parameters (x86):
  987. // EAX <- Coverage
  988. // EDX <- AlphaValues
  989. // ECX <- Count
  990. // Stack[0] <- Color
  991. // SSE register usage:
  992. // XMM0: work
  993. // XMM1: work
  994. // XMM2: [Alpha * 257] x 4
  995. // XMM3: [Color without alpha] x 4
  996. // XMM4: [$7FFFFFFF] x 4
  997. // XMM5: [256x256] x 4
  998. // XMM6: [$0001FFFF] x 4
  999. // XMM7: work
  1000. TEST ECX,ECX
  1001. JLE @EXIT
  1002. PUSH EBX
  1003. PUSH ESI
  1004. PUSH EDI
  1005. MOV EDI, Color
  1006. MOV EBX, EDI
  1007. AND EBX, $00FFFFFF
  1008. MOVD XMM3, EBX
  1009. PSHUFD XMM3, XMM3, $0 // save 0RGB
  1010. PCMPEQD XMM6, XMM6
  1011. PSRLD XMM6, 15 // $0001FFFF
  1012. MOVUPS XMM5, DQWORD PTR [SSE_Float256x256]
  1013. SHR EDI, 24
  1014. MOVD XMM2, EDI
  1015. PUNPCKLBW XMM2, XMM2 // alpha * 257
  1016. PSHUFD XMM2, XMM2, $0 // alphas
  1017. PCMPEQD XMM4, XMM4 // for abs
  1018. PSRLD XMM4, 1
  1019. CMP ECX, 4
  1020. JL @remainder
  1021. MOV ESI, ECX
  1022. SAR ESI, 2
  1023. @Loop:
  1024. MOVUPS XMM0, [EAX] // Load coverage
  1025. ANDPS XMM0, XMM4 // abs
  1026. MULPS XMM0, XMM5
  1027. CVTPS2DQ XMM0, XMM0
  1028. PAND XMM0, XMM6 // and with $0001FFFF
  1029. MOVDQA XMM7, XMM0
  1030. PXOR XMM7, XMM6
  1031. PMINUD XMM0, XMM7
  1032. PMULHUW XMM0, XMM2
  1033. PSRLW XMM0, 8
  1034. PSLLD XMM0, 24
  1035. POR XMM0, XMM3
  1036. MOVDQU [EDX], XMM0 // Save ARGB
  1037. ADD EAX, 16
  1038. ADD EDX, 16
  1039. DEC ESI
  1040. JNZ @Loop
  1041. AND ECX,3
  1042. JZ @END
  1043. @remainder:
  1044. MOVSS XMM0, [EAX] // coverage
  1045. ANDPS XMM0, XMM4 // abs
  1046. MULSS XMM0, XMM5
  1047. CVTPS2DQ XMM0, XMM0
  1048. PAND XMM0, XMM6 // and with $1FF
  1049. MOVDQA XMM7, XMM6
  1050. PSUBD XMM7, XMM0
  1051. PMINUD XMM0, XMM7
  1052. PMULHUW XMM0, XMM2
  1053. PSRLW XMM0, 8
  1054. PSLLD XMM0, 24
  1055. POR XMM0, XMM3
  1056. MOVD [EDX], XMM0
  1057. ADD EDX, 4
  1058. ADD EAX, 4
  1059. DEC ECX
  1060. JNZ @remainder
  1061. @END:
  1062. POP EDI
  1063. POP ESI
  1064. POP EBX
  1065. @EXIT:
  1066. {$elseif defined(TARGET_x64)}
  1067. // Parameters (x64):
  1068. // RCX <- Coverage
  1069. // RDX <- AlphaValues
  1070. // R8D <- Count
  1071. // R9D <- Color
  1072. // SSE register usage:
  1073. // XMM0: work
  1074. // XMM1: work
  1075. // XMM2: [Alpha * 257] x 4
  1076. // XMM3: [Color without alpha] x 4
  1077. // XMM4: [$7FFFFFFF] x 4
  1078. // XMM5: [256x256] x 4
  1079. // XMM6: [$0001FFFF] x 4
  1080. // XMM7: work
  1081. {$IFNDEF FPC}
  1082. .SAVENV XMM4
  1083. .SAVENV XMM5
  1084. .SAVENV XMM6
  1085. .SAVENV XMM7
  1086. {$ENDIF}
  1087. TEST R8D, R8D
  1088. JLE @EXIT
  1089. (*
  1090. SUB RSP,32
  1091. MOVDQU [RSP],XMM6
  1092. MOVDQU [RSP + 16],XMM7
  1093. *)
  1094. MOV R10D, R9D
  1095. AND R10D, $00FFFFFF
  1096. MOVD XMM3, R10D
  1097. PSHUFD XMM3, XMM3,$0 // save 0RGB
  1098. PCMPEQD XMM6, XMM6
  1099. PSRLD XMM6, 15 // $0001FFFF
  1100. {$if (not defined(FPC))}
  1101. MOVUPS XMM5, DQWORD PTR [SSE_Float256x256]
  1102. {$else}
  1103. MOVUPS XMM5, DQWORD PTR [rip+SSE_Float256x256]
  1104. {$ifend}
  1105. SHR R9D, 24
  1106. MOVD XMM2, R9D
  1107. PUNPCKLBW XMM2, XMM2 // alpha * 257
  1108. PSHUFD XMM2, XMM2, $0 // alphas
  1109. PCMPEQD XMM4, XMM4 // for abs
  1110. PSRLD XMM4, 1
  1111. CMP R8D, 4
  1112. JL @remainder
  1113. MOV EAX, R8D
  1114. SAR EAX, 2
  1115. @Loop:
  1116. MOVUPS XMM0, [RCX] // Load coverage
  1117. ANDPS XMM0, XMM4 // abs
  1118. MULPS XMM0, XMM5
  1119. CVTPS2DQ XMM0, XMM0
  1120. PAND XMM0, XMM6 // and with $0001FFFF
  1121. MOVDQA XMM7, XMM0
  1122. PXOR XMM7, XMM6
  1123. PMINUD XMM0, XMM7
  1124. PMULHUW XMM0, XMM2
  1125. PSRLW XMM0, 8
  1126. PSLLD XMM0, 24
  1127. POR XMM0, XMM3
  1128. MOVDQU [RDX], XMM0 // Save ARGB
  1129. ADD RCX, 16
  1130. ADD RDX, 16
  1131. DEC EAX
  1132. JNZ @Loop
  1133. AND R8D, 3
  1134. JZ @END
  1135. @remainder:
  1136. MOVSS XMM0, [RCX] // Load coverage
  1137. ANDPS XMM0, XMM4 // abs
  1138. MULSS XMM0, XMM5
  1139. CVTPS2DQ XMM0, XMM0
  1140. PAND XMM0, XMM6 // and with $1FF
  1141. MOVDQA XMM7, XMM6
  1142. PSUBD XMM7, XMM0
  1143. PMINUD XMM0, XMM7
  1144. PMULHUW XMM0, XMM2
  1145. PSRLW XMM0, 8
  1146. PSLLD XMM0, 24
  1147. POR XMM0, XMM3
  1148. MOVD [RDX], XMM0 // Save ARGB
  1149. ADD RDX, 4
  1150. ADD RCX, 4
  1151. DEC R8D
  1152. JNZ @remainder
  1153. @END:
  1154. (*
  1155. MOVDQU XMM7,[RSP + 16]
  1156. MOVDQU XMM6,[RSP]
  1157. ADD RSP,32
  1158. *)
  1159. @EXIT:
  1160. {$if defined(FPC)}end['XMM4', 'XMM5', 'XMM6', 'XMM7'];{$ifend}
  1161. {$else}
  1162. {$error 'Missing target'}
  1163. {$ifend}
  1164. end;
  1165. {$ifend}
  1166. //------------------------------------------------------------------------------
  1167. //
  1168. // Unused Make Alpha * P stuff
  1169. //
  1170. //------------------------------------------------------------------------------
  1171. procedure MakeAlphaNonZeroP(Value: Single; AlphaValues: PColor32Array;
  1172. Count: Integer; Color: TColor32);
  1173. var
  1174. M, V: Cardinal;
  1175. C: TColor32Entry absolute Color;
  1176. begin
  1177. M := C.A * $101;
  1178. V := Abs(Round(Value * $10000));
  1179. if V > $10000 then
  1180. V := $10000;
  1181. V := V * M shr 24;
  1182. C.A := V;
  1183. FillLongWord(AlphaValues[0], Count, Color);
  1184. end;
  1185. procedure MakeAlphaEvenOddP(Value: Single; AlphaValues: PColor32Array;
  1186. Count: Integer; Color: TColor32);
  1187. var
  1188. M, V: Cardinal;
  1189. C: TColor32Entry absolute Color;
  1190. begin
  1191. M := C.A * $101;
  1192. V := Abs(Round(Value * $10000));
  1193. V := V and $01ffff;
  1194. if V > $10000 then
  1195. V := V xor $1ffff;
  1196. V := V * M shr 24;
  1197. C.A := V;
  1198. FillLongWord(AlphaValues[0], Count, Color);
  1199. end;
  1200. //------------------------------------------------------------------------------
  1201. //
  1202. // Make Alpha NonZero UPF
  1203. //
  1204. //------------------------------------------------------------------------------
  1205. // Coverage builders used internally by TPolygonRenderer32VPR.
  1206. // Only extracts alpha.
  1207. // For use in pfWinding/pfNonZero fill mode with a filler.
  1208. //------------------------------------------------------------------------------
  1209. //------------------------------------------------------------------------------
  1210. // MakeAlphaNonZeroUPF_Pas
  1211. //------------------------------------------------------------------------------
  1212. procedure MakeAlphaNonZeroUPF_Pas(Coverage: PSingleArray; AlphaValues: PColor32Array;
  1213. Count: Integer; Color: TColor32);
  1214. var
  1215. I: Integer;
  1216. V: Integer;
  1217. begin
  1218. for I := 0 to Count - 1 do
  1219. begin
  1220. V := Clamp(Round(Abs(Coverage[I]) * 256));
  1221. AlphaValues[I] := V;
  1222. end;
  1223. end;
  1224. //------------------------------------------------------------------------------
  1225. //
  1226. // Make Alpha EvenOdd UPF
  1227. //
  1228. //------------------------------------------------------------------------------
  1229. // Coverage builders used internally by TPolygonRenderer32VPR.
  1230. // Only extracts alpha.
  1231. // For use in pfAlternate/pfEvenOdd fill mode with a filler.
  1232. //------------------------------------------------------------------------------
  1233. //------------------------------------------------------------------------------
  1234. // MakeAlphaEvenOddUPF_Pas
  1235. //------------------------------------------------------------------------------
  1236. procedure MakeAlphaEvenOddUPF_Pas(Coverage: PSingleArray; AlphaValues: PColor32Array;
  1237. Count: Integer; Color: TColor32);
  1238. var
  1239. I: Integer;
  1240. V: Integer;
  1241. begin
  1242. for I := 0 to Count - 1 do
  1243. begin
  1244. V := Round(Abs(Coverage[I]) * 256);
  1245. V := V and $000001ff;
  1246. if V >= $100 then
  1247. V := V xor $1ff;
  1248. AlphaValues[I] := V;
  1249. end;
  1250. end;
  1251. //------------------------------------------------------------------------------
  1252. //
  1253. // Unused MakeAlpha * PF stuff
  1254. //
  1255. //------------------------------------------------------------------------------
  1256. procedure MakeAlphaNonZeroPF(Value: Single; AlphaValues: PColor32Array;
  1257. Count: Integer; Color: TColor32);
  1258. var
  1259. V: Integer;
  1260. begin
  1261. V := Clamp(Round(Abs(Value) * 256));
  1262. FillLongWord(AlphaValues[0], Count, V);
  1263. end;
  1264. procedure MakeAlphaEvenOddPF(Value: Single; AlphaValues: PColor32Array;
  1265. Count: Integer; Color: TColor32);
  1266. var
  1267. V: Integer;
  1268. begin
  1269. V := Round(Abs(Value) * 256);
  1270. V := V and $000001ff;
  1271. if V >= $100 then
  1272. V := V xor $1ff;
  1273. FillLongWord(AlphaValues[0], Count, V);
  1274. end;
  1275. //------------------------------------------------------------------------------
  1276. //
  1277. // PolyPolygon and Polygon wrappers
  1278. //
  1279. //------------------------------------------------------------------------------
  1280. //------------------------------------------------------------------------------
  1281. // Float, unclipped versions
  1282. //------------------------------------------------------------------------------
  1283. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1284. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1285. var
  1286. Renderer: TPolygonRenderer32VPR;
  1287. begin
  1288. Renderer := TPolygonRenderer32VPR.Create;
  1289. try
  1290. Renderer.Bitmap := Bitmap;
  1291. Renderer.Color := Color;
  1292. Renderer.FillMode := FillMode;
  1293. Renderer.PolyPolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1294. finally
  1295. Renderer.Free;
  1296. end;
  1297. end;
  1298. //------------------------------------------------------------------------------
  1299. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1300. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1301. var
  1302. Renderer: TPolygonRenderer32VPR;
  1303. begin
  1304. Renderer := TPolygonRenderer32VPR.Create;
  1305. try
  1306. Renderer.Bitmap := Bitmap;
  1307. Renderer.Color := Color;
  1308. Renderer.FillMode := FillMode;
  1309. Renderer.PolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1310. finally
  1311. Renderer.Free;
  1312. end;
  1313. end;
  1314. //------------------------------------------------------------------------------
  1315. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1316. Filler: TCustomPolygonFiller; FillMode: TPolyFillMode; Transformation: TTransformation);
  1317. var
  1318. Renderer: TPolygonRenderer32VPR;
  1319. begin
  1320. if (Filler = nil) then
  1321. Exit;
  1322. Renderer := TPolygonRenderer32VPR.Create;
  1323. try
  1324. Renderer.Bitmap := Bitmap;
  1325. Renderer.Filler := Filler;
  1326. Renderer.FillMode := FillMode;
  1327. Renderer.PolyPolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1328. finally
  1329. Renderer.Free;
  1330. end;
  1331. end;
  1332. //------------------------------------------------------------------------------
  1333. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1334. Filler: TCustomPolygonFiller; FillMode: TPolyFillMode; Transformation: TTransformation);
  1335. var
  1336. Renderer: TPolygonRenderer32VPR;
  1337. begin
  1338. if (Filler = nil) then
  1339. Exit;
  1340. Renderer := TPolygonRenderer32VPR.Create;
  1341. try
  1342. Renderer.Bitmap := Bitmap;
  1343. Renderer.Filler := Filler;
  1344. Renderer.FillMode := FillMode;
  1345. Renderer.PolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1346. finally
  1347. Renderer.Free;
  1348. end;
  1349. end;
  1350. //------------------------------------------------------------------------------
  1351. procedure PolygonFS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1352. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1353. var
  1354. Renderer: TPolygonRenderer32LCD;
  1355. begin
  1356. Renderer := TPolygonRenderer32LCD.Create;
  1357. try
  1358. Renderer.Bitmap := Bitmap;
  1359. Renderer.FillMode := FillMode;
  1360. Renderer.Color := Color;
  1361. Renderer.PolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1362. finally
  1363. Renderer.Free;
  1364. end;
  1365. end;
  1366. //------------------------------------------------------------------------------
  1367. procedure PolyPolygonFS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1368. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1369. var
  1370. Renderer: TPolygonRenderer32LCD;
  1371. begin
  1372. Renderer := TPolygonRenderer32LCD.Create;
  1373. try
  1374. Renderer.Bitmap := Bitmap;
  1375. Renderer.FillMode := FillMode;
  1376. Renderer.Color := Color;
  1377. Renderer.PolyPolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1378. finally
  1379. Renderer.Free;
  1380. end;
  1381. end;
  1382. //------------------------------------------------------------------------------
  1383. procedure PolygonFS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1384. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1385. var
  1386. Renderer: TPolygonRenderer32LCD2;
  1387. begin
  1388. Renderer := TPolygonRenderer32LCD2.Create;
  1389. try
  1390. Renderer.Bitmap := Bitmap;
  1391. Renderer.FillMode := FillMode;
  1392. Renderer.Color := Color;
  1393. Renderer.PolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1394. finally
  1395. Renderer.Free;
  1396. end;
  1397. end;
  1398. //------------------------------------------------------------------------------
  1399. procedure PolyPolygonFS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1400. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1401. var
  1402. Renderer: TPolygonRenderer32LCD2;
  1403. begin
  1404. Renderer := TPolygonRenderer32LCD2.Create;
  1405. try
  1406. Renderer.Bitmap := Bitmap;
  1407. Renderer.FillMode := FillMode;
  1408. Renderer.Color := Color;
  1409. Renderer.PolyPolygonFS(Points, FloatRect(Bitmap.ClipRect), Transformation);
  1410. finally
  1411. Renderer.Free;
  1412. end;
  1413. end;
  1414. //------------------------------------------------------------------------------
  1415. // Float, clipped versions
  1416. //------------------------------------------------------------------------------
  1417. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1418. ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode;
  1419. Transformation: TTransformation);
  1420. var
  1421. Renderer: TPolygonRenderer32VPR;
  1422. IntersectedClipRect: TRect;
  1423. begin
  1424. Renderer := TPolygonRenderer32VPR.Create;
  1425. try
  1426. Renderer.Bitmap := Bitmap;
  1427. Renderer.Color := Color;
  1428. Renderer.FillMode := FillMode;
  1429. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1430. Renderer.PolyPolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1431. finally
  1432. Renderer.Free;
  1433. end;
  1434. end;
  1435. //------------------------------------------------------------------------------
  1436. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1437. ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode;
  1438. Transformation: TTransformation);
  1439. var
  1440. Renderer: TPolygonRenderer32VPR;
  1441. IntersectedClipRect: TRect;
  1442. begin
  1443. Renderer := TPolygonRenderer32VPR.Create;
  1444. try
  1445. Renderer.Bitmap := Bitmap;
  1446. Renderer.Color := Color;
  1447. Renderer.FillMode := FillMode;
  1448. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1449. Renderer.PolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1450. finally
  1451. Renderer.Free;
  1452. end;
  1453. end;
  1454. //------------------------------------------------------------------------------
  1455. procedure PolyPolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1456. ClipRect: TRect; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode;
  1457. Transformation: TTransformation);
  1458. var
  1459. Renderer: TPolygonRenderer32VPR;
  1460. IntersectedClipRect: TRect;
  1461. begin
  1462. if (Filler = nil) then
  1463. Exit;
  1464. Renderer := TPolygonRenderer32VPR.Create;
  1465. try
  1466. Renderer.Bitmap := Bitmap;
  1467. Renderer.Filler := Filler;
  1468. Renderer.FillMode := FillMode;
  1469. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1470. Renderer.PolyPolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1471. finally
  1472. Renderer.Free;
  1473. end;
  1474. end;
  1475. //------------------------------------------------------------------------------
  1476. procedure PolygonFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1477. ClipRect: TRect; Filler: TCustomPolygonFiller; FillMode: TPolyFillMode;
  1478. Transformation: TTransformation);
  1479. var
  1480. Renderer: TPolygonRenderer32VPR;
  1481. IntersectedClipRect: TRect;
  1482. begin
  1483. if (Filler = nil) then
  1484. Exit;
  1485. Renderer := TPolygonRenderer32VPR.Create;
  1486. try
  1487. Renderer.Bitmap := Bitmap;
  1488. Renderer.Filler := Filler;
  1489. Renderer.FillMode := FillMode;
  1490. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1491. Renderer.PolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1492. finally
  1493. Renderer.Free;
  1494. end;
  1495. end;
  1496. //------------------------------------------------------------------------------
  1497. procedure PolygonFS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1498. ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode;
  1499. Transformation: TTransformation);
  1500. var
  1501. Renderer: TPolygonRenderer32LCD;
  1502. IntersectedClipRect: TRect;
  1503. begin
  1504. Renderer := TPolygonRenderer32LCD.Create;
  1505. try
  1506. Renderer.Bitmap := Bitmap;
  1507. Renderer.FillMode := FillMode;
  1508. Renderer.Color := Color;
  1509. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1510. Renderer.PolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1511. finally
  1512. Renderer.Free;
  1513. end;
  1514. end;
  1515. //------------------------------------------------------------------------------
  1516. procedure PolyPolygonFS_LCD(Bitmap: TCustomBitmap32;
  1517. const Points: TArrayOfArrayOfFloatPoint; ClipRect: TRect; Color: TColor32;
  1518. FillMode: TPolyFillMode; Transformation: TTransformation);
  1519. var
  1520. Renderer: TPolygonRenderer32LCD;
  1521. IntersectedClipRect: TRect;
  1522. begin
  1523. Renderer := TPolygonRenderer32LCD.Create;
  1524. try
  1525. Renderer.Bitmap := Bitmap;
  1526. Renderer.FillMode := FillMode;
  1527. Renderer.Color := Color;
  1528. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1529. Renderer.PolyPolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1530. finally
  1531. Renderer.Free;
  1532. end;
  1533. end;
  1534. //------------------------------------------------------------------------------
  1535. procedure PolygonFS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1536. ClipRect: TRect; Color: TColor32; FillMode: TPolyFillMode;
  1537. Transformation: TTransformation);
  1538. var
  1539. Renderer: TPolygonRenderer32LCD2;
  1540. IntersectedClipRect: TRect;
  1541. begin
  1542. Renderer := TPolygonRenderer32LCD2.Create;
  1543. try
  1544. Renderer.Bitmap := Bitmap;
  1545. Renderer.FillMode := FillMode;
  1546. Renderer.Color := Color;
  1547. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1548. Renderer.PolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1549. finally
  1550. Renderer.Free;
  1551. end;
  1552. end;
  1553. //------------------------------------------------------------------------------
  1554. procedure PolyPolygonFS_LCD2(Bitmap: TCustomBitmap32;
  1555. const Points: TArrayOfArrayOfFloatPoint; ClipRect: TRect; Color: TColor32;
  1556. FillMode: TPolyFillMode; Transformation: TTransformation);
  1557. var
  1558. Renderer: TPolygonRenderer32LCD2;
  1559. IntersectedClipRect: TRect;
  1560. begin
  1561. Renderer := TPolygonRenderer32LCD2.Create;
  1562. try
  1563. Renderer.Bitmap := Bitmap;
  1564. Renderer.FillMode := FillMode;
  1565. Renderer.Color := Color;
  1566. GR32.IntersectRect(IntersectedClipRect, Bitmap.ClipRect, ClipRect);
  1567. Renderer.PolyPolygonFS(Points, FloatRect(IntersectedClipRect), Transformation);
  1568. finally
  1569. Renderer.Free;
  1570. end;
  1571. end;
  1572. //------------------------------------------------------------------------------
  1573. // Fixed, unclipped versions
  1574. //------------------------------------------------------------------------------
  1575. procedure PolyPolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  1576. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1577. var
  1578. Renderer: TPolygonRenderer32VPR;
  1579. begin
  1580. Renderer := TPolygonRenderer32VPR.Create;
  1581. try
  1582. Renderer.Bitmap := Bitmap;
  1583. Renderer.Color := Color;
  1584. Renderer.FillMode := FillMode;
  1585. Renderer.PolyPolygonFS(FixedPointToFloatPoint(Points),
  1586. FloatRect(Bitmap.ClipRect), Transformation);
  1587. finally
  1588. Renderer.Free;
  1589. end;
  1590. end;
  1591. procedure PolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1592. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1593. var
  1594. Renderer: TPolygonRenderer32VPR;
  1595. begin
  1596. Renderer := TPolygonRenderer32VPR.Create;
  1597. try
  1598. Renderer.Bitmap := Bitmap;
  1599. Renderer.Color := Color;
  1600. Renderer.FillMode := FillMode;
  1601. Renderer.PolygonFS(FixedPointToFloatPoint(Points),
  1602. FloatRect(Bitmap.ClipRect), Transformation);
  1603. finally
  1604. Renderer.Free;
  1605. end;
  1606. end;
  1607. procedure PolyPolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  1608. Filler: TCustomPolygonFiller; FillMode: TPolyFillMode; Transformation: TTransformation);
  1609. var
  1610. Renderer: TPolygonRenderer32VPR;
  1611. begin
  1612. Renderer := TPolygonRenderer32VPR.Create;
  1613. try
  1614. Renderer.Bitmap := Bitmap;
  1615. Renderer.Filler := Filler;
  1616. Renderer.FillMode := FillMode;
  1617. Renderer.PolyPolygonFS(FixedPointToFloatPoint(Points),
  1618. FloatRect(Bitmap.ClipRect), Transformation);
  1619. finally
  1620. Renderer.Free;
  1621. end;
  1622. end;
  1623. procedure PolygonXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1624. Filler: TCustomPolygonFiller; FillMode: TPolyFillMode; Transformation: TTransformation);
  1625. var
  1626. Renderer: TPolygonRenderer32VPR;
  1627. begin
  1628. Renderer := TPolygonRenderer32VPR.Create;
  1629. try
  1630. Renderer.Bitmap := Bitmap;
  1631. Renderer.Filler := Filler;
  1632. Renderer.FillMode := FillMode;
  1633. Renderer.PolygonFS(FixedPointToFloatPoint(Points),
  1634. FloatRect(Bitmap.ClipRect), Transformation);
  1635. finally
  1636. Renderer.Free;
  1637. end;
  1638. end;
  1639. procedure PolygonXS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1640. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1641. var
  1642. Renderer: TPolygonRenderer32LCD;
  1643. begin
  1644. Renderer := TPolygonRenderer32LCD.Create;
  1645. try
  1646. Renderer.Bitmap := Bitmap;
  1647. Renderer.FillMode := FillMode;
  1648. Renderer.Color := Color;
  1649. Renderer.PolygonFS(FixedPointToFloatPoint(Points),
  1650. FloatRect(Bitmap.ClipRect), Transformation);
  1651. finally
  1652. Renderer.Free;
  1653. end;
  1654. end;
  1655. procedure PolyPolygonXS_LCD(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  1656. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1657. var
  1658. Renderer: TPolygonRenderer32LCD;
  1659. begin
  1660. Renderer := TPolygonRenderer32LCD.Create;
  1661. try
  1662. Renderer.Bitmap := Bitmap;
  1663. Renderer.FillMode := FillMode;
  1664. Renderer.Color := Color;
  1665. Renderer.PolyPolygonFS(FixedPointToFloatPoint(Points),
  1666. FloatRect(Bitmap.ClipRect), Transformation);
  1667. finally
  1668. Renderer.Free;
  1669. end;
  1670. end;
  1671. procedure PolygonXS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1672. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1673. var
  1674. Renderer: TPolygonRenderer32LCD2;
  1675. begin
  1676. Renderer := TPolygonRenderer32LCD2.Create;
  1677. try
  1678. Renderer.Bitmap := Bitmap;
  1679. Renderer.FillMode := FillMode;
  1680. Renderer.Color := Color;
  1681. Renderer.PolygonFS(FixedPointToFloatPoint(Points),
  1682. FloatRect(Bitmap.ClipRect), Transformation);
  1683. finally
  1684. Renderer.Free;
  1685. end;
  1686. end;
  1687. procedure PolyPolygonXS_LCD2(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  1688. Color: TColor32; FillMode: TPolyFillMode; Transformation: TTransformation);
  1689. var
  1690. Renderer: TPolygonRenderer32LCD2;
  1691. begin
  1692. Renderer := TPolygonRenderer32LCD2.Create;
  1693. try
  1694. Renderer.Bitmap := Bitmap;
  1695. Renderer.FillMode := FillMode;
  1696. Renderer.Color := Color;
  1697. Renderer.PolyPolygonFS(FixedPointToFloatPoint(Points),
  1698. FloatRect(Bitmap.ClipRect), Transformation);
  1699. finally
  1700. Renderer.Free;
  1701. end;
  1702. end;
  1703. //------------------------------------------------------------------------------
  1704. //
  1705. // PolyPolyline and Polyline wrappers
  1706. //
  1707. //------------------------------------------------------------------------------
  1708. //------------------------------------------------------------------------------
  1709. // Float, PolyPolyline
  1710. //------------------------------------------------------------------------------
  1711. procedure PolyPolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1712. Color: TColor32; Closed: Boolean; StrokeWidth: TFloat;
  1713. JoinStyle: TJoinStyle; EndStyle: TEndStyle;
  1714. MiterLimit: TFloat; Transformation: TTransformation);
  1715. var
  1716. Dst: TArrayOfArrayOfFloatPoint;
  1717. begin
  1718. Dst := BuildPolyPolyLine(Points, Closed, StrokeWidth, JoinStyle, EndStyle, MiterLimit);
  1719. PolyPolygonFS(Bitmap, Dst, Color, pfWinding, Transformation);
  1720. end;
  1721. //------------------------------------------------------------------------------
  1722. procedure PolyPolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFloatPoint;
  1723. Filler: TCustomPolygonFiller; Closed: Boolean; StrokeWidth: TFloat;
  1724. JoinStyle: TJoinStyle; EndStyle: TEndStyle; MiterLimit: TFloat;
  1725. Transformation: TTransformation);
  1726. var
  1727. Dst: TArrayOfArrayOfFloatPoint;
  1728. begin
  1729. Dst := BuildPolyPolyLine(Points, Closed, StrokeWidth, JoinStyle, EndStyle, MiterLimit);
  1730. PolyPolygonFS(Bitmap, Dst, Filler, pfWinding, Transformation);
  1731. end;
  1732. //------------------------------------------------------------------------------
  1733. // Float, Polyline
  1734. //------------------------------------------------------------------------------
  1735. procedure PolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1736. Color: TColor32; Closed: Boolean; StrokeWidth: TFloat; JoinStyle: TJoinStyle;
  1737. EndStyle: TEndStyle; MiterLimit: TFloat; Transformation: TTransformation);
  1738. begin
  1739. PolyPolylineFS(Bitmap, PolyPolygon(Points), Color, Closed, StrokeWidth,
  1740. JoinStyle, EndStyle, MiterLimit, Transformation);
  1741. end;
  1742. //------------------------------------------------------------------------------
  1743. procedure PolylineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1744. Filler: TCustomPolygonFiller; Closed: Boolean; StrokeWidth: TFloat;
  1745. JoinStyle: TJoinStyle; EndStyle: TEndStyle; MiterLimit: TFloat;
  1746. Transformation: TTransformation);
  1747. begin
  1748. PolyPolylineFS(Bitmap, PolyPolygon(Points), Filler, Closed, StrokeWidth,
  1749. JoinStyle, EndStyle, MiterLimit, Transformation);
  1750. end;
  1751. //------------------------------------------------------------------------------
  1752. // Fixed, PolyPolyline
  1753. //------------------------------------------------------------------------------
  1754. procedure PolyPolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  1755. Color: TColor32; Closed: Boolean; StrokeWidth: TFixed; JoinStyle: TJoinStyle;
  1756. EndStyle: TEndStyle; MiterLimit: TFixed; Transformation: TTransformation);
  1757. var
  1758. Dst: TArrayOfArrayOfFixedPoint;
  1759. begin
  1760. Dst := BuildPolyPolyLine(Points, Closed, StrokeWidth, JoinStyle, EndStyle,
  1761. MiterLimit);
  1762. PolyPolygonXS(Bitmap, Dst, Color, pfWinding, Transformation);
  1763. end;
  1764. //------------------------------------------------------------------------------
  1765. procedure PolyPolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfArrayOfFixedPoint;
  1766. Filler: TCustomPolygonFiller; Closed: Boolean; StrokeWidth: TFixed;
  1767. JoinStyle: TJoinStyle; EndStyle: TEndStyle; MiterLimit: TFixed;
  1768. Transformation: TTransformation);
  1769. var
  1770. Dst: TArrayOfArrayOfFixedPoint;
  1771. begin
  1772. Dst := BuildPolyPolyLine(Points, Closed, StrokeWidth, JoinStyle, EndStyle,
  1773. MiterLimit);
  1774. PolyPolygonXS(Bitmap, Dst, Filler, pfWinding, Transformation);
  1775. end;
  1776. //------------------------------------------------------------------------------
  1777. // Fixed, Polyline
  1778. //------------------------------------------------------------------------------
  1779. procedure PolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1780. Color: TColor32; Closed: Boolean; StrokeWidth: TFixed;
  1781. JoinStyle: TJoinStyle; EndStyle: TEndStyle;
  1782. MiterLimit: TFixed; Transformation: TTransformation);
  1783. begin
  1784. PolyPolylineXS(Bitmap, PolyPolygon(Points), Color,
  1785. Closed, StrokeWidth, JoinStyle, EndStyle,
  1786. MiterLimit, Transformation);
  1787. end;
  1788. //------------------------------------------------------------------------------
  1789. procedure PolylineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1790. Filler: TCustomPolygonFiller; Closed: Boolean; StrokeWidth: TFixed;
  1791. JoinStyle: TJoinStyle; EndStyle: TEndStyle; MiterLimit: TFixed;
  1792. Transformation: TTransformation);
  1793. begin
  1794. PolyPolylineXS(Bitmap, PolyPolygon(Points), Filler, Closed, StrokeWidth,
  1795. JoinStyle, EndStyle, MiterLimit, Transformation);
  1796. end;
  1797. //------------------------------------------------------------------------------
  1798. //
  1799. // Dashed lines
  1800. //
  1801. //------------------------------------------------------------------------------
  1802. //------------------------------------------------------------------------------
  1803. // Filled only Dashes ...
  1804. //------------------------------------------------------------------------------
  1805. // Float
  1806. //------------------------------------------------------------------------------
  1807. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1808. const Dashes: TArrayOfFloat; Color: TColor32; Closed: Boolean; Width: TFloat);
  1809. var
  1810. MultiPoly: TArrayOfArrayOfFloatPoint;
  1811. begin
  1812. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1813. PolyPolylineFS(Bitmap, MultiPoly, Color, False, Width);
  1814. end;
  1815. //------------------------------------------------------------------------------
  1816. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1817. const Dashes: TArrayOfFloat; FillColor, StrokeColor: TColor32;
  1818. Closed: Boolean; Width: TFloat; StrokeWidth: TFloat);
  1819. var
  1820. MultiPoly: TArrayOfArrayOfFloatPoint;
  1821. begin
  1822. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1823. MultiPoly := BuildPolyPolyLine(MultiPoly, False, Width);
  1824. PolyPolygonFS(Bitmap, MultiPoly, FillColor);
  1825. PolyPolylineFS(Bitmap, MultiPoly, StrokeColor, True, StrokeWidth);
  1826. end;
  1827. //------------------------------------------------------------------------------
  1828. // Fixed
  1829. //------------------------------------------------------------------------------
  1830. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1831. const Dashes: TArrayOfFixed; Color: TColor32; Closed: Boolean; Width: TFixed);
  1832. var
  1833. MultiPoly: TArrayOfArrayOfFixedPoint;
  1834. begin
  1835. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1836. PolyPolylineXS(Bitmap, MultiPoly, Color, False, Width);
  1837. end;
  1838. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1839. const Dashes: TArrayOfFixed; FillColor, StrokeColor: TColor32;
  1840. Closed: Boolean; Width: TFixed; StrokeWidth: TFixed);
  1841. var
  1842. MultiPoly: TArrayOfArrayOfFixedPoint;
  1843. begin
  1844. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1845. PolyPolylineXS(Bitmap, MultiPoly, FillColor, False, Width);
  1846. MultiPoly := BuildPolyPolyLine(MultiPoly, False, Width);
  1847. PolyPolylineXS(Bitmap, MultiPoly, StrokeColor, True, strokeWidth);
  1848. end;
  1849. //------------------------------------------------------------------------------
  1850. // Filled and stroked Dashes ...
  1851. //------------------------------------------------------------------------------
  1852. // Float
  1853. //------------------------------------------------------------------------------
  1854. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1855. const Dashes: TArrayOfFloat; Filler: TCustomPolygonFiller;
  1856. Closed: Boolean; Width: TFloat);
  1857. var
  1858. MultiPoly: TArrayOfArrayOfFloatPoint;
  1859. begin
  1860. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1861. PolyPolylineFS(Bitmap, MultiPoly, Filler, False, Width);
  1862. end;
  1863. //------------------------------------------------------------------------------
  1864. procedure DashLineFS(Bitmap: TCustomBitmap32; const Points: TArrayOfFloatPoint;
  1865. const Dashes: TArrayOfFloat; Filler: TCustomPolygonFiller; StrokeColor: TColor32;
  1866. Closed: Boolean; Width: TFloat; StrokeWidth: TFloat);
  1867. var
  1868. MultiPoly: TArrayOfArrayOfFloatPoint;
  1869. begin
  1870. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1871. MultiPoly := BuildPolyPolyLine(MultiPoly, False, Width);
  1872. PolyPolygonFS(Bitmap, MultiPoly, Filler);
  1873. PolyPolylineFS(Bitmap, MultiPoly, StrokeColor, True, StrokeWidth);
  1874. end;
  1875. //------------------------------------------------------------------------------
  1876. // Fixed
  1877. //------------------------------------------------------------------------------
  1878. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1879. const Dashes: TArrayOfFixed; Filler: TCustomPolygonFiller;
  1880. Closed: Boolean; Width: TFixed);
  1881. var
  1882. MultiPoly: TArrayOfArrayOfFixedPoint;
  1883. begin
  1884. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1885. PolyPolylineXS(Bitmap, MultiPoly, Filler, False, Width);
  1886. end;
  1887. //------------------------------------------------------------------------------
  1888. procedure DashLineXS(Bitmap: TCustomBitmap32; const Points: TArrayOfFixedPoint;
  1889. const Dashes: TArrayOfFixed; Filler: TCustomPolygonFiller; StrokeColor: TColor32;
  1890. Closed: Boolean; Width: TFixed; StrokeWidth: TFixed);
  1891. var
  1892. MultiPoly: TArrayOfArrayOfFixedPoint;
  1893. begin
  1894. MultiPoly := GR32_VectorUtils.BuildDashedLine(Points, Dashes, 0, Closed);
  1895. PolyPolylineXS(Bitmap, MultiPoly, Filler, False, Width);
  1896. MultiPoly := BuildPolyPolyLine(MultiPoly, False, Width);
  1897. PolyPolylineXS(Bitmap, MultiPoly, StrokeColor, True, StrokeWidth);
  1898. end;
  1899. //------------------------------------------------------------------------------
  1900. //
  1901. // TCustomPolygonFiller wrapper
  1902. //
  1903. //------------------------------------------------------------------------------
  1904. procedure FillBitmap(Bitmap: TCustomBitmap32; Filler: TCustomPolygonFiller);
  1905. var
  1906. AlphaValues: PColor32;
  1907. Y: Integer;
  1908. begin
  1909. {$IFDEF USESTACKALLOC}
  1910. AlphaValues := StackAlloc(Bitmap.Width * SizeOf(TColor32));
  1911. {$ELSE}
  1912. GetMem(AlphaValues, Bitmap.Width * SizeOf(TColor32));
  1913. {$ENDIF}
  1914. FillLongword(AlphaValues^, Bitmap.Width, $FF);
  1915. Filler.BeginRendering;
  1916. for Y := 0 to Bitmap.Height - 1 do
  1917. Filler.FillLine(PColor32(Bitmap.ScanLine[y]), 0, y, Bitmap.Width,
  1918. AlphaValues, Bitmap.CombineMode);
  1919. Filler.EndRendering;
  1920. {$IFDEF USESTACKALLOC}
  1921. StackFree(AlphaValues);
  1922. {$ELSE}
  1923. FreeMem(AlphaValues);
  1924. {$ENDIF}
  1925. end;
  1926. //------------------------------------------------------------------------------
  1927. //
  1928. // LCD sub-pixel rendering
  1929. //
  1930. //------------------------------------------------------------------------------
  1931. // References:
  1932. // - https://en.wikipedia.org/wiki/Subpixel_rendering
  1933. // - https://www.grc.com/cleartype.htm
  1934. // - https://en.wikipedia.org/wiki/ClearType
  1935. // - https://en.wikipedia.org/wiki/CoolType
  1936. //------------------------------------------------------------------------------
  1937. type
  1938. {$if not defined(FPC)}
  1939. PByteArray = System.SysUtils.PByteArray;
  1940. {$else}
  1941. PByteArray = SysUtils.PByteArray;
  1942. {$ifend}
  1943. type
  1944. TRGBTriple = packed record
  1945. B, G, R: Byte;
  1946. end;
  1947. PRGBTripleArray = ^TRGBTripleArray;
  1948. TRGBTripleArray = array [0..0] of TRGBTriple;
  1949. TMakeAlphaProcLCD = procedure(Coverage: PSingleArray; AlphaValues: PByteArray; Count: Integer; Color: TColor32);
  1950. //------------------------------------------------------------------------------
  1951. //
  1952. // Make Alpha NonZero LCD
  1953. //
  1954. //------------------------------------------------------------------------------
  1955. // Coverage builders used internally by TPolygonRenderer32LCD.
  1956. // Uses subpixel anti-aliasing.
  1957. // For use in pfWinding/pfNonZero fill mode with a static color.
  1958. //------------------------------------------------------------------------------
  1959. procedure MakeAlphaNonZeroLCD(Coverage: PSingleArray; AlphaValues: PByteArray;
  1960. Count: Integer; Color: TColor32);
  1961. var
  1962. I: Integer;
  1963. M, V: Cardinal;
  1964. Last: TFloat;
  1965. C: TColor32Entry absolute Color;
  1966. begin
  1967. M := C.A * 86; // 86 = 258 / 3
  1968. Last := Infinity;
  1969. V := 0;
  1970. AlphaValues[0] := 0;
  1971. AlphaValues[1] := 0;
  1972. for I := 0 to Count - 1 do
  1973. begin
  1974. if PInteger(@Last)^ <> PInteger(@Coverage[I])^ then
  1975. begin
  1976. Last := Coverage[I];
  1977. V := Abs(Round(Last * $10000));
  1978. if V > $10000 then
  1979. V := $10000;
  1980. V := V * M shr 24;
  1981. end;
  1982. Inc(AlphaValues[I], V);
  1983. Inc(AlphaValues[I + 1], V);
  1984. AlphaValues[I + 2] := V;
  1985. end;
  1986. AlphaValues[Count + 2] := 0;
  1987. AlphaValues[Count + 3] := 0;
  1988. end;
  1989. //------------------------------------------------------------------------------
  1990. //
  1991. // Make Alpha EvenOdd LCD
  1992. //
  1993. //------------------------------------------------------------------------------
  1994. // Coverage builders used internally by TPolygonRenderer32LCD.
  1995. // Uses subpixel anti-aliasing.
  1996. // For use in pfAlternate/pfEvenOdd fill mode with a static color.
  1997. //------------------------------------------------------------------------------
  1998. procedure MakeAlphaEvenOddLCD(Coverage: PSingleArray; AlphaValues: PByteArray;
  1999. Count: Integer; Color: TColor32);
  2000. var
  2001. I: Integer;
  2002. M, V: Cardinal;
  2003. Last: TFloat;
  2004. begin
  2005. M := Color shr 24 * 86; // 86 = 258 / 3
  2006. Last := Infinity;
  2007. V := 0;
  2008. AlphaValues[0] := 0;
  2009. AlphaValues[1] := 0;
  2010. for I := 0 to Count - 1 do
  2011. begin
  2012. if PInteger(@Last)^ <> PInteger(@Coverage[I])^ then
  2013. begin
  2014. Last := Coverage[I];
  2015. V := Abs(Round(Coverage[I] * $10000));
  2016. V := V and $01ffff;
  2017. if V >= $10000 then
  2018. V := V xor $1ffff;
  2019. V := V * M shr 24;
  2020. end;
  2021. Inc(AlphaValues[I], V);
  2022. Inc(AlphaValues[I + 1], V);
  2023. AlphaValues[I + 2] := V;
  2024. end;
  2025. AlphaValues[Count + 2] := 0;
  2026. AlphaValues[Count + 3] := 0;
  2027. end;
  2028. //------------------------------------------------------------------------------
  2029. //
  2030. // Make Alpha NonZero LCD2
  2031. //
  2032. //------------------------------------------------------------------------------
  2033. // Coverage builders used internally by TPolygonRenderer32LCD2.
  2034. // Uses subpixel anti-aliasing. Slightly softer AA transitions.
  2035. // For use in pfWinding/pfNonZero fill mode with a static color.
  2036. //------------------------------------------------------------------------------
  2037. procedure MakeAlphaNonZeroLCD2(Coverage: PSingleArray; AlphaValues: PByteArray;
  2038. Count: Integer; Color: TColor32);
  2039. var
  2040. I: Integer;
  2041. begin
  2042. MakeAlphaNonZeroLCD(Coverage, AlphaValues, Count, Color);
  2043. AlphaValues[Count + 2] := (AlphaValues[Count] + AlphaValues[Count + 1]) div 3;
  2044. AlphaValues[Count + 3] := AlphaValues[Count + 1] div 3;
  2045. for I := Count + 1 downto 2 do
  2046. begin
  2047. AlphaValues[I] := (AlphaValues[I] + AlphaValues[I - 1] + AlphaValues[I - 2]) div 3;
  2048. end;
  2049. AlphaValues[1] := (AlphaValues[0] + AlphaValues[1]) div 3;
  2050. AlphaValues[0] := AlphaValues[0] div 3;
  2051. end;
  2052. //------------------------------------------------------------------------------
  2053. //
  2054. // Make Alpha EvenOdd LCD2
  2055. //
  2056. //------------------------------------------------------------------------------
  2057. // Coverage builders used internally by TPolygonRenderer32LCD2.
  2058. // Uses subpixel anti-aliasing. Slightly softer AA transitions.
  2059. // For use in pfAlternate/pfEvenOdd fill mode with a static color.
  2060. //------------------------------------------------------------------------------
  2061. procedure MakeAlphaEvenOddLCD2(Coverage: PSingleArray; AlphaValues: PByteArray;
  2062. Count: Integer; Color: TColor32);
  2063. var
  2064. I: Integer;
  2065. begin
  2066. MakeAlphaEvenOddLCD(Coverage, AlphaValues, Count, Color);
  2067. AlphaValues[Count + 2] := (AlphaValues[Count] + AlphaValues[Count + 1]) div 3;
  2068. AlphaValues[Count + 3] := AlphaValues[Count + 1] div 3;
  2069. for I := Count + 1 downto 2 do
  2070. begin
  2071. AlphaValues[I] := (AlphaValues[I] + AlphaValues[I - 1] + AlphaValues[I - 2]) div 3;
  2072. end;
  2073. AlphaValues[1] := (AlphaValues[0] + AlphaValues[1]) div 3;
  2074. AlphaValues[0] := AlphaValues[0] div 3;
  2075. end;
  2076. //------------------------------------------------------------------------------
  2077. // CombineLineLCD
  2078. //------------------------------------------------------------------------------
  2079. procedure CombineLineLCD(Weights: PRGBTripleArray; Dst: PColor32Array; Color: TColor32; Count: Integer);
  2080. var
  2081. I: Integer;
  2082. {$IFDEF TEST_BLENDMEMRGB128SSE4}
  2083. Weights64: UInt64;
  2084. {$ENDIF}
  2085. begin
  2086. I := 0;
  2087. while Count <> 0 do
  2088. {$IFDEF TEST_BLENDMEMRGB128SSE4}
  2089. if (Count shr 1) = 0 then
  2090. {$ENDIF}
  2091. begin
  2092. if PColor32(@Weights[I])^ = $FFFFFFFF then
  2093. Dst[I] := Color
  2094. else
  2095. BlendMemRGB(Color, Dst[I], PColor32(@Weights[I])^);
  2096. Dec(Count);
  2097. Inc(I);
  2098. end
  2099. {$IFDEF TEST_BLENDMEMRGB128SSE4}
  2100. else
  2101. begin
  2102. Weights64 := (UInt64(PColor32(@Weights[I + 1])^) shl 32) or
  2103. PColor32(@Weights[I])^;
  2104. if Weights64 = $FFFFFFFFFFFFFFFF then
  2105. begin
  2106. Dst[I] := Color;
  2107. Dst[I + 1] := Color;
  2108. end
  2109. else
  2110. BlendMemRGB128(Color, Dst[I], Weights64);
  2111. Dec(Count, 2);
  2112. Inc(I, 2);
  2113. end
  2114. {$ENDIF};
  2115. end;
  2116. //------------------------------------------------------------------------------
  2117. //
  2118. // TCustomPolygonFiller
  2119. //
  2120. //------------------------------------------------------------------------------
  2121. procedure TCustomPolygonFiller.BeginRendering;
  2122. begin
  2123. // implemented by descendants
  2124. end;
  2125. procedure TCustomPolygonFiller.EndRendering;
  2126. begin
  2127. // implemented by descendants
  2128. end;
  2129. //------------------------------------------------------------------------------
  2130. //
  2131. // TCallbackPolygonFiller
  2132. //
  2133. //------------------------------------------------------------------------------
  2134. procedure TCallbackPolygonFiller.BeginRendering;
  2135. begin
  2136. inherited;
  2137. if (not Assigned(FFillLineEvent)) then
  2138. raise Exception.Create('Missing polygon filler delegate');
  2139. end;
  2140. function TCallbackPolygonFiller.GetFillLine: TFillLineEvent;
  2141. begin
  2142. Result := FFillLineEvent;
  2143. end;
  2144. //------------------------------------------------------------------------------
  2145. //
  2146. // TInvertPolygonFiller
  2147. //
  2148. //------------------------------------------------------------------------------
  2149. procedure TInvertPolygonFiller.FillLineBlend(Dst: PColor32; DstX, DstY,
  2150. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  2151. var
  2152. X: Integer;
  2153. BlendMemEx: TBlendMemEx;
  2154. begin
  2155. BlendMemEx := BLEND_MEM_EX[CombineMode]^;
  2156. for X := DstX to DstX + Length - 1 do
  2157. begin
  2158. BlendMemEx(InvertColor(Dst^), Dst^, AlphaValues^);
  2159. Inc(Dst);
  2160. Inc(AlphaValues);
  2161. end;
  2162. end;
  2163. function TInvertPolygonFiller.GetFillLine: TFillLineEvent;
  2164. begin
  2165. Result := FillLineBlend;
  2166. end;
  2167. //------------------------------------------------------------------------------
  2168. //
  2169. // TClearPolygonFiller
  2170. //
  2171. //------------------------------------------------------------------------------
  2172. constructor TClearPolygonFiller.Create(Color: TColor32);
  2173. begin
  2174. inherited Create;
  2175. FColor := Color;
  2176. end;
  2177. procedure TClearPolygonFiller.FillLineClear(Dst: PColor32; DstX, DstY,
  2178. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  2179. begin
  2180. FillLongword(Dst^, Length, FColor);
  2181. end;
  2182. function TClearPolygonFiller.GetFillLine: TFillLineEvent;
  2183. begin
  2184. Result := FillLineClear;
  2185. end;
  2186. //------------------------------------------------------------------------------
  2187. //
  2188. // TBitmapPolygonFiller
  2189. //
  2190. //------------------------------------------------------------------------------
  2191. procedure TBitmapPolygonFiller.FillLineOpaque(Dst: PColor32; DstX, DstY,
  2192. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  2193. var
  2194. PatternX, PatternY, X: Integer;
  2195. OpaqueAlpha: TColor32;
  2196. Src: PColor32;
  2197. BlendMemEx: TBlendMemEx;
  2198. begin
  2199. PatternX := (DstX - OffsetX) mod FPattern.Width;
  2200. if PatternX < 0 then
  2201. PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
  2202. PatternY := (DstY - OffsetY) mod FPattern.Height;
  2203. if PatternY < 0 then
  2204. PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
  2205. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2206. if (AlphaValues <> nil) then
  2207. begin
  2208. OpaqueAlpha := TColor32($FF shl 24);
  2209. BlendMemEx := BLEND_MEM_EX[FPattern.CombineMode]^;
  2210. for X := DstX to DstX + Length - 1 do
  2211. begin
  2212. BlendMemEx(Src^ and $00FFFFFF or OpaqueAlpha, Dst^, AlphaValues^);
  2213. Inc(Dst); Inc(Src); Inc(PatternX);
  2214. if PatternX >= FPattern.Width then
  2215. begin
  2216. PatternX := 0;
  2217. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2218. end;
  2219. Inc(AlphaValues);
  2220. end;
  2221. end
  2222. else
  2223. for X := DstX to DstX + Length - 1 do
  2224. begin
  2225. Dst^ := Src^;
  2226. Inc(Dst); Inc(Src); Inc(PatternX);
  2227. if PatternX >= FPattern.Width then
  2228. begin
  2229. PatternX := 0;
  2230. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2231. end;
  2232. end;
  2233. end;
  2234. //------------------------------------------------------------------------------
  2235. procedure TBitmapPolygonFiller.BeginRendering;
  2236. begin
  2237. inherited;
  2238. if (FPattern = nil) or (FPattern.DrawMode = dmTransparent) or
  2239. ((FPattern.DrawMode = dmCustom) and (not Assigned(FPattern.OnPixelCombine))) then
  2240. raise Exception.Create('Missing or invalid polygon filler pattern');
  2241. end;
  2242. //------------------------------------------------------------------------------
  2243. procedure TBitmapPolygonFiller.FillLineBlend(Dst: PColor32; DstX, DstY,
  2244. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  2245. var
  2246. PatternX, PatternY, X: Integer;
  2247. Src: PColor32;
  2248. BlendMemEx: TBlendMemEx;
  2249. BlendMem: TBlendMem;
  2250. begin
  2251. PatternX := (DstX - OffsetX) mod FPattern.Width;
  2252. if PatternX < 0 then
  2253. PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
  2254. PatternY := (DstY - OffsetY) mod FPattern.Height;
  2255. if PatternY < 0 then
  2256. PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
  2257. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2258. if (AlphaValues <> nil) then
  2259. begin
  2260. BlendMemEx := BLEND_MEM_EX[FPattern.CombineMode]^;
  2261. for X := DstX to DstX + Length - 1 do
  2262. begin
  2263. BlendMemEx(Src^, Dst^, AlphaValues^);
  2264. Inc(Dst); Inc(Src); Inc(PatternX);
  2265. if PatternX >= FPattern.Width then
  2266. begin
  2267. PatternX := 0;
  2268. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2269. end;
  2270. Inc(AlphaValues);
  2271. end;
  2272. end
  2273. else
  2274. begin
  2275. BlendMem := BLEND_MEM[FPattern.CombineMode]^;
  2276. for X := DstX to DstX + Length - 1 do
  2277. begin
  2278. BlendMem(Src^, Dst^);
  2279. Inc(Dst); Inc(Src); Inc(PatternX);
  2280. if PatternX >= FPattern.Width then
  2281. begin
  2282. PatternX := 0;
  2283. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2284. end;
  2285. end;
  2286. end;
  2287. end;
  2288. //------------------------------------------------------------------------------
  2289. procedure TBitmapPolygonFiller.FillLineBlendMasterAlpha(Dst: PColor32;
  2290. DstX, DstY, Length: Integer; AlphaValues: PColor32;
  2291. CombineMode: TCombineMode);
  2292. var
  2293. PatternX, PatternY, X: Integer;
  2294. Src: PColor32;
  2295. BlendMemEx: TBlendMemEx;
  2296. begin
  2297. PatternX := (DstX - OffsetX) mod FPattern.Width;
  2298. if PatternX < 0 then
  2299. PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
  2300. PatternY := (DstY - OffsetY) mod FPattern.Height;
  2301. if PatternY < 0 then
  2302. PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
  2303. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2304. BlendMemEx := BLEND_MEM_EX[FPattern.CombineMode]^;
  2305. if (AlphaValues <> nil) then
  2306. begin
  2307. for X := DstX to DstX + Length - 1 do
  2308. begin
  2309. BlendMemEx(Src^, Dst^, Div255(AlphaValues^ * FPattern.MasterAlpha));
  2310. Inc(Dst); Inc(Src); Inc(PatternX);
  2311. if PatternX >= FPattern.Width then
  2312. begin
  2313. PatternX := 0;
  2314. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2315. end;
  2316. Inc(AlphaValues);
  2317. end;
  2318. end else
  2319. begin
  2320. for X := DstX to DstX + Length - 1 do
  2321. begin
  2322. BlendMemEx(Src^, Dst^, FPattern.MasterAlpha);
  2323. Inc(Dst); Inc(Src); Inc(PatternX);
  2324. if PatternX >= FPattern.Width then
  2325. begin
  2326. PatternX := 0;
  2327. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2328. end;
  2329. end;
  2330. end;
  2331. end;
  2332. //------------------------------------------------------------------------------
  2333. procedure TBitmapPolygonFiller.FillLineCustomCombine(Dst: PColor32;
  2334. DstX, DstY, Length: Integer; AlphaValues: PColor32;
  2335. CombineMode: TCombineMode);
  2336. var
  2337. PatternX, PatternY, X: Integer;
  2338. Src: PColor32;
  2339. begin
  2340. PatternX := (DstX - OffsetX) mod FPattern.Width;
  2341. if PatternX < 0 then
  2342. PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
  2343. PatternY := (DstY - OffsetY) mod FPattern.Height;
  2344. if PatternY < 0 then
  2345. PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
  2346. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2347. if (AlphaValues <> nil) then
  2348. begin
  2349. for X := DstX to DstX + Length - 1 do
  2350. begin
  2351. FPattern.OnPixelCombine(Src^, Dst^, Div255(AlphaValues^ * FPattern.MasterAlpha));
  2352. Inc(Dst); Inc(Src); Inc(PatternX);
  2353. if PatternX >= FPattern.Width then
  2354. begin
  2355. PatternX := 0;
  2356. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2357. end;
  2358. Inc(AlphaValues);
  2359. end;
  2360. end else
  2361. begin
  2362. for X := DstX to DstX + Length - 1 do
  2363. begin
  2364. FPattern.OnPixelCombine(Src^, Dst^, FPattern.MasterAlpha);
  2365. Inc(Dst); Inc(Src); Inc(PatternX);
  2366. if PatternX >= FPattern.Width then
  2367. begin
  2368. PatternX := 0;
  2369. Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
  2370. end;
  2371. end;
  2372. end;
  2373. end;
  2374. //------------------------------------------------------------------------------
  2375. function TBitmapPolygonFiller.GetFillLine: TFillLineEvent;
  2376. begin
  2377. if (FPattern = nil) then
  2378. Result := nil
  2379. else
  2380. if FPattern.DrawMode = dmOpaque then
  2381. Result := FillLineOpaque
  2382. else
  2383. if FPattern.DrawMode = dmBlend then
  2384. begin
  2385. if FPattern.MasterAlpha = 255 then
  2386. Result := FillLineBlend
  2387. else
  2388. Result := FillLineBlendMasterAlpha;
  2389. end else
  2390. if (FPattern.DrawMode = dmCustom) and Assigned(FPattern.OnPixelCombine) then
  2391. Result := FillLineCustomCombine
  2392. else
  2393. Result := nil;
  2394. end;
  2395. //------------------------------------------------------------------------------
  2396. //
  2397. // TSamplerFiller
  2398. //
  2399. //------------------------------------------------------------------------------
  2400. constructor TSamplerFiller.Create(Sampler: TCustomSampler = nil);
  2401. begin
  2402. inherited Create;
  2403. FSampler := Sampler;
  2404. SamplerChanged;
  2405. end;
  2406. procedure TSamplerFiller.EndRendering;
  2407. begin
  2408. if (FSampler = nil) then
  2409. raise Exception.Create(RCStrNoSamplerSpecified);
  2410. FSampler.FinalizeSampling;
  2411. inherited;
  2412. end;
  2413. procedure TSamplerFiller.SampleLineOpaque(Dst: PColor32; DstX, DstY,
  2414. Length: Integer; AlphaValues: PColor32; CombineMode: TCombineMode);
  2415. var
  2416. X: Integer;
  2417. BlendMemEx: TBlendMemEx;
  2418. begin
  2419. BlendMemEx := BLEND_MEM_EX[CombineMode]^;
  2420. for X := DstX to DstX + Length - 1 do
  2421. begin
  2422. BlendMemEx(FGetSample(X, DstY) and $00FFFFFF or $FF000000, Dst^, AlphaValues^);
  2423. Inc(Dst);
  2424. Inc(AlphaValues);
  2425. end;
  2426. end;
  2427. procedure TSamplerFiller.SamplerChanged;
  2428. begin
  2429. if (FSampler <> nil) then
  2430. FGetSample := FSampler.GetSampleInt;
  2431. end;
  2432. procedure TSamplerFiller.BeginRendering;
  2433. begin
  2434. inherited;
  2435. if (FSampler = nil) then
  2436. raise Exception.Create(RCStrNoSamplerSpecified);
  2437. FSampler.PrepareSampling;
  2438. end;
  2439. function TSamplerFiller.GetFillLine: TFillLineEvent;
  2440. begin
  2441. Result := SampleLineOpaque;
  2442. end;
  2443. procedure TSamplerFiller.SetSampler(const Value: TCustomSampler);
  2444. begin
  2445. if FSampler <> Value then
  2446. begin
  2447. FSampler := Value;
  2448. SamplerChanged;
  2449. end;
  2450. end;
  2451. //------------------------------------------------------------------------------
  2452. //
  2453. // TCustomPolygonRenderer
  2454. //
  2455. //------------------------------------------------------------------------------
  2456. procedure TCustomPolygonRenderer.PolygonFS(
  2457. const Points: TArrayOfFloatPoint; const ClipRect: TFloatRect;
  2458. Transformation: TTransformation);
  2459. begin
  2460. PolyPolygonFS(PolyPolygon(Points), ClipRect, Transformation);
  2461. end;
  2462. procedure TCustomPolygonRenderer.PolygonFS(
  2463. const Points: TArrayOfFloatPoint; const ClipRect: TFloatRect);
  2464. begin
  2465. PolyPolygonFS(PolyPolygon(Points), ClipRect);
  2466. end;
  2467. procedure TCustomPolygonRenderer.PolyPolygonFS(
  2468. const Points: TArrayOfArrayOfFloatPoint; const ClipRect: TFloatRect;
  2469. Transformation: TTransformation);
  2470. var
  2471. APoints: TArrayOfArrayOfFloatPoint;
  2472. begin
  2473. if (Transformation <> nil) then
  2474. APoints := TransformPolyPolygon(Points, Transformation)
  2475. else
  2476. APoints := Points;
  2477. PolyPolygonFS(APoints, ClipRect);
  2478. end;
  2479. //------------------------------------------------------------------------------
  2480. //
  2481. // TPolygonRenderer32
  2482. //
  2483. //------------------------------------------------------------------------------
  2484. constructor TPolygonRenderer32.Create(Bitmap: TCustomBitmap32; Fillmode: TPolyFillMode);
  2485. begin
  2486. inherited Create;
  2487. SetBitmap(Bitmap);
  2488. SetFillMode(Fillmode);
  2489. end;
  2490. procedure TPolygonRenderer32.PolygonFS(const Points: TArrayOfFloatPoint);
  2491. begin
  2492. PolyPolygonFS(PolyPolygon(Points), FloatRect(FBitmap.ClipRect));
  2493. end;
  2494. procedure TPolygonRenderer32.PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint);
  2495. begin
  2496. PolyPolygonFS(Points, FloatRect(FBitmap.ClipRect));
  2497. end;
  2498. procedure TPolygonRenderer32.SetBitmap(const Value: TCustomBitmap32);
  2499. begin
  2500. if FBitmap <> Value then
  2501. begin
  2502. FBitmap := Value;
  2503. Changed;
  2504. end;
  2505. end;
  2506. procedure TPolygonRenderer32.SetColor(const Value: TColor32);
  2507. begin
  2508. if FColor <> Value then
  2509. begin
  2510. FColor := Value;
  2511. Changed;
  2512. end;
  2513. end;
  2514. procedure TPolygonRenderer32.SetFiller(const Value: TCustomPolygonFiller);
  2515. begin
  2516. if FFiller <> Value then
  2517. begin
  2518. FFiller := Value;
  2519. Changed;
  2520. end;
  2521. end;
  2522. procedure TPolygonRenderer32.SetFillMode(const Value: TPolyFillMode);
  2523. begin
  2524. if FFillMode <> Value then
  2525. begin
  2526. FFillMode := Value;
  2527. Changed;
  2528. end;
  2529. end;
  2530. //------------------------------------------------------------------------------
  2531. //
  2532. // TPolygonRenderer32VPR
  2533. //
  2534. //------------------------------------------------------------------------------
  2535. {$IFDEF USESTACKALLOC}
  2536. {$W+}
  2537. {$ENDIF}
  2538. procedure TPolygonRenderer32VPR.FillSpan(const Span: TValueSpan; DstY: Integer);
  2539. var
  2540. AlphaValues: PColor32Array;
  2541. Count: Integer;
  2542. begin
  2543. Count := Span.HighX - Span.LowX + 1;
  2544. {$IFDEF USESTACKALLOC}
  2545. AlphaValues := StackAlloc(Count * SizeOf(TColor32));
  2546. {$ELSE}
  2547. GetMem(AlphaValues, Count * SizeOf(TColor32));
  2548. {$ENDIF}
  2549. FFillProc(Span.Values, AlphaValues, Count, FColor);
  2550. FFiller.FillLine(@Bitmap.ScanLine[DstY][Span.LowX], Span.LowX, DstY, Count, PColor32(AlphaValues), Bitmap.CombineMode);
  2551. {$IFDEF USESTACKALLOC}
  2552. StackFree(AlphaValues);
  2553. {$ELSE}
  2554. FreeMem(AlphaValues);
  2555. {$ENDIF}
  2556. end;
  2557. {$IFDEF USESTACKALLOC}
  2558. {$W-}
  2559. {$ENDIF}
  2560. //------------------------------------------------------------------------------
  2561. function TPolygonRenderer32VPR.GetRenderSpan: TRenderSpanEvent;
  2562. begin
  2563. if (FFiller <> nil) then
  2564. Result := FillSpan
  2565. else
  2566. Result := RenderSpan;
  2567. end;
  2568. //------------------------------------------------------------------------------
  2569. procedure TPolygonRenderer32VPR.PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint; const ClipRect: TFloatRect);
  2570. {$IFDEF CHANGENOTIFICATIONS}
  2571. var
  2572. i: Integer;
  2573. ChangeRect: TRect;
  2574. {$ENDIF}
  2575. begin
  2576. if (not Bitmap.MeasuringMode) then
  2577. begin
  2578. UpdateFillProc;
  2579. if (FFiller <> nil) then
  2580. begin
  2581. FFiller.BeginRendering;
  2582. RenderPolyPolygon(Points, ClipRect, GetRenderSpan());
  2583. FFiller.EndRendering;
  2584. end else
  2585. RenderPolyPolygon(Points, ClipRect, GetRenderSpan());
  2586. end;
  2587. {$IFDEF CHANGENOTIFICATIONS}
  2588. if (TBitmap32Access(Bitmap).LockUpdateCount = 0) and
  2589. ((Bitmap.MeasuringMode) or (TBitmap32Access(Bitmap).UpdateCount = 0)) then
  2590. begin
  2591. for i := 0 to High(Points) do
  2592. if (Length(Points[i]) > 0) then
  2593. begin
  2594. if (GR32.IntersectRect(ChangeRect, MakeRect(ClipRect, rrOutside), MakeRect(PolygonBounds(Points[i])))) then
  2595. Bitmap.Changed(ChangeRect);
  2596. end;
  2597. end;
  2598. {$ENDIF}
  2599. end;
  2600. //------------------------------------------------------------------------------
  2601. {$W+}
  2602. procedure TPolygonRenderer32VPR.RenderSpan(const Span: TValueSpan; DstY: Integer);
  2603. var
  2604. AlphaValues: PColor32Array;
  2605. Count: Integer;
  2606. begin
  2607. Count := Span.HighX - Span.LowX + 1;
  2608. {$IFDEF USESTACKALLOC}
  2609. AlphaValues := StackAlloc(Count * SizeOf(TColor32));
  2610. {$ELSE}
  2611. GetMem(AlphaValues, Count * SizeOf(TColor32));
  2612. {$ENDIF}
  2613. FFillProc(Span.Values, AlphaValues, Count, FColor);
  2614. if Bitmap.CombineMode = cmMerge then
  2615. MergeLine(@AlphaValues[0], @Bitmap.ScanLine[DstY][Span.LowX], Count)
  2616. else
  2617. BlendLine(@AlphaValues[0], @Bitmap.ScanLine[DstY][Span.LowX], Count);
  2618. {$IFDEF USESTACKALLOC}
  2619. StackFree(AlphaValues);
  2620. {$ELSE}
  2621. FreeMem(AlphaValues);
  2622. {$ENDIF}
  2623. end;
  2624. {$W-}
  2625. //------------------------------------------------------------------------------
  2626. procedure TPolygonRenderer32VPR.GetFillProc(var AFillProc: TFillProc);
  2627. type
  2628. PFillProc = ^TFillProc;
  2629. const
  2630. FillProcs: array [Boolean, TPolyFillMode] of PFillProc = (
  2631. (@@MakeAlphaEvenOddUP, @@MakeAlphaNonZeroUP),
  2632. (@@MakeAlphaEvenOddUPF, @@MakeAlphaNonZeroUPF)
  2633. );
  2634. begin
  2635. AFillProc := FillProcs[(FFiller <> nil), FillMode]^;
  2636. end;
  2637. //------------------------------------------------------------------------------
  2638. procedure TPolygonRenderer32VPR.UpdateFillProc;
  2639. begin
  2640. GetFillProc(FFillProc);
  2641. end;
  2642. //------------------------------------------------------------------------------
  2643. //
  2644. // TPolygonRenderer32LCD
  2645. //
  2646. //------------------------------------------------------------------------------
  2647. procedure TPolygonRenderer32LCD.PolyPolygonFS(const Points: TArrayOfArrayOfFloatPoint; const ClipRect: TFloatRect);
  2648. var
  2649. R: TFloatRect;
  2650. APoints: TArrayOfArrayOfFloatPoint;
  2651. {$IFDEF CHANGENOTIFICATIONS}
  2652. i: Integer;
  2653. ChangeRect: TRect;
  2654. {$ENDIF}
  2655. begin
  2656. if (not Bitmap.MeasuringMode) then
  2657. begin
  2658. APoints := ScalePolyPolygon(Points, 3, 1);
  2659. R.Top := ClipRect.Top;
  2660. R.Bottom := ClipRect.Bottom;
  2661. R.Left := ClipRect.Left * 3;
  2662. R.Right := ClipRect.Right * 3;
  2663. RenderPolyPolygon(APoints, R, RenderSpan);
  2664. end;
  2665. {$IFDEF CHANGENOTIFICATIONS}
  2666. if (TBitmap32Access(Bitmap).LockUpdateCount = 0) and
  2667. ((Bitmap.MeasuringMode) or (TBitmap32Access(Bitmap).UpdateCount = 0)) then
  2668. begin
  2669. for i := 0 to High(Points) do
  2670. if (Length(Points[i]) > 0) then
  2671. begin
  2672. if (GR32.IntersectRect(ChangeRect, MakeRect(ClipRect, rrOutside), MakeRect(PolygonBounds(Points[i])))) then
  2673. Bitmap.Changed(ChangeRect);
  2674. end;
  2675. end;
  2676. {$ENDIF}
  2677. end;
  2678. //------------------------------------------------------------------------------
  2679. {$W+}
  2680. procedure TPolygonRenderer32LCD.RenderSpan(const Span: TValueSpan;
  2681. DstY: Integer);
  2682. const
  2683. PADDING = 5;
  2684. var
  2685. AlphaValues: PByteArray;
  2686. Count: Integer;
  2687. X, Offset: Integer;
  2688. const
  2689. MakeAlpha: array [TPolyFillMode] of TMakeAlphaProcLCD = (MakeAlphaEvenOddLCD, MakeAlphaNonZeroLCD);
  2690. begin
  2691. Count := Span.HighX - Span.LowX + 1;
  2692. X := DivMod(Span.LowX, 3, Offset);
  2693. // Left Padding + Right Padding + Filter Width = 2 + 2 + 2 = 6
  2694. {$IFDEF USESTACKALLOC}
  2695. AlphaValues := StackAlloc((Count + 6 + PADDING) * SizeOf(Byte));
  2696. {$ELSE}
  2697. GetMem(AlphaValues, (Count + 6 + PADDING) * SizeOf(Byte));
  2698. {$ENDIF}
  2699. AlphaValues[0] := 0;
  2700. AlphaValues[1] := 0;
  2701. if (X > 0) then
  2702. begin
  2703. Dec(X);
  2704. Inc(Offset, 3);
  2705. AlphaValues[2] := 0;
  2706. AlphaValues[3] := 0;
  2707. AlphaValues[4] := 0;
  2708. end;
  2709. MakeAlpha[FFillMode](Span.Values, PByteArray(@AlphaValues[PADDING]), Count, FColor);
  2710. CombineLineLCD(@AlphaValues[PADDING - Offset], PColor32Array(@Bitmap.ScanLine[DstY][X]), FColor, (Count + Offset + 2) div 3);
  2711. {$IFDEF USESTACKALLOC}
  2712. StackFree(AlphaValues);
  2713. {$ELSE}
  2714. FreeMem(AlphaValues);
  2715. {$ENDIF}
  2716. end;
  2717. {$W-}
  2718. //------------------------------------------------------------------------------
  2719. //
  2720. // TPolygonRenderer32LCD2
  2721. //
  2722. //------------------------------------------------------------------------------
  2723. {$W+}
  2724. procedure TPolygonRenderer32LCD2.RenderSpan(const Span: TValueSpan; DstY: Integer);
  2725. const
  2726. PADDING = 5;
  2727. var
  2728. AlphaValues: PByteArray;
  2729. Count: Integer;
  2730. X, Offset: Integer;
  2731. const
  2732. MakeAlpha: array [TPolyFillMode] of TMakeAlphaProcLCD = (MakeAlphaEvenOddLCD2, MakeAlphaNonZeroLCD2);
  2733. begin
  2734. Count := Span.HighX - Span.LowX + 1;
  2735. X := DivMod(Span.LowX, 3, Offset);
  2736. // Left Padding + Right Padding + Filter Width = 2 + 2 + 2 = 6
  2737. {$IFDEF USESTACKALLOC}
  2738. AlphaValues := StackAlloc((Count + 6 + PADDING) * SizeOf(Byte));
  2739. {$ELSE}
  2740. GetMem(AlphaValues, (Count + 6 + PADDING) * SizeOf(Byte));
  2741. {$ENDIF}
  2742. AlphaValues[0] := 0;
  2743. AlphaValues[1] := 0;
  2744. if (X > 0) then
  2745. begin
  2746. Dec(X);
  2747. Inc(Offset, 3);
  2748. AlphaValues[2] := 0;
  2749. AlphaValues[3] := 0;
  2750. AlphaValues[4] := 0;
  2751. end;
  2752. Dec(Offset, 1);
  2753. MakeAlpha[FFillMode](Span.Values, PByteArray(@AlphaValues[PADDING]), Count, FColor);
  2754. Inc(Count);
  2755. CombineLineLCD(@AlphaValues[PADDING - Offset], PColor32Array(@Bitmap.ScanLine[DstY][X]), FColor, (Count + Offset + 2) div 3);
  2756. {$IFDEF USESTACKALLOC}
  2757. StackFree(AlphaValues);
  2758. {$ELSE}
  2759. FreeMem(AlphaValues);
  2760. {$ENDIF}
  2761. end;
  2762. {$W-}
  2763. //------------------------------------------------------------------------------
  2764. //
  2765. // Bindings
  2766. //
  2767. //------------------------------------------------------------------------------
  2768. procedure RegisterBindings;
  2769. begin
  2770. PolygonsRegistry.RegisterBinding(@@MakeAlphaEvenOddUP, 'MakeAlphaEvenOddUP');
  2771. PolygonsRegistry.RegisterBinding(@@MakeAlphaNonZeroUP, 'MakeAlphaNonZeroUP');
  2772. PolygonsRegistry.RegisterBinding(@@MakeAlphaEvenOddUPF, 'MakeAlphaEvenOddUPF');
  2773. PolygonsRegistry.RegisterBinding(@@MakeAlphaNonZeroUPF, 'MakeAlphaNonZeroUPF');
  2774. end;
  2775. var
  2776. FPolygonsRegistry: TFunctionRegistry = nil;
  2777. function PolygonsRegistry: TFunctionRegistry;
  2778. begin
  2779. if (FPolygonsRegistry = nil) then
  2780. begin
  2781. FPolygonsRegistry := NewRegistry('GR32_Polygons bindings');
  2782. RegisterBindings;
  2783. end;
  2784. Result := FPolygonsRegistry;
  2785. end;
  2786. //------------------------------------------------------------------------------
  2787. //
  2788. // Function bindings
  2789. //
  2790. //------------------------------------------------------------------------------
  2791. procedure RegisterBindingFunctions;
  2792. begin
  2793. // EvenOddUP
  2794. PolygonsRegistry[@@MakeAlphaEvenOddUP].Add( @MakeAlphaEvenOddUP_Pas, [isPascal]).Name := 'MakeAlphaEvenOddUP_Pas';
  2795. {$if (not defined(PUREPASCAL)) and (not defined(OMIT_SSE2))}
  2796. PolygonsRegistry[@@MakeAlphaEvenOddUP].Add( @MakeAlphaEvenOddUP_SSE2, [isSSE2]).Name := 'MakeAlphaEvenOddUP_SSE2';
  2797. PolygonsRegistry[@@MakeAlphaEvenOddUP].Add( @MakeAlphaEvenOddUP_SSE41, [isSSE2]).Name := 'MakeAlphaEvenOddUP_SSE41';
  2798. {$ifend}
  2799. // NonZeroUP
  2800. PolygonsRegistry[@@MakeAlphaNonZeroUP].Add( @MakeAlphaNonZeroUP_Pas, [isPascal]).Name := 'MakeAlphaNonZeroUP_Pas';
  2801. {$if (not defined(PUREPASCAL)) and (not defined(OMIT_SSE2))}
  2802. PolygonsRegistry[@@MakeAlphaNonZeroUP].Add( @MakeAlphaNonZeroUP_SSE2, [isSSE2]).Name := 'MakeAlphaNonZeroUP_SSE2';
  2803. {$ifend}
  2804. // EvenOddUPF
  2805. PolygonsRegistry[@@MakeAlphaEvenOddUPF].Add( @MakeAlphaEvenOddUPF_Pas, [isPascal]).Name := 'MakeAlphaEvenOddUPF_Pas';
  2806. // NonZeroUPF
  2807. PolygonsRegistry[@@MakeAlphaNonZeroUPF].Add( @MakeAlphaNonZeroUPF_Pas, [isPascal]).Name := 'MakeAlphaNonZeroUPF_Pas';
  2808. end;
  2809. //------------------------------------------------------------------------------
  2810. //------------------------------------------------------------------------------
  2811. //------------------------------------------------------------------------------
  2812. initialization
  2813. RegisterBindingFunctions;
  2814. PolygonsRegistry.RebindAll;
  2815. RegisterPolygonRenderer(TPolygonRenderer32VPR);
  2816. RegisterPolygonRenderer(TPolygonRenderer32LCD);
  2817. RegisterPolygonRenderer(TPolygonRenderer32LCD2);
  2818. finalization
  2819. CustomPolygonRendererList.Free;
  2820. PolygonRendererList.Free;
  2821. end.