xref: /haiku/headers/libs/agg/agg_rendering_buffer_dynarow.h (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
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