agg_pixfmt_rgba.h 105 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801
  1. //----------------------------------------------------------------------------
  2. // Anti-Grain Geometry - Version 2.4
  3. // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  4. //
  5. // Permission to copy, use, modify, sell and distribute this software
  6. // is granted provided this copyright notice appears in all copies.
  7. // This software is provided "as is" without express or implied
  8. // warranty, and with no claim as to its suitability for any purpose.
  9. //
  10. //----------------------------------------------------------------------------
  11. // Contact: mcseem@antigrain.com
  12. // mcseemagg@yahoo.com
  13. // http://www.antigrain.com
  14. //----------------------------------------------------------------------------
  15. //
  16. // Adaptation for high precision colors has been sponsored by
  17. // Liberty Technology Systems, Inc., visit http://lib-sys.com
  18. //
  19. // Liberty Technology Systems, Inc. is the provider of
  20. // PostScript and PDF technology for software developers.
  21. //
  22. //----------------------------------------------------------------------------
  23. #ifndef AGG_PIXFMT_RGBA_INCLUDED
  24. #define AGG_PIXFMT_RGBA_INCLUDED
  25. #include <string.h>
  26. #include <math.h>
  27. #include "agg_pixfmt_base.h"
  28. #include "agg_rendering_buffer.h"
  29. namespace agg
  30. {
  31. template<class T> inline T sd_min(T a, T b) { return (a < b) ? a : b; }
  32. template<class T> inline T sd_max(T a, T b) { return (a > b) ? a : b; }
  33. inline rgba & clip(rgba & c)
  34. {
  35. if (c.a > 1) c.a = 1; else if (c.a < 0) c.a = 0;
  36. if (c.r > c.a) c.r = c.a; else if (c.r < 0) c.r = 0;
  37. if (c.g > c.a) c.g = c.a; else if (c.g < 0) c.g = 0;
  38. if (c.b > c.a) c.b = c.a; else if (c.b < 0) c.b = 0;
  39. return c;
  40. }
  41. //=========================================================multiplier_rgba
  42. template<class ColorT, class Order>
  43. struct multiplier_rgba
  44. {
  45. typedef ColorT color_type;
  46. typedef typename color_type::value_type value_type;
  47. //--------------------------------------------------------------------
  48. static AGG_INLINE void premultiply(value_type* p)
  49. {
  50. value_type a = p[Order::A];
  51. p[Order::R] = color_type::multiply(p[Order::R], a);
  52. p[Order::G] = color_type::multiply(p[Order::G], a);
  53. p[Order::B] = color_type::multiply(p[Order::B], a);
  54. }
  55. //--------------------------------------------------------------------
  56. static AGG_INLINE void demultiply(value_type* p)
  57. {
  58. value_type a = p[Order::A];
  59. p[Order::R] = color_type::demultiply(p[Order::R], a);
  60. p[Order::G] = color_type::demultiply(p[Order::G], a);
  61. p[Order::B] = color_type::demultiply(p[Order::B], a);
  62. }
  63. };
  64. //=====================================================apply_gamma_dir_rgba
  65. template<class ColorT, class Order, class GammaLut>
  66. class apply_gamma_dir_rgba
  67. {
  68. public:
  69. typedef ColorT color_type;
  70. typedef typename color_type::value_type value_type;
  71. apply_gamma_dir_rgba(const GammaLut& gamma) : m_gamma(gamma) {}
  72. AGG_INLINE void operator () (value_type* p)
  73. {
  74. p[Order::R] = m_gamma.dir(p[Order::R]);
  75. p[Order::G] = m_gamma.dir(p[Order::G]);
  76. p[Order::B] = m_gamma.dir(p[Order::B]);
  77. }
  78. private:
  79. const GammaLut& m_gamma;
  80. };
  81. //=====================================================apply_gamma_inv_rgba
  82. template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgba
  83. {
  84. public:
  85. typedef ColorT color_type;
  86. typedef typename color_type::value_type value_type;
  87. apply_gamma_inv_rgba(const GammaLut& gamma) : m_gamma(gamma) {}
  88. AGG_INLINE void operator () (value_type* p)
  89. {
  90. p[Order::R] = m_gamma.inv(p[Order::R]);
  91. p[Order::G] = m_gamma.inv(p[Order::G]);
  92. p[Order::B] = m_gamma.inv(p[Order::B]);
  93. }
  94. private:
  95. const GammaLut& m_gamma;
  96. };
  97. template<class ColorT, class Order>
  98. struct conv_rgba_pre
  99. {
  100. typedef ColorT color_type;
  101. typedef Order order_type;
  102. typedef typename color_type::value_type value_type;
  103. //--------------------------------------------------------------------
  104. static AGG_INLINE void set_plain_color(value_type* p, color_type c)
  105. {
  106. c.premultiply();
  107. p[Order::R] = c.r;
  108. p[Order::G] = c.g;
  109. p[Order::B] = c.b;
  110. p[Order::A] = c.a;
  111. }
  112. //--------------------------------------------------------------------
  113. static AGG_INLINE color_type get_plain_color(const value_type* p)
  114. {
  115. return color_type(
  116. p[Order::R],
  117. p[Order::G],
  118. p[Order::B],
  119. p[Order::A]).demultiply();
  120. }
  121. };
  122. template<class ColorT, class Order>
  123. struct conv_rgba_plain
  124. {
  125. typedef ColorT color_type;
  126. typedef Order order_type;
  127. typedef typename color_type::value_type value_type;
  128. //--------------------------------------------------------------------
  129. static AGG_INLINE void set_plain_color(value_type* p, color_type c)
  130. {
  131. p[Order::R] = c.r;
  132. p[Order::G] = c.g;
  133. p[Order::B] = c.b;
  134. p[Order::A] = c.a;
  135. }
  136. //--------------------------------------------------------------------
  137. static AGG_INLINE color_type get_plain_color(const value_type* p)
  138. {
  139. return color_type(
  140. p[Order::R],
  141. p[Order::G],
  142. p[Order::B],
  143. p[Order::A]);
  144. }
  145. };
  146. //=============================================================blender_rgba
  147. // Blends "plain" (i.e. non-premultiplied) colors into a premultiplied buffer.
  148. template<class ColorT, class Order>
  149. struct blender_rgba : conv_rgba_pre<ColorT, Order>
  150. {
  151. typedef ColorT color_type;
  152. typedef Order order_type;
  153. typedef typename color_type::value_type value_type;
  154. typedef typename color_type::calc_type calc_type;
  155. typedef typename color_type::long_type long_type;
  156. // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
  157. // compositing function. Since the render buffer is in fact premultiplied
  158. // we omit the initial premultiplication and final demultiplication.
  159. //--------------------------------------------------------------------
  160. static AGG_INLINE void blend_pix(value_type* p,
  161. value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
  162. {
  163. blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
  164. }
  165. //--------------------------------------------------------------------
  166. static AGG_INLINE void blend_pix(value_type* p,
  167. value_type cr, value_type cg, value_type cb, value_type alpha)
  168. {
  169. p[Order::R] = color_type::lerp(p[Order::R], cr, alpha);
  170. p[Order::G] = color_type::lerp(p[Order::G], cg, alpha);
  171. p[Order::B] = color_type::lerp(p[Order::B], cb, alpha);
  172. p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha);
  173. }
  174. };
  175. //========================================================blender_rgba_pre
  176. // Blends premultiplied colors into a premultiplied buffer.
  177. template<class ColorT, class Order>
  178. struct blender_rgba_pre : conv_rgba_pre<ColorT, Order>
  179. {
  180. typedef ColorT color_type;
  181. typedef Order order_type;
  182. typedef typename color_type::value_type value_type;
  183. typedef typename color_type::calc_type calc_type;
  184. typedef typename color_type::long_type long_type;
  185. // Blend pixels using the premultiplied form of Alvy-Ray Smith's
  186. // compositing function.
  187. //--------------------------------------------------------------------
  188. static AGG_INLINE void blend_pix(value_type* p,
  189. value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
  190. {
  191. blend_pix(p,
  192. color_type::mult_cover(cr, cover),
  193. color_type::mult_cover(cg, cover),
  194. color_type::mult_cover(cb, cover),
  195. color_type::mult_cover(alpha, cover));
  196. }
  197. //--------------------------------------------------------------------
  198. static AGG_INLINE void blend_pix(value_type* p,
  199. value_type cr, value_type cg, value_type cb, value_type alpha)
  200. {
  201. p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha);
  202. p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha);
  203. p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha);
  204. p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha);
  205. }
  206. };
  207. //======================================================blender_rgba_plain
  208. // Blends "plain" (non-premultiplied) colors into a plain (non-premultiplied) buffer.
  209. template<class ColorT, class Order>
  210. struct blender_rgba_plain : conv_rgba_plain<ColorT, Order>
  211. {
  212. typedef ColorT color_type;
  213. typedef Order order_type;
  214. typedef typename color_type::value_type value_type;
  215. typedef typename color_type::calc_type calc_type;
  216. typedef typename color_type::long_type long_type;
  217. // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
  218. // compositing function.
  219. //--------------------------------------------------------------------
  220. static AGG_INLINE void blend_pix(value_type* p,
  221. value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
  222. {
  223. blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
  224. }
  225. //--------------------------------------------------------------------
  226. static AGG_INLINE void blend_pix(value_type* p,
  227. value_type cr, value_type cg, value_type cb, value_type alpha)
  228. {
  229. if (alpha > color_type::empty_value())
  230. {
  231. calc_type a = p[Order::A];
  232. calc_type r = color_type::multiply(p[Order::R], a);
  233. calc_type g = color_type::multiply(p[Order::G], a);
  234. calc_type b = color_type::multiply(p[Order::B], a);
  235. p[Order::R] = color_type::lerp(r, cr, alpha);
  236. p[Order::G] = color_type::lerp(g, cg, alpha);
  237. p[Order::B] = color_type::lerp(b, cb, alpha);
  238. p[Order::A] = color_type::prelerp(a, alpha, alpha);
  239. multiplier_rgba<ColorT, Order>::demultiply(p);
  240. }
  241. }
  242. };
  243. // SVG compositing operations.
  244. // For specifications, see http://www.w3.org/TR/SVGCompositing/
  245. //=========================================================comp_op_rgba_clear
  246. template<class ColorT, class Order>
  247. struct comp_op_rgba_clear : blender_base<ColorT, Order>
  248. {
  249. typedef ColorT color_type;
  250. typedef typename color_type::value_type value_type;
  251. using blender_base<ColorT, Order>::get;
  252. using blender_base<ColorT, Order>::set;
  253. // Dca' = 0
  254. // Da' = 0
  255. static AGG_INLINE void blend_pix(value_type* p,
  256. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  257. {
  258. if (cover >= cover_full)
  259. {
  260. p[0] = p[1] = p[2] = p[3] = color_type::empty_value();
  261. }
  262. else if (cover > cover_none)
  263. {
  264. set(p, get(p, cover_full - cover));
  265. }
  266. }
  267. };
  268. //===========================================================comp_op_rgba_src
  269. template<class ColorT, class Order>
  270. struct comp_op_rgba_src : blender_base<ColorT, Order>
  271. {
  272. typedef ColorT color_type;
  273. typedef typename color_type::value_type value_type;
  274. using blender_base<ColorT, Order>::get;
  275. using blender_base<ColorT, Order>::set;
  276. // Dca' = Sca
  277. // Da' = Sa
  278. static AGG_INLINE void blend_pix(value_type* p,
  279. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  280. {
  281. if (cover >= cover_full)
  282. {
  283. set(p, r, g, b, a);
  284. }
  285. else
  286. {
  287. rgba s = get(r, g, b, a, cover);
  288. rgba d = get(p, cover_full - cover);
  289. d.r += s.r;
  290. d.g += s.g;
  291. d.b += s.b;
  292. d.a += s.a;
  293. set(p, d);
  294. }
  295. }
  296. };
  297. //===========================================================comp_op_rgba_dst
  298. template<class ColorT, class Order>
  299. struct comp_op_rgba_dst : blender_base<ColorT, Order>
  300. {
  301. typedef ColorT color_type;
  302. typedef typename color_type::value_type value_type;
  303. // Dca' = Dca.Sa + Dca.(1 - Sa) = Dca
  304. // Da' = Da.Sa + Da.(1 - Sa) = Da
  305. static AGG_INLINE void blend_pix(value_type* p,
  306. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  307. {
  308. // Well, that was easy!
  309. }
  310. };
  311. //======================================================comp_op_rgba_src_over
  312. template<class ColorT, class Order>
  313. struct comp_op_rgba_src_over : blender_base<ColorT, Order>
  314. {
  315. typedef ColorT color_type;
  316. typedef typename color_type::value_type value_type;
  317. using blender_base<ColorT, Order>::get;
  318. using blender_base<ColorT, Order>::set;
  319. // Dca' = Sca + Dca.(1 - Sa) = Dca + Sca - Dca.Sa
  320. // Da' = Sa + Da - Sa.Da
  321. static AGG_INLINE void blend_pix(value_type* p,
  322. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  323. {
  324. #if 1
  325. blender_rgba_pre<ColorT, Order>::blend_pix(p, r, g, b, a, cover);
  326. #else
  327. rgba s = get(r, g, b, a, cover);
  328. rgba d = get(p);
  329. d.r += s.r - d.r * s.a;
  330. d.g += s.g - d.g * s.a;
  331. d.b += s.b - d.b * s.a;
  332. d.a += s.a - d.a * s.a;
  333. set(p, d);
  334. #endif
  335. }
  336. };
  337. //======================================================comp_op_rgba_dst_over
  338. template<class ColorT, class Order>
  339. struct comp_op_rgba_dst_over : blender_base<ColorT, Order>
  340. {
  341. typedef ColorT color_type;
  342. typedef typename color_type::value_type value_type;
  343. using blender_base<ColorT, Order>::get;
  344. using blender_base<ColorT, Order>::set;
  345. // Dca' = Dca + Sca.(1 - Da)
  346. // Da' = Sa + Da - Sa.Da = Da + Sa.(1 - Da)
  347. static AGG_INLINE void blend_pix(value_type* p,
  348. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  349. {
  350. rgba s = get(r, g, b, a, cover);
  351. rgba d = get(p);
  352. double d1a = 1 - d.a;
  353. d.r += s.r * d1a;
  354. d.g += s.g * d1a;
  355. d.b += s.b * d1a;
  356. d.a += s.a * d1a;
  357. set(p, d);
  358. }
  359. };
  360. //======================================================comp_op_rgba_src_in
  361. template<class ColorT, class Order>
  362. struct comp_op_rgba_src_in : blender_base<ColorT, Order>
  363. {
  364. typedef ColorT color_type;
  365. typedef typename color_type::value_type value_type;
  366. using blender_base<ColorT, Order>::get;
  367. using blender_base<ColorT, Order>::set;
  368. // Dca' = Sca.Da
  369. // Da' = Sa.Da
  370. static AGG_INLINE void blend_pix(value_type* p,
  371. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  372. {
  373. double da = ColorT::to_double(p[Order::A]);
  374. if (da > 0)
  375. {
  376. rgba s = get(r, g, b, a, cover);
  377. rgba d = get(p, cover_full - cover);
  378. d.r += s.r * da;
  379. d.g += s.g * da;
  380. d.b += s.b * da;
  381. d.a += s.a * da;
  382. set(p, d);
  383. }
  384. }
  385. };
  386. //======================================================comp_op_rgba_dst_in
  387. template<class ColorT, class Order>
  388. struct comp_op_rgba_dst_in : blender_base<ColorT, Order>
  389. {
  390. typedef ColorT color_type;
  391. typedef typename color_type::value_type value_type;
  392. using blender_base<ColorT, Order>::get;
  393. using blender_base<ColorT, Order>::set;
  394. // Dca' = Dca.Sa
  395. // Da' = Sa.Da
  396. static AGG_INLINE void blend_pix(value_type* p,
  397. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  398. {
  399. double sa = ColorT::to_double(a);
  400. rgba d = get(p, cover_full - cover);
  401. rgba d2 = get(p, cover);
  402. d.r += d2.r * sa;
  403. d.g += d2.g * sa;
  404. d.b += d2.b * sa;
  405. d.a += d2.a * sa;
  406. set(p, d);
  407. }
  408. };
  409. //======================================================comp_op_rgba_src_out
  410. template<class ColorT, class Order>
  411. struct comp_op_rgba_src_out : blender_base<ColorT, Order>
  412. {
  413. typedef ColorT color_type;
  414. typedef typename color_type::value_type value_type;
  415. using blender_base<ColorT, Order>::get;
  416. using blender_base<ColorT, Order>::set;
  417. // Dca' = Sca.(1 - Da)
  418. // Da' = Sa.(1 - Da)
  419. static AGG_INLINE void blend_pix(value_type* p,
  420. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  421. {
  422. rgba s = get(r, g, b, a, cover);
  423. rgba d = get(p, cover_full - cover);
  424. double d1a = 1 - ColorT::to_double(p[Order::A]);
  425. d.r += s.r * d1a;
  426. d.g += s.g * d1a;
  427. d.b += s.b * d1a;
  428. d.a += s.a * d1a;
  429. set(p, d);
  430. }
  431. };
  432. //======================================================comp_op_rgba_dst_out
  433. template<class ColorT, class Order>
  434. struct comp_op_rgba_dst_out : blender_base<ColorT, Order>
  435. {
  436. typedef ColorT color_type;
  437. typedef typename color_type::value_type value_type;
  438. using blender_base<ColorT, Order>::get;
  439. using blender_base<ColorT, Order>::set;
  440. // Dca' = Dca.(1 - Sa)
  441. // Da' = Da.(1 - Sa)
  442. static AGG_INLINE void blend_pix(value_type* p,
  443. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  444. {
  445. rgba d = get(p, cover_full - cover);
  446. rgba dc = get(p, cover);
  447. double s1a = 1 - ColorT::to_double(a);
  448. d.r += dc.r * s1a;
  449. d.g += dc.g * s1a;
  450. d.b += dc.b * s1a;
  451. d.a += dc.a * s1a;
  452. set(p, d);
  453. }
  454. };
  455. //=====================================================comp_op_rgba_src_atop
  456. template<class ColorT, class Order>
  457. struct comp_op_rgba_src_atop : blender_base<ColorT, Order>
  458. {
  459. typedef ColorT color_type;
  460. typedef typename color_type::value_type value_type;
  461. using blender_base<ColorT, Order>::get;
  462. using blender_base<ColorT, Order>::set;
  463. // Dca' = Sca.Da + Dca.(1 - Sa)
  464. // Da' = Da
  465. static AGG_INLINE void blend_pix(value_type* p,
  466. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  467. {
  468. rgba s = get(r, g, b, a, cover);
  469. rgba d = get(p);
  470. double s1a = 1 - s.a;
  471. d.r = s.r * d.a + d.r * s1a;
  472. d.g = s.g * d.a + d.g * s1a;
  473. d.b = s.b * d.a + d.g * s1a;
  474. set(p, d);
  475. }
  476. };
  477. //=====================================================comp_op_rgba_dst_atop
  478. template<class ColorT, class Order>
  479. struct comp_op_rgba_dst_atop : blender_base<ColorT, Order>
  480. {
  481. typedef ColorT color_type;
  482. typedef typename color_type::value_type value_type;
  483. using blender_base<ColorT, Order>::get;
  484. using blender_base<ColorT, Order>::set;
  485. // Dca' = Dca.Sa + Sca.(1 - Da)
  486. // Da' = Sa
  487. static AGG_INLINE void blend_pix(value_type* p,
  488. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  489. {
  490. rgba sc = get(r, g, b, a, cover);
  491. rgba dc = get(p, cover);
  492. rgba d = get(p, cover_full - cover);
  493. double sa = ColorT::to_double(a);
  494. double d1a = 1 - ColorT::to_double(p[Order::A]);
  495. d.r += dc.r * sa + sc.r * d1a;
  496. d.g += dc.g * sa + sc.g * d1a;
  497. d.b += dc.b * sa + sc.b * d1a;
  498. d.a += sc.a;
  499. set(p, d);
  500. }
  501. };
  502. //=========================================================comp_op_rgba_xor
  503. template<class ColorT, class Order>
  504. struct comp_op_rgba_xor : blender_base<ColorT, Order>
  505. {
  506. typedef ColorT color_type;
  507. typedef typename color_type::value_type value_type;
  508. using blender_base<ColorT, Order>::get;
  509. using blender_base<ColorT, Order>::set;
  510. // Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
  511. // Da' = Sa + Da - 2.Sa.Da
  512. static AGG_INLINE void blend_pix(value_type* p,
  513. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  514. {
  515. rgba s = get(r, g, b, a, cover);
  516. rgba d = get(p);
  517. double s1a = 1 - s.a;
  518. double d1a = 1 - ColorT::to_double(p[Order::A]);
  519. d.r = s.r * d1a + d.r * s1a;
  520. d.g = s.g * d1a + d.g * s1a;
  521. d.b = s.b * d1a + d.b * s1a;
  522. d.a = s.a + d.a - 2 * s.a * d.a;
  523. set(p, d);
  524. }
  525. };
  526. //=========================================================comp_op_rgba_plus
  527. template<class ColorT, class Order>
  528. struct comp_op_rgba_plus : blender_base<ColorT, Order>
  529. {
  530. typedef ColorT color_type;
  531. typedef typename color_type::value_type value_type;
  532. using blender_base<ColorT, Order>::get;
  533. using blender_base<ColorT, Order>::set;
  534. // Dca' = Sca + Dca
  535. // Da' = Sa + Da
  536. static AGG_INLINE void blend_pix(value_type* p,
  537. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  538. {
  539. rgba s = get(r, g, b, a, cover);
  540. if (s.a > 0)
  541. {
  542. rgba d = get(p);
  543. d.a = sd_min(d.a + s.a, 1.0);
  544. d.r = sd_min(d.r + s.r, d.a);
  545. d.g = sd_min(d.g + s.g, d.a);
  546. d.b = sd_min(d.b + s.b, d.a);
  547. set(p, clip(d));
  548. }
  549. }
  550. };
  551. //========================================================comp_op_rgba_minus
  552. // Note: not included in SVG spec.
  553. template<class ColorT, class Order>
  554. struct comp_op_rgba_minus : blender_base<ColorT, Order>
  555. {
  556. typedef ColorT color_type;
  557. typedef typename color_type::value_type value_type;
  558. using blender_base<ColorT, Order>::get;
  559. using blender_base<ColorT, Order>::set;
  560. // Dca' = Dca - Sca
  561. // Da' = 1 - (1 - Sa).(1 - Da) = Da + Sa - Sa.Da
  562. static AGG_INLINE void blend_pix(value_type* p,
  563. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  564. {
  565. rgba s = get(r, g, b, a, cover);
  566. if (s.a > 0)
  567. {
  568. rgba d = get(p);
  569. d.a += s.a - s.a * d.a;
  570. d.r = sd_max(d.r - s.r, 0.0);
  571. d.g = sd_max(d.g - s.g, 0.0);
  572. d.b = sd_max(d.b - s.b, 0.0);
  573. set(p, clip(d));
  574. }
  575. }
  576. };
  577. //=====================================================comp_op_rgba_multiply
  578. template<class ColorT, class Order>
  579. struct comp_op_rgba_multiply : blender_base<ColorT, Order>
  580. {
  581. typedef ColorT color_type;
  582. typedef typename color_type::value_type value_type;
  583. using blender_base<ColorT, Order>::get;
  584. using blender_base<ColorT, Order>::set;
  585. // Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
  586. // Da' = Sa + Da - Sa.Da
  587. static AGG_INLINE void blend_pix(value_type* p,
  588. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  589. {
  590. rgba s = get(r, g, b, a, cover);
  591. if (s.a > 0)
  592. {
  593. rgba d = get(p);
  594. double s1a = 1 - s.a;
  595. double d1a = 1 - d.a;
  596. d.r = s.r * d.r + s.r * d1a + d.r * s1a;
  597. d.g = s.g * d.g + s.g * d1a + d.g * s1a;
  598. d.b = s.b * d.b + s.b * d1a + d.b * s1a;
  599. d.a += s.a - s.a * d.a;
  600. set(p, clip(d));
  601. }
  602. }
  603. };
  604. //=====================================================comp_op_rgba_screen
  605. template<class ColorT, class Order>
  606. struct comp_op_rgba_screen : blender_base<ColorT, Order>
  607. {
  608. typedef ColorT color_type;
  609. typedef typename color_type::value_type value_type;
  610. using blender_base<ColorT, Order>::get;
  611. using blender_base<ColorT, Order>::set;
  612. // Dca' = Sca + Dca - Sca.Dca
  613. // Da' = Sa + Da - Sa.Da
  614. static AGG_INLINE void blend_pix(value_type* p,
  615. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  616. {
  617. rgba s = get(r, g, b, a, cover);
  618. if (s.a > 0)
  619. {
  620. rgba d = get(p);
  621. d.r += s.r - s.r * d.r;
  622. d.g += s.g - s.g * d.g;
  623. d.b += s.b - s.b * d.b;
  624. d.a += s.a - s.a * d.a;
  625. set(p, clip(d));
  626. }
  627. }
  628. };
  629. //=====================================================comp_op_rgba_overlay
  630. template<class ColorT, class Order>
  631. struct comp_op_rgba_overlay : blender_base<ColorT, Order>
  632. {
  633. typedef ColorT color_type;
  634. typedef typename color_type::value_type value_type;
  635. using blender_base<ColorT, Order>::get;
  636. using blender_base<ColorT, Order>::set;
  637. // if 2.Dca <= Da
  638. // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
  639. // otherwise
  640. // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
  641. //
  642. // Da' = Sa + Da - Sa.Da
  643. static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a)
  644. {
  645. return (2 * dca <= da) ?
  646. 2 * sca * dca + sca * d1a + dca * s1a :
  647. sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a;
  648. }
  649. static AGG_INLINE void blend_pix(value_type* p,
  650. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  651. {
  652. rgba s = get(r, g, b, a, cover);
  653. if (s.a > 0)
  654. {
  655. rgba d = get(p);
  656. double d1a = 1 - d.a;
  657. double s1a = 1 - s.a;
  658. double sada = s.a * d.a;
  659. d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a);
  660. d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a);
  661. d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a);
  662. d.a += s.a - s.a * d.a;
  663. set(p, clip(d));
  664. }
  665. }
  666. };
  667. //=====================================================comp_op_rgba_darken
  668. template<class ColorT, class Order>
  669. struct comp_op_rgba_darken : blender_base<ColorT, Order>
  670. {
  671. typedef ColorT color_type;
  672. typedef typename color_type::value_type value_type;
  673. using blender_base<ColorT, Order>::get;
  674. using blender_base<ColorT, Order>::set;
  675. // Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
  676. // Da' = Sa + Da - Sa.Da
  677. static AGG_INLINE void blend_pix(value_type* p,
  678. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  679. {
  680. rgba s = get(r, g, b, a, cover);
  681. if (s.a > 0)
  682. {
  683. rgba d = get(p);
  684. double d1a = 1 - d.a;
  685. double s1a = 1 - s.a;
  686. d.r = sd_min(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a;
  687. d.g = sd_min(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a;
  688. d.b = sd_min(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a;
  689. d.a += s.a - s.a * d.a;
  690. set(p, clip(d));
  691. }
  692. }
  693. };
  694. //=====================================================comp_op_rgba_lighten
  695. template<class ColorT, class Order>
  696. struct comp_op_rgba_lighten : blender_base<ColorT, Order>
  697. {
  698. typedef ColorT color_type;
  699. typedef typename color_type::value_type value_type;
  700. using blender_base<ColorT, Order>::get;
  701. using blender_base<ColorT, Order>::set;
  702. // Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
  703. // Da' = Sa + Da - Sa.Da
  704. static AGG_INLINE void blend_pix(value_type* p,
  705. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  706. {
  707. rgba s = get(r, g, b, a, cover);
  708. if (s.a > 0)
  709. {
  710. rgba d = get(p);
  711. double d1a = 1 - d.a;
  712. double s1a = 1 - s.a;
  713. d.r = sd_max(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a;
  714. d.g = sd_max(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a;
  715. d.b = sd_max(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a;
  716. d.a += s.a - s.a * d.a;
  717. set(p, clip(d));
  718. }
  719. }
  720. };
  721. //=====================================================comp_op_rgba_color_dodge
  722. template<class ColorT, class Order>
  723. struct comp_op_rgba_color_dodge : blender_base<ColorT, Order>
  724. {
  725. typedef ColorT color_type;
  726. typedef typename color_type::value_type value_type;
  727. using blender_base<ColorT, Order>::get;
  728. using blender_base<ColorT, Order>::set;
  729. // if Sca == Sa and Dca == 0
  730. // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) = Sca.(1 - Da)
  731. // otherwise if Sca == Sa
  732. // Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
  733. // otherwise if Sca < Sa
  734. // Dca' = Sa.Da.min(1, Dca/Da.Sa/(Sa - Sca)) + Sca.(1 - Da) + Dca.(1 - Sa)
  735. //
  736. // Da' = Sa + Da - Sa.Da
  737. static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a)
  738. {
  739. if (sca < sa) return sada * sd_min(1.0, (dca / da) * sa / (sa - sca)) + sca * d1a + dca * s1a;
  740. if (dca > 0) return sada + sca * d1a + dca * s1a;
  741. return sca * d1a;
  742. }
  743. static AGG_INLINE void blend_pix(value_type* p,
  744. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  745. {
  746. rgba s = get(r, g, b, a, cover);
  747. if (s.a > 0)
  748. {
  749. rgba d = get(p);
  750. if (d.a > 0)
  751. {
  752. double sada = s.a * d.a;
  753. double s1a = 1 - s.a;
  754. double d1a = 1 - d.a;
  755. d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a);
  756. d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a);
  757. d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a);
  758. d.a += s.a - s.a * d.a;
  759. set(p, clip(d));
  760. }
  761. else set(p, s);
  762. }
  763. }
  764. };
  765. //=====================================================comp_op_rgba_color_burn
  766. template<class ColorT, class Order>
  767. struct comp_op_rgba_color_burn : blender_base<ColorT, Order>
  768. {
  769. typedef ColorT color_type;
  770. typedef typename color_type::value_type value_type;
  771. using blender_base<ColorT, Order>::get;
  772. using blender_base<ColorT, Order>::set;
  773. // if Sca == 0 and Dca == Da
  774. // Dca' = Sa.Da + Dca.(1 - Sa)
  775. // otherwise if Sca == 0
  776. // Dca' = Dca.(1 - Sa)
  777. // otherwise if Sca > 0
  778. // Dca' = Sa.Da.(1 - min(1, (1 - Dca/Da).Sa/Sca)) + Sca.(1 - Da) + Dca.(1 - Sa)
  779. static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a)
  780. {
  781. if (sca > 0) return sada * (1 - sd_min(1.0, (1 - dca / da) * sa / sca)) + sca * d1a + dca * s1a;
  782. if (dca > da) return sada + dca * s1a;
  783. return dca * s1a;
  784. }
  785. static AGG_INLINE void blend_pix(value_type* p,
  786. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  787. {
  788. rgba s = get(r, g, b, a, cover);
  789. if (s.a > 0)
  790. {
  791. rgba d = get(p);
  792. if (d.a > 0)
  793. {
  794. double sada = s.a * d.a;
  795. double s1a = 1 - s.a;
  796. double d1a = 1 - d.a;
  797. d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a);
  798. d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a);
  799. d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a);
  800. d.a += s.a - sada;
  801. set(p, clip(d));
  802. }
  803. else set(p, s);
  804. }
  805. }
  806. };
  807. //=====================================================comp_op_rgba_hard_light
  808. template<class ColorT, class Order>
  809. struct comp_op_rgba_hard_light : blender_base<ColorT, Order>
  810. {
  811. typedef ColorT color_type;
  812. typedef typename color_type::value_type value_type;
  813. using blender_base<ColorT, Order>::get;
  814. using blender_base<ColorT, Order>::set;
  815. // if 2.Sca < Sa
  816. // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
  817. // otherwise
  818. // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
  819. //
  820. // Da' = Sa + Da - Sa.Da
  821. static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a)
  822. {
  823. return (2 * sca < sa) ?
  824. 2 * sca * dca + sca * d1a + dca * s1a :
  825. sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a;
  826. }
  827. static AGG_INLINE void blend_pix(value_type* p,
  828. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  829. {
  830. rgba s = get(r, g, b, a, cover);
  831. if (s.a > 0)
  832. {
  833. rgba d = get(p);
  834. double d1a = 1 - d.a;
  835. double s1a = 1 - s.a;
  836. double sada = s.a * d.a;
  837. d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a);
  838. d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a);
  839. d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a);
  840. d.a += s.a - sada;
  841. set(p, clip(d));
  842. }
  843. }
  844. };
  845. //=====================================================comp_op_rgba_soft_light
  846. template<class ColorT, class Order>
  847. struct comp_op_rgba_soft_light : blender_base<ColorT, Order>
  848. {
  849. typedef ColorT color_type;
  850. typedef typename color_type::value_type value_type;
  851. using blender_base<ColorT, Order>::get;
  852. using blender_base<ColorT, Order>::set;
  853. // if 2.Sca <= Sa
  854. // Dca' = Dca.Sa - (Sa.Da - 2.Sca.Da).Dca.Sa.(Sa.Da - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
  855. // otherwise if 2.Sca > Sa and 4.Dca <= Da
  856. // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((((16.Dsa.Sa - 12).Dsa.Sa + 4).Dsa.Da) - Dsa.Da) + Sca.(1 - Da) + Dca.(1 - Sa)
  857. // otherwise if 2.Sca > Sa and 4.Dca > Da
  858. // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((Dca.Sa)^0.5 - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
  859. //
  860. // Da' = Sa + Da - Sa.Da
  861. static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a)
  862. {
  863. double dcasa = dca * sa;
  864. if (2 * sca <= sa) return dcasa - (sada - 2 * sca * da) * dcasa * (sada - dcasa) + sca * d1a + dca * s1a;
  865. if (4 * dca <= da) return dcasa + (2 * sca * da - sada) * ((((16 * dcasa - 12) * dcasa + 4) * dca * da) - dca * da) + sca * d1a + dca * s1a;
  866. return dcasa + (2 * sca * da - sada) * (sqrt(dcasa) - dcasa) + sca * d1a + dca * s1a;
  867. }
  868. static AGG_INLINE void blend_pix(value_type* p,
  869. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  870. {
  871. rgba s = get(r, g, b, a, cover);
  872. if (s.a > 0)
  873. {
  874. rgba d = get(p);
  875. if (d.a > 0)
  876. {
  877. double sada = s.a * d.a;
  878. double s1a = 1 - s.a;
  879. double d1a = 1 - d.a;
  880. d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a);
  881. d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a);
  882. d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a);
  883. d.a += s.a - sada;
  884. set(p, clip(d));
  885. }
  886. else set(p, s);
  887. }
  888. }
  889. };
  890. //=====================================================comp_op_rgba_difference
  891. template<class ColorT, class Order>
  892. struct comp_op_rgba_difference : blender_base<ColorT, Order>
  893. {
  894. typedef ColorT color_type;
  895. typedef typename color_type::value_type value_type;
  896. using blender_base<ColorT, Order>::get;
  897. using blender_base<ColorT, Order>::set;
  898. // Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
  899. // Da' = Sa + Da - Sa.Da
  900. static AGG_INLINE void blend_pix(value_type* p,
  901. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  902. {
  903. rgba s = get(r, g, b, a, cover);
  904. if (s.a > 0)
  905. {
  906. rgba d = get(p);
  907. d.r += s.r - 2 * sd_min(s.r * d.a, d.r * s.a);
  908. d.g += s.g - 2 * sd_min(s.g * d.a, d.g * s.a);
  909. d.b += s.b - 2 * sd_min(s.b * d.a, d.b * s.a);
  910. d.a += s.a - s.a * d.a;
  911. set(p, clip(d));
  912. }
  913. }
  914. };
  915. //=====================================================comp_op_rgba_exclusion
  916. template<class ColorT, class Order>
  917. struct comp_op_rgba_exclusion : blender_base<ColorT, Order>
  918. {
  919. typedef ColorT color_type;
  920. typedef typename color_type::value_type value_type;
  921. using blender_base<ColorT, Order>::get;
  922. using blender_base<ColorT, Order>::set;
  923. // Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
  924. // Da' = Sa + Da - Sa.Da
  925. static AGG_INLINE void blend_pix(value_type* p,
  926. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  927. {
  928. rgba s = get(r, g, b, a, cover);
  929. if (s.a > 0)
  930. {
  931. rgba d = get(p);
  932. double d1a = 1 - d.a;
  933. double s1a = 1 - s.a;
  934. d.r = (s.r * d.a + d.r * s.a - 2 * s.r * d.r) + s.r * d1a + d.r * s1a;
  935. d.g = (s.g * d.a + d.g * s.a - 2 * s.g * d.g) + s.g * d1a + d.g * s1a;
  936. d.b = (s.b * d.a + d.b * s.a - 2 * s.b * d.b) + s.b * d1a + d.b * s1a;
  937. d.a += s.a - s.a * d.a;
  938. set(p, clip(d));
  939. }
  940. }
  941. };
  942. #if 0
  943. //=====================================================comp_op_rgba_contrast
  944. template<class ColorT, class Order> struct comp_op_rgba_contrast
  945. {
  946. typedef ColorT color_type;
  947. typedef Order order_type;
  948. typedef typename color_type::value_type value_type;
  949. typedef typename color_type::calc_type calc_type;
  950. typedef typename color_type::long_type long_type;
  951. enum base_scale_e
  952. {
  953. base_shift = color_type::base_shift,
  954. base_mask = color_type::base_mask
  955. };
  956. static AGG_INLINE void blend_pix(value_type* p,
  957. unsigned sr, unsigned sg, unsigned sb,
  958. unsigned sa, unsigned cover)
  959. {
  960. if (cover < 255)
  961. {
  962. sr = (sr * cover + 255) >> 8;
  963. sg = (sg * cover + 255) >> 8;
  964. sb = (sb * cover + 255) >> 8;
  965. sa = (sa * cover + 255) >> 8;
  966. }
  967. long_type dr = p[Order::R];
  968. long_type dg = p[Order::G];
  969. long_type db = p[Order::B];
  970. int da = p[Order::A];
  971. long_type d2a = da >> 1;
  972. unsigned s2a = sa >> 1;
  973. int r = (int)((((dr - d2a) * int((sr - s2a)*2 + base_mask)) >> base_shift) + d2a);
  974. int g = (int)((((dg - d2a) * int((sg - s2a)*2 + base_mask)) >> base_shift) + d2a);
  975. int b = (int)((((db - d2a) * int((sb - s2a)*2 + base_mask)) >> base_shift) + d2a);
  976. r = (r < 0) ? 0 : r;
  977. g = (g < 0) ? 0 : g;
  978. b = (b < 0) ? 0 : b;
  979. p[Order::R] = (value_type)((r > da) ? da : r);
  980. p[Order::G] = (value_type)((g > da) ? da : g);
  981. p[Order::B] = (value_type)((b > da) ? da : b);
  982. }
  983. };
  984. //=====================================================comp_op_rgba_invert
  985. template<class ColorT, class Order> struct comp_op_rgba_invert
  986. {
  987. typedef ColorT color_type;
  988. typedef Order order_type;
  989. typedef typename color_type::value_type value_type;
  990. typedef typename color_type::calc_type calc_type;
  991. typedef typename color_type::long_type long_type;
  992. enum base_scale_e
  993. {
  994. base_shift = color_type::base_shift,
  995. base_mask = color_type::base_mask
  996. };
  997. // Dca' = (Da - Dca) * Sa + Dca.(1 - Sa)
  998. // Da' = Sa + Da - Sa.Da
  999. static AGG_INLINE void blend_pix(value_type* p,
  1000. unsigned sr, unsigned sg, unsigned sb,
  1001. unsigned sa, unsigned cover)
  1002. {
  1003. sa = (sa * cover + 255) >> 8;
  1004. if (sa)
  1005. {
  1006. calc_type da = p[Order::A];
  1007. calc_type dr = ((da - p[Order::R]) * sa + base_mask) >> base_shift;
  1008. calc_type dg = ((da - p[Order::G]) * sa + base_mask) >> base_shift;
  1009. calc_type db = ((da - p[Order::B]) * sa + base_mask) >> base_shift;
  1010. calc_type s1a = base_mask - sa;
  1011. p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift));
  1012. p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift));
  1013. p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift));
  1014. p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
  1015. }
  1016. }
  1017. };
  1018. //=================================================comp_op_rgba_invert_rgb
  1019. template<class ColorT, class Order> struct comp_op_rgba_invert_rgb
  1020. {
  1021. typedef ColorT color_type;
  1022. typedef Order order_type;
  1023. typedef typename color_type::value_type value_type;
  1024. typedef typename color_type::calc_type calc_type;
  1025. typedef typename color_type::long_type long_type;
  1026. enum base_scale_e
  1027. {
  1028. base_shift = color_type::base_shift,
  1029. base_mask = color_type::base_mask
  1030. };
  1031. // Dca' = (Da - Dca) * Sca + Dca.(1 - Sa)
  1032. // Da' = Sa + Da - Sa.Da
  1033. static AGG_INLINE void blend_pix(value_type* p,
  1034. unsigned sr, unsigned sg, unsigned sb,
  1035. unsigned sa, unsigned cover)
  1036. {
  1037. if (cover < 255)
  1038. {
  1039. sr = (sr * cover + 255) >> 8;
  1040. sg = (sg * cover + 255) >> 8;
  1041. sb = (sb * cover + 255) >> 8;
  1042. sa = (sa * cover + 255) >> 8;
  1043. }
  1044. if (sa)
  1045. {
  1046. calc_type da = p[Order::A];
  1047. calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift;
  1048. calc_type dg = ((da - p[Order::G]) * sg + base_mask) >> base_shift;
  1049. calc_type db = ((da - p[Order::B]) * sb + base_mask) >> base_shift;
  1050. calc_type s1a = base_mask - sa;
  1051. p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift));
  1052. p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift));
  1053. p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift));
  1054. p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
  1055. }
  1056. }
  1057. };
  1058. #endif
  1059. //======================================================comp_op_table_rgba
  1060. template<class ColorT, class Order> struct comp_op_table_rgba
  1061. {
  1062. typedef typename ColorT::value_type value_type;
  1063. typedef typename ColorT::calc_type calc_type;
  1064. typedef void (*comp_op_func_type)(value_type* p,
  1065. value_type cr,
  1066. value_type cg,
  1067. value_type cb,
  1068. value_type ca,
  1069. cover_type cover);
  1070. static comp_op_func_type g_comp_op_func[];
  1071. };
  1072. //==========================================================g_comp_op_func
  1073. template<class ColorT, class Order>
  1074. typename comp_op_table_rgba<ColorT, Order>::comp_op_func_type
  1075. comp_op_table_rgba<ColorT, Order>::g_comp_op_func[] =
  1076. {
  1077. comp_op_rgba_clear <ColorT,Order>::blend_pix,
  1078. comp_op_rgba_src <ColorT,Order>::blend_pix,
  1079. comp_op_rgba_dst <ColorT,Order>::blend_pix,
  1080. comp_op_rgba_src_over <ColorT,Order>::blend_pix,
  1081. comp_op_rgba_dst_over <ColorT,Order>::blend_pix,
  1082. comp_op_rgba_src_in <ColorT,Order>::blend_pix,
  1083. comp_op_rgba_dst_in <ColorT,Order>::blend_pix,
  1084. comp_op_rgba_src_out <ColorT,Order>::blend_pix,
  1085. comp_op_rgba_dst_out <ColorT,Order>::blend_pix,
  1086. comp_op_rgba_src_atop <ColorT,Order>::blend_pix,
  1087. comp_op_rgba_dst_atop <ColorT,Order>::blend_pix,
  1088. comp_op_rgba_xor <ColorT,Order>::blend_pix,
  1089. comp_op_rgba_plus <ColorT,Order>::blend_pix,
  1090. //comp_op_rgba_minus <ColorT,Order>::blend_pix,
  1091. comp_op_rgba_multiply <ColorT,Order>::blend_pix,
  1092. comp_op_rgba_screen <ColorT,Order>::blend_pix,
  1093. comp_op_rgba_overlay <ColorT,Order>::blend_pix,
  1094. comp_op_rgba_darken <ColorT,Order>::blend_pix,
  1095. comp_op_rgba_lighten <ColorT,Order>::blend_pix,
  1096. comp_op_rgba_color_dodge<ColorT,Order>::blend_pix,
  1097. comp_op_rgba_color_burn <ColorT,Order>::blend_pix,
  1098. comp_op_rgba_hard_light <ColorT,Order>::blend_pix,
  1099. comp_op_rgba_soft_light <ColorT,Order>::blend_pix,
  1100. comp_op_rgba_difference <ColorT,Order>::blend_pix,
  1101. comp_op_rgba_exclusion <ColorT,Order>::blend_pix,
  1102. //comp_op_rgba_contrast <ColorT,Order>::blend_pix,
  1103. //comp_op_rgba_invert <ColorT,Order>::blend_pix,
  1104. //comp_op_rgba_invert_rgb <ColorT,Order>::blend_pix,
  1105. 0
  1106. };
  1107. //==============================================================comp_op_e
  1108. enum comp_op_e
  1109. {
  1110. comp_op_clear, //----comp_op_clear
  1111. comp_op_src, //----comp_op_src
  1112. comp_op_dst, //----comp_op_dst
  1113. comp_op_src_over, //----comp_op_src_over
  1114. comp_op_dst_over, //----comp_op_dst_over
  1115. comp_op_src_in, //----comp_op_src_in
  1116. comp_op_dst_in, //----comp_op_dst_in
  1117. comp_op_src_out, //----comp_op_src_out
  1118. comp_op_dst_out, //----comp_op_dst_out
  1119. comp_op_src_atop, //----comp_op_src_atop
  1120. comp_op_dst_atop, //----comp_op_dst_atop
  1121. comp_op_xor, //----comp_op_xor
  1122. comp_op_plus, //----comp_op_plus
  1123. //comp_op_minus, //----comp_op_minus
  1124. comp_op_multiply, //----comp_op_multiply
  1125. comp_op_screen, //----comp_op_screen
  1126. comp_op_overlay, //----comp_op_overlay
  1127. comp_op_darken, //----comp_op_darken
  1128. comp_op_lighten, //----comp_op_lighten
  1129. comp_op_color_dodge, //----comp_op_color_dodge
  1130. comp_op_color_burn, //----comp_op_color_burn
  1131. comp_op_hard_light, //----comp_op_hard_light
  1132. comp_op_soft_light, //----comp_op_soft_light
  1133. comp_op_difference, //----comp_op_difference
  1134. comp_op_exclusion, //----comp_op_exclusion
  1135. //comp_op_contrast, //----comp_op_contrast
  1136. //comp_op_invert, //----comp_op_invert
  1137. //comp_op_invert_rgb, //----comp_op_invert_rgb
  1138. end_of_comp_op_e
  1139. };
  1140. //====================================================comp_op_adaptor_rgba
  1141. template<class ColorT, class Order>
  1142. struct comp_op_adaptor_rgba
  1143. {
  1144. typedef ColorT color_type;
  1145. typedef Order order_type;
  1146. typedef typename color_type::value_type value_type;
  1147. typedef typename color_type::calc_type calc_type;
  1148. typedef typename color_type::long_type long_type;
  1149. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1150. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1151. {
  1152. comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p,
  1153. color_type::multiply(r, a),
  1154. color_type::multiply(g, a),
  1155. color_type::multiply(b, a),
  1156. a, cover);
  1157. }
  1158. };
  1159. //=========================================comp_op_adaptor_clip_to_dst_rgba
  1160. template<class ColorT, class Order>
  1161. struct comp_op_adaptor_clip_to_dst_rgba
  1162. {
  1163. typedef ColorT color_type;
  1164. typedef Order order_type;
  1165. typedef typename color_type::value_type value_type;
  1166. typedef typename color_type::calc_type calc_type;
  1167. typedef typename color_type::long_type long_type;
  1168. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1169. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1170. {
  1171. r = color_type::multiply(r, a);
  1172. g = color_type::multiply(g, a);
  1173. b = color_type::multiply(b, a);
  1174. value_type da = p[Order::A];
  1175. comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p,
  1176. color_type::multiply(r, da),
  1177. color_type::multiply(g, da),
  1178. color_type::multiply(b, da),
  1179. color_type::multiply(a, da), cover);
  1180. }
  1181. };
  1182. //================================================comp_op_adaptor_rgba_pre
  1183. template<class ColorT, class Order>
  1184. struct comp_op_adaptor_rgba_pre
  1185. {
  1186. typedef ColorT color_type;
  1187. typedef Order order_type;
  1188. typedef typename color_type::value_type value_type;
  1189. typedef typename color_type::calc_type calc_type;
  1190. typedef typename color_type::long_type long_type;
  1191. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1192. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1193. {
  1194. comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, r, g, b, a, cover);
  1195. }
  1196. };
  1197. //=====================================comp_op_adaptor_clip_to_dst_rgba_pre
  1198. template<class ColorT, class Order>
  1199. struct comp_op_adaptor_clip_to_dst_rgba_pre
  1200. {
  1201. typedef ColorT color_type;
  1202. typedef Order order_type;
  1203. typedef typename color_type::value_type value_type;
  1204. typedef typename color_type::calc_type calc_type;
  1205. typedef typename color_type::long_type long_type;
  1206. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1207. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1208. {
  1209. value_type da = p[Order::A];
  1210. comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p,
  1211. color_type::multiply(r, da),
  1212. color_type::multiply(g, da),
  1213. color_type::multiply(b, da),
  1214. color_type::multiply(a, da), cover);
  1215. }
  1216. };
  1217. //====================================================comp_op_adaptor_rgba_plain
  1218. template<class ColorT, class Order>
  1219. struct comp_op_adaptor_rgba_plain
  1220. {
  1221. typedef ColorT color_type;
  1222. typedef Order order_type;
  1223. typedef typename color_type::value_type value_type;
  1224. typedef typename color_type::calc_type calc_type;
  1225. typedef typename color_type::long_type long_type;
  1226. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1227. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1228. {
  1229. multiplier_rgba<ColorT, Order>::premultiply(p);
  1230. comp_op_adaptor_rgba<ColorT, Order>::blend_pix(op, p, r, g, b, a, cover);
  1231. multiplier_rgba<ColorT, Order>::demultiply(p);
  1232. }
  1233. };
  1234. //=========================================comp_op_adaptor_clip_to_dst_rgba_plain
  1235. template<class ColorT, class Order>
  1236. struct comp_op_adaptor_clip_to_dst_rgba_plain
  1237. {
  1238. typedef ColorT color_type;
  1239. typedef Order order_type;
  1240. typedef typename color_type::value_type value_type;
  1241. typedef typename color_type::calc_type calc_type;
  1242. typedef typename color_type::long_type long_type;
  1243. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1244. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1245. {
  1246. multiplier_rgba<ColorT, Order>::premultiply(p);
  1247. comp_op_adaptor_clip_to_dst_rgba<ColorT, Order>::blend_pix(op, p, r, g, b, a, cover);
  1248. multiplier_rgba<ColorT, Order>::demultiply(p);
  1249. }
  1250. };
  1251. //=======================================================comp_adaptor_rgba
  1252. template<class BlenderPre>
  1253. struct comp_adaptor_rgba
  1254. {
  1255. typedef typename BlenderPre::color_type color_type;
  1256. typedef typename BlenderPre::order_type order_type;
  1257. typedef typename color_type::value_type value_type;
  1258. typedef typename color_type::calc_type calc_type;
  1259. typedef typename color_type::long_type long_type;
  1260. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1261. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1262. {
  1263. BlenderPre::blend_pix(p,
  1264. color_type::multiply(r, a),
  1265. color_type::multiply(g, a),
  1266. color_type::multiply(b, a),
  1267. a, cover);
  1268. }
  1269. };
  1270. //==========================================comp_adaptor_clip_to_dst_rgba
  1271. template<class BlenderPre>
  1272. struct comp_adaptor_clip_to_dst_rgba
  1273. {
  1274. typedef typename BlenderPre::color_type color_type;
  1275. typedef typename BlenderPre::order_type order_type;
  1276. typedef typename color_type::value_type value_type;
  1277. typedef typename color_type::calc_type calc_type;
  1278. typedef typename color_type::long_type long_type;
  1279. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1280. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1281. {
  1282. r = color_type::multiply(r, a);
  1283. g = color_type::multiply(g, a);
  1284. b = color_type::multiply(b, a);
  1285. value_type da = p[order_type::A];
  1286. BlenderPre::blend_pix(p,
  1287. color_type::multiply(r, da),
  1288. color_type::multiply(g, da),
  1289. color_type::multiply(b, da),
  1290. color_type::multiply(a, da), cover);
  1291. }
  1292. };
  1293. //=======================================================comp_adaptor_rgba_pre
  1294. template<class BlenderPre>
  1295. struct comp_adaptor_rgba_pre
  1296. {
  1297. typedef typename BlenderPre::color_type color_type;
  1298. typedef typename BlenderPre::order_type order_type;
  1299. typedef typename color_type::value_type value_type;
  1300. typedef typename color_type::calc_type calc_type;
  1301. typedef typename color_type::long_type long_type;
  1302. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1303. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1304. {
  1305. BlenderPre::blend_pix(p, r, g, b, a, cover);
  1306. }
  1307. };
  1308. //======================================comp_adaptor_clip_to_dst_rgba_pre
  1309. template<class BlenderPre>
  1310. struct comp_adaptor_clip_to_dst_rgba_pre
  1311. {
  1312. typedef typename BlenderPre::color_type color_type;
  1313. typedef typename BlenderPre::order_type order_type;
  1314. typedef typename color_type::value_type value_type;
  1315. typedef typename color_type::calc_type calc_type;
  1316. typedef typename color_type::long_type long_type;
  1317. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1318. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1319. {
  1320. unsigned da = p[order_type::A];
  1321. BlenderPre::blend_pix(p,
  1322. color_type::multiply(r, da),
  1323. color_type::multiply(g, da),
  1324. color_type::multiply(b, da),
  1325. color_type::multiply(a, da),
  1326. cover);
  1327. }
  1328. };
  1329. //=======================================================comp_adaptor_rgba_plain
  1330. template<class BlenderPre>
  1331. struct comp_adaptor_rgba_plain
  1332. {
  1333. typedef typename BlenderPre::color_type color_type;
  1334. typedef typename BlenderPre::order_type order_type;
  1335. typedef typename color_type::value_type value_type;
  1336. typedef typename color_type::calc_type calc_type;
  1337. typedef typename color_type::long_type long_type;
  1338. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1339. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1340. {
  1341. multiplier_rgba<color_type, order_type>::premultiply(p);
  1342. comp_adaptor_rgba<BlenderPre>::blend_pix(op, p, r, g, b, a, cover);
  1343. multiplier_rgba<color_type, order_type>::demultiply(p);
  1344. }
  1345. };
  1346. //==========================================comp_adaptor_clip_to_dst_rgba_plain
  1347. template<class BlenderPre>
  1348. struct comp_adaptor_clip_to_dst_rgba_plain
  1349. {
  1350. typedef typename BlenderPre::color_type color_type;
  1351. typedef typename BlenderPre::order_type order_type;
  1352. typedef typename color_type::value_type value_type;
  1353. typedef typename color_type::calc_type calc_type;
  1354. typedef typename color_type::long_type long_type;
  1355. static AGG_INLINE void blend_pix(unsigned op, value_type* p,
  1356. value_type r, value_type g, value_type b, value_type a, cover_type cover)
  1357. {
  1358. multiplier_rgba<color_type, order_type>::premultiply(p);
  1359. comp_adaptor_clip_to_dst_rgba<BlenderPre>::blend_pix(op, p, r, g, b, a, cover);
  1360. multiplier_rgba<color_type, order_type>::demultiply(p);
  1361. }
  1362. };
  1363. //=================================================pixfmt_alpha_blend_rgba
  1364. template<class Blender, class RenBuf>
  1365. class pixfmt_alpha_blend_rgba
  1366. {
  1367. public:
  1368. typedef pixfmt_rgba_tag pixfmt_category;
  1369. typedef RenBuf rbuf_type;
  1370. typedef typename rbuf_type::row_data row_data;
  1371. typedef Blender blender_type;
  1372. typedef typename blender_type::color_type color_type;
  1373. typedef typename blender_type::order_type order_type;
  1374. typedef typename color_type::value_type value_type;
  1375. typedef typename color_type::calc_type calc_type;
  1376. enum
  1377. {
  1378. pix_step = 4,
  1379. pix_width = sizeof(value_type) * pix_step,
  1380. };
  1381. struct pixel_type
  1382. {
  1383. value_type c[pix_step];
  1384. void set(value_type r, value_type g, value_type b, value_type a)
  1385. {
  1386. c[order_type::R] = r;
  1387. c[order_type::G] = g;
  1388. c[order_type::B] = b;
  1389. c[order_type::A] = a;
  1390. }
  1391. void set(const color_type& color)
  1392. {
  1393. set(color.r, color.g, color.b, color.a);
  1394. }
  1395. void get(value_type& r, value_type& g, value_type& b, value_type& a) const
  1396. {
  1397. r = c[order_type::R];
  1398. g = c[order_type::G];
  1399. b = c[order_type::B];
  1400. a = c[order_type::A];
  1401. }
  1402. color_type get() const
  1403. {
  1404. return color_type(
  1405. c[order_type::R],
  1406. c[order_type::G],
  1407. c[order_type::B],
  1408. c[order_type::A]);
  1409. }
  1410. pixel_type* next()
  1411. {
  1412. return this + 1;
  1413. }
  1414. const pixel_type* next() const
  1415. {
  1416. return this + 1;
  1417. }
  1418. pixel_type* advance(int n)
  1419. {
  1420. return this + n;
  1421. }
  1422. const pixel_type* advance(int n) const
  1423. {
  1424. return this + n;
  1425. }
  1426. };
  1427. private:
  1428. //--------------------------------------------------------------------
  1429. AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
  1430. {
  1431. m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover);
  1432. }
  1433. //--------------------------------------------------------------------
  1434. AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
  1435. {
  1436. m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a);
  1437. }
  1438. //--------------------------------------------------------------------
  1439. AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
  1440. {
  1441. if (!c.is_transparent())
  1442. {
  1443. if (c.is_opaque() && cover == cover_mask)
  1444. {
  1445. p->set(c.r, c.g, c.b, c.a);
  1446. }
  1447. else
  1448. {
  1449. m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover);
  1450. }
  1451. }
  1452. }
  1453. //--------------------------------------------------------------------
  1454. AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
  1455. {
  1456. if (!c.is_transparent())
  1457. {
  1458. if (c.is_opaque())
  1459. {
  1460. p->set(c.r, c.g, c.b, c.a);
  1461. }
  1462. else
  1463. {
  1464. m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a);
  1465. }
  1466. }
  1467. }
  1468. public:
  1469. //--------------------------------------------------------------------
  1470. pixfmt_alpha_blend_rgba() : m_rbuf(0) {}
  1471. explicit pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {}
  1472. void attach(rbuf_type& rb) { m_rbuf = &rb; }
  1473. //--------------------------------------------------------------------
  1474. template<class PixFmt>
  1475. bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
  1476. {
  1477. rect_i r(x1, y1, x2, y2);
  1478. if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
  1479. {
  1480. int stride = pixf.stride();
  1481. m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
  1482. (r.x2 - r.x1) + 1,
  1483. (r.y2 - r.y1) + 1,
  1484. stride);
  1485. return true;
  1486. }
  1487. return false;
  1488. }
  1489. //--------------------------------------------------------------------
  1490. AGG_INLINE unsigned width() const { return m_rbuf->width(); }
  1491. AGG_INLINE unsigned height() const { return m_rbuf->height(); }
  1492. AGG_INLINE int stride() const { return m_rbuf->stride(); }
  1493. //--------------------------------------------------------------------
  1494. AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
  1495. AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
  1496. AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
  1497. //--------------------------------------------------------------------
  1498. AGG_INLINE int8u* pix_ptr(int x, int y)
  1499. {
  1500. return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step);
  1501. }
  1502. AGG_INLINE const int8u* pix_ptr(int x, int y) const
  1503. {
  1504. return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step);
  1505. }
  1506. // Return pointer to pixel value, forcing row to be allocated.
  1507. AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
  1508. {
  1509. return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step));
  1510. }
  1511. // Return pointer to pixel value, or null if row not allocated.
  1512. AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
  1513. {
  1514. int8u* p = m_rbuf->row_ptr(y);
  1515. return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0;
  1516. }
  1517. // Get pixel pointer from raw buffer pointer.
  1518. AGG_INLINE static pixel_type* pix_value_ptr(void* p)
  1519. {
  1520. return (pixel_type*)p;
  1521. }
  1522. // Get pixel pointer from raw buffer pointer.
  1523. AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
  1524. {
  1525. return (const pixel_type*)p;
  1526. }
  1527. //--------------------------------------------------------------------
  1528. AGG_INLINE static void write_plain_color(void* p, color_type c)
  1529. {
  1530. blender_type::set_plain_color(pix_value_ptr(p)->c, c);
  1531. }
  1532. //--------------------------------------------------------------------
  1533. AGG_INLINE static color_type read_plain_color(const void* p)
  1534. {
  1535. return blender_type::get_plain_color(pix_value_ptr(p)->c);
  1536. }
  1537. //--------------------------------------------------------------------
  1538. AGG_INLINE static void make_pix(int8u* p, const color_type& c)
  1539. {
  1540. ((pixel_type*)p)->set(c);
  1541. }
  1542. //--------------------------------------------------------------------
  1543. AGG_INLINE color_type pixel(int x, int y) const
  1544. {
  1545. if (const pixel_type* p = pix_value_ptr(x, y))
  1546. {
  1547. return p->get();
  1548. }
  1549. return color_type::no_color();
  1550. }
  1551. //--------------------------------------------------------------------
  1552. AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
  1553. {
  1554. pix_value_ptr(x, y, 1)->set(c);
  1555. }
  1556. //--------------------------------------------------------------------
  1557. AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
  1558. {
  1559. copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
  1560. }
  1561. //--------------------------------------------------------------------
  1562. AGG_INLINE void copy_hline(int x, int y,
  1563. unsigned len,
  1564. const color_type& c)
  1565. {
  1566. pixel_type v;
  1567. v.set(c);
  1568. pixel_type* p = pix_value_ptr(x, y, len);
  1569. do
  1570. {
  1571. *p = v;
  1572. p = p->next();
  1573. }
  1574. while (--len);
  1575. }
  1576. //--------------------------------------------------------------------
  1577. AGG_INLINE void copy_vline(int x, int y,
  1578. unsigned len,
  1579. const color_type& c)
  1580. {
  1581. pixel_type v;
  1582. v.set(c);
  1583. do
  1584. {
  1585. *pix_value_ptr(x, y++, 1) = v;
  1586. }
  1587. while (--len);
  1588. }
  1589. //--------------------------------------------------------------------
  1590. void blend_hline(int x, int y,
  1591. unsigned len,
  1592. const color_type& c,
  1593. int8u cover)
  1594. {
  1595. if (!c.is_transparent())
  1596. {
  1597. pixel_type* p = pix_value_ptr(x, y, len);
  1598. if (c.is_opaque() && cover == cover_mask)
  1599. {
  1600. pixel_type v;
  1601. v.set(c);
  1602. do
  1603. {
  1604. *p = v;
  1605. p = p->next();
  1606. }
  1607. while (--len);
  1608. }
  1609. else
  1610. {
  1611. if (cover == cover_mask)
  1612. {
  1613. do
  1614. {
  1615. blend_pix(p, c);
  1616. p = p->next();
  1617. }
  1618. while (--len);
  1619. }
  1620. else
  1621. {
  1622. do
  1623. {
  1624. blend_pix(p, c, cover);
  1625. p = p->next();
  1626. }
  1627. while (--len);
  1628. }
  1629. }
  1630. }
  1631. }
  1632. //--------------------------------------------------------------------
  1633. void blend_vline(int x, int y,
  1634. unsigned len,
  1635. const color_type& c,
  1636. int8u cover)
  1637. {
  1638. if (!c.is_transparent())
  1639. {
  1640. if (c.is_opaque() && cover == cover_mask)
  1641. {
  1642. pixel_type v;
  1643. v.set(c);
  1644. do
  1645. {
  1646. *pix_value_ptr(x, y++, 1) = v;
  1647. }
  1648. while (--len);
  1649. }
  1650. else
  1651. {
  1652. if (cover == cover_mask)
  1653. {
  1654. do
  1655. {
  1656. blend_pix(pix_value_ptr(x, y++, 1), c, c.a);
  1657. }
  1658. while (--len);
  1659. }
  1660. else
  1661. {
  1662. do
  1663. {
  1664. blend_pix(pix_value_ptr(x, y++, 1), c, cover);
  1665. }
  1666. while (--len);
  1667. }
  1668. }
  1669. }
  1670. }
  1671. //--------------------------------------------------------------------
  1672. void blend_solid_hspan(int x, int y,
  1673. unsigned len,
  1674. const color_type& c,
  1675. const int8u* covers)
  1676. {
  1677. if (!c.is_transparent())
  1678. {
  1679. pixel_type* p = pix_value_ptr(x, y, len);
  1680. do
  1681. {
  1682. if (c.is_opaque() && *covers == cover_mask)
  1683. {
  1684. p->set(c);
  1685. }
  1686. else
  1687. {
  1688. blend_pix(p, c, *covers);
  1689. }
  1690. p = p->next();
  1691. ++covers;
  1692. }
  1693. while (--len);
  1694. }
  1695. }
  1696. //--------------------------------------------------------------------
  1697. void blend_solid_vspan(int x, int y,
  1698. unsigned len,
  1699. const color_type& c,
  1700. const int8u* covers)
  1701. {
  1702. if (!c.is_transparent())
  1703. {
  1704. do
  1705. {
  1706. pixel_type* p = pix_value_ptr(x, y++, 1);
  1707. if (c.is_opaque() && *covers == cover_mask)
  1708. {
  1709. p->set(c);
  1710. }
  1711. else
  1712. {
  1713. blend_pix(p, c, *covers);
  1714. }
  1715. ++covers;
  1716. }
  1717. while (--len);
  1718. }
  1719. }
  1720. //--------------------------------------------------------------------
  1721. void copy_color_hspan(int x, int y,
  1722. unsigned len,
  1723. const color_type* colors)
  1724. {
  1725. pixel_type* p = pix_value_ptr(x, y, len);
  1726. do
  1727. {
  1728. p->set(*colors++);
  1729. p = p->next();
  1730. }
  1731. while (--len);
  1732. }
  1733. //--------------------------------------------------------------------
  1734. void copy_color_vspan(int x, int y,
  1735. unsigned len,
  1736. const color_type* colors)
  1737. {
  1738. do
  1739. {
  1740. pix_value_ptr(x, y++, 1)->set(*colors++);
  1741. }
  1742. while (--len);
  1743. }
  1744. //--------------------------------------------------------------------
  1745. void blend_color_hspan(int x, int y,
  1746. unsigned len,
  1747. const color_type* colors,
  1748. const int8u* covers,
  1749. int8u cover)
  1750. {
  1751. pixel_type* p = pix_value_ptr(x, y, len);
  1752. if (covers)
  1753. {
  1754. do
  1755. {
  1756. copy_or_blend_pix(p, *colors++, *covers++);
  1757. p = p->next();
  1758. }
  1759. while (--len);
  1760. }
  1761. else
  1762. {
  1763. if (cover == cover_mask)
  1764. {
  1765. do
  1766. {
  1767. copy_or_blend_pix(p, *colors++);
  1768. p = p->next();
  1769. }
  1770. while (--len);
  1771. }
  1772. else
  1773. {
  1774. do
  1775. {
  1776. copy_or_blend_pix(p, *colors++, cover);
  1777. p = p->next();
  1778. }
  1779. while (--len);
  1780. }
  1781. }
  1782. }
  1783. //--------------------------------------------------------------------
  1784. void blend_color_vspan(int x, int y,
  1785. unsigned len,
  1786. const color_type* colors,
  1787. const int8u* covers,
  1788. int8u cover)
  1789. {
  1790. if (covers)
  1791. {
  1792. do
  1793. {
  1794. copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
  1795. }
  1796. while (--len);
  1797. }
  1798. else
  1799. {
  1800. if (cover == cover_mask)
  1801. {
  1802. do
  1803. {
  1804. copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
  1805. }
  1806. while (--len);
  1807. }
  1808. else
  1809. {
  1810. do
  1811. {
  1812. copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
  1813. }
  1814. while (--len);
  1815. }
  1816. }
  1817. }
  1818. //--------------------------------------------------------------------
  1819. template<class Function> void for_each_pixel(Function f)
  1820. {
  1821. for (unsigned y = 0; y < height(); ++y)
  1822. {
  1823. row_data r = m_rbuf->row(y);
  1824. if (r.ptr)
  1825. {
  1826. unsigned len = r.x2 - r.x1 + 1;
  1827. pixel_type* p = pix_value_ptr(r.x1, y, len);
  1828. do
  1829. {
  1830. f(p->c);
  1831. p = p->next();
  1832. }
  1833. while (--len);
  1834. }
  1835. }
  1836. }
  1837. //--------------------------------------------------------------------
  1838. void premultiply()
  1839. {
  1840. for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply);
  1841. }
  1842. //--------------------------------------------------------------------
  1843. void demultiply()
  1844. {
  1845. for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply);
  1846. }
  1847. //--------------------------------------------------------------------
  1848. template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
  1849. {
  1850. for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g));
  1851. }
  1852. //--------------------------------------------------------------------
  1853. template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
  1854. {
  1855. for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g));
  1856. }
  1857. //--------------------------------------------------------------------
  1858. template<class RenBuf2> void copy_from(const RenBuf2& from,
  1859. int xdst, int ydst,
  1860. int xsrc, int ysrc,
  1861. unsigned len)
  1862. {
  1863. if (const int8u* p = from.row_ptr(ysrc))
  1864. {
  1865. memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
  1866. p + xsrc * pix_width,
  1867. len * pix_width);
  1868. }
  1869. }
  1870. //--------------------------------------------------------------------
  1871. // Blend from another RGBA surface.
  1872. template<class SrcPixelFormatRenderer>
  1873. void blend_from(const SrcPixelFormatRenderer& from,
  1874. int xdst, int ydst,
  1875. int xsrc, int ysrc,
  1876. unsigned len,
  1877. int8u cover)
  1878. {
  1879. typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
  1880. if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
  1881. {
  1882. pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
  1883. int srcinc = 1;
  1884. int dstinc = 1;
  1885. if (xdst > xsrc)
  1886. {
  1887. psrc = psrc->advance(len - 1);
  1888. pdst = pdst->advance(len - 1);
  1889. srcinc = -1;
  1890. dstinc = -1;
  1891. }
  1892. if (cover == cover_mask)
  1893. {
  1894. do
  1895. {
  1896. copy_or_blend_pix(pdst, psrc->get());
  1897. psrc = psrc->advance(srcinc);
  1898. pdst = pdst->advance(dstinc);
  1899. }
  1900. while (--len);
  1901. }
  1902. else
  1903. {
  1904. do
  1905. {
  1906. copy_or_blend_pix(pdst, psrc->get(), cover);
  1907. psrc = psrc->advance(srcinc);
  1908. pdst = pdst->advance(dstinc);
  1909. }
  1910. while (--len);
  1911. }
  1912. }
  1913. }
  1914. //--------------------------------------------------------------------
  1915. // Combine single color with grayscale surface and blend.
  1916. template<class SrcPixelFormatRenderer>
  1917. void blend_from_color(const SrcPixelFormatRenderer& from,
  1918. const color_type& color,
  1919. int xdst, int ydst,
  1920. int xsrc, int ysrc,
  1921. unsigned len,
  1922. int8u cover)
  1923. {
  1924. typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
  1925. typedef typename SrcPixelFormatRenderer::color_type src_color_type;
  1926. if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
  1927. {
  1928. pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
  1929. do
  1930. {
  1931. copy_or_blend_pix(pdst, color,
  1932. src_color_type::scale_cover(cover, psrc->c[0]));
  1933. psrc = psrc->next();
  1934. pdst = pdst->next();
  1935. }
  1936. while (--len);
  1937. }
  1938. }
  1939. //--------------------------------------------------------------------
  1940. // Blend from color table, using grayscale surface as indexes into table.
  1941. // Obviously, this only works for integer value types.
  1942. template<class SrcPixelFormatRenderer>
  1943. void blend_from_lut(const SrcPixelFormatRenderer& from,
  1944. const color_type* color_lut,
  1945. int xdst, int ydst,
  1946. int xsrc, int ysrc,
  1947. unsigned len,
  1948. int8u cover)
  1949. {
  1950. typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
  1951. if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
  1952. {
  1953. pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
  1954. if (cover == cover_mask)
  1955. {
  1956. do
  1957. {
  1958. copy_or_blend_pix(pdst, color_lut[psrc->c[0]]);
  1959. psrc = psrc->next();
  1960. pdst = pdst->next();
  1961. }
  1962. while (--len);
  1963. }
  1964. else
  1965. {
  1966. do
  1967. {
  1968. copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
  1969. psrc = psrc->next();
  1970. pdst = pdst->next();
  1971. }
  1972. while (--len);
  1973. }
  1974. }
  1975. }
  1976. private:
  1977. rbuf_type* m_rbuf;
  1978. Blender m_blender;
  1979. };
  1980. //================================================pixfmt_custom_blend_rgba
  1981. template<class Blender, class RenBuf> class pixfmt_custom_blend_rgba
  1982. {
  1983. public:
  1984. typedef pixfmt_rgba_tag pixfmt_category;
  1985. typedef RenBuf rbuf_type;
  1986. typedef typename rbuf_type::row_data row_data;
  1987. typedef Blender blender_type;
  1988. typedef typename blender_type::color_type color_type;
  1989. typedef typename blender_type::order_type order_type;
  1990. typedef typename color_type::value_type value_type;
  1991. typedef typename color_type::calc_type calc_type;
  1992. enum
  1993. {
  1994. pix_step = 4,
  1995. pix_width = sizeof(value_type) * pix_step,
  1996. };
  1997. struct pixel_type
  1998. {
  1999. value_type c[pix_step];
  2000. void set(value_type r, value_type g, value_type b, value_type a)
  2001. {
  2002. c[order_type::R] = r;
  2003. c[order_type::G] = g;
  2004. c[order_type::B] = b;
  2005. c[order_type::A] = a;
  2006. }
  2007. void set(const color_type& color)
  2008. {
  2009. set(color.r, color.g, color.b, color.a);
  2010. }
  2011. void get(value_type& r, value_type& g, value_type& b, value_type& a) const
  2012. {
  2013. r = c[order_type::R];
  2014. g = c[order_type::G];
  2015. b = c[order_type::B];
  2016. a = c[order_type::A];
  2017. }
  2018. color_type get() const
  2019. {
  2020. return color_type(
  2021. c[order_type::R],
  2022. c[order_type::G],
  2023. c[order_type::B],
  2024. c[order_type::A]);
  2025. }
  2026. pixel_type* next()
  2027. {
  2028. return this + 1;
  2029. }
  2030. const pixel_type* next() const
  2031. {
  2032. return this + 1;
  2033. }
  2034. pixel_type* advance(int n)
  2035. {
  2036. return this + n;
  2037. }
  2038. const pixel_type* advance(int n) const
  2039. {
  2040. return this + n;
  2041. }
  2042. };
  2043. private:
  2044. //--------------------------------------------------------------------
  2045. AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full)
  2046. {
  2047. m_blender.blend_pix(m_comp_op, p->c, c.r, c.g, c.b, c.a, cover);
  2048. }
  2049. //--------------------------------------------------------------------
  2050. AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full)
  2051. {
  2052. if (!c.is_transparent())
  2053. {
  2054. if (c.is_opaque() && cover == cover_mask)
  2055. {
  2056. p->set(c.r, c.g, c.b, c.a);
  2057. }
  2058. else
  2059. {
  2060. blend_pix(p, c, cover);
  2061. }
  2062. }
  2063. }
  2064. public:
  2065. //--------------------------------------------------------------------
  2066. pixfmt_custom_blend_rgba() : m_rbuf(0), m_comp_op(3) {}
  2067. explicit pixfmt_custom_blend_rgba(rbuf_type& rb, unsigned comp_op=3) :
  2068. m_rbuf(&rb),
  2069. m_comp_op(comp_op)
  2070. {}
  2071. void attach(rbuf_type& rb) { m_rbuf = &rb; }
  2072. //--------------------------------------------------------------------
  2073. template<class PixFmt>
  2074. bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
  2075. {
  2076. rect_i r(x1, y1, x2, y2);
  2077. if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
  2078. {
  2079. int stride = pixf.stride();
  2080. m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
  2081. (r.x2 - r.x1) + 1,
  2082. (r.y2 - r.y1) + 1,
  2083. stride);
  2084. return true;
  2085. }
  2086. return false;
  2087. }
  2088. //--------------------------------------------------------------------
  2089. void comp_op(unsigned op) { m_comp_op = op; }
  2090. unsigned comp_op() const { return m_comp_op; }
  2091. //--------------------------------------------------------------------
  2092. AGG_INLINE unsigned width() const { return m_rbuf->width(); }
  2093. AGG_INLINE unsigned height() const { return m_rbuf->height(); }
  2094. AGG_INLINE int stride() const { return m_rbuf->stride(); }
  2095. //--------------------------------------------------------------------
  2096. AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
  2097. AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
  2098. AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
  2099. //--------------------------------------------------------------------
  2100. AGG_INLINE int8u* pix_ptr(int x, int y)
  2101. {
  2102. return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step);
  2103. }
  2104. AGG_INLINE const int8u* pix_ptr(int x, int y) const
  2105. {
  2106. return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step);
  2107. }
  2108. // Return pointer to pixel value, forcing row to be allocated.
  2109. AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
  2110. {
  2111. return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step));
  2112. }
  2113. // Return pointer to pixel value, or null if row not allocated.
  2114. AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
  2115. {
  2116. int8u* p = m_rbuf->row_ptr(y);
  2117. return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0;
  2118. }
  2119. // Get pixel pointer from raw buffer pointer.
  2120. AGG_INLINE static pixel_type* pix_value_ptr(void* p)
  2121. {
  2122. return (pixel_type*)p;
  2123. }
  2124. // Get pixel pointer from raw buffer pointer.
  2125. AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
  2126. {
  2127. return (const pixel_type*)p;
  2128. }
  2129. //--------------------------------------------------------------------
  2130. AGG_INLINE static void make_pix(int8u* p, const color_type& c)
  2131. {
  2132. ((pixel_type*)p)->set(c);
  2133. }
  2134. //--------------------------------------------------------------------
  2135. AGG_INLINE color_type pixel(int x, int y) const
  2136. {
  2137. if (const pixel_type* p = pix_value_ptr(x, y))
  2138. {
  2139. return p->get();
  2140. }
  2141. return color_type::no_color();
  2142. }
  2143. //--------------------------------------------------------------------
  2144. AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
  2145. {
  2146. make_pix(pix_value_ptr(x, y, 1), c);
  2147. }
  2148. //--------------------------------------------------------------------
  2149. AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
  2150. {
  2151. blend_pix(pix_value_ptr(x, y, 1), c, cover);
  2152. }
  2153. //--------------------------------------------------------------------
  2154. AGG_INLINE void copy_hline(int x, int y,
  2155. unsigned len,
  2156. const color_type& c)
  2157. {
  2158. pixel_type v;
  2159. v.set(c);
  2160. pixel_type* p = pix_value_ptr(x, y, len);
  2161. do
  2162. {
  2163. *p = v;
  2164. p = p->next();
  2165. }
  2166. while (--len);
  2167. }
  2168. //--------------------------------------------------------------------
  2169. AGG_INLINE void copy_vline(int x, int y,
  2170. unsigned len,
  2171. const color_type& c)
  2172. {
  2173. pixel_type v;
  2174. v.set(c);
  2175. do
  2176. {
  2177. *pix_value_ptr(x, y++, 1) = v;
  2178. }
  2179. while (--len);
  2180. }
  2181. //--------------------------------------------------------------------
  2182. void blend_hline(int x, int y, unsigned len,
  2183. const color_type& c, int8u cover)
  2184. {
  2185. pixel_type* p = pix_value_ptr(x, y, len);
  2186. do
  2187. {
  2188. blend_pix(p, c, cover);
  2189. p = p->next();
  2190. }
  2191. while (--len);
  2192. }
  2193. //--------------------------------------------------------------------
  2194. void blend_vline(int x, int y, unsigned len,
  2195. const color_type& c, int8u cover)
  2196. {
  2197. do
  2198. {
  2199. blend_pix(pix_value_ptr(x, y++, 1), c, cover);
  2200. }
  2201. while (--len);
  2202. }
  2203. //--------------------------------------------------------------------
  2204. void blend_solid_hspan(int x, int y, unsigned len,
  2205. const color_type& c, const int8u* covers)
  2206. {
  2207. pixel_type* p = pix_value_ptr(x, y, len);
  2208. do
  2209. {
  2210. blend_pix(p, c, *covers++);
  2211. p = p->next();
  2212. }
  2213. while (--len);
  2214. }
  2215. //--------------------------------------------------------------------
  2216. void blend_solid_vspan(int x, int y, unsigned len,
  2217. const color_type& c, const int8u* covers)
  2218. {
  2219. do
  2220. {
  2221. blend_pix(pix_value_ptr(x, y++, 1), c, *covers++);
  2222. }
  2223. while (--len);
  2224. }
  2225. //--------------------------------------------------------------------
  2226. void copy_color_hspan(int x, int y,
  2227. unsigned len,
  2228. const color_type* colors)
  2229. {
  2230. pixel_type* p = pix_value_ptr(x, y, len);
  2231. do
  2232. {
  2233. p->set(*colors++);
  2234. p = p->next();
  2235. }
  2236. while (--len);
  2237. }
  2238. //--------------------------------------------------------------------
  2239. void copy_color_vspan(int x, int y,
  2240. unsigned len,
  2241. const color_type* colors)
  2242. {
  2243. do
  2244. {
  2245. pix_value_ptr(x, y++, 1)->set(*colors++);
  2246. }
  2247. while (--len);
  2248. }
  2249. //--------------------------------------------------------------------
  2250. void blend_color_hspan(int x, int y, unsigned len,
  2251. const color_type* colors,
  2252. const int8u* covers,
  2253. int8u cover)
  2254. {
  2255. pixel_type* p = pix_value_ptr(x, y, len);
  2256. do
  2257. {
  2258. blend_pix(p, *colors++, covers ? *covers++ : cover);
  2259. p = p->next();
  2260. }
  2261. while (--len);
  2262. }
  2263. //--------------------------------------------------------------------
  2264. void blend_color_vspan(int x, int y, unsigned len,
  2265. const color_type* colors,
  2266. const int8u* covers,
  2267. int8u cover)
  2268. {
  2269. do
  2270. {
  2271. blend_pix(pix_value_ptr(x, y++, 1), *colors++, covers ? *covers++ : cover);
  2272. }
  2273. while (--len);
  2274. }
  2275. //--------------------------------------------------------------------
  2276. template<class Function> void for_each_pixel(Function f)
  2277. {
  2278. unsigned y;
  2279. for (y = 0; y < height(); ++y)
  2280. {
  2281. row_data r = m_rbuf->row(y);
  2282. if (r.ptr)
  2283. {
  2284. unsigned len = r.x2 - r.x1 + 1;
  2285. pixel_type* p = pix_value_ptr(r.x1, y, len);
  2286. do
  2287. {
  2288. f(p->c);
  2289. p = p->next();
  2290. }
  2291. while (--len);
  2292. }
  2293. }
  2294. }
  2295. //--------------------------------------------------------------------
  2296. void premultiply()
  2297. {
  2298. for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply);
  2299. }
  2300. //--------------------------------------------------------------------
  2301. void demultiply()
  2302. {
  2303. for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply);
  2304. }
  2305. //--------------------------------------------------------------------
  2306. template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
  2307. {
  2308. for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g));
  2309. }
  2310. //--------------------------------------------------------------------
  2311. template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
  2312. {
  2313. for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g));
  2314. }
  2315. //--------------------------------------------------------------------
  2316. template<class RenBuf2> void copy_from(const RenBuf2& from,
  2317. int xdst, int ydst,
  2318. int xsrc, int ysrc,
  2319. unsigned len)
  2320. {
  2321. if (const int8u* p = from.row_ptr(ysrc))
  2322. {
  2323. memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
  2324. p + xsrc * pix_width,
  2325. len * pix_width);
  2326. }
  2327. }
  2328. //--------------------------------------------------------------------
  2329. // Blend from another RGBA surface.
  2330. template<class SrcPixelFormatRenderer>
  2331. void blend_from(const SrcPixelFormatRenderer& from,
  2332. int xdst, int ydst,
  2333. int xsrc, int ysrc,
  2334. unsigned len,
  2335. int8u cover)
  2336. {
  2337. typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
  2338. if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
  2339. {
  2340. pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
  2341. int srcinc = 1;
  2342. int dstinc = 1;
  2343. if (xdst > xsrc)
  2344. {
  2345. psrc = psrc->advance(len - 1);
  2346. pdst = pdst->advance(len - 1);
  2347. srcinc = -1;
  2348. dstinc = -1;
  2349. }
  2350. do
  2351. {
  2352. blend_pix(pdst, psrc->get(), cover);
  2353. psrc = psrc->advance(srcinc);
  2354. pdst = pdst->advance(dstinc);
  2355. }
  2356. while (--len);
  2357. }
  2358. }
  2359. //--------------------------------------------------------------------
  2360. // Blend from single color, using grayscale surface as alpha channel.
  2361. template<class SrcPixelFormatRenderer>
  2362. void blend_from_color(const SrcPixelFormatRenderer& from,
  2363. const color_type& color,
  2364. int xdst, int ydst,
  2365. int xsrc, int ysrc,
  2366. unsigned len,
  2367. int8u cover)
  2368. {
  2369. typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
  2370. typedef typename SrcPixelFormatRenderer::color_type src_color_type;
  2371. if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
  2372. {
  2373. pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
  2374. do
  2375. {
  2376. blend_pix(pdst, color,
  2377. src_color_type::scale_cover(cover, psrc->c[0]));
  2378. psrc = psrc->next();
  2379. pdst = pdst->next();
  2380. }
  2381. while (--len);
  2382. }
  2383. }
  2384. //--------------------------------------------------------------------
  2385. // Blend from color table, using grayscale surface as indexes into table.
  2386. // Obviously, this only works for integer value types.
  2387. template<class SrcPixelFormatRenderer>
  2388. void blend_from_lut(const SrcPixelFormatRenderer& from,
  2389. const color_type* color_lut,
  2390. int xdst, int ydst,
  2391. int xsrc, int ysrc,
  2392. unsigned len,
  2393. int8u cover)
  2394. {
  2395. typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
  2396. if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
  2397. {
  2398. pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
  2399. do
  2400. {
  2401. blend_pix(pdst, color_lut[psrc->c[0]], cover);
  2402. psrc = psrc->next();
  2403. pdst = pdst->next();
  2404. }
  2405. while (--len);
  2406. }
  2407. }
  2408. private:
  2409. rbuf_type* m_rbuf;
  2410. Blender m_blender;
  2411. unsigned m_comp_op;
  2412. };
  2413. //-----------------------------------------------------------------------
  2414. typedef blender_rgba<rgba8, order_rgba> blender_rgba32;
  2415. typedef blender_rgba<rgba8, order_argb> blender_argb32;
  2416. typedef blender_rgba<rgba8, order_abgr> blender_abgr32;
  2417. typedef blender_rgba<rgba8, order_bgra> blender_bgra32;
  2418. typedef blender_rgba<srgba8, order_rgba> blender_srgba32;
  2419. typedef blender_rgba<srgba8, order_argb> blender_sargb32;
  2420. typedef blender_rgba<srgba8, order_abgr> blender_sabgr32;
  2421. typedef blender_rgba<srgba8, order_bgra> blender_sbgra32;
  2422. typedef blender_rgba_pre<rgba8, order_rgba> blender_rgba32_pre;
  2423. typedef blender_rgba_pre<rgba8, order_argb> blender_argb32_pre;
  2424. typedef blender_rgba_pre<rgba8, order_abgr> blender_abgr32_pre;
  2425. typedef blender_rgba_pre<rgba8, order_bgra> blender_bgra32_pre;
  2426. typedef blender_rgba_pre<srgba8, order_rgba> blender_srgba32_pre;
  2427. typedef blender_rgba_pre<srgba8, order_argb> blender_sargb32_pre;
  2428. typedef blender_rgba_pre<srgba8, order_abgr> blender_sabgr32_pre;
  2429. typedef blender_rgba_pre<srgba8, order_bgra> blender_sbgra32_pre;
  2430. typedef blender_rgba_plain<rgba8, order_rgba> blender_rgba32_plain;
  2431. typedef blender_rgba_plain<rgba8, order_argb> blender_argb32_plain;
  2432. typedef blender_rgba_plain<rgba8, order_abgr> blender_abgr32_plain;
  2433. typedef blender_rgba_plain<rgba8, order_bgra> blender_bgra32_plain;
  2434. typedef blender_rgba_plain<srgba8, order_rgba> blender_srgba32_plain;
  2435. typedef blender_rgba_plain<srgba8, order_argb> blender_sargb32_plain;
  2436. typedef blender_rgba_plain<srgba8, order_abgr> blender_sabgr32_plain;
  2437. typedef blender_rgba_plain<srgba8, order_bgra> blender_sbgra32_plain;
  2438. typedef blender_rgba<rgba16, order_rgba> blender_rgba64;
  2439. typedef blender_rgba<rgba16, order_argb> blender_argb64;
  2440. typedef blender_rgba<rgba16, order_abgr> blender_abgr64;
  2441. typedef blender_rgba<rgba16, order_bgra> blender_bgra64;
  2442. typedef blender_rgba_pre<rgba16, order_rgba> blender_rgba64_pre;
  2443. typedef blender_rgba_pre<rgba16, order_argb> blender_argb64_pre;
  2444. typedef blender_rgba_pre<rgba16, order_abgr> blender_abgr64_pre;
  2445. typedef blender_rgba_pre<rgba16, order_bgra> blender_bgra64_pre;
  2446. typedef blender_rgba_plain<rgba16, order_rgba> blender_rgba64_plain;
  2447. typedef blender_rgba_plain<rgba16, order_argb> blender_argb64_plain;
  2448. typedef blender_rgba_plain<rgba16, order_abgr> blender_abgr64_plain;
  2449. typedef blender_rgba_plain<rgba16, order_bgra> blender_bgra64_plain;
  2450. typedef blender_rgba<rgba32, order_rgba> blender_rgba128;
  2451. typedef blender_rgba<rgba32, order_argb> blender_argb128;
  2452. typedef blender_rgba<rgba32, order_abgr> blender_abgr128;
  2453. typedef blender_rgba<rgba32, order_bgra> blender_bgra128;
  2454. typedef blender_rgba_pre<rgba32, order_rgba> blender_rgba128_pre;
  2455. typedef blender_rgba_pre<rgba32, order_argb> blender_argb128_pre;
  2456. typedef blender_rgba_pre<rgba32, order_abgr> blender_abgr128_pre;
  2457. typedef blender_rgba_pre<rgba32, order_bgra> blender_bgra128_pre;
  2458. typedef blender_rgba_plain<rgba32, order_rgba> blender_rgba128_plain;
  2459. typedef blender_rgba_plain<rgba32, order_argb> blender_argb128_plain;
  2460. typedef blender_rgba_plain<rgba32, order_abgr> blender_abgr128_plain;
  2461. typedef blender_rgba_plain<rgba32, order_bgra> blender_bgra128_plain;
  2462. //-----------------------------------------------------------------------
  2463. typedef pixfmt_alpha_blend_rgba<blender_rgba32, rendering_buffer> pixfmt_rgba32;
  2464. typedef pixfmt_alpha_blend_rgba<blender_argb32, rendering_buffer> pixfmt_argb32;
  2465. typedef pixfmt_alpha_blend_rgba<blender_abgr32, rendering_buffer> pixfmt_abgr32;
  2466. typedef pixfmt_alpha_blend_rgba<blender_bgra32, rendering_buffer> pixfmt_bgra32;
  2467. typedef pixfmt_alpha_blend_rgba<blender_srgba32, rendering_buffer> pixfmt_srgba32;
  2468. typedef pixfmt_alpha_blend_rgba<blender_sargb32, rendering_buffer> pixfmt_sargb32;
  2469. typedef pixfmt_alpha_blend_rgba<blender_sabgr32, rendering_buffer> pixfmt_sabgr32;
  2470. typedef pixfmt_alpha_blend_rgba<blender_sbgra32, rendering_buffer> pixfmt_sbgra32;
  2471. typedef pixfmt_alpha_blend_rgba<blender_rgba32_pre, rendering_buffer> pixfmt_rgba32_pre;
  2472. typedef pixfmt_alpha_blend_rgba<blender_argb32_pre, rendering_buffer> pixfmt_argb32_pre;
  2473. typedef pixfmt_alpha_blend_rgba<blender_abgr32_pre, rendering_buffer> pixfmt_abgr32_pre;
  2474. typedef pixfmt_alpha_blend_rgba<blender_bgra32_pre, rendering_buffer> pixfmt_bgra32_pre;
  2475. typedef pixfmt_alpha_blend_rgba<blender_srgba32_pre, rendering_buffer> pixfmt_srgba32_pre;
  2476. typedef pixfmt_alpha_blend_rgba<blender_sargb32_pre, rendering_buffer> pixfmt_sargb32_pre;
  2477. typedef pixfmt_alpha_blend_rgba<blender_sabgr32_pre, rendering_buffer> pixfmt_sabgr32_pre;
  2478. typedef pixfmt_alpha_blend_rgba<blender_sbgra32_pre, rendering_buffer> pixfmt_sbgra32_pre;
  2479. typedef pixfmt_alpha_blend_rgba<blender_rgba32_plain, rendering_buffer> pixfmt_rgba32_plain;
  2480. typedef pixfmt_alpha_blend_rgba<blender_argb32_plain, rendering_buffer> pixfmt_argb32_plain;
  2481. typedef pixfmt_alpha_blend_rgba<blender_abgr32_plain, rendering_buffer> pixfmt_abgr32_plain;
  2482. typedef pixfmt_alpha_blend_rgba<blender_bgra32_plain, rendering_buffer> pixfmt_bgra32_plain;
  2483. typedef pixfmt_alpha_blend_rgba<blender_srgba32_plain, rendering_buffer> pixfmt_srgba32_plain;
  2484. typedef pixfmt_alpha_blend_rgba<blender_sargb32_plain, rendering_buffer> pixfmt_sargb32_plain;
  2485. typedef pixfmt_alpha_blend_rgba<blender_sabgr32_plain, rendering_buffer> pixfmt_sabgr32_plain;
  2486. typedef pixfmt_alpha_blend_rgba<blender_sbgra32_plain, rendering_buffer> pixfmt_sbgra32_plain;
  2487. typedef pixfmt_alpha_blend_rgba<blender_rgba64, rendering_buffer> pixfmt_rgba64;
  2488. typedef pixfmt_alpha_blend_rgba<blender_argb64, rendering_buffer> pixfmt_argb64;
  2489. typedef pixfmt_alpha_blend_rgba<blender_abgr64, rendering_buffer> pixfmt_abgr64;
  2490. typedef pixfmt_alpha_blend_rgba<blender_bgra64, rendering_buffer> pixfmt_bgra64;
  2491. typedef pixfmt_alpha_blend_rgba<blender_rgba64_pre, rendering_buffer> pixfmt_rgba64_pre;
  2492. typedef pixfmt_alpha_blend_rgba<blender_argb64_pre, rendering_buffer> pixfmt_argb64_pre;
  2493. typedef pixfmt_alpha_blend_rgba<blender_abgr64_pre, rendering_buffer> pixfmt_abgr64_pre;
  2494. typedef pixfmt_alpha_blend_rgba<blender_bgra64_pre, rendering_buffer> pixfmt_bgra64_pre;
  2495. typedef pixfmt_alpha_blend_rgba<blender_rgba64_plain, rendering_buffer> pixfmt_rgba64_plain;
  2496. typedef pixfmt_alpha_blend_rgba<blender_argb64_plain, rendering_buffer> pixfmt_argb64_plain;
  2497. typedef pixfmt_alpha_blend_rgba<blender_abgr64_plain, rendering_buffer> pixfmt_abgr64_plain;
  2498. typedef pixfmt_alpha_blend_rgba<blender_bgra64_plain, rendering_buffer> pixfmt_bgra64_plain;
  2499. typedef pixfmt_alpha_blend_rgba<blender_rgba128, rendering_buffer> pixfmt_rgba128;
  2500. typedef pixfmt_alpha_blend_rgba<blender_argb128, rendering_buffer> pixfmt_argb128;
  2501. typedef pixfmt_alpha_blend_rgba<blender_abgr128, rendering_buffer> pixfmt_abgr128;
  2502. typedef pixfmt_alpha_blend_rgba<blender_bgra128, rendering_buffer> pixfmt_bgra128;
  2503. typedef pixfmt_alpha_blend_rgba<blender_rgba128_pre, rendering_buffer> pixfmt_rgba128_pre;
  2504. typedef pixfmt_alpha_blend_rgba<blender_argb128_pre, rendering_buffer> pixfmt_argb128_pre;
  2505. typedef pixfmt_alpha_blend_rgba<blender_abgr128_pre, rendering_buffer> pixfmt_abgr128_pre;
  2506. typedef pixfmt_alpha_blend_rgba<blender_bgra128_pre, rendering_buffer> pixfmt_bgra128_pre;
  2507. typedef pixfmt_alpha_blend_rgba<blender_rgba128_plain, rendering_buffer> pixfmt_rgba128_plain;
  2508. typedef pixfmt_alpha_blend_rgba<blender_argb128_plain, rendering_buffer> pixfmt_argb128_plain;
  2509. typedef pixfmt_alpha_blend_rgba<blender_abgr128_plain, rendering_buffer> pixfmt_abgr128_plain;
  2510. typedef pixfmt_alpha_blend_rgba<blender_bgra128_plain, rendering_buffer> pixfmt_bgra128_plain;
  2511. }
  2512. #endif