950809231f
Change-Id: Iba89a9d0845bf7e816983f903281d33e273f6e35 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5558 Reviewed-by: X512 <danger_mail@list.ru> Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
477 lines
13 KiB
C++
477 lines
13 KiB
C++
//----------------------------------------------------------------------------
|
|
// Anti-Grain Geometry - Version 2.4
|
|
// 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
|
|
//----------------------------------------------------------------------------
|
|
|
|
#ifndef AGG_IMAGE_ACCESSORS_INCLUDED
|
|
#define AGG_IMAGE_ACCESSORS_INCLUDED
|
|
|
|
#include "agg_basics.h"
|
|
|
|
namespace agg
|
|
{
|
|
|
|
//-----------------------------------------------------image_accessor_clip
|
|
template<class PixFmt> class image_accessor_clip
|
|
{
|
|
public:
|
|
typedef PixFmt pixfmt_type;
|
|
typedef typename pixfmt_type::color_type color_type;
|
|
typedef typename pixfmt_type::order_type order_type;
|
|
typedef typename pixfmt_type::value_type value_type;
|
|
enum pix_width_e { pix_width = pixfmt_type::pix_width };
|
|
|
|
image_accessor_clip() {}
|
|
image_accessor_clip(const pixfmt_type& pixf, const color_type& bk) :
|
|
m_pixf(&pixf)
|
|
{
|
|
pixfmt_type::make_pix(m_bk_buf, bk);
|
|
}
|
|
|
|
void attach(const pixfmt_type& pixf)
|
|
{
|
|
m_pixf = &pixf;
|
|
}
|
|
|
|
void background_color(const color_type& bk)
|
|
{
|
|
pixfmt_type::make_pix(m_bk_buf, bk);
|
|
}
|
|
|
|
private:
|
|
AGG_INLINE const int8u* pixel() const
|
|
{
|
|
if(m_y >= 0 && m_y < (int)m_pixf->height() &&
|
|
m_x >= 0 && m_x < (int)m_pixf->width())
|
|
{
|
|
return m_pixf->pix_ptr(m_x, m_y);
|
|
}
|
|
return m_bk_buf;
|
|
}
|
|
|
|
public:
|
|
AGG_INLINE const int8u* span(int x, int y, unsigned len)
|
|
{
|
|
m_x = m_x0 = x;
|
|
m_y = y;
|
|
if(y >= 0 && y < (int)m_pixf->height() &&
|
|
x >= 0 && x+(int)len <= (int)m_pixf->width())
|
|
{
|
|
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
|
}
|
|
m_pix_ptr = 0;
|
|
return pixel();
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_x()
|
|
{
|
|
if(m_pix_ptr) return m_pix_ptr += pix_width;
|
|
++m_x;
|
|
return pixel();
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_y()
|
|
{
|
|
++m_y;
|
|
m_x = m_x0;
|
|
if(m_pix_ptr &&
|
|
m_y >= 0 && m_y < (int)m_pixf->height())
|
|
{
|
|
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
|
}
|
|
m_pix_ptr = 0;
|
|
return pixel();
|
|
}
|
|
|
|
private:
|
|
const pixfmt_type* m_pixf;
|
|
int8u m_bk_buf[4];
|
|
int m_x, m_x0, m_y;
|
|
const int8u* m_pix_ptr;
|
|
};
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------image_accessor_no_clip
|
|
template<class PixFmt> class image_accessor_no_clip
|
|
{
|
|
public:
|
|
typedef PixFmt pixfmt_type;
|
|
typedef typename pixfmt_type::color_type color_type;
|
|
typedef typename pixfmt_type::order_type order_type;
|
|
typedef typename pixfmt_type::value_type value_type;
|
|
enum pix_width_e { pix_width = pixfmt_type::pix_width };
|
|
|
|
image_accessor_no_clip() {}
|
|
image_accessor_no_clip(const pixfmt_type& pixf) : m_pixf(&pixf) {}
|
|
|
|
void attach(const pixfmt_type& pixf)
|
|
{
|
|
m_pixf = &pixf;
|
|
}
|
|
|
|
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
|
{
|
|
m_x = x;
|
|
m_y = y;
|
|
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_x()
|
|
{
|
|
return m_pix_ptr += pix_width;
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_y()
|
|
{
|
|
++m_y;
|
|
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
|
}
|
|
|
|
private:
|
|
const pixfmt_type* m_pixf;
|
|
int m_x, m_y;
|
|
const int8u* m_pix_ptr;
|
|
};
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------image_accessor_clone
|
|
template<class PixFmt> class image_accessor_clone
|
|
{
|
|
public:
|
|
typedef PixFmt pixfmt_type;
|
|
typedef typename pixfmt_type::color_type color_type;
|
|
typedef typename pixfmt_type::order_type order_type;
|
|
typedef typename pixfmt_type::value_type value_type;
|
|
enum pix_width_e { pix_width = pixfmt_type::pix_width };
|
|
|
|
image_accessor_clone() {}
|
|
image_accessor_clone(const pixfmt_type& pixf) : m_pixf(&pixf) {}
|
|
|
|
void attach(const pixfmt_type& pixf)
|
|
{
|
|
m_pixf = &pixf;
|
|
}
|
|
|
|
private:
|
|
AGG_INLINE const int8u* pixel() const
|
|
{
|
|
int x = m_x;
|
|
int y = m_y;
|
|
if(x < 0) x = 0;
|
|
if(y < 0) y = 0;
|
|
if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1;
|
|
if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
|
|
return m_pixf->pix_ptr(x, y);
|
|
}
|
|
|
|
public:
|
|
AGG_INLINE const int8u* span(int x, int y, unsigned len)
|
|
{
|
|
m_x = m_x0 = x;
|
|
m_y = y;
|
|
if(y >= 0 && y < (int)m_pixf->height() &&
|
|
x >= 0 && (int)(x+len) <= (int)m_pixf->width())
|
|
{
|
|
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
|
}
|
|
m_pix_ptr = 0;
|
|
return pixel();
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_x()
|
|
{
|
|
if(m_pix_ptr) return m_pix_ptr += pix_width;
|
|
++m_x;
|
|
return pixel();
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_y()
|
|
{
|
|
++m_y;
|
|
m_x = m_x0;
|
|
if(m_pix_ptr &&
|
|
m_y >= 0 && m_y < (int)m_pixf->height())
|
|
{
|
|
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
|
}
|
|
m_pix_ptr = 0;
|
|
return pixel();
|
|
}
|
|
|
|
private:
|
|
const pixfmt_type* m_pixf;
|
|
int m_x, m_x0, m_y;
|
|
const int8u* m_pix_ptr;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------image_accessor_wrap
|
|
template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
|
|
{
|
|
public:
|
|
typedef PixFmt pixfmt_type;
|
|
typedef typename pixfmt_type::color_type color_type;
|
|
typedef typename pixfmt_type::order_type order_type;
|
|
typedef typename pixfmt_type::value_type value_type;
|
|
enum pix_width_e { pix_width = pixfmt_type::pix_width };
|
|
|
|
image_accessor_wrap() {}
|
|
image_accessor_wrap(const pixfmt_type& pixf) :
|
|
m_pixf(&pixf),
|
|
m_wrap_x(pixf.width()),
|
|
m_wrap_y(pixf.height())
|
|
{}
|
|
|
|
void attach(const pixfmt_type& pixf)
|
|
{
|
|
m_pixf = &pixf;
|
|
}
|
|
|
|
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
|
{
|
|
m_x = x;
|
|
m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
|
|
return m_row_ptr + m_wrap_x(x) * pix_width;
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_x()
|
|
{
|
|
int x = ++m_wrap_x;
|
|
return m_row_ptr + x * pix_width;
|
|
}
|
|
|
|
AGG_INLINE const int8u* next_y()
|
|
{
|
|
m_row_ptr = m_pixf->row_ptr(++m_wrap_y);
|
|
return m_row_ptr + m_wrap_x(m_x) * pix_width;
|
|
}
|
|
|
|
private:
|
|
const pixfmt_type* m_pixf;
|
|
const int8u* m_row_ptr;
|
|
int m_x;
|
|
WrapX m_wrap_x;
|
|
WrapY m_wrap_y;
|
|
};
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------wrap_mode_repeat
|
|
class wrap_mode_repeat
|
|
{
|
|
public:
|
|
wrap_mode_repeat() {}
|
|
wrap_mode_repeat(unsigned size) :
|
|
m_size(size),
|
|
m_add(size * (0x3FFFFFFF / size)),
|
|
m_value(0)
|
|
{}
|
|
|
|
AGG_INLINE unsigned operator() (int v)
|
|
{
|
|
return m_value = (unsigned(v) + m_add) % m_size;
|
|
}
|
|
|
|
AGG_INLINE unsigned operator++ ()
|
|
{
|
|
++m_value;
|
|
if(m_value >= m_size) m_value = 0;
|
|
return m_value;
|
|
}
|
|
private:
|
|
unsigned m_size;
|
|
unsigned m_add;
|
|
unsigned m_value;
|
|
};
|
|
|
|
|
|
//---------------------------------------------------wrap_mode_repeat_pow2
|
|
class wrap_mode_repeat_pow2
|
|
{
|
|
public:
|
|
wrap_mode_repeat_pow2() {}
|
|
wrap_mode_repeat_pow2(unsigned size) : m_value(0)
|
|
{
|
|
m_mask = 1;
|
|
while(m_mask < size) m_mask = (m_mask << 1) | 1;
|
|
m_mask >>= 1;
|
|
}
|
|
AGG_INLINE unsigned operator() (int v)
|
|
{
|
|
return m_value = unsigned(v) & m_mask;
|
|
}
|
|
AGG_INLINE unsigned operator++ ()
|
|
{
|
|
++m_value;
|
|
if(m_value > m_mask) m_value = 0;
|
|
return m_value;
|
|
}
|
|
private:
|
|
unsigned m_mask;
|
|
unsigned m_value;
|
|
};
|
|
|
|
|
|
//----------------------------------------------wrap_mode_repeat_auto_pow2
|
|
class wrap_mode_repeat_auto_pow2
|
|
{
|
|
public:
|
|
wrap_mode_repeat_auto_pow2() {}
|
|
wrap_mode_repeat_auto_pow2(unsigned size) :
|
|
m_size(size),
|
|
m_add(size * (0x3FFFFFFF / size)),
|
|
m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
|
|
m_value(0)
|
|
{}
|
|
|
|
AGG_INLINE unsigned operator() (int v)
|
|
{
|
|
if(m_mask) return m_value = unsigned(v) & m_mask;
|
|
return m_value = (unsigned(v) + m_add) % m_size;
|
|
}
|
|
AGG_INLINE unsigned operator++ ()
|
|
{
|
|
++m_value;
|
|
if(m_value >= m_size) m_value = 0;
|
|
return m_value;
|
|
}
|
|
|
|
private:
|
|
unsigned m_size;
|
|
unsigned m_add;
|
|
unsigned m_mask;
|
|
unsigned m_value;
|
|
};
|
|
|
|
|
|
//-------------------------------------------------------wrap_mode_reflect
|
|
class wrap_mode_reflect
|
|
{
|
|
public:
|
|
wrap_mode_reflect() {}
|
|
wrap_mode_reflect(unsigned size) :
|
|
m_size(size),
|
|
m_size2(size * 2),
|
|
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
|
|
m_value(0)
|
|
{}
|
|
|
|
AGG_INLINE unsigned operator() (int v)
|
|
{
|
|
m_value = (unsigned(v) + m_add) % m_size2;
|
|
if(m_value >= m_size) return m_size2 - m_value - 1;
|
|
return m_value;
|
|
}
|
|
|
|
AGG_INLINE unsigned operator++ ()
|
|
{
|
|
++m_value;
|
|
if(m_value >= m_size2) m_value = 0;
|
|
if(m_value >= m_size) return m_size2 - m_value - 1;
|
|
return m_value;
|
|
}
|
|
private:
|
|
unsigned m_size;
|
|
unsigned m_size2;
|
|
unsigned m_add;
|
|
unsigned m_value;
|
|
};
|
|
|
|
|
|
|
|
//--------------------------------------------------wrap_mode_reflect_pow2
|
|
class wrap_mode_reflect_pow2
|
|
{
|
|
public:
|
|
wrap_mode_reflect_pow2() {}
|
|
wrap_mode_reflect_pow2(unsigned size) : m_value(0)
|
|
{
|
|
m_mask = 1;
|
|
m_size = 1;
|
|
while(m_mask < size)
|
|
{
|
|
m_mask = (m_mask << 1) | 1;
|
|
m_size <<= 1;
|
|
}
|
|
}
|
|
AGG_INLINE unsigned operator() (int v)
|
|
{
|
|
m_value = unsigned(v) & m_mask;
|
|
if(m_value >= m_size) return m_mask - m_value;
|
|
return m_value;
|
|
}
|
|
AGG_INLINE unsigned operator++ ()
|
|
{
|
|
++m_value;
|
|
m_value &= m_mask;
|
|
if(m_value >= m_size) return m_mask - m_value;
|
|
return m_value;
|
|
}
|
|
private:
|
|
unsigned m_size;
|
|
unsigned m_mask;
|
|
unsigned m_value;
|
|
};
|
|
|
|
|
|
|
|
//---------------------------------------------wrap_mode_reflect_auto_pow2
|
|
class wrap_mode_reflect_auto_pow2
|
|
{
|
|
public:
|
|
wrap_mode_reflect_auto_pow2() {}
|
|
wrap_mode_reflect_auto_pow2(unsigned size) :
|
|
m_size(size),
|
|
m_size2(size * 2),
|
|
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
|
|
m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
|
|
m_value(0)
|
|
{}
|
|
|
|
AGG_INLINE unsigned operator() (int v)
|
|
{
|
|
m_value = m_mask ? unsigned(v) & m_mask :
|
|
(unsigned(v) + m_add) % m_size2;
|
|
if(m_value >= m_size) return m_size2 - m_value - 1;
|
|
return m_value;
|
|
}
|
|
AGG_INLINE unsigned operator++ ()
|
|
{
|
|
++m_value;
|
|
if(m_value >= m_size2) m_value = 0;
|
|
if(m_value >= m_size) return m_size2 - m_value - 1;
|
|
return m_value;
|
|
}
|
|
|
|
private:
|
|
unsigned m_size;
|
|
unsigned m_size2;
|
|
unsigned m_add;
|
|
unsigned m_mask;
|
|
unsigned m_value;
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|