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

/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

Large files files are truncated, but you can click here to view the full file

  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_t

Large files files are truncated, but you can click here to view the full file