499 lines
18 KiB
C++
499 lines
18 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
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// scanline_u8 class
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#ifndef AGG_ALPHA_MASK_U8_INCLUDED
|
|
#define AGG_ALPHA_MASK_U8_INCLUDED
|
|
|
|
#include <string.h>
|
|
#include "agg_basics.h"
|
|
#include "agg_rendering_buffer.h"
|
|
|
|
namespace agg
|
|
{
|
|
//===================================================one_component_mask_u8
|
|
struct one_component_mask_u8
|
|
{
|
|
static unsigned calculate(const int8u* p) { return *p; }
|
|
};
|
|
|
|
|
|
//=====================================================rgb_to_gray_mask_u8
|
|
template<unsigned R, unsigned G, unsigned B>
|
|
struct rgb_to_gray_mask_u8
|
|
{
|
|
static unsigned calculate(const int8u* p)
|
|
{
|
|
return (p[R]*77 + p[G]*150 + p[B]*29) >> 8;
|
|
}
|
|
};
|
|
|
|
//==========================================================alpha_mask_u8
|
|
template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
|
|
class alpha_mask_u8
|
|
{
|
|
public:
|
|
typedef int8u cover_type;
|
|
typedef alpha_mask_u8<Step, Offset, MaskF> self_type;
|
|
enum cover_scale_e
|
|
{
|
|
cover_shift = 8,
|
|
cover_none = 0,
|
|
cover_full = 255
|
|
};
|
|
|
|
alpha_mask_u8() : m_rbuf(0) {}
|
|
alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
|
|
|
|
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
|
|
|
|
MaskF& mask_function() { return m_mask_function; }
|
|
const MaskF& mask_function() const { return m_mask_function; }
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
cover_type pixel(int x, int y) const
|
|
{
|
|
if(x >= 0 && y >= 0 &&
|
|
x < (int)m_rbuf->width() &&
|
|
y <= (int)m_rbuf->height())
|
|
{
|
|
return (cover_type)m_mask_function.calculate(
|
|
m_rbuf->row_ptr(y) + x * Step + Offset);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
cover_type combine_pixel(int x, int y, cover_type val) const
|
|
{
|
|
if(x >= 0 && y >= 0 &&
|
|
x < (int)m_rbuf->width() &&
|
|
y <= (int)m_rbuf->height())
|
|
{
|
|
return (cover_type)((cover_full + val *
|
|
m_mask_function.calculate(
|
|
m_rbuf->row_ptr(y) + x * Step + Offset)) >>
|
|
cover_shift);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
int xmax = m_rbuf->width() - 1;
|
|
int ymax = m_rbuf->height() - 1;
|
|
|
|
int count = num_pix;
|
|
cover_type* covers = dst;
|
|
|
|
if(y < 0 || y > ymax)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
|
|
if(x < 0)
|
|
{
|
|
count += x;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers, 0, -x * sizeof(cover_type));
|
|
covers -= x;
|
|
x = 0;
|
|
}
|
|
|
|
if(x + count > xmax)
|
|
{
|
|
int rest = x + count - xmax - 1;
|
|
count -= rest;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers + count, 0, rest * sizeof(cover_type));
|
|
}
|
|
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*covers++ = (cover_type)m_mask_function.calculate(mask);
|
|
mask += Step;
|
|
}
|
|
while(--count);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
int xmax = m_rbuf->width() - 1;
|
|
int ymax = m_rbuf->height() - 1;
|
|
|
|
int count = num_pix;
|
|
cover_type* covers = dst;
|
|
|
|
if(y < 0 || y > ymax)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
|
|
if(x < 0)
|
|
{
|
|
count += x;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers, 0, -x * sizeof(cover_type));
|
|
covers -= x;
|
|
x = 0;
|
|
}
|
|
|
|
if(x + count > xmax)
|
|
{
|
|
int rest = x + count - xmax - 1;
|
|
count -= rest;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers + count, 0, rest * sizeof(cover_type));
|
|
}
|
|
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*covers = (cover_type)((cover_full + (*covers) *
|
|
m_mask_function.calculate(mask)) >>
|
|
cover_shift);
|
|
++covers;
|
|
mask += Step;
|
|
}
|
|
while(--count);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
int xmax = m_rbuf->width() - 1;
|
|
int ymax = m_rbuf->height() - 1;
|
|
|
|
int count = num_pix;
|
|
cover_type* covers = dst;
|
|
|
|
if(x < 0 || x > xmax)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
|
|
if(y < 0)
|
|
{
|
|
count += y;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers, 0, -y * sizeof(cover_type));
|
|
covers -= y;
|
|
y = 0;
|
|
}
|
|
|
|
if(y + count > ymax)
|
|
{
|
|
int rest = y + count - ymax - 1;
|
|
count -= rest;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers + count, 0, rest * sizeof(cover_type));
|
|
}
|
|
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*covers++ = (cover_type)m_mask_function.calculate(mask);
|
|
mask += m_rbuf->stride();
|
|
}
|
|
while(--count);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
int xmax = m_rbuf->width() - 1;
|
|
int ymax = m_rbuf->height() - 1;
|
|
|
|
int count = num_pix;
|
|
cover_type* covers = dst;
|
|
|
|
if(x < 0 || x > xmax)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
|
|
if(y < 0)
|
|
{
|
|
count += y;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers, 0, -y * sizeof(cover_type));
|
|
covers -= y;
|
|
y = 0;
|
|
}
|
|
|
|
if(y + count > ymax)
|
|
{
|
|
int rest = y + count - ymax - 1;
|
|
count -= rest;
|
|
if(count <= 0)
|
|
{
|
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
|
return;
|
|
}
|
|
memset(covers + count, 0, rest * sizeof(cover_type));
|
|
}
|
|
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*covers = (cover_type)((cover_full + (*covers) *
|
|
m_mask_function.calculate(mask)) >>
|
|
cover_shift);
|
|
++covers;
|
|
mask += m_rbuf->stride();
|
|
}
|
|
while(--count);
|
|
}
|
|
|
|
|
|
private:
|
|
alpha_mask_u8(const self_type&);
|
|
const self_type& operator = (const self_type&);
|
|
|
|
rendering_buffer* m_rbuf;
|
|
MaskF m_mask_function;
|
|
};
|
|
|
|
|
|
typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8
|
|
|
|
typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r
|
|
typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g
|
|
typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b
|
|
|
|
typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r
|
|
typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g
|
|
typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b
|
|
|
|
typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r
|
|
typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g
|
|
typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b
|
|
typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a
|
|
|
|
typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r
|
|
typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g
|
|
typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b
|
|
typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a
|
|
|
|
typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r
|
|
typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g
|
|
typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b
|
|
typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a
|
|
|
|
typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r
|
|
typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g
|
|
typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b
|
|
typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a
|
|
|
|
typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray
|
|
typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray
|
|
typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray
|
|
typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray
|
|
typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray
|
|
typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray
|
|
|
|
|
|
|
|
//==========================================================amask_no_clip_u8
|
|
template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
|
|
class amask_no_clip_u8
|
|
{
|
|
public:
|
|
typedef int8u cover_type;
|
|
typedef amask_no_clip_u8<Step, Offset, MaskF> self_type;
|
|
enum cover_scale_e
|
|
{
|
|
cover_shift = 8,
|
|
cover_none = 0,
|
|
cover_full = 255
|
|
};
|
|
|
|
amask_no_clip_u8() : m_rbuf(0) {}
|
|
amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
|
|
|
|
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
|
|
|
|
MaskF& mask_function() { return m_mask_function; }
|
|
const MaskF& mask_function() const { return m_mask_function; }
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
cover_type pixel(int x, int y) const
|
|
{
|
|
return (cover_type)m_mask_function.calculate(
|
|
m_rbuf->row_ptr(y) + x * Step + Offset);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
cover_type combine_pixel(int x, int y, cover_type val) const
|
|
{
|
|
return (cover_type)((cover_full + val *
|
|
m_mask_function.calculate(
|
|
m_rbuf->row_ptr(y) + x * Step + Offset)) >>
|
|
cover_shift);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*dst++ = (cover_type)m_mask_function.calculate(mask);
|
|
mask += Step;
|
|
}
|
|
while(--num_pix);
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*dst = (cover_type)((cover_full + (*dst) *
|
|
m_mask_function.calculate(mask)) >>
|
|
cover_shift);
|
|
++dst;
|
|
mask += Step;
|
|
}
|
|
while(--num_pix);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*dst++ = (cover_type)m_mask_function.calculate(mask);
|
|
mask += m_rbuf->stride();
|
|
}
|
|
while(--num_pix);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
|
{
|
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
|
do
|
|
{
|
|
*dst = (cover_type)((cover_full + (*dst) *
|
|
m_mask_function.calculate(mask)) >>
|
|
cover_shift);
|
|
++dst;
|
|
mask += m_rbuf->stride();
|
|
}
|
|
while(--num_pix);
|
|
}
|
|
|
|
private:
|
|
amask_no_clip_u8(const self_type&);
|
|
const self_type& operator = (const self_type&);
|
|
|
|
rendering_buffer* m_rbuf;
|
|
MaskF m_mask_function;
|
|
};
|
|
|
|
|
|
typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8
|
|
|
|
typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r
|
|
typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g
|
|
typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b
|
|
|
|
typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r
|
|
typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g
|
|
typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b
|
|
|
|
typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r
|
|
typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g
|
|
typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b
|
|
typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a
|
|
|
|
typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r
|
|
typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g
|
|
typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b
|
|
typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a
|
|
|
|
typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r
|
|
typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g
|
|
typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b
|
|
typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a
|
|
|
|
typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r
|
|
typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g
|
|
typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b
|
|
typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a
|
|
|
|
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray
|
|
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray
|
|
typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray
|
|
typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray
|
|
typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray
|
|
typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|