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