1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
22 //----------------------------------------------------------------------------
24 #ifndef AGG_PIXFMT_RGB_PACKED_INCLUDED
25 #define AGG_PIXFMT_RGB_PACKED_INCLUDED
28 #include "agg_basics.h"
29 #include "agg_color_rgba.h"
30 #include "agg_rendering_buffer.h"
34 //=========================================================blender_rgb555
37 typedef rgba8 color_type
;
38 typedef color_type::value_type value_type
;
39 typedef color_type::calc_type calc_type
;
40 typedef int16u pixel_type
;
42 static AGG_INLINE
void blend_pix(pixel_type
* p
,
43 unsigned cr
, unsigned cg
, unsigned cb
,
48 calc_type r
= (rgb
>> 7) & 0xF8;
49 calc_type g
= (rgb
>> 2) & 0xF8;
50 calc_type b
= (rgb
<< 3) & 0xF8;
52 (((((cr
- r
) * alpha
+ (r
<< 8)) >> 1) & 0x7C00) |
53 ((((cg
- g
) * alpha
+ (g
<< 8)) >> 6) & 0x03E0) |
54 (((cb
- b
) * alpha
+ (b
<< 8)) >> 11) | 0x8000);
57 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
59 return (pixel_type
)(((r
& 0xF8) << 7) |
64 static AGG_INLINE color_type
make_color(pixel_type p
)
66 return color_type((p
>> 7) & 0xF8,
73 //=====================================================blender_rgb555_pre
74 struct blender_rgb555_pre
76 typedef rgba8 color_type
;
77 typedef color_type::value_type value_type
;
78 typedef color_type::calc_type calc_type
;
79 typedef int16u pixel_type
;
81 static AGG_INLINE
void blend_pix(pixel_type
* p
,
82 unsigned cr
, unsigned cg
, unsigned cb
,
86 alpha
= color_type::base_mask
- alpha
;
88 calc_type r
= (rgb
>> 7) & 0xF8;
89 calc_type g
= (rgb
>> 2) & 0xF8;
90 calc_type b
= (rgb
<< 3) & 0xF8;
92 ((((r
* alpha
+ cr
* cover
) >> 1) & 0x7C00) |
93 (((g
* alpha
+ cg
* cover
) >> 6) & 0x03E0) |
94 ((b
* alpha
+ cb
* cover
) >> 11) | 0x8000);
97 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
99 return (pixel_type
)(((r
& 0xF8) << 7) |
104 static AGG_INLINE color_type
make_color(pixel_type p
)
106 return color_type((p
>> 7) & 0xF8,
115 //=====================================================blender_rgb555_gamma
116 template<class Gamma
> class blender_rgb555_gamma
119 typedef rgba8 color_type
;
120 typedef color_type::value_type value_type
;
121 typedef color_type::calc_type calc_type
;
122 typedef int16u pixel_type
;
123 typedef Gamma gamma_type
;
125 blender_rgb555_gamma() : m_gamma(0) {}
126 void gamma(const gamma_type
& g
) { m_gamma
= &g
; }
128 AGG_INLINE
void blend_pix(pixel_type
* p
,
129 unsigned cr
, unsigned cg
, unsigned cb
,
134 calc_type r
= m_gamma
->dir((rgb
>> 7) & 0xF8);
135 calc_type g
= m_gamma
->dir((rgb
>> 2) & 0xF8);
136 calc_type b
= m_gamma
->dir((rgb
<< 3) & 0xF8);
138 (((m_gamma
->inv(((m_gamma
->dir(cr
) - r
) * alpha
+ (r
<< 8)) >> 8) << 7) & 0x7C00) |
139 ((m_gamma
->inv(((m_gamma
->dir(cg
) - g
) * alpha
+ (g
<< 8)) >> 8) << 2) & 0x03E0) |
140 (m_gamma
->inv(((m_gamma
->dir(cb
) - b
) * alpha
+ (b
<< 8)) >> 8) >> 3) | 0x8000);
143 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
145 return (pixel_type
)(((r
& 0xF8) << 7) |
150 static AGG_INLINE color_type
make_color(pixel_type p
)
152 return color_type((p
>> 7) & 0xF8,
158 const Gamma
* m_gamma
;
165 //=========================================================blender_rgb565
166 struct blender_rgb565
168 typedef rgba8 color_type
;
169 typedef color_type::value_type value_type
;
170 typedef color_type::calc_type calc_type
;
171 typedef int16u pixel_type
;
173 static AGG_INLINE
void blend_pix(pixel_type
* p
,
174 unsigned cr
, unsigned cg
, unsigned cb
,
179 calc_type r
= (rgb
>> 8) & 0xF8;
180 calc_type g
= (rgb
>> 3) & 0xFC;
181 calc_type b
= (rgb
<< 3) & 0xF8;
183 (((((cr
- r
) * alpha
+ (r
<< 8)) ) & 0xF800) |
184 ((((cg
- g
) * alpha
+ (g
<< 8)) >> 5) & 0x07E0) |
185 (((cb
- b
) * alpha
+ (b
<< 8)) >> 11));
188 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
190 return (pixel_type
)(((r
& 0xF8) << 8) | ((g
& 0xFC) << 3) | (b
>> 3));
193 static AGG_INLINE color_type
make_color(pixel_type p
)
195 return color_type((p
>> 8) & 0xF8,
203 //=====================================================blender_rgb565_pre
204 struct blender_rgb565_pre
206 typedef rgba8 color_type
;
207 typedef color_type::value_type value_type
;
208 typedef color_type::calc_type calc_type
;
209 typedef int16u pixel_type
;
211 static AGG_INLINE
void blend_pix(pixel_type
* p
,
212 unsigned cr
, unsigned cg
, unsigned cb
,
216 alpha
= color_type::base_mask
- alpha
;
218 calc_type r
= (rgb
>> 8) & 0xF8;
219 calc_type g
= (rgb
>> 3) & 0xFC;
220 calc_type b
= (rgb
<< 3) & 0xF8;
222 ((((r
* alpha
+ cr
* cover
) ) & 0xF800) |
223 (((g
* alpha
+ cg
* cover
) >> 5 ) & 0x07E0) |
224 ((b
* alpha
+ cb
* cover
) >> 11));
227 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
229 return (pixel_type
)(((r
& 0xF8) << 8) | ((g
& 0xFC) << 3) | (b
>> 3));
232 static AGG_INLINE color_type
make_color(pixel_type p
)
234 return color_type((p
>> 8) & 0xF8,
242 //=====================================================blender_rgb565_gamma
243 template<class Gamma
> class blender_rgb565_gamma
246 typedef rgba8 color_type
;
247 typedef color_type::value_type value_type
;
248 typedef color_type::calc_type calc_type
;
249 typedef int16u pixel_type
;
250 typedef Gamma gamma_type
;
252 blender_rgb565_gamma() : m_gamma(0) {}
253 void gamma(const gamma_type
& g
) { m_gamma
= &g
; }
255 AGG_INLINE
void blend_pix(pixel_type
* p
,
256 unsigned cr
, unsigned cg
, unsigned cb
,
261 calc_type r
= m_gamma
->dir((rgb
>> 8) & 0xF8);
262 calc_type g
= m_gamma
->dir((rgb
>> 3) & 0xFC);
263 calc_type b
= m_gamma
->dir((rgb
<< 3) & 0xF8);
265 (((m_gamma
->inv(((m_gamma
->dir(cr
) - r
) * alpha
+ (r
<< 8)) >> 8) << 8) & 0xF800) |
266 ((m_gamma
->inv(((m_gamma
->dir(cg
) - g
) * alpha
+ (g
<< 8)) >> 8) << 3) & 0x07E0) |
267 (m_gamma
->inv(((m_gamma
->dir(cb
) - b
) * alpha
+ (b
<< 8)) >> 8) >> 3));
270 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
272 return (pixel_type
)(((r
& 0xF8) << 8) | ((g
& 0xFC) << 3) | (b
>> 3));
275 static AGG_INLINE color_type
make_color(pixel_type p
)
277 return color_type((p
>> 8) & 0xF8,
283 const Gamma
* m_gamma
;
288 //=====================================================blender_rgbAAA
289 struct blender_rgbAAA
291 typedef rgba16 color_type
;
292 typedef color_type::value_type value_type
;
293 typedef color_type::calc_type calc_type
;
294 typedef int32u pixel_type
;
296 static AGG_INLINE
void blend_pix(pixel_type
* p
,
297 unsigned cr
, unsigned cg
, unsigned cb
,
302 calc_type r
= (rgb
>> 14) & 0xFFC0;
303 calc_type g
= (rgb
>> 4) & 0xFFC0;
304 calc_type b
= (rgb
<< 6) & 0xFFC0;
306 (((((cr
- r
) * alpha
+ (r
<< 16)) >> 2) & 0x3FF00000) |
307 ((((cg
- g
) * alpha
+ (g
<< 16)) >> 12) & 0x000FFC00) |
308 (((cb
- b
) * alpha
+ (b
<< 16)) >> 22) | 0xC0000000);
311 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
313 return (pixel_type
)(((r
& 0xFFC0) << 14) |
314 ((g
& 0xFFC0) << 4) |
315 (b
>> 6) | 0xC0000000);
318 static AGG_INLINE color_type
make_color(pixel_type p
)
320 return color_type((p
>> 14) & 0xFFC0,
328 //==================================================blender_rgbAAA_pre
329 struct blender_rgbAAA_pre
331 typedef rgba16 color_type
;
332 typedef color_type::value_type value_type
;
333 typedef color_type::calc_type calc_type
;
334 typedef int32u pixel_type
;
336 static AGG_INLINE
void blend_pix(pixel_type
* p
,
337 unsigned cr
, unsigned cg
, unsigned cb
,
341 alpha
= color_type::base_mask
- alpha
;
342 cover
= (cover
+ 1) << (color_type::base_shift
- 8);
344 calc_type r
= (rgb
>> 14) & 0xFFC0;
345 calc_type g
= (rgb
>> 4) & 0xFFC0;
346 calc_type b
= (rgb
<< 6) & 0xFFC0;
348 ((((r
* alpha
+ cr
* cover
) >> 2) & 0x3FF00000) |
349 (((g
* alpha
+ cg
* cover
) >> 12) & 0x000FFC00) |
350 ((b
* alpha
+ cb
* cover
) >> 22) | 0xC0000000);
353 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
355 return (pixel_type
)(((r
& 0xFFC0) << 14) |
356 ((g
& 0xFFC0) << 4) |
357 (b
>> 6) | 0xC0000000);
360 static AGG_INLINE color_type
make_color(pixel_type p
)
362 return color_type((p
>> 14) & 0xFFC0,
370 //=================================================blender_rgbAAA_gamma
371 template<class Gamma
> class blender_rgbAAA_gamma
374 typedef rgba16 color_type
;
375 typedef color_type::value_type value_type
;
376 typedef color_type::calc_type calc_type
;
377 typedef int32u pixel_type
;
378 typedef Gamma gamma_type
;
380 blender_rgbAAA_gamma() : m_gamma(0) {}
381 void gamma(const gamma_type
& g
) { m_gamma
= &g
; }
383 AGG_INLINE
void blend_pix(pixel_type
* p
,
384 unsigned cr
, unsigned cg
, unsigned cb
,
389 calc_type r
= m_gamma
->dir((rgb
>> 14) & 0xFFC0);
390 calc_type g
= m_gamma
->dir((rgb
>> 4) & 0xFFC0);
391 calc_type b
= m_gamma
->dir((rgb
<< 6) & 0xFFC0);
393 (((m_gamma
->inv(((m_gamma
->dir(cr
) - r
) * alpha
+ (r
<< 16)) >> 16) << 14) & 0x3FF00000) |
394 ((m_gamma
->inv(((m_gamma
->dir(cg
) - g
) * alpha
+ (g
<< 16)) >> 16) << 4 ) & 0x000FFC00) |
395 (m_gamma
->inv(((m_gamma
->dir(cb
) - b
) * alpha
+ (b
<< 16)) >> 16) >> 6 ) | 0xC0000000);
398 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
400 return (pixel_type
)(((r
& 0xFFC0) << 14) |
401 ((g
& 0xFFC0) << 4) |
402 (b
>> 6) | 0xC0000000);
405 static AGG_INLINE color_type
make_color(pixel_type p
)
407 return color_type((p
>> 14) & 0xFFC0,
412 const Gamma
* m_gamma
;
416 //=====================================================blender_bgrAAA
417 struct blender_bgrAAA
419 typedef rgba16 color_type
;
420 typedef color_type::value_type value_type
;
421 typedef color_type::calc_type calc_type
;
422 typedef int32u pixel_type
;
424 static AGG_INLINE
void blend_pix(pixel_type
* p
,
425 unsigned cr
, unsigned cg
, unsigned cb
,
430 calc_type b
= (bgr
>> 14) & 0xFFC0;
431 calc_type g
= (bgr
>> 4) & 0xFFC0;
432 calc_type r
= (bgr
<< 6) & 0xFFC0;
434 (((((cb
- b
) * alpha
+ (b
<< 16)) >> 2) & 0x3FF00000) |
435 ((((cg
- g
) * alpha
+ (g
<< 16)) >> 12) & 0x000FFC00) |
436 (((cr
- r
) * alpha
+ (r
<< 16)) >> 22) | 0xC0000000);
439 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
441 return (pixel_type
)(((b
& 0xFFC0) << 14) |
442 ((g
& 0xFFC0) << 4) |
443 (r
>> 6) | 0xC0000000);
446 static AGG_INLINE color_type
make_color(pixel_type p
)
448 return color_type((p
<< 6) & 0xFFC0,
456 //=================================================blender_bgrAAA_pre
457 struct blender_bgrAAA_pre
459 typedef rgba16 color_type
;
460 typedef color_type::value_type value_type
;
461 typedef color_type::calc_type calc_type
;
462 typedef int32u pixel_type
;
464 static AGG_INLINE
void blend_pix(pixel_type
* p
,
465 unsigned cr
, unsigned cg
, unsigned cb
,
469 alpha
= color_type::base_mask
- alpha
;
470 cover
= (cover
+ 1) << (color_type::base_shift
- 8);
472 calc_type b
= (bgr
>> 14) & 0xFFC0;
473 calc_type g
= (bgr
>> 4) & 0xFFC0;
474 calc_type r
= (bgr
<< 6) & 0xFFC0;
476 ((((b
* alpha
+ cb
* cover
) >> 2) & 0x3FF00000) |
477 (((g
* alpha
+ cg
* cover
) >> 12) & 0x000FFC00) |
478 ((r
* alpha
+ cr
* cover
) >> 22) | 0xC0000000);
481 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
483 return (pixel_type
)(((b
& 0xFFC0) << 14) |
484 ((g
& 0xFFC0) << 4) |
485 (r
>> 6) | 0xC0000000);
488 static AGG_INLINE color_type
make_color(pixel_type p
)
490 return color_type((p
<< 6) & 0xFFC0,
498 //=================================================blender_bgrAAA_gamma
499 template<class Gamma
> class blender_bgrAAA_gamma
502 typedef rgba16 color_type
;
503 typedef color_type::value_type value_type
;
504 typedef color_type::calc_type calc_type
;
505 typedef int32u pixel_type
;
506 typedef Gamma gamma_type
;
508 blender_bgrAAA_gamma() : m_gamma(0) {}
509 void gamma(const gamma_type
& g
) { m_gamma
= &g
; }
511 AGG_INLINE
void blend_pix(pixel_type
* p
,
512 unsigned cr
, unsigned cg
, unsigned cb
,
517 calc_type b
= m_gamma
->dir((bgr
>> 14) & 0xFFC0);
518 calc_type g
= m_gamma
->dir((bgr
>> 4) & 0xFFC0);
519 calc_type r
= m_gamma
->dir((bgr
<< 6) & 0xFFC0);
521 (((m_gamma
->inv(((m_gamma
->dir(cb
) - b
) * alpha
+ (b
<< 16)) >> 16) << 14) & 0x3FF00000) |
522 ((m_gamma
->inv(((m_gamma
->dir(cg
) - g
) * alpha
+ (g
<< 16)) >> 16) << 4 ) & 0x000FFC00) |
523 (m_gamma
->inv(((m_gamma
->dir(cr
) - r
) * alpha
+ (r
<< 16)) >> 16) >> 6 ) | 0xC0000000);
526 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
528 return (pixel_type
)(((b
& 0xFFC0) << 14) |
529 ((g
& 0xFFC0) << 4) |
530 (r
>> 6) | 0xC0000000);
533 static AGG_INLINE color_type
make_color(pixel_type p
)
535 return color_type((p
<< 6) & 0xFFC0,
541 const Gamma
* m_gamma
;
546 //=====================================================blender_rgbBBA
547 struct blender_rgbBBA
549 typedef rgba16 color_type
;
550 typedef color_type::value_type value_type
;
551 typedef color_type::calc_type calc_type
;
552 typedef int32u pixel_type
;
554 static AGG_INLINE
void blend_pix(pixel_type
* p
,
555 unsigned cr
, unsigned cg
, unsigned cb
,
560 calc_type r
= (rgb
>> 16) & 0xFFE0;
561 calc_type g
= (rgb
>> 5) & 0xFFE0;
562 calc_type b
= (rgb
<< 6) & 0xFFC0;
564 (((((cr
- r
) * alpha
+ (r
<< 16)) ) & 0xFFE00000) |
565 ((((cg
- g
) * alpha
+ (g
<< 16)) >> 11) & 0x001FFC00) |
566 (((cb
- b
) * alpha
+ (b
<< 16)) >> 22));
569 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
571 return (pixel_type
)(((r
& 0xFFE0) << 16) | ((g
& 0xFFE0) << 5) | (b
>> 6));
574 static AGG_INLINE color_type
make_color(pixel_type p
)
576 return color_type((p
>> 16) & 0xFFE0,
583 //=================================================blender_rgbBBA_pre
584 struct blender_rgbBBA_pre
586 typedef rgba16 color_type
;
587 typedef color_type::value_type value_type
;
588 typedef color_type::calc_type calc_type
;
589 typedef int32u pixel_type
;
591 static AGG_INLINE
void blend_pix(pixel_type
* p
,
592 unsigned cr
, unsigned cg
, unsigned cb
,
596 alpha
= color_type::base_mask
- alpha
;
597 cover
= (cover
+ 1) << (color_type::base_shift
- 8);
599 calc_type r
= (rgb
>> 16) & 0xFFE0;
600 calc_type g
= (rgb
>> 5) & 0xFFE0;
601 calc_type b
= (rgb
<< 6) & 0xFFC0;
603 ((((r
* alpha
+ cr
* cover
) ) & 0xFFE00000) |
604 (((g
* alpha
+ cg
* cover
) >> 11) & 0x001FFC00) |
605 ((b
* alpha
+ cb
* cover
) >> 22));
608 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
610 return (pixel_type
)(((r
& 0xFFE0) << 16) | ((g
& 0xFFE0) << 5) | (b
>> 6));
613 static AGG_INLINE color_type
make_color(pixel_type p
)
615 return color_type((p
>> 16) & 0xFFE0,
623 //=================================================blender_rgbBBA_gamma
624 template<class Gamma
> class blender_rgbBBA_gamma
627 typedef rgba16 color_type
;
628 typedef color_type::value_type value_type
;
629 typedef color_type::calc_type calc_type
;
630 typedef int32u pixel_type
;
631 typedef Gamma gamma_type
;
633 blender_rgbBBA_gamma() : m_gamma(0) {}
634 void gamma(const gamma_type
& g
) { m_gamma
= &g
; }
636 AGG_INLINE
void blend_pix(pixel_type
* p
,
637 unsigned cr
, unsigned cg
, unsigned cb
,
642 calc_type r
= m_gamma
->dir((rgb
>> 16) & 0xFFE0);
643 calc_type g
= m_gamma
->dir((rgb
>> 5) & 0xFFE0);
644 calc_type b
= m_gamma
->dir((rgb
<< 6) & 0xFFC0);
646 (((m_gamma
->inv(((m_gamma
->dir(cr
) - r
) * alpha
+ (r
<< 16)) >> 16) << 16) & 0xFFE00000) |
647 ((m_gamma
->inv(((m_gamma
->dir(cg
) - g
) * alpha
+ (g
<< 16)) >> 16) << 5 ) & 0x001FFC00) |
648 (m_gamma
->inv(((m_gamma
->dir(cb
) - b
) * alpha
+ (b
<< 16)) >> 16) >> 6 ));
651 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
653 return (pixel_type
)(((r
& 0xFFE0) << 16) | ((g
& 0xFFE0) << 5) | (b
>> 6));
656 static AGG_INLINE color_type
make_color(pixel_type p
)
658 return color_type((p
>> 16) & 0xFFE0,
664 const Gamma
* m_gamma
;
668 //=====================================================blender_bgrABB
669 struct blender_bgrABB
671 typedef rgba16 color_type
;
672 typedef color_type::value_type value_type
;
673 typedef color_type::calc_type calc_type
;
674 typedef int32u pixel_type
;
676 static AGG_INLINE
void blend_pix(pixel_type
* p
,
677 unsigned cr
, unsigned cg
, unsigned cb
,
682 calc_type b
= (bgr
>> 16) & 0xFFC0;
683 calc_type g
= (bgr
>> 6) & 0xFFE0;
684 calc_type r
= (bgr
<< 5) & 0xFFE0;
686 (((((cb
- b
) * alpha
+ (b
<< 16)) ) & 0xFFC00000) |
687 ((((cg
- g
) * alpha
+ (g
<< 16)) >> 10) & 0x003FF800) |
688 (((cr
- r
) * alpha
+ (r
<< 16)) >> 21));
691 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
693 return (pixel_type
)(((b
& 0xFFC0) << 16) | ((g
& 0xFFE0) << 6) | (r
>> 5));
696 static AGG_INLINE color_type
make_color(pixel_type p
)
698 return color_type((p
<< 5) & 0xFFE0,
705 //=================================================blender_bgrABB_pre
706 struct blender_bgrABB_pre
708 typedef rgba16 color_type
;
709 typedef color_type::value_type value_type
;
710 typedef color_type::calc_type calc_type
;
711 typedef int32u pixel_type
;
713 static AGG_INLINE
void blend_pix(pixel_type
* p
,
714 unsigned cr
, unsigned cg
, unsigned cb
,
718 alpha
= color_type::base_mask
- alpha
;
719 cover
= (cover
+ 1) << (color_type::base_shift
- 8);
721 calc_type b
= (bgr
>> 16) & 0xFFC0;
722 calc_type g
= (bgr
>> 6) & 0xFFE0;
723 calc_type r
= (bgr
<< 5) & 0xFFE0;
725 ((((b
* alpha
+ cb
* cover
) ) & 0xFFC00000) |
726 (((g
* alpha
+ cg
* cover
) >> 10) & 0x003FF800) |
727 ((r
* alpha
+ cr
* cover
) >> 21));
730 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
732 return (pixel_type
)(((b
& 0xFFC0) << 16) | ((g
& 0xFFE0) << 6) | (r
>> 5));
735 static AGG_INLINE color_type
make_color(pixel_type p
)
737 return color_type((p
<< 5) & 0xFFE0,
745 //=================================================blender_bgrABB_gamma
746 template<class Gamma
> class blender_bgrABB_gamma
749 typedef rgba16 color_type
;
750 typedef color_type::value_type value_type
;
751 typedef color_type::calc_type calc_type
;
752 typedef int32u pixel_type
;
753 typedef Gamma gamma_type
;
755 blender_bgrABB_gamma() : m_gamma(0) {}
756 void gamma(const gamma_type
& g
) { m_gamma
= &g
; }
758 AGG_INLINE
void blend_pix(pixel_type
* p
,
759 unsigned cr
, unsigned cg
, unsigned cb
,
764 calc_type b
= m_gamma
->dir((bgr
>> 16) & 0xFFC0);
765 calc_type g
= m_gamma
->dir((bgr
>> 6) & 0xFFE0);
766 calc_type r
= m_gamma
->dir((bgr
<< 5) & 0xFFE0);
768 (((m_gamma
->inv(((m_gamma
->dir(cb
) - b
) * alpha
+ (b
<< 16)) >> 16) << 16) & 0xFFC00000) |
769 ((m_gamma
->inv(((m_gamma
->dir(cg
) - g
) * alpha
+ (g
<< 16)) >> 16) << 6 ) & 0x003FF800) |
770 (m_gamma
->inv(((m_gamma
->dir(cr
) - r
) * alpha
+ (r
<< 16)) >> 16) >> 5 ));
773 static AGG_INLINE pixel_type
make_pix(unsigned r
, unsigned g
, unsigned b
)
775 return (pixel_type
)(((b
& 0xFFC0) << 16) | ((g
& 0xFFE0) << 6) | (r
>> 5));
778 static AGG_INLINE color_type
make_color(pixel_type p
)
780 return color_type((p
<< 5) & 0xFFE0,
786 const Gamma
* m_gamma
;
791 //===============================================pixel_formats_rgb_packed
792 template<class Blender
> class pixel_formats_rgb_packed
795 typedef rendering_buffer::row_data row_data
;
796 typedef typename
Blender::color_type color_type
;
797 typedef typename
Blender::pixel_type pixel_type
;
798 typedef typename
color_type::value_type value_type
;
799 typedef typename
color_type::calc_type calc_type
;
802 base_shift
= color_type::base_shift
,
803 base_size
= color_type::base_size
,
804 base_mask
= color_type::base_mask
808 //--------------------------------------------------------------------
809 AGG_INLINE
void copy_or_blend_pix(pixel_type
* p
, const color_type
& c
, unsigned cover
)
813 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
814 if(alpha
== base_mask
)
816 *p
= m_blender
.make_pix(c
.r
, c
.g
, c
.b
);
820 m_blender
.blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, cover
);
825 //--------------------------------------------------------------------
826 AGG_INLINE
void copy_or_blend_opaque_pix(pixel_type
* p
, const color_type
& c
, unsigned cover
)
830 *p
= m_blender
.make_pix(c
.r
, c
.g
, c
.b
);
834 m_blender
.blend_pix(p
, c
.r
, c
.g
, c
.b
, (cover
+ 1) << (base_shift
- 8), cover
);
840 //--------------------------------------------------------------------
841 pixel_formats_rgb_packed(rendering_buffer
& rb
) :
845 //--------------------------------------------------------------------
846 Blender
& blender() { return m_blender
; }
848 //--------------------------------------------------------------------
849 AGG_INLINE
unsigned width() const { return m_rbuf
->width(); }
850 AGG_INLINE
unsigned height() const { return m_rbuf
->height(); }
852 //--------------------------------------------------------------------
853 AGG_INLINE color_type
pixel(int x
, int y
) const
855 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
856 return m_blender
.make_color(((pixel_type
*)m_rbuf
->row(y
))[x
]);
859 //--------------------------------------------------------------------
860 row_data
span(int x
, int y
) const
864 m_rbuf
->row(y
) + x
* sizeof(pixel_type
));
867 //--------------------------------------------------------------------
868 AGG_INLINE
void copy_pixel(int x
, int y
, const color_type
& c
)
870 ((pixel_type
*)m_rbuf
->row(y
))[x
] = m_blender
.make_pix(c
.r
, c
.g
, c
.b
);
873 //--------------------------------------------------------------------
874 AGG_INLINE
void blend_pixel(int x
, int y
, const color_type
& c
, int8u cover
)
876 copy_or_blend_pix((pixel_type
*)m_rbuf
->row(y
) + x
, c
, cover
);
880 //--------------------------------------------------------------------
881 AGG_INLINE
void copy_hline(int x
, int y
,
885 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
886 pixel_type v
= m_blender
.make_pix(c
.r
, c
.g
, c
.b
);
895 //--------------------------------------------------------------------
896 AGG_INLINE
void copy_vline(int x
, int y
,
900 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
901 pixel_type v
= m_blender
.make_pix(c
.r
, c
.g
, c
.b
);
905 p
= (pixel_type
*)m_rbuf
->next_row(p
);
911 //--------------------------------------------------------------------
912 void blend_hline(int x
, int y
,
919 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
920 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
921 if(alpha
== base_mask
)
923 pixel_type v
= m_blender
.make_pix(c
.r
, c
.g
, c
.b
);
934 m_blender
.blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, cover
);
943 //--------------------------------------------------------------------
944 void blend_vline(int x
, int y
,
951 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
952 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
953 if(alpha
== base_mask
)
955 pixel_type v
= m_blender
.make_pix(c
.r
, c
.g
, c
.b
);
959 p
= (pixel_type
*)m_rbuf
->next_row(p
);
967 m_blender
.blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, cover
);
968 p
= (pixel_type
*)m_rbuf
->next_row(p
);
976 //--------------------------------------------------------------------
977 void blend_solid_hspan(int x
, int y
,
982 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
985 copy_or_blend_pix(p
, c
, *covers
++);
992 //--------------------------------------------------------------------
993 void blend_solid_vspan(int x
, int y
,
998 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
1001 copy_or_blend_pix(p
, c
, *covers
++);
1002 p
= (pixel_type
*)m_rbuf
->next_row(p
);
1008 //--------------------------------------------------------------------
1009 void blend_color_hspan(int x
, int y
,
1011 const color_type
* colors
,
1012 const int8u
* covers
,
1015 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
1018 copy_or_blend_pix(p
++, *colors
++, covers
? *covers
++ : cover
);
1024 //--------------------------------------------------------------------
1025 void blend_color_vspan(int x
, int y
,
1027 const color_type
* colors
,
1028 const int8u
* covers
,
1031 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
1034 copy_or_blend_pix(p
, *colors
++, covers
? *covers
++ : cover
);
1035 p
= (pixel_type
*)m_rbuf
->next_row(p
);
1041 //--------------------------------------------------------------------
1042 void blend_opaque_color_hspan(int x
, int y
,
1044 const color_type
* colors
,
1045 const int8u
* covers
,
1048 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
1053 copy_or_blend_opaque_pix(p
++, *colors
++, *covers
++);
1063 *p
++ = m_blender
.make_pix(colors
->r
, colors
->g
, colors
->b
);
1072 copy_or_blend_opaque_pix(p
++, *colors
++, cover
);
1080 //--------------------------------------------------------------------
1081 void blend_opaque_color_vspan(int x
, int y
,
1083 const color_type
* colors
,
1084 const int8u
* covers
,
1087 pixel_type
* p
= (pixel_type
*)m_rbuf
->row(y
) + x
;
1092 copy_or_blend_opaque_pix(p
, *colors
++, *covers
++);
1093 p
= (pixel_type
*)m_rbuf
->next_row(p
);
1103 *p
= m_blender
.make_pix(colors
->r
, colors
->g
, colors
->b
);
1104 p
= (value_type
*)m_rbuf
->next_row(p
);
1113 copy_or_blend_opaque_pix(p
, *colors
++, cover
);
1114 p
= (value_type
*)m_rbuf
->next_row(p
);
1122 //--------------------------------------------------------------------
1123 void copy_from(const rendering_buffer
& from
,
1128 memmove((pixel_type
*)m_rbuf
->row(ydst
) + xdst
,
1129 (pixel_type
*)from
.row(ysrc
) + xsrc
,
1130 sizeof(pixel_type
) * len
);
1134 //--------------------------------------------------------------------
1135 template<class SrcPixelFormatRenderer
>
1136 void blend_from(const SrcPixelFormatRenderer
& from
,
1142 typedef typename
SrcPixelFormatRenderer::order_type src_order
;
1144 const value_type
* psrc
= (const value_type
*)psrc_
;
1145 pixel_type
* pdst
= (pixel_type
*)m_rbuf
->row(ydst
) + xdst
;
1148 value_type alpha
= psrc
[src_order::A
];
1151 if(alpha
== base_mask
)
1153 *pdst
= m_blender
.make_pix(psrc
[src_order::R
],
1155 psrc
[src_order::B
]);
1159 m_blender
.blend_pix(pdst
,
1175 rendering_buffer
* m_rbuf
;
1179 typedef pixel_formats_rgb_packed
<blender_rgb555
> pixfmt_rgb555
; //----pixfmt_rgb555
1180 typedef pixel_formats_rgb_packed
<blender_rgb565
> pixfmt_rgb565
; //----pixfmt_rgb565
1182 typedef pixel_formats_rgb_packed
<blender_rgb555_pre
> pixfmt_rgb555_pre
; //----pixfmt_rgb555_pre
1183 typedef pixel_formats_rgb_packed
<blender_rgb565_pre
> pixfmt_rgb565_pre
; //----pixfmt_rgb565_pre
1185 typedef pixel_formats_rgb_packed
<blender_rgbAAA
> pixfmt_rgbAAA
; //----pixfmt_rgbAAA
1186 typedef pixel_formats_rgb_packed
<blender_bgrAAA
> pixfmt_bgrAAA
; //----pixfmt_bgrAAA
1187 typedef pixel_formats_rgb_packed
<blender_rgbBBA
> pixfmt_rgbBBA
; //----pixfmt_rgbBBA
1188 typedef pixel_formats_rgb_packed
<blender_bgrABB
> pixfmt_bgrABB
; //----pixfmt_bgrABB
1190 typedef pixel_formats_rgb_packed
<blender_rgbAAA_pre
> pixfmt_rgbAAA_pre
; //----pixfmt_rgbAAA_pre
1191 typedef pixel_formats_rgb_packed
<blender_bgrAAA_pre
> pixfmt_bgrAAA_pre
; //----pixfmt_bgrAAA_pre
1192 typedef pixel_formats_rgb_packed
<blender_rgbBBA_pre
> pixfmt_rgbBBA_pre
; //----pixfmt_rgbBBA_pre
1193 typedef pixel_formats_rgb_packed
<blender_bgrABB_pre
> pixfmt_bgrABB_pre
; //----pixfmt_bgrABB_pre
1196 //-----------------------------------------------------pixfmt_rgb555_gamma
1197 template<class Gamma
> class pixfmt_rgb555_gamma
:
1198 public pixel_formats_rgb_packed
<blender_rgb555_gamma
<Gamma
> >
1201 pixfmt_rgb555_gamma(rendering_buffer
& rb
, const Gamma
& g
) :
1202 pixel_formats_rgb_packed
<blender_rgb555_gamma
<Gamma
> >(rb
)
1204 this->blender().gamma(g
);
1209 //-----------------------------------------------------pixfmt_rgb565_gamma
1210 template<class Gamma
> class pixfmt_rgb565_gamma
:
1211 public pixel_formats_rgb_packed
<blender_rgb565_gamma
<Gamma
> >
1214 pixfmt_rgb565_gamma(rendering_buffer
& rb
, const Gamma
& g
) :
1215 pixel_formats_rgb_packed
<blender_rgb565_gamma
<Gamma
> >(rb
)
1217 this->blender().gamma(g
);
1222 //-----------------------------------------------------pixfmt_rgbAAA_gamma
1223 template<class Gamma
> class pixfmt_rgbAAA_gamma
:
1224 public pixel_formats_rgb_packed
<blender_rgbAAA_gamma
<Gamma
> >
1227 pixfmt_rgbAAA_gamma(rendering_buffer
& rb
, const Gamma
& g
) :
1228 pixel_formats_rgb_packed
<blender_rgbAAA_gamma
<Gamma
> >(rb
)
1230 this->blender().gamma(g
);
1235 //-----------------------------------------------------pixfmt_bgrAAA_gamma
1236 template<class Gamma
> class pixfmt_bgrAAA_gamma
:
1237 public pixel_formats_rgb_packed
<blender_bgrAAA_gamma
<Gamma
> >
1240 pixfmt_bgrAAA_gamma(rendering_buffer
& rb
, const Gamma
& g
) :
1241 pixel_formats_rgb_packed
<blender_bgrAAA_gamma
<Gamma
> >(rb
)
1243 this->blender().gamma(g
);
1248 //-----------------------------------------------------pixfmt_rgbBBA_gamma
1249 template<class Gamma
> class pixfmt_rgbBBA_gamma
:
1250 public pixel_formats_rgb_packed
<blender_rgbBBA_gamma
<Gamma
> >
1253 pixfmt_rgbBBA_gamma(rendering_buffer
& rb
, const Gamma
& g
) :
1254 pixel_formats_rgb_packed
<blender_rgbBBA_gamma
<Gamma
> >(rb
)
1256 this->blender().gamma(g
);
1261 //-----------------------------------------------------pixfmt_bgrABB_gamma
1262 template<class Gamma
> class pixfmt_bgrABB_gamma
:
1263 public pixel_formats_rgb_packed
<blender_bgrABB_gamma
<Gamma
> >
1266 pixfmt_bgrABB_gamma(rendering_buffer
& rb
, const Gamma
& g
) :
1267 pixel_formats_rgb_packed
<blender_bgrABB_gamma
<Gamma
> >(rb
)
1269 this->blender().gamma(g
);