blob: 844dc9aad3599c0f78a55d7d580df531971ea78d [file] [log] [blame]
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_U_INCLUDED
#define AGG_SCANLINE_U_INCLUDED
#include "agg_array.h"
namespace agg
{
template<class CoverT> class scanline_u
{
public:
typedef scanline_u<CoverT> self_type;
typedef CoverT cover_type;
typedef int16 coord_type;
struct span {
coord_type x;
coord_type len;
cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
~scanline_u()
{
FX_Free(m_spans);
FX_Free(m_covers);
}
scanline_u() :
m_min_x(0),
m_max_len(0),
m_last_x(0x7FFFFFF0),
m_covers(0),
m_spans(0),
m_cur_span(0)
{}
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 2;
if(max_len > m_max_len) {
FX_Free(m_spans);
FX_Free(m_covers);
m_covers = FX_Alloc( cover_type , max_len);
m_spans = FX_Alloc( span , max_len);
m_max_len = max_len;
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = m_spans;
}
void add_cell(int x, unsigned cover)
{
x -= m_min_x;
m_covers[x] = (cover_type)cover;
if(x == m_last_x + 1) {
m_cur_span->len++;
} else {
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 1;
m_cur_span->covers = m_covers + x;
}
m_last_x = x;
}
void add_cells(int x, unsigned len, const CoverT* covers)
{
x -= m_min_x;
memcpy(m_covers + x, covers, len * sizeof(CoverT));
if(x == m_last_x + 1) {
m_cur_span->len += (coord_type)len;
} else {
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = (coord_type)len;
m_cur_span->covers = m_covers + x;
}
m_last_x = x + len - 1;
}
void add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(m_covers + x, cover, len);
if(x == m_last_x + 1) {
m_cur_span->len += (coord_type)len;
} else {
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = (coord_type)len;
m_cur_span->covers = m_covers + x;
}
m_last_x = x + len - 1;
}
void finalize(int y)
{
m_y = y;
}
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = m_spans;
}
int y() const
{
return m_y;
}
unsigned num_spans() const
{
return unsigned(m_cur_span - m_spans);
}
const_iterator begin() const
{
return m_spans + 1;
}
iterator begin()
{
return m_spans + 1;
}
private:
scanline_u(const self_type&);
const self_type& operator = (const self_type&);
private:
int m_min_x;
unsigned m_max_len;
int m_last_x;
int m_y;
cover_type* m_covers;
span* m_spans;
span* m_cur_span;
};
typedef scanline_u<int8u> scanline_u8;
}
#endif