PageRenderTime 54ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/bb_waze_code/src/agg/include/agg_pixfmt_rgba.h

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