Home | History | Annotate | Download | only in agg23
      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 (at) antigrain.com
     13 //          mcseemagg (at) 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 : public CFX_Object {
     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 : public CFX_Object
     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:
     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     }
     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:
     82     pixel_formats_gray(rendering_buffer& rb) :
     83         m_rbuf(&rb)
     84     {}
     85     AGG_INLINE unsigned width()  const
     86     {
     87         return m_rbuf->width();
     88     }
     89     AGG_INLINE unsigned height() const
     90     {
     91         return m_rbuf->height();
     92     }
     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     }
     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     }
    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     }
    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     }
    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     }
    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     }
    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     }
    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