1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry (AGG) - Version 2.5 3 // A high quality rendering engine for C++ 4 // Copyright (C) 2002-2006 Maxim Shemanarev 5 // Contact: mcseem@antigrain.com 6 // mcseemagg@yahoo.com 7 // http://antigrain.com 8 // 9 // AGG is free software; you can redistribute it and/or 10 // modify it under the terms of the GNU General Public License 11 // as published by the Free Software Foundation; either version 2 12 // of the License, or (at your option) any later version. 13 // 14 // AGG is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with AGG; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 22 // MA 02110-1301, USA. 23 //---------------------------------------------------------------------------- 24 25 #ifndef AGG_RENDERING_BUFFER_INCLUDED 26 #define AGG_RENDERING_BUFFER_INCLUDED 27 28 #include "agg_array.h" 29 30 namespace agg 31 { 32 33 //===========================================================row_accessor 34 template<class T> class row_accessor 35 { 36 public: 37 typedef const_row_info<T> row_data; 38 39 //------------------------------------------------------------------- row_accessor()40 row_accessor() : 41 m_buf(0), 42 m_start(0), 43 m_width(0), 44 m_height(0), 45 m_stride(0) 46 { 47 } 48 49 //-------------------------------------------------------------------- row_accessor(T * buf,unsigned width,unsigned height,int stride)50 row_accessor(T* buf, unsigned width, unsigned height, int stride) : 51 m_buf(0), 52 m_start(0), 53 m_width(0), 54 m_height(0), 55 m_stride(0) 56 { 57 attach(buf, width, height, stride); 58 } 59 60 61 //-------------------------------------------------------------------- attach(T * buf,unsigned width,unsigned height,int stride)62 void attach(T* buf, unsigned width, unsigned height, int stride) 63 { 64 m_buf = m_start = buf; 65 m_width = width; 66 m_height = height; 67 m_stride = stride; 68 if(stride < 0) 69 { 70 m_start = m_buf - int(height - 1) * stride; 71 } 72 } 73 74 //-------------------------------------------------------------------- buf()75 AGG_INLINE T* buf() { return m_buf; } buf()76 AGG_INLINE const T* buf() const { return m_buf; } width()77 AGG_INLINE unsigned width() const { return m_width; } height()78 AGG_INLINE unsigned height() const { return m_height; } stride()79 AGG_INLINE int stride() const { return m_stride; } stride_abs()80 AGG_INLINE unsigned stride_abs() const 81 { 82 return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); 83 } 84 85 //-------------------------------------------------------------------- row_ptr(int,int y,unsigned)86 AGG_INLINE T* row_ptr(int, int y, unsigned) 87 { 88 return m_start + y * m_stride; 89 } row_ptr(int y)90 AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; } row_ptr(int y)91 AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; } row(int y)92 AGG_INLINE row_data row (int y) const 93 { 94 return row_data(0, m_width-1, row_ptr(y)); 95 } 96 97 //-------------------------------------------------------------------- 98 template<class RenBuf> copy_from(const RenBuf & src)99 void copy_from(const RenBuf& src) 100 { 101 unsigned h = height(); 102 if(src.height() < h) h = src.height(); 103 104 unsigned l = stride_abs(); 105 if(src.stride_abs() < l) l = src.stride_abs(); 106 107 l *= sizeof(T); 108 109 unsigned y; 110 unsigned w = width(); 111 for (y = 0; y < h; y++) 112 { 113 memcpy(row_ptr(0, y, w), src.row_ptr(y), l); 114 } 115 } 116 117 //-------------------------------------------------------------------- clear(T value)118 void clear(T value) 119 { 120 unsigned y; 121 unsigned w = width(); 122 unsigned stride = stride_abs(); 123 for(y = 0; y < height(); y++) 124 { 125 T* p = row_ptr(0, y, w); 126 unsigned x; 127 for(x = 0; x < stride; x++) 128 { 129 *p++ = value; 130 } 131 } 132 } 133 134 private: 135 //-------------------------------------------------------------------- 136 T* m_buf; // Pointer to renrdering buffer 137 T* m_start; // Pointer to first pixel depending on stride 138 unsigned m_width; // Width in pixels 139 unsigned m_height; // Height in pixels 140 int m_stride; // Number of bytes per row. Can be < 0 141 }; 142 143 144 145 146 //==========================================================row_ptr_cache 147 template<class T> class row_ptr_cache 148 { 149 public: 150 typedef const_row_info<T> row_data; 151 152 //------------------------------------------------------------------- row_ptr_cache()153 row_ptr_cache() : 154 m_buf(0), 155 m_rows(), 156 m_width(0), 157 m_height(0), 158 m_stride(0) 159 { 160 } 161 162 //-------------------------------------------------------------------- row_ptr_cache(T * buf,unsigned width,unsigned height,int stride)163 row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) : 164 m_buf(0), 165 m_rows(), 166 m_width(0), 167 m_height(0), 168 m_stride(0) 169 { 170 attach(buf, width, height, stride); 171 } 172 173 //-------------------------------------------------------------------- attach(T * buf,unsigned width,unsigned height,int stride)174 void attach(T* buf, unsigned width, unsigned height, int stride) 175 { 176 m_buf = buf; 177 m_width = width; 178 m_height = height; 179 m_stride = stride; 180 if(height > m_rows.size()) 181 { 182 m_rows.resize(height); 183 } 184 185 T* row_ptr = m_buf; 186 187 if(stride < 0) 188 { 189 row_ptr = m_buf - int(height - 1) * stride; 190 } 191 192 T** rows = &m_rows[0]; 193 194 while(height--) 195 { 196 *rows++ = row_ptr; 197 row_ptr += stride; 198 } 199 } 200 201 //-------------------------------------------------------------------- buf()202 AGG_INLINE T* buf() { return m_buf; } buf()203 AGG_INLINE const T* buf() const { return m_buf; } width()204 AGG_INLINE unsigned width() const { return m_width; } height()205 AGG_INLINE unsigned height() const { return m_height; } stride()206 AGG_INLINE int stride() const { return m_stride; } stride_abs()207 AGG_INLINE unsigned stride_abs() const 208 { 209 return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); 210 } 211 212 //-------------------------------------------------------------------- row_ptr(int,int y,unsigned)213 AGG_INLINE T* row_ptr(int, int y, unsigned) 214 { 215 return m_rows[y]; 216 } row_ptr(int y)217 AGG_INLINE T* row_ptr(int y) { return m_rows[y]; } row_ptr(int y)218 AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; } row(int y)219 AGG_INLINE row_data row (int y) const 220 { 221 return row_data(0, m_width-1, m_rows[y]); 222 } 223 224 //-------------------------------------------------------------------- rows()225 T const* const* rows() const { return &m_rows[0]; } 226 227 //-------------------------------------------------------------------- 228 template<class RenBuf> copy_from(const RenBuf & src)229 void copy_from(const RenBuf& src) 230 { 231 unsigned h = height(); 232 if(src.height() < h) h = src.height(); 233 234 unsigned l = stride_abs(); 235 if(src.stride_abs() < l) l = src.stride_abs(); 236 237 l *= sizeof(T); 238 239 unsigned y; 240 unsigned w = width(); 241 for (y = 0; y < h; y++) 242 { 243 memcpy(row_ptr(0, y, w), src.row_ptr(y), l); 244 } 245 } 246 247 //-------------------------------------------------------------------- clear(T value)248 void clear(T value) 249 { 250 unsigned y; 251 unsigned w = width(); 252 unsigned stride = stride_abs(); 253 for(y = 0; y < height(); y++) 254 { 255 T* p = row_ptr(0, y, w); 256 unsigned x; 257 for(x = 0; x < stride; x++) 258 { 259 *p++ = value; 260 } 261 } 262 } 263 264 private: 265 //-------------------------------------------------------------------- 266 T* m_buf; // Pointer to renrdering buffer 267 pod_array<T*> m_rows; // Pointers to each row of the buffer 268 unsigned m_width; // Width in pixels 269 unsigned m_height; // Height in pixels 270 int m_stride; // Number of bytes per row. Can be < 0 271 }; 272 273 274 275 276 //========================================================rendering_buffer 277 // 278 // The definition of the main type for accessing the rows in the frame 279 // buffer. It provides functionality to navigate to the rows in a 280 // rectangular matrix, from top to bottom or from bottom to top depending 281 // on stride. 282 // 283 // row_accessor is cheap to create/destroy, but performs one multiplication 284 // when calling row_ptr(). 285 // 286 // row_ptr_cache creates an array of pointers to rows, so, the access 287 // via row_ptr() may be faster. But it requires memory allocation 288 // when creating. For example, on typical Intel Pentium hardware 289 // row_ptr_cache speeds span_image_filter_rgb_nn up to 10% 290 // 291 // It's used only in short hand typedefs like pixfmt_rgba32 and can be 292 // redefined in agg_config.h 293 // In real applications you can use both, depending on your needs 294 //------------------------------------------------------------------------ 295 #ifdef AGG_RENDERING_BUFFER 296 typedef AGG_RENDERING_BUFFER rendering_buffer; 297 #else 298 // typedef row_ptr_cache<int8u> rendering_buffer; 299 typedef row_accessor<int8u> rendering_buffer; 300 #endif 301 302 } 303 304 305 #endif 306