1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.2 3 // Copyright (C) 2002-2004 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 // class rendering_buffer_dynarow 17 // 18 //---------------------------------------------------------------------------- 19 20 #ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED 21 #define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED 22 23 #include "agg_basics.h" 24 25 namespace agg 26 { 27 28 //===============================================rendering_buffer_dynarow 29 // Rendering buffer class with dynamic allocation of the rows. 30 // The rows are allocated as needed when requesting for span_ptr(). 31 // The class automatically calculates min_x and max_x for each row. 32 // Generally it's more efficient to use this class as a temporary buffer 33 // for rendering a few lines and then to blend it with another buffer. 34 // 35 template<unsigned PixWidth> class rendering_buffer_dynarow 36 { 37 public: 38 //------------------------------------------------------------------- 39 struct row_data 40 { 41 int8u* ptr; 42 int x1; 43 int x2; 44 }; 45 46 //------------------------------------------------------------------- 47 ~rendering_buffer_dynarow() 48 { 49 init(0,0); 50 } 51 52 //------------------------------------------------------------------- 53 rendering_buffer_dynarow() : 54 m_rows(0), 55 m_width(0), 56 m_height(0) 57 { 58 } 59 60 // Allocate and clear the buffer 61 //-------------------------------------------------------------------- 62 rendering_buffer_dynarow(unsigned width, unsigned height) : 63 m_rows(new row_data[height]), 64 m_width(width), 65 m_height(height) 66 { 67 memset(m_rows, 0, sizeof(row_data) * height); 68 } 69 70 // Allocate and clear the buffer 71 //-------------------------------------------------------------------- 72 void init(unsigned width, unsigned height) 73 { 74 unsigned i; 75 for(i = 0; i < m_height; ++i) delete [] m_rows[i].ptr; 76 delete [] m_rows; 77 m_rows = 0; 78 if(width && height) 79 { 80 m_width = width; 81 m_height = height; 82 m_rows = new row_data[height]; 83 memset(m_rows, 0, sizeof(row_data) * height); 84 } 85 } 86 87 //-------------------------------------------------------------------- 88 unsigned width() const { return m_width; } 89 unsigned height() const { return m_height; } 90 91 // Get pointer to the beginning of the row. Memory for the row 92 // is allocated as needed. 93 //-------------------------------------------------------------------- 94 int8u* row(int y) 95 { 96 row_data* r = m_rows + y; 97 if(r->ptr == 0) 98 { 99 r->ptr = new int8u [m_width * PixWidth]; 100 memset(r->ptr, 0, m_width * PixWidth); 101 } 102 return r->ptr; 103 } 104 105 // Get const pointer to the row. The caller must check it for null. 106 //-------------------------------------------------------------------- 107 const int8u* row(int y) const 108 { 109 return m_rows[y].ptr; 110 } 111 112 // Get the Y-th span. The pointer r.ptr is automatically adjusted 113 // to the actual beginning of the span. Use this function as follows: 114 // 115 // rendering_buffer_dynarow::row_data r = rbuf.span(x, y); 116 // if(r.ptr) 117 // { 118 // do { blend(r.ptr); r.ptr += PixWidth } while(++r.x1 < r.x2); 119 // } 120 //-------------------------------------------------------------------- 121 row_data span(int x, int y) const 122 { 123 row_data r = m_rows[y]; 124 if(r.ptr) 125 { 126 if(x < r.x1) x = r.x1; 127 r.ptr += x * PixWidth; 128 } 129 return r; 130 } 131 132 133 // The main function used for rendering. Returns pointer to the 134 // pre-allocated span. Memory for the row is allocated as needed. 135 //-------------------------------------------------------------------- 136 int8u* span_ptr(int x, int y, unsigned len) 137 { 138 row_data* r = m_rows + y; 139 int x2 = x + len - 1; 140 if(r->ptr) 141 { 142 if(x < r->x1) { r->x1 = x; } 143 if(x2 > r->x2) { r->x2 = x2; } 144 } 145 else 146 { 147 r->ptr = new int8u [m_width * PixWidth]; 148 r->x1 = x; 149 r->x2 = x2; 150 memset(r->ptr, 0, m_width * PixWidth); 151 } 152 return r->ptr + x * PixWidth; 153 } 154 155 // Get const pointer to the span. Used mostly in GetPixel function 156 // The caller must check the returned pointer for null. 157 //-------------------------------------------------------------------- 158 const int8u* span_ptr(int x, int y, unsigned) const 159 { 160 row_data* r = m_rows + y; 161 return r->ptr ? r->ptr + x * PixWidth : 0; 162 } 163 164 165 166 private: 167 //-------------------------------------------------------------------- 168 // Prohibit copying 169 rendering_buffer_dynarow(const rendering_buffer_dynarow<PixWidth>&); 170 const rendering_buffer_dynarow<PixWidth>& 171 operator = (const rendering_buffer_dynarow<PixWidth>&); 172 173 private: 174 //-------------------------------------------------------------------- 175 row_data* m_rows; // Pointers to each row of the buffer 176 unsigned m_width; // Width in pixels 177 unsigned m_height; // Height in pixels 178 }; 179 180 181 } 182 183 184 #endif 185