xref: /haiku/headers/libs/agg/agg_scanline_u.h (revision 8cc5325ad5cbbd78898aeec615151be52c33d1af)
139241fe2SDarkWyrm //----------------------------------------------------------------------------
2e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4
3e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
439241fe2SDarkWyrm //
539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software
639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies.
739241fe2SDarkWyrm // This software is provided "as is" without express or implied
839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose.
939241fe2SDarkWyrm //
1039241fe2SDarkWyrm //----------------------------------------------------------------------------
1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com
1239241fe2SDarkWyrm //          mcseemagg@yahoo.com
1339241fe2SDarkWyrm //          http://www.antigrain.com
1439241fe2SDarkWyrm //----------------------------------------------------------------------------
15e39da397SStephan Aßmus //
16e39da397SStephan Aßmus // Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
17e39da397SStephan Aßmus // Liberty Technology Systems, Inc., visit http://lib-sys.com
18e39da397SStephan Aßmus //
19e39da397SStephan Aßmus // Liberty Technology Systems, Inc. is the provider of
20e39da397SStephan Aßmus // PostScript and PDF technology for software developers.
21e39da397SStephan Aßmus //
22e39da397SStephan Aßmus //----------------------------------------------------------------------------
2339241fe2SDarkWyrm 
2439241fe2SDarkWyrm #ifndef AGG_SCANLINE_U_INCLUDED
2539241fe2SDarkWyrm #define AGG_SCANLINE_U_INCLUDED
2639241fe2SDarkWyrm 
27e39da397SStephan Aßmus #include "agg_array.h"
2839241fe2SDarkWyrm 
2939241fe2SDarkWyrm namespace agg
3039241fe2SDarkWyrm {
31e39da397SStephan Aßmus     //=============================================================scanline_u8
3239241fe2SDarkWyrm     //
3339241fe2SDarkWyrm     // Unpacked scanline container class
3439241fe2SDarkWyrm     //
35e39da397SStephan Aßmus     // This class is used to transfer data from a scanline rasterizer
3639241fe2SDarkWyrm     // to the rendering buffer. It's organized very simple. The class stores
3739241fe2SDarkWyrm     // information of horizontal spans to render it into a pixel-map buffer.
3839241fe2SDarkWyrm     // Each span has staring X, length, and an array of bytes that determine the
3939241fe2SDarkWyrm     // cover-values for each pixel.
4039241fe2SDarkWyrm     // Before using this class you should know the minimal and maximal pixel
4139241fe2SDarkWyrm     // coordinates of your scanline. The protocol of using is:
4239241fe2SDarkWyrm     // 1. reset(min_x, max_x)
4339241fe2SDarkWyrm     // 2. add_cell() / add_span() - accumulate scanline.
4439241fe2SDarkWyrm     //    When forming one scanline the next X coordinate must be always greater
4539241fe2SDarkWyrm     //    than the last stored one, i.e. it works only with ordered coordinates.
4639241fe2SDarkWyrm     // 3. Call finalize(y) and render the scanline.
4739241fe2SDarkWyrm     // 3. Call reset_spans() to prepare for the new scanline.
4839241fe2SDarkWyrm     //
4939241fe2SDarkWyrm     // 4. Rendering:
5039241fe2SDarkWyrm     //
5139241fe2SDarkWyrm     // Scanline provides an iterator class that allows you to extract
5239241fe2SDarkWyrm     // the spans and the cover values for each pixel. Be aware that clipping
5339241fe2SDarkWyrm     // has not been done yet, so you should perform it yourself.
5439241fe2SDarkWyrm     // Use scanline_u8::iterator to render spans:
5539241fe2SDarkWyrm     //-------------------------------------------------------------------------
5639241fe2SDarkWyrm     //
5739241fe2SDarkWyrm     // int y = sl.y();                    // Y-coordinate of the scanline
5839241fe2SDarkWyrm     //
5939241fe2SDarkWyrm     // ************************************
6039241fe2SDarkWyrm     // ...Perform vertical clipping here...
6139241fe2SDarkWyrm     // ************************************
6239241fe2SDarkWyrm     //
6339241fe2SDarkWyrm     // scanline_u8::const_iterator span = sl.begin();
6439241fe2SDarkWyrm     //
6539241fe2SDarkWyrm     // unsigned char* row = m_rbuf->row(y); // The the address of the beginning
6639241fe2SDarkWyrm     //                                      // of the current row
6739241fe2SDarkWyrm     //
6839241fe2SDarkWyrm     // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that
6939241fe2SDarkWyrm     //                                      // num_spans is always greater than 0.
7039241fe2SDarkWyrm     //
7139241fe2SDarkWyrm     // do
7239241fe2SDarkWyrm     // {
7339241fe2SDarkWyrm     //     const scanline_u8::cover_type* covers =
7439241fe2SDarkWyrm     //         span->covers;                     // The array of the cover values
7539241fe2SDarkWyrm     //
7639241fe2SDarkWyrm     //     int num_pix = span->len;              // Number of pixels of the span.
7739241fe2SDarkWyrm     //                                           // Always greater than 0, still it's
7839241fe2SDarkWyrm     //                                           // better to use "int" instead of
7939241fe2SDarkWyrm     //                                           // "unsigned" because it's more
8039241fe2SDarkWyrm     //                                           // convenient for clipping
8139241fe2SDarkWyrm     //     int x = span->x;
8239241fe2SDarkWyrm     //
8339241fe2SDarkWyrm     //     **************************************
8439241fe2SDarkWyrm     //     ...Perform horizontal clipping here...
8539241fe2SDarkWyrm     //     ...you have x, covers, and pix_count..
8639241fe2SDarkWyrm     //     **************************************
8739241fe2SDarkWyrm     //
8839241fe2SDarkWyrm     //     unsigned char* dst = row + x;  // Calculate the start address of the row.
8939241fe2SDarkWyrm     //                                    // In this case we assume a simple
9039241fe2SDarkWyrm     //                                    // grayscale image 1-byte per pixel.
9139241fe2SDarkWyrm     //     do
9239241fe2SDarkWyrm     //     {
9339241fe2SDarkWyrm     //         *dst++ = *covers++;        // Hypotetical rendering.
9439241fe2SDarkWyrm     //     }
9539241fe2SDarkWyrm     //     while(--num_pix);
9639241fe2SDarkWyrm     //
9739241fe2SDarkWyrm     //     ++span;
9839241fe2SDarkWyrm     // }
9939241fe2SDarkWyrm     // while(--num_spans);  // num_spans cannot be 0, so this loop is quite safe
10039241fe2SDarkWyrm     //------------------------------------------------------------------------
10139241fe2SDarkWyrm     //
10239241fe2SDarkWyrm     // The question is: why should we accumulate the whole scanline when we
10339241fe2SDarkWyrm     // could render just separate spans when they're ready?
104e39da397SStephan Aßmus     // That's because using the scanline is generally faster. When is consists
10539241fe2SDarkWyrm     // of more than one span the conditions for the processor cash system
10639241fe2SDarkWyrm     // are better, because switching between two different areas of memory
107e39da397SStephan Aßmus     // (that can be very large) occurs less frequently.
10839241fe2SDarkWyrm     //------------------------------------------------------------------------
109e39da397SStephan Aßmus     class scanline_u8
11039241fe2SDarkWyrm     {
11139241fe2SDarkWyrm     public:
112e39da397SStephan Aßmus         typedef scanline_u8 self_type;
113e39da397SStephan Aßmus         typedef int8u       cover_type;
114e39da397SStephan Aßmus         typedef int16       coord_type;
11539241fe2SDarkWyrm 
11639241fe2SDarkWyrm         //--------------------------------------------------------------------
11739241fe2SDarkWyrm         struct span
11839241fe2SDarkWyrm         {
119e39da397SStephan Aßmus             coord_type  x;
120e39da397SStephan Aßmus             coord_type  len;
12139241fe2SDarkWyrm             cover_type* covers;
12239241fe2SDarkWyrm         };
12339241fe2SDarkWyrm 
12439241fe2SDarkWyrm         typedef span* iterator;
12539241fe2SDarkWyrm         typedef const span* const_iterator;
12639241fe2SDarkWyrm 
12739241fe2SDarkWyrm         //--------------------------------------------------------------------
scanline_u8()128e39da397SStephan Aßmus         scanline_u8() :
12939241fe2SDarkWyrm             m_min_x(0),
13039241fe2SDarkWyrm             m_last_x(0x7FFFFFF0),
13139241fe2SDarkWyrm             m_cur_span(0)
132e39da397SStephan Aßmus         {}
13339241fe2SDarkWyrm 
134e39da397SStephan Aßmus         //--------------------------------------------------------------------
reset(int min_x,int max_x)135e39da397SStephan Aßmus         void reset(int min_x, int max_x)
13639241fe2SDarkWyrm         {
13739241fe2SDarkWyrm             unsigned max_len = max_x - min_x + 2;
138e39da397SStephan Aßmus             if(max_len > m_spans.size())
13939241fe2SDarkWyrm             {
140e39da397SStephan Aßmus                 m_spans.resize(max_len);
141e39da397SStephan Aßmus                 m_covers.resize(max_len);
14239241fe2SDarkWyrm             }
14339241fe2SDarkWyrm             m_last_x   = 0x7FFFFFF0;
14439241fe2SDarkWyrm             m_min_x    = min_x;
145e39da397SStephan Aßmus             m_cur_span = &m_spans[0];
14639241fe2SDarkWyrm         }
14739241fe2SDarkWyrm 
148e39da397SStephan Aßmus         //--------------------------------------------------------------------
add_cell(int x,unsigned cover)149e39da397SStephan Aßmus         void add_cell(int x, unsigned cover)
15039241fe2SDarkWyrm         {
15139241fe2SDarkWyrm             x -= m_min_x;
152e39da397SStephan Aßmus             m_covers[x] = (cover_type)cover;
15339241fe2SDarkWyrm             if(x == m_last_x+1)
15439241fe2SDarkWyrm             {
15539241fe2SDarkWyrm                 m_cur_span->len++;
15639241fe2SDarkWyrm             }
15739241fe2SDarkWyrm             else
15839241fe2SDarkWyrm             {
15939241fe2SDarkWyrm                 m_cur_span++;
160e39da397SStephan Aßmus                 m_cur_span->x      = (coord_type)(x + m_min_x);
16139241fe2SDarkWyrm                 m_cur_span->len    = 1;
162e39da397SStephan Aßmus                 m_cur_span->covers = &m_covers[x];
16339241fe2SDarkWyrm             }
16439241fe2SDarkWyrm             m_last_x = x;
16539241fe2SDarkWyrm         }
16639241fe2SDarkWyrm 
167e39da397SStephan Aßmus         //--------------------------------------------------------------------
add_cells(int x,unsigned len,const cover_type * covers)168e39da397SStephan Aßmus         void add_cells(int x, unsigned len, const cover_type* covers)
16939241fe2SDarkWyrm         {
17039241fe2SDarkWyrm             x -= m_min_x;
171e39da397SStephan Aßmus             memcpy(&m_covers[x], covers, len * sizeof(cover_type));
17239241fe2SDarkWyrm             if(x == m_last_x+1)
17339241fe2SDarkWyrm             {
174e39da397SStephan Aßmus                 m_cur_span->len += (coord_type)len;
17539241fe2SDarkWyrm             }
17639241fe2SDarkWyrm             else
17739241fe2SDarkWyrm             {
17839241fe2SDarkWyrm                 m_cur_span++;
179e39da397SStephan Aßmus                 m_cur_span->x      = (coord_type)(x + m_min_x);
180e39da397SStephan Aßmus                 m_cur_span->len    = (coord_type)len;
181e39da397SStephan Aßmus                 m_cur_span->covers = &m_covers[x];
18239241fe2SDarkWyrm             }
18339241fe2SDarkWyrm             m_last_x = x + len - 1;
18439241fe2SDarkWyrm         }
18539241fe2SDarkWyrm 
186e39da397SStephan Aßmus         //--------------------------------------------------------------------
add_span(int x,unsigned len,unsigned cover)187e39da397SStephan Aßmus         void add_span(int x, unsigned len, unsigned cover)
18839241fe2SDarkWyrm         {
18939241fe2SDarkWyrm             x -= m_min_x;
190e39da397SStephan Aßmus             memset(&m_covers[x], cover, len);
19139241fe2SDarkWyrm             if(x == m_last_x+1)
19239241fe2SDarkWyrm             {
193e39da397SStephan Aßmus                 m_cur_span->len += (coord_type)len;
19439241fe2SDarkWyrm             }
19539241fe2SDarkWyrm             else
19639241fe2SDarkWyrm             {
19739241fe2SDarkWyrm                 m_cur_span++;
198e39da397SStephan Aßmus                 m_cur_span->x      = (coord_type)(x + m_min_x);
199e39da397SStephan Aßmus                 m_cur_span->len    = (coord_type)len;
200e39da397SStephan Aßmus                 m_cur_span->covers = &m_covers[x];
20139241fe2SDarkWyrm             }
20239241fe2SDarkWyrm             m_last_x = x + len - 1;
20339241fe2SDarkWyrm         }
20439241fe2SDarkWyrm 
205e39da397SStephan Aßmus         //--------------------------------------------------------------------
finalize(int y)206e39da397SStephan Aßmus         void finalize(int y)
207e39da397SStephan Aßmus         {
208e39da397SStephan Aßmus             m_y = y;
209e39da397SStephan Aßmus         }
21039241fe2SDarkWyrm 
211e39da397SStephan Aßmus         //--------------------------------------------------------------------
reset_spans()212e39da397SStephan Aßmus         void reset_spans()
213e39da397SStephan Aßmus         {
214e39da397SStephan Aßmus             m_last_x    = 0x7FFFFFF0;
215e39da397SStephan Aßmus             m_cur_span  = &m_spans[0];
216e39da397SStephan Aßmus         }
21739241fe2SDarkWyrm 
218e39da397SStephan Aßmus         //--------------------------------------------------------------------
y()219e39da397SStephan Aßmus         int      y()           const { return m_y; }
num_spans()220e39da397SStephan Aßmus         unsigned num_spans()   const { return unsigned(m_cur_span - &m_spans[0]); }
begin()221e39da397SStephan Aßmus         const_iterator begin() const { return &m_spans[1]; }
begin()222e39da397SStephan Aßmus         iterator       begin()       { return &m_spans[1]; }
22339241fe2SDarkWyrm 
224e39da397SStephan Aßmus     private:
225e39da397SStephan Aßmus         scanline_u8(const self_type&);
226e39da397SStephan Aßmus         const self_type& operator = (const self_type&);
227e39da397SStephan Aßmus 
228e39da397SStephan Aßmus     private:
229e39da397SStephan Aßmus         int                   m_min_x;
230e39da397SStephan Aßmus         int                   m_last_x;
231e39da397SStephan Aßmus         int                   m_y;
232e39da397SStephan Aßmus         pod_array<cover_type> m_covers;
233e39da397SStephan Aßmus         pod_array<span>       m_spans;
234e39da397SStephan Aßmus         span*                 m_cur_span;
235e39da397SStephan Aßmus     };
23639241fe2SDarkWyrm 
23739241fe2SDarkWyrm 
238e39da397SStephan Aßmus 
239e39da397SStephan Aßmus 
240e39da397SStephan Aßmus     //==========================================================scanline_u8_am
24139241fe2SDarkWyrm     //
24239241fe2SDarkWyrm     // The scanline container with alpha-masking
24339241fe2SDarkWyrm     //
24439241fe2SDarkWyrm     //------------------------------------------------------------------------
245e39da397SStephan Aßmus     template<class AlphaMask>
246e39da397SStephan Aßmus     class scanline_u8_am : public scanline_u8
24739241fe2SDarkWyrm     {
24839241fe2SDarkWyrm     public:
249e39da397SStephan Aßmus         typedef scanline_u8           base_type;
25039241fe2SDarkWyrm         typedef AlphaMask             alpha_mask_type;
251e39da397SStephan Aßmus         typedef base_type::cover_type cover_type;
252e39da397SStephan Aßmus         typedef base_type::coord_type coord_type;
25339241fe2SDarkWyrm 
scanline_u8_am()254e39da397SStephan Aßmus         scanline_u8_am() : base_type(), m_alpha_mask(0) {}
scanline_u8_am(AlphaMask & am)255*8cc5325aSAlexander von Gluck IV         scanline_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
25639241fe2SDarkWyrm 
25739241fe2SDarkWyrm         //--------------------------------------------------------------------
finalize(int span_y)25839241fe2SDarkWyrm         void finalize(int span_y)
25939241fe2SDarkWyrm         {
260e39da397SStephan Aßmus             base_type::finalize(span_y);
26139241fe2SDarkWyrm             if(m_alpha_mask)
26239241fe2SDarkWyrm             {
263e39da397SStephan Aßmus                 typename base_type::iterator span = base_type::begin();
264e39da397SStephan Aßmus                 unsigned count = base_type::num_spans();
26539241fe2SDarkWyrm                 do
26639241fe2SDarkWyrm                 {
26739241fe2SDarkWyrm                     m_alpha_mask->combine_hspan(span->x,
268e39da397SStephan Aßmus                                                 base_type::y(),
26939241fe2SDarkWyrm                                                 span->covers,
27039241fe2SDarkWyrm                                                 span->len);
27139241fe2SDarkWyrm                     ++span;
27239241fe2SDarkWyrm                 }
27339241fe2SDarkWyrm                 while(--count);
27439241fe2SDarkWyrm             }
27539241fe2SDarkWyrm         }
27639241fe2SDarkWyrm 
27739241fe2SDarkWyrm     private:
278*8cc5325aSAlexander von Gluck IV         AlphaMask* m_alpha_mask;
27939241fe2SDarkWyrm     };
28039241fe2SDarkWyrm 
28139241fe2SDarkWyrm 
282e39da397SStephan Aßmus 
283e39da397SStephan Aßmus 
284e39da397SStephan Aßmus     //===========================================================scanline32_u8
285e39da397SStephan Aßmus     class scanline32_u8
28639241fe2SDarkWyrm     {
28739241fe2SDarkWyrm     public:
288e39da397SStephan Aßmus         typedef scanline32_u8 self_type;
28939241fe2SDarkWyrm         typedef int8u         cover_type;
290e39da397SStephan Aßmus         typedef int32         coord_type;
29139241fe2SDarkWyrm 
292e39da397SStephan Aßmus         //--------------------------------------------------------------------
293e39da397SStephan Aßmus         struct span
294e39da397SStephan Aßmus         {
spanspan295e39da397SStephan Aßmus             span() {}
spanspan296e39da397SStephan Aßmus             span(coord_type x_, coord_type len_, cover_type* covers_) :
297e39da397SStephan Aßmus                 x(x_), len(len_), covers(covers_) {}
298e39da397SStephan Aßmus 
299e39da397SStephan Aßmus             coord_type  x;
300e39da397SStephan Aßmus             coord_type  len;
301e39da397SStephan Aßmus             cover_type* covers;
30239241fe2SDarkWyrm         };
30339241fe2SDarkWyrm 
304e39da397SStephan Aßmus         typedef pod_bvector<span, 4> span_array_type;
305e39da397SStephan Aßmus 
306e39da397SStephan Aßmus         //--------------------------------------------------------------------
307e39da397SStephan Aßmus         class const_iterator
308e39da397SStephan Aßmus         {
309e39da397SStephan Aßmus         public:
const_iterator(const span_array_type & spans)310e39da397SStephan Aßmus             const_iterator(const span_array_type& spans) :
311e39da397SStephan Aßmus                 m_spans(spans),
312e39da397SStephan Aßmus                 m_span_idx(0)
313e39da397SStephan Aßmus             {}
314e39da397SStephan Aßmus 
315e39da397SStephan Aßmus             const span& operator*()  const { return m_spans[m_span_idx];  }
316e39da397SStephan Aßmus             const span* operator->() const { return &m_spans[m_span_idx]; }
317e39da397SStephan Aßmus 
318e39da397SStephan Aßmus             void operator ++ () { ++m_span_idx; }
319e39da397SStephan Aßmus 
320e39da397SStephan Aßmus         private:
321e39da397SStephan Aßmus             const span_array_type& m_spans;
322e39da397SStephan Aßmus             unsigned               m_span_idx;
323e39da397SStephan Aßmus         };
324e39da397SStephan Aßmus 
325e39da397SStephan Aßmus         //--------------------------------------------------------------------
326e39da397SStephan Aßmus         class iterator
327e39da397SStephan Aßmus         {
328e39da397SStephan Aßmus         public:
iterator(span_array_type & spans)329e39da397SStephan Aßmus             iterator(span_array_type& spans) :
330e39da397SStephan Aßmus                 m_spans(spans),
331e39da397SStephan Aßmus                 m_span_idx(0)
332e39da397SStephan Aßmus             {}
333e39da397SStephan Aßmus 
334e39da397SStephan Aßmus             span& operator*()  { return m_spans[m_span_idx];  }
335e39da397SStephan Aßmus             span* operator->() { return &m_spans[m_span_idx]; }
336e39da397SStephan Aßmus 
337e39da397SStephan Aßmus             void operator ++ () { ++m_span_idx; }
338e39da397SStephan Aßmus 
339e39da397SStephan Aßmus         private:
340e39da397SStephan Aßmus             span_array_type& m_spans;
341e39da397SStephan Aßmus             unsigned         m_span_idx;
342e39da397SStephan Aßmus         };
343e39da397SStephan Aßmus 
344e39da397SStephan Aßmus 
345e39da397SStephan Aßmus 
346e39da397SStephan Aßmus         //--------------------------------------------------------------------
scanline32_u8()347e39da397SStephan Aßmus         scanline32_u8() :
348e39da397SStephan Aßmus             m_min_x(0),
349e39da397SStephan Aßmus             m_last_x(0x7FFFFFF0),
350e39da397SStephan Aßmus             m_covers()
351e39da397SStephan Aßmus         {}
352e39da397SStephan Aßmus 
353e39da397SStephan Aßmus         //--------------------------------------------------------------------
reset(int min_x,int max_x)354e39da397SStephan Aßmus         void reset(int min_x, int max_x)
355e39da397SStephan Aßmus         {
356e39da397SStephan Aßmus             unsigned max_len = max_x - min_x + 2;
357e39da397SStephan Aßmus             if(max_len > m_covers.size())
358e39da397SStephan Aßmus             {
359e39da397SStephan Aßmus                 m_covers.resize(max_len);
360e39da397SStephan Aßmus             }
361e39da397SStephan Aßmus             m_last_x = 0x7FFFFFF0;
362e39da397SStephan Aßmus             m_min_x  = min_x;
363e39da397SStephan Aßmus             m_spans.remove_all();
364e39da397SStephan Aßmus         }
365e39da397SStephan Aßmus 
366e39da397SStephan Aßmus         //--------------------------------------------------------------------
add_cell(int x,unsigned cover)367e39da397SStephan Aßmus         void add_cell(int x, unsigned cover)
368e39da397SStephan Aßmus         {
369e39da397SStephan Aßmus             x -= m_min_x;
370e39da397SStephan Aßmus             m_covers[x] = cover_type(cover);
371e39da397SStephan Aßmus             if(x == m_last_x+1)
372e39da397SStephan Aßmus             {
373e39da397SStephan Aßmus                 m_spans.last().len++;
374e39da397SStephan Aßmus             }
375e39da397SStephan Aßmus             else
376e39da397SStephan Aßmus             {
377e39da397SStephan Aßmus                 m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x]));
378e39da397SStephan Aßmus             }
379e39da397SStephan Aßmus             m_last_x = x;
380e39da397SStephan Aßmus         }
381e39da397SStephan Aßmus 
382e39da397SStephan Aßmus         //--------------------------------------------------------------------
add_cells(int x,unsigned len,const cover_type * covers)383e39da397SStephan Aßmus         void add_cells(int x, unsigned len, const cover_type* covers)
384e39da397SStephan Aßmus         {
385e39da397SStephan Aßmus             x -= m_min_x;
386e39da397SStephan Aßmus             memcpy(&m_covers[x], covers, len * sizeof(cover_type));
387e39da397SStephan Aßmus             if(x == m_last_x+1)
388e39da397SStephan Aßmus             {
389e39da397SStephan Aßmus                 m_spans.last().len += coord_type(len);
390e39da397SStephan Aßmus             }
391e39da397SStephan Aßmus             else
392e39da397SStephan Aßmus             {
393e39da397SStephan Aßmus                 m_spans.add(span(coord_type(x + m_min_x),
394e39da397SStephan Aßmus                                  coord_type(len),
395e39da397SStephan Aßmus                                  &m_covers[x]));
396e39da397SStephan Aßmus             }
397e39da397SStephan Aßmus             m_last_x = x + len - 1;
398e39da397SStephan Aßmus         }
399e39da397SStephan Aßmus 
400e39da397SStephan Aßmus         //--------------------------------------------------------------------
add_span(int x,unsigned len,unsigned cover)401e39da397SStephan Aßmus         void add_span(int x, unsigned len, unsigned cover)
402e39da397SStephan Aßmus         {
403e39da397SStephan Aßmus             x -= m_min_x;
404e39da397SStephan Aßmus             memset(&m_covers[x], cover, len);
405e39da397SStephan Aßmus             if(x == m_last_x+1)
406e39da397SStephan Aßmus             {
407e39da397SStephan Aßmus                 m_spans.last().len += coord_type(len);
408e39da397SStephan Aßmus             }
409e39da397SStephan Aßmus             else
410e39da397SStephan Aßmus             {
411e39da397SStephan Aßmus                 m_spans.add(span(coord_type(x + m_min_x),
412e39da397SStephan Aßmus                                  coord_type(len),
413e39da397SStephan Aßmus                                  &m_covers[x]));
414e39da397SStephan Aßmus             }
415e39da397SStephan Aßmus             m_last_x = x + len - 1;
416e39da397SStephan Aßmus         }
417e39da397SStephan Aßmus 
418e39da397SStephan Aßmus         //--------------------------------------------------------------------
finalize(int y)419e39da397SStephan Aßmus         void finalize(int y)
420e39da397SStephan Aßmus         {
421e39da397SStephan Aßmus             m_y = y;
422e39da397SStephan Aßmus         }
423e39da397SStephan Aßmus 
424e39da397SStephan Aßmus         //--------------------------------------------------------------------
reset_spans()425e39da397SStephan Aßmus         void reset_spans()
426e39da397SStephan Aßmus         {
427e39da397SStephan Aßmus             m_last_x = 0x7FFFFFF0;
428e39da397SStephan Aßmus             m_spans.remove_all();
429e39da397SStephan Aßmus         }
430e39da397SStephan Aßmus 
431e39da397SStephan Aßmus         //--------------------------------------------------------------------
y()432e39da397SStephan Aßmus         int      y()           const { return m_y; }
num_spans()433e39da397SStephan Aßmus         unsigned num_spans()   const { return m_spans.size(); }
begin()434e39da397SStephan Aßmus         const_iterator begin() const { return const_iterator(m_spans); }
begin()435e39da397SStephan Aßmus         iterator       begin()       { return iterator(m_spans); }
436e39da397SStephan Aßmus 
437e39da397SStephan Aßmus     private:
438e39da397SStephan Aßmus         scanline32_u8(const self_type&);
439e39da397SStephan Aßmus         const self_type& operator = (const self_type&);
440e39da397SStephan Aßmus 
441e39da397SStephan Aßmus     private:
442e39da397SStephan Aßmus         int                   m_min_x;
443e39da397SStephan Aßmus         int                   m_last_x;
444e39da397SStephan Aßmus         int                   m_y;
445e39da397SStephan Aßmus         pod_array<cover_type> m_covers;
446e39da397SStephan Aßmus         span_array_type       m_spans;
447e39da397SStephan Aßmus     };
448e39da397SStephan Aßmus 
449e39da397SStephan Aßmus 
450e39da397SStephan Aßmus 
451e39da397SStephan Aßmus 
452e39da397SStephan Aßmus     //========================================================scanline32_u8_am
453e39da397SStephan Aßmus     //
454e39da397SStephan Aßmus     // The scanline container with alpha-masking
455e39da397SStephan Aßmus     //
456e39da397SStephan Aßmus     //------------------------------------------------------------------------
457e39da397SStephan Aßmus     template<class AlphaMask>
458e39da397SStephan Aßmus     class scanline32_u8_am : public scanline32_u8
459e39da397SStephan Aßmus     {
460e39da397SStephan Aßmus     public:
46158916d4aSMurai Takashi         typedef scanline32_u8         base_type;
462e39da397SStephan Aßmus         typedef AlphaMask             alpha_mask_type;
463e39da397SStephan Aßmus         typedef base_type::cover_type cover_type;
464e39da397SStephan Aßmus         typedef base_type::coord_type coord_type;
465e39da397SStephan Aßmus 
466e39da397SStephan Aßmus 
scanline32_u8_am()467*8cc5325aSAlexander von Gluck IV         scanline32_u8_am() : base_type(), m_alpha_mask(0) {}
scanline32_u8_am(AlphaMask & am)468*8cc5325aSAlexander von Gluck IV         scanline32_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
469e39da397SStephan Aßmus 
470e39da397SStephan Aßmus         //--------------------------------------------------------------------
finalize(int span_y)471e39da397SStephan Aßmus         void finalize(int span_y)
472e39da397SStephan Aßmus         {
473*8cc5325aSAlexander von Gluck IV             base_type::finalize(span_y);
474e39da397SStephan Aßmus             if(m_alpha_mask)
475e39da397SStephan Aßmus             {
476*8cc5325aSAlexander von Gluck IV                 typename base_type::iterator span = base_type::begin();
477*8cc5325aSAlexander von Gluck IV                 unsigned count = base_type::num_spans();
478e39da397SStephan Aßmus                 do
479e39da397SStephan Aßmus                 {
480e39da397SStephan Aßmus                     m_alpha_mask->combine_hspan(span->x,
481*8cc5325aSAlexander von Gluck IV                                                 base_type::y(),
482e39da397SStephan Aßmus                                                 span->covers,
483e39da397SStephan Aßmus                                                 span->len);
484e39da397SStephan Aßmus                     ++span;
485e39da397SStephan Aßmus                 }
486e39da397SStephan Aßmus                 while(--count);
487e39da397SStephan Aßmus             }
488e39da397SStephan Aßmus         }
489e39da397SStephan Aßmus 
490e39da397SStephan Aßmus     private:
491*8cc5325aSAlexander von Gluck IV         AlphaMask* m_alpha_mask;
492e39da397SStephan Aßmus     };
493e39da397SStephan Aßmus 
494e39da397SStephan Aßmus 
495e39da397SStephan Aßmus 
49639241fe2SDarkWyrm }
49739241fe2SDarkWyrm 
49839241fe2SDarkWyrm #endif
49939241fe2SDarkWyrm 
500