1//----------------------------------------------------------------------------
2// Anti-Grain Geometry - Version 2.4
3// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4//
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.
9//
10//----------------------------------------------------------------------------
11// Contact: mcseem@antigrain.com
12//          mcseemagg@yahoo.com
13//          http://www.antigrain.com
14//----------------------------------------------------------------------------
15
16#ifndef AGG_RENDERER_RASTER_TEXT_INCLUDED
17#define AGG_RENDERER_RASTER_TEXT_INCLUDED
18
19#include "agg_basics.h"
20
21namespace agg
22{
23
24    //==============================================renderer_raster_htext_solid
25    template<class BaseRenderer, class GlyphGenerator>
26    class renderer_raster_htext_solid
27    {
28    public:
29        typedef BaseRenderer ren_type;
30        typedef GlyphGenerator glyph_gen_type;
31        typedef typename glyph_gen_type::glyph_rect glyph_rect;
32        typedef typename ren_type::color_type color_type;
33
34        renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) :
35            m_ren(&ren),
36            m_glyph(&glyph)
37        {}
38        void attach(ren_type& ren) { m_ren = &ren; }
39
40        //--------------------------------------------------------------------
41        void color(const color_type& c) { m_color = c; }
42        const color_type& color() const { return m_color; }
43
44        //--------------------------------------------------------------------
45        template<class CharT>
46        void render_text(double x, double y, const CharT* str, bool flip=false)
47        {
48            glyph_rect r;
49            while(*str)
50            {
51                m_glyph->prepare(&r, x, y, *str, flip);
52                if(r.x2 >= r.x1)
53                {
54                    int i;
55                    if(flip)
56                    {
57                        for(i = r.y1; i <= r.y2; i++)
58                        {
59                            m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
60                                                     m_color,
61                                                     m_glyph->span(r.y2 - i));
62                        }
63                    }
64                    else
65                    {
66                        for(i = r.y1; i <= r.y2; i++)
67                        {
68                            m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
69                                                     m_color,
70                                                     m_glyph->span(i - r.y1));
71                        }
72                    }
73                }
74                x += r.dx;
75                y += r.dy;
76                ++str;
77            }
78        }
79
80    private:
81        ren_type* m_ren;
82        glyph_gen_type* m_glyph;
83        color_type m_color;
84    };
85
86
87
88    //=============================================renderer_raster_vtext_solid
89    template<class BaseRenderer, class GlyphGenerator>
90    class renderer_raster_vtext_solid
91    {
92    public:
93        typedef BaseRenderer ren_type;
94        typedef GlyphGenerator glyph_gen_type;
95        typedef typename glyph_gen_type::glyph_rect glyph_rect;
96        typedef typename ren_type::color_type color_type;
97
98        renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph) :
99            m_ren(&ren),
100            m_glyph(&glyph)
101        {
102        }
103
104        //--------------------------------------------------------------------
105        void color(const color_type& c) { m_color = c; }
106        const color_type& color() const { return m_color; }
107
108        //--------------------------------------------------------------------
109        template<class CharT>
110        void render_text(double x, double y, const CharT* str, bool flip=false)
111        {
112            glyph_rect r;
113            while(*str)
114            {
115                m_glyph->prepare(&r, x, y, *str, !flip);
116                if(r.x2 >= r.x1)
117                {
118                    int i;
119                    if(flip)
120                    {
121                        for(i = r.y1; i <= r.y2; i++)
122                        {
123                            m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
124                                                     m_color,
125                                                     m_glyph->span(i - r.y1));
126                        }
127                    }
128                    else
129                    {
130                        for(i = r.y1; i <= r.y2; i++)
131                        {
132                            m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
133                                                     m_color,
134                                                     m_glyph->span(r.y2 - i));
135                        }
136                    }
137                }
138                x += r.dx;
139                y += r.dy;
140                ++str;
141            }
142        }
143
144    private:
145        ren_type* m_ren;
146        glyph_gen_type* m_glyph;
147        color_type m_color;
148    };
149
150
151
152
153
154
155    //===================================================renderer_raster_htext
156    template<class ScanlineRenderer, class GlyphGenerator>
157    class renderer_raster_htext
158    {
159    public:
160        typedef ScanlineRenderer ren_type;
161        typedef GlyphGenerator glyph_gen_type;
162        typedef typename glyph_gen_type::glyph_rect glyph_rect;
163
164        class scanline_single_span
165        {
166        public:
167            typedef agg::cover_type cover_type;
168
169            //----------------------------------------------------------------
170            struct const_span
171            {
172                int x;
173                unsigned len;
174                const cover_type* covers;
175
176                const_span() {}
177                const_span(int x_, unsigned len_, const cover_type* covers_) :
178                    x(x_), len(len_), covers(covers_)
179                {}
180            };
181
182            typedef const const_span* const_iterator;
183
184            //----------------------------------------------------------------
185            scanline_single_span(int x, int y, unsigned len,
186                                 const cover_type* covers) :
187                m_y(y),
188                m_span(x, len, covers)
189            {}
190
191            //----------------------------------------------------------------
192            int      y()           const { return m_y; }
193            unsigned num_spans()   const { return 1;   }
194            const_iterator begin() const { return &m_span; }
195
196        private:
197            //----------------------------------------------------------------
198            int m_y;
199            const_span m_span;
200        };
201
202
203
204        //--------------------------------------------------------------------
205        renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) :
206            m_ren(&ren),
207            m_glyph(&glyph)
208        {
209        }
210
211
212        //--------------------------------------------------------------------
213        template<class CharT>
214        void render_text(double x, double y, const CharT* str, bool flip=false)
215        {
216            glyph_rect r;
217            while(*str)
218            {
219                m_glyph->prepare(&r, x, y, *str, flip);
220                if(r.x2 >= r.x1)
221                {
222                    m_ren->prepare();
223                    int i;
224                    if(flip)
225                    {
226                        for(i = r.y1; i <= r.y2; i++)
227                        {
228                            m_ren->render(
229                                scanline_single_span(r.x1,
230                                                     i,
231                                                     (r.x2 - r.x1 + 1),
232                                                     m_glyph->span(r.y2 - i)));
233                        }
234                    }
235                    else
236                    {
237                        for(i = r.y1; i <= r.y2; i++)
238                        {
239                            m_ren->render(
240                                scanline_single_span(r.x1,
241                                                     i,
242                                                     (r.x2 - r.x1 + 1),
243                                                     m_glyph->span(i - r.y1)));
244                        }
245                    }
246                }
247                x += r.dx;
248                y += r.dy;
249                ++str;
250            }
251        }
252
253    private:
254        ren_type* m_ren;
255        glyph_gen_type* m_glyph;
256    };
257
258
259
260
261}
262
263#endif
264
265