xref: /haiku/headers/libs/agg/agg_renderer_raster_text.h (revision f2b4344867e97c3f4e742a1b4a15e6879644601a)
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 
21 namespace 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