1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
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_GRAY_INCLUDED
25 #define AGG_PIXFMT_GRAY_INCLUDED
28 #include "agg_basics.h"
29 #include "agg_color_gray.h"
30 #include "agg_rendering_buffer.h"
35 //============================================================blender_gray
36 template<class ColorT
> struct blender_gray
38 typedef ColorT color_type
;
39 typedef typename
color_type::value_type value_type
;
40 typedef typename
color_type::calc_type calc_type
;
41 enum base_scale_e
{ base_shift
= color_type::base_shift
};
43 static AGG_INLINE
void blend_pix(value_type
* p
, unsigned cv
,
44 unsigned alpha
, unsigned cover
=0)
46 *p
= (value_type
)((((cv
- calc_type(*p
)) * alpha
) + (calc_type(*p
) << base_shift
)) >> base_shift
);
51 //======================================================blender_gray_pre
52 template<class ColorT
> struct blender_gray_pre
54 typedef ColorT color_type
;
55 typedef typename
color_type::value_type value_type
;
56 typedef typename
color_type::calc_type calc_type
;
57 enum base_scale_e
{ base_shift
= color_type::base_shift
};
59 static AGG_INLINE
void blend_pix(value_type
* p
, unsigned cv
,
60 unsigned alpha
, unsigned cover
)
62 alpha
= color_type::base_mask
- alpha
;
63 cover
= (cover
+ 1) << (base_shift
- 8);
64 *p
= (value_type
)((*p
* alpha
+ cv
* cover
) >> base_shift
);
67 static AGG_INLINE
void blend_pix(value_type
* p
, unsigned cv
,
70 *p
= (value_type
)(((*p
* (color_type::base_mask
- alpha
)) >> base_shift
) + cv
);
76 //=====================================================apply_gamma_dir_gray
77 template<class ColorT
, class GammaLut
> class apply_gamma_dir_gray
80 typedef typename
ColorT::value_type value_type
;
82 apply_gamma_dir_gray(const GammaLut
& gamma
) : m_gamma(gamma
) {}
84 AGG_INLINE
void operator () (value_type
* p
)
90 const GammaLut
& m_gamma
;
95 //=====================================================apply_gamma_inv_gray
96 template<class ColorT
, class GammaLut
> class apply_gamma_inv_gray
99 typedef typename
ColorT::value_type value_type
;
101 apply_gamma_inv_gray(const GammaLut
& gamma
) : m_gamma(gamma
) {}
103 AGG_INLINE
void operator () (value_type
* p
)
105 *p
= m_gamma
.inv(*p
);
109 const GammaLut
& m_gamma
;
114 //=================================================pixfmt_alpha_blend_gray
115 template<class Blender
, class RenBuf
, unsigned Step
=1, unsigned Offset
=0>
116 class pixfmt_alpha_blend_gray
119 typedef RenBuf rbuf_type
;
120 typedef typename
rbuf_type::row_data row_data
;
121 typedef Blender blender_type
;
122 typedef typename
blender_type::color_type color_type
;
123 typedef int order_type
; // A fake one
124 typedef typename
color_type::value_type value_type
;
125 typedef typename
color_type::calc_type calc_type
;
128 base_shift
= color_type::base_shift
,
129 base_scale
= color_type::base_scale
,
130 base_mask
= color_type::base_mask
,
131 pix_width
= sizeof(value_type
),
137 //--------------------------------------------------------------------
138 static AGG_INLINE
void copy_or_blend_pix(value_type
* p
,
144 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
145 if(alpha
== base_mask
)
151 Blender::blend_pix(p
, c
.v
, alpha
, cover
);
157 static AGG_INLINE
void copy_or_blend_pix(value_type
* p
,
168 Blender::blend_pix(p
, c
.v
, c
.a
);
175 //--------------------------------------------------------------------
176 pixfmt_alpha_blend_gray(rbuf_type
& rb
) :
179 void attach(rbuf_type
& rb
) { m_rbuf
= &rb
; }
180 //--------------------------------------------------------------------
182 template<class PixFmt
>
183 bool attach(PixFmt
& pixf
, int x1
, int y1
, int x2
, int y2
)
185 rect_i
r(x1
, y1
, x2
, y2
);
186 if(r
.clip(rect_i(0, 0, pixf
.width()-1, pixf
.height()-1)))
188 int stride
= pixf
.stride();
189 m_rbuf
->attach(pixf
.pix_ptr(r
.x1
, stride
< 0 ? r
.y2
: r
.y1
),
198 //--------------------------------------------------------------------
199 AGG_INLINE
unsigned width() const { return m_rbuf
->width(); }
200 AGG_INLINE
unsigned height() const { return m_rbuf
->height(); }
201 AGG_INLINE
int stride() const { return m_rbuf
->stride(); }
203 //--------------------------------------------------------------------
204 int8u
* row_ptr(int y
) { return m_rbuf
->row_ptr(y
); }
205 const int8u
* row_ptr(int y
) const { return m_rbuf
->row_ptr(y
); }
206 row_data
row(int y
) const { return m_rbuf
->row(y
); }
208 const int8u
* pix_ptr(int x
, int y
) const
210 return m_rbuf
->row_ptr(y
) + x
* Step
+ Offset
;
213 int8u
* pix_ptr(int x
, int y
)
215 return m_rbuf
->row_ptr(y
) + x
* Step
+ Offset
;
218 //--------------------------------------------------------------------
219 AGG_INLINE
static void make_pix(int8u
* p
, const color_type
& c
)
221 *(value_type
*)p
= c
.v
;
224 //--------------------------------------------------------------------
225 AGG_INLINE color_type
pixel(int x
, int y
) const
227 value_type
* p
= (value_type
*)m_rbuf
->row_ptr(y
) + x
* Step
+ Offset
;
228 return color_type(*p
);
231 //--------------------------------------------------------------------
232 AGG_INLINE
void copy_pixel(int x
, int y
, const color_type
& c
)
234 *((value_type
*)m_rbuf
->row_ptr(x
, y
, 1) + x
* Step
+ Offset
) = c
.v
;
237 //--------------------------------------------------------------------
238 AGG_INLINE
void blend_pixel(int x
, int y
, const color_type
& c
, int8u cover
)
240 copy_or_blend_pix((value_type
*)
241 m_rbuf
->row_ptr(x
, y
, 1) + x
* Step
+ Offset
,
247 //--------------------------------------------------------------------
248 AGG_INLINE
void copy_hline(int x
, int y
,
252 value_type
* p
= (value_type
*)
253 m_rbuf
->row_ptr(x
, y
, len
) + x
* Step
+ Offset
;
264 //--------------------------------------------------------------------
265 AGG_INLINE
void copy_vline(int x
, int y
,
271 value_type
* p
= (value_type
*)
272 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
280 //--------------------------------------------------------------------
281 void blend_hline(int x
, int y
,
288 value_type
* p
= (value_type
*)
289 m_rbuf
->row_ptr(x
, y
, len
) + x
* Step
+ Offset
;
291 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
292 if(alpha
== base_mask
)
305 Blender::blend_pix(p
, c
.v
, alpha
, cover
);
314 //--------------------------------------------------------------------
315 void blend_vline(int x
, int y
,
323 calc_type alpha
= (calc_type(c
.a
) * (cover
+ 1)) >> 8;
324 if(alpha
== base_mask
)
329 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
340 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
342 Blender::blend_pix(p
, c
.v
, alpha
, cover
);
350 //--------------------------------------------------------------------
351 void blend_solid_hspan(int x
, int y
,
358 value_type
* p
= (value_type
*)
359 m_rbuf
->row_ptr(x
, y
, len
) + x
* Step
+ Offset
;
363 calc_type alpha
= (calc_type(c
.a
) * (calc_type(*covers
) + 1)) >> 8;
364 if(alpha
== base_mask
)
370 Blender::blend_pix(p
, c
.v
, alpha
, *covers
);
380 //--------------------------------------------------------------------
381 void blend_solid_vspan(int x
, int y
,
390 calc_type alpha
= (calc_type(c
.a
) * (calc_type(*covers
) + 1)) >> 8;
392 value_type
* p
= (value_type
*)
393 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
395 if(alpha
== base_mask
)
401 Blender::blend_pix(p
, c
.v
, alpha
, *covers
);
410 //--------------------------------------------------------------------
411 void copy_color_hspan(int x
, int y
,
413 const color_type
* colors
)
415 value_type
* p
= (value_type
*)
416 m_rbuf
->row_ptr(x
, y
, len
) + x
* Step
+ Offset
;
428 //--------------------------------------------------------------------
429 void copy_color_vspan(int x
, int y
,
431 const color_type
* colors
)
435 value_type
* p
= (value_type
*)
436 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
444 //--------------------------------------------------------------------
445 void blend_color_hspan(int x
, int y
,
447 const color_type
* colors
,
451 value_type
* p
= (value_type
*)
452 m_rbuf
->row_ptr(x
, y
, len
) + x
* Step
+ Offset
;
458 copy_or_blend_pix(p
, *colors
++, *covers
++);
469 if(colors
->a
== base_mask
)
475 copy_or_blend_pix(p
, *colors
);
486 copy_or_blend_pix(p
, *colors
++, cover
);
496 //--------------------------------------------------------------------
497 void blend_color_vspan(int x
, int y
,
499 const color_type
* colors
,
509 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
511 copy_or_blend_pix(p
, *colors
++, *covers
++);
522 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
524 if(colors
->a
== base_mask
)
530 copy_or_blend_pix(p
, *colors
);
541 m_rbuf
->row_ptr(x
, y
++, 1) + x
* Step
+ Offset
;
543 copy_or_blend_pix(p
, *colors
++, cover
);
550 //--------------------------------------------------------------------
551 template<class Function
> void for_each_pixel(Function f
)
554 for(y
= 0; y
< height(); ++y
)
556 row_data r
= m_rbuf
->row(y
);
559 unsigned len
= r
.x2
- r
.x1
+ 1;
561 value_type
* p
= (value_type
*)
562 m_rbuf
->row_ptr(r
.x1
, y
, len
) + r
.x1
* Step
+ Offset
;
574 //--------------------------------------------------------------------
575 template<class GammaLut
> void apply_gamma_dir(const GammaLut
& g
)
577 for_each_pixel(apply_gamma_dir_gray
<color_type
, GammaLut
>(g
));
580 //--------------------------------------------------------------------
581 template<class GammaLut
> void apply_gamma_inv(const GammaLut
& g
)
583 for_each_pixel(apply_gamma_inv_gray
<color_type
, GammaLut
>(g
));
586 //--------------------------------------------------------------------
587 template<class RenBuf2
>
588 void copy_from(const RenBuf2
& from
,
593 const int8u
* p
= from
.row_ptr(ysrc
);
596 memmove(m_rbuf
->row_ptr(xdst
, ydst
, len
) + xdst
* pix_width
,
597 p
+ xsrc
* pix_width
,
606 typedef blender_gray
<gray8
> blender_gray8
;
607 typedef blender_gray_pre
<gray8
> blender_gray8_pre
;
608 typedef blender_gray
<gray16
> blender_gray16
;
609 typedef blender_gray_pre
<gray16
> blender_gray16_pre
;
611 typedef pixfmt_alpha_blend_gray
<blender_gray8
, rendering_buffer
> pixfmt_gray8
; //----pixfmt_gray8
612 typedef pixfmt_alpha_blend_gray
<blender_gray8_pre
, rendering_buffer
> pixfmt_gray8_pre
; //----pixfmt_gray8_pre
613 typedef pixfmt_alpha_blend_gray
<blender_gray16
, rendering_buffer
> pixfmt_gray16
; //----pixfmt_gray16
614 typedef pixfmt_alpha_blend_gray
<blender_gray16_pre
, rendering_buffer
> pixfmt_gray16_pre
; //----pixfmt_gray16_pre