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_RGBA_INCLUDED
25 #define AGG_PIXFMT_RGBA_INCLUDED
28 #include "agg_basics.h"
29 #include "agg_color_rgba.h"
30 #include "agg_rendering_buffer.h"
35 //=========================================================multiplier_rgba
36 template<class ColorT
, class Order
> struct multiplier_rgba
38 typedef typename
ColorT::value_type value_type
;
39 typedef typename
ColorT::calc_type calc_type
;
41 //--------------------------------------------------------------------
42 static AGG_INLINE
void premultiply(value_type
* p
)
44 calc_type a
= p
[Order::A
];
45 if(a
< ColorT::base_mask
)
49 p
[Order::R
] = p
[Order::G
] = p
[Order::B
] = 0;
52 p
[Order::R
] = value_type((p
[Order::R
] * a
) >> ColorT::base_shift
);
53 p
[Order::G
] = value_type((p
[Order::G
] * a
) >> ColorT::base_shift
);
54 p
[Order::B
] = value_type((p
[Order::B
] * a
) >> ColorT::base_shift
);
59 //--------------------------------------------------------------------
60 static AGG_INLINE
void demultiply(value_type
* p
)
62 calc_type a
= p
[Order::A
];
63 if(a
< ColorT::base_mask
)
67 p
[Order::R
] = p
[Order::G
] = p
[Order::B
] = 0;
70 calc_type r
= (calc_type(p
[Order::R
]) * ColorT::base_mask
) / a
;
71 calc_type g
= (calc_type(p
[Order::G
]) * ColorT::base_mask
) / a
;
72 calc_type b
= (calc_type(p
[Order::B
]) * ColorT::base_mask
) / a
;
73 p
[Order::R
] = value_type((r
> ColorT::base_mask
) ? ColorT::base_mask
: r
);
74 p
[Order::G
] = value_type((g
> ColorT::base_mask
) ? ColorT::base_mask
: g
);
75 p
[Order::B
] = value_type((b
> ColorT::base_mask
) ? ColorT::base_mask
: b
);
81 //=====================================================apply_gamma_dir_rgba
82 template<class ColorT
, class Order
, class GammaLut
> class apply_gamma_dir_rgba
85 typedef typename
ColorT::value_type value_type
;
87 apply_gamma_dir_rgba(const GammaLut
& gamma
) : m_gamma(gamma
) {}
89 AGG_INLINE
void operator () (value_type
* p
)
91 p
[Order::R
] = m_gamma
.dir(p
[Order::R
]);
92 p
[Order::G
] = m_gamma
.dir(p
[Order::G
]);
93 p
[Order::B
] = m_gamma
.dir(p
[Order::B
]);
97 const GammaLut
& m_gamma
;
102 //=====================================================apply_gamma_inv_rgba
103 template<class ColorT
, class Order
, class GammaLut
> class apply_gamma_inv_rgba
106 typedef typename
ColorT::value_type value_type
;
108 apply_gamma_inv_rgba(const GammaLut
& gamma
) : m_gamma(gamma
) {}
110 AGG_INLINE
void operator () (value_type
* p
)
112 p
[Order::R
] = m_gamma
.inv(p
[Order::R
]);
113 p
[Order::G
] = m_gamma
.inv(p
[Order::G
]);
114 p
[Order::B
] = m_gamma
.inv(p
[Order::B
]);
118 const GammaLut
& m_gamma
;
123 //=============================================================blender_rgba
124 template<class ColorT
, class Order
, class PixelT
> struct blender_rgba
126 typedef ColorT color_type
;
127 typedef PixelT pixel_type
;
128 typedef Order order_type
;
129 typedef typename
color_type::value_type value_type
;
130 typedef typename
color_type::calc_type calc_type
;
133 base_shift
= color_type::base_shift
,
134 base_mask
= color_type::base_mask
137 //--------------------------------------------------------------------
138 static AGG_INLINE
void blend_pix(value_type
* p
,
139 unsigned cr
, unsigned cg
, unsigned cb
,
143 calc_type r
= p
[Order::R
];
144 calc_type g
= p
[Order::G
];
145 calc_type b
= p
[Order::B
];
146 calc_type a
= p
[Order::A
];
147 p
[Order::R
] = (value_type
)(((cr
- r
) * alpha
+ (r
<< base_shift
)) >> base_shift
);
148 p
[Order::G
] = (value_type
)(((cg
- g
) * alpha
+ (g
<< base_shift
)) >> base_shift
);
149 p
[Order::B
] = (value_type
)(((cb
- b
) * alpha
+ (b
<< base_shift
)) >> base_shift
);
150 p
[Order::A
] = (value_type
)((alpha
+ a
) - ((alpha
* a
+ base_mask
) >> base_shift
));
155 //=========================================================blender_rgba_pre
156 template<class ColorT
, class Order
, class PixelT
> struct blender_rgba_pre
158 typedef ColorT color_type
;
159 typedef PixelT pixel_type
;
160 typedef Order order_type
;
161 typedef typename
color_type::value_type value_type
;
162 typedef typename
color_type::calc_type calc_type
;
165 base_shift
= color_type::base_shift
,
166 base_mask
= color_type::base_mask
169 //--------------------------------------------------------------------
170 static AGG_INLINE
void blend_pix(value_type
* p
,
171 unsigned cr
, unsigned cg
, unsigned cb
,
175 alpha
= color_type::base_mask
- alpha
;
176 cover
= (cover
+ 1) << (base_shift
- 8);
177 p
[Order::R
] = (value_type
)((p
[Order::R
] * alpha
+ cr
* cover
) >> base_shift
);
178 p
[Order::G
] = (value_type
)((p
[Order::G
] * alpha
+ cg
* cover
) >> base_shift
);
179 p
[Order::B
] = (value_type
)((p
[Order::B
] * alpha
+ cb
* cover
) >> base_shift
);
180 p
[Order::A
] = (value_type
)(base_mask
- ((alpha
* (base_mask
- p
[Order::A
])) >> base_shift
));
186 //======================================================blender_rgba_plain
187 template<class ColorT
, class Order
, class PixelT
> struct blender_rgba_plain
189 typedef ColorT color_type
;
190 typedef PixelT pixel_type
;
191 typedef Order order_type
;
192 typedef typename
color_type::value_type value_type
;
193 typedef typename
color_type::calc_type calc_type
;
194 enum { base_shift
= color_type::base_shift
};
196 //--------------------------------------------------------------------
197 static AGG_INLINE
void blend_pix(value_type
* p
,
198 unsigned cr
, unsigned cg
, unsigned cb
,
202 if(alpha
== 0) return;
203 calc_type a
= p
[Order::A
];
204 calc_type r
= p
[Order::R
] * a
;
205 calc_type g
= p
[Order::G
] * a
;
206 calc_type b
= p
[Order::B
] * a
;
207 a
= ((alpha
+ a
) << base_shift
) - alpha
* a
;
208 p
[Order::A
] = (value_type
)(a
>> base_shift
);
209 p
[Order::R
] = (value_type
)((((cr
<< base_shift
) - r
) * alpha
+ (r
<< base_shift
)) / a
);
210 p
[Order::G
] = (value_type
)((((cg
<< base_shift
) - g
) * alpha
+ (g
<< base_shift
)) / a
);
211 p
[Order::B
] = (value_type
)((((cb
<< base_shift
) - b
) * alpha
+ (b
<< base_shift
)) / a
);
216 //====================================================blender_rgba_wrapper
217 template<class Blender
> struct blender_rgba_wrapper
219 typedef typename
Blender::color_type color_type
;
220 typedef typename
Blender::order_type order_type
;
221 typedef typename
Blender::pixel_type pixel_type
;
222 typedef typename
color_type::value_type value_type
;
223 typedef typename
color_type::calc_type calc_type
;
226 base_shift
= color_type::base_shift
,
227 base_size
= color_type::base_size
,
228 base_mask
= color_type::base_mask
231 //--------------------------------------------------------------------
232 static AGG_INLINE
void blend_pix(value_type
* p
,
233 unsigned cr
, unsigned cg
, unsigned cb
,
237 Blender::blend_pix(p
, cr
, cg
, cb
, alpha
, cover
);
240 //--------------------------------------------------------------------
241 static AGG_INLINE
void copy_or_blend_pix(value_type
* p
,
247 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
248 if(alpha
== base_mask
)
250 p
[order_type::R
] = c
.r
;
251 p
[order_type::G
] = c
.g
;
252 p
[order_type::B
] = c
.b
;
253 p
[order_type::A
] = c
.a
;
257 Blender::blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, cover
);
262 //--------------------------------------------------------------------
263 static AGG_INLINE
void copy_or_blend_opaque_pix(value_type
* p
,
269 p
[order_type::R
] = c
.r
;
270 p
[order_type::G
] = c
.g
;
271 p
[order_type::B
] = c
.b
;
272 p
[order_type::A
] = base_mask
;
276 Blender::blend_pix(p
, c
.r
, c
.g
, c
.b
, (cover
+ 1) << (base_shift
- 8), cover
);
284 //=======================================================pixel_formats_rgba
285 template<class Blender
> class pixel_formats_rgba
288 typedef rendering_buffer::row_data row_data
;
289 typedef typename
Blender::color_type color_type
;
290 typedef typename
Blender::order_type order_type
;
291 typedef typename
Blender::pixel_type pixel_type
;
292 typedef typename
color_type::value_type value_type
;
293 typedef typename
color_type::calc_type calc_type
;
294 typedef blender_rgba_wrapper
<Blender
> blender_type
;
297 base_shift
= color_type::base_shift
,
298 base_size
= color_type::base_size
,
299 base_mask
= color_type::base_mask
302 //--------------------------------------------------------------------
303 pixel_formats_rgba(rendering_buffer
& rb
) :
307 //--------------------------------------------------------------------
308 AGG_INLINE
unsigned width() const { return m_rbuf
->width(); }
309 AGG_INLINE
unsigned height() const { return m_rbuf
->height(); }
311 //--------------------------------------------------------------------
312 AGG_INLINE color_type
pixel(int x
, int y
) const
314 const value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
315 return color_type(p
[order_type::R
],
321 //--------------------------------------------------------------------
322 row_data
span(int x
, int y
) const
326 m_rbuf
->row(y
) + x
* 4 * sizeof(value_type
));
329 //--------------------------------------------------------------------
330 AGG_INLINE
void copy_pixel(int x
, int y
, const color_type
& c
)
332 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
333 p
[order_type::R
] = c
.r
;
334 p
[order_type::G
] = c
.g
;
335 p
[order_type::B
] = c
.b
;
336 p
[order_type::A
] = c
.a
;
339 //--------------------------------------------------------------------
340 AGG_INLINE
void blend_pixel(int x
, int y
, const color_type
& c
, int8u cover
)
342 blender_type::copy_or_blend_pix((value_type
*)m_rbuf
->row(y
) + (x
<< 2), c
, cover
);
346 //--------------------------------------------------------------------
347 AGG_INLINE
void copy_hline(int x
, int y
,
351 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
353 ((value_type
*)&v
)[order_type::R
] = c
.r
;
354 ((value_type
*)&v
)[order_type::G
] = c
.g
;
355 ((value_type
*)&v
)[order_type::B
] = c
.b
;
356 ((value_type
*)&v
)[order_type::A
] = c
.a
;
366 //--------------------------------------------------------------------
367 AGG_INLINE
void copy_vline(int x
, int y
,
371 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
373 ((value_type
*)&v
)[order_type::R
] = c
.r
;
374 ((value_type
*)&v
)[order_type::G
] = c
.g
;
375 ((value_type
*)&v
)[order_type::B
] = c
.b
;
376 ((value_type
*)&v
)[order_type::A
] = c
.a
;
380 p
= (value_type
*)m_rbuf
->next_row(p
);
386 //--------------------------------------------------------------------
387 void blend_hline(int x
, int y
,
394 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
395 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
396 if(alpha
== base_mask
)
399 ((value_type
*)&v
)[order_type::R
] = c
.r
;
400 ((value_type
*)&v
)[order_type::G
] = c
.g
;
401 ((value_type
*)&v
)[order_type::B
] = c
.b
;
402 ((value_type
*)&v
)[order_type::A
] = c
.a
;
414 blender_type::blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, cover
);
423 //--------------------------------------------------------------------
424 void blend_vline(int x
, int y
,
431 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
432 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
433 if(alpha
== base_mask
)
436 ((value_type
*)&v
)[order_type::R
] = c
.r
;
437 ((value_type
*)&v
)[order_type::G
] = c
.g
;
438 ((value_type
*)&v
)[order_type::B
] = c
.b
;
439 ((value_type
*)&v
)[order_type::A
] = c
.a
;
443 p
= (value_type
*)m_rbuf
->next_row(p
);
451 blender_type::blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, cover
);
452 p
= (value_type
*)m_rbuf
->next_row(p
);
460 //--------------------------------------------------------------------
461 void blend_solid_hspan(int x
, int y
,
468 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
471 calc_type alpha
= (calc_type(c
.a
) * (calc_type(*covers
) + 1)) >> 8;
472 if(alpha
== base_mask
)
474 p
[order_type::R
] = c
.r
;
475 p
[order_type::G
] = c
.g
;
476 p
[order_type::B
] = c
.b
;
477 p
[order_type::A
] = base_mask
;
481 blender_type::blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, *covers
);
491 //--------------------------------------------------------------------
492 void blend_solid_vspan(int x
, int y
,
499 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
502 calc_type alpha
= (calc_type(c
.a
) * (calc_type(*covers
) + 1)) >> 8;
503 if(alpha
== base_mask
)
505 p
[order_type::R
] = c
.r
;
506 p
[order_type::G
] = c
.g
;
507 p
[order_type::B
] = c
.b
;
508 p
[order_type::A
] = base_mask
;
512 blender_type::blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, *covers
);
514 p
= (value_type
*)m_rbuf
->next_row(p
);
522 //--------------------------------------------------------------------
523 void blend_color_hspan(int x
, int y
,
525 const color_type
* colors
,
529 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
534 blender_type::copy_or_blend_pix(p
, *colors
++, *covers
++);
545 if(colors
->a
== base_mask
)
547 p
[order_type::R
] = colors
->r
;
548 p
[order_type::G
] = colors
->g
;
549 p
[order_type::B
] = colors
->b
;
550 p
[order_type::A
] = base_mask
;
554 blender_type::copy_or_blend_pix(p
, *colors
, 255);
565 blender_type::copy_or_blend_pix(p
, *colors
++, cover
);
575 //--------------------------------------------------------------------
576 void blend_color_vspan(int x
, int y
,
578 const color_type
* colors
,
582 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
587 blender_type::copy_or_blend_pix(p
, *colors
++, *covers
++);
588 p
= (value_type
*)m_rbuf
->next_row(p
);
598 if(colors
->a
== base_mask
)
600 p
[order_type::R
] = colors
->r
;
601 p
[order_type::G
] = colors
->g
;
602 p
[order_type::B
] = colors
->b
;
603 p
[order_type::A
] = base_mask
;
607 blender_type::copy_or_blend_pix(p
, *colors
, 255);
609 p
= (value_type
*)m_rbuf
->next_row(p
);
618 blender_type::copy_or_blend_pix(p
, *colors
++, cover
);
619 p
= (value_type
*)m_rbuf
->next_row(p
);
627 //--------------------------------------------------------------------
628 void blend_opaque_color_hspan(int x
, int y
,
630 const color_type
* colors
,
634 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
639 blender_type::copy_or_blend_opaque_pix(p
, *colors
++, *covers
++);
650 p
[order_type::R
] = colors
->r
;
651 p
[order_type::G
] = colors
->g
;
652 p
[order_type::B
] = colors
->b
;
653 p
[order_type::A
] = base_mask
;
663 blender_type::copy_or_blend_opaque_pix(p
, *colors
++, cover
);
672 //--------------------------------------------------------------------
673 void blend_opaque_color_vspan(int x
, int y
,
675 const color_type
* colors
,
679 value_type
* p
= (value_type
*)m_rbuf
->row(y
) + (x
<< 2);
684 blender_type::copy_or_blend_opaque_pix(p
, *colors
++, *covers
++);
685 p
= (value_type
*)m_rbuf
->next_row(p
);
695 p
[order_type::R
] = colors
->r
;
696 p
[order_type::G
] = colors
->g
;
697 p
[order_type::B
] = colors
->b
;
698 p
[order_type::A
] = base_mask
;
699 p
= (value_type
*)m_rbuf
->next_row(p
);
708 blender_type::copy_or_blend_opaque_pix(p
, *colors
++, cover
);
709 p
= (value_type
*)m_rbuf
->next_row(p
);
717 //--------------------------------------------------------------------
718 template<class Function
> void for_each_pixel(Function f
)
721 for(y
= 0; y
< height(); ++y
)
723 unsigned len
= width();
724 value_type
* p
= (value_type
*)m_rbuf
->row(y
);
734 //--------------------------------------------------------------------
737 for_each_pixel(multiplier_rgba
<color_type
, order_type
>::premultiply
);
740 //--------------------------------------------------------------------
743 for_each_pixel(multiplier_rgba
<color_type
, order_type
>::demultiply
);
746 //--------------------------------------------------------------------
747 template<class GammaLut
> void apply_gamma_dir(const GammaLut
& g
)
749 for_each_pixel(apply_gamma_dir_rgba
<color_type
, order_type
, GammaLut
>(g
));
752 //--------------------------------------------------------------------
753 template<class GammaLut
> void apply_gamma_inv(const GammaLut
& g
)
755 for_each_pixel(apply_gamma_inv_rgba
<color_type
, order_type
, GammaLut
>(g
));
758 //--------------------------------------------------------------------
759 void copy_from(const rendering_buffer
& from
,
764 memmove((value_type
*)m_rbuf
->row(ydst
) + xdst
* 4,
765 (value_type
*)from
.row(ysrc
) + xsrc
* 4,
766 sizeof(value_type
) * 4 * len
);
770 //--------------------------------------------------------------------
771 template<class SrcPixelFormatRenderer
>
772 void blend_from(const SrcPixelFormatRenderer
& from
,
778 typedef typename
SrcPixelFormatRenderer::order_type src_order
;
780 const value_type
* psrc
= (const value_type
*)psrc_
;
781 value_type
* pdst
= (value_type
*)m_rbuf
->row(ydst
) + (xdst
<< 2);
785 psrc
+= (len
-1) << 2;
786 pdst
+= (len
-1) << 2;
791 value_type alpha
= psrc
[src_order::A
];
795 if(alpha
== base_mask
)
797 pdst
[order_type::R
] = psrc
[src_order::R
];
798 pdst
[order_type::G
] = psrc
[src_order::G
];
799 pdst
[order_type::B
] = psrc
[src_order::B
];
800 pdst
[order_type::A
] = psrc
[src_order::A
];
804 blender_type::blend_pix(pdst
,
819 rendering_buffer
* m_rbuf
;
825 //================================================pixfmt_custom_rbuf_rgba
826 template<class Blender
, class RenBuf
> class pixfmt_custom_rbuf_rgba
829 typedef typename
Blender::color_type color_type
;
830 typedef typename
Blender::order_type order_type
;
831 typedef typename
Blender::pixel_type pixel_type
;
832 typedef typename
color_type::value_type value_type
;
833 typedef typename
color_type::calc_type calc_type
;
834 typedef blender_rgba_wrapper
<Blender
> blender_type
;
837 base_shift
= color_type::base_shift
,
838 base_size
= color_type::base_size
,
839 base_mask
= color_type::base_mask
842 typedef RenBuf rbuf_type
;
843 typedef typename
rbuf_type::row_data row_data
;
845 //--------------------------------------------------------------------
846 pixfmt_custom_rbuf_rgba(rbuf_type
& rb
) : m_rbuf(&rb
) {}
848 //--------------------------------------------------------------------
849 unsigned width() const { return m_rbuf
->width(); }
850 unsigned height() const { return m_rbuf
->height(); }
852 //--------------------------------------------------------------------
853 color_type
pixel(int x
, int y
) const
855 const value_type
* p
= m_rbuf
->span_ptr(x
, y
, 1);
856 return p
? color_type(p
[order_type::R
],
860 color_type::no_color();
863 //--------------------------------------------------------------------
864 row_data
span(int x
, int y
) const
866 return m_rbuf
->span(x
, y
);
869 //--------------------------------------------------------------------
870 void copy_pixel(int x
, int y
, const color_type
& c
)
872 int8u
* p
= m_rbuf
->span_ptr(x
, y
, 1);
873 p
[order_type::R
] = c
.r
;
874 p
[order_type::G
] = c
.g
;
875 p
[order_type::B
] = c
.b
;
876 p
[order_type::A
] = c
.b
;
879 //--------------------------------------------------------------------
880 void blend_pixel(int x
, int y
, const color_type
& c
, int8u cover
)
882 blender_type::copy_or_blend_pix((value_type
*)m_rbuf
->span_ptr(x
, y
, 1), c
, cover
);
885 //--------------------------------------------------------------------
886 void copy_hline(int x
, int y
, unsigned len
, const color_type
& c
)
888 value_type
* p
= (value_type
*)m_rbuf
->span_ptr(x
, y
, len
);
890 ((value_type
*)&v
)[order_type::R
] = c
.r
;
891 ((value_type
*)&v
)[order_type::G
] = c
.g
;
892 ((value_type
*)&v
)[order_type::B
] = c
.b
;
893 ((value_type
*)&v
)[order_type::A
] = c
.a
;
902 //--------------------------------------------------------------------
903 void copy_vline(int x
, int y
, unsigned len
, const color_type
& c
)
906 ((value_type
*)&v
)[order_type::R
] = c
.r
;
907 ((value_type
*)&v
)[order_type::G
] = c
.g
;
908 ((value_type
*)&v
)[order_type::B
] = c
.b
;
909 ((value_type
*)&v
)[order_type::A
] = c
.a
;
912 *(pixel_type
*)(m_rbuf
->span_ptr(x
, y
++, 1)) = v
;
917 //--------------------------------------------------------------------
918 void blend_hline(int x
, int y
, unsigned len
,
919 const color_type
& c
, int8u cover
)
923 value_type
* p
= (value_type
*)m_rbuf
->span_ptr(x
, y
, len
);
924 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
925 if(alpha
== base_mask
)
928 ((value_type
*)&v
)[order_type::R
] = c
.r
;
929 ((value_type
*)&v
)[order_type::G
] = c
.g
;
930 ((value_type
*)&v
)[order_type::B
] = c
.b
;
931 ((value_type
*)&v
)[order_type::A
] = c
.a
;
943 blender_type::blend_pix(p
, c
.r
, c
.g
, c
.b
, alpha
, cover
);
951 //--------------------------------------------------------------------
952 void blend_vline(int x
, int y
, unsigned len
,
953 const color_type
& c
, int8u cover
)
957 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
958 if(alpha
== base_mask
)
961 ((value_type
*)&v
)[order_type::R
] = c
.r
;
962 ((value_type
*)&v
)[order_type::G
] = c
.g
;
963 ((value_type
*)&v
)[order_type::B
] = c
.b
;
964 ((value_type
*)&v
)[order_type::A
] = c
.a
;
967 *(pixel_type
*)(m_rbuf
->span_ptr(x
, y
++, 1)) = v
;
975 blender_type::blend_pix(*(pixel_type
*)m_rbuf
->span_ptr(x
, y
++, 1),
976 c
.r
, c
.g
, c
.b
, alpha
, cover
);
984 //--------------------------------------------------------------------
985 void blend_solid_hspan(int x
, int y
, unsigned len
,
986 const color_type
& c
, const int8u
* covers
)
988 value_type
* p
= (value_type
*)m_rbuf
->span_ptr(x
, y
, len
);
991 blender_type::copy_or_blend_pix(p
, c
, *covers
++);
999 //--------------------------------------------------------------------
1000 void blend_solid_vspan(int x
, int y
, unsigned len
,
1001 const color_type
& c
, const int8u
* covers
)
1005 blender_type::copy_or_blend_pix((value_type
*)m_rbuf
->span_ptr(x
, y
++, 1),
1013 //--------------------------------------------------------------------
1014 void blend_color_hspan(int x
, int y
, unsigned len
,
1015 const color_type
* colors
,
1016 const int8u
* covers
,
1019 value_type
* p
= (value_type
*)m_rbuf
->span_ptr(x
, y
, len
);
1022 blender_type::copy_or_blend_pix(p
, *colors
++, covers
? *covers
++ : cover
);
1029 //--------------------------------------------------------------------
1030 void blend_color_vspan(int x
, int y
, unsigned len
,
1031 const color_type
* colors
,
1032 const int8u
* covers
,
1037 blender_type::copy_or_blend_pix((value_type
*)m_rbuf
->span_ptr(x
, y
++, 1),
1038 *colors
++, covers
? *covers
++ : cover
);
1044 //--------------------------------------------------------------------
1045 void blend_opaque_color_hspan(int x
, int y
,
1047 const color_type
* colors
,
1048 const int8u
* covers
,
1051 value_type
* p
= (value_type
*)m_rbuf
->span_ptr(x
, y
, len
);
1056 blender_type::copy_or_blend_opaque_pix(p
, *colors
++, *covers
++);
1067 p
[order_type::R
] = colors
->r
;
1068 p
[order_type::G
] = colors
->g
;
1069 p
[order_type::B
] = colors
->b
;
1070 p
[order_type::A
] = base_mask
;
1080 blender_type::copy_or_blend_opaque_pix(p
, *colors
++, cover
);
1089 //--------------------------------------------------------------------
1090 void blend_opaque_color_vspan(int x
, int y
,
1092 const color_type
* colors
,
1093 const int8u
* covers
,
1100 blender_type::copy_or_blend_opaque_pix((value_type
*)m_rbuf
->span_ptr(x
, y
++, 1),
1101 *colors
++, *covers
++);
1111 value_type
* p
= (value_type
*)m_rbuf
->span_ptr(x
, y
++, 1);
1112 p
[order_type::R
] = colors
->r
;
1113 p
[order_type::G
] = colors
->g
;
1114 p
[order_type::B
] = colors
->b
;
1115 p
[order_type::A
] = base_mask
;
1124 blender_type::copy_or_blend_opaque_pix((value_type
*)m_rbuf
->span_ptr(x
, y
++, 1),
1134 //--------------------------------------------------------------------
1135 template<class Function
> void for_each_pixel(Function f
)
1138 for(y
= 0; y
< height(); ++y
)
1140 row_data sp
= span(0, y
);
1143 value_type
* p
= (value_type
*)sp
.ptr
;
1144 while(sp
.x1
<= sp
.x2
)
1155 //--------------------------------------------------------------------
1158 for_each_pixel(multiplier_rgba
<color_type
, order_type
>::premultiply
);
1161 //--------------------------------------------------------------------
1164 for_each_pixel(multiplier_rgba
<color_type
, order_type
>::demultiply
);
1167 //--------------------------------------------------------------------
1168 template<class GammaLut
> void apply_gamma_dir(const GammaLut
& g
)
1170 for_each_pixel(apply_gamma_dir_rgba
<color_type
, order_type
, GammaLut
>(g
));
1173 //--------------------------------------------------------------------
1174 template<class GammaLut
> void apply_gamma_inv(const GammaLut
& g
)
1176 for_each_pixel(apply_gamma_inv_rgba
<color_type
, order_type
, GammaLut
>(g
));
1179 //--------------------------------------------------------------------
1180 template<class RenBuf2
> void copy_from(const RenBuf2
& from
,
1185 const int8u
* p
= from
.row(ysrc
);
1188 p
+= xsrc
* 4 * sizeof(value_type
);
1189 memmove(m_rbuf
->span_ptr(xdst
, ydst
, len
),
1191 len
* 4 * sizeof(value_type
));
1197 //--------------------------------------------------------------------
1198 template<class SrcPixelFormatRenderer
>
1199 void blend_from(const SrcPixelFormatRenderer
& from
,
1205 typedef typename
SrcPixelFormatRenderer::order_type src_order
;
1206 const value_type
* psrc
= (const value_type
*)psrc_
;
1207 value_type
* pdst
= (value_type
*)m_rbuf
->span_ptr(xdst
, ydst
, len
);
1212 psrc
+= (len
-1) << 2;
1213 pdst
+= (len
-1) << 2;
1218 value_type alpha
= psrc
[src_order::A
];
1222 if(alpha
== base_mask
)
1224 pdst
[order_type::R
] = psrc
[src_order::R
];
1225 pdst
[order_type::G
] = psrc
[src_order::G
];
1226 pdst
[order_type::B
] = psrc
[src_order::B
];
1227 pdst
[order_type::A
] = psrc
[src_order::A
];
1231 blender_type::blend_pix(pdst
,
1256 //-----------------------------------------------------------------------
1257 typedef blender_rgba
<rgba8
, order_rgba
, int32u
> blender_rgba32
; //----blender_rgba32
1258 typedef blender_rgba
<rgba8
, order_argb
, int32u
> blender_argb32
; //----blender_argb32
1259 typedef blender_rgba
<rgba8
, order_abgr
, int32u
> blender_abgr32
; //----blender_abgr32
1260 typedef blender_rgba
<rgba8
, order_bgra
, int32u
> blender_bgra32
; //----blender_bgra32
1262 typedef blender_rgba_pre
<rgba8
, order_rgba
, int32u
> blender_rgba32_pre
; //----blender_rgba32_pre
1263 typedef blender_rgba_pre
<rgba8
, order_argb
, int32u
> blender_argb32_pre
; //----blender_argb32_pre
1264 typedef blender_rgba_pre
<rgba8
, order_abgr
, int32u
> blender_abgr32_pre
; //----blender_abgr32_pre
1265 typedef blender_rgba_pre
<rgba8
, order_bgra
, int32u
> blender_bgra32_pre
; //----blender_bgra32_pre
1267 typedef blender_rgba_plain
<rgba8
, order_rgba
, int32u
> blender_rgba32_plain
; //----blender_rgba32_plain
1268 typedef blender_rgba_plain
<rgba8
, order_argb
, int32u
> blender_argb32_plain
; //----blender_argb32_plain
1269 typedef blender_rgba_plain
<rgba8
, order_abgr
, int32u
> blender_abgr32_plain
; //----blender_abgr32_plain
1270 typedef blender_rgba_plain
<rgba8
, order_bgra
, int32u
> blender_bgra32_plain
; //----blender_bgra32_plain
1272 struct pixel64_type
{ int16u c
[4]; };
1273 typedef blender_rgba
<rgba16
, order_rgba
, pixel64_type
> blender_rgba64
; //----blender_rgba64
1274 typedef blender_rgba
<rgba16
, order_argb
, pixel64_type
> blender_argb64
; //----blender_argb64
1275 typedef blender_rgba
<rgba16
, order_abgr
, pixel64_type
> blender_abgr64
; //----blender_abgr64
1276 typedef blender_rgba
<rgba16
, order_bgra
, pixel64_type
> blender_bgra64
; //----blender_bgra64
1278 typedef blender_rgba_pre
<rgba16
, order_rgba
, pixel64_type
> blender_rgba64_pre
; //----blender_rgba64_pre
1279 typedef blender_rgba_pre
<rgba16
, order_argb
, pixel64_type
> blender_argb64_pre
; //----blender_argb64_pre
1280 typedef blender_rgba_pre
<rgba16
, order_abgr
, pixel64_type
> blender_abgr64_pre
; //----blender_abgr64_pre
1281 typedef blender_rgba_pre
<rgba16
, order_bgra
, pixel64_type
> blender_bgra64_pre
; //----blender_bgra64_pre
1284 //-----------------------------------------------------------------------
1285 typedef pixel_formats_rgba
<blender_rgba32
> pixfmt_rgba32
; //----pixfmt_rgba32
1286 typedef pixel_formats_rgba
<blender_argb32
> pixfmt_argb32
; //----pixfmt_argb32
1287 typedef pixel_formats_rgba
<blender_abgr32
> pixfmt_abgr32
; //----pixfmt_abgr32
1288 typedef pixel_formats_rgba
<blender_bgra32
> pixfmt_bgra32
; //----pixfmt_bgra32
1290 typedef pixel_formats_rgba
<blender_rgba32_pre
> pixfmt_rgba32_pre
; //----pixfmt_rgba32_pre
1291 typedef pixel_formats_rgba
<blender_argb32_pre
> pixfmt_argb32_pre
; //----pixfmt_argb32_pre
1292 typedef pixel_formats_rgba
<blender_abgr32_pre
> pixfmt_abgr32_pre
; //----pixfmt_abgr32_pre
1293 typedef pixel_formats_rgba
<blender_bgra32_pre
> pixfmt_bgra32_pre
; //----pixfmt_bgra32_pre
1295 typedef pixel_formats_rgba
<blender_rgba32_plain
> pixfmt_rgba32_plain
; //----pixfmt_rgba32_plain
1296 typedef pixel_formats_rgba
<blender_argb32_plain
> pixfmt_argb32_plain
; //----pixfmt_argb32_plain
1297 typedef pixel_formats_rgba
<blender_abgr32_plain
> pixfmt_abgr32_plain
; //----pixfmt_abgr32_plain
1298 typedef pixel_formats_rgba
<blender_bgra32_plain
> pixfmt_bgra32_plain
; //----pixfmt_bgra32_plain
1300 typedef pixel_formats_rgba
<blender_rgba64
> pixfmt_rgba64
; //----pixfmt_rgba64
1301 typedef pixel_formats_rgba
<blender_argb64
> pixfmt_argb64
; //----pixfmt_argb64
1302 typedef pixel_formats_rgba
<blender_abgr64
> pixfmt_abgr64
; //----pixfmt_abgr64
1303 typedef pixel_formats_rgba
<blender_bgra64
> pixfmt_bgra64
; //----pixfmt_bgra64
1305 typedef pixel_formats_rgba
<blender_rgba64_pre
> pixfmt_rgba64_pre
; //----pixfmt_rgba64_pre
1306 typedef pixel_formats_rgba
<blender_argb64_pre
> pixfmt_argb64_pre
; //----pixfmt_argb64_pre
1307 typedef pixel_formats_rgba
<blender_abgr64_pre
> pixfmt_abgr64_pre
; //----pixfmt_abgr64_pre
1308 typedef pixel_formats_rgba
<blender_bgra64_pre
> pixfmt_bgra64_pre
; //----pixfmt_bgra64_pre