xref: /haiku/headers/libs/agg/agg_rendering_buffer_dynarow.h (revision e39da397f5ff79f2db9f9a3ddf1852b6710578af)
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 // 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_array.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     class rendering_buffer_dynarow
36     {
37     public:
38         //----------------------------------------------------------------------
39         struct row_data
40         {
41             int x1, x2;
42             const int8u* ptr;
43         };
44 
45         //-------------------------------------------------------------------
~rendering_buffer_dynarow()46         ~rendering_buffer_dynarow()
47         {
48             init(0,0,0);
49         }
50 
51         //-------------------------------------------------------------------
rendering_buffer_dynarow()52         rendering_buffer_dynarow() :
53             m_rows(),
54             m_width(0),
55             m_height(0),
56             m_byte_width(0)
57         {
58         }
59 
60         // Allocate and clear the buffer
61         //--------------------------------------------------------------------
rendering_buffer_dynarow(unsigned width,unsigned height,unsigned byte_width)62         rendering_buffer_dynarow(unsigned width, unsigned height,
63                                  unsigned byte_width) :
64             m_rows(height),
65             m_width(width),
66             m_height(height),
67             m_byte_width(byte_width)
68         {
69             memset(&m_rows[0], 0, sizeof(row_data) * height);
70         }
71 
72         // Allocate and clear the buffer
73         //--------------------------------------------------------------------
init(unsigned width,unsigned height,unsigned byte_width)74         void init(unsigned width, unsigned height, unsigned byte_width)
75         {
76             unsigned i;
77             for(i = 0; i < m_height; ++i)
78             {
79                 pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
80             }
81             if(width && height)
82             {
83                 m_width  = width;
84                 m_height = height;
85                 m_byte_width = byte_width;
86                 m_rows.resize(height);
87                 memset(&m_rows[0], 0, sizeof(row_data) * height);
88             }
89         }
90 
91         //--------------------------------------------------------------------
width()92         unsigned width()      const { return m_width;  }
height()93         unsigned height()     const { return m_height; }
byte_width()94         unsigned byte_width() const { return m_byte_width; }
95 
96         // The main function used for rendering. Returns pointer to the
97         // pre-allocated span. Memory for the row is allocated as needed.
98         //--------------------------------------------------------------------
row_ptr(int x,int y,unsigned len)99         int8u* row_ptr(int x, int y, unsigned len)
100         {
101             row_data* r = &m_rows[y];
102             int x2 = x + len - 1;
103             if(r->ptr)
104             {
105                 if(x  < r->x1) { r->x1 = x;  }
106                 if(x2 > r->x2) { r->x2 = x2; }
107             }
108             else
109             {
110                 int8u* p = pod_allocator<int8u>::allocate(m_byte_width);
111                 r->ptr = p;
112                 r->x1  = x;
113                 r->x2  = x2;
114                 memset(p, 0, m_byte_width);
115             }
116             return (int8u*)r->ptr;
117         }
118 
119         //--------------------------------------------------------------------
row_ptr(int y)120         const int8u* row_ptr(int y) const { return m_rows[y].ptr; }
row_ptr(int y)121               int8u* row_ptr(int y)       { return row_ptr(0, y, m_width); }
row(int y)122         row_data     row    (int y) const { return m_rows[y]; }
123 
124     private:
125         //--------------------------------------------------------------------
126         // Prohibit copying
127         rendering_buffer_dynarow(const rendering_buffer_dynarow&);
128         const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&);
129 
130     private:
131         //--------------------------------------------------------------------
132         pod_array<row_data> m_rows;       // Pointers to each row of the buffer
133         unsigned            m_width;      // Width in pixels
134         unsigned            m_height;     // Height in pixels
135         unsigned            m_byte_width; // Width in bytes
136     };
137 
138 
139 }
140 
141 
142 #endif
143