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