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