1 
2 //----------------------------------------------------------------------------
3 // Anti-Grain Geometry - Version 2.3
4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 //
6 // Permission to copy, use, modify, sell and distribute this software
7 // is granted provided this copyright notice appears in all copies.
8 // This software is provided "as is" without express or implied
9 // warranty, and with no claim as to its suitability for any purpose.
10 //
11 //----------------------------------------------------------------------------
12 // Contact: mcseem@antigrain.com
13 //          mcseemagg@yahoo.com
14 //          http://www.antigrain.com
15 //----------------------------------------------------------------------------
16 //
17 // Adaptation for high precision colors has been sponsored by
18 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 //
20 // Liberty Technology Systems, Inc. is the provider of
21 // PostScript and PDF technology for software developers.
22 //
23 //----------------------------------------------------------------------------
24 #ifndef AGG_PIXFMT_GRAY_INCLUDED
25 #define AGG_PIXFMT_GRAY_INCLUDED
26 #include "agg_basics.h"
27 #include "agg_color_gray.h"
28 #include "agg_rendering_buffer.h"
29 namespace agg
30 {
31 template<class ColorT> struct blender_gray  {
32     typedef ColorT color_type;
33     typedef typename color_type::value_type value_type;
34     typedef typename color_type::calc_type calc_type;
35     enum base_scale_e { base_shift = color_type::base_shift };
36     static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
37                                      unsigned alpha, unsigned cover = 0)
38     {
39         *p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift);
40     }
41 };
42 template<class Blender, unsigned Step = 1, unsigned Offset = 0>
43 class pixel_formats_gray
44 {
45 public:
46     typedef rendering_buffer::row_data row_data;
47     typedef rendering_buffer::span_data span_data;
48     typedef typename Blender::color_type color_type;
49     typedef typename color_type::value_type value_type;
50     typedef typename color_type::calc_type calc_type;
51     enum base_scale_e {
52         base_shift = color_type::base_shift,
53         base_size  = color_type::base_size,
54         base_mask  = color_type::base_mask
55     };
56 private:
copy_or_blend_pix(value_type * p,const color_type & c,unsigned cover)57     static AGG_INLINE void copy_or_blend_pix(value_type* p,
58             const color_type& c,
59             unsigned cover)
60     {
61         if (c.a) {
62             calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
63             if(alpha == base_mask) {
64                 *p = c.v;
65             } else {
66                 Blender::blend_pix(p, c.v, alpha, cover);
67             }
68         }
69     }
copy_or_blend_pix(value_type * p,const color_type & c)70     static AGG_INLINE void copy_or_blend_pix(value_type* p,
71             const color_type& c)
72     {
73         if (c.a) {
74             if(c.a == base_mask) {
75                 *p = c.v;
76             } else {
77                 Blender::blend_pix(p, c.v, c.a);
78             }
79         }
80     }
81 public:
pixel_formats_gray(rendering_buffer & rb)82     pixel_formats_gray(rendering_buffer& rb) :
83         m_rbuf(&rb)
84     {}
width()85     AGG_INLINE unsigned width()  const
86     {
87         return m_rbuf->width();
88     }
height()89     AGG_INLINE unsigned height() const
90     {
91         return m_rbuf->height();
92     }
pixel(int x,int y)93     AGG_INLINE color_type pixel(int x, int y) const
94     {
95         value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
96         return color_type(*p);
97     }
row(int x,int y)98     row_data row(int x, int y) const
99     {
100         return row_data(x,
101                         width() - 1,
102                         m_rbuf->row(y) +
103                         x * Step * sizeof(value_type) +
104                         Offset * sizeof(value_type));
105     }
span(int x,int y,unsigned len)106     span_data span(int x, int y, unsigned len)
107     {
108         return span_data(x, len,
109                          m_rbuf->row(y) +
110                          x * Step * sizeof(value_type) +
111                          Offset * sizeof(value_type));
112     }
copy_pixel(int x,int y,const color_type & c)113     AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
114     {
115         *((value_type*)m_rbuf->row(y) + x * Step + Offset) = c.v;
116     }
blend_pixel(int x,int y,const color_type & c,int8u cover)117     AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
118     {
119         copy_or_blend_pix((value_type*)m_rbuf->row(y) + x * Step + Offset, c, cover);
120     }
copy_hline(int x,int y,unsigned len,const color_type & c)121     AGG_INLINE void copy_hline(int x, int y,
122                                unsigned len,
123                                const color_type& c)
124     {
125         value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
126         do {
127             *p = c.v;
128             p += Step;
129         } while(--len);
130     }
blend_hline(int x,int y,unsigned len,const color_type & c,int8u cover)131     void blend_hline(int x, int y,
132                      unsigned len,
133                      const color_type& c,
134                      int8u cover)
135     {
136         if (c.a) {
137             value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
138             calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
139             if(alpha == base_mask) {
140                 do {
141                     *p = c.v;
142                     p += Step;
143                 } while(--len);
144             } else {
145                 do {
146                     Blender::blend_pix(p, c.v, alpha, cover);
147                     p += Step;
148                 } while(--len);
149             }
150         }
151     }
blend_solid_hspan(int x,int y,unsigned len,const color_type & c,const int8u * covers)152     void blend_solid_hspan(int x, int y,
153                            unsigned len,
154                            const color_type& c,
155                            const int8u* covers)
156     {
157         if (c.a) {
158             value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
159             do {
160                 calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
161                 if(alpha == base_mask) {
162                     *p = c.v;
163                 } else {
164                     Blender::blend_pix(p, c.v, alpha, *covers);
165                 }
166                 p += Step;
167                 ++covers;
168             } while(--len);
169         }
170     }
171 private:
172     rendering_buffer* m_rbuf;
173 };
174 typedef blender_gray<gray8>      blender_gray8;
175 typedef pixel_formats_gray<blender_gray8, 1, 0> pixfmt_gray8;
176 }
177 #endif
178