Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #ifndef AGG_RENDERING_BUFFER_INCLUDED 00026 #define AGG_RENDERING_BUFFER_INCLUDED 00027 00028 #include "agg_array.h" 00029 00030 namespace agg 00031 { 00032 00033 //===========================================================row_accessor 00034 template<class T> class row_accessor 00035 { 00036 public: 00037 typedef const_row_info<T> row_data; 00038 00039 //------------------------------------------------------------------- 00040 row_accessor() : 00041 m_buf(0), 00042 m_start(0), 00043 m_width(0), 00044 m_height(0), 00045 m_stride(0) 00046 { 00047 } 00048 00049 //-------------------------------------------------------------------- 00050 row_accessor(T* buf, unsigned width, unsigned height, int stride) : 00051 m_buf(0), 00052 m_start(0), 00053 m_width(0), 00054 m_height(0), 00055 m_stride(0) 00056 { 00057 attach(buf, width, height, stride); 00058 } 00059 00060 00061 //-------------------------------------------------------------------- 00062 void attach(T* buf, unsigned width, unsigned height, int stride) 00063 { 00064 m_buf = m_start = buf; 00065 m_width = width; 00066 m_height = height; 00067 m_stride = stride; 00068 if(stride < 0) 00069 { 00070 m_start = m_buf - int(height - 1) * stride; 00071 } 00072 } 00073 00074 //-------------------------------------------------------------------- 00075 AGG_INLINE T* buf() { return m_buf; } 00076 AGG_INLINE const T* buf() const { return m_buf; } 00077 AGG_INLINE unsigned width() const { return m_width; } 00078 AGG_INLINE unsigned height() const { return m_height; } 00079 AGG_INLINE int stride() const { return m_stride; } 00080 AGG_INLINE unsigned stride_abs() const 00081 { 00082 return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); 00083 } 00084 00085 //-------------------------------------------------------------------- 00086 AGG_INLINE T* row_ptr(int, int y, unsigned) 00087 { 00088 return m_start + y * m_stride; 00089 } 00090 AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; } 00091 AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; } 00092 AGG_INLINE row_data row (int y) const 00093 { 00094 return row_data(0, m_width-1, row_ptr(y)); 00095 } 00096 00097 //-------------------------------------------------------------------- 00098 template<class RenBuf> 00099 void copy_from(const RenBuf& src) 00100 { 00101 unsigned h = height(); 00102 if(src.height() < h) h = src.height(); 00103 00104 unsigned l = stride_abs(); 00105 if(src.stride_abs() < l) l = src.stride_abs(); 00106 00107 l *= sizeof(T); 00108 00109 unsigned y; 00110 unsigned w = width(); 00111 for (y = 0; y < h; y++) 00112 { 00113 memcpy(row_ptr(0, y, w), src.row_ptr(y), l); 00114 } 00115 } 00116 00117 //-------------------------------------------------------------------- 00118 void clear(T value) 00119 { 00120 unsigned y; 00121 unsigned w = width(); 00122 unsigned stride = stride_abs(); 00123 for(y = 0; y < height(); y++) 00124 { 00125 T* p = row_ptr(0, y, w); 00126 unsigned x; 00127 for(x = 0; x < stride; x++) 00128 { 00129 *p++ = value; 00130 } 00131 } 00132 } 00133 00134 private: 00135 //-------------------------------------------------------------------- 00136 T* m_buf; // Pointer to renrdering buffer 00137 T* m_start; // Pointer to first pixel depending on stride 00138 unsigned m_width; // Width in pixels 00139 unsigned m_height; // Height in pixels 00140 int m_stride; // Number of bytes per row. Can be < 0 00141 }; 00142 00143 00144 00145 00146 //==========================================================row_ptr_cache 00147 template<class T> class row_ptr_cache 00148 { 00149 public: 00150 typedef const_row_info<T> row_data; 00151 00152 //------------------------------------------------------------------- 00153 row_ptr_cache() : 00154 m_buf(0), 00155 m_rows(), 00156 m_width(0), 00157 m_height(0), 00158 m_stride(0) 00159 { 00160 } 00161 00162 //-------------------------------------------------------------------- 00163 row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) : 00164 m_buf(0), 00165 m_rows(), 00166 m_width(0), 00167 m_height(0), 00168 m_stride(0) 00169 { 00170 attach(buf, width, height, stride); 00171 } 00172 00173 //-------------------------------------------------------------------- 00174 void attach(T* buf, unsigned width, unsigned height, int stride) 00175 { 00176 m_buf = buf; 00177 m_width = width; 00178 m_height = height; 00179 m_stride = stride; 00180 if(height > m_rows.size()) 00181 { 00182 m_rows.resize(height); 00183 } 00184 00185 T* row_ptr = m_buf; 00186 00187 if(stride < 0) 00188 { 00189 row_ptr = m_buf - int(height - 1) * stride; 00190 } 00191 00192 T** rows = &m_rows[0]; 00193 00194 while(height--) 00195 { 00196 *rows++ = row_ptr; 00197 row_ptr += stride; 00198 } 00199 } 00200 00201 //-------------------------------------------------------------------- 00202 AGG_INLINE T* buf() { return m_buf; } 00203 AGG_INLINE const T* buf() const { return m_buf; } 00204 AGG_INLINE unsigned width() const { return m_width; } 00205 AGG_INLINE unsigned height() const { return m_height; } 00206 AGG_INLINE int stride() const { return m_stride; } 00207 AGG_INLINE unsigned stride_abs() const 00208 { 00209 return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); 00210 } 00211 00212 //-------------------------------------------------------------------- 00213 AGG_INLINE T* row_ptr(int, int y, unsigned) 00214 { 00215 return m_rows[y]; 00216 } 00217 AGG_INLINE T* row_ptr(int y) { return m_rows[y]; } 00218 AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; } 00219 AGG_INLINE row_data row (int y) const 00220 { 00221 return row_data(0, m_width-1, m_rows[y]); 00222 } 00223 00224 //-------------------------------------------------------------------- 00225 T const* const* rows() const { return &m_rows[0]; } 00226 00227 //-------------------------------------------------------------------- 00228 template<class RenBuf> 00229 void copy_from(const RenBuf& src) 00230 { 00231 unsigned h = height(); 00232 if(src.height() < h) h = src.height(); 00233 00234 unsigned l = stride_abs(); 00235 if(src.stride_abs() < l) l = src.stride_abs(); 00236 00237 l *= sizeof(T); 00238 00239 unsigned y; 00240 unsigned w = width(); 00241 for (y = 0; y < h; y++) 00242 { 00243 memcpy(row_ptr(0, y, w), src.row_ptr(y), l); 00244 } 00245 } 00246 00247 //-------------------------------------------------------------------- 00248 void clear(T value) 00249 { 00250 unsigned y; 00251 unsigned w = width(); 00252 unsigned stride = stride_abs(); 00253 for(y = 0; y < height(); y++) 00254 { 00255 T* p = row_ptr(0, y, w); 00256 unsigned x; 00257 for(x = 0; x < stride; x++) 00258 { 00259 *p++ = value; 00260 } 00261 } 00262 } 00263 00264 private: 00265 //-------------------------------------------------------------------- 00266 T* m_buf; // Pointer to renrdering buffer 00267 pod_array<T*> m_rows; // Pointers to each row of the buffer 00268 unsigned m_width; // Width in pixels 00269 unsigned m_height; // Height in pixels 00270 int m_stride; // Number of bytes per row. Can be < 0 00271 }; 00272 00273 00274 00275 00276 //========================================================rendering_buffer 00277 // 00278 // The definition of the main type for accessing the rows in the frame 00279 // buffer. It provides functionality to navigate to the rows in a 00280 // rectangular matrix, from top to bottom or from bottom to top depending 00281 // on stride. 00282 // 00283 // row_accessor is cheap to create/destroy, but performs one multiplication 00284 // when calling row_ptr(). 00285 // 00286 // row_ptr_cache creates an array of pointers to rows, so, the access 00287 // via row_ptr() may be faster. But it requires memory allocation 00288 // when creating. For example, on typical Intel Pentium hardware 00289 // row_ptr_cache speeds span_image_filter_rgb_nn up to 10% 00290 // 00291 // It's used only in short hand typedefs like pixfmt_rgba32 and can be 00292 // redefined in agg_config.h 00293 // In real applications you can use both, depending on your needs 00294 //------------------------------------------------------------------------ 00295 #ifdef AGG_RENDERING_BUFFER 00296 typedef AGG_RENDERING_BUFFER rendering_buffer; 00297 #else 00298 // typedef row_ptr_cache<int8u> rendering_buffer; 00299 typedef row_accessor<int8u> rendering_buffer; 00300 #endif 00301 00302 } 00303 00304 00305 #endif