parent
f48589738f
commit
2b7456f54b
234 changed files with 58173 additions and 58873 deletions
|
@ -1,16 +0,0 @@
|
|||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.3.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
files: ^.*\.cmake|CMakeLists\.txt$
|
||||
- id: end-of-file-fixer
|
||||
files: ^.*\.cmake|CMakeLists\.txt$
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v14.0.6
|
||||
hooks:
|
||||
- id: clang-format
|
||||
types_or: [c++, c]
|
742
deps/agg/include/agg_alpha_mask_u8.h
vendored
742
deps/agg/include/agg_alpha_mask_u8.h
vendored
|
@ -23,427 +23,477 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg {
|
||||
//===================================================one_component_mask_u8
|
||||
struct one_component_mask_u8
|
||||
namespace agg
|
||||
{
|
||||
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)
|
||||
{}
|
||||
explicit 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
|
||||
//===================================================one_component_mask_u8
|
||||
struct one_component_mask_u8
|
||||
{
|
||||
if (x >= 0 && y >= 0 && x < (int)m_rbuf->width() && y < (int)m_rbuf->height())
|
||||
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 (cover_type)m_mask_function.calculate(m_rbuf->row_ptr(y) + x * Step + Offset);
|
||||
return (p[R]*77 + p[G]*150 + p[B]*29) >> 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
cover_type combine_pixel(int x, int y, cover_type val) const
|
||||
//==========================================================alpha_mask_u8
|
||||
template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
|
||||
class alpha_mask_u8
|
||||
{
|
||||
if (x >= 0 && y >= 0 && x < (int)m_rbuf->width() && y < (int)m_rbuf->height())
|
||||
public:
|
||||
typedef int8u cover_type;
|
||||
typedef alpha_mask_u8<Step, Offset, MaskF> self_type;
|
||||
enum cover_scale_e
|
||||
{
|
||||
return (
|
||||
cover_type)((cover_full + val * m_mask_function.calculate(m_rbuf->row_ptr(y) + x * Step + Offset)) >>
|
||||
cover_shift);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
cover_shift = 8,
|
||||
cover_none = 0,
|
||||
cover_full = 255
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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;
|
||||
alpha_mask_u8() : m_rbuf(0) {}
|
||||
explicit alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
|
||||
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
|
||||
|
||||
if (y < 0 || y > ymax)
|
||||
MaskF& mask_function() { return m_mask_function; }
|
||||
const MaskF& mask_function() const { return m_mask_function; }
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
cover_type pixel(int x, int y) const
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
if (x < 0)
|
||||
//--------------------------------------------------------------------
|
||||
cover_type combine_pixel(int x, int y, cover_type val) const
|
||||
{
|
||||
count += x;
|
||||
if (count <= 0)
|
||||
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;
|
||||
}
|
||||
memset(covers, 0, -x * sizeof(cover_type));
|
||||
covers -= x;
|
||||
x = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (x + count > xmax)
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
int rest = x + count - xmax - 1;
|
||||
count -= rest;
|
||||
if (count <= 0)
|
||||
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;
|
||||
}
|
||||
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
*covers++ = (cover_type)m_mask_function.calculate(mask);
|
||||
mask += Step;
|
||||
} while (--count);
|
||||
}
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
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)
|
||||
if(x < 0 || x > xmax)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers, 0, -x * sizeof(cover_type));
|
||||
covers -= x;
|
||||
x = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (x + count > xmax)
|
||||
//--------------------------------------------------------------------
|
||||
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
int rest = x + count - xmax - 1;
|
||||
count -= rest;
|
||||
if (count <= 0)
|
||||
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;
|
||||
}
|
||||
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)
|
||||
if(y < 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
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;
|
||||
}
|
||||
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)
|
||||
if(y + count > ymax)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
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));
|
||||
}
|
||||
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)
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
*covers = (cover_type)((cover_full + (*covers) *
|
||||
m_mask_function.calculate(mask)) >>
|
||||
cover_shift);
|
||||
++covers;
|
||||
mask += m_rbuf->stride();
|
||||
}
|
||||
memset(covers, 0, -y * sizeof(cover_type));
|
||||
covers -= y;
|
||||
y = 0;
|
||||
while(--count);
|
||||
}
|
||||
|
||||
if (y + count > ymax)
|
||||
|
||||
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
|
||||
{
|
||||
int rest = y + count - ymax - 1;
|
||||
count -= rest;
|
||||
if (count <= 0)
|
||||
cover_shift = 8,
|
||||
cover_none = 0,
|
||||
cover_full = 255
|
||||
};
|
||||
|
||||
amask_no_clip_u8() : m_rbuf(0) {}
|
||||
explicit 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
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
*dst++ = (cover_type)m_mask_function.calculate(mask);
|
||||
mask += Step;
|
||||
}
|
||||
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||
while(--num_pix);
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
*covers = (cover_type)((cover_full + (*covers) * m_mask_function.calculate(mask)) >> cover_shift);
|
||||
++covers;
|
||||
mask += m_rbuf->stride();
|
||||
} while (--count);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{}
|
||||
explicit 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
|
||||
//--------------------------------------------------------------------
|
||||
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
*dst++ = (cover_type)m_mask_function.calculate(mask);
|
||||
mask += Step;
|
||||
} while (--num_pix);
|
||||
}
|
||||
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_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
*dst = (cover_type)((cover_full + (*dst) * m_mask_function.calculate(mask)) >> cover_shift);
|
||||
++dst;
|
||||
mask += Step;
|
||||
} while (--num_pix);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
private:
|
||||
amask_no_clip_u8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
rendering_buffer* m_rbuf;
|
||||
MaskF m_mask_function;
|
||||
};
|
||||
|
||||
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<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, 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<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, 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, 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, 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<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
|
||||
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
74
deps/agg/include/agg_arc.h
vendored
74
deps/agg/include/agg_arc.h
vendored
|
@ -23,46 +23,52 @@
|
|||
#include <cmath>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=====================================================================arc
|
||||
//
|
||||
// See Implementation agg_arc.cpp
|
||||
//
|
||||
class arc
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
arc()
|
||||
: m_scale(1.0)
|
||||
, m_initialized(false)
|
||||
{}
|
||||
arc(double x, double y, double rx, double ry, double a1, double a2, bool ccw = true);
|
||||
|
||||
void init(double x, double y, double rx, double ry, double a1, double a2, bool ccw = true);
|
||||
//=====================================================================arc
|
||||
//
|
||||
// See Implementation agg_arc.cpp
|
||||
//
|
||||
class arc
|
||||
{
|
||||
public:
|
||||
arc() : m_scale(1.0), m_initialized(false) {}
|
||||
arc(double x, double y,
|
||||
double rx, double ry,
|
||||
double a1, double a2,
|
||||
bool ccw=true);
|
||||
|
||||
void approximation_scale(double s);
|
||||
double approximation_scale() const { return m_scale; }
|
||||
void init(double x, double y,
|
||||
double rx, double ry,
|
||||
double a1, double a2,
|
||||
bool ccw=true);
|
||||
|
||||
void rewind(unsigned);
|
||||
unsigned vertex(double* x, double* y);
|
||||
void approximation_scale(double s);
|
||||
double approximation_scale() const { return m_scale; }
|
||||
|
||||
private:
|
||||
void normalize(double a1, double a2, bool ccw);
|
||||
void rewind(unsigned);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_rx;
|
||||
double m_ry;
|
||||
double m_angle;
|
||||
double m_start;
|
||||
double m_end;
|
||||
double m_scale;
|
||||
double m_da;
|
||||
bool m_ccw;
|
||||
bool m_initialized;
|
||||
unsigned m_path_cmd;
|
||||
};
|
||||
private:
|
||||
void normalize(double a1, double a2, bool ccw);
|
||||
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_rx;
|
||||
double m_ry;
|
||||
double m_angle;
|
||||
double m_start;
|
||||
double m_end;
|
||||
double m_scale;
|
||||
double m_da;
|
||||
bool m_ccw;
|
||||
bool m_initialized;
|
||||
unsigned m_path_cmd;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
1981
deps/agg/include/agg_array.h
vendored
1981
deps/agg/include/agg_array.h
vendored
File diff suppressed because it is too large
Load diff
95
deps/agg/include/agg_arrowhead.h
vendored
95
deps/agg/include/agg_arrowhead.h
vendored
|
@ -21,61 +21,62 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//===============================================================arrowhead
|
||||
//
|
||||
// See implementation agg_arrowhead.cpp
|
||||
//
|
||||
class arrowhead
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
arrowhead();
|
||||
|
||||
void head(double d1, double d2, double d3, double d4)
|
||||
//===============================================================arrowhead
|
||||
//
|
||||
// See implementation agg_arrowhead.cpp
|
||||
//
|
||||
class arrowhead
|
||||
{
|
||||
m_head_d1 = d1;
|
||||
m_head_d2 = d2;
|
||||
m_head_d3 = d3;
|
||||
m_head_d4 = d4;
|
||||
m_head_flag = true;
|
||||
}
|
||||
public:
|
||||
arrowhead();
|
||||
|
||||
void head() { m_head_flag = true; }
|
||||
void no_head() { m_head_flag = false; }
|
||||
void head(double d1, double d2, double d3, double d4)
|
||||
{
|
||||
m_head_d1 = d1;
|
||||
m_head_d2 = d2;
|
||||
m_head_d3 = d3;
|
||||
m_head_d4 = d4;
|
||||
m_head_flag = true;
|
||||
}
|
||||
|
||||
void tail(double d1, double d2, double d3, double d4)
|
||||
{
|
||||
m_tail_d1 = d1;
|
||||
m_tail_d2 = d2;
|
||||
m_tail_d3 = d3;
|
||||
m_tail_d4 = d4;
|
||||
m_tail_flag = true;
|
||||
}
|
||||
void head() { m_head_flag = true; }
|
||||
void no_head() { m_head_flag = false; }
|
||||
|
||||
void tail() { m_tail_flag = true; }
|
||||
void no_tail() { m_tail_flag = false; }
|
||||
void tail(double d1, double d2, double d3, double d4)
|
||||
{
|
||||
m_tail_d1 = d1;
|
||||
m_tail_d2 = d2;
|
||||
m_tail_d3 = d3;
|
||||
m_tail_d4 = d4;
|
||||
m_tail_flag = true;
|
||||
}
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
void tail() { m_tail_flag = true; }
|
||||
void no_tail() { m_tail_flag = false; }
|
||||
|
||||
private:
|
||||
double m_head_d1;
|
||||
double m_head_d2;
|
||||
double m_head_d3;
|
||||
double m_head_d4;
|
||||
double m_tail_d1;
|
||||
double m_tail_d2;
|
||||
double m_tail_d3;
|
||||
double m_tail_d4;
|
||||
bool m_head_flag;
|
||||
bool m_tail_flag;
|
||||
double m_coord[16];
|
||||
unsigned m_cmd[8];
|
||||
unsigned m_curr_id;
|
||||
unsigned m_curr_coord;
|
||||
};
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
double m_head_d1;
|
||||
double m_head_d2;
|
||||
double m_head_d3;
|
||||
double m_head_d4;
|
||||
double m_tail_d1;
|
||||
double m_tail_d2;
|
||||
double m_tail_d3;
|
||||
double m_tail_d4;
|
||||
bool m_head_flag;
|
||||
bool m_tail_flag;
|
||||
double m_coord[16];
|
||||
unsigned m_cmd[8];
|
||||
unsigned m_curr_id;
|
||||
unsigned m_curr_coord;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
793
deps/agg/include/agg_basics.h
vendored
793
deps/agg/include/agg_basics.h
vendored
|
@ -23,41 +23,41 @@
|
|||
#ifdef AGG_CUSTOM_ALLOCATOR
|
||||
#include "agg_allocator.h"
|
||||
#else
|
||||
namespace agg {
|
||||
// The policy of all AGG containers and memory allocation strategy
|
||||
// in general is that no allocated data requires explicit construction.
|
||||
// It means that the allocator can be really simple; you can even
|
||||
// replace new/delete to malloc/free. The constructors and destructors
|
||||
// won't be called in this case, however everything will remain working.
|
||||
// The second argument of deallocate() is the size of the allocated
|
||||
// block. You can use this information if you wish.
|
||||
//------------------------------------------------------------pod_allocator
|
||||
template<class T>
|
||||
struct pod_allocator
|
||||
namespace agg
|
||||
{
|
||||
// static T* allocate(unsigned num) { return static_cast<T*>(::operator new(sizeof(T)*num));}
|
||||
// static void deallocate(T* ptr, unsigned) { ::operator delete(ptr) ;}
|
||||
static T* allocate(unsigned num) { return new T[num]; }
|
||||
static void deallocate(T* ptr, unsigned) { delete[] ptr; }
|
||||
};
|
||||
// The policy of all AGG containers and memory allocation strategy
|
||||
// in general is that no allocated data requires explicit construction.
|
||||
// It means that the allocator can be really simple; you can even
|
||||
// replace new/delete to malloc/free. The constructors and destructors
|
||||
// won't be called in this case, however everything will remain working.
|
||||
// The second argument of deallocate() is the size of the allocated
|
||||
// block. You can use this information if you wish.
|
||||
//------------------------------------------------------------pod_allocator
|
||||
template<class T> struct pod_allocator
|
||||
{
|
||||
//static T* allocate(unsigned num) { return static_cast<T*>(::operator new(sizeof(T)*num));}
|
||||
//static void deallocate(T* ptr, unsigned) { ::operator delete(ptr) ;}
|
||||
static T* allocate(unsigned num) { return new T [num]; }
|
||||
static void deallocate(T* ptr, unsigned) { delete [] ptr; }
|
||||
};
|
||||
|
||||
// Single object allocator. It's also can be replaced with your custom
|
||||
// allocator. The difference is that it can only allocate a single
|
||||
// object and the constructor and destructor must be called.
|
||||
// In AGG there is no need to allocate an array of objects with
|
||||
// calling their constructors (only single ones). So that, if you
|
||||
// replace these new/delete to malloc/free make sure that the in-place
|
||||
// new is called and take care of calling the destructor too.
|
||||
//------------------------------------------------------------obj_allocator
|
||||
template<class T>
|
||||
struct obj_allocator
|
||||
{
|
||||
static T* allocate() { return new T; }
|
||||
static void deallocate(T* ptr) { delete ptr; }
|
||||
};
|
||||
} // namespace agg
|
||||
// Single object allocator. It's also can be replaced with your custom
|
||||
// allocator. The difference is that it can only allocate a single
|
||||
// object and the constructor and destructor must be called.
|
||||
// In AGG there is no need to allocate an array of objects with
|
||||
// calling their constructors (only single ones). So that, if you
|
||||
// replace these new/delete to malloc/free make sure that the in-place
|
||||
// new is called and take care of calling the destructor too.
|
||||
//------------------------------------------------------------obj_allocator
|
||||
template<class T> struct obj_allocator
|
||||
{
|
||||
static T* allocate() { return new T; }
|
||||
static void deallocate(T* ptr) { delete ptr; }
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-------------------------------------------------------- Default basic types
|
||||
//
|
||||
// If the compiler has different capacity of the basic types you can redefine
|
||||
|
@ -98,7 +98,7 @@ struct obj_allocator
|
|||
|
||||
//------------------------------------------------ Some fixes for MS Visual C++
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4786) // Identifier was truncated...
|
||||
#pragma warning(disable:4786) // Identifier was truncated...
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
@ -107,407 +107,372 @@ struct obj_allocator
|
|||
#define AGG_INLINE inline
|
||||
#endif
|
||||
|
||||
namespace agg {
|
||||
//-------------------------------------------------------------------------
|
||||
typedef AGG_INT8 int8; //----int8
|
||||
typedef AGG_INT8U int8u; //----int8u
|
||||
typedef AGG_INT16 int16; //----int16
|
||||
typedef AGG_INT16U int16u; //----int16u
|
||||
typedef AGG_INT32 int32; //----int32
|
||||
typedef AGG_INT32U int32u; //----int32u
|
||||
typedef AGG_INT64 int64; //----int64
|
||||
typedef AGG_INT64U int64u; //----int64u
|
||||
namespace agg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
typedef AGG_INT8 int8; //----int8
|
||||
typedef AGG_INT8U int8u; //----int8u
|
||||
typedef AGG_INT16 int16; //----int16
|
||||
typedef AGG_INT16U int16u; //----int16u
|
||||
typedef AGG_INT32 int32; //----int32
|
||||
typedef AGG_INT32U int32u; //----int32u
|
||||
typedef AGG_INT64 int64; //----int64
|
||||
typedef AGG_INT64U int64u; //----int64u
|
||||
|
||||
AGG_INLINE int iround(double v)
|
||||
{
|
||||
return int((v < 0.0) ? v - 0.5 : v + 0.5);
|
||||
}
|
||||
AGG_INLINE int uround(double v)
|
||||
{
|
||||
return unsigned(v + 0.5);
|
||||
}
|
||||
AGG_INLINE unsigned ufloor(double v)
|
||||
{
|
||||
return unsigned(v);
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v)
|
||||
{
|
||||
return unsigned(std::ceil(v));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------saturation
|
||||
template<int Limit>
|
||||
struct saturation
|
||||
{
|
||||
AGG_INLINE static int iround(double v)
|
||||
AGG_INLINE int iround(double v)
|
||||
{
|
||||
if (v < double(-Limit))
|
||||
return -Limit;
|
||||
if (v > double(Limit))
|
||||
return Limit;
|
||||
return agg::iround(v);
|
||||
return int((v < 0.0) ? v - 0.5 : v + 0.5);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------mul_one
|
||||
template<unsigned Shift>
|
||||
struct mul_one
|
||||
{
|
||||
AGG_INLINE static unsigned mul(unsigned a, unsigned b)
|
||||
AGG_INLINE int uround(double v)
|
||||
{
|
||||
unsigned q = a * b + (1 << (Shift - 1));
|
||||
return (q + (q >> Shift)) >> Shift;
|
||||
return unsigned(v + 0.5);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
typedef unsigned char cover_type; //----cover_type
|
||||
enum cover_scale_e {
|
||||
cover_shift = 8, //----cover_shift
|
||||
cover_size = 1 << cover_shift, //----cover_size
|
||||
cover_mask = cover_size - 1, //----cover_mask
|
||||
cover_none = 0, //----cover_none
|
||||
cover_full = cover_mask //----cover_full
|
||||
};
|
||||
|
||||
//----------------------------------------------------poly_subpixel_scale_e
|
||||
// These constants determine the subpixel accuracy, to be more precise,
|
||||
// the number of bits of the fractional part of the coordinates.
|
||||
// The possible coordinate capacity in bits can be calculated by formula:
|
||||
// sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
|
||||
// 8-bits fractional part the capacity is 24 bits.
|
||||
enum poly_subpixel_scale_e {
|
||||
poly_subpixel_shift = 8, //----poly_subpixel_shift
|
||||
poly_subpixel_scale = 1 << poly_subpixel_shift, //----poly_subpixel_scale
|
||||
poly_subpixel_mask = poly_subpixel_scale - 1 //----poly_subpixel_mask
|
||||
};
|
||||
|
||||
//----------------------------------------------------------filling_rule_e
|
||||
enum filling_rule_e { fill_non_zero, fill_even_odd };
|
||||
|
||||
//-----------------------------------------------------------------------pi
|
||||
const double pi = 3.14159265358979323846;
|
||||
|
||||
//------------------------------------------------------------------deg2rad
|
||||
inline double deg2rad(double deg)
|
||||
{
|
||||
return deg * pi / 180.0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------rad2deg
|
||||
inline double rad2deg(double rad)
|
||||
{
|
||||
return rad * 180.0 / pi;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------rect_base
|
||||
template<class T>
|
||||
struct rect_base
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef rect_base<T> self_type;
|
||||
T x1, y1, x2, y2;
|
||||
|
||||
rect_base() {}
|
||||
rect_base(T x1_, T y1_, T x2_, T y2_)
|
||||
: x1(x1_)
|
||||
, y1(y1_)
|
||||
, x2(x2_)
|
||||
, y2(y2_)
|
||||
{}
|
||||
|
||||
void init(T x1_, T y1_, T x2_, T y2_)
|
||||
AGG_INLINE unsigned ufloor(double v)
|
||||
{
|
||||
x1 = x1_;
|
||||
y1 = y1_;
|
||||
x2 = x2_;
|
||||
y2 = y2_;
|
||||
return unsigned(v);
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v)
|
||||
{
|
||||
return unsigned(std::ceil(v));
|
||||
}
|
||||
|
||||
const self_type& normalize()
|
||||
//---------------------------------------------------------------saturation
|
||||
template<int Limit> struct saturation
|
||||
{
|
||||
T t;
|
||||
if (x1 > x2)
|
||||
AGG_INLINE static int iround(double v)
|
||||
{
|
||||
t = x1;
|
||||
x1 = x2;
|
||||
x2 = t;
|
||||
if(v < double(-Limit)) return -Limit;
|
||||
if(v > double( Limit)) return Limit;
|
||||
return agg::iround(v);
|
||||
}
|
||||
if (y1 > y2)
|
||||
{
|
||||
t = y1;
|
||||
y1 = y2;
|
||||
y2 = t;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
bool clip(const self_type& r)
|
||||
//------------------------------------------------------------------mul_one
|
||||
template<unsigned Shift> struct mul_one
|
||||
{
|
||||
if (x2 > r.x2)
|
||||
x2 = r.x2;
|
||||
if (y2 > r.y2)
|
||||
y2 = r.y2;
|
||||
if (x1 < r.x1)
|
||||
x1 = r.x1;
|
||||
if (y1 < r.y1)
|
||||
y1 = r.y1;
|
||||
return x1 <= x2 && y1 <= y2;
|
||||
AGG_INLINE static unsigned mul(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned q = a * b + (1 << (Shift-1));
|
||||
return (q + (q >> Shift)) >> Shift;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
typedef unsigned char cover_type; //----cover_type
|
||||
enum cover_scale_e
|
||||
{
|
||||
cover_shift = 8, //----cover_shift
|
||||
cover_size = 1 << cover_shift, //----cover_size
|
||||
cover_mask = cover_size - 1, //----cover_mask
|
||||
cover_none = 0, //----cover_none
|
||||
cover_full = cover_mask //----cover_full
|
||||
};
|
||||
|
||||
//----------------------------------------------------poly_subpixel_scale_e
|
||||
// These constants determine the subpixel accuracy, to be more precise,
|
||||
// the number of bits of the fractional part of the coordinates.
|
||||
// The possible coordinate capacity in bits can be calculated by formula:
|
||||
// sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
|
||||
// 8-bits fractional part the capacity is 24 bits.
|
||||
enum poly_subpixel_scale_e
|
||||
{
|
||||
poly_subpixel_shift = 8, //----poly_subpixel_shift
|
||||
poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
|
||||
poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask
|
||||
};
|
||||
|
||||
//----------------------------------------------------------filling_rule_e
|
||||
enum filling_rule_e
|
||||
{
|
||||
fill_non_zero,
|
||||
fill_even_odd
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------pi
|
||||
const double pi = 3.14159265358979323846;
|
||||
|
||||
//------------------------------------------------------------------deg2rad
|
||||
inline double deg2rad(double deg)
|
||||
{
|
||||
return deg * pi / 180.0;
|
||||
}
|
||||
|
||||
bool is_valid() const { return x1 <= x2 && y1 <= y2; }
|
||||
//------------------------------------------------------------------rad2deg
|
||||
inline double rad2deg(double rad)
|
||||
{
|
||||
return rad * 180.0 / pi;
|
||||
}
|
||||
|
||||
bool hit_test(T x, T y) const { return (x >= x1 && x <= x2 && y >= y1 && y <= y2); }
|
||||
};
|
||||
//----------------------------------------------------------------rect_base
|
||||
template<class T> struct rect_base
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef rect_base<T> self_type;
|
||||
T x1, y1, x2, y2;
|
||||
|
||||
//-----------------------------------------------------intersect_rectangles
|
||||
template<class Rect>
|
||||
inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
rect_base() {}
|
||||
rect_base(T x1_, T y1_, T x2_, T y2_) :
|
||||
x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
|
||||
|
||||
void init(T x1_, T y1_, T x2_, T y2_)
|
||||
{
|
||||
x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_;
|
||||
}
|
||||
|
||||
const self_type& normalize()
|
||||
{
|
||||
T t;
|
||||
if(x1 > x2) { t = x1; x1 = x2; x2 = t; }
|
||||
if(y1 > y2) { t = y1; y1 = y2; y2 = t; }
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool clip(const self_type& r)
|
||||
{
|
||||
if(x2 > r.x2) x2 = r.x2;
|
||||
if(y2 > r.y2) y2 = r.y2;
|
||||
if(x1 < r.x1) x1 = r.x1;
|
||||
if(y1 < r.y1) y1 = r.y1;
|
||||
return x1 <= x2 && y1 <= y2;
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
return x1 <= x2 && y1 <= y2;
|
||||
}
|
||||
|
||||
bool hit_test(T x, T y) const
|
||||
{
|
||||
return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------intersect_rectangles
|
||||
template<class Rect>
|
||||
inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
|
||||
// First process x2,y2 because the other order
|
||||
// results in Internal Compiler Error under
|
||||
// Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in
|
||||
// case of "Maximize Speed" optimization option.
|
||||
//-----------------
|
||||
if(r.x2 > r2.x2) r.x2 = r2.x2;
|
||||
if(r.y2 > r2.y2) r.y2 = r2.y2;
|
||||
if(r.x1 < r2.x1) r.x1 = r2.x1;
|
||||
if(r.y1 < r2.y1) r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------unite_rectangles
|
||||
template<class Rect>
|
||||
inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
if(r.x2 < r2.x2) r.x2 = r2.x2;
|
||||
if(r.y2 < r2.y2) r.y2 = r2.y2;
|
||||
if(r.x1 > r2.x1) r.x1 = r2.x1;
|
||||
if(r.y1 > r2.y1) r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
typedef rect_base<int> rect_i; //----rect_i
|
||||
typedef rect_base<float> rect_f; //----rect_f
|
||||
typedef rect_base<double> rect_d; //----rect_d
|
||||
|
||||
//---------------------------------------------------------path_commands_e
|
||||
enum path_commands_e
|
||||
{
|
||||
path_cmd_stop = 0, //----path_cmd_stop
|
||||
path_cmd_move_to = 1, //----path_cmd_move_to
|
||||
path_cmd_line_to = 2, //----path_cmd_line_to
|
||||
path_cmd_curve3 = 3, //----path_cmd_curve3
|
||||
path_cmd_curve4 = 4, //----path_cmd_curve4
|
||||
path_cmd_curveN = 5, //----path_cmd_curveN
|
||||
path_cmd_catrom = 6, //----path_cmd_catrom
|
||||
path_cmd_ubspline = 7, //----path_cmd_ubspline
|
||||
path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
|
||||
path_cmd_mask = 0x0F //----path_cmd_mask
|
||||
};
|
||||
|
||||
//------------------------------------------------------------path_flags_e
|
||||
enum path_flags_e
|
||||
{
|
||||
path_flags_none = 0, //----path_flags_none
|
||||
path_flags_ccw = 0x10, //----path_flags_ccw
|
||||
path_flags_cw = 0x20, //----path_flags_cw
|
||||
path_flags_close = 0x40, //----path_flags_close
|
||||
path_flags_mask = 0xF0 //----path_flags_mask
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------is_vertex
|
||||
inline bool is_vertex(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_move_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_drawing
|
||||
inline bool is_drawing(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_line_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------is_stop
|
||||
inline bool is_stop(unsigned c)
|
||||
{
|
||||
return c == path_cmd_stop;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_move_to
|
||||
inline bool is_move_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_move_to;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_line_to
|
||||
inline bool is_line_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_line_to;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_curve
|
||||
inline bool is_curve(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3 || c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve3
|
||||
inline bool is_curve3(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve4
|
||||
inline bool is_curve4(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_end_poly
|
||||
inline bool is_end_poly(unsigned c)
|
||||
{
|
||||
return (c & path_cmd_mask) == path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_close
|
||||
inline bool is_close(unsigned c)
|
||||
{
|
||||
return (c & ~(path_flags_cw | path_flags_ccw)) ==
|
||||
(path_cmd_end_poly | path_flags_close);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------is_next_poly
|
||||
inline bool is_next_poly(unsigned c)
|
||||
{
|
||||
return is_stop(c) || is_move_to(c) || is_end_poly(c);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------is_cw
|
||||
inline bool is_cw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_cw) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------is_ccw
|
||||
inline bool is_ccw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_ccw) != 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_oriented
|
||||
inline bool is_oriented(unsigned c)
|
||||
{
|
||||
return (c & (path_flags_cw | path_flags_ccw)) != 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_closed
|
||||
inline bool is_closed(unsigned c)
|
||||
{
|
||||
return (c & path_flags_close) != 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------get_close_flag
|
||||
inline unsigned get_close_flag(unsigned c)
|
||||
{
|
||||
return c & path_flags_close;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clear_orientation
|
||||
inline unsigned clear_orientation(unsigned c)
|
||||
{
|
||||
return c & ~(path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------get_orientation
|
||||
inline unsigned get_orientation(unsigned c)
|
||||
{
|
||||
return c & (path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------set_orientation
|
||||
inline unsigned set_orientation(unsigned c, unsigned o)
|
||||
{
|
||||
return clear_orientation(c) | o;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------point_base
|
||||
template<class T> struct point_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x,y;
|
||||
point_base() {}
|
||||
point_base(T x_, T y_) : x(x_), y(y_) {}
|
||||
};
|
||||
typedef point_base<int> point_i; //-----point_i
|
||||
typedef point_base<float> point_f; //-----point_f
|
||||
typedef point_base<double> point_d; //-----point_d
|
||||
|
||||
//-------------------------------------------------------------vertex_base
|
||||
template<class T> struct vertex_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x,y;
|
||||
unsigned cmd;
|
||||
vertex_base() {}
|
||||
vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
|
||||
};
|
||||
typedef vertex_base<int> vertex_i; //-----vertex_i
|
||||
typedef vertex_base<float> vertex_f; //-----vertex_f
|
||||
typedef vertex_base<double> vertex_d; //-----vertex_d
|
||||
|
||||
//----------------------------------------------------------------row_info
|
||||
template<class T> struct row_info
|
||||
{
|
||||
int x1, x2;
|
||||
T* ptr;
|
||||
row_info() {}
|
||||
row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------const_row_info
|
||||
template<class T> struct const_row_info
|
||||
{
|
||||
int x1, x2;
|
||||
const T* ptr;
|
||||
const_row_info() {}
|
||||
const_row_info(int x1_, int x2_, const T* ptr_) :
|
||||
x1(x1_), x2(x2_), ptr(ptr_) {}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------is_equal_eps
|
||||
template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
|
||||
{
|
||||
return std::fabs(v1 - v2) <= double(epsilon);
|
||||
}
|
||||
|
||||
// First process x2,y2 because the other order
|
||||
// results in Internal Compiler Error under
|
||||
// Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in
|
||||
// case of "Maximize Speed" optimization option.
|
||||
//-----------------
|
||||
if (r.x2 > r2.x2)
|
||||
r.x2 = r2.x2;
|
||||
if (r.y2 > r2.y2)
|
||||
r.y2 = r2.y2;
|
||||
if (r.x1 < r2.x1)
|
||||
r.x1 = r2.x1;
|
||||
if (r.y1 < r2.y1)
|
||||
r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------unite_rectangles
|
||||
template<class Rect>
|
||||
inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
if (r.x2 < r2.x2)
|
||||
r.x2 = r2.x2;
|
||||
if (r.y2 < r2.y2)
|
||||
r.y2 = r2.y2;
|
||||
if (r.x1 > r2.x1)
|
||||
r.x1 = r2.x1;
|
||||
if (r.y1 > r2.y1)
|
||||
r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
typedef rect_base<int> rect_i; //----rect_i
|
||||
typedef rect_base<float> rect_f; //----rect_f
|
||||
typedef rect_base<double> rect_d; //----rect_d
|
||||
|
||||
//---------------------------------------------------------path_commands_e
|
||||
enum path_commands_e {
|
||||
path_cmd_stop = 0, //----path_cmd_stop
|
||||
path_cmd_move_to = 1, //----path_cmd_move_to
|
||||
path_cmd_line_to = 2, //----path_cmd_line_to
|
||||
path_cmd_curve3 = 3, //----path_cmd_curve3
|
||||
path_cmd_curve4 = 4, //----path_cmd_curve4
|
||||
path_cmd_curveN = 5, //----path_cmd_curveN
|
||||
path_cmd_catrom = 6, //----path_cmd_catrom
|
||||
path_cmd_ubspline = 7, //----path_cmd_ubspline
|
||||
path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
|
||||
path_cmd_mask = 0x0F //----path_cmd_mask
|
||||
};
|
||||
|
||||
//------------------------------------------------------------path_flags_e
|
||||
enum path_flags_e {
|
||||
path_flags_none = 0, //----path_flags_none
|
||||
path_flags_ccw = 0x10, //----path_flags_ccw
|
||||
path_flags_cw = 0x20, //----path_flags_cw
|
||||
path_flags_close = 0x40, //----path_flags_close
|
||||
path_flags_mask = 0xF0 //----path_flags_mask
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------is_vertex
|
||||
inline bool is_vertex(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_move_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_drawing
|
||||
inline bool is_drawing(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_line_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------is_stop
|
||||
inline bool is_stop(unsigned c)
|
||||
{
|
||||
return c == path_cmd_stop;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_move_to
|
||||
inline bool is_move_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_move_to;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_line_to
|
||||
inline bool is_line_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_line_to;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_curve
|
||||
inline bool is_curve(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3 || c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve3
|
||||
inline bool is_curve3(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve4
|
||||
inline bool is_curve4(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_end_poly
|
||||
inline bool is_end_poly(unsigned c)
|
||||
{
|
||||
return (c & path_cmd_mask) == path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_close
|
||||
inline bool is_close(unsigned c)
|
||||
{
|
||||
return (c & ~(path_flags_cw | path_flags_ccw)) == (path_cmd_end_poly | path_flags_close);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------is_next_poly
|
||||
inline bool is_next_poly(unsigned c)
|
||||
{
|
||||
return is_stop(c) || is_move_to(c) || is_end_poly(c);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------is_cw
|
||||
inline bool is_cw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_cw) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------is_ccw
|
||||
inline bool is_ccw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_ccw) != 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_oriented
|
||||
inline bool is_oriented(unsigned c)
|
||||
{
|
||||
return (c & (path_flags_cw | path_flags_ccw)) != 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_closed
|
||||
inline bool is_closed(unsigned c)
|
||||
{
|
||||
return (c & path_flags_close) != 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------get_close_flag
|
||||
inline unsigned get_close_flag(unsigned c)
|
||||
{
|
||||
return c & path_flags_close;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clear_orientation
|
||||
inline unsigned clear_orientation(unsigned c)
|
||||
{
|
||||
return c & ~(path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------get_orientation
|
||||
inline unsigned get_orientation(unsigned c)
|
||||
{
|
||||
return c & (path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------set_orientation
|
||||
inline unsigned set_orientation(unsigned c, unsigned o)
|
||||
{
|
||||
return clear_orientation(c) | o;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------point_base
|
||||
template<class T>
|
||||
struct point_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x, y;
|
||||
point_base() {}
|
||||
point_base(T x_, T y_)
|
||||
: x(x_)
|
||||
, y(y_)
|
||||
{}
|
||||
};
|
||||
typedef point_base<int> point_i; //-----point_i
|
||||
typedef point_base<float> point_f; //-----point_f
|
||||
typedef point_base<double> point_d; //-----point_d
|
||||
|
||||
//-------------------------------------------------------------vertex_base
|
||||
template<class T>
|
||||
struct vertex_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x, y;
|
||||
unsigned cmd;
|
||||
vertex_base() {}
|
||||
vertex_base(T x_, T y_, unsigned cmd_)
|
||||
: x(x_)
|
||||
, y(y_)
|
||||
, cmd(cmd_)
|
||||
{}
|
||||
};
|
||||
typedef vertex_base<int> vertex_i; //-----vertex_i
|
||||
typedef vertex_base<float> vertex_f; //-----vertex_f
|
||||
typedef vertex_base<double> vertex_d; //-----vertex_d
|
||||
|
||||
//----------------------------------------------------------------row_info
|
||||
template<class T>
|
||||
struct row_info
|
||||
{
|
||||
int x1, x2;
|
||||
T* ptr;
|
||||
row_info() {}
|
||||
row_info(int x1_, int x2_, T* ptr_)
|
||||
: x1(x1_)
|
||||
, x2(x2_)
|
||||
, ptr(ptr_)
|
||||
{}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------const_row_info
|
||||
template<class T>
|
||||
struct const_row_info
|
||||
{
|
||||
int x1, x2;
|
||||
const T* ptr;
|
||||
const_row_info() {}
|
||||
const_row_info(int x1_, int x2_, const T* ptr_)
|
||||
: x1(x1_)
|
||||
, x2(x2_)
|
||||
, ptr(ptr_)
|
||||
{}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------is_equal_eps
|
||||
template<class T>
|
||||
inline bool is_equal_eps(T v1, T v2, T epsilon)
|
||||
{
|
||||
return std::fabs(v1 - v2) <= double(epsilon);
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
220
deps/agg/include/agg_bezier_arc.h
vendored
220
deps/agg/include/agg_bezier_arc.h
vendored
|
@ -23,127 +23,137 @@
|
|||
|
||||
#include "agg_conv_transform.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void arc_to_bezier(double cx, double cy, double rx, double ry, double start_angle, double sweep_angle, double* curve);
|
||||
|
||||
//==============================================================bezier_arc
|
||||
//
|
||||
// See implemantaion agg_bezier_arc.cpp
|
||||
//
|
||||
class bezier_arc
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
bezier_arc()
|
||||
: m_vertex(26)
|
||||
, m_num_vertices(0)
|
||||
, m_cmd(path_cmd_line_to)
|
||||
{}
|
||||
bezier_arc(double x, double y, double rx, double ry, double start_angle, double sweep_angle)
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void arc_to_bezier(double cx, double cy, double rx, double ry,
|
||||
double start_angle, double sweep_angle,
|
||||
double* curve);
|
||||
|
||||
|
||||
//==============================================================bezier_arc
|
||||
//
|
||||
// See implemantaion agg_bezier_arc.cpp
|
||||
//
|
||||
class bezier_arc
|
||||
{
|
||||
init(x, y, rx, ry, start_angle, sweep_angle);
|
||||
}
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
|
||||
bezier_arc(double x, double y,
|
||||
double rx, double ry,
|
||||
double start_angle,
|
||||
double sweep_angle)
|
||||
{
|
||||
init(x, y, rx, ry, start_angle, sweep_angle);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(double x, double y, double rx, double ry, double start_angle, double sweep_angle);
|
||||
//--------------------------------------------------------------------
|
||||
void init(double x, double y,
|
||||
double rx, double ry,
|
||||
double start_angle,
|
||||
double sweep_angle);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned) { m_vertex = 0; }
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_vertex = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_vertex >= m_num_vertices) return path_cmd_stop;
|
||||
*x = m_vertices[m_vertex];
|
||||
*y = m_vertices[m_vertex + 1];
|
||||
m_vertex += 2;
|
||||
return (m_vertex == 2) ? (unsigned)path_cmd_move_to : m_cmd;
|
||||
}
|
||||
|
||||
// Supplemantary functions. num_vertices() actually returns doubled
|
||||
// number of vertices. That is, for 1 vertex it returns 2.
|
||||
//--------------------------------------------------------------------
|
||||
unsigned num_vertices() const { return m_num_vertices; }
|
||||
const double* vertices() const { return m_vertices; }
|
||||
double* vertices() { return m_vertices; }
|
||||
|
||||
private:
|
||||
unsigned m_vertex;
|
||||
unsigned m_num_vertices;
|
||||
double m_vertices[26];
|
||||
unsigned m_cmd;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================================bezier_arc_svg
|
||||
// Compute an SVG-style bezier arc.
|
||||
//
|
||||
// Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
|
||||
// orientation of the ellipse are defined by two radii (rx, ry)
|
||||
// and an x-axis-rotation, which indicates how the ellipse as a whole
|
||||
// is rotated relative to the current coordinate system. The center
|
||||
// (cx, cy) of the ellipse is calculated automatically to satisfy the
|
||||
// constraints imposed by the other parameters.
|
||||
// large-arc-flag and sweep-flag contribute to the automatic calculations
|
||||
// and help determine how the arc is drawn.
|
||||
class bezier_arc_svg
|
||||
{
|
||||
if (m_vertex >= m_num_vertices)
|
||||
return path_cmd_stop;
|
||||
*x = m_vertices[m_vertex];
|
||||
*y = m_vertices[m_vertex + 1];
|
||||
m_vertex += 2;
|
||||
return (m_vertex == 2) ? (unsigned)path_cmd_move_to : m_cmd;
|
||||
}
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
bezier_arc_svg() : m_arc(), m_radii_ok(false) {}
|
||||
|
||||
// Supplemantary functions. num_vertices() actually returns doubled
|
||||
// number of vertices. That is, for 1 vertex it returns 2.
|
||||
//--------------------------------------------------------------------
|
||||
unsigned num_vertices() const { return m_num_vertices; }
|
||||
const double* vertices() const { return m_vertices; }
|
||||
double* vertices() { return m_vertices; }
|
||||
bezier_arc_svg(double x1, double y1,
|
||||
double rx, double ry,
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double x2, double y2) :
|
||||
m_arc(), m_radii_ok(false)
|
||||
{
|
||||
init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_vertex;
|
||||
unsigned m_num_vertices;
|
||||
double m_vertices[26];
|
||||
unsigned m_cmd;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
void init(double x1, double y1,
|
||||
double rx, double ry,
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double x2, double y2);
|
||||
|
||||
//==========================================================bezier_arc_svg
|
||||
// Compute an SVG-style bezier arc.
|
||||
//
|
||||
// Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
|
||||
// orientation of the ellipse are defined by two radii (rx, ry)
|
||||
// and an x-axis-rotation, which indicates how the ellipse as a whole
|
||||
// is rotated relative to the current coordinate system. The center
|
||||
// (cx, cy) of the ellipse is calculated automatically to satisfy the
|
||||
// constraints imposed by the other parameters.
|
||||
// large-arc-flag and sweep-flag contribute to the automatic calculations
|
||||
// and help determine how the arc is drawn.
|
||||
class bezier_arc_svg
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
bezier_arc_svg()
|
||||
: m_arc()
|
||||
, m_radii_ok(false)
|
||||
{}
|
||||
//--------------------------------------------------------------------
|
||||
bool radii_ok() const { return m_radii_ok; }
|
||||
|
||||
bezier_arc_svg(double x1,
|
||||
double y1,
|
||||
double rx,
|
||||
double ry,
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double x2,
|
||||
double y2)
|
||||
: m_arc()
|
||||
, m_radii_ok(false)
|
||||
{
|
||||
init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_arc.rewind(0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(double x1,
|
||||
double y1,
|
||||
double rx,
|
||||
double ry,
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double x2,
|
||||
double y2);
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
return m_arc.vertex(x, y);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool radii_ok() const { return m_radii_ok; }
|
||||
// Supplemantary functions. num_vertices() actually returns doubled
|
||||
// number of vertices. That is, for 1 vertex it returns 2.
|
||||
//--------------------------------------------------------------------
|
||||
unsigned num_vertices() const { return m_arc.num_vertices(); }
|
||||
const double* vertices() const { return m_arc.vertices(); }
|
||||
double* vertices() { return m_arc.vertices(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned) { m_arc.rewind(0); }
|
||||
private:
|
||||
bezier_arc m_arc;
|
||||
bool m_radii_ok;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y) { return m_arc.vertex(x, y); }
|
||||
|
||||
// Supplemantary functions. num_vertices() actually returns doubled
|
||||
// number of vertices. That is, for 1 vertex it returns 2.
|
||||
//--------------------------------------------------------------------
|
||||
unsigned num_vertices() const { return m_arc.num_vertices(); }
|
||||
const double* vertices() const { return m_arc.vertices(); }
|
||||
double* vertices() { return m_arc.vertices(); }
|
||||
|
||||
private:
|
||||
bezier_arc m_arc;
|
||||
bool m_radii_ok;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
44
deps/agg/include/agg_bitset_iterator.h
vendored
44
deps/agg/include/agg_bitset_iterator.h
vendored
|
@ -18,33 +18,37 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
class bitset_iterator
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
bitset_iterator(const int8u* bits, unsigned offset = 0)
|
||||
: m_bits(bits + (offset >> 3))
|
||||
, m_mask(0x80 >> (offset & 7))
|
||||
{}
|
||||
|
||||
void operator++()
|
||||
class bitset_iterator
|
||||
{
|
||||
m_mask >>= 1;
|
||||
if (m_mask == 0)
|
||||
public:
|
||||
bitset_iterator(const int8u* bits, unsigned offset = 0) :
|
||||
m_bits(bits + (offset >> 3)),
|
||||
m_mask(0x80 >> (offset & 7))
|
||||
{}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
++m_bits;
|
||||
m_mask = 0x80;
|
||||
m_mask >>= 1;
|
||||
if(m_mask == 0)
|
||||
{
|
||||
++m_bits;
|
||||
m_mask = 0x80;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned bit() const { return (*m_bits) & m_mask; }
|
||||
unsigned bit() const
|
||||
{
|
||||
return (*m_bits) & m_mask;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_bits;
|
||||
int8u m_mask;
|
||||
};
|
||||
private:
|
||||
const int8u* m_bits;
|
||||
int8u m_mask;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
2401
deps/agg/include/agg_blur.h
vendored
2401
deps/agg/include/agg_blur.h
vendored
File diff suppressed because it is too large
Load diff
153
deps/agg/include/agg_bounding_rect.h
vendored
153
deps/agg/include/agg_bounding_rect.h
vendored
|
@ -21,38 +21,76 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-----------------------------------------------------------bounding_rect
|
||||
template<class VertexSource, class GetId, class CoordT>
|
||||
bool bounding_rect(VertexSource& vs,
|
||||
GetId& gi,
|
||||
unsigned start,
|
||||
unsigned num,
|
||||
CoordT* x1,
|
||||
CoordT* y1,
|
||||
CoordT* x2,
|
||||
CoordT* y2)
|
||||
namespace agg
|
||||
{
|
||||
unsigned i;
|
||||
double x;
|
||||
double y;
|
||||
bool first = true;
|
||||
|
||||
*x1 = CoordT(1);
|
||||
*y1 = CoordT(1);
|
||||
*x2 = CoordT(0);
|
||||
*y2 = CoordT(0);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
//-----------------------------------------------------------bounding_rect
|
||||
template<class VertexSource, class GetId, class CoordT>
|
||||
bool bounding_rect(VertexSource& vs, GetId& gi,
|
||||
unsigned start, unsigned num,
|
||||
CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
|
||||
{
|
||||
vs.rewind(gi[start + i]);
|
||||
unsigned cmd;
|
||||
while (!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
unsigned i;
|
||||
double x;
|
||||
double y;
|
||||
bool first = true;
|
||||
|
||||
*x1 = CoordT(1);
|
||||
*y1 = CoordT(1);
|
||||
*x2 = CoordT(0);
|
||||
*y2 = CoordT(0);
|
||||
|
||||
for(i = 0; i < num; i++)
|
||||
{
|
||||
if (is_vertex(cmd))
|
||||
vs.rewind(gi[start + i]);
|
||||
unsigned cmd;
|
||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
if (first)
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
if(first)
|
||||
{
|
||||
*x1 = CoordT(x);
|
||||
*y1 = CoordT(y);
|
||||
*x2 = CoordT(x);
|
||||
*y2 = CoordT(y);
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CoordT(x) < *x1) *x1 = CoordT(x);
|
||||
if(CoordT(y) < *y1) *y1 = CoordT(y);
|
||||
if(CoordT(x) > *x2) *x2 = CoordT(x);
|
||||
if(CoordT(y) > *y2) *y2 = CoordT(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return *x1 <= *x2 && *y1 <= *y2;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------bounding_rect_single
|
||||
template<class VertexSource, class CoordT>
|
||||
bool bounding_rect_single(VertexSource& vs, unsigned path_id,
|
||||
CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
bool first = true;
|
||||
|
||||
*x1 = CoordT(1);
|
||||
*y1 = CoordT(1);
|
||||
*x2 = CoordT(0);
|
||||
*y2 = CoordT(0);
|
||||
|
||||
vs.rewind(path_id);
|
||||
unsigned cmd;
|
||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
if(first)
|
||||
{
|
||||
*x1 = CoordT(x);
|
||||
*y1 = CoordT(y);
|
||||
|
@ -62,64 +100,17 @@ bool bounding_rect(VertexSource& vs,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (CoordT(x) < *x1)
|
||||
*x1 = CoordT(x);
|
||||
if (CoordT(y) < *y1)
|
||||
*y1 = CoordT(y);
|
||||
if (CoordT(x) > *x2)
|
||||
*x2 = CoordT(x);
|
||||
if (CoordT(y) > *y2)
|
||||
*y2 = CoordT(y);
|
||||
if(CoordT(x) < *x1) *x1 = CoordT(x);
|
||||
if(CoordT(y) < *y1) *y1 = CoordT(y);
|
||||
if(CoordT(x) > *x2) *x2 = CoordT(x);
|
||||
if(CoordT(y) > *y2) *y2 = CoordT(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return *x1 <= *x2 && *y1 <= *y2;
|
||||
}
|
||||
return *x1 <= *x2 && *y1 <= *y2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------bounding_rect_single
|
||||
template<class VertexSource, class CoordT>
|
||||
bool bounding_rect_single(VertexSource& vs, unsigned path_id, CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
bool first = true;
|
||||
|
||||
*x1 = CoordT(1);
|
||||
*y1 = CoordT(1);
|
||||
*x2 = CoordT(0);
|
||||
*y2 = CoordT(0);
|
||||
|
||||
vs.rewind(path_id);
|
||||
unsigned cmd;
|
||||
while (!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
if (is_vertex(cmd))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
*x1 = CoordT(x);
|
||||
*y1 = CoordT(y);
|
||||
*x2 = CoordT(x);
|
||||
*y2 = CoordT(y);
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CoordT(x) < *x1)
|
||||
*x1 = CoordT(x);
|
||||
if (CoordT(y) < *y1)
|
||||
*y1 = CoordT(y);
|
||||
if (CoordT(x) > *x2)
|
||||
*x2 = CoordT(x);
|
||||
if (CoordT(y) > *y2)
|
||||
*y2 = CoordT(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return *x1 <= *x2 && *y1 <= *y2;
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
82
deps/agg/include/agg_bspline.h
vendored
82
deps/agg/include/agg_bspline.h
vendored
|
@ -22,53 +22,55 @@
|
|||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
//----------------------------------------------------------------bspline
|
||||
// A very simple class of Bi-cubic Spline interpolation.
|
||||
// First call init(num, x[], y[]) where num - number of source points,
|
||||
// x, y - arrays of X and Y values respectively. Here Y must be a function
|
||||
// of X. It means that all the X-coordinates must be arranged in the ascending
|
||||
// order.
|
||||
// Then call get(x) that calculates a value Y for the respective X.
|
||||
// The class supports extrapolation, i.e. you can call get(x) where x is
|
||||
// outside the given with init() X-range. Extrapolation is a simple linear
|
||||
// function.
|
||||
//
|
||||
// See Implementation agg_bspline.cpp
|
||||
//------------------------------------------------------------------------
|
||||
class bspline
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
bspline();
|
||||
bspline(int num);
|
||||
bspline(int num, const double* x, const double* y);
|
||||
//----------------------------------------------------------------bspline
|
||||
// A very simple class of Bi-cubic Spline interpolation.
|
||||
// First call init(num, x[], y[]) where num - number of source points,
|
||||
// x, y - arrays of X and Y values respectively. Here Y must be a function
|
||||
// of X. It means that all the X-coordinates must be arranged in the ascending
|
||||
// order.
|
||||
// Then call get(x) that calculates a value Y for the respective X.
|
||||
// The class supports extrapolation, i.e. you can call get(x) where x is
|
||||
// outside the given with init() X-range. Extrapolation is a simple linear
|
||||
// function.
|
||||
//
|
||||
// See Implementation agg_bspline.cpp
|
||||
//------------------------------------------------------------------------
|
||||
class bspline
|
||||
{
|
||||
public:
|
||||
bspline();
|
||||
bspline(int num);
|
||||
bspline(int num, const double* x, const double* y);
|
||||
|
||||
void init(int num);
|
||||
void add_point(double x, double y);
|
||||
void prepare();
|
||||
void init(int num);
|
||||
void add_point(double x, double y);
|
||||
void prepare();
|
||||
|
||||
void init(int num, const double* x, const double* y);
|
||||
void init(int num, const double* x, const double* y);
|
||||
|
||||
double get(double x) const;
|
||||
double get_stateful(double x) const;
|
||||
double get(double x) const;
|
||||
double get_stateful(double x) const;
|
||||
|
||||
private:
|
||||
bspline(const bspline&);
|
||||
const bspline& operator=(const bspline&);
|
||||
private:
|
||||
bspline(const bspline&);
|
||||
const bspline& operator = (const bspline&);
|
||||
|
||||
static void bsearch(int n, const double* x, double x0, int* i);
|
||||
double extrapolation_left(double x) const;
|
||||
double extrapolation_right(double x) const;
|
||||
double interpolation(double x, int i) const;
|
||||
static void bsearch(int n, const double *x, double x0, int *i);
|
||||
double extrapolation_left(double x) const;
|
||||
double extrapolation_right(double x) const;
|
||||
double interpolation(double x, int i) const;
|
||||
|
||||
int m_max;
|
||||
int m_num;
|
||||
double* m_x;
|
||||
double* m_y;
|
||||
pod_array<double> m_am;
|
||||
mutable int m_last_idx;
|
||||
};
|
||||
int m_max;
|
||||
int m_num;
|
||||
double* m_x;
|
||||
double* m_y;
|
||||
pod_array<double> m_am;
|
||||
mutable int m_last_idx;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
525
deps/agg/include/agg_clip_liang_barsky.h
vendored
525
deps/agg/include/agg_clip_liang_barsky.h
vendored
|
@ -21,296 +21,313 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum clipping_flags_e {
|
||||
clipping_flags_x1_clipped = 4,
|
||||
clipping_flags_x2_clipped = 1,
|
||||
clipping_flags_y1_clipped = 8,
|
||||
clipping_flags_y2_clipped = 2,
|
||||
clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped,
|
||||
clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped
|
||||
};
|
||||
|
||||
//----------------------------------------------------------clipping_flags
|
||||
// Determine the clipping code of the vertex according to the
|
||||
// Cyrus-Beck line clipping algorithm
|
||||
//
|
||||
// | |
|
||||
// 0110 | 0010 | 0011
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y2
|
||||
// | |
|
||||
// 0100 | 0000 | 0001
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y1
|
||||
// | |
|
||||
// 1100 | 1000 | 1001
|
||||
// | |
|
||||
// clip_box.x1 clip_box.x2
|
||||
//
|
||||
//
|
||||
template<class T>
|
||||
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
|
||||
namespace agg
|
||||
{
|
||||
return (x > clip_box.x2) | ((y > clip_box.y2) << 1) | ((x < clip_box.x1) << 2) | ((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------clipping_flags_x
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
|
||||
{
|
||||
return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------clipping_flags_y
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
|
||||
{
|
||||
return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clip_liang_barsky
|
||||
template<class T>
|
||||
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2, const rect_base<T>& clip_box, T* x, T* y)
|
||||
{
|
||||
const double nearzero = 1e-30;
|
||||
|
||||
double deltax = x2 - x1;
|
||||
double deltay = y2 - y1;
|
||||
double xin;
|
||||
double xout;
|
||||
double yin;
|
||||
double yout;
|
||||
double tinx;
|
||||
double tiny;
|
||||
double toutx;
|
||||
double touty;
|
||||
double tin1;
|
||||
double tin2;
|
||||
double tout1;
|
||||
unsigned np = 0;
|
||||
|
||||
if (deltax == 0.0)
|
||||
//------------------------------------------------------------------------
|
||||
enum clipping_flags_e
|
||||
{
|
||||
// bump off of the vertical
|
||||
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
|
||||
clipping_flags_x1_clipped = 4,
|
||||
clipping_flags_x2_clipped = 1,
|
||||
clipping_flags_y1_clipped = 8,
|
||||
clipping_flags_y2_clipped = 2,
|
||||
clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped,
|
||||
clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped
|
||||
};
|
||||
|
||||
//----------------------------------------------------------clipping_flags
|
||||
// Determine the clipping code of the vertex according to the
|
||||
// Cyrus-Beck line clipping algorithm
|
||||
//
|
||||
// | |
|
||||
// 0110 | 0010 | 0011
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y2
|
||||
// | |
|
||||
// 0100 | 0000 | 0001
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y1
|
||||
// | |
|
||||
// 1100 | 1000 | 1001
|
||||
// | |
|
||||
// clip_box.x1 clip_box.x2
|
||||
//
|
||||
//
|
||||
template<class T>
|
||||
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
|
||||
{
|
||||
return (x > clip_box.x2) |
|
||||
((y > clip_box.y2) << 1) |
|
||||
((x < clip_box.x1) << 2) |
|
||||
((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
if (deltay == 0.0)
|
||||
//--------------------------------------------------------clipping_flags_x
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
|
||||
{
|
||||
// bump off of the horizontal
|
||||
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
|
||||
return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
|
||||
}
|
||||
|
||||
if (deltax > 0.0)
|
||||
|
||||
//--------------------------------------------------------clipping_flags_y
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
|
||||
{
|
||||
// points to right
|
||||
xin = clip_box.x1;
|
||||
xout = clip_box.x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
xin = clip_box.x2;
|
||||
xout = clip_box.x1;
|
||||
return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
if (deltay > 0.0)
|
||||
{
|
||||
// points up
|
||||
yin = clip_box.y1;
|
||||
yout = clip_box.y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
yin = clip_box.y2;
|
||||
yout = clip_box.y1;
|
||||
}
|
||||
|
||||
tinx = (xin - x1) / deltax;
|
||||
tiny = (yin - y1) / deltay;
|
||||
//-------------------------------------------------------clip_liang_barsky
|
||||
template<class T>
|
||||
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
|
||||
const rect_base<T>& clip_box,
|
||||
T* x, T* y)
|
||||
{
|
||||
const double nearzero = 1e-30;
|
||||
|
||||
if (tinx < tiny)
|
||||
{
|
||||
// hits x first
|
||||
tin1 = tinx;
|
||||
tin2 = tiny;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hits y first
|
||||
tin1 = tiny;
|
||||
tin2 = tinx;
|
||||
}
|
||||
double deltax = x2 - x1;
|
||||
double deltay = y2 - y1;
|
||||
double xin;
|
||||
double xout;
|
||||
double yin;
|
||||
double yout;
|
||||
double tinx;
|
||||
double tiny;
|
||||
double toutx;
|
||||
double touty;
|
||||
double tin1;
|
||||
double tin2;
|
||||
double tout1;
|
||||
unsigned np = 0;
|
||||
|
||||
if (tin1 <= 1.0)
|
||||
{
|
||||
if (0.0 < tin1)
|
||||
if(deltax == 0.0)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yin;
|
||||
++np;
|
||||
// bump off of the vertical
|
||||
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
|
||||
}
|
||||
|
||||
if (tin2 <= 1.0)
|
||||
if(deltay == 0.0)
|
||||
{
|
||||
toutx = (xout - x1) / deltax;
|
||||
touty = (yout - y1) / deltay;
|
||||
// bump off of the horizontal
|
||||
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
|
||||
}
|
||||
|
||||
tout1 = (toutx < touty) ? toutx : touty;
|
||||
if(deltax > 0.0)
|
||||
{
|
||||
// points to right
|
||||
xin = clip_box.x1;
|
||||
xout = clip_box.x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
xin = clip_box.x2;
|
||||
xout = clip_box.x1;
|
||||
}
|
||||
|
||||
if (tin2 > 0.0 || tout1 > 0.0)
|
||||
if(deltay > 0.0)
|
||||
{
|
||||
// points up
|
||||
yin = clip_box.y1;
|
||||
yout = clip_box.y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
yin = clip_box.y2;
|
||||
yout = clip_box.y1;
|
||||
}
|
||||
|
||||
tinx = (xin - x1) / deltax;
|
||||
tiny = (yin - y1) / deltay;
|
||||
|
||||
if (tinx < tiny)
|
||||
{
|
||||
// hits x first
|
||||
tin1 = tinx;
|
||||
tin2 = tiny;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hits y first
|
||||
tin1 = tiny;
|
||||
tin2 = tinx;
|
||||
}
|
||||
|
||||
if(tin1 <= 1.0)
|
||||
{
|
||||
if(0.0 < tin1)
|
||||
{
|
||||
if (tin2 <= tout1)
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yin;
|
||||
++np;
|
||||
}
|
||||
|
||||
if(tin2 <= 1.0)
|
||||
{
|
||||
toutx = (xout - x1) / deltax;
|
||||
touty = (yout - y1) / deltay;
|
||||
|
||||
tout1 = (toutx < touty) ? toutx : touty;
|
||||
|
||||
if(tin2 > 0.0 || tout1 > 0.0)
|
||||
{
|
||||
if (tin2 > 0.0)
|
||||
if(tin2 <= tout1)
|
||||
{
|
||||
if (tinx > tiny)
|
||||
if(tin2 > 0.0)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)(y1 + tinx * deltay);
|
||||
if(tinx > tiny)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)(y1 + tinx * deltay);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + tiny * deltax);
|
||||
*y++ = (T)yin;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
|
||||
if(tout1 < 1.0)
|
||||
{
|
||||
if(toutx < touty)
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)(y1 + toutx * deltay);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + touty * deltax);
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + tiny * deltax);
|
||||
*x++ = x2;
|
||||
*y++ = y2;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tinx > tiny)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)yin;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
|
||||
if (tout1 < 1.0)
|
||||
{
|
||||
if (toutx < touty)
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)(y1 + toutx * deltay);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + touty * deltax);
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = x2;
|
||||
*y++ = y2;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tinx > tiny)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)yin;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
}
|
||||
}
|
||||
return np;
|
||||
}
|
||||
return np;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class T>
|
||||
bool clip_move_point(T x1, T y1, T x2, T y2,
|
||||
const rect_base<T>& clip_box,
|
||||
T* x, T* y, unsigned flags)
|
||||
{
|
||||
T bound;
|
||||
|
||||
if(flags & clipping_flags_x_clipped)
|
||||
{
|
||||
if(x1 == x2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2;
|
||||
*y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1);
|
||||
*x = bound;
|
||||
}
|
||||
|
||||
flags = clipping_flags_y(*y, clip_box);
|
||||
if(flags & clipping_flags_y_clipped)
|
||||
{
|
||||
if(y1 == y2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2;
|
||||
*x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1);
|
||||
*y = bound;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clip_line_segment
|
||||
// Returns: ret >= 4 - Fully clipped
|
||||
// (ret & 1) != 0 - First point has been moved
|
||||
// (ret & 2) != 0 - Second point has been moved
|
||||
//
|
||||
template<class T>
|
||||
unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2,
|
||||
const rect_base<T>& clip_box)
|
||||
{
|
||||
unsigned f1 = clipping_flags(*x1, *y1, clip_box);
|
||||
unsigned f2 = clipping_flags(*x2, *y2, clip_box);
|
||||
unsigned ret = 0;
|
||||
|
||||
if((f2 | f1) == 0)
|
||||
{
|
||||
// Fully visible
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((f1 & clipping_flags_x_clipped) != 0 &&
|
||||
(f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
if((f1 & clipping_flags_y_clipped) != 0 &&
|
||||
(f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
T tx1 = *x1;
|
||||
T ty1 = *y1;
|
||||
T tx2 = *x2;
|
||||
T ty2 = *y2;
|
||||
if(f1)
|
||||
{
|
||||
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if(*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 1;
|
||||
}
|
||||
if(f2)
|
||||
{
|
||||
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if(*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class T>
|
||||
bool clip_move_point(T x1, T y1, T x2, T y2, const rect_base<T>& clip_box, T* x, T* y, unsigned flags)
|
||||
{
|
||||
T bound;
|
||||
|
||||
if (flags & clipping_flags_x_clipped)
|
||||
{
|
||||
if (x1 == x2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2;
|
||||
*y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1);
|
||||
*x = bound;
|
||||
}
|
||||
|
||||
flags = clipping_flags_y(*y, clip_box);
|
||||
if (flags & clipping_flags_y_clipped)
|
||||
{
|
||||
if (y1 == y2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2;
|
||||
*x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1);
|
||||
*y = bound;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clip_line_segment
|
||||
// Returns: ret >= 4 - Fully clipped
|
||||
// (ret & 1) != 0 - First point has been moved
|
||||
// (ret & 2) != 0 - Second point has been moved
|
||||
//
|
||||
template<class T>
|
||||
unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2, const rect_base<T>& clip_box)
|
||||
{
|
||||
unsigned f1 = clipping_flags(*x1, *y1, clip_box);
|
||||
unsigned f2 = clipping_flags(*x2, *y2, clip_box);
|
||||
unsigned ret = 0;
|
||||
|
||||
if ((f2 | f1) == 0)
|
||||
{
|
||||
// Fully visible
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((f1 & clipping_flags_x_clipped) != 0 && (f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
if ((f1 & clipping_flags_y_clipped) != 0 && (f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
T tx1 = *x1;
|
||||
T ty1 = *y1;
|
||||
T tx2 = *x2;
|
||||
T ty2 = *y2;
|
||||
if (f1)
|
||||
{
|
||||
if (!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if (*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 1;
|
||||
}
|
||||
if (f2)
|
||||
{
|
||||
if (!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if (*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
524
deps/agg/include/agg_color_gray.h
vendored
524
deps/agg/include/agg_color_gray.h
vendored
|
@ -31,19 +31,21 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
namespace agg {
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//===================================================================gray8
|
||||
template<class Colorspace>
|
||||
struct gray8T
|
||||
{
|
||||
typedef int8u value_type;
|
||||
typedef int8u value_type;
|
||||
typedef int32u calc_type;
|
||||
typedef int32 long_type;
|
||||
enum base_scale_e {
|
||||
typedef int32 long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
base_shift = 8,
|
||||
base_scale = 1 << base_shift,
|
||||
base_mask = base_scale - 1,
|
||||
base_mask = base_scale - 1,
|
||||
base_MSB = 1 << (base_shift - 1)
|
||||
};
|
||||
typedef gray8T self_type;
|
||||
|
@ -103,22 +105,17 @@ struct gray8T
|
|||
gray8T() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray8T(unsigned v_, unsigned a_ = base_mask)
|
||||
: v(int8u(v_))
|
||||
, a(int8u(a_))
|
||||
{}
|
||||
gray8T(unsigned v_, unsigned a_=base_mask) :
|
||||
v(int8u(v_)), a(int8u(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray8T(const self_type& c, unsigned a_)
|
||||
: v(c.v)
|
||||
, a(value_type(a_))
|
||||
{}
|
||||
gray8T(const self_type& c, unsigned a_) :
|
||||
v(c.v), a(value_type(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray8T(const rgba& c)
|
||||
: v(luminance(c))
|
||||
, a(value_type(uround(c.a * base_mask)))
|
||||
{}
|
||||
gray8T(const rgba& c) :
|
||||
v(luminance(c)),
|
||||
a(value_type(uround(c.a * base_mask))) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class T>
|
||||
|
@ -150,18 +147,36 @@ struct gray8T
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba8 make_rgba8(const linear&) const { return rgba8(v, v, v, a); }
|
||||
rgba8 make_rgba8(const linear&) const
|
||||
{
|
||||
return rgba8(v, v, v, a);
|
||||
}
|
||||
|
||||
rgba8 make_rgba8(const sRGB&) const { return convert_from_sRGB<srgba8>(); }
|
||||
rgba8 make_rgba8(const sRGB&) const
|
||||
{
|
||||
return convert_from_sRGB<srgba8>();
|
||||
}
|
||||
|
||||
operator rgba8() const { return make_rgba8(Colorspace()); }
|
||||
operator rgba8() const
|
||||
{
|
||||
return make_rgba8(Colorspace());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
srgba8 make_srgba8(const linear&) const { return convert_to_sRGB<rgba8>(); }
|
||||
srgba8 make_srgba8(const linear&) const
|
||||
{
|
||||
return convert_to_sRGB<rgba8>();
|
||||
}
|
||||
|
||||
srgba8 make_srgba8(const sRGB&) const { return srgba8(v, v, v, a); }
|
||||
srgba8 make_srgba8(const sRGB&) const
|
||||
{
|
||||
return srgba8(v, v, v, a);
|
||||
}
|
||||
|
||||
operator srgba8() const { return make_rgba8(Colorspace()); }
|
||||
operator srgba8() const
|
||||
{
|
||||
return make_rgba8(Colorspace());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba16 make_rgba16(const linear&) const
|
||||
|
@ -170,9 +185,15 @@ struct gray8T
|
|||
return rgba16(rgb, rgb, rgb, (a << 8) | a);
|
||||
}
|
||||
|
||||
rgba16 make_rgba16(const sRGB&) const { return convert_from_sRGB<rgba16>(); }
|
||||
rgba16 make_rgba16(const sRGB&) const
|
||||
{
|
||||
return convert_from_sRGB<rgba16>();
|
||||
}
|
||||
|
||||
operator rgba16() const { return make_rgba16(Colorspace()); }
|
||||
operator rgba16() const
|
||||
{
|
||||
return make_rgba16(Colorspace());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba32 make_rgba32(const linear&) const
|
||||
|
@ -181,27 +202,51 @@ struct gray8T
|
|||
return rgba32(v32, v32, v32, a / 255.0);
|
||||
}
|
||||
|
||||
rgba32 make_rgba32(const sRGB&) const { return convert_from_sRGB<rgba32>(); }
|
||||
rgba32 make_rgba32(const sRGB&) const
|
||||
{
|
||||
return convert_from_sRGB<rgba32>();
|
||||
}
|
||||
|
||||
operator rgba32() const { return make_rgba32(Colorspace()); }
|
||||
operator rgba32() const
|
||||
{
|
||||
return make_rgba32(Colorspace());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return double(a) / base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(uround(a * base_mask));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type empty_value() { return 0; }
|
||||
static AGG_INLINE value_type empty_value()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||
static AGG_INLINE value_type full_value()
|
||||
{
|
||||
return base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||
AGG_INLINE bool is_transparent() const
|
||||
{
|
||||
return a == 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||
AGG_INLINE bool is_opaque() const
|
||||
{
|
||||
return a == base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, exact over int8u.
|
||||
|
@ -222,8 +267,7 @@ struct gray8T
|
|||
{
|
||||
return base_mask;
|
||||
}
|
||||
else
|
||||
return value_type((a * base_mask + (b >> 1)) / b);
|
||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -243,14 +287,23 @@ struct gray8T
|
|||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, exact over int8u.
|
||||
// Specifically for multiplying a color component by a cover.
|
||||
static AGG_INLINE value_type mult_cover(value_type a, value_type b) { return multiply(a, b); }
|
||||
static AGG_INLINE value_type mult_cover(value_type a, value_type b)
|
||||
{
|
||||
return multiply(a, b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply(b, a); }
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
||||
{
|
||||
return multiply(b, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
|
||||
{
|
||||
return p + q - multiply(p, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a.
|
||||
|
@ -277,27 +330,25 @@ struct gray8T
|
|||
//--------------------------------------------------------------------
|
||||
self_type& opacity(double a_)
|
||||
{
|
||||
if (a_ < 0)
|
||||
a = 0;
|
||||
else if (a_ > 1)
|
||||
a = 1;
|
||||
else
|
||||
a = (value_type)uround(a_ * double(base_mask));
|
||||
if (a_ < 0) a = 0;
|
||||
else if (a_ > 1) a = 1;
|
||||
else a = (value_type)uround(a_ * double(base_mask));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double opacity() const { return double(a) / double(base_mask); }
|
||||
double opacity() const
|
||||
{
|
||||
return double(a) / double(base_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
self_type& premultiply()
|
||||
{
|
||||
if (a < base_mask)
|
||||
{
|
||||
if (a == 0)
|
||||
v = 0;
|
||||
else
|
||||
v = multiply(v, a);
|
||||
if (a == 0) v = 0;
|
||||
else v = multiply(v, a);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -357,22 +408,24 @@ struct gray8T
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type no_color() { return self_type(0, 0); }
|
||||
static self_type no_color() { return self_type(0,0); }
|
||||
};
|
||||
|
||||
typedef gray8T<linear> gray8;
|
||||
typedef gray8T<sRGB> sgray8;
|
||||
|
||||
|
||||
//==================================================================gray16
|
||||
struct gray16
|
||||
{
|
||||
typedef int16u value_type;
|
||||
typedef int32u calc_type;
|
||||
typedef int64 long_type;
|
||||
enum base_scale_e {
|
||||
typedef int64 long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
base_shift = 16,
|
||||
base_scale = 1 << base_shift,
|
||||
base_mask = base_scale - 1,
|
||||
base_mask = base_scale - 1,
|
||||
base_MSB = 1 << (base_shift - 1)
|
||||
};
|
||||
typedef gray16 self_type;
|
||||
|
@ -392,65 +445,67 @@ struct gray16
|
|||
return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16);
|
||||
}
|
||||
|
||||
static value_type luminance(const rgba8& c) { return luminance(rgba16(c)); }
|
||||
static value_type luminance(const rgba8& c)
|
||||
{
|
||||
return luminance(rgba16(c));
|
||||
}
|
||||
|
||||
static value_type luminance(const srgba8& c) { return luminance(rgba16(c)); }
|
||||
static value_type luminance(const srgba8& c)
|
||||
{
|
||||
return luminance(rgba16(c));
|
||||
}
|
||||
|
||||
static value_type luminance(const rgba32& c) { return luminance(rgba(c)); }
|
||||
static value_type luminance(const rgba32& c)
|
||||
{
|
||||
return luminance(rgba(c));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(unsigned v_, unsigned a_ = base_mask)
|
||||
: v(int16u(v_))
|
||||
, a(int16u(a_))
|
||||
{}
|
||||
gray16(unsigned v_, unsigned a_ = base_mask) :
|
||||
v(int16u(v_)), a(int16u(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(const self_type& c, unsigned a_)
|
||||
: v(c.v)
|
||||
, a(value_type(a_))
|
||||
{}
|
||||
gray16(const self_type& c, unsigned a_) :
|
||||
v(c.v), a(value_type(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(const rgba& c)
|
||||
: v(luminance(c))
|
||||
, a((value_type)uround(c.a * double(base_mask)))
|
||||
{}
|
||||
gray16(const rgba& c) :
|
||||
v(luminance(c)),
|
||||
a((value_type)uround(c.a * double(base_mask))) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(const rgba8& c)
|
||||
: v(luminance(c))
|
||||
, a((value_type(c.a) << 8) | c.a)
|
||||
{}
|
||||
gray16(const rgba8& c) :
|
||||
v(luminance(c)),
|
||||
a((value_type(c.a) << 8) | c.a) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(const srgba8& c)
|
||||
: v(luminance(c))
|
||||
, a((value_type(c.a) << 8) | c.a)
|
||||
{}
|
||||
gray16(const srgba8& c) :
|
||||
v(luminance(c)),
|
||||
a((value_type(c.a) << 8) | c.a) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(const rgba16& c)
|
||||
: v(luminance(c))
|
||||
, a(c.a)
|
||||
{}
|
||||
gray16(const rgba16& c) :
|
||||
v(luminance(c)),
|
||||
a(c.a) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(const gray8& c)
|
||||
: v((value_type(c.v) << 8) | c.v)
|
||||
, a((value_type(c.a) << 8) | c.a)
|
||||
{}
|
||||
gray16(const gray8& c) :
|
||||
v((value_type(c.v) << 8) | c.v),
|
||||
a((value_type(c.a) << 8) | c.a) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray16(const sgray8& c)
|
||||
: v(sRGB_conv<value_type>::rgb_from_sRGB(c.v))
|
||||
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||
{}
|
||||
gray16(const sgray8& c) :
|
||||
v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)),
|
||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba8() const { return rgba8(v >> 8, v >> 8, v >> 8, a >> 8); }
|
||||
operator rgba8() const
|
||||
{
|
||||
return rgba8(v >> 8, v >> 8, v >> 8, a >> 8);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator srgba8() const
|
||||
|
@ -460,34 +515,60 @@ struct gray16
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba16() const { return rgba16(v, v, v, a); }
|
||||
operator rgba16() const
|
||||
{
|
||||
return rgba16(v, v, v, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator gray8() const { return gray8(v >> 8, a >> 8); }
|
||||
operator gray8() const
|
||||
{
|
||||
return gray8(v >> 8, a >> 8);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator sgray8() const
|
||||
{
|
||||
return sgray8(sRGB_conv<value_type>::rgb_to_sRGB(v), sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
return sgray8(
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(v),
|
||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return double(a) / base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(uround(a * base_mask));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type empty_value() { return 0; }
|
||||
static AGG_INLINE value_type empty_value()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||
static AGG_INLINE value_type full_value()
|
||||
{
|
||||
return base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||
AGG_INLINE bool is_transparent() const
|
||||
{
|
||||
return a == 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||
AGG_INLINE bool is_opaque() const
|
||||
{
|
||||
return a == base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, exact over int16u.
|
||||
|
@ -508,8 +589,7 @@ struct gray16
|
|||
{
|
||||
return base_mask;
|
||||
}
|
||||
else
|
||||
return value_type((a * base_mask + (b >> 1)) / b);
|
||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -529,14 +609,23 @@ struct gray16
|
|||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, almost exact over int16u.
|
||||
// Specifically for multiplying a color component by a cover.
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, b << 8 | b); }
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
||||
{
|
||||
return multiply(a, b << 8 | b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return mult_cover(b, a) >> 8; }
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
||||
{
|
||||
return mult_cover(b, a) >> 8;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
|
||||
{
|
||||
return p + q - multiply(p, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a.
|
||||
|
@ -563,27 +652,26 @@ struct gray16
|
|||
//--------------------------------------------------------------------
|
||||
self_type& opacity(double a_)
|
||||
{
|
||||
if (a_ < 0)
|
||||
a = 0;
|
||||
else if (a_ > 1)
|
||||
a = 1;
|
||||
else
|
||||
a = (value_type)uround(a_ * double(base_mask));
|
||||
if (a_ < 0) a = 0;
|
||||
else if(a_ > 1) a = 1;
|
||||
else a = (value_type)uround(a_ * double(base_mask));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double opacity() const { return double(a) / double(base_mask); }
|
||||
double opacity() const
|
||||
{
|
||||
return double(a) / double(base_mask);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
self_type& premultiply()
|
||||
{
|
||||
if (a < base_mask)
|
||||
{
|
||||
if (a == 0)
|
||||
v = 0;
|
||||
else
|
||||
v = multiply(v, a);
|
||||
if(a == 0) v = 0;
|
||||
else v = multiply(v, a);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -643,9 +731,10 @@ struct gray16
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type no_color() { return self_type(0, 0); }
|
||||
static self_type no_color() { return self_type(0,0); }
|
||||
};
|
||||
|
||||
|
||||
//===================================================================gray32
|
||||
struct gray32
|
||||
{
|
||||
|
@ -657,10 +746,11 @@ struct gray32
|
|||
value_type v;
|
||||
value_type a;
|
||||
|
||||
enum base_scale_e {
|
||||
enum base_scale_e
|
||||
{
|
||||
base_shift = 8,
|
||||
base_scale = 1 << base_shift,
|
||||
base_mask = base_scale - 1,
|
||||
base_mask = base_scale - 1,
|
||||
};
|
||||
|
||||
// Calculate grayscale value as per ITU-R BT.709.
|
||||
|
@ -669,92 +759,103 @@ struct gray32
|
|||
return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b);
|
||||
}
|
||||
|
||||
static value_type luminance(const rgba& c) { return luminance(c.r, c.g, c.b); }
|
||||
static value_type luminance(const rgba& c)
|
||||
{
|
||||
return luminance(c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
static value_type luminance(const rgba32& c) { return luminance(c.r, c.g, c.b); }
|
||||
static value_type luminance(const rgba32& c)
|
||||
{
|
||||
return luminance(c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
static value_type luminance(const rgba8& c) { return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0); }
|
||||
static value_type luminance(const rgba8& c)
|
||||
{
|
||||
return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0);
|
||||
}
|
||||
|
||||
static value_type luminance(const rgba16& c) { return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0); }
|
||||
static value_type luminance(const rgba16& c)
|
||||
{
|
||||
return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(value_type v_, value_type a_ = 1)
|
||||
: v(v_)
|
||||
, a(a_)
|
||||
{}
|
||||
gray32(value_type v_, value_type a_ = 1) :
|
||||
v(v_), a(a_) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const self_type& c, value_type a_)
|
||||
: v(c.v)
|
||||
, a(a_)
|
||||
{}
|
||||
gray32(const self_type& c, value_type a_) :
|
||||
v(c.v), a(a_) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const rgba& c)
|
||||
: v(luminance(c))
|
||||
, a(value_type(c.a))
|
||||
{}
|
||||
gray32(const rgba& c) :
|
||||
v(luminance(c)),
|
||||
a(value_type(c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const rgba8& c)
|
||||
: v(luminance(c))
|
||||
, a(value_type(c.a / 255.0))
|
||||
{}
|
||||
gray32(const rgba8& c) :
|
||||
v(luminance(c)),
|
||||
a(value_type(c.a / 255.0)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const srgba8& c)
|
||||
: v(luminance(rgba32(c)))
|
||||
, a(value_type(c.a / 255.0))
|
||||
{}
|
||||
gray32(const srgba8& c) :
|
||||
v(luminance(rgba32(c))),
|
||||
a(value_type(c.a / 255.0)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const rgba16& c)
|
||||
: v(luminance(c))
|
||||
, a(value_type(c.a / 65535.0))
|
||||
{}
|
||||
gray32(const rgba16& c) :
|
||||
v(luminance(c)),
|
||||
a(value_type(c.a / 65535.0)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const rgba32& c)
|
||||
: v(luminance(c))
|
||||
, a(value_type(c.a))
|
||||
{}
|
||||
gray32(const rgba32& c) :
|
||||
v(luminance(c)),
|
||||
a(value_type(c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const gray8& c)
|
||||
: v(value_type(c.v / 255.0))
|
||||
, a(value_type(c.a / 255.0))
|
||||
{}
|
||||
gray32(const gray8& c) :
|
||||
v(value_type(c.v / 255.0)),
|
||||
a(value_type(c.a / 255.0)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const sgray8& c)
|
||||
: v(sRGB_conv<value_type>::rgb_from_sRGB(c.v))
|
||||
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||
{}
|
||||
gray32(const sgray8& c) :
|
||||
v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)),
|
||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gray32(const gray16& c)
|
||||
: v(value_type(c.v / 65535.0))
|
||||
, a(value_type(c.a / 65535.0))
|
||||
{}
|
||||
gray32(const gray16& c) :
|
||||
v(value_type(c.v / 65535.0)),
|
||||
a(value_type(c.a / 65535.0)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba() const { return rgba(v, v, v, a); }
|
||||
operator rgba() const
|
||||
{
|
||||
return rgba(v, v, v, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator gray8() const { return gray8(uround(v * 255.0), uround(a * 255.0)); }
|
||||
operator gray8() const
|
||||
{
|
||||
return gray8(uround(v * 255.0), uround(a * 255.0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator sgray8() const
|
||||
{
|
||||
// Return (non-premultiplied) sRGB values.
|
||||
return sgray8(sRGB_conv<value_type>::rgb_to_sRGB(v), sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
return sgray8(
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(v),
|
||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator gray16() const { return gray16(uround(v * 65535.0), uround(a * 65535.0)); }
|
||||
operator gray16() const
|
||||
{
|
||||
return gray16(uround(v * 65535.0), uround(a * 65535.0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba8() const
|
||||
|
@ -778,31 +879,58 @@ struct gray32
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a) { return a; }
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a) { return value_type(a); }
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type empty_value() { return 0; }
|
||||
static AGG_INLINE value_type empty_value()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type full_value() { return 1; }
|
||||
static AGG_INLINE value_type full_value()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_transparent() const { return a <= 0; }
|
||||
AGG_INLINE bool is_transparent() const
|
||||
{
|
||||
return a <= 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_opaque() const { return a >= 1; }
|
||||
AGG_INLINE bool is_opaque() const
|
||||
{
|
||||
return a >= 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type invert(value_type x) { return 1 - x; }
|
||||
static AGG_INLINE value_type invert(value_type x)
|
||||
{
|
||||
return 1 - x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type multiply(value_type a, value_type b) { return value_type(a * b); }
|
||||
static AGG_INLINE value_type multiply(value_type a, value_type b)
|
||||
{
|
||||
return value_type(a * b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type demultiply(value_type a, value_type b) { return (b == 0) ? 0 : value_type(a / b); }
|
||||
static AGG_INLINE value_type demultiply(value_type a, value_type b)
|
||||
{
|
||||
return (b == 0) ? 0 : value_type(a / b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<typename T>
|
||||
|
@ -819,10 +947,16 @@ struct gray32
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return value_type(a * b / cover_mask); }
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
||||
{
|
||||
return value_type(a * b / cover_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return cover_type(uround(a * b)); }
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
||||
{
|
||||
return cover_type(uround(a * b));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||
|
@ -859,47 +993,49 @@ struct gray32
|
|||
//--------------------------------------------------------------------
|
||||
self_type& opacity(double a_)
|
||||
{
|
||||
if (a_ < 0)
|
||||
a = 0;
|
||||
else if (a_ > 1)
|
||||
a = 1;
|
||||
else
|
||||
a = value_type(a_);
|
||||
if (a_ < 0) a = 0;
|
||||
else if (a_ > 1) a = 1;
|
||||
else a = value_type(a_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double opacity() const { return a; }
|
||||
double opacity() const
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
self_type& premultiply()
|
||||
{
|
||||
if (a < 0)
|
||||
v = 0;
|
||||
else if (a < 1)
|
||||
v *= a;
|
||||
if (a < 0) v = 0;
|
||||
else if(a < 1) v *= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
self_type& demultiply()
|
||||
{
|
||||
if (a < 0)
|
||||
v = 0;
|
||||
else if (a < 1)
|
||||
v /= a;
|
||||
if (a < 0) v = 0;
|
||||
else if (a < 1) v /= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
self_type gradient(self_type c, double k) const
|
||||
{
|
||||
return self_type(value_type(v + (c.v - v) * k), value_type(a + (c.a - a) * k));
|
||||
return self_type(
|
||||
value_type(v + (c.v - v) * k),
|
||||
value_type(a + (c.a - a) * k));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type no_color() { return self_type(0, 0); }
|
||||
static self_type no_color() { return self_type(0,0); }
|
||||
};
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
525
deps/agg/include/agg_color_rgba.h
vendored
525
deps/agg/include/agg_color_rgba.h
vendored
|
@ -28,39 +28,20 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_gamma_lut.h"
|
||||
|
||||
namespace agg {
|
||||
namespace agg
|
||||
{
|
||||
// Supported byte orders for RGB and RGBA pixel formats
|
||||
//=======================================================================
|
||||
struct order_rgb
|
||||
{
|
||||
enum rgb_e { R = 0, G = 1, B = 2, rgb_tag, hasAlpha = false };
|
||||
}; //----order_rgb
|
||||
struct order_bgr
|
||||
{
|
||||
enum bgr_e { B = 0, G = 1, R = 2, rgb_tag, hasAlpha = false };
|
||||
}; //----order_bgr
|
||||
struct order_rgba
|
||||
{
|
||||
enum rgba_e { R = 0, G = 1, B = 2, A = 3, rgba_tag, hasAlpha = true };
|
||||
}; //----order_rgba
|
||||
struct order_argb
|
||||
{
|
||||
enum argb_e { A = 0, R = 1, G = 2, B = 3, rgba_tag, hasAlpha = true };
|
||||
}; //----order_argb
|
||||
struct order_abgr
|
||||
{
|
||||
enum abgr_e { A = 0, B = 1, G = 2, R = 3, rgba_tag, hasAlpha = true };
|
||||
}; //----order_abgr
|
||||
struct order_bgra
|
||||
{
|
||||
enum bgra_e { B = 0, G = 1, R = 2, A = 3, rgba_tag, hasAlpha = true };
|
||||
}; //----order_bgra
|
||||
struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag, hasAlpha=false }; }; //----order_rgb
|
||||
struct order_bgr { enum bgr_e { B=0, G=1, R=2, rgb_tag, hasAlpha=false }; }; //----order_bgr
|
||||
struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag, hasAlpha=true }; }; //----order_rgba
|
||||
struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag, hasAlpha=true }; }; //----order_argb
|
||||
struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag, hasAlpha=true }; }; //----order_abgr
|
||||
struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag, hasAlpha=true }; }; //----order_bgra
|
||||
|
||||
// Colorspace tag types.
|
||||
struct linear
|
||||
{};
|
||||
struct sRGB
|
||||
{};
|
||||
struct linear {};
|
||||
struct sRGB {};
|
||||
|
||||
//====================================================================rgba
|
||||
struct rgba
|
||||
|
@ -76,20 +57,11 @@ struct rgba
|
|||
rgba() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba(double r_, double g_, double b_, double a_ = 1.0)
|
||||
: r(r_)
|
||||
, g(g_)
|
||||
, b(b_)
|
||||
, a(a_)
|
||||
{}
|
||||
rgba(double r_, double g_, double b_, double a_=1.0) :
|
||||
r(r_), g(g_), b(b_), a(a_) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba(const rgba& c, double a_)
|
||||
: r(c.r)
|
||||
, g(c.g)
|
||||
, b(c.b)
|
||||
, a(a_)
|
||||
{}
|
||||
rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba& clear()
|
||||
|
@ -108,17 +80,17 @@ struct rgba
|
|||
//--------------------------------------------------------------------
|
||||
rgba& opacity(double a_)
|
||||
{
|
||||
if (a_ < 0)
|
||||
a = 0;
|
||||
else if (a_ > 1)
|
||||
a = 1;
|
||||
else
|
||||
a = a_;
|
||||
if (a_ < 0) a = 0;
|
||||
else if (a_ > 1) a = 1;
|
||||
else a = a_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double opacity() const { return a; }
|
||||
double opacity() const
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba& premultiply()
|
||||
|
@ -142,7 +114,7 @@ struct rgba
|
|||
r *= a_;
|
||||
g *= a_;
|
||||
b *= a_;
|
||||
a = a_;
|
||||
a = a_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -164,6 +136,7 @@ struct rgba
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba gradient(rgba c, double k) const
|
||||
{
|
||||
|
@ -194,13 +167,17 @@ struct rgba
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static rgba no_color() { return rgba(0, 0, 0, 0); }
|
||||
static rgba no_color() { return rgba(0,0,0,0); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static rgba from_wavelength(double wl, double gamma = 1.0);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
explicit rgba(double wavelen, double gamma = 1.0) { *this = from_wavelength(wavelen, gamma); }
|
||||
explicit rgba(double wavelen, double gamma=1.0)
|
||||
{
|
||||
*this = from_wavelength(wavelen, gamma);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline rgba operator+(const rgba& a, const rgba& b)
|
||||
|
@ -249,10 +226,8 @@ inline rgba rgba::from_wavelength(double wl, double gamma)
|
|||
}
|
||||
|
||||
double s = 1.0;
|
||||
if (wl > 700.0)
|
||||
s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
|
||||
else if (wl < 420.0)
|
||||
s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
|
||||
if (wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
|
||||
else if (wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
|
||||
|
||||
t.r = pow(t.r * s, gamma);
|
||||
t.g = pow(t.g * s, gamma);
|
||||
|
@ -265,21 +240,24 @@ inline rgba rgba_pre(double r, double g, double b, double a)
|
|||
return rgba(r, g, b, a).premultiply();
|
||||
}
|
||||
|
||||
|
||||
//===================================================================rgba8
|
||||
template<class Colorspace>
|
||||
struct rgba8T
|
||||
{
|
||||
typedef int8u value_type;
|
||||
typedef int8u value_type;
|
||||
typedef int32u calc_type;
|
||||
typedef int32 long_type;
|
||||
enum base_scale_e {
|
||||
typedef int32 long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
base_shift = 8,
|
||||
base_scale = 1 << base_shift,
|
||||
base_mask = base_scale - 1,
|
||||
base_mask = base_scale - 1,
|
||||
base_MSB = 1 << (base_shift - 1)
|
||||
};
|
||||
typedef rgba8T self_type;
|
||||
|
||||
|
||||
value_type r;
|
||||
value_type g;
|
||||
value_type b;
|
||||
|
@ -339,23 +317,21 @@ struct rgba8T
|
|||
rgba8T() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask)
|
||||
: r(value_type(r_))
|
||||
, g(value_type(g_))
|
||||
, b(value_type(b_))
|
||||
, a(value_type(a_))
|
||||
{}
|
||||
rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) :
|
||||
r(value_type(r_)),
|
||||
g(value_type(g_)),
|
||||
b(value_type(b_)),
|
||||
a(value_type(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba8T(const rgba& c) { convert(*this, c); }
|
||||
rgba8T(const rgba& c)
|
||||
{
|
||||
convert(*this, c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba8T(const self_type& c, unsigned a_)
|
||||
: r(c.r)
|
||||
, g(c.g)
|
||||
, b(c.b)
|
||||
, a(value_type(a_))
|
||||
{}
|
||||
rgba8T(const self_type& c, unsigned a_) :
|
||||
r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class T>
|
||||
|
@ -373,25 +349,46 @@ struct rgba8T
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return double(a) / base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(uround(a * base_mask));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type empty_value() { return 0; }
|
||||
static AGG_INLINE value_type empty_value()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||
static AGG_INLINE value_type full_value()
|
||||
{
|
||||
return base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||
AGG_INLINE bool is_transparent() const
|
||||
{
|
||||
return a == 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||
AGG_INLINE bool is_opaque() const
|
||||
{
|
||||
return a == base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type invert(value_type x) { return base_mask - x; }
|
||||
static AGG_INLINE value_type invert(value_type x)
|
||||
{
|
||||
return base_mask - x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, exact over int8u.
|
||||
|
@ -412,8 +409,7 @@ struct rgba8T
|
|||
{
|
||||
return base_mask;
|
||||
}
|
||||
else
|
||||
return value_type((a * base_mask + (b >> 1)) / b);
|
||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -433,14 +429,23 @@ struct rgba8T
|
|||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, exact over int8u.
|
||||
// Specifically for multiplying a color component by a cover.
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, b); }
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
||||
{
|
||||
return multiply(a, b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply(b, a); }
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
||||
{
|
||||
return multiply(b, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
|
||||
{
|
||||
return p + q - multiply(p, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a.
|
||||
|
@ -467,17 +472,17 @@ struct rgba8T
|
|||
//--------------------------------------------------------------------
|
||||
self_type& opacity(double a_)
|
||||
{
|
||||
if (a_ < 0)
|
||||
a = 0;
|
||||
else if (a_ > 1)
|
||||
a = 1;
|
||||
else
|
||||
a = (value_type)uround(a_ * double(base_mask));
|
||||
if (a_ < 0) a = 0;
|
||||
else if (a_ > 1) a = 1;
|
||||
else a = (value_type)uround(a_ * double(base_mask));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double opacity() const { return double(a) / double(base_mask); }
|
||||
double opacity() const
|
||||
{
|
||||
return double(a) / double(base_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE self_type& premultiply()
|
||||
|
@ -599,7 +604,7 @@ struct rgba8T
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type no_color() { return self_type(0, 0, 0, 0); }
|
||||
static self_type no_color() { return self_type(0,0,0,0); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type from_wavelength(double wl, double gamma = 1.0)
|
||||
|
@ -612,9 +617,10 @@ typedef rgba8T<linear> rgba8;
|
|||
typedef rgba8T<sRGB> srgba8;
|
||||
|
||||
//-------------------------------------------------------------rgba8_pre
|
||||
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, unsigned a = rgba8::base_mask)
|
||||
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b,
|
||||
unsigned a = rgba8::base_mask)
|
||||
{
|
||||
return rgba8(r, g, b, a).premultiply();
|
||||
return rgba8(r,g,b,a).premultiply();
|
||||
}
|
||||
inline rgba8 rgba8_pre(const rgba8& c)
|
||||
{
|
||||
|
@ -622,7 +628,7 @@ inline rgba8 rgba8_pre(const rgba8& c)
|
|||
}
|
||||
inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
|
||||
{
|
||||
return rgba8(c, a).premultiply();
|
||||
return rgba8(c,a).premultiply();
|
||||
}
|
||||
inline rgba8 rgba8_pre(const rgba& c)
|
||||
{
|
||||
|
@ -630,9 +636,12 @@ inline rgba8 rgba8_pre(const rgba& c)
|
|||
}
|
||||
inline rgba8 rgba8_pre(const rgba& c, double a)
|
||||
{
|
||||
return rgba8(c, a).premultiply();
|
||||
return rgba8(c,a).premultiply();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------rgb8_packed
|
||||
inline rgba8 rgb8_packed(unsigned v)
|
||||
{
|
||||
|
@ -665,16 +674,19 @@ rgba8 rgba8_gamma_inv(rgba8 c, const GammaLUT& gamma)
|
|||
return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================================================================rgba16
|
||||
struct rgba16
|
||||
{
|
||||
typedef int16u value_type;
|
||||
typedef int32u calc_type;
|
||||
typedef int64 long_type;
|
||||
enum base_scale_e {
|
||||
typedef int64 long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
base_shift = 16,
|
||||
base_scale = 1 << base_shift,
|
||||
base_mask = base_scale - 1,
|
||||
base_mask = base_scale - 1,
|
||||
base_MSB = 1 << (base_shift - 1)
|
||||
};
|
||||
typedef rgba16 self_type;
|
||||
|
@ -688,81 +700,105 @@ struct rgba16
|
|||
rgba16() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask)
|
||||
: r(value_type(r_))
|
||||
, g(value_type(g_))
|
||||
, b(value_type(b_))
|
||||
, a(value_type(a_))
|
||||
{}
|
||||
rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
|
||||
r(value_type(r_)),
|
||||
g(value_type(g_)),
|
||||
b(value_type(b_)),
|
||||
a(value_type(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba16(const self_type& c, unsigned a_)
|
||||
: r(c.r)
|
||||
, g(c.g)
|
||||
, b(c.b)
|
||||
, a(value_type(a_))
|
||||
{}
|
||||
rgba16(const self_type& c, unsigned a_) :
|
||||
r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba16(const rgba& c)
|
||||
: r((value_type)uround(c.r * double(base_mask)))
|
||||
, g((value_type)uround(c.g * double(base_mask)))
|
||||
, b((value_type)uround(c.b * double(base_mask)))
|
||||
, a((value_type)uround(c.a * double(base_mask)))
|
||||
{}
|
||||
rgba16(const rgba& c) :
|
||||
r((value_type)uround(c.r * double(base_mask))),
|
||||
g((value_type)uround(c.g * double(base_mask))),
|
||||
b((value_type)uround(c.b * double(base_mask))),
|
||||
a((value_type)uround(c.a * double(base_mask))) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba16(const rgba8& c)
|
||||
: r(value_type((value_type(c.r) << 8) | c.r))
|
||||
, g(value_type((value_type(c.g) << 8) | c.g))
|
||||
, b(value_type((value_type(c.b) << 8) | c.b))
|
||||
, a(value_type((value_type(c.a) << 8) | c.a))
|
||||
{}
|
||||
rgba16(const rgba8& c) :
|
||||
r(value_type((value_type(c.r) << 8) | c.r)),
|
||||
g(value_type((value_type(c.g) << 8) | c.g)),
|
||||
b(value_type((value_type(c.b) << 8) | c.b)),
|
||||
a(value_type((value_type(c.a) << 8) | c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba16(const srgba8& c)
|
||||
: r(sRGB_conv<value_type>::rgb_from_sRGB(c.r))
|
||||
, g(sRGB_conv<value_type>::rgb_from_sRGB(c.g))
|
||||
, b(sRGB_conv<value_type>::rgb_from_sRGB(c.b))
|
||||
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||
{}
|
||||
rgba16(const srgba8& c) :
|
||||
r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)),
|
||||
g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)),
|
||||
b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)),
|
||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba() const { return rgba(r / 65535.0, g / 65535.0, b / 65535.0, a / 65535.0); }
|
||||
operator rgba() const
|
||||
{
|
||||
return rgba(
|
||||
r / 65535.0,
|
||||
g / 65535.0,
|
||||
b / 65535.0,
|
||||
a / 65535.0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba8() const { return rgba8(r >> 8, g >> 8, b >> 8, a >> 8); }
|
||||
operator rgba8() const
|
||||
{
|
||||
return rgba8(r >> 8, g >> 8, b >> 8, a >> 8);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator srgba8() const
|
||||
{
|
||||
// Return (non-premultiplied) sRGB values.
|
||||
return srgba8(sRGB_conv<value_type>::rgb_to_sRGB(r),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
return srgba8(
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(r),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return double(a) / base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(uround(a * base_mask));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type empty_value() { return 0; }
|
||||
static AGG_INLINE value_type empty_value()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||
static AGG_INLINE value_type full_value()
|
||||
{
|
||||
return base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||
AGG_INLINE bool is_transparent() const
|
||||
{
|
||||
return a == 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||
AGG_INLINE bool is_opaque() const
|
||||
{
|
||||
return a == base_mask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type invert(value_type x) { return base_mask - x; }
|
||||
static AGG_INLINE value_type invert(value_type x)
|
||||
{
|
||||
return base_mask - x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, exact over int16u.
|
||||
|
@ -783,8 +819,7 @@ struct rgba16
|
|||
{
|
||||
return base_mask;
|
||||
}
|
||||
else
|
||||
return value_type((a * base_mask + (b >> 1)) / b);
|
||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -804,14 +839,23 @@ struct rgba16
|
|||
//--------------------------------------------------------------------
|
||||
// Fixed-point multiply, almost exact over int16u.
|
||||
// Specifically for multiplying a color component by a cover.
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, (b << 8) | b); }
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
||||
{
|
||||
return multiply(a, (b << 8) | b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply((a << 8) | a, b) >> 8; }
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
||||
{
|
||||
return multiply((a << 8) | a, b) >> 8;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
|
||||
{
|
||||
return p + q - multiply(p, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a.
|
||||
|
@ -838,16 +882,17 @@ struct rgba16
|
|||
//--------------------------------------------------------------------
|
||||
AGG_INLINE self_type& opacity(double a_)
|
||||
{
|
||||
if (a_ < 0)
|
||||
a = 0;
|
||||
if (a_ > 1)
|
||||
a = 1;
|
||||
if (a_ < 0) a = 0;
|
||||
if (a_ > 1) a = 1;
|
||||
a = value_type(uround(a_ * double(base_mask)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double opacity() const { return double(a) / double(base_mask); }
|
||||
double opacity() const
|
||||
{
|
||||
return double(a) / double(base_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE self_type& premultiply()
|
||||
|
@ -969,7 +1014,7 @@ struct rgba16
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type no_color() { return self_type(0, 0, 0, 0); }
|
||||
static self_type no_color() { return self_type(0,0,0,0); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type from_wavelength(double wl, double gamma = 1.0)
|
||||
|
@ -978,6 +1023,7 @@ struct rgba16
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------rgba16_gamma_dir
|
||||
template<class GammaLUT>
|
||||
rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma)
|
||||
|
@ -1009,100 +1055,127 @@ struct rgba32
|
|||
rgba32() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba32(value_type r_, value_type g_, value_type b_, value_type a_ = 1)
|
||||
: r(r_)
|
||||
, g(g_)
|
||||
, b(b_)
|
||||
, a(a_)
|
||||
{}
|
||||
rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) :
|
||||
r(r_), g(g_), b(b_), a(a_) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba32(const self_type& c, float a_)
|
||||
: r(c.r)
|
||||
, g(c.g)
|
||||
, b(c.b)
|
||||
, a(a_)
|
||||
{}
|
||||
rgba32(const self_type& c, float a_) :
|
||||
r(c.r), g(c.g), b(c.b), a(a_) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba32(const rgba& c)
|
||||
: r(value_type(c.r))
|
||||
, g(value_type(c.g))
|
||||
, b(value_type(c.b))
|
||||
, a(value_type(c.a))
|
||||
{}
|
||||
rgba32(const rgba& c) :
|
||||
r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba32(const rgba8& c)
|
||||
: r(value_type(c.r / 255.0))
|
||||
, g(value_type(c.g / 255.0))
|
||||
, b(value_type(c.b / 255.0))
|
||||
, a(value_type(c.a / 255.0))
|
||||
{}
|
||||
rgba32(const rgba8& c) :
|
||||
r(value_type(c.r / 255.0)),
|
||||
g(value_type(c.g / 255.0)),
|
||||
b(value_type(c.b / 255.0)),
|
||||
a(value_type(c.a / 255.0)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba32(const srgba8& c)
|
||||
: r(sRGB_conv<value_type>::rgb_from_sRGB(c.r))
|
||||
, g(sRGB_conv<value_type>::rgb_from_sRGB(c.g))
|
||||
, b(sRGB_conv<value_type>::rgb_from_sRGB(c.b))
|
||||
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||
{}
|
||||
rgba32(const srgba8& c) :
|
||||
r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)),
|
||||
g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)),
|
||||
b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)),
|
||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rgba32(const rgba16& c)
|
||||
: r(value_type(c.r / 65535.0))
|
||||
, g(value_type(c.g / 65535.0))
|
||||
, b(value_type(c.b / 65535.0))
|
||||
, a(value_type(c.a / 65535.0))
|
||||
{}
|
||||
rgba32(const rgba16& c) :
|
||||
r(value_type(c.r / 65535.0)),
|
||||
g(value_type(c.g / 65535.0)),
|
||||
b(value_type(c.b / 65535.0)),
|
||||
a(value_type(c.a / 65535.0)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba() const { return rgba(r, g, b, a); }
|
||||
operator rgba() const
|
||||
{
|
||||
return rgba(r, g, b, a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba8() const { return rgba8(uround(r * 255.0), uround(g * 255.0), uround(b * 255.0), uround(a * 255.0)); }
|
||||
operator rgba8() const
|
||||
{
|
||||
return rgba8(
|
||||
uround(r * 255.0),
|
||||
uround(g * 255.0),
|
||||
uround(b * 255.0),
|
||||
uround(a * 255.0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator srgba8() const
|
||||
{
|
||||
return srgba8(sRGB_conv<value_type>::rgb_to_sRGB(r),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
return srgba8(
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(r),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
||||
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
operator rgba16() const
|
||||
{
|
||||
return rgba8(uround(r * 65535.0), uround(g * 65535.0), uround(b * 65535.0), uround(a * 65535.0));
|
||||
return rgba8(
|
||||
uround(r * 65535.0),
|
||||
uround(g * 65535.0),
|
||||
uround(b * 65535.0),
|
||||
uround(a * 65535.0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a) { return a; }
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a) { return value_type(a); }
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(a);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type empty_value() { return 0; }
|
||||
static AGG_INLINE value_type empty_value()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type full_value() { return 1; }
|
||||
static AGG_INLINE value_type full_value()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_transparent() const { return a <= 0; }
|
||||
AGG_INLINE bool is_transparent() const
|
||||
{
|
||||
return a <= 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE bool is_opaque() const { return a >= 1; }
|
||||
AGG_INLINE bool is_opaque() const
|
||||
{
|
||||
return a >= 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type invert(value_type x) { return 1 - x; }
|
||||
static AGG_INLINE value_type invert(value_type x)
|
||||
{
|
||||
return 1 - x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type multiply(value_type a, value_type b) { return value_type(a * b); }
|
||||
static AGG_INLINE value_type multiply(value_type a, value_type b)
|
||||
{
|
||||
return value_type(a * b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type demultiply(value_type a, value_type b) { return (b == 0) ? 0 : value_type(a / b); }
|
||||
static AGG_INLINE value_type demultiply(value_type a, value_type b)
|
||||
{
|
||||
return (b == 0) ? 0 : value_type(a / b);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<typename T>
|
||||
|
@ -1119,10 +1192,16 @@ struct rgba32
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return value_type(a * b / cover_mask); }
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
||||
{
|
||||
return value_type(a * b / cover_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return cover_type(uround(a * b)); }
|
||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
||||
{
|
||||
return cover_type(uround(a * b));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||
|
@ -1159,17 +1238,17 @@ struct rgba32
|
|||
//--------------------------------------------------------------------
|
||||
AGG_INLINE self_type& opacity(double a_)
|
||||
{
|
||||
if (a_ < 0)
|
||||
a = 0;
|
||||
else if (a_ > 1)
|
||||
a = 1;
|
||||
else
|
||||
a = value_type(a_);
|
||||
if (a_ < 0) a = 0;
|
||||
else if (a_ > 1) a = 1;
|
||||
else a = value_type(a_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double opacity() const { return a; }
|
||||
double opacity() const
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE self_type& premultiply()
|
||||
|
@ -1245,14 +1324,10 @@ struct rgba32
|
|||
b += mult_cover(c.b, cover);
|
||||
a += mult_cover(c.a, cover);
|
||||
}
|
||||
if (a > 1)
|
||||
a = 1;
|
||||
if (r > a)
|
||||
r = a;
|
||||
if (g > a)
|
||||
g = a;
|
||||
if (b > a)
|
||||
b = a;
|
||||
if (a > 1) a = 1;
|
||||
if (r > a) r = a;
|
||||
if (g > a) g = a;
|
||||
if (b > a) b = a;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -1274,7 +1349,7 @@ struct rgba32
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type no_color() { return self_type(0, 0, 0, 0); }
|
||||
static self_type no_color() { return self_type(0,0,0,0); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static self_type from_wavelength(double wl, double gamma = 1)
|
||||
|
@ -1282,6 +1357,8 @@ struct rgba32
|
|||
return self_type(rgba::from_wavelength(wl, gamma));
|
||||
}
|
||||
};
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
1
deps/agg/include/agg_config.h
vendored
1
deps/agg/include/agg_config.h
vendored
|
@ -26,6 +26,7 @@
|
|||
// but it won't result any crash and the rest of the library will remain
|
||||
// fully functional.
|
||||
|
||||
|
||||
//---------------------------------------
|
||||
// 2. Default rendering_buffer type. Can be:
|
||||
//
|
||||
|
|
157
deps/agg/include/agg_conv_adaptor_vcgen.h
vendored
157
deps/agg/include/agg_conv_adaptor_vcgen.h
vendored
|
@ -18,95 +18,106 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
//------------------------------------------------------------null_markers
|
||||
struct null_markers
|
||||
namespace agg
|
||||
{
|
||||
void remove_all() {}
|
||||
void add_vertex(double, double, unsigned) {}
|
||||
void prepare_src() {}
|
||||
|
||||
void rewind(unsigned) {}
|
||||
unsigned vertex(double*, double*) { return path_cmd_stop; }
|
||||
unsigned type() const { return 0; }
|
||||
};
|
||||
|
||||
//------------------------------------------------------conv_adaptor_vcgen
|
||||
template<class VertexSource, class Generator, class Markers = null_markers>
|
||||
class conv_adaptor_vcgen
|
||||
{
|
||||
enum status { initial, accumulate, generate };
|
||||
|
||||
public:
|
||||
explicit conv_adaptor_vcgen(VertexSource& source)
|
||||
: m_source(&source)
|
||||
, m_status(initial)
|
||||
{}
|
||||
|
||||
conv_adaptor_vcgen(conv_adaptor_vcgen<VertexSource, Generator, Markers>&&) = default;
|
||||
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
Generator& generator() { return m_generator; }
|
||||
const Generator& generator() const { return m_generator; }
|
||||
|
||||
Markers& markers() { return m_markers; }
|
||||
const Markers& markers() const { return m_markers; }
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
//------------------------------------------------------------null_markers
|
||||
struct null_markers
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_status = initial;
|
||||
}
|
||||
void remove_all() {}
|
||||
void add_vertex(double, double, unsigned) {}
|
||||
void prepare_src() {}
|
||||
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned type() const { return m_source->type(); }
|
||||
void rewind(unsigned) {}
|
||||
unsigned vertex(double*, double*) { return path_cmd_stop; }
|
||||
unsigned type() const { return 0; }
|
||||
};
|
||||
|
||||
private:
|
||||
// Prohibit copying
|
||||
conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
|
||||
const conv_adaptor_vcgen<VertexSource, Generator, Markers>&
|
||||
operator=(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
Generator m_generator;
|
||||
Markers m_markers;
|
||||
status m_status;
|
||||
unsigned m_last_cmd;
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class Generator, class Markers>
|
||||
unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_stop;
|
||||
bool done = false;
|
||||
while (!done)
|
||||
//------------------------------------------------------conv_adaptor_vcgen
|
||||
template<class VertexSource,
|
||||
class Generator,
|
||||
class Markers=null_markers> class conv_adaptor_vcgen
|
||||
{
|
||||
switch (m_status)
|
||||
enum status
|
||||
{
|
||||
initial,
|
||||
accumulate,
|
||||
generate
|
||||
};
|
||||
|
||||
public:
|
||||
explicit conv_adaptor_vcgen(VertexSource& source) :
|
||||
m_source(&source),
|
||||
m_status(initial)
|
||||
{}
|
||||
|
||||
conv_adaptor_vcgen(conv_adaptor_vcgen<VertexSource, Generator, Markers> &&) = default;
|
||||
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
Generator& generator() { return m_generator; }
|
||||
const Generator& generator() const { return m_generator; }
|
||||
|
||||
Markers& markers() { return m_markers; }
|
||||
const Markers& markers() const { return m_markers; }
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_status = initial;
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned type() const { return m_source->type(); }
|
||||
|
||||
private:
|
||||
// Prohibit copying
|
||||
conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
|
||||
const conv_adaptor_vcgen<VertexSource, Generator, Markers>&
|
||||
operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
Generator m_generator;
|
||||
Markers m_markers;
|
||||
status m_status;
|
||||
unsigned m_last_cmd;
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class Generator, class Markers>
|
||||
unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_stop;
|
||||
bool done = false;
|
||||
while(!done)
|
||||
{
|
||||
switch(m_status)
|
||||
{
|
||||
case initial:
|
||||
m_markers.remove_all();
|
||||
m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
|
||||
m_status = accumulate;
|
||||
|
||||
case accumulate:
|
||||
if (is_stop(m_last_cmd))
|
||||
return path_cmd_stop;
|
||||
if(is_stop(m_last_cmd)) return path_cmd_stop;
|
||||
|
||||
m_generator.remove_all();
|
||||
m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
|
||||
m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
|
||||
|
||||
for (;;)
|
||||
for(;;)
|
||||
{
|
||||
cmd = m_source->vertex(x, y);
|
||||
if (is_vertex(cmd))
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
m_last_cmd = cmd;
|
||||
if (is_move_to(cmd))
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
m_start_x = *x;
|
||||
m_start_y = *y;
|
||||
|
@ -117,12 +128,12 @@ unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (is_stop(cmd))
|
||||
if(is_stop(cmd))
|
||||
{
|
||||
m_last_cmd = path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
if (is_end_poly(cmd))
|
||||
if(is_end_poly(cmd))
|
||||
{
|
||||
m_generator.add_vertex(*x, *y, cmd);
|
||||
break;
|
||||
|
@ -134,18 +145,18 @@ unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x,
|
|||
|
||||
case generate:
|
||||
cmd = m_generator.vertex(x, y);
|
||||
if (is_stop(cmd))
|
||||
if(is_stop(cmd))
|
||||
{
|
||||
m_status = accumulate;
|
||||
break;
|
||||
}
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
return cmd;
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
245
deps/agg/include/agg_conv_adaptor_vpgen.h
vendored
245
deps/agg/include/agg_conv_adaptor_vpgen.h
vendored
|
@ -18,140 +18,143 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//======================================================conv_adaptor_vpgen
|
||||
template<class VertexSource, class VPGen>
|
||||
class conv_adaptor_vpgen
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
explicit conv_adaptor_vpgen(VertexSource& source)
|
||||
: m_source(&source)
|
||||
{}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
VPGen& vpgen() { return m_vpgen; }
|
||||
const VPGen& vpgen() const { return m_vpgen; }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned type() const { return m_source->type(); }
|
||||
|
||||
private:
|
||||
conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&);
|
||||
const conv_adaptor_vpgen<VertexSource, VPGen>& operator=(const conv_adaptor_vpgen<VertexSource, VPGen>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
VPGen m_vpgen;
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
unsigned m_poly_flags;
|
||||
int m_vertices;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class VPGen>
|
||||
void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_vpgen.reset();
|
||||
m_start_x = 0;
|
||||
m_start_y = 0;
|
||||
m_poly_flags = 0;
|
||||
m_vertices = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class VPGen>
|
||||
unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_stop;
|
||||
for (;;)
|
||||
//======================================================conv_adaptor_vpgen
|
||||
template<class VertexSource, class VPGen> class conv_adaptor_vpgen
|
||||
{
|
||||
cmd = m_vpgen.vertex(x, y);
|
||||
if (!is_stop(cmd))
|
||||
break;
|
||||
public:
|
||||
explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
if (m_poly_flags && !m_vpgen.auto_unclose())
|
||||
{
|
||||
*x = 0.0;
|
||||
*y = 0.0;
|
||||
cmd = m_poly_flags;
|
||||
m_poly_flags = 0;
|
||||
break;
|
||||
}
|
||||
VPGen& vpgen() { return m_vpgen; }
|
||||
const VPGen& vpgen() const { return m_vpgen; }
|
||||
|
||||
if (m_vertices < 0)
|
||||
{
|
||||
if (m_vertices < -1)
|
||||
{
|
||||
m_vertices = 0;
|
||||
return path_cmd_stop;
|
||||
}
|
||||
m_vpgen.move_to(m_start_x, m_start_y);
|
||||
m_vertices = 1;
|
||||
continue;
|
||||
}
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned type() const { return m_source->type(); }
|
||||
|
||||
double tx, ty;
|
||||
cmd = m_source->vertex(&tx, &ty);
|
||||
if (is_vertex(cmd))
|
||||
private:
|
||||
conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&);
|
||||
const conv_adaptor_vpgen<VertexSource, VPGen>&
|
||||
operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
VPGen m_vpgen;
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
unsigned m_poly_flags;
|
||||
int m_vertices;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class VPGen>
|
||||
void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_vpgen.reset();
|
||||
m_start_x = 0;
|
||||
m_start_y = 0;
|
||||
m_poly_flags = 0;
|
||||
m_vertices = 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class VPGen>
|
||||
unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_stop;
|
||||
for(;;)
|
||||
{
|
||||
if (is_move_to(cmd))
|
||||
cmd = m_vpgen.vertex(x, y);
|
||||
if(!is_stop(cmd)) break;
|
||||
|
||||
if(m_poly_flags && !m_vpgen.auto_unclose())
|
||||
{
|
||||
if (m_vpgen.auto_close() && m_vertices > 2)
|
||||
{
|
||||
m_vpgen.line_to(m_start_x, m_start_y);
|
||||
m_poly_flags = path_cmd_end_poly | path_flags_close;
|
||||
m_start_x = tx;
|
||||
m_start_y = ty;
|
||||
m_vertices = -1;
|
||||
continue;
|
||||
}
|
||||
m_vpgen.move_to(tx, ty);
|
||||
m_start_x = tx;
|
||||
m_start_y = ty;
|
||||
m_vertices = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vpgen.line_to(tx, ty);
|
||||
++m_vertices;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_end_poly(cmd))
|
||||
{
|
||||
m_poly_flags = cmd;
|
||||
if (is_closed(cmd) || m_vpgen.auto_close())
|
||||
{
|
||||
if (m_vpgen.auto_close())
|
||||
m_poly_flags |= path_flags_close;
|
||||
if (m_vertices > 2)
|
||||
{
|
||||
m_vpgen.line_to(m_start_x, m_start_y);
|
||||
}
|
||||
m_vertices = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// path_cmd_stop
|
||||
if (m_vpgen.auto_close() && m_vertices > 2)
|
||||
{
|
||||
m_vpgen.line_to(m_start_x, m_start_y);
|
||||
m_poly_flags = path_cmd_end_poly | path_flags_close;
|
||||
m_vertices = -2;
|
||||
continue;
|
||||
}
|
||||
*x = 0.0;
|
||||
*y = 0.0;
|
||||
cmd = m_poly_flags;
|
||||
m_poly_flags = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_vertices < 0)
|
||||
{
|
||||
if(m_vertices < -1)
|
||||
{
|
||||
m_vertices = 0;
|
||||
return path_cmd_stop;
|
||||
}
|
||||
m_vpgen.move_to(m_start_x, m_start_y);
|
||||
m_vertices = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
double tx, ty;
|
||||
cmd = m_source->vertex(&tx, &ty);
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
if(m_vpgen.auto_close() && m_vertices > 2)
|
||||
{
|
||||
m_vpgen.line_to(m_start_x, m_start_y);
|
||||
m_poly_flags = path_cmd_end_poly | path_flags_close;
|
||||
m_start_x = tx;
|
||||
m_start_y = ty;
|
||||
m_vertices = -1;
|
||||
continue;
|
||||
}
|
||||
m_vpgen.move_to(tx, ty);
|
||||
m_start_x = tx;
|
||||
m_start_y = ty;
|
||||
m_vertices = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vpgen.line_to(tx, ty);
|
||||
++m_vertices;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_end_poly(cmd))
|
||||
{
|
||||
m_poly_flags = cmd;
|
||||
if(is_closed(cmd) || m_vpgen.auto_close())
|
||||
{
|
||||
if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close;
|
||||
if(m_vertices > 2)
|
||||
{
|
||||
m_vpgen.line_to(m_start_x, m_start_y);
|
||||
}
|
||||
m_vertices = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// path_cmd_stop
|
||||
if(m_vpgen.auto_close() && m_vertices > 2)
|
||||
{
|
||||
m_vpgen.line_to(m_start_x, m_start_y);
|
||||
m_poly_flags = path_cmd_end_poly | path_flags_close;
|
||||
m_vertices = -2;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
return cmd;
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
|
34
deps/agg/include/agg_conv_bspline.h
vendored
34
deps/agg/include/agg_conv_bspline.h
vendored
|
@ -19,26 +19,30 @@
|
|||
#include "agg_vcgen_bspline.h"
|
||||
#include "agg_conv_adaptor_vcgen.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//---------------------------------------------------------conv_bspline
|
||||
template<class VertexSource>
|
||||
struct conv_bspline : public conv_adaptor_vcgen<VertexSource, vcgen_bspline>
|
||||
namespace agg
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_bspline> base_type;
|
||||
|
||||
conv_bspline(VertexSource& vs)
|
||||
: conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs)
|
||||
{}
|
||||
//---------------------------------------------------------conv_bspline
|
||||
template<class VertexSource>
|
||||
struct conv_bspline : public conv_adaptor_vcgen<VertexSource, vcgen_bspline>
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_bspline> base_type;
|
||||
|
||||
void interpolation_step(double v) { base_type::generator().interpolation_step(v); }
|
||||
double interpolation_step() const { return base_type::generator().interpolation_step(); }
|
||||
conv_bspline(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs) {}
|
||||
|
||||
private:
|
||||
conv_bspline(const conv_bspline<VertexSource>&);
|
||||
const conv_bspline<VertexSource>& operator=(const conv_bspline<VertexSource>&);
|
||||
};
|
||||
void interpolation_step(double v) { base_type::generator().interpolation_step(v); }
|
||||
double interpolation_step() const { return base_type::generator().interpolation_step(); }
|
||||
|
||||
private:
|
||||
conv_bspline(const conv_bspline<VertexSource>&);
|
||||
const conv_bspline<VertexSource>&
|
||||
operator = (const conv_bspline<VertexSource>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
|
44
deps/agg/include/agg_conv_clip_polygon.h
vendored
44
deps/agg/include/agg_conv_clip_polygon.h
vendored
|
@ -30,31 +30,35 @@
|
|||
#include "agg_conv_adaptor_vpgen.h"
|
||||
#include "agg_vpgen_clip_polygon.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=======================================================conv_clip_polygon
|
||||
template<class VertexSource>
|
||||
struct conv_clip_polygon : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>
|
||||
namespace agg
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon> base_type;
|
||||
|
||||
conv_clip_polygon(VertexSource& vs)
|
||||
: conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs)
|
||||
{}
|
||||
//=======================================================conv_clip_polygon
|
||||
template<class VertexSource>
|
||||
struct conv_clip_polygon : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon> base_type;
|
||||
|
||||
void clip_box(double _x1, double _y1, double _x2, double _y2) { base_type::vpgen().clip_box(_x1, _y1, _x2, _y2); }
|
||||
conv_clip_polygon(VertexSource& vs) :
|
||||
conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs) {}
|
||||
|
||||
double x1() const { return base_type::vpgen().x1(); }
|
||||
double y1() const { return base_type::vpgen().y1(); }
|
||||
double x2() const { return base_type::vpgen().x2(); }
|
||||
double y2() const { return base_type::vpgen().y2(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
void clip_box(double _x1, double _y1, double _x2, double _y2)
|
||||
{
|
||||
base_type::vpgen().clip_box(_x1, _y1, _x2, _y2);
|
||||
}
|
||||
|
||||
private:
|
||||
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
|
||||
const conv_clip_polygon<VertexSource>& operator=(const conv_clip_polygon<VertexSource>&);
|
||||
};
|
||||
double x1() const { return base_type::vpgen().x1(); }
|
||||
double y1() const { return base_type::vpgen().y1(); }
|
||||
double x2() const { return base_type::vpgen().x2(); }
|
||||
double y2() const { return base_type::vpgen().y2(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
|
||||
const conv_clip_polygon<VertexSource>&
|
||||
operator = (const conv_clip_polygon<VertexSource>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
44
deps/agg/include/agg_conv_clip_polyline.h
vendored
44
deps/agg/include/agg_conv_clip_polyline.h
vendored
|
@ -30,31 +30,35 @@
|
|||
#include "agg_conv_adaptor_vpgen.h"
|
||||
#include "agg_vpgen_clip_polyline.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=======================================================conv_clip_polyline
|
||||
template<class VertexSource>
|
||||
struct conv_clip_polyline : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>
|
||||
namespace agg
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> base_type;
|
||||
|
||||
conv_clip_polyline(VertexSource& vs)
|
||||
: conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs)
|
||||
{}
|
||||
//=======================================================conv_clip_polyline
|
||||
template<class VertexSource>
|
||||
struct conv_clip_polyline : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> base_type;
|
||||
|
||||
void clip_box(double _x1, double _y1, double _x2, double _y2) { base_type::vpgen().clip_box(_x1, _y1, _x2, _y2); }
|
||||
conv_clip_polyline(VertexSource& vs) :
|
||||
conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs) {}
|
||||
|
||||
double x1() const { return base_type::vpgen().x1(); }
|
||||
double y1() const { return base_type::vpgen().y1(); }
|
||||
double x2() const { return base_type::vpgen().x2(); }
|
||||
double y2() const { return base_type::vpgen().y2(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
void clip_box(double _x1, double _y1, double _x2, double _y2)
|
||||
{
|
||||
base_type::vpgen().clip_box(_x1, _y1, _x2, _y2);
|
||||
}
|
||||
|
||||
private:
|
||||
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
|
||||
const conv_clip_polyline<VertexSource>& operator=(const conv_clip_polyline<VertexSource>&);
|
||||
};
|
||||
double x1() const { return base_type::vpgen().x1(); }
|
||||
double y1() const { return base_type::vpgen().y1(); }
|
||||
double x2() const { return base_type::vpgen().x2(); }
|
||||
double y2() const { return base_type::vpgen().y2(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
|
||||
const conv_clip_polyline<VertexSource>&
|
||||
operator = (const conv_clip_polyline<VertexSource>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
183
deps/agg/include/agg_conv_close_polygon.h
vendored
183
deps/agg/include/agg_conv_close_polygon.h
vendored
|
@ -18,105 +18,108 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//======================================================conv_close_polygon
|
||||
template<class VertexSource>
|
||||
class conv_close_polygon
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
explicit conv_close_polygon(VertexSource& vs)
|
||||
: m_source(&vs)
|
||||
{}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
conv_close_polygon(const conv_close_polygon<VertexSource>&);
|
||||
const conv_close_polygon<VertexSource>& operator=(const conv_close_polygon<VertexSource>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
unsigned m_cmd[2];
|
||||
double m_x[2];
|
||||
double m_y[2];
|
||||
unsigned m_vertex;
|
||||
bool m_line_to;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void conv_close_polygon<VertexSource>::rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_vertex = 2;
|
||||
m_line_to = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
unsigned conv_close_polygon<VertexSource>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_stop;
|
||||
for (;;)
|
||||
//======================================================conv_close_polygon
|
||||
template<class VertexSource> class conv_close_polygon
|
||||
{
|
||||
if (m_vertex < 2)
|
||||
{
|
||||
*x = m_x[m_vertex];
|
||||
*y = m_y[m_vertex];
|
||||
cmd = m_cmd[m_vertex];
|
||||
++m_vertex;
|
||||
break;
|
||||
}
|
||||
public:
|
||||
explicit conv_close_polygon(VertexSource& vs) : m_source(&vs) {}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
cmd = m_source->vertex(x, y);
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
if (is_end_poly(cmd))
|
||||
{
|
||||
cmd |= path_flags_close;
|
||||
break;
|
||||
}
|
||||
private:
|
||||
conv_close_polygon(const conv_close_polygon<VertexSource>&);
|
||||
const conv_close_polygon<VertexSource>&
|
||||
operator = (const conv_close_polygon<VertexSource>&);
|
||||
|
||||
if (is_stop(cmd))
|
||||
{
|
||||
if (m_line_to)
|
||||
{
|
||||
m_cmd[0] = path_cmd_end_poly | path_flags_close;
|
||||
m_cmd[1] = path_cmd_stop;
|
||||
m_vertex = 0;
|
||||
m_line_to = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
VertexSource* m_source;
|
||||
unsigned m_cmd[2];
|
||||
double m_x[2];
|
||||
double m_y[2];
|
||||
unsigned m_vertex;
|
||||
bool m_line_to;
|
||||
};
|
||||
|
||||
if (is_move_to(cmd))
|
||||
{
|
||||
if (m_line_to)
|
||||
{
|
||||
m_x[0] = 0.0;
|
||||
m_y[0] = 0.0;
|
||||
m_cmd[0] = path_cmd_end_poly | path_flags_close;
|
||||
m_x[1] = *x;
|
||||
m_y[1] = *y;
|
||||
m_cmd[1] = cmd;
|
||||
m_vertex = 0;
|
||||
m_line_to = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_vertex(cmd))
|
||||
{
|
||||
m_line_to = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void conv_close_polygon<VertexSource>::rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_vertex = 2;
|
||||
m_line_to = false;
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
unsigned conv_close_polygon<VertexSource>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_stop;
|
||||
for(;;)
|
||||
{
|
||||
if(m_vertex < 2)
|
||||
{
|
||||
*x = m_x[m_vertex];
|
||||
*y = m_y[m_vertex];
|
||||
cmd = m_cmd[m_vertex];
|
||||
++m_vertex;
|
||||
break;
|
||||
}
|
||||
|
||||
cmd = m_source->vertex(x, y);
|
||||
|
||||
if(is_end_poly(cmd))
|
||||
{
|
||||
cmd |= path_flags_close;
|
||||
break;
|
||||
}
|
||||
|
||||
if(is_stop(cmd))
|
||||
{
|
||||
if(m_line_to)
|
||||
{
|
||||
m_cmd[0] = path_cmd_end_poly | path_flags_close;
|
||||
m_cmd[1] = path_cmd_stop;
|
||||
m_vertex = 0;
|
||||
m_line_to = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
if(m_line_to)
|
||||
{
|
||||
m_x[0] = 0.0;
|
||||
m_y[0] = 0.0;
|
||||
m_cmd[0] = path_cmd_end_poly | path_flags_close;
|
||||
m_x[1] = *x;
|
||||
m_y[1] = *y;
|
||||
m_cmd[1] = cmd;
|
||||
m_vertex = 0;
|
||||
m_line_to = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
m_line_to = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
85
deps/agg/include/agg_conv_concat.h
vendored
85
deps/agg/include/agg_conv_concat.h
vendored
|
@ -18,57 +18,56 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
//=============================================================conv_concat
|
||||
// Concatenation of two paths. Usually used to combine lines or curves
|
||||
// with markers such as arrowheads
|
||||
template<class VS1, class VS2>
|
||||
class conv_concat
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
conv_concat(VS1& source1, VS2& source2)
|
||||
: m_source1(&source1)
|
||||
, m_source2(&source2)
|
||||
, m_status(2)
|
||||
{}
|
||||
void attach1(VS1& source) { m_source1 = &source; }
|
||||
void attach2(VS2& source) { m_source2 = &source; }
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
//=============================================================conv_concat
|
||||
// Concatenation of two paths. Usually used to combine lines or curves
|
||||
// with markers such as arrowheads
|
||||
template<class VS1, class VS2> class conv_concat
|
||||
{
|
||||
m_source1->rewind(path_id);
|
||||
m_source2->rewind(0);
|
||||
m_status = 0;
|
||||
}
|
||||
public:
|
||||
conv_concat(VS1& source1, VS2& source2) :
|
||||
m_source1(&source1), m_source2(&source2), m_status(2) {}
|
||||
void attach1(VS1& source) { m_source1 = &source; }
|
||||
void attach2(VS2& source) { m_source2 = &source; }
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd;
|
||||
if (m_status == 0)
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
cmd = m_source1->vertex(x, y);
|
||||
if (!is_stop(cmd))
|
||||
return cmd;
|
||||
m_status = 1;
|
||||
m_source1->rewind(path_id);
|
||||
m_source2->rewind(0);
|
||||
m_status = 0;
|
||||
}
|
||||
if (m_status == 1)
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
cmd = m_source2->vertex(x, y);
|
||||
if (!is_stop(cmd))
|
||||
return cmd;
|
||||
m_status = 2;
|
||||
unsigned cmd;
|
||||
if(m_status == 0)
|
||||
{
|
||||
cmd = m_source1->vertex(x, y);
|
||||
if(!is_stop(cmd)) return cmd;
|
||||
m_status = 1;
|
||||
}
|
||||
if(m_status == 1)
|
||||
{
|
||||
cmd = m_source2->vertex(x, y);
|
||||
if(!is_stop(cmd)) return cmd;
|
||||
m_status = 2;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
|
||||
private:
|
||||
conv_concat(const conv_concat<VS1, VS2>&);
|
||||
const conv_concat<VS1, VS2>& operator=(const conv_concat<VS1, VS2>&);
|
||||
private:
|
||||
conv_concat(const conv_concat<VS1, VS2>&);
|
||||
const conv_concat<VS1, VS2>&
|
||||
operator = (const conv_concat<VS1, VS2>&);
|
||||
|
||||
VS1* m_source1;
|
||||
VS2* m_source2;
|
||||
int m_status;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
VS1* m_source1;
|
||||
VS2* m_source2;
|
||||
int m_status;
|
||||
};
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
61
deps/agg/include/agg_conv_contour.h
vendored
61
deps/agg/include/agg_conv_contour.h
vendored
|
@ -23,40 +23,43 @@
|
|||
#include "agg_vcgen_contour.h"
|
||||
#include "agg_conv_adaptor_vcgen.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-----------------------------------------------------------conv_contour
|
||||
template<class VertexSource>
|
||||
struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour>
|
||||
namespace agg
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type;
|
||||
|
||||
conv_contour(VertexSource& vs)
|
||||
: conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
|
||||
{}
|
||||
//-----------------------------------------------------------conv_contour
|
||||
template<class VertexSource>
|
||||
struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour>
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type;
|
||||
|
||||
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
|
||||
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
|
||||
void width(double w) { base_type::generator().width(w); }
|
||||
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
|
||||
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
|
||||
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
|
||||
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
|
||||
void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); }
|
||||
conv_contour(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
line_join_e line_join() const { return base_type::generator().line_join(); }
|
||||
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
||||
double width() const { return base_type::generator().width(); }
|
||||
double miter_limit() const { return base_type::generator().miter_limit(); }
|
||||
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
|
||||
double approximation_scale() const { return base_type::generator().approximation_scale(); }
|
||||
bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); }
|
||||
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
|
||||
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
|
||||
void width(double w) { base_type::generator().width(w); }
|
||||
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
|
||||
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
|
||||
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
|
||||
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
|
||||
void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); }
|
||||
|
||||
private:
|
||||
conv_contour(const conv_contour<VertexSource>&);
|
||||
const conv_contour<VertexSource>& operator=(const conv_contour<VertexSource>&);
|
||||
};
|
||||
line_join_e line_join() const { return base_type::generator().line_join(); }
|
||||
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
||||
double width() const { return base_type::generator().width(); }
|
||||
double miter_limit() const { return base_type::generator().miter_limit(); }
|
||||
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
|
||||
double approximation_scale() const { return base_type::generator().approximation_scale(); }
|
||||
bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_contour(const conv_contour<VertexSource>&);
|
||||
const conv_contour<VertexSource>&
|
||||
operator = (const conv_contour<VertexSource>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
275
deps/agg/include/agg_conv_curve.h
vendored
275
deps/agg/include/agg_conv_curve.h
vendored
|
@ -23,140 +23,157 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_curves.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//---------------------------------------------------------------conv_curve
|
||||
// Curve converter class. Any path storage can have Bezier curves defined
|
||||
// by their control points. There're two types of curves supported: curve3
|
||||
// and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control
|
||||
// point. Curve4 has 2 control points (4 points in total) and can be used
|
||||
// to interpolate more complicated curves. Curve4, unlike curve3 can be used
|
||||
// to approximate arcs, both circular and elliptical. Curves are approximated
|
||||
// with straight lines and one of the approaches is just to store the whole
|
||||
// sequence of vertices that approximate our curve. It takes additional
|
||||
// memory, and at the same time the consecutive vertices can be calculated
|
||||
// on demand.
|
||||
//
|
||||
// Initially, path storages are not suppose to keep all the vertices of the
|
||||
// curves (although, nothing prevents us from doing so). Instead, path_storage
|
||||
// keeps only vertices, needed to calculate a curve on demand. Those vertices
|
||||
// are marked with special commands. So, if the path_storage contains curves
|
||||
// (which are not real curves yet), and we render this storage directly,
|
||||
// all we will see is only 2 or 3 straight line segments (for curve3 and
|
||||
// curve4 respectively). If we need to see real curves drawn we need to
|
||||
// include this class into the conversion pipeline.
|
||||
//
|
||||
// Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4
|
||||
// and converts these vertices into a move_to/line_to sequence.
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VertexSource, class Curve3 = curve3, class Curve4 = curve4>
|
||||
class conv_curve
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef Curve3 curve3_type;
|
||||
typedef Curve4 curve4_type;
|
||||
typedef conv_curve<VertexSource, Curve3, Curve4> self_type;
|
||||
|
||||
explicit conv_curve(VertexSource& source)
|
||||
: m_source(&source)
|
||||
, m_last_x(0.0)
|
||||
, m_last_y(0.0)
|
||||
{}
|
||||
|
||||
conv_curve(self_type&&) = default;
|
||||
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void approximation_method(curve_approximation_method_e v)
|
||||
//---------------------------------------------------------------conv_curve
|
||||
// Curve converter class. Any path storage can have Bezier curves defined
|
||||
// by their control points. There're two types of curves supported: curve3
|
||||
// and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control
|
||||
// point. Curve4 has 2 control points (4 points in total) and can be used
|
||||
// to interpolate more complicated curves. Curve4, unlike curve3 can be used
|
||||
// to approximate arcs, both circular and elliptical. Curves are approximated
|
||||
// with straight lines and one of the approaches is just to store the whole
|
||||
// sequence of vertices that approximate our curve. It takes additional
|
||||
// memory, and at the same time the consecutive vertices can be calculated
|
||||
// on demand.
|
||||
//
|
||||
// Initially, path storages are not suppose to keep all the vertices of the
|
||||
// curves (although, nothing prevents us from doing so). Instead, path_storage
|
||||
// keeps only vertices, needed to calculate a curve on demand. Those vertices
|
||||
// are marked with special commands. So, if the path_storage contains curves
|
||||
// (which are not real curves yet), and we render this storage directly,
|
||||
// all we will see is only 2 or 3 straight line segments (for curve3 and
|
||||
// curve4 respectively). If we need to see real curves drawn we need to
|
||||
// include this class into the conversion pipeline.
|
||||
//
|
||||
// Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4
|
||||
// and converts these vertices into a move_to/line_to sequence.
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VertexSource,
|
||||
class Curve3=curve3,
|
||||
class Curve4=curve4> class conv_curve
|
||||
{
|
||||
m_curve3.approximation_method(v);
|
||||
m_curve4.approximation_method(v);
|
||||
public:
|
||||
typedef Curve3 curve3_type;
|
||||
typedef Curve4 curve4_type;
|
||||
typedef conv_curve<VertexSource, Curve3, Curve4> self_type;
|
||||
|
||||
explicit conv_curve(VertexSource& source) :
|
||||
m_source(&source), m_last_x(0.0), m_last_y(0.0) {}
|
||||
|
||||
conv_curve(self_type &&) = default;
|
||||
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void approximation_method(curve_approximation_method_e v)
|
||||
{
|
||||
m_curve3.approximation_method(v);
|
||||
m_curve4.approximation_method(v);
|
||||
}
|
||||
|
||||
curve_approximation_method_e approximation_method() const
|
||||
{
|
||||
return m_curve4.approximation_method();
|
||||
}
|
||||
|
||||
void approximation_scale(double s)
|
||||
{
|
||||
m_curve3.approximation_scale(s);
|
||||
m_curve4.approximation_scale(s);
|
||||
}
|
||||
|
||||
double approximation_scale() const
|
||||
{
|
||||
return m_curve4.approximation_scale();
|
||||
}
|
||||
|
||||
void angle_tolerance(double v)
|
||||
{
|
||||
m_curve3.angle_tolerance(v);
|
||||
m_curve4.angle_tolerance(v);
|
||||
}
|
||||
|
||||
double angle_tolerance() const
|
||||
{
|
||||
return m_curve4.angle_tolerance();
|
||||
}
|
||||
|
||||
void cusp_limit(double v)
|
||||
{
|
||||
m_curve3.cusp_limit(v);
|
||||
m_curve4.cusp_limit(v);
|
||||
}
|
||||
|
||||
double cusp_limit() const
|
||||
{
|
||||
return m_curve4.cusp_limit();
|
||||
}
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
conv_curve(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
VertexSource* m_source;
|
||||
double m_last_x;
|
||||
double m_last_y;
|
||||
curve3_type m_curve3;
|
||||
curve4_type m_curve4;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class Curve3, class Curve4>
|
||||
void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_last_x = 0.0;
|
||||
m_last_y = 0.0;
|
||||
m_curve3.reset();
|
||||
m_curve4.reset();
|
||||
}
|
||||
|
||||
curve_approximation_method_e approximation_method() const { return m_curve4.approximation_method(); }
|
||||
|
||||
void approximation_scale(double s)
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class Curve3, class Curve4>
|
||||
unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
|
||||
{
|
||||
m_curve3.approximation_scale(s);
|
||||
m_curve4.approximation_scale(s);
|
||||
}
|
||||
if(!is_stop(m_curve3.vertex(x, y)))
|
||||
{
|
||||
m_last_x = *x;
|
||||
m_last_y = *y;
|
||||
return path_cmd_line_to;
|
||||
}
|
||||
|
||||
double approximation_scale() const { return m_curve4.approximation_scale(); }
|
||||
if(!is_stop(m_curve4.vertex(x, y)))
|
||||
{
|
||||
m_last_x = *x;
|
||||
m_last_y = *y;
|
||||
return path_cmd_line_to;
|
||||
}
|
||||
|
||||
void angle_tolerance(double v)
|
||||
{
|
||||
m_curve3.angle_tolerance(v);
|
||||
m_curve4.angle_tolerance(v);
|
||||
}
|
||||
double ct2_x=0;
|
||||
double ct2_y=0;
|
||||
double end_x=0;
|
||||
double end_y=0;
|
||||
|
||||
double angle_tolerance() const { return m_curve4.angle_tolerance(); }
|
||||
|
||||
void cusp_limit(double v)
|
||||
{
|
||||
m_curve3.cusp_limit(v);
|
||||
m_curve4.cusp_limit(v);
|
||||
}
|
||||
|
||||
double cusp_limit() const { return m_curve4.cusp_limit(); }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
conv_curve(const self_type&);
|
||||
const self_type& operator=(const self_type&);
|
||||
|
||||
VertexSource* m_source;
|
||||
double m_last_x;
|
||||
double m_last_y;
|
||||
curve3_type m_curve3;
|
||||
curve4_type m_curve4;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class Curve3, class Curve4>
|
||||
void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
m_last_x = 0.0;
|
||||
m_last_y = 0.0;
|
||||
m_curve3.reset();
|
||||
m_curve4.reset();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class Curve3, class Curve4>
|
||||
unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
|
||||
{
|
||||
if (!is_stop(m_curve3.vertex(x, y)))
|
||||
{
|
||||
m_last_x = *x;
|
||||
m_last_y = *y;
|
||||
return path_cmd_line_to;
|
||||
}
|
||||
|
||||
if (!is_stop(m_curve4.vertex(x, y)))
|
||||
{
|
||||
m_last_x = *x;
|
||||
m_last_y = *y;
|
||||
return path_cmd_line_to;
|
||||
}
|
||||
|
||||
double ct2_x = 0;
|
||||
double ct2_y = 0;
|
||||
double end_x = 0;
|
||||
double end_y = 0;
|
||||
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
switch (cmd)
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
switch(cmd)
|
||||
{
|
||||
case path_cmd_curve3:
|
||||
m_source->vertex(&end_x, &end_y);
|
||||
|
||||
m_curve3.init(m_last_x, m_last_y, *x, *y, end_x, end_y);
|
||||
m_curve3.init(m_last_x, m_last_y,
|
||||
*x, *y,
|
||||
end_x, end_y);
|
||||
|
||||
m_curve3.vertex(x, y); // First call returns path_cmd_move_to
|
||||
m_curve3.vertex(x, y); // This is the first vertex of the curve
|
||||
m_curve3.vertex(x, y); // First call returns path_cmd_move_to
|
||||
m_curve3.vertex(x, y); // This is the first vertex of the curve
|
||||
cmd = path_cmd_line_to;
|
||||
break;
|
||||
|
||||
|
@ -164,18 +181,24 @@ unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
|
|||
m_source->vertex(&ct2_x, &ct2_y);
|
||||
m_source->vertex(&end_x, &end_y);
|
||||
|
||||
m_curve4.init(m_last_x, m_last_y, *x, *y, ct2_x, ct2_y, end_x, end_y);
|
||||
m_curve4.init(m_last_x, m_last_y,
|
||||
*x, *y,
|
||||
ct2_x, ct2_y,
|
||||
end_x, end_y);
|
||||
|
||||
m_curve4.vertex(x, y); // First call returns path_cmd_move_to
|
||||
m_curve4.vertex(x, y); // This is the first vertex of the curve
|
||||
m_curve4.vertex(x, y); // First call returns path_cmd_move_to
|
||||
m_curve4.vertex(x, y); // This is the first vertex of the curve
|
||||
cmd = path_cmd_line_to;
|
||||
break;
|
||||
}
|
||||
m_last_x = *x;
|
||||
m_last_y = *y;
|
||||
return cmd;
|
||||
}
|
||||
m_last_x = *x;
|
||||
m_last_y = *y;
|
||||
return cmd;
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
|
||||
#endif
|
||||
|
|
53
deps/agg/include/agg_conv_dash.h
vendored
53
deps/agg/include/agg_conv_dash.h
vendored
|
@ -23,33 +23,46 @@
|
|||
#include "agg_vcgen_dash.h"
|
||||
#include "agg_conv_adaptor_vcgen.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//---------------------------------------------------------------conv_dash
|
||||
template<class VertexSource, class Markers = null_markers>
|
||||
struct conv_dash : public conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>
|
||||
namespace agg
|
||||
{
|
||||
typedef Markers marker_type;
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers> base_type;
|
||||
|
||||
conv_dash(VertexSource& vs)
|
||||
: conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>(vs)
|
||||
{}
|
||||
//---------------------------------------------------------------conv_dash
|
||||
template<class VertexSource, class Markers=null_markers>
|
||||
struct conv_dash : public conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>
|
||||
{
|
||||
typedef Markers marker_type;
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers> base_type;
|
||||
|
||||
void remove_all_dashes() { base_type::generator().remove_all_dashes(); }
|
||||
conv_dash(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
void add_dash(double dash_len, double gap_len) { base_type::generator().add_dash(dash_len, gap_len); }
|
||||
void remove_all_dashes()
|
||||
{
|
||||
base_type::generator().remove_all_dashes();
|
||||
}
|
||||
|
||||
void dash_start(double ds) { base_type::generator().dash_start(ds); }
|
||||
void add_dash(double dash_len, double gap_len)
|
||||
{
|
||||
base_type::generator().add_dash(dash_len, gap_len);
|
||||
}
|
||||
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
void dash_start(double ds)
|
||||
{
|
||||
base_type::generator().dash_start(ds);
|
||||
}
|
||||
|
||||
private:
|
||||
conv_dash(const conv_dash<VertexSource, Markers>&);
|
||||
const conv_dash<VertexSource, Markers>& operator=(const conv_dash<VertexSource, Markers>&);
|
||||
};
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_dash(const conv_dash<VertexSource, Markers>&);
|
||||
const conv_dash<VertexSource, Markers>&
|
||||
operator = (const conv_dash<VertexSource, Markers>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
662
deps/agg/include/agg_conv_gpc.h
vendored
662
deps/agg/include/agg_conv_gpc.h
vendored
|
@ -33,348 +33,400 @@ extern "C"
|
|||
#include "gpc.h"
|
||||
}
|
||||
|
||||
namespace agg {
|
||||
enum gpc_op_e { gpc_or, gpc_and, gpc_xor, gpc_a_minus_b, gpc_b_minus_a };
|
||||
|
||||
//================================================================conv_gpc
|
||||
template<class VSA, class VSB>
|
||||
class conv_gpc
|
||||
namespace agg
|
||||
{
|
||||
enum status { status_move_to, status_line_to, status_stop };
|
||||
|
||||
struct contour_header_type
|
||||
enum gpc_op_e
|
||||
{
|
||||
int num_vertices;
|
||||
int hole_flag;
|
||||
gpc_vertex* vertices;
|
||||
gpc_or,
|
||||
gpc_and,
|
||||
gpc_xor,
|
||||
gpc_a_minus_b,
|
||||
gpc_b_minus_a
|
||||
};
|
||||
|
||||
typedef pod_bvector<gpc_vertex, 8> vertex_array_type;
|
||||
typedef pod_bvector<contour_header_type, 6> contour_header_array_type;
|
||||
|
||||
public:
|
||||
typedef VSA source_a_type;
|
||||
typedef VSB source_b_type;
|
||||
typedef conv_gpc<source_a_type, source_b_type> self_type;
|
||||
|
||||
~conv_gpc() { free_gpc_data(); }
|
||||
|
||||
conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or)
|
||||
: m_src_a(&a)
|
||||
, m_src_b(&b)
|
||||
, m_status(status_move_to)
|
||||
, m_vertex(-1)
|
||||
, m_contour(-1)
|
||||
, m_operation(op)
|
||||
//================================================================conv_gpc
|
||||
template<class VSA, class VSB> class conv_gpc
|
||||
{
|
||||
memset(&m_poly_a, 0, sizeof(m_poly_a));
|
||||
memset(&m_poly_b, 0, sizeof(m_poly_b));
|
||||
enum status
|
||||
{
|
||||
status_move_to,
|
||||
status_line_to,
|
||||
status_stop
|
||||
};
|
||||
|
||||
struct contour_header_type
|
||||
{
|
||||
int num_vertices;
|
||||
int hole_flag;
|
||||
gpc_vertex* vertices;
|
||||
};
|
||||
|
||||
typedef pod_bvector<gpc_vertex, 8> vertex_array_type;
|
||||
typedef pod_bvector<contour_header_type, 6> contour_header_array_type;
|
||||
|
||||
|
||||
public:
|
||||
typedef VSA source_a_type;
|
||||
typedef VSB source_b_type;
|
||||
typedef conv_gpc<source_a_type, source_b_type> self_type;
|
||||
|
||||
~conv_gpc()
|
||||
{
|
||||
free_gpc_data();
|
||||
}
|
||||
|
||||
conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or) :
|
||||
m_src_a(&a),
|
||||
m_src_b(&b),
|
||||
m_status(status_move_to),
|
||||
m_vertex(-1),
|
||||
m_contour(-1),
|
||||
m_operation(op)
|
||||
{
|
||||
memset(&m_poly_a, 0, sizeof(m_poly_a));
|
||||
memset(&m_poly_b, 0, sizeof(m_poly_b));
|
||||
memset(&m_result, 0, sizeof(m_result));
|
||||
}
|
||||
|
||||
void attach1(VSA& source) { m_src_a = &source; }
|
||||
void attach2(VSB& source) { m_src_b = &source; }
|
||||
|
||||
void operation(gpc_op_e v) { m_operation = v; }
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
conv_gpc(const conv_gpc<VSA, VSB>&);
|
||||
const conv_gpc<VSA, VSB>& operator = (const conv_gpc<VSA, VSB>&);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void free_polygon(gpc_polygon& p);
|
||||
void free_result();
|
||||
void free_gpc_data();
|
||||
void start_contour();
|
||||
void add_vertex(double x, double y);
|
||||
void end_contour(unsigned orientation);
|
||||
void make_polygon(gpc_polygon& p);
|
||||
void start_extracting();
|
||||
bool next_contour();
|
||||
bool next_vertex(double* x, double* y);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class VS> void add(VS& src, gpc_polygon& p)
|
||||
{
|
||||
unsigned cmd;
|
||||
double x, y;
|
||||
double start_x = 0.0;
|
||||
double start_y = 0.0;
|
||||
bool line_to = false;
|
||||
unsigned orientation = 0;
|
||||
|
||||
m_contour_accumulator.remove_all();
|
||||
|
||||
while(!is_stop(cmd = src.vertex(&x, &y)))
|
||||
{
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
if(line_to)
|
||||
{
|
||||
end_contour(orientation);
|
||||
orientation = 0;
|
||||
}
|
||||
start_contour();
|
||||
start_x = x;
|
||||
start_y = y;
|
||||
}
|
||||
add_vertex(x, y);
|
||||
line_to = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_end_poly(cmd))
|
||||
{
|
||||
orientation = get_orientation(cmd);
|
||||
if(line_to && is_closed(cmd))
|
||||
{
|
||||
add_vertex(start_x, start_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(line_to)
|
||||
{
|
||||
end_contour(orientation);
|
||||
}
|
||||
make_polygon(p);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
source_a_type* m_src_a;
|
||||
source_b_type* m_src_b;
|
||||
status m_status;
|
||||
int m_vertex;
|
||||
int m_contour;
|
||||
gpc_op_e m_operation;
|
||||
vertex_array_type m_vertex_accumulator;
|
||||
contour_header_array_type m_contour_accumulator;
|
||||
gpc_polygon m_poly_a;
|
||||
gpc_polygon m_poly_b;
|
||||
gpc_polygon m_result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::free_polygon(gpc_polygon& p)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < p.num_contours; i++)
|
||||
{
|
||||
pod_allocator<gpc_vertex>::deallocate(p.contour[i].vertex,
|
||||
p.contour[i].num_vertices);
|
||||
}
|
||||
pod_allocator<gpc_vertex_list>::deallocate(p.contour, p.num_contours);
|
||||
memset(&p, 0, sizeof(gpc_polygon));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::free_result()
|
||||
{
|
||||
if(m_result.contour)
|
||||
{
|
||||
gpc_free_polygon(&m_result);
|
||||
}
|
||||
memset(&m_result, 0, sizeof(m_result));
|
||||
}
|
||||
|
||||
void attach1(VSA& source) { m_src_a = &source; }
|
||||
void attach2(VSB& source) { m_src_b = &source; }
|
||||
|
||||
void operation(gpc_op_e v) { m_operation = v; }
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
conv_gpc(const conv_gpc<VSA, VSB>&);
|
||||
const conv_gpc<VSA, VSB>& operator=(const conv_gpc<VSA, VSB>&);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void free_polygon(gpc_polygon& p);
|
||||
void free_result();
|
||||
void free_gpc_data();
|
||||
void start_contour();
|
||||
void add_vertex(double x, double y);
|
||||
void end_contour(unsigned orientation);
|
||||
void make_polygon(gpc_polygon& p);
|
||||
void start_extracting();
|
||||
bool next_contour();
|
||||
bool next_vertex(double* x, double* y);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class VS>
|
||||
void add(VS& src, gpc_polygon& p)
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::free_gpc_data()
|
||||
{
|
||||
unsigned cmd;
|
||||
double x, y;
|
||||
double start_x = 0.0;
|
||||
double start_y = 0.0;
|
||||
bool line_to = false;
|
||||
unsigned orientation = 0;
|
||||
free_polygon(m_poly_a);
|
||||
free_polygon(m_poly_b);
|
||||
free_result();
|
||||
}
|
||||
|
||||
m_contour_accumulator.remove_all();
|
||||
|
||||
while (!is_stop(cmd = src.vertex(&x, &y)))
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::start_contour()
|
||||
{
|
||||
contour_header_type h;
|
||||
memset(&h, 0, sizeof(h));
|
||||
m_contour_accumulator.add(h);
|
||||
m_vertex_accumulator.remove_all();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
inline void conv_gpc<VSA, VSB>::add_vertex(double x, double y)
|
||||
{
|
||||
gpc_vertex v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
m_vertex_accumulator.add(v);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::end_contour(unsigned orientation)
|
||||
{
|
||||
if(m_contour_accumulator.size())
|
||||
{
|
||||
if (is_vertex(cmd))
|
||||
if(m_vertex_accumulator.size() > 2)
|
||||
{
|
||||
if (is_move_to(cmd))
|
||||
contour_header_type& h =
|
||||
m_contour_accumulator[m_contour_accumulator.size() - 1];
|
||||
|
||||
h.num_vertices = m_vertex_accumulator.size();
|
||||
h.hole_flag = 0;
|
||||
|
||||
// TO DO: Clarify the "holes"
|
||||
//if(is_cw(orientation)) h.hole_flag = 1;
|
||||
|
||||
h.vertices = pod_allocator<gpc_vertex>::allocate(h.num_vertices);
|
||||
gpc_vertex* d = h.vertices;
|
||||
int i;
|
||||
for(i = 0; i < h.num_vertices; i++)
|
||||
{
|
||||
if (line_to)
|
||||
{
|
||||
end_contour(orientation);
|
||||
orientation = 0;
|
||||
}
|
||||
start_contour();
|
||||
start_x = x;
|
||||
start_y = y;
|
||||
const gpc_vertex& s = m_vertex_accumulator[i];
|
||||
d->x = s.x;
|
||||
d->y = s.y;
|
||||
++d;
|
||||
}
|
||||
add_vertex(x, y);
|
||||
line_to = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_end_poly(cmd))
|
||||
{
|
||||
orientation = get_orientation(cmd);
|
||||
if (line_to && is_closed(cmd))
|
||||
{
|
||||
add_vertex(start_x, start_y);
|
||||
}
|
||||
}
|
||||
m_vertex_accumulator.remove_last();
|
||||
}
|
||||
}
|
||||
if (line_to)
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::make_polygon(gpc_polygon& p)
|
||||
{
|
||||
free_polygon(p);
|
||||
if(m_contour_accumulator.size())
|
||||
{
|
||||
end_contour(orientation);
|
||||
}
|
||||
make_polygon(p);
|
||||
}
|
||||
p.num_contours = m_contour_accumulator.size();
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
source_a_type* m_src_a;
|
||||
source_b_type* m_src_b;
|
||||
status m_status;
|
||||
int m_vertex;
|
||||
int m_contour;
|
||||
gpc_op_e m_operation;
|
||||
vertex_array_type m_vertex_accumulator;
|
||||
contour_header_array_type m_contour_accumulator;
|
||||
gpc_polygon m_poly_a;
|
||||
gpc_polygon m_poly_b;
|
||||
gpc_polygon m_result;
|
||||
};
|
||||
p.hole = 0;
|
||||
p.contour = pod_allocator<gpc_vertex_list>::allocate(p.num_contours);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::free_polygon(gpc_polygon& p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < p.num_contours; i++)
|
||||
{
|
||||
pod_allocator<gpc_vertex>::deallocate(p.contour[i].vertex, p.contour[i].num_vertices);
|
||||
}
|
||||
pod_allocator<gpc_vertex_list>::deallocate(p.contour, p.num_contours);
|
||||
memset(&p, 0, sizeof(gpc_polygon));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::free_result()
|
||||
{
|
||||
if (m_result.contour)
|
||||
{
|
||||
gpc_free_polygon(&m_result);
|
||||
}
|
||||
memset(&m_result, 0, sizeof(m_result));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::free_gpc_data()
|
||||
{
|
||||
free_polygon(m_poly_a);
|
||||
free_polygon(m_poly_b);
|
||||
free_result();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::start_contour()
|
||||
{
|
||||
contour_header_type h;
|
||||
memset(&h, 0, sizeof(h));
|
||||
m_contour_accumulator.add(h);
|
||||
m_vertex_accumulator.remove_all();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
inline void conv_gpc<VSA, VSB>::add_vertex(double x, double y)
|
||||
{
|
||||
gpc_vertex v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
m_vertex_accumulator.add(v);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::end_contour(unsigned orientation)
|
||||
{
|
||||
if (m_contour_accumulator.size())
|
||||
{
|
||||
if (m_vertex_accumulator.size() > 2)
|
||||
{
|
||||
contour_header_type& h = m_contour_accumulator[m_contour_accumulator.size() - 1];
|
||||
|
||||
h.num_vertices = m_vertex_accumulator.size();
|
||||
h.hole_flag = 0;
|
||||
|
||||
// TO DO: Clarify the "holes"
|
||||
// if(is_cw(orientation)) h.hole_flag = 1;
|
||||
|
||||
h.vertices = pod_allocator<gpc_vertex>::allocate(h.num_vertices);
|
||||
gpc_vertex* d = h.vertices;
|
||||
int i;
|
||||
for (i = 0; i < h.num_vertices; i++)
|
||||
gpc_vertex_list* pv = p.contour;
|
||||
for(i = 0; i < p.num_contours; i++)
|
||||
{
|
||||
const gpc_vertex& s = m_vertex_accumulator[i];
|
||||
d->x = s.x;
|
||||
d->y = s.y;
|
||||
++d;
|
||||
const contour_header_type& h = m_contour_accumulator[i];
|
||||
pv->num_vertices = h.num_vertices;
|
||||
pv->vertex = h.vertices;
|
||||
++pv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::start_extracting()
|
||||
{
|
||||
m_status = status_move_to;
|
||||
m_contour = -1;
|
||||
m_vertex = -1;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
bool conv_gpc<VSA, VSB>::next_contour()
|
||||
{
|
||||
if(++m_contour < m_result.num_contours)
|
||||
{
|
||||
m_vertex = -1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
inline bool conv_gpc<VSA, VSB>::next_vertex(double* x, double* y)
|
||||
{
|
||||
const gpc_vertex_list& vlist = m_result.contour[m_contour];
|
||||
if(++m_vertex < vlist.num_vertices)
|
||||
{
|
||||
const gpc_vertex& v = vlist.vertex[m_vertex];
|
||||
*x = v.x;
|
||||
*y = v.y;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::rewind(unsigned path_id)
|
||||
{
|
||||
free_result();
|
||||
m_src_a->rewind(path_id);
|
||||
m_src_b->rewind(path_id);
|
||||
add(*m_src_a, m_poly_a);
|
||||
add(*m_src_b, m_poly_b);
|
||||
switch(m_operation)
|
||||
{
|
||||
case gpc_or:
|
||||
gpc_polygon_clip(GPC_UNION,
|
||||
&m_poly_a,
|
||||
&m_poly_b,
|
||||
&m_result);
|
||||
break;
|
||||
|
||||
case gpc_and:
|
||||
gpc_polygon_clip(GPC_INT,
|
||||
&m_poly_a,
|
||||
&m_poly_b,
|
||||
&m_result);
|
||||
break;
|
||||
|
||||
case gpc_xor:
|
||||
gpc_polygon_clip(GPC_XOR,
|
||||
&m_poly_a,
|
||||
&m_poly_b,
|
||||
&m_result);
|
||||
break;
|
||||
|
||||
case gpc_a_minus_b:
|
||||
gpc_polygon_clip(GPC_DIFF,
|
||||
&m_poly_a,
|
||||
&m_poly_b,
|
||||
&m_result);
|
||||
break;
|
||||
|
||||
case gpc_b_minus_a:
|
||||
gpc_polygon_clip(GPC_DIFF,
|
||||
&m_poly_b,
|
||||
&m_poly_a,
|
||||
&m_result);
|
||||
break;
|
||||
}
|
||||
start_extracting();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
unsigned conv_gpc<VSA, VSB>::vertex(double* x, double* y)
|
||||
{
|
||||
if(m_status == status_move_to)
|
||||
{
|
||||
if(next_contour())
|
||||
{
|
||||
if(next_vertex(x, y))
|
||||
{
|
||||
m_status = status_line_to;
|
||||
return path_cmd_move_to;
|
||||
}
|
||||
m_status = status_stop;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vertex_accumulator.remove_last();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::make_polygon(gpc_polygon& p)
|
||||
{
|
||||
free_polygon(p);
|
||||
if (m_contour_accumulator.size())
|
||||
{
|
||||
p.num_contours = m_contour_accumulator.size();
|
||||
|
||||
p.hole = 0;
|
||||
p.contour = pod_allocator<gpc_vertex_list>::allocate(p.num_contours);
|
||||
|
||||
int i;
|
||||
gpc_vertex_list* pv = p.contour;
|
||||
for (i = 0; i < p.num_contours; i++)
|
||||
{
|
||||
const contour_header_type& h = m_contour_accumulator[i];
|
||||
pv->num_vertices = h.num_vertices;
|
||||
pv->vertex = h.vertices;
|
||||
++pv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::start_extracting()
|
||||
{
|
||||
m_status = status_move_to;
|
||||
m_contour = -1;
|
||||
m_vertex = -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
bool conv_gpc<VSA, VSB>::next_contour()
|
||||
{
|
||||
if (++m_contour < m_result.num_contours)
|
||||
{
|
||||
m_vertex = -1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
inline bool conv_gpc<VSA, VSB>::next_vertex(double* x, double* y)
|
||||
{
|
||||
const gpc_vertex_list& vlist = m_result.contour[m_contour];
|
||||
if (++m_vertex < vlist.num_vertices)
|
||||
{
|
||||
const gpc_vertex& v = vlist.vertex[m_vertex];
|
||||
*x = v.x;
|
||||
*y = v.y;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
void conv_gpc<VSA, VSB>::rewind(unsigned path_id)
|
||||
{
|
||||
free_result();
|
||||
m_src_a->rewind(path_id);
|
||||
m_src_b->rewind(path_id);
|
||||
add(*m_src_a, m_poly_a);
|
||||
add(*m_src_b, m_poly_b);
|
||||
switch (m_operation)
|
||||
{
|
||||
case gpc_or:
|
||||
gpc_polygon_clip(GPC_UNION, &m_poly_a, &m_poly_b, &m_result);
|
||||
break;
|
||||
|
||||
case gpc_and:
|
||||
gpc_polygon_clip(GPC_INT, &m_poly_a, &m_poly_b, &m_result);
|
||||
break;
|
||||
|
||||
case gpc_xor:
|
||||
gpc_polygon_clip(GPC_XOR, &m_poly_a, &m_poly_b, &m_result);
|
||||
break;
|
||||
|
||||
case gpc_a_minus_b:
|
||||
gpc_polygon_clip(GPC_DIFF, &m_poly_a, &m_poly_b, &m_result);
|
||||
break;
|
||||
|
||||
case gpc_b_minus_a:
|
||||
gpc_polygon_clip(GPC_DIFF, &m_poly_b, &m_poly_a, &m_result);
|
||||
break;
|
||||
}
|
||||
start_extracting();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VSA, class VSB>
|
||||
unsigned conv_gpc<VSA, VSB>::vertex(double* x, double* y)
|
||||
{
|
||||
if (m_status == status_move_to)
|
||||
{
|
||||
if (next_contour())
|
||||
{
|
||||
if (next_vertex(x, y))
|
||||
if(next_vertex(x, y))
|
||||
{
|
||||
m_status = status_line_to;
|
||||
return path_cmd_move_to;
|
||||
return path_cmd_line_to;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = status_move_to;
|
||||
}
|
||||
m_status = status_stop;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (next_vertex(x, y))
|
||||
{
|
||||
return path_cmd_line_to;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = status_move_to;
|
||||
}
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
142
deps/agg/include/agg_conv_marker.h
vendored
142
deps/agg/include/agg_conv_marker.h
vendored
|
@ -22,70 +22,82 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
namespace agg {
|
||||
//-------------------------------------------------------------conv_marker
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
class conv_marker
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
conv_marker(MarkerLocator& ml, MarkerShapes& ms);
|
||||
|
||||
trans_affine& transform() { return m_transform; }
|
||||
const trans_affine& transform() const { return m_transform; }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&);
|
||||
const conv_marker<MarkerLocator, MarkerShapes>& operator=(const conv_marker<MarkerLocator, MarkerShapes>&);
|
||||
|
||||
enum status_e { initial, markers, polygon, stop };
|
||||
|
||||
MarkerLocator* m_marker_locator;
|
||||
MarkerShapes* m_marker_shapes;
|
||||
trans_affine m_transform;
|
||||
trans_affine m_mtx;
|
||||
status_e m_status;
|
||||
unsigned m_marker;
|
||||
unsigned m_num_markers;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms)
|
||||
: m_marker_locator(&ml)
|
||||
, m_marker_shapes(&ms)
|
||||
, m_status(initial)
|
||||
, m_marker(0)
|
||||
, m_num_markers(1)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned)
|
||||
{
|
||||
m_status = initial;
|
||||
m_marker = 0;
|
||||
m_num_markers = 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_move_to;
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
while (!is_stop(cmd))
|
||||
//-------------------------------------------------------------conv_marker
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
class conv_marker
|
||||
{
|
||||
switch (m_status)
|
||||
public:
|
||||
conv_marker(MarkerLocator& ml, MarkerShapes& ms);
|
||||
|
||||
trans_affine& transform() { return m_transform; }
|
||||
const trans_affine& transform() const { return m_transform; }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&);
|
||||
const conv_marker<MarkerLocator, MarkerShapes>&
|
||||
operator = (const conv_marker<MarkerLocator, MarkerShapes>&);
|
||||
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
markers,
|
||||
polygon,
|
||||
stop
|
||||
};
|
||||
|
||||
MarkerLocator* m_marker_locator;
|
||||
MarkerShapes* m_marker_shapes;
|
||||
trans_affine m_transform;
|
||||
trans_affine m_mtx;
|
||||
status_e m_status;
|
||||
unsigned m_marker;
|
||||
unsigned m_num_markers;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms) :
|
||||
m_marker_locator(&ml),
|
||||
m_marker_shapes(&ms),
|
||||
m_status(initial),
|
||||
m_marker(0),
|
||||
m_num_markers(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned)
|
||||
{
|
||||
m_status = initial;
|
||||
m_marker = 0;
|
||||
m_num_markers = 1;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = path_cmd_move_to;
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
while(!is_stop(cmd))
|
||||
{
|
||||
switch(m_status)
|
||||
{
|
||||
case initial:
|
||||
if (m_num_markers == 0)
|
||||
if(m_num_markers == 0)
|
||||
{
|
||||
cmd = path_cmd_stop;
|
||||
break;
|
||||
cmd = path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
m_marker_locator->rewind(m_marker);
|
||||
++m_marker;
|
||||
|
@ -93,12 +105,12 @@ unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
|
|||
m_status = markers;
|
||||
|
||||
case markers:
|
||||
if (is_stop(m_marker_locator->vertex(&x1, &y1)))
|
||||
if(is_stop(m_marker_locator->vertex(&x1, &y1)))
|
||||
{
|
||||
m_status = initial;
|
||||
break;
|
||||
}
|
||||
if (is_stop(m_marker_locator->vertex(&x2, &y2)))
|
||||
if(is_stop(m_marker_locator->vertex(&x2, &y2)))
|
||||
{
|
||||
m_status = initial;
|
||||
break;
|
||||
|
@ -112,7 +124,7 @@ unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
|
|||
|
||||
case polygon:
|
||||
cmd = m_marker_shapes->vertex(x, y);
|
||||
if (is_stop(cmd))
|
||||
if(is_stop(cmd))
|
||||
{
|
||||
cmd = path_cmd_move_to;
|
||||
m_status = markers;
|
||||
|
@ -124,11 +136,13 @@ unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
|
|||
case stop:
|
||||
cmd = path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
return cmd;
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
|
39
deps/agg/include/agg_conv_marker_adaptor.h
vendored
39
deps/agg/include/agg_conv_marker_adaptor.h
vendored
|
@ -20,27 +20,32 @@
|
|||
#include "agg_conv_adaptor_vcgen.h"
|
||||
#include "agg_vcgen_vertex_sequence.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=====================================================conv_marker_adaptor
|
||||
template<class VertexSource, class Markers = null_markers>
|
||||
struct conv_marker_adaptor : public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>
|
||||
namespace agg
|
||||
{
|
||||
typedef Markers marker_type;
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers> base_type;
|
||||
|
||||
conv_marker_adaptor(VertexSource& vs)
|
||||
: conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>(vs)
|
||||
{}
|
||||
//=====================================================conv_marker_adaptor
|
||||
template<class VertexSource, class Markers=null_markers>
|
||||
struct conv_marker_adaptor :
|
||||
public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>
|
||||
{
|
||||
typedef Markers marker_type;
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers> base_type;
|
||||
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
conv_marker_adaptor(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&);
|
||||
const conv_marker_adaptor<VertexSource, Markers>& operator=(const conv_marker_adaptor<VertexSource, Markers>&);
|
||||
};
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&);
|
||||
const conv_marker_adaptor<VertexSource, Markers>&
|
||||
operator = (const conv_marker_adaptor<VertexSource, Markers>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
139
deps/agg/include/agg_conv_offset.h
vendored
139
deps/agg/include/agg_conv_offset.h
vendored
|
@ -22,53 +22,59 @@
|
|||
#include "agg_array.h"
|
||||
#include "clipper.hpp"
|
||||
|
||||
namespace agg {
|
||||
namespace agg
|
||||
{
|
||||
|
||||
template<class VSA>
|
||||
class conv_offset
|
||||
template<class VSA> class conv_offset
|
||||
{
|
||||
enum status { status_move_to, status_line_to, status_stop };
|
||||
typedef VSA source_a_type;
|
||||
typedef conv_offset<source_a_type> self_type;
|
||||
|
||||
private:
|
||||
source_a_type* m_src_a;
|
||||
private:
|
||||
source_a_type* m_src_a;
|
||||
double m_offset;
|
||||
status m_status;
|
||||
int m_vertex;
|
||||
int m_contour;
|
||||
int m_scaling_factor;
|
||||
pod_bvector<ClipperLib::IntPoint, 8> m_vertex_accumulator;
|
||||
ClipperLib::Paths m_poly_a;
|
||||
ClipperLib::Paths m_result;
|
||||
ClipperLib::Paths m_poly_a;
|
||||
ClipperLib::Paths m_result;
|
||||
ClipperLib::ClipperOffset m_clipper_offset;
|
||||
|
||||
int Round(double val)
|
||||
{
|
||||
if ((val < 0))
|
||||
return (int)(val - 0.5);
|
||||
else
|
||||
return (int)(val + 0.5);
|
||||
if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5);
|
||||
}
|
||||
|
||||
public:
|
||||
conv_offset(source_a_type& a, double offset = 0.0, int scaling_factor = 0)
|
||||
: m_src_a(&a)
|
||||
, m_offset(offset)
|
||||
, m_status(status_move_to)
|
||||
, m_vertex(-1)
|
||||
, m_contour(-1)
|
||||
public:
|
||||
conv_offset(source_a_type &a, double offset = 0.0,
|
||||
int scaling_factor = 0)
|
||||
: m_src_a(&a),
|
||||
m_offset(offset),
|
||||
m_status(status_move_to),
|
||||
m_vertex(-1),
|
||||
m_contour(-1)
|
||||
{
|
||||
m_scaling_factor = std::max(std::min(scaling_factor, 6), 0);
|
||||
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
|
||||
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
|
||||
}
|
||||
|
||||
~conv_offset() {}
|
||||
~conv_offset()
|
||||
{
|
||||
}
|
||||
|
||||
void set_offset(double offset) { m_offset = offset; }
|
||||
unsigned type() const { return static_cast<unsigned>(m_src_a->type()); }
|
||||
void set_offset(double offset) { m_offset = offset;}
|
||||
unsigned type() const
|
||||
{
|
||||
return static_cast<unsigned>(m_src_a->type());
|
||||
}
|
||||
|
||||
double get_offset() const { return m_offset; }
|
||||
double get_offset() const
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
@ -76,17 +82,13 @@ class conv_offset
|
|||
bool next_contour();
|
||||
bool next_vertex(double* x, double* y);
|
||||
void start_extracting();
|
||||
void add_vertex_(double& x, double& y);
|
||||
void end_contour(ClipperLib::Paths& p);
|
||||
void add_vertex_(double &x, double &y);
|
||||
void end_contour(ClipperLib::Paths &p);
|
||||
|
||||
template<class VS>
|
||||
void add(VS& src, ClipperLib::Paths& p)
|
||||
template<class VS> void add(VS &src, ClipperLib::Paths &p)
|
||||
{
|
||||
unsigned cmd;
|
||||
double x;
|
||||
double y;
|
||||
double start_x;
|
||||
double start_y;
|
||||
double x; double y; double start_x; double start_y;
|
||||
bool starting_first_line;
|
||||
|
||||
start_x = 0.0;
|
||||
|
@ -94,27 +96,26 @@ class conv_offset
|
|||
starting_first_line = true;
|
||||
p.resize(0);
|
||||
|
||||
cmd = src->vertex(&x, &y);
|
||||
while (!is_stop(cmd))
|
||||
cmd = src->vertex( &x , &y );
|
||||
while(!is_stop(cmd))
|
||||
{
|
||||
if (is_vertex(cmd))
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
if (is_move_to(cmd))
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
if (!starting_first_line)
|
||||
end_contour(p);
|
||||
if(!starting_first_line ) end_contour(p);
|
||||
start_x = x;
|
||||
start_y = y;
|
||||
}
|
||||
add_vertex_(x, y);
|
||||
add_vertex_( x, y );
|
||||
starting_first_line = false;
|
||||
}
|
||||
else if (is_end_poly(cmd))
|
||||
else if(is_end_poly(cmd))
|
||||
{
|
||||
if (!starting_first_line && is_closed(cmd))
|
||||
add_vertex_(start_x, start_y);
|
||||
if(!starting_first_line && is_closed(cmd))
|
||||
add_vertex_( start_x, start_y );
|
||||
}
|
||||
cmd = src->vertex(&x, &y);
|
||||
cmd = src->vertex( &x, &y );
|
||||
}
|
||||
end_contour(p);
|
||||
}
|
||||
|
@ -134,43 +135,42 @@ void conv_offset<VSA>::start_extracting()
|
|||
template<class VSA>
|
||||
void conv_offset<VSA>::rewind(unsigned path_id)
|
||||
{
|
||||
m_src_a->rewind(path_id);
|
||||
// m_src_b->rewind( path_id );
|
||||
m_src_a->rewind( path_id );
|
||||
//m_src_b->rewind( path_id );
|
||||
|
||||
add(m_src_a, m_poly_a);
|
||||
// add( m_src_b , m_poly_b );
|
||||
add( m_src_a , m_poly_a );
|
||||
//add( m_src_b , m_poly_b );
|
||||
m_result.resize(0);
|
||||
m_clipper_offset.Clear();
|
||||
m_clipper_offset.AddPaths(m_poly_a, ClipperLib::jtMiter, ClipperLib::etOpenButt); // ClosedLine);//Polygon);
|
||||
m_clipper_offset.AddPaths(m_poly_a,ClipperLib::jtMiter, ClipperLib::etOpenButt);//ClosedLine);//Polygon);
|
||||
m_clipper_offset.Execute(m_result, m_offset * m_scaling_factor);
|
||||
start_extracting();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class VSA>
|
||||
void conv_offset<VSA>::end_contour(ClipperLib::Paths& p)
|
||||
void conv_offset<VSA>::end_contour( ClipperLib::Paths &p)
|
||||
{
|
||||
unsigned i, len;
|
||||
|
||||
if (m_vertex_accumulator.size() < 3)
|
||||
return;
|
||||
if( m_vertex_accumulator.size() < 3 ) return;
|
||||
len = p.size();
|
||||
p.resize(len + 1);
|
||||
p.resize(len+1);
|
||||
p[len].resize(m_vertex_accumulator.size());
|
||||
for (i = 0; i < m_vertex_accumulator.size(); i++)
|
||||
for( i = 0 ; i < m_vertex_accumulator.size() ; i++ )
|
||||
p[len][i] = m_vertex_accumulator[i];
|
||||
m_vertex_accumulator.remove_all();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class VSA>
|
||||
void conv_offset<VSA>::add_vertex_(double& x, double& y)
|
||||
void conv_offset<VSA>::add_vertex_(double &x, double &y)
|
||||
{
|
||||
ClipperLib::IntPoint v;
|
||||
|
||||
v.X = Round(x * m_scaling_factor);
|
||||
v.Y = Round(y * m_scaling_factor);
|
||||
m_vertex_accumulator.add(v);
|
||||
m_vertex_accumulator.add( v );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -178,35 +178,33 @@ template<class VSA>
|
|||
bool conv_offset<VSA>::next_contour()
|
||||
{
|
||||
m_contour++;
|
||||
if (m_contour >= (int)m_result.size())
|
||||
return false;
|
||||
m_vertex = -1;
|
||||
if(m_contour >= (int)m_result.size()) return false;
|
||||
m_vertex =-1;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class VSA>
|
||||
bool conv_offset<VSA>::next_vertex(double* x, double* y)
|
||||
bool conv_offset<VSA>::next_vertex(double *x, double *y)
|
||||
{
|
||||
m_vertex++;
|
||||
if (m_vertex >= (int)m_result[m_contour].size())
|
||||
return false;
|
||||
*x = (double)m_result[m_contour][m_vertex].X / m_scaling_factor;
|
||||
*y = (double)m_result[m_contour][m_vertex].Y / m_scaling_factor;
|
||||
if(m_vertex >= (int)m_result[m_contour].size()) return false;
|
||||
*x = (double)m_result[ m_contour ][ m_vertex ].X / m_scaling_factor;
|
||||
*y = (double)m_result[ m_contour ][ m_vertex ].Y / m_scaling_factor;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class VSA>
|
||||
unsigned conv_offset<VSA>::vertex(double* x, double* y)
|
||||
unsigned conv_offset<VSA>::vertex(double *x, double *y)
|
||||
{
|
||||
if (m_status == status_move_to)
|
||||
if( m_status == status_move_to )
|
||||
{
|
||||
if (next_contour())
|
||||
if( next_contour() )
|
||||
{
|
||||
if (next_vertex(x, y))
|
||||
if( next_vertex( x, y ) )
|
||||
{
|
||||
m_status = status_line_to;
|
||||
m_status =status_line_to;
|
||||
return path_cmd_move_to;
|
||||
}
|
||||
else
|
||||
|
@ -220,7 +218,7 @@ unsigned conv_offset<VSA>::vertex(double* x, double* y)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (next_vertex(x, y))
|
||||
if( next_vertex( x, y ) )
|
||||
{
|
||||
return path_cmd_line_to;
|
||||
}
|
||||
|
@ -233,5 +231,6 @@ unsigned conv_offset<VSA>::vertex(double* x, double* y)
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace agg
|
||||
#endif // AGG_CONV_OFFSET_INCLUDED
|
||||
|
||||
} //namespace agg
|
||||
#endif //AGG_CONV_OFFSET_INCLUDED
|
||||
|
|
35
deps/agg/include/agg_conv_segmentator.h
vendored
35
deps/agg/include/agg_conv_segmentator.h
vendored
|
@ -20,26 +20,29 @@
|
|||
#include "agg_conv_adaptor_vpgen.h"
|
||||
#include "agg_vpgen_segmentator.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//========================================================conv_segmentator
|
||||
template<class VertexSource>
|
||||
struct conv_segmentator : public conv_adaptor_vpgen<VertexSource, vpgen_segmentator>
|
||||
namespace agg
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_segmentator> base_type;
|
||||
|
||||
conv_segmentator(VertexSource& vs)
|
||||
: conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs)
|
||||
{}
|
||||
//========================================================conv_segmentator
|
||||
template<class VertexSource>
|
||||
struct conv_segmentator : public conv_adaptor_vpgen<VertexSource, vpgen_segmentator>
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_segmentator> base_type;
|
||||
|
||||
void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); }
|
||||
double approximation_scale() const { return base_type::vpgen().approximation_scale(); }
|
||||
conv_segmentator(VertexSource& vs) :
|
||||
conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs) {}
|
||||
|
||||
private:
|
||||
conv_segmentator(const conv_segmentator<VertexSource>&);
|
||||
const conv_segmentator<VertexSource>& operator=(const conv_segmentator<VertexSource>&);
|
||||
};
|
||||
void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); }
|
||||
double approximation_scale() const { return base_type::vpgen().approximation_scale(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_segmentator(const conv_segmentator<VertexSource>&);
|
||||
const conv_segmentator<VertexSource>&
|
||||
operator = (const conv_segmentator<VertexSource>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
38
deps/agg/include/agg_conv_shorten_path.h
vendored
38
deps/agg/include/agg_conv_shorten_path.h
vendored
|
@ -20,27 +20,31 @@
|
|||
#include "agg_conv_adaptor_vcgen.h"
|
||||
#include "agg_vcgen_vertex_sequence.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=======================================================conv_shorten_path
|
||||
template<class VertexSource>
|
||||
class conv_shorten_path : public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> base_type;
|
||||
|
||||
conv_shorten_path(VertexSource& vs)
|
||||
: conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs)
|
||||
{}
|
||||
//=======================================================conv_shorten_path
|
||||
template<class VertexSource> class conv_shorten_path :
|
||||
public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>
|
||||
{
|
||||
public:
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> base_type;
|
||||
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
conv_shorten_path(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
conv_shorten_path(const conv_shorten_path<VertexSource>&);
|
||||
const conv_shorten_path<VertexSource>& operator=(const conv_shorten_path<VertexSource>&);
|
||||
};
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_shorten_path(const conv_shorten_path<VertexSource>&);
|
||||
const conv_shorten_path<VertexSource>&
|
||||
operator = (const conv_shorten_path<VertexSource>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
106
deps/agg/include/agg_conv_smooth_poly1.h
vendored
106
deps/agg/include/agg_conv_smooth_poly1.h
vendored
|
@ -24,62 +24,70 @@
|
|||
#include "agg_conv_adaptor_vcgen.h"
|
||||
#include "agg_conv_curve.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-------------------------------------------------------conv_smooth
|
||||
template<class VertexSource, class VertexGenerator>
|
||||
struct conv_smooth : public conv_adaptor_vcgen<VertexSource, VertexGenerator>
|
||||
namespace agg
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, VertexGenerator> base_type;
|
||||
|
||||
conv_smooth(VertexSource& vs)
|
||||
: conv_adaptor_vcgen<VertexSource, VertexGenerator>(vs)
|
||||
{}
|
||||
|
||||
conv_smooth(conv_smooth<VertexSource, VertexGenerator>&&) = default;
|
||||
|
||||
conv_smooth(const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
||||
const conv_smooth<VertexSource, VertexGenerator>&
|
||||
operator=(const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
||||
|
||||
void smooth_value(double v) { base_type::generator().smooth_value(v); }
|
||||
double smooth_value() const { return base_type::generator().smooth_value(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
};
|
||||
|
||||
template<class VertexSource>
|
||||
using conv_smooth_poly1 = conv_smooth<VertexSource, vcgen_smooth_poly1>;
|
||||
|
||||
//-------------------------------------------------conv_smooth_curve
|
||||
template<class VertexSource, class VertexGenerator>
|
||||
struct conv_smooth_curve : public conv_curve<conv_smooth<VertexSource, VertexGenerator>>
|
||||
{
|
||||
conv_smooth_curve(VertexSource& vs)
|
||||
: conv_curve<conv_smooth<VertexSource, VertexGenerator>>(m_smooth)
|
||||
, m_smooth(vs)
|
||||
{}
|
||||
|
||||
conv_smooth_curve(conv_smooth_curve<VertexSource, VertexGenerator>&& rhs)
|
||||
: conv_curve<conv_smooth<VertexSource, VertexGenerator>>(std::move(rhs))
|
||||
, m_smooth(std::move(rhs.m_smooth))
|
||||
//-------------------------------------------------------conv_smooth
|
||||
template<class VertexSource, class VertexGenerator>
|
||||
struct conv_smooth :
|
||||
public conv_adaptor_vcgen<VertexSource, VertexGenerator>
|
||||
{
|
||||
this->attach(m_smooth);
|
||||
}
|
||||
typedef conv_adaptor_vcgen<VertexSource, VertexGenerator> base_type;
|
||||
|
||||
conv_smooth_curve(const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
||||
const conv_smooth_curve<VertexSource, VertexGenerator>&
|
||||
operator=(const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
||||
conv_smooth(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, VertexGenerator>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
|
||||
double smooth_value() const { return m_smooth.generator().smooth_value(); }
|
||||
unsigned type() const { return m_smooth.type(); }
|
||||
conv_smooth(conv_smooth<VertexSource, VertexGenerator> &&) = default;
|
||||
|
||||
private:
|
||||
conv_smooth<VertexSource, VertexGenerator> m_smooth;
|
||||
};
|
||||
conv_smooth(const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
||||
const conv_smooth<VertexSource, VertexGenerator>&
|
||||
operator = (const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
||||
|
||||
void smooth_value(double v) { base_type::generator().smooth_value(v); }
|
||||
double smooth_value() const { return base_type::generator().smooth_value(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
};
|
||||
|
||||
template<class VertexSource>
|
||||
using conv_smooth_poly1 = conv_smooth<VertexSource, vcgen_smooth_poly1>;
|
||||
|
||||
//-------------------------------------------------conv_smooth_curve
|
||||
template<class VertexSource, class VertexGenerator>
|
||||
struct conv_smooth_curve :
|
||||
public conv_curve<conv_smooth<VertexSource, VertexGenerator>>
|
||||
{
|
||||
conv_smooth_curve(VertexSource& vs) :
|
||||
conv_curve<conv_smooth<VertexSource, VertexGenerator>>(m_smooth),
|
||||
m_smooth(vs)
|
||||
{
|
||||
}
|
||||
|
||||
conv_smooth_curve(conv_smooth_curve<VertexSource, VertexGenerator> && rhs) :
|
||||
conv_curve<conv_smooth<VertexSource, VertexGenerator>>(std::move(rhs)),
|
||||
m_smooth(std::move(rhs.m_smooth))
|
||||
{
|
||||
this->attach(m_smooth);
|
||||
}
|
||||
|
||||
conv_smooth_curve(const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
||||
const conv_smooth_curve<VertexSource, VertexGenerator>&
|
||||
operator = (const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
||||
|
||||
void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
|
||||
double smooth_value() const { return m_smooth.generator().smooth_value(); }
|
||||
unsigned type() const { return m_smooth.type(); }
|
||||
|
||||
private:
|
||||
conv_smooth<VertexSource, VertexGenerator> m_smooth;
|
||||
};
|
||||
|
||||
template<class VertexSource>
|
||||
using conv_smooth_poly1_curve = conv_smooth_curve<VertexSource, vcgen_smooth_poly1>;
|
||||
}
|
||||
|
||||
template<class VertexSource>
|
||||
using conv_smooth_poly1_curve = conv_smooth_curve<VertexSource, vcgen_smooth_poly1>;
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
|
69
deps/agg/include/agg_conv_stroke.h
vendored
69
deps/agg/include/agg_conv_stroke.h
vendored
|
@ -23,46 +23,51 @@
|
|||
#include "agg_vcgen_stroke.h"
|
||||
#include "agg_conv_adaptor_vcgen.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-------------------------------------------------------------conv_stroke
|
||||
template<class VertexSource, class Markers = null_markers>
|
||||
struct conv_stroke : public conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>
|
||||
namespace agg
|
||||
{
|
||||
typedef Markers marker_type;
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> base_type;
|
||||
|
||||
conv_stroke(VertexSource& vs)
|
||||
: conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs)
|
||||
{}
|
||||
//-------------------------------------------------------------conv_stroke
|
||||
template<class VertexSource, class Markers=null_markers>
|
||||
struct conv_stroke :
|
||||
public conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>
|
||||
{
|
||||
typedef Markers marker_type;
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> base_type;
|
||||
|
||||
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
|
||||
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
|
||||
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
|
||||
conv_stroke(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
|
||||
line_join_e line_join() const { return base_type::generator().line_join(); }
|
||||
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
||||
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
|
||||
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
|
||||
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
|
||||
|
||||
void width(double w) { base_type::generator().width(w); }
|
||||
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
|
||||
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
|
||||
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
|
||||
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
|
||||
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
|
||||
line_join_e line_join() const { return base_type::generator().line_join(); }
|
||||
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
||||
|
||||
double width() const { return base_type::generator().width(); }
|
||||
double miter_limit() const { return base_type::generator().miter_limit(); }
|
||||
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
|
||||
double approximation_scale() const { return base_type::generator().approximation_scale(); }
|
||||
void width(double w) { base_type::generator().width(w); }
|
||||
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
|
||||
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
|
||||
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
|
||||
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
|
||||
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
double width() const { return base_type::generator().width(); }
|
||||
double miter_limit() const { return base_type::generator().miter_limit(); }
|
||||
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
|
||||
double approximation_scale() const { return base_type::generator().approximation_scale(); }
|
||||
|
||||
private:
|
||||
conv_stroke(const conv_stroke<VertexSource, Markers>&);
|
||||
const conv_stroke<VertexSource, Markers>& operator=(const conv_stroke<VertexSource, Markers>&);
|
||||
};
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_stroke(const conv_stroke<VertexSource, Markers>&);
|
||||
const conv_stroke<VertexSource, Markers>&
|
||||
operator = (const conv_stroke<VertexSource, Markers>&);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
64
deps/agg/include/agg_conv_transform.h
vendored
64
deps/agg/include/agg_conv_transform.h
vendored
|
@ -22,44 +22,50 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//----------------------------------------------------------conv_transform
|
||||
template<class VertexSource, class Transformer = trans_affine>
|
||||
class conv_transform
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
conv_transform(VertexSource& source, Transformer& tr)
|
||||
: m_source(&source)
|
||||
, m_trans(&tr)
|
||||
{}
|
||||
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void rewind(unsigned path_id) { m_source->rewind(path_id); }
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
//----------------------------------------------------------conv_transform
|
||||
template<class VertexSource, class Transformer=trans_affine> class conv_transform
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
if (is_vertex(cmd))
|
||||
public:
|
||||
conv_transform(VertexSource& source, Transformer& tr) :
|
||||
m_source(&source), m_trans(&tr) {}
|
||||
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
m_trans->transform(x, y);
|
||||
m_source->rewind(path_id);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void transformer(Transformer& tr) { m_trans = &tr; }
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
m_trans->transform(x, y);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
unsigned type() const { return m_source->type(); }
|
||||
void transformer(Transformer& tr)
|
||||
{
|
||||
m_trans = &tr;
|
||||
}
|
||||
|
||||
private:
|
||||
conv_transform(const conv_transform<VertexSource>&);
|
||||
const conv_transform<VertexSource>& operator=(const conv_transform<VertexSource>&);
|
||||
unsigned type() const { return m_source->type(); }
|
||||
|
||||
VertexSource* m_source;
|
||||
const Transformer* m_trans;
|
||||
};
|
||||
private:
|
||||
conv_transform(const conv_transform<VertexSource>&);
|
||||
const conv_transform<VertexSource>&
|
||||
operator = (const conv_transform<VertexSource>&);
|
||||
|
||||
} // namespace agg
|
||||
VertexSource* m_source;
|
||||
const Transformer* m_trans;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
49
deps/agg/include/agg_conv_unclose_polygon.h
vendored
49
deps/agg/include/agg_conv_unclose_polygon.h
vendored
|
@ -18,34 +18,35 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
//====================================================conv_unclose_polygon
|
||||
template<class VertexSource>
|
||||
class conv_unclose_polygon
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
explicit conv_unclose_polygon(VertexSource& vs)
|
||||
: m_source(&vs)
|
||||
{}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void rewind(unsigned path_id) { m_source->rewind(path_id); }
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
//====================================================conv_unclose_polygon
|
||||
template<class VertexSource> class conv_unclose_polygon
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
if (is_end_poly(cmd))
|
||||
cmd &= ~path_flags_close;
|
||||
return cmd;
|
||||
}
|
||||
public:
|
||||
explicit conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
private:
|
||||
conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
|
||||
const conv_unclose_polygon<VertexSource>& operator=(const conv_unclose_polygon<VertexSource>&);
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
}
|
||||
|
||||
VertexSource* m_source;
|
||||
};
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
if(is_end_poly(cmd)) cmd &= ~path_flags_close;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
|
||||
const conv_unclose_polygon<VertexSource>&
|
||||
operator = (const conv_unclose_polygon<VertexSource>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
1166
deps/agg/include/agg_curves.h
vendored
1166
deps/agg/include/agg_curves.h
vendored
File diff suppressed because it is too large
Load diff
425
deps/agg/include/agg_dda_line.h
vendored
425
deps/agg/include/agg_dda_line.h
vendored
|
@ -23,229 +23,268 @@
|
|||
#include <cstdlib>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//===================================================dda_line_interpolator
|
||||
template<int FractionShift, int YShift = 0>
|
||||
class dda_line_interpolator
|
||||
namespace agg
|
||||
{
|
||||
static constexpr int factor = 2 << (FractionShift - 1);
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
dda_line_interpolator() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
dda_line_interpolator(int y1, int y2, unsigned count)
|
||||
: m_y(y1)
|
||||
, m_inc(((y2 - y1) * factor) / static_cast<int>(count))
|
||||
, m_dy(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator++() { m_dy += m_inc; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator--() { m_dy -= m_inc; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator+=(unsigned n) { m_dy += m_inc * n; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator-=(unsigned n) { m_dy -= m_inc * n; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y + (m_dy >> (FractionShift - YShift)); }
|
||||
int dy() const { return m_dy; }
|
||||
|
||||
private:
|
||||
int m_y;
|
||||
int m_inc;
|
||||
int m_dy;
|
||||
};
|
||||
|
||||
//=================================================dda2_line_interpolator
|
||||
class dda2_line_interpolator
|
||||
{
|
||||
public:
|
||||
typedef int save_data_type;
|
||||
enum save_size_e { save_size = 2 };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
dda2_line_interpolator() {}
|
||||
|
||||
//-------------------------------------------- Forward-adjusted line
|
||||
dda2_line_interpolator(int y1, int y2, int count)
|
||||
: m_cnt(count <= 0 ? 1 : count)
|
||||
, m_lft((y2 - y1) / m_cnt)
|
||||
, m_rem((y2 - y1) % m_cnt)
|
||||
, m_mod(m_rem)
|
||||
, m_y(y1)
|
||||
//===================================================dda_line_interpolator
|
||||
template<int FractionShift, int YShift = 0> class dda_line_interpolator
|
||||
{
|
||||
if (m_mod <= 0)
|
||||
static constexpr int factor = 2 << (FractionShift - 1);
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
dda_line_interpolator() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
dda_line_interpolator(int y1, int y2, unsigned count) :
|
||||
m_y(y1),
|
||||
m_inc(((y2 - y1) * factor) / static_cast<int>(count)),
|
||||
m_dy(0)
|
||||
{
|
||||
m_mod += count;
|
||||
m_rem += count;
|
||||
m_lft--;
|
||||
}
|
||||
m_mod -= count;
|
||||
}
|
||||
|
||||
//-------------------------------------------- Backward-adjusted line
|
||||
dda2_line_interpolator(int y1, int y2, int count, int)
|
||||
: m_cnt(count <= 0 ? 1 : count)
|
||||
, m_lft((y2 - y1) / m_cnt)
|
||||
, m_rem((y2 - y1) % m_cnt)
|
||||
, m_mod(m_rem)
|
||||
, m_y(y1)
|
||||
{
|
||||
if (m_mod <= 0)
|
||||
//--------------------------------------------------------------------
|
||||
void operator ++ ()
|
||||
{
|
||||
m_mod += count;
|
||||
m_rem += count;
|
||||
m_lft--;
|
||||
m_dy += m_inc;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------- Backward-adjusted line
|
||||
dda2_line_interpolator(int y, int count)
|
||||
: m_cnt(count <= 0 ? 1 : count)
|
||||
, m_lft(y / m_cnt)
|
||||
, m_rem(y % m_cnt)
|
||||
, m_mod(m_rem)
|
||||
, m_y(0)
|
||||
{
|
||||
if (m_mod <= 0)
|
||||
//--------------------------------------------------------------------
|
||||
void operator -- ()
|
||||
{
|
||||
m_mod += count;
|
||||
m_rem += count;
|
||||
m_lft--;
|
||||
m_dy -= m_inc;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void save(save_data_type* data) const
|
||||
{
|
||||
data[0] = m_mod;
|
||||
data[1] = m_y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void load(const save_data_type* data)
|
||||
{
|
||||
m_mod = data[0];
|
||||
m_y = data[1];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
m_mod += m_rem;
|
||||
m_y += m_lft;
|
||||
if (m_mod > 0)
|
||||
//--------------------------------------------------------------------
|
||||
void operator += (unsigned n)
|
||||
{
|
||||
m_mod -= m_cnt;
|
||||
m_y++;
|
||||
m_dy += m_inc * n;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator--()
|
||||
{
|
||||
if (m_mod <= m_rem)
|
||||
//--------------------------------------------------------------------
|
||||
void operator -= (unsigned n)
|
||||
{
|
||||
m_mod += m_cnt;
|
||||
m_y--;
|
||||
m_dy -= m_inc * n;
|
||||
}
|
||||
m_mod -= m_rem;
|
||||
m_y -= m_lft;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void adjust_forward() { m_mod -= m_cnt; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void adjust_backward() { m_mod += m_cnt; }
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y + (m_dy >> (FractionShift - YShift)); }
|
||||
int dy() const { return m_dy; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int mod() const { return m_mod; }
|
||||
int rem() const { return m_rem; }
|
||||
int lft() const { return m_lft; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
|
||||
private:
|
||||
int m_cnt;
|
||||
int m_lft;
|
||||
int m_rem;
|
||||
int m_mod;
|
||||
int m_y;
|
||||
};
|
||||
|
||||
//---------------------------------------------line_bresenham_interpolator
|
||||
class line_bresenham_interpolator
|
||||
{
|
||||
public:
|
||||
enum subpixel_scale_e {
|
||||
subpixel_shift = 8,
|
||||
subpixel_scale = 1 << subpixel_shift,
|
||||
subpixel_mask = subpixel_scale - 1
|
||||
private:
|
||||
int m_y;
|
||||
int m_inc;
|
||||
int m_dy;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static int line_lr(int v) { return v >> subpixel_shift; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
line_bresenham_interpolator(int x1, int y1, int x2, int y2)
|
||||
: m_x1_lr(line_lr(x1))
|
||||
, m_y1_lr(line_lr(y1))
|
||||
, m_x2_lr(line_lr(x2))
|
||||
, m_y2_lr(line_lr(y2))
|
||||
, m_ver(std::abs(m_x2_lr - m_x1_lr) < std::abs(m_y2_lr - m_y1_lr))
|
||||
, m_len(m_ver ? std::abs(m_y2_lr - m_y1_lr) : std::abs(m_x2_lr - m_x1_lr))
|
||||
, m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1))
|
||||
, m_interpolator(m_ver ? x1 : y1, m_ver ? x2 : y2, m_len)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool is_ver() const { return m_ver; }
|
||||
unsigned len() const { return m_len; }
|
||||
int inc() const { return m_inc; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void hstep()
|
||||
|
||||
//=================================================dda2_line_interpolator
|
||||
class dda2_line_interpolator
|
||||
{
|
||||
++m_interpolator;
|
||||
m_x1_lr += m_inc;
|
||||
}
|
||||
public:
|
||||
typedef int save_data_type;
|
||||
enum save_size_e { save_size = 2 };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void vstep()
|
||||
//--------------------------------------------------------------------
|
||||
dda2_line_interpolator() {}
|
||||
|
||||
//-------------------------------------------- Forward-adjusted line
|
||||
dda2_line_interpolator(int y1, int y2, int count) :
|
||||
m_cnt(count <= 0 ? 1 : count),
|
||||
m_lft((y2 - y1) / m_cnt),
|
||||
m_rem((y2 - y1) % m_cnt),
|
||||
m_mod(m_rem),
|
||||
m_y(y1)
|
||||
{
|
||||
if(m_mod <= 0)
|
||||
{
|
||||
m_mod += count;
|
||||
m_rem += count;
|
||||
m_lft--;
|
||||
}
|
||||
m_mod -= count;
|
||||
}
|
||||
|
||||
//-------------------------------------------- Backward-adjusted line
|
||||
dda2_line_interpolator(int y1, int y2, int count, int) :
|
||||
m_cnt(count <= 0 ? 1 : count),
|
||||
m_lft((y2 - y1) / m_cnt),
|
||||
m_rem((y2 - y1) % m_cnt),
|
||||
m_mod(m_rem),
|
||||
m_y(y1)
|
||||
{
|
||||
if(m_mod <= 0)
|
||||
{
|
||||
m_mod += count;
|
||||
m_rem += count;
|
||||
m_lft--;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------- Backward-adjusted line
|
||||
dda2_line_interpolator(int y, int count) :
|
||||
m_cnt(count <= 0 ? 1 : count),
|
||||
m_lft(y / m_cnt),
|
||||
m_rem(y % m_cnt),
|
||||
m_mod(m_rem),
|
||||
m_y(0)
|
||||
{
|
||||
if(m_mod <= 0)
|
||||
{
|
||||
m_mod += count;
|
||||
m_rem += count;
|
||||
m_lft--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void save(save_data_type* data) const
|
||||
{
|
||||
data[0] = m_mod;
|
||||
data[1] = m_y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void load(const save_data_type* data)
|
||||
{
|
||||
m_mod = data[0];
|
||||
m_y = data[1];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
m_mod += m_rem;
|
||||
m_y += m_lft;
|
||||
if(m_mod > 0)
|
||||
{
|
||||
m_mod -= m_cnt;
|
||||
m_y++;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void operator--()
|
||||
{
|
||||
if(m_mod <= m_rem)
|
||||
{
|
||||
m_mod += m_cnt;
|
||||
m_y--;
|
||||
}
|
||||
m_mod -= m_rem;
|
||||
m_y -= m_lft;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void adjust_forward()
|
||||
{
|
||||
m_mod -= m_cnt;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void adjust_backward()
|
||||
{
|
||||
m_mod += m_cnt;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int mod() const { return m_mod; }
|
||||
int rem() const { return m_rem; }
|
||||
int lft() const { return m_lft; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
|
||||
private:
|
||||
int m_cnt;
|
||||
int m_lft;
|
||||
int m_rem;
|
||||
int m_mod;
|
||||
int m_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------line_bresenham_interpolator
|
||||
class line_bresenham_interpolator
|
||||
{
|
||||
++m_interpolator;
|
||||
m_y1_lr += m_inc;
|
||||
}
|
||||
public:
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = 8,
|
||||
subpixel_scale = 1 << subpixel_shift,
|
||||
subpixel_mask = subpixel_scale - 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int x1() const { return m_x1_lr; }
|
||||
int y1() const { return m_y1_lr; }
|
||||
int x2() const { return line_lr(m_interpolator.y()); }
|
||||
int y2() const { return line_lr(m_interpolator.y()); }
|
||||
int x2_hr() const { return m_interpolator.y(); }
|
||||
int y2_hr() const { return m_interpolator.y(); }
|
||||
//--------------------------------------------------------------------
|
||||
static int line_lr(int v) { return v >> subpixel_shift; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
|
||||
m_x1_lr(line_lr(x1)),
|
||||
m_y1_lr(line_lr(y1)),
|
||||
m_x2_lr(line_lr(x2)),
|
||||
m_y2_lr(line_lr(y2)),
|
||||
m_ver(std::abs(m_x2_lr - m_x1_lr) < std::abs(m_y2_lr - m_y1_lr)),
|
||||
m_len(m_ver ? std::abs(m_y2_lr - m_y1_lr) :
|
||||
std::abs(m_x2_lr - m_x1_lr)),
|
||||
m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
|
||||
m_interpolator(m_ver ? x1 : y1,
|
||||
m_ver ? x2 : y2,
|
||||
m_len)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool is_ver() const { return m_ver; }
|
||||
unsigned len() const { return m_len; }
|
||||
int inc() const { return m_inc; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void hstep()
|
||||
{
|
||||
++m_interpolator;
|
||||
m_x1_lr += m_inc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void vstep()
|
||||
{
|
||||
++m_interpolator;
|
||||
m_y1_lr += m_inc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int x1() const { return m_x1_lr; }
|
||||
int y1() const { return m_y1_lr; }
|
||||
int x2() const { return line_lr(m_interpolator.y()); }
|
||||
int y2() const { return line_lr(m_interpolator.y()); }
|
||||
int x2_hr() const { return m_interpolator.y(); }
|
||||
int y2_hr() const { return m_interpolator.y(); }
|
||||
|
||||
private:
|
||||
int m_x1_lr;
|
||||
int m_y1_lr;
|
||||
int m_x2_lr;
|
||||
int m_y2_lr;
|
||||
bool m_ver;
|
||||
unsigned m_len;
|
||||
int m_inc;
|
||||
dda2_line_interpolator m_interpolator;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
int m_x1_lr;
|
||||
int m_y1_lr;
|
||||
int m_x2_lr;
|
||||
int m_y2_lr;
|
||||
bool m_ver;
|
||||
unsigned m_len;
|
||||
int m_inc;
|
||||
dda2_line_interpolator m_interpolator;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
185
deps/agg/include/agg_ellipse.h
vendored
185
deps/agg/include/agg_ellipse.h
vendored
|
@ -23,111 +23,102 @@
|
|||
#include "agg_basics.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace agg {
|
||||
|
||||
//----------------------------------------------------------------ellipse
|
||||
class ellipse
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
ellipse()
|
||||
: m_x(0.0)
|
||||
, m_y(0.0)
|
||||
, m_rx(1.0)
|
||||
, m_ry(1.0)
|
||||
, m_scale(1.0)
|
||||
, m_num(4)
|
||||
, m_step(0)
|
||||
, m_cw(false)
|
||||
{}
|
||||
|
||||
ellipse(double x, double y, double rx, double ry, unsigned num_steps = 0, bool cw = false)
|
||||
: m_x(x)
|
||||
, m_y(y)
|
||||
, m_rx(rx)
|
||||
, m_ry(ry)
|
||||
, m_scale(1.0)
|
||||
, m_num(num_steps)
|
||||
, m_step(0)
|
||||
, m_cw(cw)
|
||||
//----------------------------------------------------------------ellipse
|
||||
class ellipse
|
||||
{
|
||||
if (m_num == 0)
|
||||
calc_num_steps();
|
||||
public:
|
||||
ellipse() :
|
||||
m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_scale(1.0),
|
||||
m_num(4), m_step(0), m_cw(false) {}
|
||||
|
||||
ellipse(double x, double y, double rx, double ry,
|
||||
unsigned num_steps=0, bool cw=false) :
|
||||
m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0),
|
||||
m_num(num_steps), m_step(0), m_cw(cw)
|
||||
{
|
||||
if(m_num == 0) calc_num_steps();
|
||||
}
|
||||
|
||||
void init(double x, double y, double rx, double ry,
|
||||
unsigned num_steps=0, bool cw=false);
|
||||
|
||||
void approximation_scale(double scale);
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned num_steps() { return m_num; }
|
||||
|
||||
private:
|
||||
void calc_num_steps();
|
||||
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_rx;
|
||||
double m_ry;
|
||||
double m_scale;
|
||||
unsigned m_num;
|
||||
unsigned m_step;
|
||||
bool m_cw;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::init(double x, double y, double rx, double ry,
|
||||
unsigned num_steps, bool cw)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_rx = rx;
|
||||
m_ry = ry;
|
||||
m_num = num_steps;
|
||||
m_step = 0;
|
||||
m_cw = cw;
|
||||
if(m_num == 0) calc_num_steps();
|
||||
}
|
||||
|
||||
void init(double x, double y, double rx, double ry, unsigned num_steps = 0, bool cw = false);
|
||||
|
||||
void approximation_scale(double scale);
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned num_steps() { return m_num; }
|
||||
|
||||
private:
|
||||
void calc_num_steps();
|
||||
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_rx;
|
||||
double m_ry;
|
||||
double m_scale;
|
||||
unsigned m_num;
|
||||
unsigned m_step;
|
||||
bool m_cw;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::init(double x, double y, double rx, double ry, unsigned num_steps, bool cw)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_rx = rx;
|
||||
m_ry = ry;
|
||||
m_num = num_steps;
|
||||
m_step = 0;
|
||||
m_cw = cw;
|
||||
if (m_num == 0)
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::approximation_scale(double scale)
|
||||
{
|
||||
m_scale = scale;
|
||||
calc_num_steps();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::approximation_scale(double scale)
|
||||
{
|
||||
m_scale = scale;
|
||||
calc_num_steps();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::calc_num_steps()
|
||||
{
|
||||
double ra = (std::fabs(m_rx) + std::fabs(m_ry)) / 2;
|
||||
double da = std::acos(ra / (ra + 0.125 / m_scale)) * 2;
|
||||
m_num = uround(2 * pi / da);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::rewind(unsigned)
|
||||
{
|
||||
m_step = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline unsigned ellipse::vertex(double* x, double* y)
|
||||
{
|
||||
if (m_step == m_num)
|
||||
{
|
||||
++m_step;
|
||||
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
|
||||
}
|
||||
if (m_step > m_num)
|
||||
return path_cmd_stop;
|
||||
double angle = double(m_step) / double(m_num) * 2.0 * pi;
|
||||
if (m_cw)
|
||||
angle = 2.0 * pi - angle;
|
||||
*x = m_x + std::cos(angle) * m_rx;
|
||||
*y = m_y + std::sin(angle) * m_ry;
|
||||
m_step++;
|
||||
return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::calc_num_steps()
|
||||
{
|
||||
double ra = (std::fabs(m_rx) + std::fabs(m_ry)) / 2;
|
||||
double da = std::acos(ra / (ra + 0.125 / m_scale)) * 2;
|
||||
m_num = uround(2*pi / da);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::rewind(unsigned)
|
||||
{
|
||||
m_step = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline unsigned ellipse::vertex(double* x, double* y)
|
||||
{
|
||||
if(m_step == m_num)
|
||||
{
|
||||
++m_step;
|
||||
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
|
||||
}
|
||||
if(m_step > m_num) return path_cmd_stop;
|
||||
double angle = double(m_step) / double(m_num) * 2.0 * pi;
|
||||
if(m_cw) angle = 2.0 * pi - angle;
|
||||
*x = m_x + std::cos(angle) * m_rx;
|
||||
*y = m_y + std::sin(angle) * m_ry;
|
||||
m_step++;
|
||||
return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
142
deps/agg/include/agg_ellipse_bresenham.h
vendored
142
deps/agg/include/agg_ellipse_bresenham.h
vendored
|
@ -20,92 +20,94 @@
|
|||
#ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED
|
||||
#define AGG_ELLIPSE_BRESENHAM_INCLUDED
|
||||
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//------------------------------------------ellipse_bresenham_interpolator
|
||||
class ellipse_bresenham_interpolator
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
ellipse_bresenham_interpolator(int rx, int ry)
|
||||
: m_rx2(rx * rx)
|
||||
, m_ry2(ry * ry)
|
||||
, m_two_rx2(m_rx2 << 1)
|
||||
, m_two_ry2(m_ry2 << 1)
|
||||
, m_dx(0)
|
||||
, m_dy(0)
|
||||
, m_inc_x(0)
|
||||
, m_inc_y(-ry * m_two_rx2)
|
||||
, m_cur_f(0)
|
||||
{}
|
||||
|
||||
int dx() const { return m_dx; }
|
||||
int dy() const { return m_dy; }
|
||||
|
||||
void operator++()
|
||||
//------------------------------------------ellipse_bresenham_interpolator
|
||||
class ellipse_bresenham_interpolator
|
||||
{
|
||||
int mx, my, mxy, min_m;
|
||||
int fx, fy, fxy;
|
||||
public:
|
||||
ellipse_bresenham_interpolator(int rx, int ry) :
|
||||
m_rx2(rx * rx),
|
||||
m_ry2(ry * ry),
|
||||
m_two_rx2(m_rx2 << 1),
|
||||
m_two_ry2(m_ry2 << 1),
|
||||
m_dx(0),
|
||||
m_dy(0),
|
||||
m_inc_x(0),
|
||||
m_inc_y(-ry * m_two_rx2),
|
||||
m_cur_f(0)
|
||||
{}
|
||||
|
||||
mx = fx = m_cur_f + m_inc_x + m_ry2;
|
||||
if (mx < 0)
|
||||
mx = -mx;
|
||||
int dx() const { return m_dx; }
|
||||
int dy() const { return m_dy; }
|
||||
|
||||
my = fy = m_cur_f + m_inc_y + m_rx2;
|
||||
if (my < 0)
|
||||
my = -my;
|
||||
|
||||
mxy = fxy = m_cur_f + m_inc_x + m_ry2 + m_inc_y + m_rx2;
|
||||
if (mxy < 0)
|
||||
mxy = -mxy;
|
||||
|
||||
min_m = mx;
|
||||
bool flag = true;
|
||||
|
||||
if (min_m > my)
|
||||
void operator++ ()
|
||||
{
|
||||
min_m = my;
|
||||
flag = false;
|
||||
}
|
||||
int mx, my, mxy, min_m;
|
||||
int fx, fy, fxy;
|
||||
|
||||
m_dx = m_dy = 0;
|
||||
mx = fx = m_cur_f + m_inc_x + m_ry2;
|
||||
if(mx < 0) mx = -mx;
|
||||
|
||||
my = fy = m_cur_f + m_inc_y + m_rx2;
|
||||
if(my < 0) my = -my;
|
||||
|
||||
mxy = fxy = m_cur_f + m_inc_x + m_ry2 + m_inc_y + m_rx2;
|
||||
if(mxy < 0) mxy = -mxy;
|
||||
|
||||
min_m = mx;
|
||||
bool flag = true;
|
||||
|
||||
if(min_m > my)
|
||||
{
|
||||
min_m = my;
|
||||
flag = false;
|
||||
}
|
||||
|
||||
m_dx = m_dy = 0;
|
||||
|
||||
if(min_m > mxy)
|
||||
{
|
||||
m_inc_x += m_two_ry2;
|
||||
m_inc_y += m_two_rx2;
|
||||
m_cur_f = fxy;
|
||||
m_dx = 1;
|
||||
m_dy = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(flag)
|
||||
{
|
||||
m_inc_x += m_two_ry2;
|
||||
m_cur_f = fx;
|
||||
m_dx = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (min_m > mxy)
|
||||
{
|
||||
m_inc_x += m_two_ry2;
|
||||
m_inc_y += m_two_rx2;
|
||||
m_cur_f = fxy;
|
||||
m_dx = 1;
|
||||
m_cur_f = fy;
|
||||
m_dy = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
m_inc_x += m_two_ry2;
|
||||
m_cur_f = fx;
|
||||
m_dx = 1;
|
||||
return;
|
||||
}
|
||||
private:
|
||||
int m_rx2;
|
||||
int m_ry2;
|
||||
int m_two_rx2;
|
||||
int m_two_ry2;
|
||||
int m_dx;
|
||||
int m_dy;
|
||||
int m_inc_x;
|
||||
int m_inc_y;
|
||||
int m_cur_f;
|
||||
|
||||
m_inc_y += m_two_rx2;
|
||||
m_cur_f = fy;
|
||||
m_dy = 1;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
int m_rx2;
|
||||
int m_ry2;
|
||||
int m_two_rx2;
|
||||
int m_two_ry2;
|
||||
int m_dx;
|
||||
int m_dy;
|
||||
int m_inc_x;
|
||||
int m_inc_y;
|
||||
int m_cur_f;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
73
deps/agg/include/agg_embedded_raster_fonts.h
vendored
73
deps/agg/include/agg_embedded_raster_fonts.h
vendored
|
@ -18,41 +18,42 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
extern const int8u gse4x6[];
|
||||
extern const int8u gse4x8[];
|
||||
extern const int8u gse5x7[];
|
||||
extern const int8u gse5x9[];
|
||||
extern const int8u gse6x12[];
|
||||
extern const int8u gse6x9[];
|
||||
extern const int8u gse7x11[];
|
||||
extern const int8u gse7x11_bold[];
|
||||
extern const int8u gse7x15[];
|
||||
extern const int8u gse7x15_bold[];
|
||||
extern const int8u gse8x16[];
|
||||
extern const int8u gse8x16_bold[];
|
||||
extern const int8u mcs11_prop[];
|
||||
extern const int8u mcs11_prop_condensed[];
|
||||
extern const int8u mcs12_prop[];
|
||||
extern const int8u mcs13_prop[];
|
||||
extern const int8u mcs5x10_mono[];
|
||||
extern const int8u mcs5x11_mono[];
|
||||
extern const int8u mcs6x10_mono[];
|
||||
extern const int8u mcs6x11_mono[];
|
||||
extern const int8u mcs7x12_mono_high[];
|
||||
extern const int8u mcs7x12_mono_low[];
|
||||
extern const int8u verdana12[];
|
||||
extern const int8u verdana12_bold[];
|
||||
extern const int8u verdana13[];
|
||||
extern const int8u verdana13_bold[];
|
||||
extern const int8u verdana14[];
|
||||
extern const int8u verdana14_bold[];
|
||||
extern const int8u verdana16[];
|
||||
extern const int8u verdana16_bold[];
|
||||
extern const int8u verdana17[];
|
||||
extern const int8u verdana17_bold[];
|
||||
extern const int8u verdana18[];
|
||||
extern const int8u verdana18_bold[];
|
||||
} // namespace agg
|
||||
namespace agg
|
||||
{
|
||||
extern const int8u gse4x6[];
|
||||
extern const int8u gse4x8[];
|
||||
extern const int8u gse5x7[];
|
||||
extern const int8u gse5x9[];
|
||||
extern const int8u gse6x12[];
|
||||
extern const int8u gse6x9[];
|
||||
extern const int8u gse7x11[];
|
||||
extern const int8u gse7x11_bold[];
|
||||
extern const int8u gse7x15[];
|
||||
extern const int8u gse7x15_bold[];
|
||||
extern const int8u gse8x16[];
|
||||
extern const int8u gse8x16_bold[];
|
||||
extern const int8u mcs11_prop[];
|
||||
extern const int8u mcs11_prop_condensed[];
|
||||
extern const int8u mcs12_prop[];
|
||||
extern const int8u mcs13_prop[];
|
||||
extern const int8u mcs5x10_mono[];
|
||||
extern const int8u mcs5x11_mono[];
|
||||
extern const int8u mcs6x10_mono[];
|
||||
extern const int8u mcs6x11_mono[];
|
||||
extern const int8u mcs7x12_mono_high[];
|
||||
extern const int8u mcs7x12_mono_low[];
|
||||
extern const int8u verdana12[];
|
||||
extern const int8u verdana12_bold[];
|
||||
extern const int8u verdana13[];
|
||||
extern const int8u verdana13_bold[];
|
||||
extern const int8u verdana14[];
|
||||
extern const int8u verdana14_bold[];
|
||||
extern const int8u verdana16[];
|
||||
extern const int8u verdana16_bold[];
|
||||
extern const int8u verdana17[];
|
||||
extern const int8u verdana17_bold[];
|
||||
extern const int8u verdana18[];
|
||||
extern const int8u verdana18_bold[];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
605
deps/agg/include/agg_font_cache_manager.h
vendored
605
deps/agg/include/agg_font_cache_manager.h
vendored
|
@ -19,265 +19,307 @@
|
|||
#include <cstring>
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//---------------------------------------------------------glyph_data_type
|
||||
enum glyph_data_type { glyph_data_invalid = 0, glyph_data_mono = 1, glyph_data_gray8 = 2, glyph_data_outline = 3 };
|
||||
|
||||
//-------------------------------------------------------------glyph_cache
|
||||
struct glyph_cache
|
||||
namespace agg
|
||||
{
|
||||
unsigned glyph_index;
|
||||
int8u* data;
|
||||
unsigned data_size;
|
||||
glyph_data_type data_type;
|
||||
rect_i bounds;
|
||||
double advance_x;
|
||||
double advance_y;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------font_cache
|
||||
class font_cache
|
||||
{
|
||||
public:
|
||||
enum block_size_e { block_size = 16384 - 16 };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
font_cache()
|
||||
: m_allocator(block_size)
|
||||
, m_font_signature(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void signature(const char* font_signature)
|
||||
//---------------------------------------------------------glyph_data_type
|
||||
enum glyph_data_type
|
||||
{
|
||||
m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
|
||||
strcpy(m_font_signature, font_signature);
|
||||
memset(m_glyphs, 0, sizeof(m_glyphs));
|
||||
}
|
||||
glyph_data_invalid = 0,
|
||||
glyph_data_mono = 1,
|
||||
glyph_data_gray8 = 2,
|
||||
glyph_data_outline = 3
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool font_is(const char* font_signature) const { return strcmp(font_signature, m_font_signature) == 0; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* find_glyph(unsigned glyph_code) const
|
||||
//-------------------------------------------------------------glyph_cache
|
||||
struct glyph_cache
|
||||
{
|
||||
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||
if (m_glyphs[msb])
|
||||
unsigned glyph_index;
|
||||
int8u* data;
|
||||
unsigned data_size;
|
||||
glyph_data_type data_type;
|
||||
rect_i bounds;
|
||||
double advance_x;
|
||||
double advance_y;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------font_cache
|
||||
class font_cache
|
||||
{
|
||||
public:
|
||||
enum block_size_e { block_size = 16384-16 };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
font_cache() :
|
||||
m_allocator(block_size),
|
||||
m_font_signature(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void signature(const char* font_signature)
|
||||
{
|
||||
return m_glyphs[msb][glyph_code & 0xFF];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
glyph_cache* cache_glyph(unsigned glyph_code,
|
||||
unsigned glyph_index,
|
||||
unsigned data_size,
|
||||
glyph_data_type data_type,
|
||||
const rect_i& bounds,
|
||||
double advance_x,
|
||||
double advance_y)
|
||||
{
|
||||
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||
if (m_glyphs[msb] == 0)
|
||||
{
|
||||
m_glyphs[msb] = (glyph_cache**)m_allocator.allocate(sizeof(glyph_cache*) * 256, sizeof(glyph_cache*));
|
||||
memset(m_glyphs[msb], 0, sizeof(glyph_cache*) * 256);
|
||||
m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
|
||||
strcpy(m_font_signature, font_signature);
|
||||
memset(m_glyphs, 0, sizeof(m_glyphs));
|
||||
}
|
||||
|
||||
unsigned lsb = glyph_code & 0xFF;
|
||||
if (m_glyphs[msb][lsb])
|
||||
return 0; // Already exists, do not overwrite
|
||||
|
||||
glyph_cache* glyph = (glyph_cache*)m_allocator.allocate(sizeof(glyph_cache), sizeof(double));
|
||||
|
||||
glyph->glyph_index = glyph_index;
|
||||
glyph->data = m_allocator.allocate(data_size);
|
||||
glyph->data_size = data_size;
|
||||
glyph->data_type = data_type;
|
||||
glyph->bounds = bounds;
|
||||
glyph->advance_x = advance_x;
|
||||
glyph->advance_y = advance_y;
|
||||
return m_glyphs[msb][lsb] = glyph;
|
||||
}
|
||||
|
||||
private:
|
||||
block_allocator m_allocator;
|
||||
glyph_cache** m_glyphs[256];
|
||||
char* m_font_signature;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------font_cache_pool
|
||||
class font_cache_pool
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
~font_cache_pool()
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < m_num_fonts; ++i)
|
||||
//--------------------------------------------------------------------
|
||||
bool font_is(const char* font_signature) const
|
||||
{
|
||||
obj_allocator<font_cache>::deallocate(m_fonts[i]);
|
||||
return strcmp(font_signature, m_font_signature) == 0;
|
||||
}
|
||||
pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_pool(unsigned max_fonts = 32)
|
||||
: m_fonts(pod_allocator<font_cache*>::allocate(max_fonts))
|
||||
, m_max_fonts(max_fonts)
|
||||
, m_num_fonts(0)
|
||||
, m_cur_font(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void font(const char* font_signature, bool reset_cache = false)
|
||||
{
|
||||
int idx = find_font(font_signature);
|
||||
if (idx >= 0)
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* find_glyph(unsigned glyph_code) const
|
||||
{
|
||||
if (reset_cache)
|
||||
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||
if(m_glyphs[msb])
|
||||
{
|
||||
obj_allocator<font_cache>::deallocate(m_fonts[idx]);
|
||||
m_fonts[idx] = obj_allocator<font_cache>::allocate();
|
||||
m_fonts[idx]->signature(font_signature);
|
||||
return m_glyphs[msb][glyph_code & 0xFF];
|
||||
}
|
||||
m_cur_font = m_fonts[idx];
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
glyph_cache* cache_glyph(unsigned glyph_code,
|
||||
unsigned glyph_index,
|
||||
unsigned data_size,
|
||||
glyph_data_type data_type,
|
||||
const rect_i& bounds,
|
||||
double advance_x,
|
||||
double advance_y)
|
||||
{
|
||||
if (m_num_fonts >= m_max_fonts)
|
||||
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||
if(m_glyphs[msb] == 0)
|
||||
{
|
||||
obj_allocator<font_cache>::deallocate(m_fonts[0]);
|
||||
memcpy(m_fonts, m_fonts + 1, (m_max_fonts - 1) * sizeof(font_cache*));
|
||||
m_num_fonts = m_max_fonts - 1;
|
||||
m_glyphs[msb] =
|
||||
(glyph_cache**)m_allocator.allocate(sizeof(glyph_cache*) * 256,
|
||||
sizeof(glyph_cache*));
|
||||
memset(m_glyphs[msb], 0, sizeof(glyph_cache*) * 256);
|
||||
}
|
||||
m_fonts[m_num_fonts] = obj_allocator<font_cache>::allocate();
|
||||
m_fonts[m_num_fonts]->signature(font_signature);
|
||||
m_cur_font = m_fonts[m_num_fonts];
|
||||
++m_num_fonts;
|
||||
|
||||
unsigned lsb = glyph_code & 0xFF;
|
||||
if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite
|
||||
|
||||
glyph_cache* glyph =
|
||||
(glyph_cache*)m_allocator.allocate(sizeof(glyph_cache),
|
||||
sizeof(double));
|
||||
|
||||
glyph->glyph_index = glyph_index;
|
||||
glyph->data = m_allocator.allocate(data_size);
|
||||
glyph->data_size = data_size;
|
||||
glyph->data_type = data_type;
|
||||
glyph->bounds = bounds;
|
||||
glyph->advance_x = advance_x;
|
||||
glyph->advance_y = advance_y;
|
||||
return m_glyphs[msb][lsb] = glyph;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const font_cache* font() const { return m_cur_font; }
|
||||
private:
|
||||
block_allocator m_allocator;
|
||||
glyph_cache** m_glyphs[256];
|
||||
char* m_font_signature;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* find_glyph(unsigned glyph_code) const
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------font_cache_pool
|
||||
class font_cache_pool
|
||||
{
|
||||
if (m_cur_font)
|
||||
return m_cur_font->find_glyph(glyph_code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
glyph_cache* cache_glyph(unsigned glyph_code,
|
||||
unsigned glyph_index,
|
||||
unsigned data_size,
|
||||
glyph_data_type data_type,
|
||||
const rect_i& bounds,
|
||||
double advance_x,
|
||||
double advance_y)
|
||||
{
|
||||
if (m_cur_font)
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
~font_cache_pool()
|
||||
{
|
||||
return m_cur_font->cache_glyph(glyph_code, glyph_index, data_size, data_type, bounds, advance_x, advance_y);
|
||||
unsigned i;
|
||||
for(i = 0; i < m_num_fonts; ++i)
|
||||
{
|
||||
obj_allocator<font_cache>::deallocate(m_fonts[i]);
|
||||
}
|
||||
pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int find_font(const char* font_signature)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < m_num_fonts; i++)
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_pool(unsigned max_fonts=32) :
|
||||
m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)),
|
||||
m_max_fonts(max_fonts),
|
||||
m_num_fonts(0),
|
||||
m_cur_font(0)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void font(const char* font_signature, bool reset_cache = false)
|
||||
{
|
||||
if (m_fonts[i]->font_is(font_signature))
|
||||
return int(i);
|
||||
int idx = find_font(font_signature);
|
||||
if(idx >= 0)
|
||||
{
|
||||
if(reset_cache)
|
||||
{
|
||||
obj_allocator<font_cache>::deallocate(m_fonts[idx]);
|
||||
m_fonts[idx] = obj_allocator<font_cache>::allocate();
|
||||
m_fonts[idx]->signature(font_signature);
|
||||
}
|
||||
m_cur_font = m_fonts[idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_num_fonts >= m_max_fonts)
|
||||
{
|
||||
obj_allocator<font_cache>::deallocate(m_fonts[0]);
|
||||
memcpy(m_fonts,
|
||||
m_fonts + 1,
|
||||
(m_max_fonts - 1) * sizeof(font_cache*));
|
||||
m_num_fonts = m_max_fonts - 1;
|
||||
}
|
||||
m_fonts[m_num_fonts] = obj_allocator<font_cache>::allocate();
|
||||
m_fonts[m_num_fonts]->signature(font_signature);
|
||||
m_cur_font = m_fonts[m_num_fonts];
|
||||
++m_num_fonts;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
font_cache** m_fonts;
|
||||
unsigned m_max_fonts;
|
||||
unsigned m_num_fonts;
|
||||
font_cache* m_cur_font;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum glyph_rendering {
|
||||
glyph_ren_native_mono,
|
||||
glyph_ren_native_gray8,
|
||||
glyph_ren_outline,
|
||||
glyph_ren_agg_mono,
|
||||
glyph_ren_agg_gray8
|
||||
};
|
||||
|
||||
//------------------------------------------------------font_cache_manager
|
||||
template<class FontEngine>
|
||||
class font_cache_manager
|
||||
{
|
||||
public:
|
||||
typedef FontEngine font_engine_type;
|
||||
typedef font_cache_manager<FontEngine> self_type;
|
||||
typedef typename font_engine_type::path_adaptor_type path_adaptor_type;
|
||||
typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type;
|
||||
typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type;
|
||||
typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type;
|
||||
typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_manager(font_engine_type& engine, unsigned max_fonts = 32)
|
||||
: m_fonts(max_fonts)
|
||||
, m_engine(engine)
|
||||
, m_change_stamp(-1)
|
||||
, m_prev_glyph(0)
|
||||
, m_last_glyph(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_last_glyph() { m_prev_glyph = m_last_glyph = 0; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* glyph(unsigned glyph_code)
|
||||
{
|
||||
synchronize();
|
||||
const glyph_cache* gl = m_fonts.find_glyph(glyph_code);
|
||||
if (gl)
|
||||
//--------------------------------------------------------------------
|
||||
const font_cache* font() const
|
||||
{
|
||||
m_prev_glyph = m_last_glyph;
|
||||
return m_last_glyph = gl;
|
||||
return m_cur_font;
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* find_glyph(unsigned glyph_code) const
|
||||
{
|
||||
if (m_engine.prepare_glyph(glyph_code))
|
||||
if(m_cur_font) return m_cur_font->find_glyph(glyph_code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
glyph_cache* cache_glyph(unsigned glyph_code,
|
||||
unsigned glyph_index,
|
||||
unsigned data_size,
|
||||
glyph_data_type data_type,
|
||||
const rect_i& bounds,
|
||||
double advance_x,
|
||||
double advance_y)
|
||||
{
|
||||
if(m_cur_font)
|
||||
{
|
||||
return m_cur_font->cache_glyph(glyph_code,
|
||||
glyph_index,
|
||||
data_size,
|
||||
data_type,
|
||||
bounds,
|
||||
advance_x,
|
||||
advance_y);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int find_font(const char* font_signature)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < m_num_fonts; i++)
|
||||
{
|
||||
if(m_fonts[i]->font_is(font_signature)) return int(i);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
font_cache** m_fonts;
|
||||
unsigned m_max_fonts;
|
||||
unsigned m_num_fonts;
|
||||
font_cache* m_cur_font;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum glyph_rendering
|
||||
{
|
||||
glyph_ren_native_mono,
|
||||
glyph_ren_native_gray8,
|
||||
glyph_ren_outline,
|
||||
glyph_ren_agg_mono,
|
||||
glyph_ren_agg_gray8
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------font_cache_manager
|
||||
template<class FontEngine> class font_cache_manager
|
||||
{
|
||||
public:
|
||||
typedef FontEngine font_engine_type;
|
||||
typedef font_cache_manager<FontEngine> self_type;
|
||||
typedef typename font_engine_type::path_adaptor_type path_adaptor_type;
|
||||
typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type;
|
||||
typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type;
|
||||
typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type;
|
||||
typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_manager(font_engine_type& engine, unsigned max_fonts=32) :
|
||||
m_fonts(max_fonts),
|
||||
m_engine(engine),
|
||||
m_change_stamp(-1),
|
||||
m_prev_glyph(0),
|
||||
m_last_glyph(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_last_glyph()
|
||||
{
|
||||
m_prev_glyph = m_last_glyph = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* glyph(unsigned glyph_code)
|
||||
{
|
||||
synchronize();
|
||||
const glyph_cache* gl = m_fonts.find_glyph(glyph_code);
|
||||
if(gl)
|
||||
{
|
||||
m_prev_glyph = m_last_glyph;
|
||||
m_last_glyph = m_fonts.cache_glyph(glyph_code,
|
||||
m_engine.glyph_index(),
|
||||
m_engine.data_size(),
|
||||
m_engine.data_type(),
|
||||
m_engine.bounds(),
|
||||
m_engine.advance_x(),
|
||||
m_engine.advance_y());
|
||||
m_engine.write_glyph_to(m_last_glyph->data);
|
||||
return m_last_glyph;
|
||||
return m_last_glyph = gl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init_embedded_adaptors(const glyph_cache* gl, double x, double y, double scale = 1.0)
|
||||
{
|
||||
if (gl)
|
||||
{
|
||||
switch (gl->data_type)
|
||||
else
|
||||
{
|
||||
default:
|
||||
return;
|
||||
if(m_engine.prepare_glyph(glyph_code))
|
||||
{
|
||||
m_prev_glyph = m_last_glyph;
|
||||
m_last_glyph = m_fonts.cache_glyph(glyph_code,
|
||||
m_engine.glyph_index(),
|
||||
m_engine.data_size(),
|
||||
m_engine.data_type(),
|
||||
m_engine.bounds(),
|
||||
m_engine.advance_x(),
|
||||
m_engine.advance_y());
|
||||
m_engine.write_glyph_to(m_last_glyph->data);
|
||||
return m_last_glyph;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init_embedded_adaptors(const glyph_cache* gl,
|
||||
double x, double y,
|
||||
double scale=1.0)
|
||||
{
|
||||
if(gl)
|
||||
{
|
||||
switch(gl->data_type)
|
||||
{
|
||||
default: return;
|
||||
case glyph_data_mono:
|
||||
m_mono_adaptor.init(gl->data, gl->data_size, x, y);
|
||||
break;
|
||||
|
@ -289,76 +331,79 @@ class font_cache_manager
|
|||
case glyph_data_outline:
|
||||
m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
path_adaptor_type& path_adaptor() { return m_path_adaptor; }
|
||||
gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; }
|
||||
gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; }
|
||||
mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; }
|
||||
mono_scanline_type& mono_scanline() { return m_mono_scanline; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* perv_glyph() const { return m_prev_glyph; }
|
||||
const glyph_cache* last_glyph() const { return m_last_glyph; }
|
||||
//--------------------------------------------------------------------
|
||||
path_adaptor_type& path_adaptor() { return m_path_adaptor; }
|
||||
gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; }
|
||||
gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; }
|
||||
mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; }
|
||||
mono_scanline_type& mono_scanline() { return m_mono_scanline; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool add_kerning(double* x, double* y)
|
||||
{
|
||||
if (m_prev_glyph && m_last_glyph)
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* perv_glyph() const { return m_prev_glyph; }
|
||||
const glyph_cache* last_glyph() const { return m_last_glyph; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool add_kerning(double* x, double* y)
|
||||
{
|
||||
return m_engine.add_kerning(m_prev_glyph->glyph_index, m_last_glyph->glyph_index, x, y);
|
||||
if(m_prev_glyph && m_last_glyph)
|
||||
{
|
||||
return m_engine.add_kerning(m_prev_glyph->glyph_index,
|
||||
m_last_glyph->glyph_index,
|
||||
x, y);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void precache(unsigned from, unsigned to)
|
||||
{
|
||||
for (; from <= to; ++from)
|
||||
glyph(from);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_cache()
|
||||
{
|
||||
m_fonts.font(m_engine.font_signature(), true);
|
||||
m_change_stamp = m_engine.change_stamp();
|
||||
m_prev_glyph = m_last_glyph = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_manager(const self_type&);
|
||||
const self_type& operator=(const self_type&);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void synchronize()
|
||||
{
|
||||
if (m_change_stamp != m_engine.change_stamp())
|
||||
//--------------------------------------------------------------------
|
||||
void precache(unsigned from, unsigned to)
|
||||
{
|
||||
m_fonts.font(m_engine.font_signature());
|
||||
for(; from <= to; ++from) glyph(from);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_cache()
|
||||
{
|
||||
m_fonts.font(m_engine.font_signature(), true);
|
||||
m_change_stamp = m_engine.change_stamp();
|
||||
m_prev_glyph = m_last_glyph = 0;
|
||||
}
|
||||
}
|
||||
|
||||
font_cache_pool m_fonts;
|
||||
font_engine_type& m_engine;
|
||||
int m_change_stamp;
|
||||
double m_dx;
|
||||
double m_dy;
|
||||
const glyph_cache* m_prev_glyph;
|
||||
const glyph_cache* m_last_glyph;
|
||||
path_adaptor_type m_path_adaptor;
|
||||
gray8_adaptor_type m_gray8_adaptor;
|
||||
gray8_scanline_type m_gray8_scanline;
|
||||
mono_adaptor_type m_mono_adaptor;
|
||||
mono_scanline_type m_mono_scanline;
|
||||
};
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_manager(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
void synchronize()
|
||||
{
|
||||
if(m_change_stamp != m_engine.change_stamp())
|
||||
{
|
||||
m_fonts.font(m_engine.font_signature());
|
||||
m_change_stamp = m_engine.change_stamp();
|
||||
m_prev_glyph = m_last_glyph = 0;
|
||||
}
|
||||
}
|
||||
|
||||
font_cache_pool m_fonts;
|
||||
font_engine_type& m_engine;
|
||||
int m_change_stamp;
|
||||
double m_dx;
|
||||
double m_dy;
|
||||
const glyph_cache* m_prev_glyph;
|
||||
const glyph_cache* m_last_glyph;
|
||||
path_adaptor_type m_path_adaptor;
|
||||
gray8_adaptor_type m_gray8_adaptor;
|
||||
gray8_scanline_type m_gray8_scanline;
|
||||
mono_adaptor_type m_mono_adaptor;
|
||||
mono_scanline_type m_mono_scanline;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
227
deps/agg/include/agg_gamma_functions.h
vendored
227
deps/agg/include/agg_gamma_functions.h
vendored
|
@ -19,135 +19,116 @@
|
|||
#include <cmath>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
//===============================================================gamma_none
|
||||
struct gamma_none
|
||||
namespace agg
|
||||
{
|
||||
double operator()(double x) const { return x; }
|
||||
};
|
||||
|
||||
//==============================================================gamma_power
|
||||
class gamma_power
|
||||
{
|
||||
public:
|
||||
gamma_power()
|
||||
: m_gamma(1.0)
|
||||
{}
|
||||
gamma_power(double g)
|
||||
: m_gamma(g)
|
||||
{}
|
||||
|
||||
void gamma(double g) { m_gamma = g; }
|
||||
double gamma() const { return m_gamma; }
|
||||
|
||||
double operator()(double x) const
|
||||
//===============================================================gamma_none
|
||||
struct gamma_none
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 0.0;
|
||||
return pow(x, m_gamma);
|
||||
double operator()(double x) const { return x; }
|
||||
};
|
||||
|
||||
|
||||
//==============================================================gamma_power
|
||||
class gamma_power
|
||||
{
|
||||
public:
|
||||
gamma_power() : m_gamma(1.0) {}
|
||||
gamma_power(double g) : m_gamma(g) {}
|
||||
|
||||
void gamma(double g) { m_gamma = g; }
|
||||
double gamma() const { return m_gamma; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
if (x == 0.0) return 0.0;
|
||||
return pow(x, m_gamma);
|
||||
}
|
||||
|
||||
private:
|
||||
double m_gamma;
|
||||
};
|
||||
|
||||
|
||||
//==========================================================gamma_threshold
|
||||
class gamma_threshold
|
||||
{
|
||||
public:
|
||||
gamma_threshold() : m_threshold(0.5) {}
|
||||
gamma_threshold(double t) : m_threshold(t) {}
|
||||
|
||||
void threshold(double t) { m_threshold = t; }
|
||||
double threshold() const { return m_threshold; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
return (x < m_threshold) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_threshold;
|
||||
};
|
||||
|
||||
|
||||
//============================================================gamma_linear
|
||||
class gamma_linear
|
||||
{
|
||||
public:
|
||||
gamma_linear() : m_start(0.0), m_end(1.0) {}
|
||||
gamma_linear(double s, double e) : m_start(s), m_end(e) {}
|
||||
|
||||
void set(double s, double e) { m_start = s; m_end = e; }
|
||||
void start(double s) { m_start = s; }
|
||||
void end(double e) { m_end = e; }
|
||||
double start() const { return m_start; }
|
||||
double end() const { return m_end; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
if(x < m_start) return 0.0;
|
||||
if(x > m_end) return 1.0;
|
||||
double delta = m_end - m_start;
|
||||
// avoid nan from potential zero division
|
||||
// https://github.com/mapnik/mapnik/issues/761
|
||||
if (delta <= 0.0) return 0.0;
|
||||
return (x - m_start) / delta;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_start;
|
||||
double m_end;
|
||||
};
|
||||
|
||||
|
||||
//==========================================================gamma_multiply
|
||||
class gamma_multiply
|
||||
{
|
||||
public:
|
||||
gamma_multiply() : m_mul(1.0) {}
|
||||
gamma_multiply(double v) : m_mul(v) {}
|
||||
|
||||
void value(double v) { m_mul = v; }
|
||||
double value() const { return m_mul; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
double y = x * m_mul;
|
||||
if(y > 1.0) y = 1.0;
|
||||
return y;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_mul;
|
||||
};
|
||||
|
||||
inline double sRGB_to_linear(double x)
|
||||
{
|
||||
return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4);
|
||||
}
|
||||
|
||||
private:
|
||||
double m_gamma;
|
||||
};
|
||||
|
||||
//==========================================================gamma_threshold
|
||||
class gamma_threshold
|
||||
{
|
||||
public:
|
||||
gamma_threshold()
|
||||
: m_threshold(0.5)
|
||||
{}
|
||||
gamma_threshold(double t)
|
||||
: m_threshold(t)
|
||||
{}
|
||||
|
||||
void threshold(double t) { m_threshold = t; }
|
||||
double threshold() const { return m_threshold; }
|
||||
|
||||
double operator()(double x) const { return (x < m_threshold) ? 0.0 : 1.0; }
|
||||
|
||||
private:
|
||||
double m_threshold;
|
||||
};
|
||||
|
||||
//============================================================gamma_linear
|
||||
class gamma_linear
|
||||
{
|
||||
public:
|
||||
gamma_linear()
|
||||
: m_start(0.0)
|
||||
, m_end(1.0)
|
||||
{}
|
||||
gamma_linear(double s, double e)
|
||||
: m_start(s)
|
||||
, m_end(e)
|
||||
{}
|
||||
|
||||
void set(double s, double e)
|
||||
inline double linear_to_sRGB(double x)
|
||||
{
|
||||
m_start = s;
|
||||
m_end = e;
|
||||
return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
|
||||
}
|
||||
void start(double s) { m_start = s; }
|
||||
void end(double e) { m_end = e; }
|
||||
double start() const { return m_start; }
|
||||
double end() const { return m_end; }
|
||||
|
||||
double operator()(double x) const
|
||||
{
|
||||
if (x < m_start)
|
||||
return 0.0;
|
||||
if (x > m_end)
|
||||
return 1.0;
|
||||
double delta = m_end - m_start;
|
||||
// avoid nan from potential zero division
|
||||
// https://github.com/mapnik/mapnik/issues/761
|
||||
if (delta <= 0.0)
|
||||
return 0.0;
|
||||
return (x - m_start) / delta;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_start;
|
||||
double m_end;
|
||||
};
|
||||
|
||||
//==========================================================gamma_multiply
|
||||
class gamma_multiply
|
||||
{
|
||||
public:
|
||||
gamma_multiply()
|
||||
: m_mul(1.0)
|
||||
{}
|
||||
gamma_multiply(double v)
|
||||
: m_mul(v)
|
||||
{}
|
||||
|
||||
void value(double v) { m_mul = v; }
|
||||
double value() const { return m_mul; }
|
||||
|
||||
double operator()(double x) const
|
||||
{
|
||||
double y = x * m_mul;
|
||||
if (y > 1.0)
|
||||
y = 1.0;
|
||||
return y;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_mul;
|
||||
};
|
||||
|
||||
inline double sRGB_to_linear(double x)
|
||||
{
|
||||
return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4);
|
||||
}
|
||||
|
||||
inline double linear_to_sRGB(double x)
|
||||
{
|
||||
return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
|
||||
}
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
459
deps/agg/include/agg_gamma_lut.h
vendored
459
deps/agg/include/agg_gamma_lut.h
vendored
|
@ -20,247 +20,286 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_gamma_functions.h"
|
||||
|
||||
namespace agg {
|
||||
template<class LoResT = int8u, class HiResT = int8u, unsigned GammaShift = 8, unsigned HiResShift = 8>
|
||||
class gamma_lut
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
|
||||
|
||||
enum gamma_scale_e { gamma_shift = GammaShift, gamma_size = 1 << gamma_shift, gamma_mask = gamma_size - 1 };
|
||||
|
||||
enum hi_res_scale_e { hi_res_shift = HiResShift, hi_res_size = 1 << hi_res_shift, hi_res_mask = hi_res_size - 1 };
|
||||
|
||||
~gamma_lut()
|
||||
template<class LoResT=int8u,
|
||||
class HiResT=int8u,
|
||||
unsigned GammaShift=8,
|
||||
unsigned HiResShift=8> class gamma_lut
|
||||
{
|
||||
pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
|
||||
pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
|
||||
}
|
||||
public:
|
||||
typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
|
||||
|
||||
gamma_lut()
|
||||
: m_gamma(1.0)
|
||||
, m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size))
|
||||
, m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < gamma_size; i++)
|
||||
enum gamma_scale_e
|
||||
{
|
||||
m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift));
|
||||
gamma_shift = GammaShift,
|
||||
gamma_size = 1 << gamma_shift,
|
||||
gamma_mask = gamma_size - 1
|
||||
};
|
||||
|
||||
enum hi_res_scale_e
|
||||
{
|
||||
hi_res_shift = HiResShift,
|
||||
hi_res_size = 1 << hi_res_shift,
|
||||
hi_res_mask = hi_res_size - 1
|
||||
};
|
||||
|
||||
~gamma_lut()
|
||||
{
|
||||
pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
|
||||
pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
|
||||
}
|
||||
|
||||
for (i = 0; i < hi_res_size; i++)
|
||||
gamma_lut() :
|
||||
m_gamma(1.0),
|
||||
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
|
||||
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||
{
|
||||
m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift));
|
||||
}
|
||||
}
|
||||
unsigned i;
|
||||
for(i = 0; i < gamma_size; i++)
|
||||
{
|
||||
m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift));
|
||||
}
|
||||
|
||||
gamma_lut(double g)
|
||||
: m_gamma(1.0)
|
||||
, m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size))
|
||||
, m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||
{
|
||||
gamma(g);
|
||||
}
|
||||
|
||||
void gamma(double g)
|
||||
{
|
||||
m_gamma = g;
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < gamma_size; i++)
|
||||
{
|
||||
m_dir_gamma[i] = (HiResT)uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask));
|
||||
for(i = 0; i < hi_res_size; i++)
|
||||
{
|
||||
m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift));
|
||||
}
|
||||
}
|
||||
|
||||
double inv_g = 1.0 / g;
|
||||
for (i = 0; i < hi_res_size; i++)
|
||||
gamma_lut(double g) :
|
||||
m_gamma(1.0),
|
||||
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
|
||||
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||
{
|
||||
m_inv_gamma[i] = (LoResT)uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask));
|
||||
gamma(g);
|
||||
}
|
||||
}
|
||||
|
||||
double gamma() const { return m_gamma; }
|
||||
|
||||
HiResT dir(LoResT v) const { return m_dir_gamma[unsigned(v)]; }
|
||||
|
||||
LoResT inv(HiResT v) const { return m_inv_gamma[unsigned(v)]; }
|
||||
|
||||
private:
|
||||
gamma_lut(const self_type&);
|
||||
const self_type& operator=(const self_type&);
|
||||
|
||||
double m_gamma;
|
||||
HiResT* m_dir_gamma;
|
||||
LoResT* m_inv_gamma;
|
||||
};
|
||||
|
||||
//
|
||||
// sRGB support classes
|
||||
//
|
||||
|
||||
// Optimized sRGB lookup table. The direct conversion (sRGB to linear)
|
||||
// is a straightforward lookup. The inverse conversion (linear to sRGB)
|
||||
// is implemented using binary search.
|
||||
template<class LinearType>
|
||||
class sRGB_lut_base
|
||||
{
|
||||
public:
|
||||
LinearType dir(int8u v) const { return m_dir_table[v]; }
|
||||
|
||||
int8u inv(LinearType v) const
|
||||
{
|
||||
// Unrolled binary search.
|
||||
int8u x = 0;
|
||||
if (v > m_inv_table[128])
|
||||
x = 128;
|
||||
if (v > m_inv_table[x + 64])
|
||||
x += 64;
|
||||
if (v > m_inv_table[x + 32])
|
||||
x += 32;
|
||||
if (v > m_inv_table[x + 16])
|
||||
x += 16;
|
||||
if (v > m_inv_table[x + 8])
|
||||
x += 8;
|
||||
if (v > m_inv_table[x + 4])
|
||||
x += 4;
|
||||
if (v > m_inv_table[x + 2])
|
||||
x += 2;
|
||||
if (v > m_inv_table[x + 1])
|
||||
x += 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
protected:
|
||||
LinearType m_dir_table[256];
|
||||
LinearType m_inv_table[256];
|
||||
|
||||
// Only derived classes may instantiate.
|
||||
sRGB_lut_base() {}
|
||||
};
|
||||
|
||||
// sRGB_lut - implements sRGB conversion for the various types.
|
||||
// Base template is undefined, specializations are provided below.
|
||||
template<class LinearType>
|
||||
class sRGB_lut;
|
||||
|
||||
template<>
|
||||
class sRGB_lut<float> : public sRGB_lut_base<float>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
m_dir_table[0] = 0;
|
||||
m_inv_table[0] = 0;
|
||||
for (unsigned i = 1; i <= 255; ++i)
|
||||
void gamma(double g)
|
||||
{
|
||||
// Floating-point RGB is in range [0,1].
|
||||
m_dir_table[i] = float(sRGB_to_linear(i / 255.0));
|
||||
m_inv_table[i] = float(sRGB_to_linear((i - 0.5) / 255.0));
|
||||
}
|
||||
}
|
||||
};
|
||||
m_gamma = g;
|
||||
|
||||
template<>
|
||||
class sRGB_lut<int16u> : public sRGB_lut_base<int16u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
m_dir_table[0] = 0;
|
||||
m_inv_table[0] = 0;
|
||||
for (unsigned i = 1; i <= 255; ++i)
|
||||
unsigned i;
|
||||
for(i = 0; i < gamma_size; i++)
|
||||
{
|
||||
m_dir_gamma[i] = (HiResT)
|
||||
uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask));
|
||||
}
|
||||
|
||||
double inv_g = 1.0 / g;
|
||||
for(i = 0; i < hi_res_size; i++)
|
||||
{
|
||||
m_inv_gamma[i] = (LoResT)
|
||||
uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask));
|
||||
}
|
||||
}
|
||||
|
||||
double gamma() const
|
||||
{
|
||||
// 16-bit RGB is in range [0,65535].
|
||||
m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0));
|
||||
m_inv_table[i] = uround(65535.0 * sRGB_to_linear((i - 0.5) / 255.0));
|
||||
return m_gamma;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_lut<int8u> : public sRGB_lut_base<int8u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
m_dir_table[0] = 0;
|
||||
m_inv_table[0] = 0;
|
||||
for (unsigned i = 1; i <= 255; ++i)
|
||||
HiResT dir(LoResT v) const
|
||||
{
|
||||
// 8-bit RGB is handled with simple bidirectional lookup tables.
|
||||
m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0));
|
||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0));
|
||||
return m_dir_gamma[unsigned(v)];
|
||||
}
|
||||
}
|
||||
|
||||
int8u inv(int8u v) const
|
||||
LoResT inv(HiResT v) const
|
||||
{
|
||||
return m_inv_gamma[unsigned(v)];
|
||||
}
|
||||
|
||||
private:
|
||||
gamma_lut(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
double m_gamma;
|
||||
HiResT* m_dir_gamma;
|
||||
LoResT* m_inv_gamma;
|
||||
};
|
||||
|
||||
//
|
||||
// sRGB support classes
|
||||
//
|
||||
|
||||
// Optimized sRGB lookup table. The direct conversion (sRGB to linear)
|
||||
// is a straightforward lookup. The inverse conversion (linear to sRGB)
|
||||
// is implemented using binary search.
|
||||
template<class LinearType>
|
||||
class sRGB_lut_base
|
||||
{
|
||||
// In this case, the inverse transform is a simple lookup.
|
||||
return m_inv_table[v];
|
||||
}
|
||||
};
|
||||
public:
|
||||
LinearType dir(int8u v) const
|
||||
{
|
||||
return m_dir_table[v];
|
||||
}
|
||||
|
||||
// Common base class for sRGB_conv objects. Defines an internal
|
||||
// sRGB_lut object so that users don't have to.
|
||||
template<class T>
|
||||
class sRGB_conv_base
|
||||
{
|
||||
public:
|
||||
static T rgb_from_sRGB(int8u x) { return lut.dir(x); }
|
||||
int8u inv(LinearType v) const
|
||||
{
|
||||
// Unrolled binary search.
|
||||
int8u x = 0;
|
||||
if (v > m_inv_table[128]) x = 128;
|
||||
if (v > m_inv_table[x + 64]) x += 64;
|
||||
if (v > m_inv_table[x + 32]) x += 32;
|
||||
if (v > m_inv_table[x + 16]) x += 16;
|
||||
if (v > m_inv_table[x + 8]) x += 8;
|
||||
if (v > m_inv_table[x + 4]) x += 4;
|
||||
if (v > m_inv_table[x + 2]) x += 2;
|
||||
if (v > m_inv_table[x + 1]) x += 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
static int8u rgb_to_sRGB(T x) { return lut.inv(x); }
|
||||
protected:
|
||||
LinearType m_dir_table[256];
|
||||
LinearType m_inv_table[256];
|
||||
|
||||
private:
|
||||
static sRGB_lut<T> lut;
|
||||
};
|
||||
// Only derived classes may instantiate.
|
||||
sRGB_lut_base()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Definition of sRGB_conv_base::lut. Due to the fact that this a template,
|
||||
// we don't need to place the definition in a cpp file. Hurrah.
|
||||
template<class T>
|
||||
sRGB_lut<T> sRGB_conv_base<T>::lut;
|
||||
// sRGB_lut - implements sRGB conversion for the various types.
|
||||
// Base template is undefined, specializations are provided below.
|
||||
template<class LinearType>
|
||||
class sRGB_lut;
|
||||
|
||||
// Wrapper for sRGB-linear conversion.
|
||||
// Base template is undefined, specializations are provided below.
|
||||
template<class T>
|
||||
class sRGB_conv;
|
||||
|
||||
template<>
|
||||
class sRGB_conv<float> : public sRGB_conv_base<float>
|
||||
{
|
||||
public:
|
||||
static float alpha_from_sRGB(int8u x) { return float(x / 255.0); }
|
||||
|
||||
static int8u alpha_to_sRGB(float x)
|
||||
template<>
|
||||
class sRGB_lut<float> : public sRGB_lut_base<float>
|
||||
{
|
||||
if (x <= 0)
|
||||
return 0;
|
||||
else if (x >= 1)
|
||||
return 255;
|
||||
else
|
||||
return int8u(0.5 + x * 255);
|
||||
}
|
||||
};
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
m_dir_table[0] = 0;
|
||||
m_inv_table[0] = 0;
|
||||
for (unsigned i = 1; i <= 255; ++i)
|
||||
{
|
||||
// Floating-point RGB is in range [0,1].
|
||||
m_dir_table[i] = float(sRGB_to_linear(i / 255.0));
|
||||
m_inv_table[i] = float(sRGB_to_linear((i - 0.5) / 255.0));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_conv<int16u> : public sRGB_conv_base<int16u>
|
||||
{
|
||||
public:
|
||||
static int16u alpha_from_sRGB(int8u x) { return (x << 8) | x; }
|
||||
template<>
|
||||
class sRGB_lut<int16u> : public sRGB_lut_base<int16u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
m_dir_table[0] = 0;
|
||||
m_inv_table[0] = 0;
|
||||
for (unsigned i = 1; i <= 255; ++i)
|
||||
{
|
||||
// 16-bit RGB is in range [0,65535].
|
||||
m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0));
|
||||
m_inv_table[i] = uround(65535.0 * sRGB_to_linear((i - 0.5) / 255.0));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int8u alpha_to_sRGB(int16u x) { return x >> 8; }
|
||||
};
|
||||
template<>
|
||||
class sRGB_lut<int8u> : public sRGB_lut_base<int8u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
m_dir_table[0] = 0;
|
||||
m_inv_table[0] = 0;
|
||||
for (unsigned i = 1; i <= 255; ++i)
|
||||
{
|
||||
// 8-bit RGB is handled with simple bidirectional lookup tables.
|
||||
m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0));
|
||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0));
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
class sRGB_conv<int8u> : public sRGB_conv_base<int8u>
|
||||
{
|
||||
public:
|
||||
static int8u alpha_from_sRGB(int8u x) { return x; }
|
||||
int8u inv(int8u v) const
|
||||
{
|
||||
// In this case, the inverse transform is a simple lookup.
|
||||
return m_inv_table[v];
|
||||
}
|
||||
};
|
||||
|
||||
static int8u alpha_to_sRGB(int8u x) { return x; }
|
||||
};
|
||||
} // namespace agg
|
||||
// Common base class for sRGB_conv objects. Defines an internal
|
||||
// sRGB_lut object so that users don't have to.
|
||||
template<class T>
|
||||
class sRGB_conv_base
|
||||
{
|
||||
public:
|
||||
static T rgb_from_sRGB(int8u x)
|
||||
{
|
||||
return lut.dir(x);
|
||||
}
|
||||
|
||||
static int8u rgb_to_sRGB(T x)
|
||||
{
|
||||
return lut.inv(x);
|
||||
}
|
||||
|
||||
private:
|
||||
static sRGB_lut<T> lut;
|
||||
};
|
||||
|
||||
// Definition of sRGB_conv_base::lut. Due to the fact that this a template,
|
||||
// we don't need to place the definition in a cpp file. Hurrah.
|
||||
template<class T>
|
||||
sRGB_lut<T> sRGB_conv_base<T>::lut;
|
||||
|
||||
// Wrapper for sRGB-linear conversion.
|
||||
// Base template is undefined, specializations are provided below.
|
||||
template<class T>
|
||||
class sRGB_conv;
|
||||
|
||||
template<>
|
||||
class sRGB_conv<float> : public sRGB_conv_base<float>
|
||||
{
|
||||
public:
|
||||
static float alpha_from_sRGB(int8u x)
|
||||
{
|
||||
return float(x / 255.0);
|
||||
}
|
||||
|
||||
static int8u alpha_to_sRGB(float x)
|
||||
{
|
||||
if (x <= 0) return 0;
|
||||
else if (x >= 1) return 255;
|
||||
else return int8u(0.5 + x * 255);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_conv<int16u> : public sRGB_conv_base<int16u>
|
||||
{
|
||||
public:
|
||||
static int16u alpha_from_sRGB(int8u x)
|
||||
{
|
||||
return (x << 8) | x;
|
||||
}
|
||||
|
||||
static int8u alpha_to_sRGB(int16u x)
|
||||
{
|
||||
return x >> 8;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_conv<int8u> : public sRGB_conv_base<int8u>
|
||||
{
|
||||
public:
|
||||
static int8u alpha_from_sRGB(int8u x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
static int8u alpha_to_sRGB(int8u x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
249
deps/agg/include/agg_glyph_raster_bin.h
vendored
249
deps/agg/include/agg_glyph_raster_bin.h
vendored
|
@ -19,134 +19,137 @@
|
|||
#include <cstring>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//========================================================glyph_raster_bin
|
||||
template<class ColorT>
|
||||
class glyph_raster_bin
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct glyph_rect
|
||||
//========================================================glyph_raster_bin
|
||||
template<class ColorT> class glyph_raster_bin
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
double dx, dy;
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct glyph_rect
|
||||
{
|
||||
int x1,y1,x2,y2;
|
||||
double dx, dy;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
glyph_raster_bin(const int8u* font) :
|
||||
m_font(font),
|
||||
m_big_endian(false)
|
||||
{
|
||||
int t = 1;
|
||||
if(*(char*)&t == 0) m_big_endian = true;
|
||||
memset(m_span, 0, sizeof(m_span));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const int8u* font() const { return m_font; }
|
||||
void font(const int8u* f) { m_font = f; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double height() const { return m_font[0]; }
|
||||
double base_line() const { return m_font[1]; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
double width(const CharT* str) const
|
||||
{
|
||||
unsigned start_char = m_font[2];
|
||||
unsigned num_chars = m_font[3];
|
||||
|
||||
unsigned w = 0;
|
||||
while(*str)
|
||||
{
|
||||
unsigned glyph = *str;
|
||||
const int8u* bits = m_font + 4 + num_chars * 2 +
|
||||
value(m_font + 4 + (glyph - start_char) * 2);
|
||||
w += *bits;
|
||||
++str;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip)
|
||||
{
|
||||
unsigned start_char = m_font[2];
|
||||
unsigned num_chars = m_font[3];
|
||||
|
||||
m_bits = m_font + 4 + num_chars * 2 +
|
||||
value(m_font + 4 + (glyph - start_char) * 2);
|
||||
|
||||
m_glyph_width = *m_bits++;
|
||||
m_glyph_byte_width = (m_glyph_width + 7) >> 3;
|
||||
|
||||
r->x1 = int(x);
|
||||
r->x2 = r->x1 + m_glyph_width - 1;
|
||||
if(flip)
|
||||
{
|
||||
r->y1 = int(y) - m_font[0] + m_font[1];
|
||||
r->y2 = r->y1 + m_font[0] - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r->y1 = int(y) - m_font[1] + 1;
|
||||
r->y2 = r->y1 + m_font[0] - 1;
|
||||
}
|
||||
r->dx = m_glyph_width;
|
||||
r->dy = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const cover_type* span(unsigned i)
|
||||
{
|
||||
i = m_font[0] - i - 1;
|
||||
const int8u* bits = m_bits + i * m_glyph_byte_width;
|
||||
unsigned j;
|
||||
unsigned val = *bits;
|
||||
unsigned nb = 0;
|
||||
for(j = 0; j < m_glyph_width; ++j)
|
||||
{
|
||||
m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none);
|
||||
val <<= 1;
|
||||
if(++nb >= 8)
|
||||
{
|
||||
val = *++bits;
|
||||
nb = 0;
|
||||
}
|
||||
}
|
||||
return m_span;
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
int16u value(const int8u* p) const
|
||||
{
|
||||
int16u v;
|
||||
if(m_big_endian)
|
||||
{
|
||||
*(int8u*)&v = p[1];
|
||||
*((int8u*)&v + 1) = p[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(int8u*)&v = p[0];
|
||||
*((int8u*)&v + 1) = p[1];
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const int8u* m_font;
|
||||
bool m_big_endian;
|
||||
cover_type m_span[32];
|
||||
const int8u* m_bits;
|
||||
unsigned m_glyph_width;
|
||||
unsigned m_glyph_byte_width;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
glyph_raster_bin(const int8u* font)
|
||||
: m_font(font)
|
||||
, m_big_endian(false)
|
||||
{
|
||||
int t = 1;
|
||||
if (*(char*)&t == 0)
|
||||
m_big_endian = true;
|
||||
memset(m_span, 0, sizeof(m_span));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const int8u* font() const { return m_font; }
|
||||
void font(const int8u* f) { m_font = f; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double height() const { return m_font[0]; }
|
||||
double base_line() const { return m_font[1]; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
double width(const CharT* str) const
|
||||
{
|
||||
unsigned start_char = m_font[2];
|
||||
unsigned num_chars = m_font[3];
|
||||
|
||||
unsigned w = 0;
|
||||
while (*str)
|
||||
{
|
||||
unsigned glyph = *str;
|
||||
const int8u* bits = m_font + 4 + num_chars * 2 + value(m_font + 4 + (glyph - start_char) * 2);
|
||||
w += *bits;
|
||||
++str;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip)
|
||||
{
|
||||
unsigned start_char = m_font[2];
|
||||
unsigned num_chars = m_font[3];
|
||||
|
||||
m_bits = m_font + 4 + num_chars * 2 + value(m_font + 4 + (glyph - start_char) * 2);
|
||||
|
||||
m_glyph_width = *m_bits++;
|
||||
m_glyph_byte_width = (m_glyph_width + 7) >> 3;
|
||||
|
||||
r->x1 = int(x);
|
||||
r->x2 = r->x1 + m_glyph_width - 1;
|
||||
if (flip)
|
||||
{
|
||||
r->y1 = int(y) - m_font[0] + m_font[1];
|
||||
r->y2 = r->y1 + m_font[0] - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r->y1 = int(y) - m_font[1] + 1;
|
||||
r->y2 = r->y1 + m_font[0] - 1;
|
||||
}
|
||||
r->dx = m_glyph_width;
|
||||
r->dy = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const cover_type* span(unsigned i)
|
||||
{
|
||||
i = m_font[0] - i - 1;
|
||||
const int8u* bits = m_bits + i * m_glyph_byte_width;
|
||||
unsigned j;
|
||||
unsigned val = *bits;
|
||||
unsigned nb = 0;
|
||||
for (j = 0; j < m_glyph_width; ++j)
|
||||
{
|
||||
m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none);
|
||||
val <<= 1;
|
||||
if (++nb >= 8)
|
||||
{
|
||||
val = *++bits;
|
||||
nb = 0;
|
||||
}
|
||||
}
|
||||
return m_span;
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
int16u value(const int8u* p) const
|
||||
{
|
||||
int16u v;
|
||||
if (m_big_endian)
|
||||
{
|
||||
*(int8u*)&v = p[1];
|
||||
*((int8u*)&v + 1) = p[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(int8u*)&v = p[0];
|
||||
*((int8u*)&v + 1) = p[1];
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const int8u* m_font;
|
||||
bool m_big_endian;
|
||||
cover_type m_span[32];
|
||||
const int8u* m_bits;
|
||||
unsigned m_glyph_width;
|
||||
unsigned m_glyph_byte_width;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
378
deps/agg/include/agg_gradient_lut.h
vendored
378
deps/agg/include/agg_gradient_lut.h
vendored
|
@ -21,200 +21,226 @@
|
|||
#include "agg_color_rgba.h"
|
||||
#include "agg_color_gray.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//======================================================color_interpolator
|
||||
template<class ColorT>
|
||||
struct color_interpolator
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
color_interpolator(const color_type& c1, const color_type& c2, unsigned len)
|
||||
: m_c1(c1)
|
||||
, m_c2(c2)
|
||||
, m_len(len)
|
||||
, m_count(0)
|
||||
{}
|
||||
|
||||
void operator++() { ++m_count; }
|
||||
|
||||
color_type color() const { return m_c1.gradient(m_c2, double(m_count) / m_len); }
|
||||
|
||||
private:
|
||||
color_type m_c1;
|
||||
color_type m_c2;
|
||||
unsigned m_len;
|
||||
unsigned m_count;
|
||||
};
|
||||
|
||||
//========================================================================
|
||||
// Fast specialization for rgba8
|
||||
template<>
|
||||
struct color_interpolator<rgba8>
|
||||
{
|
||||
public:
|
||||
typedef rgba8 color_type;
|
||||
|
||||
color_interpolator(const color_type& c1, const color_type& c2, unsigned len)
|
||||
: r(c1.r, c2.r, len)
|
||||
, g(c1.g, c2.g, len)
|
||||
, b(c1.b, c2.b, len)
|
||||
, a(c1.a, c2.a, len)
|
||||
{}
|
||||
|
||||
void operator++()
|
||||
//======================================================color_interpolator
|
||||
template<class ColorT> struct color_interpolator
|
||||
{
|
||||
++r;
|
||||
++g;
|
||||
++b;
|
||||
++a;
|
||||
}
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
color_type color() const { return color_type(r.y(), g.y(), b.y(), a.y()); }
|
||||
color_interpolator(const color_type& c1,
|
||||
const color_type& c2,
|
||||
unsigned len) :
|
||||
m_c1(c1),
|
||||
m_c2(c2),
|
||||
m_len(len),
|
||||
m_count(0)
|
||||
{}
|
||||
|
||||
private:
|
||||
agg::dda_line_interpolator<14> r, g, b, a;
|
||||
};
|
||||
|
||||
//========================================================================
|
||||
// Fast specialization for gray8
|
||||
template<>
|
||||
struct color_interpolator<gray8>
|
||||
{
|
||||
public:
|
||||
typedef gray8 color_type;
|
||||
|
||||
color_interpolator(const color_type& c1, const color_type& c2, unsigned len)
|
||||
: v(c1.v, c2.v, len)
|
||||
, a(c1.a, c2.a, len)
|
||||
{}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
++v;
|
||||
++a;
|
||||
}
|
||||
|
||||
color_type color() const { return color_type(v.y(), a.y()); }
|
||||
|
||||
private:
|
||||
agg::dda_line_interpolator<14> v, a;
|
||||
};
|
||||
|
||||
//============================================================gradient_lut
|
||||
template<class ColorInterpolator, unsigned ColorLutSize = 256>
|
||||
class gradient_lut
|
||||
{
|
||||
public:
|
||||
typedef ColorInterpolator interpolator_type;
|
||||
typedef typename interpolator_type::color_type color_type;
|
||||
enum { color_lut_size = ColorLutSize };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gradient_lut()
|
||||
: m_color_lut(color_lut_size)
|
||||
{}
|
||||
|
||||
// Build Gradient Lut
|
||||
// First, call remove_all(), then add_color() at least twice,
|
||||
// then build_lut(). Argument "offset" in add_color must be
|
||||
// in range [0...1] and defines a color stop as it is described
|
||||
// in SVG specification, section Gradients and Patterns.
|
||||
// The simplest linear gradient is:
|
||||
// gradient_lut.add_color(0.0, start_color);
|
||||
// gradient_lut.add_color(1.0, end_color);
|
||||
//--------------------------------------------------------------------
|
||||
void remove_all();
|
||||
void add_color(double offset, const color_type& color);
|
||||
bool build_lut();
|
||||
|
||||
// Size-index Interface. This class can be used directly as the
|
||||
// ColorF in span_gradient. All it needs is two access methods
|
||||
// size() and operator [].
|
||||
//--------------------------------------------------------------------
|
||||
static unsigned size() { return color_lut_size; }
|
||||
const color_type& operator[](unsigned i) const { return m_color_lut[i]; }
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
struct color_point
|
||||
{
|
||||
double offset;
|
||||
color_type color;
|
||||
|
||||
color_point() {}
|
||||
color_point(double off, const color_type& c)
|
||||
: offset(off)
|
||||
, color(c)
|
||||
void operator ++ ()
|
||||
{
|
||||
if (offset < 0.0)
|
||||
offset = 0.0;
|
||||
if (offset > 1.0)
|
||||
offset = 1.0;
|
||||
++m_count;
|
||||
}
|
||||
|
||||
color_type color() const
|
||||
{
|
||||
return m_c1.gradient(m_c2, double(m_count) / m_len);
|
||||
}
|
||||
|
||||
private:
|
||||
color_type m_c1;
|
||||
color_type m_c2;
|
||||
unsigned m_len;
|
||||
unsigned m_count;
|
||||
};
|
||||
typedef agg::pod_bvector<color_point, 4> color_profile_type;
|
||||
typedef agg::pod_array<color_type> color_lut_type;
|
||||
|
||||
static bool offset_less(const color_point& a, const color_point& b) { return a.offset < b.offset; }
|
||||
static bool offset_equal(const color_point& a, const color_point& b) { return a.offset == b.offset; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_profile_type m_color_profile;
|
||||
color_lut_type m_color_lut;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void gradient_lut<T, S>::remove_all()
|
||||
{
|
||||
m_color_profile.remove_all();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void gradient_lut<T, S>::add_color(double offset, const color_type& color)
|
||||
{
|
||||
m_color_profile.add(color_point(offset, color));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
bool gradient_lut<T, S>::build_lut()
|
||||
{
|
||||
quick_sort(m_color_profile, offset_less);
|
||||
m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal));
|
||||
if (m_color_profile.size() >= 2)
|
||||
//========================================================================
|
||||
// Fast specialization for rgba8
|
||||
template<> struct color_interpolator<rgba8>
|
||||
{
|
||||
unsigned i;
|
||||
unsigned start = uround(m_color_profile[0].offset * color_lut_size);
|
||||
unsigned end = 0;
|
||||
color_type c = m_color_profile[0].color;
|
||||
for (i = 0; i < start; i++)
|
||||
public:
|
||||
typedef rgba8 color_type;
|
||||
|
||||
color_interpolator(const color_type& c1,
|
||||
const color_type& c2,
|
||||
unsigned len) :
|
||||
r(c1.r, c2.r, len),
|
||||
g(c1.g, c2.g, len),
|
||||
b(c1.b, c2.b, len),
|
||||
a(c1.a, c2.a, len)
|
||||
{}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
m_color_lut[i] = c;
|
||||
++r; ++g; ++b; ++a;
|
||||
}
|
||||
for (i = 1; i < m_color_profile.size(); i++)
|
||||
|
||||
color_type color() const
|
||||
{
|
||||
end = uround(m_color_profile[i].offset * color_lut_size);
|
||||
interpolator_type ci(m_color_profile[i - 1].color, m_color_profile[i].color, end - start + 1);
|
||||
while (start < end)
|
||||
return color_type(r.y(), g.y(), b.y(), a.y());
|
||||
}
|
||||
|
||||
private:
|
||||
agg::dda_line_interpolator<14> r, g, b, a;
|
||||
};
|
||||
|
||||
//========================================================================
|
||||
// Fast specialization for gray8
|
||||
template<> struct color_interpolator<gray8>
|
||||
{
|
||||
public:
|
||||
typedef gray8 color_type;
|
||||
|
||||
color_interpolator(const color_type& c1,
|
||||
const color_type& c2,
|
||||
unsigned len) :
|
||||
v(c1.v, c2.v, len),
|
||||
a(c1.a, c2.a, len)
|
||||
{}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
++v; ++a;
|
||||
}
|
||||
|
||||
color_type color() const
|
||||
{
|
||||
return color_type(v.y(), a.y());
|
||||
}
|
||||
|
||||
private:
|
||||
agg::dda_line_interpolator<14> v,a;
|
||||
};
|
||||
|
||||
//============================================================gradient_lut
|
||||
template<class ColorInterpolator,
|
||||
unsigned ColorLutSize=256> class gradient_lut
|
||||
{
|
||||
public:
|
||||
typedef ColorInterpolator interpolator_type;
|
||||
typedef typename interpolator_type::color_type color_type;
|
||||
enum { color_lut_size = ColorLutSize };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
gradient_lut() : m_color_lut(color_lut_size) {}
|
||||
|
||||
// Build Gradient Lut
|
||||
// First, call remove_all(), then add_color() at least twice,
|
||||
// then build_lut(). Argument "offset" in add_color must be
|
||||
// in range [0...1] and defines a color stop as it is described
|
||||
// in SVG specification, section Gradients and Patterns.
|
||||
// The simplest linear gradient is:
|
||||
// gradient_lut.add_color(0.0, start_color);
|
||||
// gradient_lut.add_color(1.0, end_color);
|
||||
//--------------------------------------------------------------------
|
||||
void remove_all();
|
||||
void add_color(double offset, const color_type& color);
|
||||
bool build_lut();
|
||||
|
||||
// Size-index Interface. This class can be used directly as the
|
||||
// ColorF in span_gradient. All it needs is two access methods
|
||||
// size() and operator [].
|
||||
//--------------------------------------------------------------------
|
||||
static unsigned size()
|
||||
{
|
||||
return color_lut_size;
|
||||
}
|
||||
const color_type& operator [] (unsigned i) const
|
||||
{
|
||||
return m_color_lut[i];
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
struct color_point
|
||||
{
|
||||
double offset;
|
||||
color_type color;
|
||||
|
||||
color_point() {}
|
||||
color_point(double off, const color_type& c) :
|
||||
offset(off), color(c)
|
||||
{
|
||||
m_color_lut[start] = ci.color();
|
||||
++ci;
|
||||
++start;
|
||||
if(offset < 0.0) offset = 0.0;
|
||||
if(offset > 1.0) offset = 1.0;
|
||||
}
|
||||
}
|
||||
c = m_color_profile.last().color;
|
||||
for (; end < m_color_lut.size(); end++)
|
||||
};
|
||||
typedef agg::pod_bvector<color_point, 4> color_profile_type;
|
||||
typedef agg::pod_array<color_type> color_lut_type;
|
||||
|
||||
static bool offset_less(const color_point& a, const color_point& b)
|
||||
{
|
||||
m_color_lut[end] = c;
|
||||
return a.offset < b.offset;
|
||||
}
|
||||
return true;
|
||||
static bool offset_equal(const color_point& a, const color_point& b)
|
||||
{
|
||||
return a.offset == b.offset;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_profile_type m_color_profile;
|
||||
color_lut_type m_color_lut;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void gradient_lut<T,S>::remove_all()
|
||||
{
|
||||
m_color_profile.remove_all();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void gradient_lut<T,S>::add_color(double offset, const color_type& color)
|
||||
{
|
||||
m_color_profile.add(color_point(offset, color));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
bool gradient_lut<T,S>::build_lut()
|
||||
{
|
||||
quick_sort(m_color_profile, offset_less);
|
||||
m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal));
|
||||
if(m_color_profile.size() >= 2)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned start = uround(m_color_profile[0].offset * color_lut_size);
|
||||
unsigned end = 0;
|
||||
color_type c = m_color_profile[0].color;
|
||||
for(i = 0; i < start; i++)
|
||||
{
|
||||
m_color_lut[i] = c;
|
||||
}
|
||||
for(i = 1; i < m_color_profile.size(); i++)
|
||||
{
|
||||
end = uround(m_color_profile[i].offset * color_lut_size);
|
||||
interpolator_type ci(m_color_profile[i-1].color,
|
||||
m_color_profile[i ].color,
|
||||
end - start + 1);
|
||||
while(start < end)
|
||||
{
|
||||
m_color_lut[start] = ci.color();
|
||||
++ci;
|
||||
++start;
|
||||
}
|
||||
}
|
||||
c = m_color_profile.last().color;
|
||||
for(; end < m_color_lut.size(); end++)
|
||||
{
|
||||
m_color_lut[end] = c;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace agg
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
195
deps/agg/include/agg_gsv_text.h
vendored
195
deps/agg/include/agg_gsv_text.h
vendored
|
@ -24,107 +24,130 @@
|
|||
#include "agg_conv_stroke.h"
|
||||
#include "agg_conv_transform.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//---------------------------------------------------------------gsv_text
|
||||
//
|
||||
// See Implementation agg_gsv_text.cpp
|
||||
//
|
||||
class gsv_text
|
||||
namespace agg
|
||||
{
|
||||
enum status { initial, next_char, start_glyph, glyph };
|
||||
|
||||
public:
|
||||
gsv_text();
|
||||
|
||||
void font(const void* font);
|
||||
void flip(bool flip_y) { m_flip = flip_y; }
|
||||
void load_font(const char* file);
|
||||
void size(double height, double width = 0.0);
|
||||
void space(double space);
|
||||
void line_space(double line_space);
|
||||
void start_point(double x, double y);
|
||||
void text(const char* text);
|
||||
|
||||
double text_width();
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
// not supposed to be copied
|
||||
gsv_text(const gsv_text&);
|
||||
const gsv_text& operator=(const gsv_text&);
|
||||
|
||||
int16u value(const int8u* p) const
|
||||
//---------------------------------------------------------------gsv_text
|
||||
//
|
||||
// See Implementation agg_gsv_text.cpp
|
||||
//
|
||||
class gsv_text
|
||||
{
|
||||
int16u v;
|
||||
if (m_big_endian)
|
||||
enum status
|
||||
{
|
||||
*(int8u*)&v = p[1];
|
||||
*((int8u*)&v + 1) = p[0];
|
||||
}
|
||||
else
|
||||
initial,
|
||||
next_char,
|
||||
start_glyph,
|
||||
glyph
|
||||
};
|
||||
|
||||
public:
|
||||
gsv_text();
|
||||
|
||||
void font(const void* font);
|
||||
void flip(bool flip_y) { m_flip = flip_y; }
|
||||
void load_font(const char* file);
|
||||
void size(double height, double width=0.0);
|
||||
void space(double space);
|
||||
void line_space(double line_space);
|
||||
void start_point(double x, double y);
|
||||
void text(const char* text);
|
||||
|
||||
double text_width();
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
// not supposed to be copied
|
||||
gsv_text(const gsv_text&);
|
||||
const gsv_text& operator = (const gsv_text&);
|
||||
|
||||
int16u value(const int8u* p) const
|
||||
{
|
||||
*(int8u*)&v = p[0];
|
||||
*((int8u*)&v + 1) = p[1];
|
||||
int16u v;
|
||||
if(m_big_endian)
|
||||
{
|
||||
*(int8u*)&v = p[1];
|
||||
*((int8u*)&v + 1) = p[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(int8u*)&v = p[0];
|
||||
*((int8u*)&v + 1) = p[1];
|
||||
}
|
||||
return v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_start_x;
|
||||
double m_width;
|
||||
double m_height;
|
||||
double m_space;
|
||||
double m_line_space;
|
||||
char m_chr[2];
|
||||
char* m_text;
|
||||
pod_array<char> m_text_buf;
|
||||
char* m_cur_chr;
|
||||
const void* m_font;
|
||||
pod_array<char> m_loaded_font;
|
||||
status m_status;
|
||||
bool m_big_endian;
|
||||
bool m_flip;
|
||||
int8u* m_indices;
|
||||
int8* m_glyphs;
|
||||
int8* m_bglyph;
|
||||
int8* m_eglyph;
|
||||
double m_w;
|
||||
double m_h;
|
||||
};
|
||||
private:
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_start_x;
|
||||
double m_width;
|
||||
double m_height;
|
||||
double m_space;
|
||||
double m_line_space;
|
||||
char m_chr[2];
|
||||
char* m_text;
|
||||
pod_array<char> m_text_buf;
|
||||
char* m_cur_chr;
|
||||
const void* m_font;
|
||||
pod_array<char> m_loaded_font;
|
||||
status m_status;
|
||||
bool m_big_endian;
|
||||
bool m_flip;
|
||||
int8u* m_indices;
|
||||
int8* m_glyphs;
|
||||
int8* m_bglyph;
|
||||
int8* m_eglyph;
|
||||
double m_w;
|
||||
double m_h;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------gsv_text_outline
|
||||
template<class Transformer = trans_affine>
|
||||
class gsv_text_outline
|
||||
{
|
||||
public:
|
||||
gsv_text_outline(gsv_text& text, const Transformer& trans)
|
||||
: m_polyline(text)
|
||||
, m_trans(m_polyline, trans)
|
||||
{}
|
||||
|
||||
void width(double w) { m_polyline.width(w); }
|
||||
|
||||
void transformer(const Transformer* trans) { m_trans->transformer(trans); }
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
//--------------------------------------------------------gsv_text_outline
|
||||
template<class Transformer = trans_affine> class gsv_text_outline
|
||||
{
|
||||
m_trans.rewind(path_id);
|
||||
m_polyline.line_join(round_join);
|
||||
m_polyline.line_cap(round_cap);
|
||||
}
|
||||
public:
|
||||
gsv_text_outline(gsv_text& text, const Transformer& trans) :
|
||||
m_polyline(text),
|
||||
m_trans(m_polyline, trans)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y) { return m_trans.vertex(x, y); }
|
||||
void width(double w)
|
||||
{
|
||||
m_polyline.width(w);
|
||||
}
|
||||
|
||||
private:
|
||||
conv_stroke<gsv_text> m_polyline;
|
||||
conv_transform<conv_stroke<gsv_text>, Transformer> m_trans;
|
||||
};
|
||||
void transformer(const Transformer* trans)
|
||||
{
|
||||
m_trans->transformer(trans);
|
||||
}
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
m_trans.rewind(path_id);
|
||||
m_polyline.line_join(round_join);
|
||||
m_polyline.line_cap(round_cap);
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
return m_trans.vertex(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
conv_stroke<gsv_text> m_polyline;
|
||||
conv_transform<conv_stroke<gsv_text>, Transformer> m_trans;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
797
deps/agg/include/agg_image_accessors.h
vendored
797
deps/agg/include/agg_image_accessors.h
vendored
|
@ -18,439 +18,464 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-----------------------------------------------------image_accessor_clip
|
||||
template<class PixFmt>
|
||||
class image_accessor_clip
|
||||
namespace agg
|
||||
{
|
||||
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() {}
|
||||
explicit image_accessor_clip(const pixfmt_type& pixf, const color_type& bk)
|
||||
: m_pixf(&pixf)
|
||||
//-----------------------------------------------------image_accessor_clip
|
||||
template<class PixFmt> class image_accessor_clip
|
||||
{
|
||||
pixfmt_type::make_pix(m_bk_buf, bk);
|
||||
}
|
||||
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 };
|
||||
|
||||
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())
|
||||
image_accessor_clip() {}
|
||||
explicit image_accessor_clip(const pixfmt_type& pixf,
|
||||
const color_type& bk) :
|
||||
m_pixf(&pixf)
|
||||
{
|
||||
return m_pixf->pix_ptr(m_x, m_y);
|
||||
pixfmt_type::make_pix(m_bk_buf, bk);
|
||||
}
|
||||
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())
|
||||
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() {}
|
||||
explicit 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);
|
||||
}
|
||||
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())
|
||||
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);
|
||||
}
|
||||
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;
|
||||
};
|
||||
private:
|
||||
const pixfmt_type* m_pixf;
|
||||
int m_x, 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() {}
|
||||
explicit 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)
|
||||
//----------------------------------------------------image_accessor_clone
|
||||
template<class PixFmt> class image_accessor_clone
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
||||
}
|
||||
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 };
|
||||
|
||||
AGG_INLINE const int8u* next_x() { return m_pix_ptr += pix_width; }
|
||||
image_accessor_clone() {}
|
||||
explicit image_accessor_clone(const pixfmt_type& pixf) :
|
||||
m_pixf(&pixf)
|
||||
{}
|
||||
|
||||
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() {}
|
||||
explicit 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 && x + (int)len <= (int)m_pixf->width())
|
||||
void attach(const pixfmt_type& pixf)
|
||||
{
|
||||
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
||||
m_pixf = &pixf;
|
||||
}
|
||||
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())
|
||||
private:
|
||||
AGG_INLINE const int8u* pixel() const
|
||||
{
|
||||
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
||||
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);
|
||||
}
|
||||
m_pix_ptr = 0;
|
||||
return pixel();
|
||||
}
|
||||
|
||||
private:
|
||||
const pixfmt_type* m_pixf;
|
||||
int m_x, m_x0, m_y;
|
||||
const int8u* m_pix_ptr;
|
||||
};
|
||||
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();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------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 };
|
||||
AGG_INLINE const int8u* next_x()
|
||||
{
|
||||
if(m_pix_ptr) return m_pix_ptr += pix_width;
|
||||
++m_x;
|
||||
return pixel();
|
||||
}
|
||||
|
||||
image_accessor_wrap() {}
|
||||
explicit image_accessor_wrap(const pixfmt_type& pixf)
|
||||
: m_pixf(&pixf)
|
||||
, m_wrap_x(pixf.width())
|
||||
, m_wrap_y(pixf.height())
|
||||
{}
|
||||
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();
|
||||
}
|
||||
|
||||
void attach(const pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||
private:
|
||||
const pixfmt_type* m_pixf;
|
||||
int m_x, m_x0, m_y;
|
||||
const int8u* m_pix_ptr;
|
||||
};
|
||||
|
||||
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------image_accessor_wrap
|
||||
template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
|
||||
{
|
||||
m_x = x;
|
||||
m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
|
||||
return m_row_ptr + m_wrap_x(x) * pix_width;
|
||||
}
|
||||
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 };
|
||||
|
||||
AGG_INLINE const int8u* next_x()
|
||||
image_accessor_wrap() {}
|
||||
explicit 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
|
||||
{
|
||||
int x = ++m_wrap_x;
|
||||
return m_row_ptr + x * pix_width;
|
||||
}
|
||||
public:
|
||||
wrap_mode_repeat() {}
|
||||
wrap_mode_repeat(unsigned size) :
|
||||
m_size(size),
|
||||
m_add(size * (0x3FFFFFFF / size)),
|
||||
m_value(0)
|
||||
{}
|
||||
|
||||
AGG_INLINE const int8u* next_y()
|
||||
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
|
||||
{
|
||||
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)
|
||||
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;
|
||||
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)
|
||||
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
|
||||
{
|
||||
m_value = unsigned(v) & m_mask;
|
||||
if (m_value >= m_size)
|
||||
return m_mask - m_value;
|
||||
return m_value;
|
||||
}
|
||||
AGG_INLINE unsigned operator++()
|
||||
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
|
||||
{
|
||||
++m_value;
|
||||
m_value &= m_mask;
|
||||
if (m_value >= m_size)
|
||||
return m_mask - m_value;
|
||||
return m_value;
|
||||
}
|
||||
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)
|
||||
{}
|
||||
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned m_mask;
|
||||
unsigned m_value;
|
||||
};
|
||||
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;
|
||||
}
|
||||
|
||||
//---------------------------------------------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++ ()
|
||||
{
|
||||
++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;
|
||||
};
|
||||
|
||||
AGG_INLINE unsigned operator()(int v)
|
||||
|
||||
|
||||
//--------------------------------------------------wrap_mode_reflect_pow2
|
||||
class wrap_mode_reflect_pow2
|
||||
{
|
||||
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++()
|
||||
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
|
||||
{
|
||||
++m_value;
|
||||
if (m_value >= m_size2)
|
||||
m_value = 0;
|
||||
if (m_value >= m_size)
|
||||
return m_size2 - m_value - 1;
|
||||
return m_value;
|
||||
}
|
||||
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)
|
||||
{}
|
||||
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned m_size2;
|
||||
unsigned m_add;
|
||||
unsigned m_mask;
|
||||
unsigned m_value;
|
||||
};
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
811
deps/agg/include/agg_image_filters.h
vendored
811
deps/agg/include/agg_image_filters.h
vendored
|
@ -23,499 +23,426 @@
|
|||
#include "agg_array.h"
|
||||
#include "agg_math.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
// See Implementation agg_image_filters.cpp
|
||||
|
||||
enum image_filter_scale_e {
|
||||
image_filter_shift = 14, //----image_filter_shift
|
||||
image_filter_scale = 1 << image_filter_shift, //----image_filter_scale
|
||||
image_filter_mask = image_filter_scale - 1 //----image_filter_mask
|
||||
};
|
||||
|
||||
enum image_subpixel_scale_e {
|
||||
image_subpixel_shift = 8, //----image_subpixel_shift
|
||||
image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale
|
||||
image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask
|
||||
};
|
||||
|
||||
//-----------------------------------------------------image_filter_lut
|
||||
class image_filter_lut
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
template<class FilterF>
|
||||
void calculate(const FilterF& filter, bool normalization = true)
|
||||
|
||||
// See Implementation agg_image_filters.cpp
|
||||
|
||||
enum image_filter_scale_e
|
||||
{
|
||||
double r = filter.radius();
|
||||
realloc_lut(r);
|
||||
unsigned i;
|
||||
unsigned pivot = diameter() << (image_subpixel_shift - 1);
|
||||
for (i = 0; i < pivot; i++)
|
||||
image_filter_shift = 14, //----image_filter_shift
|
||||
image_filter_scale = 1 << image_filter_shift, //----image_filter_scale
|
||||
image_filter_mask = image_filter_scale - 1 //----image_filter_mask
|
||||
};
|
||||
|
||||
enum image_subpixel_scale_e
|
||||
{
|
||||
image_subpixel_shift = 8, //----image_subpixel_shift
|
||||
image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale
|
||||
image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------image_filter_lut
|
||||
class image_filter_lut
|
||||
{
|
||||
public:
|
||||
template<class FilterF> void calculate(const FilterF& filter,
|
||||
bool normalization=true)
|
||||
{
|
||||
double x = double(i) / double(image_subpixel_scale);
|
||||
double y = filter.calc_weight(x);
|
||||
m_weight_array[pivot + i] = m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
|
||||
double r = filter.radius();
|
||||
realloc_lut(r);
|
||||
unsigned i;
|
||||
unsigned pivot = diameter() << (image_subpixel_shift - 1);
|
||||
for(i = 0; i < pivot; i++)
|
||||
{
|
||||
double x = double(i) / double(image_subpixel_scale);
|
||||
double y = filter.calc_weight(x);
|
||||
m_weight_array[pivot + i] =
|
||||
m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
|
||||
}
|
||||
unsigned end = (diameter() << image_subpixel_shift) - 1;
|
||||
m_weight_array[0] = m_weight_array[end];
|
||||
if(normalization)
|
||||
{
|
||||
normalize();
|
||||
}
|
||||
}
|
||||
unsigned end = (diameter() << image_subpixel_shift) - 1;
|
||||
m_weight_array[0] = m_weight_array[end];
|
||||
if (normalization)
|
||||
|
||||
image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
|
||||
|
||||
template<class FilterF> image_filter_lut(const FilterF& filter,
|
||||
bool normalization=true)
|
||||
{
|
||||
normalize();
|
||||
calculate(filter, normalization);
|
||||
}
|
||||
}
|
||||
|
||||
image_filter_lut()
|
||||
: m_radius(0)
|
||||
, m_diameter(0)
|
||||
, m_start(0)
|
||||
{}
|
||||
double radius() const { return m_radius; }
|
||||
unsigned diameter() const { return m_diameter; }
|
||||
int start() const { return m_start; }
|
||||
const int16* weight_array() const { return &m_weight_array[0]; }
|
||||
void normalize();
|
||||
|
||||
template<class FilterF>
|
||||
image_filter_lut(const FilterF& filter, bool normalization = true)
|
||||
private:
|
||||
void realloc_lut(double radius);
|
||||
image_filter_lut(const image_filter_lut&);
|
||||
const image_filter_lut& operator = (const image_filter_lut&);
|
||||
|
||||
double m_radius;
|
||||
unsigned m_diameter;
|
||||
int m_start;
|
||||
pod_array<int16> m_weight_array;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------image_filter
|
||||
template<class FilterF> class image_filter : public image_filter_lut
|
||||
{
|
||||
calculate(filter, normalization);
|
||||
}
|
||||
|
||||
double radius() const { return m_radius; }
|
||||
unsigned diameter() const { return m_diameter; }
|
||||
int start() const { return m_start; }
|
||||
const int16* weight_array() const { return &m_weight_array[0]; }
|
||||
void normalize();
|
||||
|
||||
private:
|
||||
void realloc_lut(double radius);
|
||||
image_filter_lut(const image_filter_lut&);
|
||||
const image_filter_lut& operator=(const image_filter_lut&);
|
||||
|
||||
double m_radius;
|
||||
unsigned m_diameter;
|
||||
int m_start;
|
||||
pod_array<int16> m_weight_array;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------image_filter
|
||||
template<class FilterF>
|
||||
class image_filter : public image_filter_lut
|
||||
{
|
||||
public:
|
||||
image_filter() { calculate(m_filter_function); }
|
||||
|
||||
private:
|
||||
FilterF m_filter_function;
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_bilinear
|
||||
struct image_filter_bilinear
|
||||
{
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x) { return 1.0 - x; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_hanning
|
||||
struct image_filter_hanning
|
||||
{
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x) { return 0.5 + 0.5 * std::cos(pi * x); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_hamming
|
||||
struct image_filter_hamming
|
||||
{
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x) { return 0.54 + 0.46 * std::cos(pi * x); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_hermite
|
||||
struct image_filter_hermite
|
||||
{
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x) { return (2.0 * x - 3.0) * x * x + 1.0; }
|
||||
};
|
||||
|
||||
//------------------------------------------------image_filter_quadric
|
||||
struct image_filter_quadric
|
||||
{
|
||||
static double radius() { return 1.5; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
double t;
|
||||
if (x < 0.5)
|
||||
return 0.75 - x * x;
|
||||
if (x < 1.5)
|
||||
public:
|
||||
image_filter()
|
||||
{
|
||||
t = x - 1.5;
|
||||
return 0.5 * t * t;
|
||||
calculate(m_filter_function);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
};
|
||||
private:
|
||||
FilterF m_filter_function;
|
||||
};
|
||||
|
||||
//------------------------------------------------image_filter_bicubic
|
||||
class image_filter_bicubic
|
||||
{
|
||||
static double pow3(double x) { return (x <= 0.0) ? 0.0 : x * x * x; }
|
||||
|
||||
public:
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x)
|
||||
//-----------------------------------------------image_filter_bilinear
|
||||
struct image_filter_bilinear
|
||||
{
|
||||
return (1.0 / 6.0) * (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1));
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------image_filter_kaiser
|
||||
class image_filter_kaiser
|
||||
{
|
||||
double a;
|
||||
double i0a;
|
||||
double epsilon;
|
||||
|
||||
public:
|
||||
image_filter_kaiser(double b = 6.33)
|
||||
: a(b)
|
||||
, epsilon(1e-12)
|
||||
{
|
||||
i0a = 1.0 / bessel_i0(b);
|
||||
}
|
||||
|
||||
static double radius() { return 1.0; }
|
||||
double calc_weight(double x) const { return bessel_i0(a * sqrt(1. - x * x)) * i0a; }
|
||||
|
||||
private:
|
||||
double bessel_i0(double x) const
|
||||
{
|
||||
int i;
|
||||
double sum, y, t;
|
||||
|
||||
sum = 1.;
|
||||
y = x * x / 4.;
|
||||
t = y;
|
||||
|
||||
for (i = 2; t > epsilon; i++)
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
sum += t;
|
||||
t *= (double)y / (i * i);
|
||||
return 1.0 - x;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//----------------------------------------------image_filter_catrom
|
||||
struct image_filter_catrom
|
||||
{
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x)
|
||||
|
||||
//-----------------------------------------------image_filter_hanning
|
||||
struct image_filter_hanning
|
||||
{
|
||||
if (x < 1.0)
|
||||
return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
|
||||
if (x < 2.0)
|
||||
return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
|
||||
return 0.;
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------image_filter_mitchell
|
||||
class image_filter_mitchell
|
||||
{
|
||||
double p0, p2, p3;
|
||||
double q0, q1, q2, q3;
|
||||
|
||||
public:
|
||||
image_filter_mitchell(double b = 1.0 / 3.0, double c = 1.0 / 3.0)
|
||||
: p0((6.0 - 2.0 * b) / 6.0)
|
||||
, p2((-18.0 + 12.0 * b + 6.0 * c) / 6.0)
|
||||
, p3((12.0 - 9.0 * b - 6.0 * c) / 6.0)
|
||||
, q0((8.0 * b + 24.0 * c) / 6.0)
|
||||
, q1((-12.0 * b - 48.0 * c) / 6.0)
|
||||
, q2((6.0 * b + 30.0 * c) / 6.0)
|
||||
, q3((-b - 6.0 * c) / 6.0)
|
||||
{}
|
||||
|
||||
static double radius() { return 2.0; }
|
||||
double calc_weight(double x) const
|
||||
{
|
||||
if (x < 1.0)
|
||||
return p0 + x * x * (p2 + x * p3);
|
||||
if (x < 2.0)
|
||||
return q0 + x * (q1 + x * (q2 + x * q3));
|
||||
return 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------image_filter_spline16
|
||||
struct image_filter_spline16
|
||||
{
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
if (x < 1.0)
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
return ((x - 9.0 / 5.0) * x - 1.0 / 5.0) * x + 1.0;
|
||||
return 0.5 + 0.5 * std::cos(pi * x);
|
||||
}
|
||||
return ((-1.0 / 3.0 * (x - 1) + 4.0 / 5.0) * (x - 1) - 7.0 / 15.0) * (x - 1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//---------------------------------------------image_filter_spline36
|
||||
struct image_filter_spline36
|
||||
{
|
||||
static double radius() { return 3.0; }
|
||||
static double calc_weight(double x)
|
||||
|
||||
//-----------------------------------------------image_filter_hamming
|
||||
struct image_filter_hamming
|
||||
{
|
||||
if (x < 1.0)
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
return ((13.0 / 11.0 * x - 453.0 / 209.0) * x - 3.0 / 209.0) * x + 1.0;
|
||||
return 0.54 + 0.46 * std::cos(pi * x);
|
||||
}
|
||||
if (x < 2.0)
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_hermite
|
||||
struct image_filter_hermite
|
||||
{
|
||||
static double radius() { return 1.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
return ((-6.0 / 11.0 * (x - 1) + 270.0 / 209.0) * (x - 1) - 156.0 / 209.0) * (x - 1);
|
||||
return (2.0 * x - 3.0) * x * x + 1.0;
|
||||
}
|
||||
return ((1.0 / 11.0 * (x - 2) - 45.0 / 209.0) * (x - 2) + 26.0 / 209.0) * (x - 2);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//----------------------------------------------image_filter_gaussian
|
||||
struct image_filter_gaussian
|
||||
{
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x) { return exp(-2.0 * x * x) * sqrt(2.0 / pi); }
|
||||
};
|
||||
|
||||
//------------------------------------------------image_filter_bessel
|
||||
struct image_filter_bessel
|
||||
{
|
||||
static double radius() { return 3.2383; }
|
||||
static double calc_weight(double x) { return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x); }
|
||||
};
|
||||
|
||||
//-------------------------------------------------image_filter_sinc
|
||||
class image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc(double r)
|
||||
: m_radius(r < 2.0 ? 2.0 : r)
|
||||
{}
|
||||
double radius() const { return m_radius; }
|
||||
double calc_weight(double x) const
|
||||
//------------------------------------------------image_filter_quadric
|
||||
struct image_filter_quadric
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 1.0;
|
||||
x *= pi;
|
||||
return std::sin(x) / x;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_radius;
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_lanczos
|
||||
class image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos(double r)
|
||||
: m_radius(r < 2.0 ? 2.0 : r)
|
||||
{}
|
||||
double radius() const { return m_radius; }
|
||||
double calc_weight(double x) const
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 1.0;
|
||||
if (x > m_radius)
|
||||
static double radius() { return 1.5; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
double t;
|
||||
if(x < 0.5) return 0.75 - x * x;
|
||||
if(x < 1.5) {t = x - 1.5; return 0.5 * t * t;}
|
||||
return 0.0;
|
||||
x *= pi;
|
||||
double xr = x / m_radius;
|
||||
return (std::sin(x) / x) * (std::sin(xr) / xr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
double m_radius;
|
||||
};
|
||||
|
||||
//----------------------------------------------image_filter_blackman
|
||||
class image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman(double r)
|
||||
: m_radius(r < 2.0 ? 2.0 : r)
|
||||
{}
|
||||
double radius() const { return m_radius; }
|
||||
double calc_weight(double x) const
|
||||
//------------------------------------------------image_filter_bicubic
|
||||
class image_filter_bicubic
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 1.0;
|
||||
if (x > m_radius)
|
||||
static double pow3(double x)
|
||||
{
|
||||
return (x <= 0.0) ? 0.0 : x * x * x;
|
||||
}
|
||||
|
||||
public:
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
return
|
||||
(1.0/6.0) *
|
||||
(pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1));
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------image_filter_kaiser
|
||||
class image_filter_kaiser
|
||||
{
|
||||
double a;
|
||||
double i0a;
|
||||
double epsilon;
|
||||
|
||||
public:
|
||||
image_filter_kaiser(double b = 6.33) :
|
||||
a(b), epsilon(1e-12)
|
||||
{
|
||||
i0a = 1.0 / bessel_i0(b);
|
||||
}
|
||||
|
||||
static double radius() { return 1.0; }
|
||||
double calc_weight(double x) const
|
||||
{
|
||||
return bessel_i0(a * sqrt(1. - x * x)) * i0a;
|
||||
}
|
||||
|
||||
private:
|
||||
double bessel_i0(double x) const
|
||||
{
|
||||
int i;
|
||||
double sum, y, t;
|
||||
|
||||
sum = 1.;
|
||||
y = x * x / 4.;
|
||||
t = y;
|
||||
|
||||
for(i = 2; t > epsilon; i++)
|
||||
{
|
||||
sum += t;
|
||||
t *= (double)y / (i * i);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------image_filter_catrom
|
||||
struct image_filter_catrom
|
||||
{
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
if(x < 1.0) return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
|
||||
if(x < 2.0) return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
|
||||
return 0.;
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------image_filter_mitchell
|
||||
class image_filter_mitchell
|
||||
{
|
||||
double p0, p2, p3;
|
||||
double q0, q1, q2, q3;
|
||||
|
||||
public:
|
||||
image_filter_mitchell(double b = 1.0/3.0, double c = 1.0/3.0) :
|
||||
p0((6.0 - 2.0 * b) / 6.0),
|
||||
p2((-18.0 + 12.0 * b + 6.0 * c) / 6.0),
|
||||
p3((12.0 - 9.0 * b - 6.0 * c) / 6.0),
|
||||
q0((8.0 * b + 24.0 * c) / 6.0),
|
||||
q1((-12.0 * b - 48.0 * c) / 6.0),
|
||||
q2((6.0 * b + 30.0 * c) / 6.0),
|
||||
q3((-b - 6.0 * c) / 6.0)
|
||||
{}
|
||||
|
||||
static double radius() { return 2.0; }
|
||||
double calc_weight(double x) const
|
||||
{
|
||||
if(x < 1.0) return p0 + x * x * (p2 + x * p3);
|
||||
if(x < 2.0) return q0 + x * (q1 + x * (q2 + x * q3));
|
||||
return 0.0;
|
||||
x *= pi;
|
||||
double xr = x / m_radius;
|
||||
return (std::sin(x) / x) * (0.42 + 0.5 * std::cos(xr) + 0.08 * std::cos(2 * xr));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
double m_radius;
|
||||
};
|
||||
|
||||
//------------------------------------------------image_filter_sinc36
|
||||
class image_filter_sinc36 : public image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc36()
|
||||
: image_filter_sinc(3.0)
|
||||
{}
|
||||
};
|
||||
//----------------------------------------------image_filter_spline16
|
||||
struct image_filter_spline16
|
||||
{
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
if(x < 1.0)
|
||||
{
|
||||
return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0;
|
||||
}
|
||||
return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------image_filter_sinc64
|
||||
class image_filter_sinc64 : public image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc64()
|
||||
: image_filter_sinc(4.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_sinc100
|
||||
class image_filter_sinc100 : public image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc100()
|
||||
: image_filter_sinc(5.0)
|
||||
{}
|
||||
};
|
||||
//---------------------------------------------image_filter_spline36
|
||||
struct image_filter_spline36
|
||||
{
|
||||
static double radius() { return 3.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
if(x < 1.0)
|
||||
{
|
||||
return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0;
|
||||
}
|
||||
if(x < 2.0)
|
||||
{
|
||||
return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1);
|
||||
}
|
||||
return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_sinc144
|
||||
class image_filter_sinc144 : public image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc144()
|
||||
: image_filter_sinc(6.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_sinc196
|
||||
class image_filter_sinc196 : public image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc196()
|
||||
: image_filter_sinc(7.0)
|
||||
{}
|
||||
};
|
||||
//----------------------------------------------image_filter_gaussian
|
||||
struct image_filter_gaussian
|
||||
{
|
||||
static double radius() { return 2.0; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
return exp(-2.0 * x * x) * sqrt(2.0 / pi);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------image_filter_sinc256
|
||||
class image_filter_sinc256 : public image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc256()
|
||||
: image_filter_sinc(8.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//---------------------------------------------image_filter_lanczos36
|
||||
class image_filter_lanczos36 : public image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos36()
|
||||
: image_filter_lanczos(3.0)
|
||||
{}
|
||||
};
|
||||
//------------------------------------------------image_filter_bessel
|
||||
struct image_filter_bessel
|
||||
{
|
||||
static double radius() { return 3.2383; }
|
||||
static double calc_weight(double x)
|
||||
{
|
||||
return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------image_filter_lanczos64
|
||||
class image_filter_lanczos64 : public image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos64()
|
||||
: image_filter_lanczos(4.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//--------------------------------------------image_filter_lanczos100
|
||||
class image_filter_lanczos100 : public image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos100()
|
||||
: image_filter_lanczos(5.0)
|
||||
{}
|
||||
};
|
||||
//-------------------------------------------------image_filter_sinc
|
||||
class image_filter_sinc
|
||||
{
|
||||
public:
|
||||
image_filter_sinc(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
|
||||
double radius() const { return m_radius; }
|
||||
double calc_weight(double x) const
|
||||
{
|
||||
if(x == 0.0) return 1.0;
|
||||
x *= pi;
|
||||
return std::sin(x) / x;
|
||||
}
|
||||
private:
|
||||
double m_radius;
|
||||
};
|
||||
|
||||
//--------------------------------------------image_filter_lanczos144
|
||||
class image_filter_lanczos144 : public image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos144()
|
||||
: image_filter_lanczos(6.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//--------------------------------------------image_filter_lanczos196
|
||||
class image_filter_lanczos196 : public image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos196()
|
||||
: image_filter_lanczos(7.0)
|
||||
{}
|
||||
};
|
||||
//-----------------------------------------------image_filter_lanczos
|
||||
class image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
|
||||
double radius() const { return m_radius; }
|
||||
double calc_weight(double x) const
|
||||
{
|
||||
if(x == 0.0) return 1.0;
|
||||
if(x > m_radius) return 0.0;
|
||||
x *= pi;
|
||||
double xr = x / m_radius;
|
||||
return (std::sin(x) / x) * (std::sin(xr) / xr);
|
||||
}
|
||||
private:
|
||||
double m_radius;
|
||||
};
|
||||
|
||||
//--------------------------------------------image_filter_lanczos256
|
||||
class image_filter_lanczos256 : public image_filter_lanczos
|
||||
{
|
||||
public:
|
||||
image_filter_lanczos256()
|
||||
: image_filter_lanczos(8.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//--------------------------------------------image_filter_blackman36
|
||||
class image_filter_blackman36 : public image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman36()
|
||||
: image_filter_blackman(3.0)
|
||||
{}
|
||||
};
|
||||
//----------------------------------------------image_filter_blackman
|
||||
class image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
|
||||
double radius() const { return m_radius; }
|
||||
double calc_weight(double x) const
|
||||
{
|
||||
if(x == 0.0) return 1.0;
|
||||
if(x > m_radius) return 0.0;
|
||||
x *= pi;
|
||||
double xr = x / m_radius;
|
||||
return (std::sin(x) / x) * (0.42 + 0.5 * std::cos(xr) + 0.08 * std::cos(2*xr));
|
||||
}
|
||||
private:
|
||||
double m_radius;
|
||||
};
|
||||
|
||||
//--------------------------------------------image_filter_blackman64
|
||||
class image_filter_blackman64 : public image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman64()
|
||||
: image_filter_blackman(4.0)
|
||||
{}
|
||||
};
|
||||
//------------------------------------------------image_filter_sinc36
|
||||
class image_filter_sinc36 : public image_filter_sinc
|
||||
{ public: image_filter_sinc36() : image_filter_sinc(3.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman100
|
||||
class image_filter_blackman100 : public image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman100()
|
||||
: image_filter_blackman(5.0)
|
||||
{}
|
||||
};
|
||||
//------------------------------------------------image_filter_sinc64
|
||||
class image_filter_sinc64 : public image_filter_sinc
|
||||
{ public: image_filter_sinc64() : image_filter_sinc(4.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman144
|
||||
class image_filter_blackman144 : public image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman144()
|
||||
: image_filter_blackman(6.0)
|
||||
{}
|
||||
};
|
||||
//-----------------------------------------------image_filter_sinc100
|
||||
class image_filter_sinc100 : public image_filter_sinc
|
||||
{ public: image_filter_sinc100() : image_filter_sinc(5.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman196
|
||||
class image_filter_blackman196 : public image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman196()
|
||||
: image_filter_blackman(7.0)
|
||||
{}
|
||||
};
|
||||
//-----------------------------------------------image_filter_sinc144
|
||||
class image_filter_sinc144 : public image_filter_sinc
|
||||
{ public: image_filter_sinc144() : image_filter_sinc(6.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman256
|
||||
class image_filter_blackman256 : public image_filter_blackman
|
||||
{
|
||||
public:
|
||||
image_filter_blackman256()
|
||||
: image_filter_blackman(8.0)
|
||||
{}
|
||||
};
|
||||
//-----------------------------------------------image_filter_sinc196
|
||||
class image_filter_sinc196 : public image_filter_sinc
|
||||
{ public: image_filter_sinc196() : image_filter_sinc(7.0){} };
|
||||
|
||||
} // namespace agg
|
||||
//-----------------------------------------------image_filter_sinc256
|
||||
class image_filter_sinc256 : public image_filter_sinc
|
||||
{ public: image_filter_sinc256() : image_filter_sinc(8.0){} };
|
||||
|
||||
//---------------------------------------------image_filter_lanczos36
|
||||
class image_filter_lanczos36 : public image_filter_lanczos
|
||||
{ public: image_filter_lanczos36() : image_filter_lanczos(3.0){} };
|
||||
|
||||
//---------------------------------------------image_filter_lanczos64
|
||||
class image_filter_lanczos64 : public image_filter_lanczos
|
||||
{ public: image_filter_lanczos64() : image_filter_lanczos(4.0){} };
|
||||
|
||||
//--------------------------------------------image_filter_lanczos100
|
||||
class image_filter_lanczos100 : public image_filter_lanczos
|
||||
{ public: image_filter_lanczos100() : image_filter_lanczos(5.0){} };
|
||||
|
||||
//--------------------------------------------image_filter_lanczos144
|
||||
class image_filter_lanczos144 : public image_filter_lanczos
|
||||
{ public: image_filter_lanczos144() : image_filter_lanczos(6.0){} };
|
||||
|
||||
//--------------------------------------------image_filter_lanczos196
|
||||
class image_filter_lanczos196 : public image_filter_lanczos
|
||||
{ public: image_filter_lanczos196() : image_filter_lanczos(7.0){} };
|
||||
|
||||
//--------------------------------------------image_filter_lanczos256
|
||||
class image_filter_lanczos256 : public image_filter_lanczos
|
||||
{ public: image_filter_lanczos256() : image_filter_lanczos(8.0){} };
|
||||
|
||||
//--------------------------------------------image_filter_blackman36
|
||||
class image_filter_blackman36 : public image_filter_blackman
|
||||
{ public: image_filter_blackman36() : image_filter_blackman(3.0){} };
|
||||
|
||||
//--------------------------------------------image_filter_blackman64
|
||||
class image_filter_blackman64 : public image_filter_blackman
|
||||
{ public: image_filter_blackman64() : image_filter_blackman(4.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman100
|
||||
class image_filter_blackman100 : public image_filter_blackman
|
||||
{ public: image_filter_blackman100() : image_filter_blackman(5.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman144
|
||||
class image_filter_blackman144 : public image_filter_blackman
|
||||
{ public: image_filter_blackman144() : image_filter_blackman(6.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman196
|
||||
class image_filter_blackman196 : public image_filter_blackman
|
||||
{ public: image_filter_blackman196() : image_filter_blackman(7.0){} };
|
||||
|
||||
//-------------------------------------------image_filter_blackman256
|
||||
class image_filter_blackman256 : public image_filter_blackman
|
||||
{ public: image_filter_blackman256() : image_filter_blackman(8.0){} };
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
286
deps/agg/include/agg_line_aa_basics.h
vendored
286
deps/agg/include/agg_line_aa_basics.h
vendored
|
@ -18,154 +18,172 @@
|
|||
#include <cstdlib>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
// See Implementation agg_line_aa_basics.cpp
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
enum line_subpixel_scale_e {
|
||||
line_subpixel_shift = 8, //----line_subpixel_shift
|
||||
line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale
|
||||
line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask
|
||||
line_max_coord = (1 << 28) - 1, //----line_max_coord
|
||||
line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
enum line_mr_subpixel_scale_e {
|
||||
line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift
|
||||
line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale
|
||||
line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------line_mr
|
||||
AGG_INLINE int line_mr(int x)
|
||||
namespace agg
|
||||
{
|
||||
return x >> (line_subpixel_shift - line_mr_subpixel_shift);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------line_hr
|
||||
AGG_INLINE int line_hr(int x)
|
||||
{
|
||||
return x << (line_subpixel_shift - line_mr_subpixel_shift);
|
||||
}
|
||||
// See Implementation agg_line_aa_basics.cpp
|
||||
|
||||
//---------------------------------------------------------------line_dbl_hr
|
||||
AGG_INLINE int line_dbl_hr(int x)
|
||||
{
|
||||
return x * line_subpixel_scale;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------line_coord
|
||||
struct line_coord
|
||||
{
|
||||
AGG_INLINE static int conv(double x) { return iround(x * line_subpixel_scale); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------line_coord_sat
|
||||
struct line_coord_sat
|
||||
{
|
||||
AGG_INLINE static int conv(double x) { return saturation<line_max_coord>::iround(x * line_subpixel_scale); }
|
||||
};
|
||||
|
||||
//==========================================================line_parameters
|
||||
struct line_parameters
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
line_parameters() {}
|
||||
line_parameters(int x1_, int y1_, int x2_, int y2_, int len_)
|
||||
: x1(x1_)
|
||||
, y1(y1_)
|
||||
, x2(x2_)
|
||||
, y2(y2_)
|
||||
, dx(std::abs(x2_ - x1_))
|
||||
, dy(std::abs(y2_ - y1_))
|
||||
, sx((x2_ > x1_) ? 1 : -1)
|
||||
, sy((y2_ > y1_) ? 1 : -1)
|
||||
, vertical(dy >= dx)
|
||||
, inc(vertical ? sy : sx)
|
||||
, len(len_)
|
||||
, octant((sy & 4) | (sx & 2) | int(vertical))
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
|
||||
unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; }
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
bool same_orthogonal_quadrant(const line_parameters& lp) const
|
||||
//-------------------------------------------------------------------------
|
||||
enum line_subpixel_scale_e
|
||||
{
|
||||
return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
|
||||
line_subpixel_shift = 8, //----line_subpixel_shift
|
||||
line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale
|
||||
line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask
|
||||
line_max_coord = (1 << 28) - 1, //----line_max_coord
|
||||
line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
enum line_mr_subpixel_scale_e
|
||||
{
|
||||
line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift
|
||||
line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale
|
||||
line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------line_mr
|
||||
AGG_INLINE int line_mr(int x)
|
||||
{
|
||||
return x >> (line_subpixel_shift - line_mr_subpixel_shift);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
bool same_diagonal_quadrant(const line_parameters& lp) const
|
||||
//-------------------------------------------------------------------line_hr
|
||||
AGG_INLINE int line_hr(int x)
|
||||
{
|
||||
return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
|
||||
return x << (line_subpixel_shift - line_mr_subpixel_shift);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void divide(line_parameters& lp1, line_parameters& lp2) const
|
||||
//---------------------------------------------------------------line_dbl_hr
|
||||
AGG_INLINE int line_dbl_hr(int x)
|
||||
{
|
||||
int xmid = (x1 + x2) >> 1;
|
||||
int ymid = (y1 + y2) >> 1;
|
||||
int len2 = len >> 1;
|
||||
|
||||
lp1 = *this;
|
||||
lp2 = *this;
|
||||
|
||||
lp1.x2 = xmid;
|
||||
lp1.y2 = ymid;
|
||||
lp1.len = len2;
|
||||
lp1.dx = std::abs(lp1.x2 - lp1.x1);
|
||||
lp1.dy = std::abs(lp1.y2 - lp1.y1);
|
||||
|
||||
lp2.x1 = xmid;
|
||||
lp2.y1 = ymid;
|
||||
lp2.len = len2;
|
||||
lp2.dx = std::abs(lp2.x2 - lp2.x1);
|
||||
lp2.dy = std::abs(lp2.y2 - lp2.y1);
|
||||
return x * line_subpixel_scale;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
int x1, y1, x2, y2, dx, dy, sx, sy;
|
||||
bool vertical;
|
||||
int inc;
|
||||
int len;
|
||||
int octant;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
static const int8u s_orthogonal_quadrant[8];
|
||||
static const int8u s_diagonal_quadrant[8];
|
||||
};
|
||||
|
||||
// See Implementation agg_line_aa_basics.cpp
|
||||
|
||||
//----------------------------------------------------------------bisectrix
|
||||
void bisectrix(const line_parameters& l1, const line_parameters& l2, int* x, int* y);
|
||||
|
||||
//-------------------------------------------fix_degenerate_bisectrix_start
|
||||
void inline fix_degenerate_bisectrix_start(const line_parameters& lp, int* x, int* y)
|
||||
{
|
||||
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
||||
if (d < line_subpixel_scale / 2)
|
||||
//---------------------------------------------------------------line_coord
|
||||
struct line_coord
|
||||
{
|
||||
*x = lp.x1 + (lp.y2 - lp.y1);
|
||||
*y = lp.y1 - (lp.x2 - lp.x1);
|
||||
AGG_INLINE static int conv(double x)
|
||||
{
|
||||
return iround(x * line_subpixel_scale);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------line_coord_sat
|
||||
struct line_coord_sat
|
||||
{
|
||||
AGG_INLINE static int conv(double x)
|
||||
{
|
||||
return saturation<line_max_coord>::iround(x * line_subpixel_scale);
|
||||
}
|
||||
};
|
||||
|
||||
//==========================================================line_parameters
|
||||
struct line_parameters
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
line_parameters() {}
|
||||
line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) :
|
||||
x1(x1_), y1(y1_), x2(x2_), y2(y2_),
|
||||
dx(std::abs(x2_ - x1_)),
|
||||
dy(std::abs(y2_ - y1_)),
|
||||
sx((x2_ > x1_) ? 1 : -1),
|
||||
sy((y2_ > y1_) ? 1 : -1),
|
||||
vertical(dy >= dx),
|
||||
inc(vertical ? sy : sx),
|
||||
len(len_),
|
||||
octant((sy & 4) | (sx & 2) | int(vertical))
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
|
||||
unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; }
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
bool same_orthogonal_quadrant(const line_parameters& lp) const
|
||||
{
|
||||
return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
bool same_diagonal_quadrant(const line_parameters& lp) const
|
||||
{
|
||||
return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void divide(line_parameters& lp1, line_parameters& lp2) const
|
||||
{
|
||||
int xmid = (x1 + x2) >> 1;
|
||||
int ymid = (y1 + y2) >> 1;
|
||||
int len2 = len >> 1;
|
||||
|
||||
lp1 = *this;
|
||||
lp2 = *this;
|
||||
|
||||
lp1.x2 = xmid;
|
||||
lp1.y2 = ymid;
|
||||
lp1.len = len2;
|
||||
lp1.dx = std::abs(lp1.x2 - lp1.x1);
|
||||
lp1.dy = std::abs(lp1.y2 - lp1.y1);
|
||||
|
||||
lp2.x1 = xmid;
|
||||
lp2.y1 = ymid;
|
||||
lp2.len = len2;
|
||||
lp2.dx = std::abs(lp2.x2 - lp2.x1);
|
||||
lp2.dy = std::abs(lp2.y2 - lp2.y1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
int x1, y1, x2, y2, dx, dy, sx, sy;
|
||||
bool vertical;
|
||||
int inc;
|
||||
int len;
|
||||
int octant;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
static const int8u s_orthogonal_quadrant[8];
|
||||
static const int8u s_diagonal_quadrant[8];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// See Implementation agg_line_aa_basics.cpp
|
||||
|
||||
//----------------------------------------------------------------bisectrix
|
||||
void bisectrix(const line_parameters& l1,
|
||||
const line_parameters& l2,
|
||||
int* x, int* y);
|
||||
|
||||
|
||||
//-------------------------------------------fix_degenerate_bisectrix_start
|
||||
void inline fix_degenerate_bisectrix_start(const line_parameters& lp,
|
||||
int* x, int* y)
|
||||
{
|
||||
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
|
||||
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
||||
if(d < line_subpixel_scale/2)
|
||||
{
|
||||
*x = lp.x1 + (lp.y2 - lp.y1);
|
||||
*y = lp.y1 - (lp.x2 - lp.x1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------fix_degenerate_bisectrix_end
|
||||
void inline fix_degenerate_bisectrix_end(const line_parameters& lp,
|
||||
int* x, int* y)
|
||||
{
|
||||
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
|
||||
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
||||
if(d < line_subpixel_scale/2)
|
||||
{
|
||||
*x = lp.x2 + (lp.y2 - lp.y1);
|
||||
*y = lp.y2 - (lp.x2 - lp.x1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------fix_degenerate_bisectrix_end
|
||||
void inline fix_degenerate_bisectrix_end(const line_parameters& lp, int* x, int* y)
|
||||
{
|
||||
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
||||
if (d < line_subpixel_scale / 2)
|
||||
{
|
||||
*x = lp.x2 + (lp.y2 - lp.y1);
|
||||
*y = lp.y2 - (lp.x2 - lp.x1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
682
deps/agg/include/agg_math.h
vendored
682
deps/agg/include/agg_math.h
vendored
|
@ -22,236 +22,251 @@
|
|||
#include <cmath>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//------------------------------------------------------vertex_dist_epsilon
|
||||
// Coinciding points maximal distance (Epsilon)
|
||||
const double vertex_dist_epsilon = 1e-5;
|
||||
|
||||
//-----------------------------------------------------intersection_epsilon
|
||||
// See calc_intersection
|
||||
const double intersection_epsilon = 1.0e-30;
|
||||
|
||||
//------------------------------------------------------------cross_product
|
||||
AGG_INLINE double cross_product(double x1, double y1, double x2, double y2, double x, double y)
|
||||
namespace agg
|
||||
{
|
||||
return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------point_in_triangle
|
||||
AGG_INLINE bool point_in_triangle(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y)
|
||||
{
|
||||
bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
|
||||
bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
|
||||
bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
|
||||
return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
|
||||
}
|
||||
//------------------------------------------------------vertex_dist_epsilon
|
||||
// Coinciding points maximal distance (Epsilon)
|
||||
const double vertex_dist_epsilon = 1e-5;
|
||||
|
||||
//-----------------------------------------------------------calc_distance
|
||||
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
return sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
//-----------------------------------------------------intersection_epsilon
|
||||
// See calc_intersection
|
||||
const double intersection_epsilon = 1.0e-30;
|
||||
|
||||
//--------------------------------------------------------calc_sq_distance
|
||||
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
//------------------------------------------------calc_line_point_distance
|
||||
AGG_INLINE double calc_line_point_distance(double x1, double y1, double x2, double y2, double x, double y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
double d = sqrt(dx * dx + dy * dy);
|
||||
if (d < vertex_dist_epsilon)
|
||||
//------------------------------------------------------------cross_product
|
||||
AGG_INLINE double cross_product(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
return calc_distance(x1, y1, x, y);
|
||||
}
|
||||
return ((x - x2) * dy - (y - y2) * dx) / d;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_line_point_u
|
||||
AGG_INLINE double calc_segment_point_u(double x1, double y1, double x2, double y2, double x, double y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
|
||||
if (dx == 0 && dy == 0)
|
||||
{
|
||||
return 0;
|
||||
return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
|
||||
}
|
||||
|
||||
double pdx = x - x1;
|
||||
double pdy = y - y1;
|
||||
|
||||
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double
|
||||
calc_segment_point_sq_distance(double x1, double y1, double x2, double y2, double x, double y, double u)
|
||||
{
|
||||
if (u <= 0)
|
||||
//--------------------------------------------------------point_in_triangle
|
||||
AGG_INLINE bool point_in_triangle(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x, double y)
|
||||
{
|
||||
return calc_sq_distance(x, y, x1, y1);
|
||||
bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
|
||||
bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
|
||||
bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
|
||||
return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
|
||||
}
|
||||
else if (u >= 1)
|
||||
|
||||
//-----------------------------------------------------------calc_distance
|
||||
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
return calc_sq_distance(x, y, x2, y2);
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
return sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
|
||||
}
|
||||
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, double x2, double y2, double x, double y)
|
||||
{
|
||||
return calc_segment_point_sq_distance(x1, y1, x2, y2, x, y, calc_segment_point_u(x1, y1, x2, y2, x, y));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_intersection
|
||||
AGG_INLINE bool calc_intersection(double ax,
|
||||
double ay,
|
||||
double bx,
|
||||
double by,
|
||||
double cx,
|
||||
double cy,
|
||||
double dx,
|
||||
double dy,
|
||||
double* x,
|
||||
double* y)
|
||||
{
|
||||
double num = (ay - cy) * (dx - cx) - (ax - cx) * (dy - cy);
|
||||
double den = (bx - ax) * (dy - cy) - (by - ay) * (dx - cx);
|
||||
if (std::fabs(den) < intersection_epsilon)
|
||||
return false;
|
||||
double r = num / den;
|
||||
*x = ax + r * (bx - ax);
|
||||
*y = ay + r * (by - ay);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------intersection_exists
|
||||
AGG_INLINE bool
|
||||
intersection_exists(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
|
||||
{
|
||||
// It's less expensive but you can't control the
|
||||
// boundary conditions: Less or LessEqual
|
||||
double dx1 = x2 - x1;
|
||||
double dy1 = y2 - y1;
|
||||
double dx2 = x4 - x3;
|
||||
double dy2 = y4 - y3;
|
||||
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) != ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
|
||||
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) != ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
|
||||
|
||||
// It's is more expensive but more flexible
|
||||
// in terms of boundary conditions.
|
||||
//--------------------
|
||||
// double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
|
||||
// if(std::fabs(den) < intersection_epsilon) return false;
|
||||
// double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
|
||||
// double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
|
||||
// double ua = nom1 / den;
|
||||
// double ub = nom2 / den;
|
||||
// return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------calc_orthogonal
|
||||
AGG_INLINE void calc_orthogonal(double thickness, double x1, double y1, double x2, double y2, double* x, double* y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
double d = sqrt(dx * dx + dy * dy);
|
||||
*x = thickness * dy / d;
|
||||
*y = -thickness * dx / d;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------dilate_triangle
|
||||
AGG_INLINE void
|
||||
dilate_triangle(double x1, double y1, double x2, double y2, double x3, double y3, double* x, double* y, double d)
|
||||
{
|
||||
double dx1 = 0.0;
|
||||
double dy1 = 0.0;
|
||||
double dx2 = 0.0;
|
||||
double dy2 = 0.0;
|
||||
double dx3 = 0.0;
|
||||
double dy3 = 0.0;
|
||||
double loc = cross_product(x1, y1, x2, y2, x3, y3);
|
||||
if (std::fabs(loc) > intersection_epsilon)
|
||||
//--------------------------------------------------------calc_sq_distance
|
||||
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
if (cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
//------------------------------------------------calc_line_point_distance
|
||||
AGG_INLINE double calc_line_point_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
double d = sqrt(dx * dx + dy * dy);
|
||||
if(d < vertex_dist_epsilon)
|
||||
{
|
||||
d = -d;
|
||||
return calc_distance(x1, y1, x, y);
|
||||
}
|
||||
calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
|
||||
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
|
||||
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
|
||||
return ((x - x2) * dy - (y - y2) * dx) / d;
|
||||
}
|
||||
*x++ = x1 + dx1;
|
||||
*y++ = y1 + dy1;
|
||||
*x++ = x2 + dx1;
|
||||
*y++ = y2 + dy1;
|
||||
*x++ = x2 + dx2;
|
||||
*y++ = y2 + dy2;
|
||||
*x++ = x3 + dx2;
|
||||
*y++ = y3 + dy2;
|
||||
*x++ = x3 + dx3;
|
||||
*y++ = y3 + dy3;
|
||||
*x++ = x1 + dx3;
|
||||
*y++ = y1 + dy3;
|
||||
}
|
||||
|
||||
//------------------------------------------------------calc_triangle_area
|
||||
AGG_INLINE double calc_triangle_area(double x1, double y1, double x2, double y2, double x3, double y3)
|
||||
{
|
||||
return (x1 * y2 - x2 * y1 + x2 * y3 - x3 * y2 + x3 * y1 - x1 * y3) * 0.5;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_polygon_area
|
||||
template<class Storage>
|
||||
double calc_polygon_area(const Storage& st)
|
||||
{
|
||||
unsigned i;
|
||||
double sum = 0.0;
|
||||
double x = st[0].x;
|
||||
double y = st[0].y;
|
||||
double xs = x;
|
||||
double ys = y;
|
||||
|
||||
for (i = 1; i < st.size(); i++)
|
||||
//-------------------------------------------------------calc_line_point_u
|
||||
AGG_INLINE double calc_segment_point_u(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
const typename Storage::value_type& v = st[i];
|
||||
sum += x * v.y - y * v.x;
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
|
||||
if(dx == 0 && dy == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double pdx = x - x1;
|
||||
double pdy = y - y1;
|
||||
|
||||
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
|
||||
}
|
||||
return (sum + x * ys - y * xs) * 0.5;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Tables for fast sqrt
|
||||
extern int16u g_sqrt_table[1024];
|
||||
extern int8 g_elder_bit_table[256];
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y,
|
||||
double u)
|
||||
{
|
||||
if(u <= 0)
|
||||
{
|
||||
return calc_sq_distance(x, y, x1, y1);
|
||||
}
|
||||
else
|
||||
if(u >= 1)
|
||||
{
|
||||
return calc_sq_distance(x, y, x2, y2);
|
||||
}
|
||||
return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------fast_sqrt
|
||||
// Fast integer Sqrt - really fast: no cycles, divisions or multiplications
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4035) // Disable warning "no return value"
|
||||
#endif
|
||||
AGG_INLINE unsigned fast_sqrt(unsigned val)
|
||||
{
|
||||
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
|
||||
// For Ix86 family processors this assembler code is used.
|
||||
// The key command here is bsr - determination the number of the most
|
||||
// significant bit of the value. For other processors
|
||||
//(and maybe compilers) the pure C "#else" section is used.
|
||||
__asm {
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
return
|
||||
calc_segment_point_sq_distance(
|
||||
x1, y1, x2, y2, x, y,
|
||||
calc_segment_point_u(x1, y1, x2, y2, x, y));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_intersection
|
||||
AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
|
||||
double cx, double cy, double dx, double dy,
|
||||
double* x, double* y)
|
||||
{
|
||||
double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
|
||||
double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
|
||||
if(std::fabs(den) < intersection_epsilon) return false;
|
||||
double r = num / den;
|
||||
*x = ax + r * (bx-ax);
|
||||
*y = ay + r * (by-ay);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------intersection_exists
|
||||
AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
|
||||
double x3, double y3, double x4, double y4)
|
||||
{
|
||||
// It's less expensive but you can't control the
|
||||
// boundary conditions: Less or LessEqual
|
||||
double dx1 = x2 - x1;
|
||||
double dy1 = y2 - y1;
|
||||
double dx2 = x4 - x3;
|
||||
double dy2 = y4 - y3;
|
||||
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
|
||||
((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
|
||||
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
|
||||
((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
|
||||
|
||||
// It's is more expensive but more flexible
|
||||
// in terms of boundary conditions.
|
||||
//--------------------
|
||||
//double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
|
||||
//if(std::fabs(den) < intersection_epsilon) return false;
|
||||
//double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
|
||||
//double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
|
||||
//double ua = nom1 / den;
|
||||
//double ub = nom2 / den;
|
||||
//return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------calc_orthogonal
|
||||
AGG_INLINE void calc_orthogonal(double thickness,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double* x, double* y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
double d = sqrt(dx*dx + dy*dy);
|
||||
*x = thickness * dy / d;
|
||||
*y = -thickness * dx / d;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------dilate_triangle
|
||||
AGG_INLINE void dilate_triangle(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double *x, double* y,
|
||||
double d)
|
||||
{
|
||||
double dx1=0.0;
|
||||
double dy1=0.0;
|
||||
double dx2=0.0;
|
||||
double dy2=0.0;
|
||||
double dx3=0.0;
|
||||
double dy3=0.0;
|
||||
double loc = cross_product(x1, y1, x2, y2, x3, y3);
|
||||
if(std::fabs(loc) > intersection_epsilon)
|
||||
{
|
||||
if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
|
||||
{
|
||||
d = -d;
|
||||
}
|
||||
calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
|
||||
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
|
||||
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
|
||||
}
|
||||
*x++ = x1 + dx1; *y++ = y1 + dy1;
|
||||
*x++ = x2 + dx1; *y++ = y2 + dy1;
|
||||
*x++ = x2 + dx2; *y++ = y2 + dy2;
|
||||
*x++ = x3 + dx2; *y++ = y3 + dy2;
|
||||
*x++ = x3 + dx3; *y++ = y3 + dy3;
|
||||
*x++ = x1 + dx3; *y++ = y1 + dy3;
|
||||
}
|
||||
|
||||
//------------------------------------------------------calc_triangle_area
|
||||
AGG_INLINE double calc_triangle_area(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_polygon_area
|
||||
template<class Storage> double calc_polygon_area(const Storage& st)
|
||||
{
|
||||
unsigned i;
|
||||
double sum = 0.0;
|
||||
double x = st[0].x;
|
||||
double y = st[0].y;
|
||||
double xs = x;
|
||||
double ys = y;
|
||||
|
||||
for(i = 1; i < st.size(); i++)
|
||||
{
|
||||
const typename Storage::value_type& v = st[i];
|
||||
sum += x * v.y - y * v.x;
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
}
|
||||
return (sum + x * ys - y * xs) * 0.5;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Tables for fast sqrt
|
||||
extern int16u g_sqrt_table[1024];
|
||||
extern int8 g_elder_bit_table[256];
|
||||
|
||||
|
||||
//---------------------------------------------------------------fast_sqrt
|
||||
//Fast integer Sqrt - really fast: no cycles, divisions or multiplications
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4035) //Disable warning "no return value"
|
||||
#endif
|
||||
AGG_INLINE unsigned fast_sqrt(unsigned val)
|
||||
{
|
||||
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
|
||||
//For Ix86 family processors this assembler code is used.
|
||||
//The key command here is bsr - determination the number of the most
|
||||
//significant bit of the value. For other processors
|
||||
//(and maybe compilers) the pure C "#else" section is used.
|
||||
__asm
|
||||
{
|
||||
mov ebx, val
|
||||
mov edx, 11
|
||||
bsr ecx, ebx
|
||||
|
@ -267,153 +282,156 @@ AGG_INLINE unsigned fast_sqrt(unsigned val)
|
|||
mov ax, g_sqrt_table[ebx*2]
|
||||
mov ecx, edx
|
||||
shr eax, cl
|
||||
}
|
||||
#else
|
||||
}
|
||||
#else
|
||||
|
||||
// This code is actually pure C and portable to most
|
||||
// arcitectures including 64bit ones.
|
||||
unsigned t = val;
|
||||
int bit = 0;
|
||||
unsigned shift = 11;
|
||||
//This code is actually pure C and portable to most
|
||||
//arcitectures including 64bit ones.
|
||||
unsigned t = val;
|
||||
int bit=0;
|
||||
unsigned shift = 11;
|
||||
|
||||
// The following piece of code is just an emulation of the
|
||||
// Ix86 assembler command "bsr" (see above). However on old
|
||||
// Intels (like Intel MMX 233MHz) this code is about twice
|
||||
// faster (sic!) then just one "bsr". On PIII and PIV the
|
||||
// bsr is optimized quite well.
|
||||
bit = t >> 24;
|
||||
if (bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = (t >> 16) & 0xFF;
|
||||
if (bit)
|
||||
//The following piece of code is just an emulation of the
|
||||
//Ix86 assembler command "bsr" (see above). However on old
|
||||
//Intels (like Intel MMX 233MHz) this code is about twice
|
||||
//faster (sic!) then just one "bsr". On PIII and PIV the
|
||||
//bsr is optimized quite well.
|
||||
bit = t >> 24;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 16;
|
||||
bit = g_elder_bit_table[bit] + 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = (t >> 8) & 0xFF;
|
||||
if (bit)
|
||||
bit = (t >> 16) & 0xFF;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 8;
|
||||
bit = g_elder_bit_table[bit] + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = g_elder_bit_table[t];
|
||||
bit = (t >> 8) & 0xFF;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = g_elder_bit_table[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This code calculates the sqrt.
|
||||
bit -= 9;
|
||||
if (bit > 0)
|
||||
{
|
||||
bit = (bit >> 1) + (bit & 1);
|
||||
shift -= bit;
|
||||
val >>= (bit << 1);
|
||||
}
|
||||
return g_sqrt_table[val] >> shift;
|
||||
#endif
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------besj
|
||||
// Function BESJ calculates Bessel function of first kind of order n
|
||||
// Arguments:
|
||||
// n - an integer (>=0), the order
|
||||
// x - value at which the Bessel function is required
|
||||
//--------------------
|
||||
// C++ Mathematical Library
|
||||
// Convereted from equivalent FORTRAN library
|
||||
// Converetd by Gareth Walker for use by course 392 computational project
|
||||
// All functions tested and yield the same results as the corresponding
|
||||
// FORTRAN versions.
|
||||
//
|
||||
// If you have any problems using these functions please report them to
|
||||
// M.Muldoon@UMIST.ac.uk
|
||||
//
|
||||
// Documentation available on the web
|
||||
// http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
|
||||
// Version 1.0 8/98
|
||||
// 29 October, 1999
|
||||
//--------------------
|
||||
// Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
|
||||
//------------------------------------------------------------------------
|
||||
inline double besj(double x, int n)
|
||||
{
|
||||
if (n < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
double d = 1E-6;
|
||||
double b = 0;
|
||||
if (std::fabs(x) <= d)
|
||||
{
|
||||
if (n != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
double b1 = 0; // b1 is the value from the previous iteration
|
||||
// Set up a starting order for recurrence
|
||||
int m1 = (int)fabs(x) + 6;
|
||||
if (std::fabs(x) > 5)
|
||||
{
|
||||
m1 = (int)(std::fabs(1.4 * x + 60 / x));
|
||||
}
|
||||
int m2 = (int)(n + 2 + std::fabs(x) / 4);
|
||||
if (m1 > m2)
|
||||
{
|
||||
m2 = m1;
|
||||
}
|
||||
|
||||
// Apply recurrence down from curent max order
|
||||
for (;;)
|
||||
{
|
||||
double c3 = 0;
|
||||
double c2 = 1E-30;
|
||||
double c4 = 0;
|
||||
int m8 = 1;
|
||||
if (m2 / 2 * 2 == m2)
|
||||
//This code calculates the sqrt.
|
||||
bit -= 9;
|
||||
if(bit > 0)
|
||||
{
|
||||
m8 = -1;
|
||||
bit = (bit >> 1) + (bit & 1);
|
||||
shift -= bit;
|
||||
val >>= (bit << 1);
|
||||
}
|
||||
int imax = m2 - 2;
|
||||
for (int i = 1; i <= imax; i++)
|
||||
return g_sqrt_table[val] >> shift;
|
||||
#endif
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------besj
|
||||
// Function BESJ calculates Bessel function of first kind of order n
|
||||
// Arguments:
|
||||
// n - an integer (>=0), the order
|
||||
// x - value at which the Bessel function is required
|
||||
//--------------------
|
||||
// C++ Mathematical Library
|
||||
// Convereted from equivalent FORTRAN library
|
||||
// Converetd by Gareth Walker for use by course 392 computational project
|
||||
// All functions tested and yield the same results as the corresponding
|
||||
// FORTRAN versions.
|
||||
//
|
||||
// If you have any problems using these functions please report them to
|
||||
// M.Muldoon@UMIST.ac.uk
|
||||
//
|
||||
// Documentation available on the web
|
||||
// http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
|
||||
// Version 1.0 8/98
|
||||
// 29 October, 1999
|
||||
//--------------------
|
||||
// Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
|
||||
//------------------------------------------------------------------------
|
||||
inline double besj(double x, int n)
|
||||
{
|
||||
if(n < 0)
|
||||
{
|
||||
double c6 = 2 * (m2 - i) * c2 / x - c3;
|
||||
c3 = c2;
|
||||
c2 = c6;
|
||||
if (m2 - i - 1 == n)
|
||||
return 0;
|
||||
}
|
||||
double d = 1E-6;
|
||||
double b = 0;
|
||||
if(std::fabs(x) <= d)
|
||||
{
|
||||
if(n != 0) return 0;
|
||||
return 1;
|
||||
}
|
||||
double b1 = 0; // b1 is the value from the previous iteration
|
||||
// Set up a starting order for recurrence
|
||||
int m1 = (int)fabs(x) + 6;
|
||||
if(std::fabs(x) > 5)
|
||||
{
|
||||
m1 = (int)(std::fabs(1.4 * x + 60 / x));
|
||||
}
|
||||
int m2 = (int)(n + 2 + std::fabs(x) / 4);
|
||||
if (m1 > m2)
|
||||
{
|
||||
m2 = m1;
|
||||
}
|
||||
|
||||
// Apply recurrence down from curent max order
|
||||
for(;;)
|
||||
{
|
||||
double c3 = 0;
|
||||
double c2 = 1E-30;
|
||||
double c4 = 0;
|
||||
int m8 = 1;
|
||||
if (m2 / 2 * 2 == m2)
|
||||
{
|
||||
m8 = -1;
|
||||
}
|
||||
int imax = m2 - 2;
|
||||
for (int i = 1; i <= imax; i++)
|
||||
{
|
||||
double c6 = 2 * (m2 - i) * c2 / x - c3;
|
||||
c3 = c2;
|
||||
c2 = c6;
|
||||
if(m2 - i - 1 == n)
|
||||
{
|
||||
b = c6;
|
||||
}
|
||||
m8 = -1 * m8;
|
||||
if (m8 > 0)
|
||||
{
|
||||
c4 = c4 + 2 * c6;
|
||||
}
|
||||
}
|
||||
double c6 = 2 * c2 / x - c3;
|
||||
if(n == 0)
|
||||
{
|
||||
b = c6;
|
||||
}
|
||||
m8 = -1 * m8;
|
||||
if (m8 > 0)
|
||||
c4 += c6;
|
||||
b /= c4;
|
||||
if(std::fabs(b - b1) < d)
|
||||
{
|
||||
c4 = c4 + 2 * c6;
|
||||
return b;
|
||||
}
|
||||
b1 = b;
|
||||
m2 += 3;
|
||||
}
|
||||
double c6 = 2 * c2 / x - c3;
|
||||
if (n == 0)
|
||||
{
|
||||
b = c6;
|
||||
}
|
||||
c4 += c6;
|
||||
b /= c4;
|
||||
if (std::fabs(b - b1) < d)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
b1 = b;
|
||||
m2 += 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
749
deps/agg/include/agg_math_stroke.h
vendored
749
deps/agg/include/agg_math_stroke.h
vendored
|
@ -23,236 +23,254 @@
|
|||
#include "agg_math.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg {
|
||||
//-------------------------------------------------------------line_cap_e
|
||||
enum line_cap_e { butt_cap, square_cap, round_cap };
|
||||
|
||||
//------------------------------------------------------------line_join_e
|
||||
enum line_join_e { miter_join = 0, miter_join_revert = 1, round_join = 2, bevel_join = 3, miter_join_round = 4 };
|
||||
|
||||
//-----------------------------------------------------------inner_join_e
|
||||
enum inner_join_e { inner_bevel, inner_miter, inner_jag, inner_round };
|
||||
|
||||
//------------------------------------------------------------math_stroke
|
||||
template<class VertexConsumer>
|
||||
class math_stroke
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef typename VertexConsumer::value_type coord_type;
|
||||
|
||||
math_stroke();
|
||||
|
||||
void line_cap(line_cap_e lc) { m_line_cap = lc; }
|
||||
void line_join(line_join_e lj) { m_line_join = lj; }
|
||||
void inner_join(inner_join_e ij) { m_inner_join = ij; }
|
||||
|
||||
line_cap_e line_cap() const { return m_line_cap; }
|
||||
line_join_e line_join() const { return m_line_join; }
|
||||
inner_join_e inner_join() const { return m_inner_join; }
|
||||
|
||||
void width(double w);
|
||||
void miter_limit(double ml) { m_miter_limit = ml; }
|
||||
void miter_limit_theta(double t);
|
||||
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
|
||||
void approximation_scale(double as) { m_approx_scale = as; }
|
||||
|
||||
double width() const { return m_width * 2.0; }
|
||||
double miter_limit() const { return m_miter_limit; }
|
||||
double inner_miter_limit() const { return m_inner_miter_limit; }
|
||||
double approximation_scale() const { return m_approx_scale; }
|
||||
|
||||
void calc_cap(VertexConsumer& vc, const vertex_dist& v0, const vertex_dist& v1, double len);
|
||||
|
||||
void calc_join(VertexConsumer& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double len1,
|
||||
double len2);
|
||||
|
||||
private:
|
||||
AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y) { vc.add(coord_type(x, y)); }
|
||||
|
||||
void calc_arc(VertexConsumer& vc, double x, double y, double dx1, double dy1, double dx2, double dy2);
|
||||
|
||||
void calc_miter(VertexConsumer& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double dx1,
|
||||
double dy1,
|
||||
double dx2,
|
||||
double dy2,
|
||||
line_join_e lj,
|
||||
double mlimit,
|
||||
double dbevel);
|
||||
|
||||
double m_width;
|
||||
double m_width_abs;
|
||||
double m_width_eps;
|
||||
int m_width_sign;
|
||||
double m_miter_limit;
|
||||
double m_inner_miter_limit;
|
||||
double m_approx_scale;
|
||||
line_cap_e m_line_cap;
|
||||
line_join_e m_line_join;
|
||||
inner_join_e m_inner_join;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
math_stroke<VC>::math_stroke()
|
||||
: m_width(0.5)
|
||||
, m_width_abs(0.5)
|
||||
, m_width_eps(0.5 / 1024.0)
|
||||
, m_width_sign(1)
|
||||
, m_miter_limit(4.0)
|
||||
, m_inner_miter_limit(1.01)
|
||||
, m_approx_scale(1.0)
|
||||
, m_line_cap(butt_cap)
|
||||
, m_line_join(miter_join)
|
||||
, m_inner_join(inner_miter)
|
||||
{}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::width(double w)
|
||||
{
|
||||
m_width = w * 0.5;
|
||||
if (m_width < 0)
|
||||
//-------------------------------------------------------------line_cap_e
|
||||
enum line_cap_e
|
||||
{
|
||||
m_width_abs = -m_width;
|
||||
m_width_sign = -1;
|
||||
}
|
||||
else
|
||||
butt_cap,
|
||||
square_cap,
|
||||
round_cap
|
||||
};
|
||||
|
||||
//------------------------------------------------------------line_join_e
|
||||
enum line_join_e
|
||||
{
|
||||
m_width_abs = m_width;
|
||||
m_width_sign = 1;
|
||||
}
|
||||
m_width_eps = m_width / 1024.0;
|
||||
}
|
||||
miter_join = 0,
|
||||
miter_join_revert = 1,
|
||||
round_join = 2,
|
||||
bevel_join = 3,
|
||||
miter_join_round = 4
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::miter_limit_theta(double t)
|
||||
{
|
||||
m_miter_limit = 1.0 / std::sin(t * 0.5);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_arc(VC& vc, double x, double y, double dx1, double dy1, double dx2, double dy2)
|
||||
{
|
||||
double a1 = std::atan2(dy1 * m_width_sign, dx1 * m_width_sign);
|
||||
double a2 = std::atan2(dy2 * m_width_sign, dx2 * m_width_sign);
|
||||
double da = a1 - a2;
|
||||
int i, n;
|
||||
|
||||
da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
|
||||
|
||||
add_vertex(vc, x + dx1, y + dy1);
|
||||
if (m_width_sign > 0)
|
||||
//-----------------------------------------------------------inner_join_e
|
||||
enum inner_join_e
|
||||
{
|
||||
if (a1 > a2)
|
||||
a2 += 2 * pi;
|
||||
n = int((a2 - a1) / da);
|
||||
da = (a2 - a1) / (n + 1);
|
||||
a1 += da;
|
||||
for (i = 0; i < n; i++)
|
||||
inner_bevel,
|
||||
inner_miter,
|
||||
inner_jag,
|
||||
inner_round
|
||||
};
|
||||
|
||||
//------------------------------------------------------------math_stroke
|
||||
template<class VertexConsumer> class math_stroke
|
||||
{
|
||||
public:
|
||||
typedef typename VertexConsumer::value_type coord_type;
|
||||
|
||||
math_stroke();
|
||||
|
||||
void line_cap(line_cap_e lc) { m_line_cap = lc; }
|
||||
void line_join(line_join_e lj) { m_line_join = lj; }
|
||||
void inner_join(inner_join_e ij) { m_inner_join = ij; }
|
||||
|
||||
line_cap_e line_cap() const { return m_line_cap; }
|
||||
line_join_e line_join() const { return m_line_join; }
|
||||
inner_join_e inner_join() const { return m_inner_join; }
|
||||
|
||||
void width(double w);
|
||||
void miter_limit(double ml) { m_miter_limit = ml; }
|
||||
void miter_limit_theta(double t);
|
||||
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
|
||||
void approximation_scale(double as) { m_approx_scale = as; }
|
||||
|
||||
double width() const { return m_width * 2.0; }
|
||||
double miter_limit() const { return m_miter_limit; }
|
||||
double inner_miter_limit() const { return m_inner_miter_limit; }
|
||||
double approximation_scale() const { return m_approx_scale; }
|
||||
|
||||
void calc_cap(VertexConsumer& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
double len);
|
||||
|
||||
void calc_join(VertexConsumer& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double len1,
|
||||
double len2);
|
||||
|
||||
private:
|
||||
AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y)
|
||||
{
|
||||
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
||||
vc.add(coord_type(x, y));
|
||||
}
|
||||
|
||||
void calc_arc(VertexConsumer& vc,
|
||||
double x, double y,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2);
|
||||
|
||||
void calc_miter(VertexConsumer& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
line_join_e lj,
|
||||
double mlimit,
|
||||
double dbevel);
|
||||
|
||||
double m_width;
|
||||
double m_width_abs;
|
||||
double m_width_eps;
|
||||
int m_width_sign;
|
||||
double m_miter_limit;
|
||||
double m_inner_miter_limit;
|
||||
double m_approx_scale;
|
||||
line_cap_e m_line_cap;
|
||||
line_join_e m_line_join;
|
||||
inner_join_e m_inner_join;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC> math_stroke<VC>::math_stroke() :
|
||||
m_width(0.5),
|
||||
m_width_abs(0.5),
|
||||
m_width_eps(0.5/1024.0),
|
||||
m_width_sign(1),
|
||||
m_miter_limit(4.0),
|
||||
m_inner_miter_limit(1.01),
|
||||
m_approx_scale(1.0),
|
||||
m_line_cap(butt_cap),
|
||||
m_line_join(miter_join),
|
||||
m_inner_join(inner_miter)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC> void math_stroke<VC>::width(double w)
|
||||
{
|
||||
m_width = w * 0.5;
|
||||
if(m_width < 0)
|
||||
{
|
||||
m_width_abs = -m_width;
|
||||
m_width_sign = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_width_abs = m_width;
|
||||
m_width_sign = 1;
|
||||
}
|
||||
m_width_eps = m_width / 1024.0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
|
||||
{
|
||||
m_miter_limit = 1.0 / std::sin(t * 0.5) ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_arc(VC& vc,
|
||||
double x, double y,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
double a1 = std::atan2(dy1 * m_width_sign, dx1 * m_width_sign);
|
||||
double a2 = std::atan2(dy2 * m_width_sign, dx2 * m_width_sign);
|
||||
double da = a1 - a2;
|
||||
int i, n;
|
||||
|
||||
da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
|
||||
|
||||
add_vertex(vc, x + dx1, y + dy1);
|
||||
if(m_width_sign > 0)
|
||||
{
|
||||
if(a1 > a2) a2 += 2 * pi;
|
||||
n = int((a2 - a1) / da);
|
||||
da = (a2 - a1) / (n + 1);
|
||||
a1 += da;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
||||
a1 += da;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a1 < a2)
|
||||
a2 -= 2 * pi;
|
||||
n = int((a1 - a2) / da);
|
||||
da = (a1 - a2) / (n + 1);
|
||||
a1 -= da;
|
||||
for (i = 0; i < n; i++)
|
||||
else
|
||||
{
|
||||
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
||||
if(a1 < a2) a2 -= 2 * pi;
|
||||
n = int((a1 - a2) / da);
|
||||
da = (a1 - a2) / (n + 1);
|
||||
a1 -= da;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
||||
a1 -= da;
|
||||
}
|
||||
}
|
||||
add_vertex(vc, x + dx2, y + dy2);
|
||||
}
|
||||
add_vertex(vc, x + dx2, y + dy2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_miter(VC& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double dx1,
|
||||
double dy1,
|
||||
double dx2,
|
||||
double dy2,
|
||||
line_join_e lj,
|
||||
double mlimit,
|
||||
double dbevel)
|
||||
{
|
||||
double xi = v1.x;
|
||||
double yi = v1.y;
|
||||
double di = 1;
|
||||
double lim = m_width_abs * mlimit;
|
||||
bool miter_limit_exceeded = true; // Assume the worst
|
||||
bool intersection_failed = true; // Assume the worst
|
||||
|
||||
if (calc_intersection(v0.x + dx1,
|
||||
v0.y - dy1,
|
||||
v1.x + dx1,
|
||||
v1.y - dy1,
|
||||
v1.x + dx2,
|
||||
v1.y - dy2,
|
||||
v2.x + dx2,
|
||||
v2.y - dy2,
|
||||
&xi,
|
||||
&yi))
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_miter(VC& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
line_join_e lj,
|
||||
double mlimit,
|
||||
double dbevel)
|
||||
{
|
||||
// Calculation of the intersection succeeded
|
||||
//---------------------
|
||||
di = calc_distance(v1.x, v1.y, xi, yi);
|
||||
if (di <= lim)
|
||||
double xi = v1.x;
|
||||
double yi = v1.y;
|
||||
double di = 1;
|
||||
double lim = m_width_abs * mlimit;
|
||||
bool miter_limit_exceeded = true; // Assume the worst
|
||||
bool intersection_failed = true; // Assume the worst
|
||||
|
||||
if(calc_intersection(v0.x + dx1, v0.y - dy1,
|
||||
v1.x + dx1, v1.y - dy1,
|
||||
v1.x + dx2, v1.y - dy2,
|
||||
v2.x + dx2, v2.y - dy2,
|
||||
&xi, &yi))
|
||||
{
|
||||
// Inside the miter limit
|
||||
// Calculation of the intersection succeeded
|
||||
//---------------------
|
||||
add_vertex(vc, xi, yi);
|
||||
miter_limit_exceeded = false;
|
||||
di = calc_distance(v1.x, v1.y, xi, yi);
|
||||
if(di <= lim)
|
||||
{
|
||||
// Inside the miter limit
|
||||
//---------------------
|
||||
add_vertex(vc, xi, yi);
|
||||
miter_limit_exceeded = false;
|
||||
}
|
||||
intersection_failed = false;
|
||||
}
|
||||
intersection_failed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculation of the intersection failed, most probably
|
||||
// the three points lie one straight line.
|
||||
// First check if v0 and v2 lie on the opposite sides of vector:
|
||||
// (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
|
||||
// to the line determined by vertices v0 and v1.
|
||||
// This condition determines whether the next line segments continues
|
||||
// the previous one or goes back.
|
||||
//----------------
|
||||
double x2 = v1.x + dx1;
|
||||
double y2 = v1.y - dy1;
|
||||
if ((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) ==
|
||||
(cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
|
||||
else
|
||||
{
|
||||
// This case means that the next segment continues
|
||||
// the previous one (straight line)
|
||||
//-----------------
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
miter_limit_exceeded = false;
|
||||
// Calculation of the intersection failed, most probably
|
||||
// the three points lie one straight line.
|
||||
// First check if v0 and v2 lie on the opposite sides of vector:
|
||||
// (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
|
||||
// to the line determined by vertices v0 and v1.
|
||||
// This condition determines whether the next line segments continues
|
||||
// the previous one or goes back.
|
||||
//----------------
|
||||
double x2 = v1.x + dx1;
|
||||
double y2 = v1.y - dy1;
|
||||
if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) ==
|
||||
(cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
|
||||
{
|
||||
// This case means that the next segment continues
|
||||
// the previous one (straight line)
|
||||
//-----------------
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
miter_limit_exceeded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (miter_limit_exceeded)
|
||||
{
|
||||
// Miter limit exceeded
|
||||
//------------------------
|
||||
switch (lj)
|
||||
if(miter_limit_exceeded)
|
||||
{
|
||||
// Miter limit exceeded
|
||||
//------------------------
|
||||
switch(lj)
|
||||
{
|
||||
case miter_join_revert:
|
||||
// For the compatibility with SVG, PDF, etc,
|
||||
// we use a simple bevel join instead of
|
||||
|
@ -269,11 +287,13 @@ void math_stroke<VC>::calc_miter(VC& vc,
|
|||
default:
|
||||
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
|
||||
//----------------
|
||||
if (intersection_failed)
|
||||
if(intersection_failed)
|
||||
{
|
||||
mlimit *= m_width_sign;
|
||||
add_vertex(vc, v1.x + dx1 + dy1 * mlimit, v1.y - dy1 + dx1 * mlimit);
|
||||
add_vertex(vc, v1.x + dx2 - dy2 * mlimit, v1.y - dy2 - dx2 * mlimit);
|
||||
add_vertex(vc, v1.x + dx1 + dy1 * mlimit,
|
||||
v1.y - dy1 + dx1 * mlimit);
|
||||
add_vertex(vc, v1.x + dx2 - dy2 * mlimit,
|
||||
v1.y - dy2 - dx2 * mlimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -282,196 +302,208 @@ void math_stroke<VC>::calc_miter(VC& vc,
|
|||
double x2 = v1.x + dx2;
|
||||
double y2 = v1.y - dy2;
|
||||
di = (lim - dbevel) / (di - dbevel);
|
||||
add_vertex(vc, x1 + (xi - x1) * di, y1 + (yi - y1) * di);
|
||||
add_vertex(vc, x2 + (xi - x2) * di, y2 + (yi - y2) * di);
|
||||
add_vertex(vc, x1 + (xi - x1) * di,
|
||||
y1 + (yi - y1) * di);
|
||||
add_vertex(vc, x2 + (xi - x2) * di,
|
||||
y2 + (yi - y2) * di);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------stroke_calc_cap
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_cap(VC& vc, const vertex_dist& v0, const vertex_dist& v1, double len)
|
||||
{
|
||||
vc.remove_all();
|
||||
|
||||
double dx1 = (v1.y - v0.y) / len;
|
||||
double dy1 = (v1.x - v0.x) / len;
|
||||
double dx2 = 0;
|
||||
double dy2 = 0;
|
||||
|
||||
dx1 *= m_width;
|
||||
dy1 *= m_width;
|
||||
|
||||
if (m_line_cap != round_cap)
|
||||
{
|
||||
if (m_line_cap == square_cap)
|
||||
{
|
||||
dx2 = dy1 * m_width_sign;
|
||||
dy2 = dx1 * m_width_sign;
|
||||
}
|
||||
add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
|
||||
add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
|
||||
}
|
||||
else
|
||||
{
|
||||
double da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
|
||||
double a1;
|
||||
int i;
|
||||
int n = int(pi / da);
|
||||
|
||||
da = pi / (n + 1);
|
||||
add_vertex(vc, v0.x - dx1, v0.y + dy1);
|
||||
if (m_width_sign > 0)
|
||||
{
|
||||
a1 = std::atan2(dy1, -dx1);
|
||||
a1 += da;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
add_vertex(vc, v0.x + std::cos(a1) * m_width, v0.y + std::sin(a1) * m_width);
|
||||
a1 += da;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------stroke_calc_cap
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_cap(VC& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
double len)
|
||||
{
|
||||
vc.remove_all();
|
||||
|
||||
double dx1 = (v1.y - v0.y) / len;
|
||||
double dy1 = (v1.x - v0.x) / len;
|
||||
double dx2 = 0;
|
||||
double dy2 = 0;
|
||||
|
||||
dx1 *= m_width;
|
||||
dy1 *= m_width;
|
||||
|
||||
if(m_line_cap != round_cap)
|
||||
{
|
||||
if(m_line_cap == square_cap)
|
||||
{
|
||||
dx2 = dy1 * m_width_sign;
|
||||
dy2 = dx1 * m_width_sign;
|
||||
}
|
||||
add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
|
||||
add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
|
||||
}
|
||||
else
|
||||
{
|
||||
a1 = std::atan2(-dy1, dx1);
|
||||
a1 -= da;
|
||||
for (i = 0; i < n; i++)
|
||||
double da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
|
||||
double a1;
|
||||
int i;
|
||||
int n = int(pi / da);
|
||||
|
||||
da = pi / (n + 1);
|
||||
add_vertex(vc, v0.x - dx1, v0.y + dy1);
|
||||
if(m_width_sign > 0)
|
||||
{
|
||||
add_vertex(vc, v0.x + std::cos(a1) * m_width, v0.y + std::sin(a1) * m_width);
|
||||
a1 -= da;
|
||||
a1 = std::atan2(dy1, -dx1);
|
||||
a1 += da;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
add_vertex(vc, v0.x + std::cos(a1) * m_width,
|
||||
v0.y + std::sin(a1) * m_width);
|
||||
a1 += da;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a1 = std::atan2(-dy1, dx1);
|
||||
a1 -= da;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
add_vertex(vc, v0.x + std::cos(a1) * m_width,
|
||||
v0.y + std::sin(a1) * m_width);
|
||||
a1 -= da;
|
||||
}
|
||||
}
|
||||
add_vertex(vc, v0.x + dx1, v0.y - dy1);
|
||||
}
|
||||
add_vertex(vc, v0.x + dx1, v0.y - dy1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_join(VC& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double len1,
|
||||
double len2)
|
||||
{
|
||||
double dx1 = m_width * (v1.y - v0.y) / len1;
|
||||
double dy1 = m_width * (v1.x - v0.x) / len1;
|
||||
double dx2 = m_width * (v2.y - v1.y) / len2;
|
||||
double dy2 = m_width * (v2.x - v1.x) / len2;
|
||||
|
||||
vc.remove_all();
|
||||
|
||||
double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
|
||||
if (cp != 0 && (cp > 0) == (m_width > 0) && m_width_abs > 0)
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VC>
|
||||
void math_stroke<VC>::calc_join(VC& vc,
|
||||
const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
double len1,
|
||||
double len2)
|
||||
{
|
||||
// Inner join
|
||||
//---------------
|
||||
double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
|
||||
if (limit < m_inner_miter_limit)
|
||||
{
|
||||
limit = m_inner_miter_limit;
|
||||
}
|
||||
double dx1 = m_width * (v1.y - v0.y) / len1;
|
||||
double dy1 = m_width * (v1.x - v0.x) / len1;
|
||||
double dx2 = m_width * (v2.y - v1.y) / len2;
|
||||
double dy2 = m_width * (v2.x - v1.x) / len2;
|
||||
|
||||
switch (m_inner_join)
|
||||
vc.remove_all();
|
||||
|
||||
double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
|
||||
if (cp != 0 && (cp > 0) == (m_width > 0) && m_width_abs > 0)
|
||||
{
|
||||
// Inner join
|
||||
//---------------
|
||||
double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
|
||||
if (limit < m_inner_miter_limit)
|
||||
{
|
||||
limit = m_inner_miter_limit;
|
||||
}
|
||||
|
||||
switch(m_inner_join)
|
||||
{
|
||||
default: // inner_bevel
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||
break;
|
||||
|
||||
case inner_miter:
|
||||
calc_miter(vc, v0, v1, v2, dx1, dy1, dx2, dy2, miter_join_revert, limit, 0);
|
||||
calc_miter(vc,
|
||||
v0, v1, v2, dx1, dy1, dx2, dy2,
|
||||
miter_join_revert,
|
||||
limit, 0);
|
||||
break;
|
||||
|
||||
case inner_jag:
|
||||
case inner_round:
|
||||
cp = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2);
|
||||
if (cp < len1 * len1 && cp < len2 * len2)
|
||||
cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
|
||||
if(cp < len1 * len1 && cp < len2 * len2)
|
||||
{
|
||||
calc_miter(vc, v0, v1, v2, dx1, dy1, dx2, dy2, miter_join_revert, limit, 0);
|
||||
calc_miter(vc,
|
||||
v0, v1, v2, dx1, dy1, dx2, dy2,
|
||||
miter_join_revert,
|
||||
limit, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_inner_join == inner_jag)
|
||||
if(m_inner_join == inner_jag)
|
||||
{
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
add_vertex(vc, v1.x, v1.y);
|
||||
add_vertex(vc, v1.x, v1.y );
|
||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
add_vertex(vc, v1.x, v1.y);
|
||||
add_vertex(vc, v1.x, v1.y );
|
||||
calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
|
||||
add_vertex(vc, v1.x, v1.y);
|
||||
add_vertex(vc, v1.x, v1.y );
|
||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Outer join
|
||||
//---------------
|
||||
|
||||
// Calculate the distance between v1 and
|
||||
// the central point of the bevel line segment
|
||||
//---------------
|
||||
double dx = (dx1 + dx2) / 2;
|
||||
double dy = (dy1 + dy2) / 2;
|
||||
double dbevel = sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (m_line_join == round_join || m_line_join == bevel_join)
|
||||
{
|
||||
// This is an optimization that reduces the number of points
|
||||
// in cases of almost collinear segments. If there's no
|
||||
// visible difference between bevel and miter joins we'd rather
|
||||
// use miter join because it adds only one point instead of two.
|
||||
//
|
||||
// Here we calculate the middle point between the bevel points
|
||||
// and then, the distance between v1 and this middle point.
|
||||
// At outer joins this distance always less than stroke width,
|
||||
// because it's actually the height of an isosceles triangle of
|
||||
// v1 and its two bevel points. If the difference between this
|
||||
// width and this value is small (no visible bevel) we can
|
||||
// add just one point.
|
||||
//
|
||||
// The constant in the expression makes the result approximately
|
||||
// the same as in round joins and caps. You can safely comment
|
||||
// out this entire "if".
|
||||
//-------------------
|
||||
if (m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
|
||||
{
|
||||
if (calc_intersection(v0.x + dx1,
|
||||
v0.y - dy1,
|
||||
v1.x + dx1,
|
||||
v1.y - dy1,
|
||||
v1.x + dx2,
|
||||
v1.y - dy2,
|
||||
v2.x + dx2,
|
||||
v2.y - dy2,
|
||||
&dx,
|
||||
&dy))
|
||||
{
|
||||
add_vertex(vc, dx, dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (m_line_join)
|
||||
else
|
||||
{
|
||||
// Outer join
|
||||
//---------------
|
||||
|
||||
// Calculate the distance between v1 and
|
||||
// the central point of the bevel line segment
|
||||
//---------------
|
||||
double dx = (dx1 + dx2) / 2;
|
||||
double dy = (dy1 + dy2) / 2;
|
||||
double dbevel = sqrt(dx * dx + dy * dy);
|
||||
|
||||
if(m_line_join == round_join || m_line_join == bevel_join)
|
||||
{
|
||||
// This is an optimization that reduces the number of points
|
||||
// in cases of almost collinear segments. If there's no
|
||||
// visible difference between bevel and miter joins we'd rather
|
||||
// use miter join because it adds only one point instead of two.
|
||||
//
|
||||
// Here we calculate the middle point between the bevel points
|
||||
// and then, the distance between v1 and this middle point.
|
||||
// At outer joins this distance always less than stroke width,
|
||||
// because it's actually the height of an isosceles triangle of
|
||||
// v1 and its two bevel points. If the difference between this
|
||||
// width and this value is small (no visible bevel) we can
|
||||
// add just one point.
|
||||
//
|
||||
// The constant in the expression makes the result approximately
|
||||
// the same as in round joins and caps. You can safely comment
|
||||
// out this entire "if".
|
||||
//-------------------
|
||||
if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
|
||||
{
|
||||
if(calc_intersection(v0.x + dx1, v0.y - dy1,
|
||||
v1.x + dx1, v1.y - dy1,
|
||||
v1.x + dx2, v1.y - dy2,
|
||||
v2.x + dx2, v2.y - dy2,
|
||||
&dx, &dy))
|
||||
{
|
||||
add_vertex(vc, dx, dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(m_line_join)
|
||||
{
|
||||
case miter_join:
|
||||
case miter_join_revert:
|
||||
case miter_join_round:
|
||||
calc_miter(vc, v0, v1, v2, dx1, dy1, dx2, dy2, m_line_join, m_miter_limit, dbevel);
|
||||
calc_miter(vc,
|
||||
v0, v1, v2, dx1, dy1, dx2, dy2,
|
||||
m_line_join,
|
||||
m_miter_limit,
|
||||
dbevel);
|
||||
break;
|
||||
|
||||
case round_join:
|
||||
|
@ -482,10 +514,13 @@ void math_stroke<VC>::calc_join(VC& vc,
|
|||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
65
deps/agg/include/agg_path_length.h
vendored
65
deps/agg/include/agg_path_length.h
vendored
|
@ -17,48 +17,49 @@
|
|||
|
||||
#include "agg_math.h"
|
||||
|
||||
namespace agg {
|
||||
template<class VertexSource>
|
||||
double path_length(VertexSource& vs, unsigned path_id = 0)
|
||||
namespace agg
|
||||
{
|
||||
double len = 0.0;
|
||||
double start_x = 0.0;
|
||||
double start_y = 0.0;
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x2 = 0.0;
|
||||
double y2 = 0.0;
|
||||
bool first = true;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while (!is_stop(cmd = vs.vertex(&x2, &y2)))
|
||||
template<class VertexSource>
|
||||
double path_length(VertexSource& vs, unsigned path_id = 0)
|
||||
{
|
||||
if (is_vertex(cmd))
|
||||
double len = 0.0;
|
||||
double start_x = 0.0;
|
||||
double start_y = 0.0;
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x2 = 0.0;
|
||||
double y2 = 0.0;
|
||||
bool first = true;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while(!is_stop(cmd = vs.vertex(&x2, &y2)))
|
||||
{
|
||||
if (first || is_move_to(cmd))
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
start_x = x2;
|
||||
start_y = y2;
|
||||
if(first || is_move_to(cmd))
|
||||
{
|
||||
start_x = x2;
|
||||
start_y = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
len += calc_distance(x1, y1, x2, y2);
|
||||
}
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
len += calc_distance(x1, y1, x2, y2);
|
||||
}
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_close(cmd) && !first)
|
||||
{
|
||||
len += calc_distance(x1, y1, start_x, start_y);
|
||||
if(is_close(cmd) && !first)
|
||||
{
|
||||
len += calc_distance(x1, y1, start_x, start_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
2759
deps/agg/include/agg_path_storage.h
vendored
2759
deps/agg/include/agg_path_storage.h
vendored
File diff suppressed because it is too large
Load diff
464
deps/agg/include/agg_path_storage_integer.h
vendored
464
deps/agg/include/agg_path_storage_integer.h
vendored
|
@ -19,259 +19,277 @@
|
|||
#include <cstring>
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
//---------------------------------------------------------vertex_integer
|
||||
template<class T, unsigned CoordShift = 6>
|
||||
struct vertex_integer
|
||||
namespace agg
|
||||
{
|
||||
enum path_cmd { cmd_move_to = 0, cmd_line_to = 1, cmd_curve3 = 2, cmd_curve4 = 3 };
|
||||
|
||||
enum coord_scale_e { coord_shift = CoordShift, coord_scale = 1 << coord_shift };
|
||||
|
||||
T x, y;
|
||||
vertex_integer() {}
|
||||
vertex_integer(T x_, T y_, unsigned flag)
|
||||
: x(((x_ << 1) & ~1) | (flag & 1))
|
||||
, y(((y_ << 1) & ~1) | (flag >> 1))
|
||||
{}
|
||||
|
||||
unsigned vertex(double* x_, double* y_, double dx = 0, double dy = 0, double scale = 1.0) const
|
||||
//---------------------------------------------------------vertex_integer
|
||||
template<class T, unsigned CoordShift=6> struct vertex_integer
|
||||
{
|
||||
*x_ = dx + (double(x >> 1) / coord_scale) * scale;
|
||||
*y_ = dy + (double(y >> 1) / coord_scale) * scale;
|
||||
switch (((y & 1) << 1) | (x & 1))
|
||||
enum path_cmd
|
||||
{
|
||||
case cmd_move_to:
|
||||
return path_cmd_move_to;
|
||||
case cmd_line_to:
|
||||
return path_cmd_line_to;
|
||||
case cmd_curve3:
|
||||
return path_cmd_curve3;
|
||||
case cmd_curve4:
|
||||
return path_cmd_curve4;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
};
|
||||
cmd_move_to = 0,
|
||||
cmd_line_to = 1,
|
||||
cmd_curve3 = 2,
|
||||
cmd_curve4 = 3
|
||||
};
|
||||
|
||||
//---------------------------------------------------path_storage_integer
|
||||
template<class T, unsigned CoordShift = 6>
|
||||
class path_storage_integer
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef vertex_integer<T, CoordShift> vertex_integer_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
path_storage_integer()
|
||||
: m_storage()
|
||||
, m_vertex_idx(0)
|
||||
, m_closed(true)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void remove_all() { m_storage.remove_all(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(T x, T y) { m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to)); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line_to(T x, T y) { m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to)); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void curve3(T x_ctrl, T y_ctrl, T x_to, T y_to)
|
||||
{
|
||||
m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3));
|
||||
m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve3));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void curve4(T x_ctrl1, T y_ctrl1, T x_ctrl2, T y_ctrl2, T x_to, T y_to)
|
||||
{
|
||||
m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4));
|
||||
m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4));
|
||||
m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve4));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void close_polygon() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned size() const { return m_storage.size(); }
|
||||
unsigned vertex(unsigned idx, double* x, double* y) const { return m_storage[idx].vertex(x, y); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); }
|
||||
void serialize(int8u* ptr) const
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < m_storage.size(); i++)
|
||||
enum coord_scale_e
|
||||
{
|
||||
memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
|
||||
ptr += sizeof(vertex_integer_type);
|
||||
}
|
||||
}
|
||||
coord_shift = CoordShift,
|
||||
coord_scale = 1 << coord_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_vertex_idx = 0;
|
||||
m_closed = true;
|
||||
}
|
||||
T x,y;
|
||||
vertex_integer() {}
|
||||
vertex_integer(T x_, T y_, unsigned flag) :
|
||||
x(((x_ << 1) & ~1) | (flag & 1)),
|
||||
y(((y_ << 1) & ~1) | (flag >> 1)) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if (m_storage.size() < 2 || m_vertex_idx > m_storage.size())
|
||||
unsigned vertex(double* x_, double* y_,
|
||||
double dx=0, double dy=0,
|
||||
double scale=1.0) const
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*x_ = dx + (double(x >> 1) / coord_scale) * scale;
|
||||
*y_ = dy + (double(y >> 1) / coord_scale) * scale;
|
||||
switch(((y & 1) << 1) | (x & 1))
|
||||
{
|
||||
case cmd_move_to: return path_cmd_move_to;
|
||||
case cmd_line_to: return path_cmd_line_to;
|
||||
case cmd_curve3: return path_cmd_curve3;
|
||||
case cmd_curve4: return path_cmd_curve4;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
if (m_vertex_idx == m_storage.size())
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
++m_vertex_idx;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
unsigned cmd = m_storage[m_vertex_idx].vertex(x, y);
|
||||
if (is_move_to(cmd) && !m_closed)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
m_closed = true;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
m_closed = false;
|
||||
++m_vertex_idx;
|
||||
return cmd;
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rect_d bounding_rect() const
|
||||
|
||||
//---------------------------------------------------path_storage_integer
|
||||
template<class T, unsigned CoordShift=6> class path_storage_integer
|
||||
{
|
||||
rect_d bounds(1e100, 1e100, -1e100, -1e100);
|
||||
if (m_storage.size() == 0)
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef vertex_integer<T, CoordShift> vertex_integer_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void remove_all() { m_storage.remove_all(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(T x, T y)
|
||||
{
|
||||
bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
|
||||
m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to));
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line_to(T x, T y)
|
||||
{
|
||||
m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void curve3(T x_ctrl, T y_ctrl,
|
||||
T x_to, T y_to)
|
||||
{
|
||||
m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3));
|
||||
m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve3));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void curve4(T x_ctrl1, T y_ctrl1,
|
||||
T x_ctrl2, T y_ctrl2,
|
||||
T x_to, T y_to)
|
||||
{
|
||||
m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4));
|
||||
m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4));
|
||||
m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve4));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void close_polygon() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned size() const { return m_storage.size(); }
|
||||
unsigned vertex(unsigned idx, double* x, double* y) const
|
||||
{
|
||||
return m_storage[idx].vertex(x, y);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); }
|
||||
void serialize(int8u* ptr) const
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < m_storage.size(); i++)
|
||||
for(i = 0; i < m_storage.size(); i++)
|
||||
{
|
||||
double x, y;
|
||||
m_storage[i].vertex(&x, &y);
|
||||
if (x < bounds.x1)
|
||||
bounds.x1 = x;
|
||||
if (y < bounds.y1)
|
||||
bounds.y1 = y;
|
||||
if (x > bounds.x2)
|
||||
bounds.x2 = x;
|
||||
if (y > bounds.y2)
|
||||
bounds.y2 = y;
|
||||
memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
|
||||
ptr += sizeof(vertex_integer_type);
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private:
|
||||
pod_bvector<vertex_integer_type, 6> m_storage;
|
||||
unsigned m_vertex_idx;
|
||||
bool m_closed;
|
||||
};
|
||||
|
||||
//-----------------------------------------serialized_integer_path_adaptor
|
||||
template<class T, unsigned CoordShift = 6>
|
||||
class serialized_integer_path_adaptor
|
||||
{
|
||||
public:
|
||||
typedef vertex_integer<T, CoordShift> vertex_integer_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
serialized_integer_path_adaptor()
|
||||
: m_data(0)
|
||||
, m_end(0)
|
||||
, m_ptr(0)
|
||||
, m_dx(0.0)
|
||||
, m_dy(0.0)
|
||||
, m_scale(1.0)
|
||||
, m_vertices(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
serialized_integer_path_adaptor(const int8u* data, unsigned size, double dx, double dy)
|
||||
: m_data(data)
|
||||
, m_end(data + size)
|
||||
, m_ptr(data)
|
||||
, m_dx(dx)
|
||||
, m_dy(dy)
|
||||
, m_vertices(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(const int8u* data, unsigned size, double dx, double dy, double scale = 1.0)
|
||||
{
|
||||
m_data = data;
|
||||
m_end = data + size;
|
||||
m_ptr = data;
|
||||
m_dx = dx;
|
||||
m_dy = dy;
|
||||
m_scale = scale;
|
||||
m_vertices = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_ptr = m_data;
|
||||
m_vertices = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if (m_data == 0 || m_ptr > m_end)
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
return path_cmd_stop;
|
||||
m_vertex_idx = 0;
|
||||
m_closed = true;
|
||||
}
|
||||
|
||||
if (m_ptr == m_end)
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
m_ptr += sizeof(vertex_integer_type);
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
if(m_storage.size() < 2 || m_vertex_idx > m_storage.size())
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
return path_cmd_stop;
|
||||
}
|
||||
if(m_vertex_idx == m_storage.size())
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
++m_vertex_idx;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
unsigned cmd = m_storage[m_vertex_idx].vertex(x, y);
|
||||
if(is_move_to(cmd) && !m_closed)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
m_closed = true;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
m_closed = false;
|
||||
++m_vertex_idx;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
vertex_integer_type v;
|
||||
memcpy(&v, m_ptr, sizeof(vertex_integer_type));
|
||||
unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
|
||||
if (is_move_to(cmd) && m_vertices > 2)
|
||||
//--------------------------------------------------------------------
|
||||
rect_d bounding_rect() const
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
rect_d bounds(1e100, 1e100, -1e100, -1e100);
|
||||
if(m_storage.size() == 0)
|
||||
{
|
||||
bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < m_storage.size(); i++)
|
||||
{
|
||||
double x, y;
|
||||
m_storage[i].vertex(&x, &y);
|
||||
if(x < bounds.x1) bounds.x1 = x;
|
||||
if(y < bounds.y1) bounds.y1 = y;
|
||||
if(x > bounds.x2) bounds.x2 = x;
|
||||
if(y > bounds.y2) bounds.y2 = y;
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private:
|
||||
pod_bvector<vertex_integer_type, 6> m_storage;
|
||||
unsigned m_vertex_idx;
|
||||
bool m_closed;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------serialized_integer_path_adaptor
|
||||
template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor
|
||||
{
|
||||
public:
|
||||
typedef vertex_integer<T, CoordShift> vertex_integer_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
serialized_integer_path_adaptor() :
|
||||
m_data(0),
|
||||
m_end(0),
|
||||
m_ptr(0),
|
||||
m_dx(0.0),
|
||||
m_dy(0.0),
|
||||
m_scale(1.0),
|
||||
m_vertices(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
serialized_integer_path_adaptor(const int8u* data, unsigned size,
|
||||
double dx, double dy) :
|
||||
m_data(data),
|
||||
m_end(data + size),
|
||||
m_ptr(data),
|
||||
m_dx(dx),
|
||||
m_dy(dy),
|
||||
m_vertices(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(const int8u* data, unsigned size,
|
||||
double dx, double dy, double scale=1.0)
|
||||
{
|
||||
m_data = data;
|
||||
m_end = data + size;
|
||||
m_ptr = data;
|
||||
m_dx = dx;
|
||||
m_dy = dy;
|
||||
m_scale = scale;
|
||||
m_vertices = 0;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
++m_vertices;
|
||||
m_ptr += sizeof(vertex_integer_type);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_data;
|
||||
const int8u* m_end;
|
||||
const int8u* m_ptr;
|
||||
double m_dx;
|
||||
double m_dy;
|
||||
double m_scale;
|
||||
unsigned m_vertices;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_ptr = m_data;
|
||||
m_vertices = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_data == 0 || m_ptr > m_end)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
return path_cmd_stop;
|
||||
}
|
||||
|
||||
if(m_ptr == m_end)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
m_ptr += sizeof(vertex_integer_type);
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
|
||||
vertex_integer_type v;
|
||||
memcpy(&v, m_ptr, sizeof(vertex_integer_type));
|
||||
unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
|
||||
if(is_move_to(cmd) && m_vertices > 2)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
m_vertices = 0;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
++m_vertices;
|
||||
m_ptr += sizeof(vertex_integer_type);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_data;
|
||||
const int8u* m_end;
|
||||
const int8u* m_ptr;
|
||||
double m_dx;
|
||||
double m_dy;
|
||||
double m_scale;
|
||||
unsigned m_vertices;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
142
deps/agg/include/agg_pattern_filters_rgba.h
vendored
142
deps/agg/include/agg_pattern_filters_rgba.h
vendored
|
@ -19,90 +19,104 @@
|
|||
#include "agg_line_aa_basics.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=======================================================pattern_filter_nn
|
||||
template<class ColorT>
|
||||
struct pattern_filter_nn
|
||||
namespace agg
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
static unsigned dilation() { return 0; }
|
||||
|
||||
static void AGG_INLINE pixel_low_res(color_type const* const* buf, color_type* p, int x, int y) { *p = buf[y][x]; }
|
||||
|
||||
static void AGG_INLINE pixel_high_res(color_type const* const* buf, color_type* p, int x, int y)
|
||||
//=======================================================pattern_filter_nn
|
||||
template<class ColorT> struct pattern_filter_nn
|
||||
{
|
||||
*p = buf[y >> line_subpixel_shift][x >> line_subpixel_shift];
|
||||
}
|
||||
};
|
||||
typedef ColorT color_type;
|
||||
static unsigned dilation() { return 0; }
|
||||
|
||||
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
|
||||
typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
|
||||
static void AGG_INLINE pixel_low_res(color_type const* const* buf,
|
||||
color_type* p, int x, int y)
|
||||
{
|
||||
*p = buf[y][x];
|
||||
}
|
||||
|
||||
//===========================================pattern_filter_bilinear_rgba
|
||||
template<class ColorT>
|
||||
struct pattern_filter_bilinear_rgba
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
static void AGG_INLINE pixel_high_res(color_type const* const* buf,
|
||||
color_type* p, int x, int y)
|
||||
{
|
||||
*p = buf[y >> line_subpixel_shift]
|
||||
[x >> line_subpixel_shift];
|
||||
}
|
||||
};
|
||||
|
||||
static unsigned dilation() { return 1; }
|
||||
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
|
||||
typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
|
||||
|
||||
static AGG_INLINE void pixel_low_res(color_type const* const* buf, color_type* p, int x, int y) { *p = buf[y][x]; }
|
||||
|
||||
static AGG_INLINE void pixel_high_res(color_type const* const* buf, color_type* p, int x, int y)
|
||||
//===========================================pattern_filter_bilinear_rgba
|
||||
template<class ColorT> struct pattern_filter_bilinear_rgba
|
||||
{
|
||||
calc_type r, g, b, a;
|
||||
r = g = b = a = line_subpixel_scale * line_subpixel_scale / 2;
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
|
||||
calc_type weight;
|
||||
int x_lr = x >> line_subpixel_shift;
|
||||
int y_lr = y >> line_subpixel_shift;
|
||||
|
||||
x &= line_subpixel_mask;
|
||||
y &= line_subpixel_mask;
|
||||
const color_type* ptr = buf[y_lr] + x_lr;
|
||||
static unsigned dilation() { return 1; }
|
||||
|
||||
weight = (line_subpixel_scale - x) * (line_subpixel_scale - y);
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
static AGG_INLINE void pixel_low_res(color_type const* const* buf,
|
||||
color_type* p, int x, int y)
|
||||
{
|
||||
*p = buf[y][x];
|
||||
}
|
||||
|
||||
++ptr;
|
||||
static AGG_INLINE void pixel_high_res(color_type const* const* buf,
|
||||
color_type* p, int x, int y)
|
||||
{
|
||||
calc_type r, g, b, a;
|
||||
r = g = b = a = line_subpixel_scale * line_subpixel_scale / 2;
|
||||
|
||||
weight = x * (line_subpixel_scale - y);
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
calc_type weight;
|
||||
int x_lr = x >> line_subpixel_shift;
|
||||
int y_lr = y >> line_subpixel_shift;
|
||||
|
||||
ptr = buf[y_lr + 1] + x_lr;
|
||||
x &= line_subpixel_mask;
|
||||
y &= line_subpixel_mask;
|
||||
const color_type* ptr = buf[y_lr] + x_lr;
|
||||
|
||||
weight = (line_subpixel_scale - x) * y;
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
weight = (line_subpixel_scale - x) *
|
||||
(line_subpixel_scale - y);
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
|
||||
++ptr;
|
||||
++ptr;
|
||||
|
||||
weight = x * y;
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
weight = x * (line_subpixel_scale - y);
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
|
||||
p->r = (value_type)(r >> line_subpixel_shift * 2);
|
||||
p->g = (value_type)(g >> line_subpixel_shift * 2);
|
||||
p->b = (value_type)(b >> line_subpixel_shift * 2);
|
||||
p->a = (value_type)(a >> line_subpixel_shift * 2);
|
||||
}
|
||||
};
|
||||
ptr = buf[y_lr + 1] + x_lr;
|
||||
|
||||
typedef pattern_filter_bilinear_rgba<rgba8> pattern_filter_bilinear_rgba8;
|
||||
typedef pattern_filter_bilinear_rgba<rgba16> pattern_filter_bilinear_rgba16;
|
||||
} // namespace agg
|
||||
weight = (line_subpixel_scale - x) * y;
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
|
||||
++ptr;
|
||||
|
||||
weight = x * y;
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
|
||||
p->r = (value_type)(r >> line_subpixel_shift * 2);
|
||||
p->g = (value_type)(g >> line_subpixel_shift * 2);
|
||||
p->b = (value_type)(b >> line_subpixel_shift * 2);
|
||||
p->a = (value_type)(a >> line_subpixel_shift * 2);
|
||||
}
|
||||
};
|
||||
|
||||
typedef pattern_filter_bilinear_rgba<rgba8> pattern_filter_bilinear_rgba8;
|
||||
typedef pattern_filter_bilinear_rgba<rgba16> pattern_filter_bilinear_rgba16;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
363
deps/agg/include/agg_pixfmt_amask_adaptor.h
vendored
363
deps/agg/include/agg_pixfmt_amask_adaptor.h
vendored
|
@ -16,196 +16,225 @@
|
|||
#ifndef AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
||||
#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include "agg_array.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg {
|
||||
//==================================================pixfmt_amask_adaptor
|
||||
template<class PixFmt, class AlphaMask>
|
||||
class pixfmt_amask_adaptor
|
||||
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef PixFmt pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
typedef AlphaMask amask_type;
|
||||
typedef typename amask_type::cover_type cover_type;
|
||||
|
||||
private:
|
||||
enum span_extra_tail_e { span_extra_tail = 256 };
|
||||
|
||||
void realloc_span(unsigned len)
|
||||
//==================================================pixfmt_amask_adaptor
|
||||
template<class PixFmt, class AlphaMask> class pixfmt_amask_adaptor
|
||||
{
|
||||
if (len > m_span.size())
|
||||
public:
|
||||
typedef PixFmt pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
typedef AlphaMask amask_type;
|
||||
typedef typename amask_type::cover_type cover_type;
|
||||
|
||||
private:
|
||||
enum span_extra_tail_e { span_extra_tail = 256 };
|
||||
|
||||
void realloc_span(unsigned len)
|
||||
{
|
||||
m_span.resize(len + span_extra_tail);
|
||||
if(len > m_span.size())
|
||||
{
|
||||
m_span.resize(len + span_extra_tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_span(unsigned len)
|
||||
{
|
||||
realloc_span(len);
|
||||
memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
|
||||
}
|
||||
|
||||
void init_span(unsigned len, const cover_type* covers)
|
||||
{
|
||||
realloc_span(len);
|
||||
memcpy(&m_span[0], covers, len * sizeof(cover_type));
|
||||
}
|
||||
|
||||
public:
|
||||
pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask)
|
||||
: m_pixf(&pixf)
|
||||
, m_mask(&mask)
|
||||
, m_span()
|
||||
{}
|
||||
|
||||
void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||
void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class PixFmt2>
|
||||
bool attach_pixfmt(PixFmt2& pixf, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
return m_pixf->attach(pixf, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_pixf->width(); }
|
||||
unsigned height() const { return m_pixf->height(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_type pixel(int x, int y) { return m_pixf->pixel(x, y); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_pixel(int x, int y, const color_type& c) { m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y)); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||
{
|
||||
m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_hline(int x, int y, unsigned len, const color_type& c)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x, int y, unsigned len, const color_type& c, cover_type cover)
|
||||
{
|
||||
init_span(len);
|
||||
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_vline(int x, int y, unsigned len, const color_type& c)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y, unsigned len, const color_type& c, cover_type cover)
|
||||
{
|
||||
init_span(len);
|
||||
m_mask->combine_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len)
|
||||
{
|
||||
m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const cover_type* covers)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const cover_type* covers)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x,
|
||||
int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
if (covers)
|
||||
void init_span(unsigned len)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||
realloc_span(len);
|
||||
memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
|
||||
}
|
||||
else
|
||||
|
||||
void init_span(unsigned len, const cover_type* covers)
|
||||
{
|
||||
realloc_span(len);
|
||||
memcpy(&m_span[0], covers, len * sizeof(cover_type));
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask) :
|
||||
m_pixf(&pixf), m_mask(&mask), m_span()
|
||||
{}
|
||||
|
||||
void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||
void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class PixFmt2>
|
||||
bool attach_pixfmt(PixFmt2& pixf, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
return m_pixf->attach(pixf, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_pixf->width(); }
|
||||
unsigned height() const { return m_pixf->height(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_type pixel(int x, int y)
|
||||
{
|
||||
return m_pixf->pixel(x, y);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||
{
|
||||
m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x,
|
||||
int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
if (covers)
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
cover_type cover)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_vspan(x, y, &m_span[0], len);
|
||||
init_span(len);
|
||||
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover);
|
||||
}
|
||||
|
||||
private:
|
||||
pixfmt_type* m_pixf;
|
||||
const amask_type* m_mask;
|
||||
pod_array<cover_type> m_span;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
cover_type cover)
|
||||
{
|
||||
init_span(len);
|
||||
m_mask->combine_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
void copy_from(const rendering_buffer& from,
|
||||
int xdst, int ydst,
|
||||
int xsrc, int ysrc,
|
||||
unsigned len)
|
||||
{
|
||||
m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const cover_type* covers)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const cover_type* covers)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_hspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_vspan(x, y, &m_span[0], len);
|
||||
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
if(covers)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_hspan(x, y, &m_span[0], len);
|
||||
}
|
||||
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
if(covers)
|
||||
{
|
||||
init_span(len, covers);
|
||||
m_mask->combine_vspan(x, y, &m_span[0], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
realloc_span(len);
|
||||
m_mask->fill_vspan(x, y, &m_span[0], len);
|
||||
}
|
||||
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover);
|
||||
}
|
||||
|
||||
private:
|
||||
pixfmt_type* m_pixf;
|
||||
const amask_type* m_mask;
|
||||
pod_array<cover_type> m_span;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
119
deps/agg/include/agg_pixfmt_base.h
vendored
119
deps/agg/include/agg_pixfmt_base.h
vendored
|
@ -20,69 +20,78 @@
|
|||
#include "agg_color_gray.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
namespace agg {
|
||||
struct pixfmt_gray_tag
|
||||
{};
|
||||
|
||||
struct pixfmt_rgb_tag
|
||||
{};
|
||||
|
||||
struct pixfmt_rgba_tag
|
||||
{};
|
||||
|
||||
//--------------------------------------------------------------blender_base
|
||||
template<class ColorT, class Order = void>
|
||||
struct blender_base
|
||||
namespace agg
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
|
||||
static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
|
||||
struct pixfmt_gray_tag
|
||||
{
|
||||
if (cover > cover_none)
|
||||
};
|
||||
|
||||
struct pixfmt_rgb_tag
|
||||
{
|
||||
};
|
||||
|
||||
struct pixfmt_rgba_tag
|
||||
{
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------blender_base
|
||||
template<class ColorT, class Order = void>
|
||||
struct blender_base
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
|
||||
static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
|
||||
{
|
||||
rgba c(color_type::to_double(r),
|
||||
color_type::to_double(g),
|
||||
color_type::to_double(b),
|
||||
color_type::to_double(a));
|
||||
|
||||
if (cover < cover_full)
|
||||
if (cover > cover_none)
|
||||
{
|
||||
double x = double(cover) / cover_full;
|
||||
c.r *= x;
|
||||
c.g *= x;
|
||||
c.b *= x;
|
||||
c.a *= x;
|
||||
rgba c(
|
||||
color_type::to_double(r),
|
||||
color_type::to_double(g),
|
||||
color_type::to_double(b),
|
||||
color_type::to_double(a));
|
||||
|
||||
if (cover < cover_full)
|
||||
{
|
||||
double x = double(cover) / cover_full;
|
||||
c.r *= x;
|
||||
c.g *= x;
|
||||
c.b *= x;
|
||||
c.a *= x;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
return c;
|
||||
else return rgba::no_color();
|
||||
}
|
||||
else
|
||||
return rgba::no_color();
|
||||
}
|
||||
|
||||
static rgba get(const value_type* p, cover_type cover = cover_full)
|
||||
{
|
||||
return get(p[order_type::R], p[order_type::G], p[order_type::B], p[order_type::A], cover);
|
||||
}
|
||||
static rgba get(const value_type* p, cover_type cover = cover_full)
|
||||
{
|
||||
return get(
|
||||
p[order_type::R],
|
||||
p[order_type::G],
|
||||
p[order_type::B],
|
||||
p[order_type::A],
|
||||
cover);
|
||||
}
|
||||
|
||||
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
|
||||
{
|
||||
p[order_type::R] = r;
|
||||
p[order_type::G] = g;
|
||||
p[order_type::B] = b;
|
||||
p[order_type::A] = a;
|
||||
}
|
||||
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
|
||||
{
|
||||
p[order_type::R] = r;
|
||||
p[order_type::G] = g;
|
||||
p[order_type::B] = b;
|
||||
p[order_type::A] = a;
|
||||
}
|
||||
|
||||
static void set(value_type* p, const rgba& c)
|
||||
{
|
||||
p[order_type::R] = color_type::from_double(c.r);
|
||||
p[order_type::G] = color_type::from_double(c.g);
|
||||
p[order_type::B] = color_type::from_double(c.b);
|
||||
p[order_type::A] = color_type::from_double(c.a);
|
||||
}
|
||||
};
|
||||
} // namespace agg
|
||||
static void set(value_type* p, const rgba& c)
|
||||
{
|
||||
p[order_type::R] = color_type::from_double(c.r);
|
||||
p[order_type::G] = color_type::from_double(c.g);
|
||||
p[order_type::B] = color_type::from_double(c.b);
|
||||
p[order_type::A] = color_type::from_double(c.a);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
1106
deps/agg/include/agg_pixfmt_gray.h
vendored
1106
deps/agg/include/agg_pixfmt_gray.h
vendored
File diff suppressed because it is too large
Load diff
1388
deps/agg/include/agg_pixfmt_rgb.h
vendored
1388
deps/agg/include/agg_pixfmt_rgb.h
vendored
File diff suppressed because it is too large
Load diff
2209
deps/agg/include/agg_pixfmt_rgb_packed.h
vendored
2209
deps/agg/include/agg_pixfmt_rgb_packed.h
vendored
File diff suppressed because it is too large
Load diff
1894
deps/agg/include/agg_pixfmt_rgba.h
vendored
1894
deps/agg/include/agg_pixfmt_rgba.h
vendored
File diff suppressed because it is too large
Load diff
209
deps/agg/include/agg_pixfmt_transposer.h
vendored
209
deps/agg/include/agg_pixfmt_transposer.h
vendored
|
@ -18,99 +18,140 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
//=======================================================pixfmt_transposer
|
||||
template<class PixFmt>
|
||||
class pixfmt_transposer
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef PixFmt pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
pixfmt_transposer()
|
||||
: m_pixf(0)
|
||||
{}
|
||||
explicit pixfmt_transposer(pixfmt_type& pixf)
|
||||
: m_pixf(&pixf)
|
||||
{}
|
||||
void attach(pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned width() const { return m_pixf->height(); }
|
||||
AGG_INLINE unsigned height() const { return m_pixf->width(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE color_type pixel(int x, int y) const { return m_pixf->pixel(y, x); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_pixel(int x, int y, const color_type& c) { m_pixf->copy_pixel(y, x, c); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) { m_pixf->blend_pixel(y, x, c, cover); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_hline(int x, int y, unsigned len, const color_type& c) { m_pixf->copy_vline(y, x, len, c); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_vline(int x, int y, unsigned len, const color_type& c) { m_pixf->copy_hline(y, x, len, c); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover)
|
||||
//=======================================================pixfmt_transposer
|
||||
template<class PixFmt> class pixfmt_transposer
|
||||
{
|
||||
m_pixf->blend_vline(y, x, len, c, cover);
|
||||
}
|
||||
public:
|
||||
typedef PixFmt pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover)
|
||||
{
|
||||
m_pixf->blend_hline(y, x, len, c, cover);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
pixfmt_transposer() : m_pixf(0) {}
|
||||
explicit pixfmt_transposer(pixfmt_type& pixf) : m_pixf(&pixf) {}
|
||||
void attach(pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers)
|
||||
{
|
||||
m_pixf->blend_solid_vspan(y, x, len, c, covers);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned width() const { return m_pixf->height(); }
|
||||
AGG_INLINE unsigned height() const { return m_pixf->width(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers)
|
||||
{
|
||||
m_pixf->blend_solid_hspan(y, x, len, c, covers);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE color_type pixel(int x, int y) const
|
||||
{
|
||||
return m_pixf->pixel(y, x);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
|
||||
{
|
||||
m_pixf->copy_color_vspan(y, x, len, colors);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
m_pixf->copy_pixel(y, x, c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
|
||||
{
|
||||
m_pixf->copy_color_hspan(y, x, len, colors);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pixel(int x, int y,
|
||||
const color_type& c,
|
||||
int8u cover)
|
||||
{
|
||||
m_pixf->blend_pixel(y, x, c, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void
|
||||
blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover)
|
||||
{
|
||||
m_pixf->blend_color_vspan(y, x, len, colors, covers, cover);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
m_pixf->copy_vline(y, x, len, c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void
|
||||
blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover)
|
||||
{
|
||||
m_pixf->blend_color_hspan(y, x, len, colors, covers, cover);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c)
|
||||
{
|
||||
m_pixf->copy_hline(y, x, len, c);
|
||||
}
|
||||
|
||||
private:
|
||||
pixfmt_type* m_pixf;
|
||||
};
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_hline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
int8u cover)
|
||||
{
|
||||
m_pixf->blend_vline(y, x, len, c, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_vline(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
int8u cover)
|
||||
{
|
||||
m_pixf->blend_hline(y, x, len, c, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_solid_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const int8u* covers)
|
||||
{
|
||||
m_pixf->blend_solid_vspan(y, x, len, c, covers);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_solid_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type& c,
|
||||
const int8u* covers)
|
||||
{
|
||||
m_pixf->blend_solid_hspan(y, x, len, c, covers);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_color_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors)
|
||||
{
|
||||
m_pixf->copy_color_vspan(y, x, len, colors);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void copy_color_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors)
|
||||
{
|
||||
m_pixf->copy_color_hspan(y, x, len, colors);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_color_hspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const int8u* covers,
|
||||
int8u cover)
|
||||
{
|
||||
m_pixf->blend_color_vspan(y, x, len, colors, covers, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_color_vspan(int x, int y,
|
||||
unsigned len,
|
||||
const color_type* colors,
|
||||
const int8u* covers,
|
||||
int8u cover)
|
||||
{
|
||||
m_pixf->blend_color_hspan(y, x, len, colors, covers, cover);
|
||||
}
|
||||
|
||||
private:
|
||||
pixfmt_type* m_pixf;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
1303
deps/agg/include/agg_rasterizer_cells_aa.h
vendored
1303
deps/agg/include/agg_rasterizer_cells_aa.h
vendored
File diff suppressed because it is too large
Load diff
1201
deps/agg/include/agg_rasterizer_compound_aa.h
vendored
1201
deps/agg/include/agg_rasterizer_compound_aa.h
vendored
File diff suppressed because it is too large
Load diff
183
deps/agg/include/agg_rasterizer_outline.h
vendored
183
deps/agg/include/agg_rasterizer_outline.h
vendored
|
@ -17,116 +17,131 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
//======================================================rasterizer_outline
|
||||
template<class Renderer>
|
||||
class rasterizer_outline
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
explicit rasterizer_outline(Renderer& ren)
|
||||
: m_ren(&ren)
|
||||
, m_start_x(0)
|
||||
, m_start_y(0)
|
||||
, m_vertices(0)
|
||||
{}
|
||||
void attach(Renderer& ren) { m_ren = &ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y)
|
||||
//======================================================rasterizer_outline
|
||||
template<class Renderer> class rasterizer_outline
|
||||
{
|
||||
m_vertices = 1;
|
||||
m_ren->move_to(m_start_x = x, m_start_y = y);
|
||||
}
|
||||
public:
|
||||
explicit rasterizer_outline(Renderer& ren) :
|
||||
m_ren(&ren),
|
||||
m_start_x(0),
|
||||
m_start_y(0),
|
||||
m_vertices(0)
|
||||
{}
|
||||
void attach(Renderer& ren) { m_ren = &ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line_to(int x, int y)
|
||||
{
|
||||
++m_vertices;
|
||||
m_ren->line_to(x, y);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to_d(double x, double y) { move_to(m_ren->coord(x), m_ren->coord(y)); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line_to_d(double x, double y) { line_to(m_ren->coord(x), m_ren->coord(y)); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void close()
|
||||
{
|
||||
if (m_vertices > 2)
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y)
|
||||
{
|
||||
line_to(m_start_x, m_start_y);
|
||||
m_vertices = 1;
|
||||
m_ren->move_to(m_start_x = x, m_start_y = y);
|
||||
}
|
||||
m_vertices = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if (is_move_to(cmd))
|
||||
//--------------------------------------------------------------------
|
||||
void line_to(int x, int y)
|
||||
{
|
||||
move_to_d(x, y);
|
||||
++m_vertices;
|
||||
m_ren->line_to(x, y);
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to_d(double x, double y)
|
||||
{
|
||||
if (is_end_poly(cmd))
|
||||
move_to(m_ren->coord(x), m_ren->coord(y));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line_to_d(double x, double y)
|
||||
{
|
||||
line_to(m_ren->coord(x), m_ren->coord(y));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void close()
|
||||
{
|
||||
if(m_vertices > 2)
|
||||
{
|
||||
if (is_closed(cmd))
|
||||
close();
|
||||
line_to(m_start_x, m_start_y);
|
||||
}
|
||||
m_vertices = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
move_to_d(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
line_to_d(x, y);
|
||||
if(is_end_poly(cmd))
|
||||
{
|
||||
if(is_closed(cmd)) close();
|
||||
}
|
||||
else
|
||||
{
|
||||
line_to_d(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id = 0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while (!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
//--------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id=0)
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
double x;
|
||||
double y;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class VertexSource, class ColorStorage, class PathId>
|
||||
void render_all_paths(VertexSource& vs, const ColorStorage& colors, const PathId& path_id, unsigned num_paths)
|
||||
{
|
||||
for (unsigned i = 0; i < num_paths; i++)
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class VertexSource, class ColorStorage, class PathId>
|
||||
void render_all_paths(VertexSource& vs,
|
||||
const ColorStorage& colors,
|
||||
const PathId& path_id,
|
||||
unsigned num_paths)
|
||||
{
|
||||
m_ren->line_color(colors[i]);
|
||||
add_path(vs, path_id[i]);
|
||||
for(unsigned i = 0; i < num_paths; i++)
|
||||
{
|
||||
m_ren->line_color(colors[i]);
|
||||
add_path(vs, path_id[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Ctrl>
|
||||
void render_ctrl(Ctrl& c)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < c.num_paths(); i++)
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Ctrl> void render_ctrl(Ctrl& c)
|
||||
{
|
||||
m_ren->line_color(c.color(i));
|
||||
add_path(c, i);
|
||||
unsigned i;
|
||||
for(i = 0; i < c.num_paths(); i++)
|
||||
{
|
||||
m_ren->line_color(c.color(i));
|
||||
add_path(c, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Renderer* m_ren;
|
||||
int m_start_x;
|
||||
int m_start_y;
|
||||
unsigned m_vertices;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
Renderer* m_ren;
|
||||
int m_start_x;
|
||||
int m_start_y;
|
||||
unsigned m_vertices;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
865
deps/agg/include/agg_rasterizer_outline_aa.h
vendored
865
deps/agg/include/agg_rasterizer_outline_aa.h
vendored
|
@ -19,254 +19,275 @@
|
|||
#include "agg_line_aa_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool cmp_dist_start(int d)
|
||||
namespace agg
|
||||
{
|
||||
return d > 0;
|
||||
}
|
||||
inline bool cmp_dist_end(int d)
|
||||
{
|
||||
return d <= 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------line_aa_vertex
|
||||
// Vertex (x, y) with the distance to the next one. The last vertex has
|
||||
// the distance between the last and the first points
|
||||
struct line_aa_vertex
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int len;
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool cmp_dist_start(int d) { return d > 0; }
|
||||
inline bool cmp_dist_end(int d) { return d <= 0; }
|
||||
|
||||
line_aa_vertex() {}
|
||||
line_aa_vertex(int x_, int y_)
|
||||
: x(x_)
|
||||
, y(y_)
|
||||
, len(0)
|
||||
{}
|
||||
|
||||
bool operator()(const line_aa_vertex& val)
|
||||
|
||||
//-----------------------------------------------------------line_aa_vertex
|
||||
// Vertex (x, y) with the distance to the next one. The last vertex has
|
||||
// the distance between the last and the first points
|
||||
struct line_aa_vertex
|
||||
{
|
||||
double dx = val.x - x;
|
||||
double dy = val.y - y;
|
||||
return (len = uround(sqrt(dx * dx + dy * dy))) > (line_subpixel_scale + line_subpixel_scale / 2);
|
||||
}
|
||||
};
|
||||
int x;
|
||||
int y;
|
||||
int len;
|
||||
|
||||
//----------------------------------------------------------outline_aa_join_e
|
||||
enum outline_aa_join_e {
|
||||
outline_no_join, //-----outline_no_join
|
||||
outline_miter_join, //-----outline_miter_join
|
||||
outline_round_join, //-----outline_round_join
|
||||
outline_miter_accurate_join //-----outline_accurate_join
|
||||
};
|
||||
line_aa_vertex() {}
|
||||
line_aa_vertex(int x_, int y_) :
|
||||
x(x_),
|
||||
y(y_),
|
||||
len(0)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================rasterizer_outline_aa
|
||||
template<class Renderer, class Coord = line_coord>
|
||||
class rasterizer_outline_aa
|
||||
{
|
||||
private:
|
||||
//------------------------------------------------------------------------
|
||||
struct draw_vars
|
||||
{
|
||||
unsigned idx;
|
||||
int x1, y1, x2, y2;
|
||||
line_parameters curr, next;
|
||||
int lcurr, lnext;
|
||||
int xb1, yb1, xb2, yb2;
|
||||
unsigned flags;
|
||||
bool operator () (const line_aa_vertex& val)
|
||||
{
|
||||
double dx = val.x - x;
|
||||
double dy = val.y - y;
|
||||
return (len = uround(sqrt(dx * dx + dy * dy))) >
|
||||
(line_subpixel_scale + line_subpixel_scale / 2);
|
||||
}
|
||||
};
|
||||
|
||||
void draw(draw_vars& dv, unsigned start, unsigned end);
|
||||
|
||||
public:
|
||||
typedef line_aa_vertex vertex_type;
|
||||
typedef vertex_sequence<vertex_type, 6> vertex_storage_type;
|
||||
|
||||
explicit rasterizer_outline_aa(Renderer& ren)
|
||||
: m_ren(&ren)
|
||||
, m_line_join(ren.accurate_join_only() ? outline_miter_accurate_join : outline_round_join)
|
||||
, m_round_cap(false)
|
||||
, m_start_x(0)
|
||||
, m_start_y(0)
|
||||
{}
|
||||
void attach(Renderer& ren) { m_ren = &ren; }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void line_join(outline_aa_join_e join)
|
||||
//----------------------------------------------------------outline_aa_join_e
|
||||
enum outline_aa_join_e
|
||||
{
|
||||
m_line_join = m_ren->accurate_join_only() ? outline_miter_accurate_join : join;
|
||||
}
|
||||
bool line_join() const { return m_line_join; }
|
||||
outline_no_join, //-----outline_no_join
|
||||
outline_miter_join, //-----outline_miter_join
|
||||
outline_round_join, //-----outline_round_join
|
||||
outline_miter_accurate_join //-----outline_accurate_join
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void round_cap(bool v) { m_round_cap = v; }
|
||||
bool round_cap() const { return m_round_cap; }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void move_to(int x, int y) { m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y)); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void line_to(int x, int y) { m_src_vertices.add(vertex_type(x, y)); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void move_to_d(double x, double y) { move_to(Coord::conv(x), Coord::conv(y)); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void line_to_d(double x, double y) { line_to(Coord::conv(x), Coord::conv(y)); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void render(bool close_polygon);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void add_vertex(double x, double y, unsigned cmd)
|
||||
//=======================================================rasterizer_outline_aa
|
||||
template<class Renderer, class Coord=line_coord> class rasterizer_outline_aa
|
||||
{
|
||||
if (is_move_to(cmd))
|
||||
private:
|
||||
//------------------------------------------------------------------------
|
||||
struct draw_vars
|
||||
{
|
||||
render(false);
|
||||
move_to_d(x, y);
|
||||
unsigned idx;
|
||||
int x1, y1, x2, y2;
|
||||
line_parameters curr, next;
|
||||
int lcurr, lnext;
|
||||
int xb1, yb1, xb2, yb2;
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
void draw(draw_vars& dv, unsigned start, unsigned end);
|
||||
|
||||
public:
|
||||
typedef line_aa_vertex vertex_type;
|
||||
typedef vertex_sequence<vertex_type, 6> vertex_storage_type;
|
||||
|
||||
explicit rasterizer_outline_aa(Renderer& ren) :
|
||||
m_ren(&ren),
|
||||
m_line_join(ren.accurate_join_only() ?
|
||||
outline_miter_accurate_join :
|
||||
outline_round_join),
|
||||
m_round_cap(false),
|
||||
m_start_x(0),
|
||||
m_start_y(0)
|
||||
{}
|
||||
void attach(Renderer& ren) { m_ren = &ren; }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void line_join(outline_aa_join_e join)
|
||||
{
|
||||
m_line_join = m_ren->accurate_join_only() ?
|
||||
outline_miter_accurate_join :
|
||||
join;
|
||||
}
|
||||
else
|
||||
bool line_join() const { return m_line_join; }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void round_cap(bool v) { m_round_cap = v; }
|
||||
bool round_cap() const { return m_round_cap; }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void move_to(int x, int y)
|
||||
{
|
||||
if (is_end_poly(cmd))
|
||||
m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void line_to(int x, int y)
|
||||
{
|
||||
m_src_vertices.add(vertex_type(x, y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void move_to_d(double x, double y)
|
||||
{
|
||||
move_to(Coord::conv(x), Coord::conv(y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void line_to_d(double x, double y)
|
||||
{
|
||||
line_to(Coord::conv(x), Coord::conv(y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void render(bool close_polygon);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
render(is_closed(cmd));
|
||||
if (is_closed(cmd))
|
||||
{
|
||||
move_to(m_start_x, m_start_y);
|
||||
}
|
||||
render(false);
|
||||
move_to_d(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
line_to_d(x, y);
|
||||
if(is_end_poly(cmd))
|
||||
{
|
||||
render(is_closed(cmd));
|
||||
if(is_closed(cmd))
|
||||
{
|
||||
move_to(m_start_x, m_start_y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
line_to_d(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id = 0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while (!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id=0)
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
render(false);
|
||||
}
|
||||
double x;
|
||||
double y;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class ColorStorage, class PathId>
|
||||
void render_all_paths(VertexSource& vs, const ColorStorage& colors, const PathId& path_id, unsigned num_paths)
|
||||
{
|
||||
for (unsigned i = 0; i < num_paths; i++)
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
render(false);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class VertexSource, class ColorStorage, class PathId>
|
||||
void render_all_paths(VertexSource& vs,
|
||||
const ColorStorage& colors,
|
||||
const PathId& path_id,
|
||||
unsigned num_paths)
|
||||
{
|
||||
m_ren->color(colors[i]);
|
||||
add_path(vs, path_id[i]);
|
||||
for(unsigned i = 0; i < num_paths; i++)
|
||||
{
|
||||
m_ren->color(colors[i]);
|
||||
add_path(vs, path_id[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Ctrl>
|
||||
void render_ctrl(Ctrl& c)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Ctrl> void render_ctrl(Ctrl& c)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < c.num_paths(); i++)
|
||||
{
|
||||
m_ren->color(c.color(i));
|
||||
add_path(c, i);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&);
|
||||
const rasterizer_outline_aa<Renderer, Coord>& operator =
|
||||
(const rasterizer_outline_aa<Renderer, Coord>&);
|
||||
|
||||
Renderer* m_ren;
|
||||
vertex_storage_type m_src_vertices;
|
||||
outline_aa_join_e m_line_join;
|
||||
bool m_round_cap;
|
||||
int m_start_x;
|
||||
int m_start_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Renderer, class Coord>
|
||||
void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv,
|
||||
unsigned start,
|
||||
unsigned end)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < c.num_paths(); i++)
|
||||
const vertex_storage_type::value_type* v;
|
||||
|
||||
for(i = start; i < end; i++)
|
||||
{
|
||||
m_ren->color(c.color(i));
|
||||
add_path(c, i);
|
||||
}
|
||||
}
|
||||
if(m_line_join == outline_round_join)
|
||||
{
|
||||
dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1);
|
||||
dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1);
|
||||
dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1);
|
||||
dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);
|
||||
}
|
||||
|
||||
private:
|
||||
rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&);
|
||||
const rasterizer_outline_aa<Renderer, Coord>& operator=(const rasterizer_outline_aa<Renderer, Coord>&);
|
||||
switch(dv.flags)
|
||||
{
|
||||
case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
|
||||
case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break;
|
||||
case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break;
|
||||
case 3: m_ren->line0(dv.curr); break;
|
||||
}
|
||||
|
||||
Renderer* m_ren;
|
||||
vertex_storage_type m_src_vertices;
|
||||
outline_aa_join_e m_line_join;
|
||||
bool m_round_cap;
|
||||
int m_start_x;
|
||||
int m_start_y;
|
||||
};
|
||||
if(m_line_join == outline_round_join && (dv.flags & 2) == 0)
|
||||
{
|
||||
m_ren->pie(dv.curr.x2, dv.curr.y2,
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),
|
||||
dv.curr.x2 + (dv.next.y2 - dv.next.y1),
|
||||
dv.curr.y2 - (dv.next.x2 - dv.next.x1));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Renderer, class Coord>
|
||||
void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv, unsigned start, unsigned end)
|
||||
{
|
||||
unsigned i;
|
||||
const vertex_storage_type::value_type* v;
|
||||
dv.x1 = dv.x2;
|
||||
dv.y1 = dv.y2;
|
||||
dv.lcurr = dv.lnext;
|
||||
dv.lnext = m_src_vertices[dv.idx].len;
|
||||
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
if (m_line_join == outline_round_join)
|
||||
{
|
||||
dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1);
|
||||
dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1);
|
||||
dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1);
|
||||
dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);
|
||||
}
|
||||
++dv.idx;
|
||||
if(dv.idx >= m_src_vertices.size()) dv.idx = 0;
|
||||
|
||||
switch (dv.flags)
|
||||
{
|
||||
case 0:
|
||||
m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2);
|
||||
break;
|
||||
case 1:
|
||||
m_ren->line2(dv.curr, dv.xb2, dv.yb2);
|
||||
break;
|
||||
case 2:
|
||||
m_ren->line1(dv.curr, dv.xb1, dv.yb1);
|
||||
break;
|
||||
case 3:
|
||||
m_ren->line0(dv.curr);
|
||||
break;
|
||||
}
|
||||
v = &m_src_vertices[dv.idx];
|
||||
dv.x2 = v->x;
|
||||
dv.y2 = v->y;
|
||||
|
||||
if (m_line_join == outline_round_join && (dv.flags & 2) == 0)
|
||||
{
|
||||
m_ren->pie(dv.curr.x2,
|
||||
dv.curr.y2,
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),
|
||||
dv.curr.x2 + (dv.next.y2 - dv.next.y1),
|
||||
dv.curr.y2 - (dv.next.x2 - dv.next.x1));
|
||||
}
|
||||
dv.curr = dv.next;
|
||||
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
|
||||
dv.xb1 = dv.xb2;
|
||||
dv.yb1 = dv.yb2;
|
||||
|
||||
dv.x1 = dv.x2;
|
||||
dv.y1 = dv.y2;
|
||||
dv.lcurr = dv.lnext;
|
||||
dv.lnext = m_src_vertices[dv.idx].len;
|
||||
|
||||
++dv.idx;
|
||||
if (dv.idx >= m_src_vertices.size())
|
||||
dv.idx = 0;
|
||||
|
||||
v = &m_src_vertices[dv.idx];
|
||||
dv.x2 = v->x;
|
||||
dv.y2 = v->y;
|
||||
|
||||
dv.curr = dv.next;
|
||||
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
|
||||
dv.xb1 = dv.xb2;
|
||||
dv.yb1 = dv.yb2;
|
||||
|
||||
switch (m_line_join)
|
||||
{
|
||||
switch(m_line_join)
|
||||
{
|
||||
case outline_no_join:
|
||||
dv.flags = 3;
|
||||
break;
|
||||
|
||||
case outline_miter_join:
|
||||
dv.flags >>= 1;
|
||||
dv.flags |= ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
|
||||
if ((dv.flags & 2) == 0)
|
||||
dv.flags |= ((dv.curr.diagonal_quadrant() ==
|
||||
dv.next.diagonal_quadrant()) << 1);
|
||||
if((dv.flags & 2) == 0)
|
||||
{
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
}
|
||||
|
@ -274,282 +295,302 @@ void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv, unsigned start,
|
|||
|
||||
case outline_round_join:
|
||||
dv.flags >>= 1;
|
||||
dv.flags |= ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
|
||||
dv.flags |= ((dv.curr.diagonal_quadrant() ==
|
||||
dv.next.diagonal_quadrant()) << 1);
|
||||
break;
|
||||
|
||||
case outline_miter_accurate_join:
|
||||
dv.flags = 0;
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Renderer, class Coord>
|
||||
void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon)
|
||||
{
|
||||
m_src_vertices.close(close_polygon);
|
||||
draw_vars dv;
|
||||
const vertex_storage_type::value_type* v;
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int lprev;
|
||||
|
||||
if (close_polygon && (m_src_vertices.size() >= 3))
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Renderer, class Coord>
|
||||
void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon)
|
||||
{
|
||||
dv.idx = 2;
|
||||
m_src_vertices.close(close_polygon);
|
||||
draw_vars dv;
|
||||
const vertex_storage_type::value_type* v;
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int lprev;
|
||||
|
||||
v = &m_src_vertices[m_src_vertices.size() - 1];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
|
||||
v = &m_src_vertices[0];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
dv.lcurr = v->len;
|
||||
line_parameters prev(x1, y1, x2, y2, lprev);
|
||||
|
||||
v = &m_src_vertices[1];
|
||||
dv.x1 = v->x;
|
||||
dv.y1 = v->y;
|
||||
dv.lnext = v->len;
|
||||
dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
|
||||
|
||||
v = &m_src_vertices[dv.idx];
|
||||
dv.x2 = v->x;
|
||||
dv.y2 = v->y;
|
||||
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
|
||||
|
||||
dv.xb1 = 0;
|
||||
dv.yb1 = 0;
|
||||
dv.xb2 = 0;
|
||||
dv.yb2 = 0;
|
||||
|
||||
switch (m_line_join)
|
||||
if(close_polygon && (m_src_vertices.size() >= 3))
|
||||
{
|
||||
dv.idx = 2;
|
||||
|
||||
v = &m_src_vertices[m_src_vertices.size() - 1];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
|
||||
v = &m_src_vertices[0];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
dv.lcurr = v->len;
|
||||
line_parameters prev(x1, y1, x2, y2, lprev);
|
||||
|
||||
v = &m_src_vertices[1];
|
||||
dv.x1 = v->x;
|
||||
dv.y1 = v->y;
|
||||
dv.lnext = v->len;
|
||||
dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
|
||||
|
||||
v = &m_src_vertices[dv.idx];
|
||||
dv.x2 = v->x;
|
||||
dv.y2 = v->y;
|
||||
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
|
||||
|
||||
dv.xb1 = 0;
|
||||
dv.yb1 = 0;
|
||||
dv.xb2 = 0;
|
||||
dv.yb2 = 0;
|
||||
|
||||
switch(m_line_join)
|
||||
{
|
||||
case outline_no_join:
|
||||
dv.flags = 3;
|
||||
break;
|
||||
|
||||
case outline_miter_join:
|
||||
case outline_round_join:
|
||||
dv.flags = (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
|
||||
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
|
||||
dv.flags =
|
||||
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
|
||||
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
|
||||
break;
|
||||
|
||||
case outline_miter_accurate_join:
|
||||
dv.flags = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dv.flags & 1) == 0 && m_line_join != outline_round_join)
|
||||
{
|
||||
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
|
||||
}
|
||||
if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
|
||||
{
|
||||
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
|
||||
}
|
||||
|
||||
if ((dv.flags & 2) == 0 && m_line_join != outline_round_join)
|
||||
{
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
|
||||
{
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
}
|
||||
draw(dv, 0, m_src_vertices.size());
|
||||
}
|
||||
draw(dv, 0, m_src_vertices.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_src_vertices.size())
|
||||
else
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
switch(m_src_vertices.size())
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
v = &m_src_vertices[0];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
v = &m_src_vertices[1];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
line_parameters lp(x1, y1, x2, y2, lprev);
|
||||
if(m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
|
||||
}
|
||||
m_ren->line3(lp,
|
||||
x1 + (y2 - y1),
|
||||
y1 - (x2 - x1),
|
||||
x2 + (y2 - y1),
|
||||
y2 - (x2 - x1));
|
||||
if(m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
v = &m_src_vertices[0];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
v = &m_src_vertices[1];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
line_parameters lp(x1, y1, x2, y2, lprev);
|
||||
if (m_round_cap)
|
||||
case 3:
|
||||
{
|
||||
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
|
||||
int x3, y3;
|
||||
int lnext;
|
||||
v = &m_src_vertices[0];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
v = &m_src_vertices[1];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
lnext = v->len;
|
||||
v = &m_src_vertices[2];
|
||||
x3 = v->x;
|
||||
y3 = v->y;
|
||||
line_parameters lp1(x1, y1, x2, y2, lprev);
|
||||
line_parameters lp2(x2, y2, x3, y3, lnext);
|
||||
|
||||
if(m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
|
||||
}
|
||||
|
||||
if(m_line_join == outline_round_join)
|
||||
{
|
||||
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
|
||||
x2 + (y2 - y1), y2 - (x2 - x1));
|
||||
|
||||
m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1),
|
||||
x2 + (y3 - y2), y2 - (x3 - x2));
|
||||
|
||||
m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2),
|
||||
x3 + (y3 - y2), y3 - (x3 - x2));
|
||||
}
|
||||
else
|
||||
{
|
||||
bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
|
||||
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
|
||||
dv.xb1, dv.yb1);
|
||||
|
||||
m_ren->line3(lp2, dv.xb1, dv.yb1,
|
||||
x3 + (y3 - y2), y3 - (x3 - x2));
|
||||
}
|
||||
if(m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
|
||||
}
|
||||
}
|
||||
m_ren->line3(lp, x1 + (y2 - y1), y1 - (x2 - x1), x2 + (y2 - y1), y2 - (x2 - x1));
|
||||
if (m_round_cap)
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
dv.idx = 3;
|
||||
|
||||
case 3: {
|
||||
int x3, y3;
|
||||
int lnext;
|
||||
v = &m_src_vertices[0];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
v = &m_src_vertices[1];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
lnext = v->len;
|
||||
v = &m_src_vertices[2];
|
||||
x3 = v->x;
|
||||
y3 = v->y;
|
||||
line_parameters lp1(x1, y1, x2, y2, lprev);
|
||||
line_parameters lp2(x2, y2, x3, y3, lnext);
|
||||
v = &m_src_vertices[0];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
|
||||
if (m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
|
||||
}
|
||||
v = &m_src_vertices[1];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
dv.lcurr = v->len;
|
||||
line_parameters prev(x1, y1, x2, y2, lprev);
|
||||
|
||||
if (m_line_join == outline_round_join)
|
||||
{
|
||||
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), x2 + (y2 - y1), y2 - (x2 - x1));
|
||||
v = &m_src_vertices[2];
|
||||
dv.x1 = v->x;
|
||||
dv.y1 = v->y;
|
||||
dv.lnext = v->len;
|
||||
dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
|
||||
|
||||
m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1), x2 + (y3 - y2), y2 - (x3 - x2));
|
||||
v = &m_src_vertices[dv.idx];
|
||||
dv.x2 = v->x;
|
||||
dv.y2 = v->y;
|
||||
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
|
||||
|
||||
m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2), x3 + (y3 - y2), y3 - (x3 - x2));
|
||||
}
|
||||
else
|
||||
{
|
||||
bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
|
||||
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), dv.xb1, dv.yb1);
|
||||
dv.xb1 = 0;
|
||||
dv.yb1 = 0;
|
||||
dv.xb2 = 0;
|
||||
dv.yb2 = 0;
|
||||
|
||||
m_ren->line3(lp2, dv.xb1, dv.yb1, x3 + (y3 - y2), y3 - (x3 - x2));
|
||||
}
|
||||
if (m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
dv.idx = 3;
|
||||
|
||||
v = &m_src_vertices[0];
|
||||
x1 = v->x;
|
||||
y1 = v->y;
|
||||
lprev = v->len;
|
||||
|
||||
v = &m_src_vertices[1];
|
||||
x2 = v->x;
|
||||
y2 = v->y;
|
||||
dv.lcurr = v->len;
|
||||
line_parameters prev(x1, y1, x2, y2, lprev);
|
||||
|
||||
v = &m_src_vertices[2];
|
||||
dv.x1 = v->x;
|
||||
dv.y1 = v->y;
|
||||
dv.lnext = v->len;
|
||||
dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
|
||||
|
||||
v = &m_src_vertices[dv.idx];
|
||||
dv.x2 = v->x;
|
||||
dv.y2 = v->y;
|
||||
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
|
||||
|
||||
dv.xb1 = 0;
|
||||
dv.yb1 = 0;
|
||||
dv.xb2 = 0;
|
||||
dv.yb2 = 0;
|
||||
|
||||
switch (m_line_join)
|
||||
{
|
||||
switch(m_line_join)
|
||||
{
|
||||
case outline_no_join:
|
||||
dv.flags = 3;
|
||||
break;
|
||||
|
||||
case outline_miter_join:
|
||||
case outline_round_join:
|
||||
dv.flags = (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
|
||||
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
|
||||
dv.flags =
|
||||
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
|
||||
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
|
||||
break;
|
||||
|
||||
case outline_miter_accurate_join:
|
||||
dv.flags = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
|
||||
}
|
||||
if ((dv.flags & 1) == 0)
|
||||
{
|
||||
if (m_line_join == outline_round_join)
|
||||
if(m_round_cap)
|
||||
{
|
||||
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), x2 + (y2 - y1), y2 - (x2 - x1));
|
||||
m_ren->pie(prev.x2,
|
||||
prev.y2,
|
||||
x2 + (y2 - y1),
|
||||
y2 - (x2 - x1),
|
||||
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1));
|
||||
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
|
||||
}
|
||||
if((dv.flags & 1) == 0)
|
||||
{
|
||||
if(m_line_join == outline_round_join)
|
||||
{
|
||||
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
|
||||
x2 + (y2 - y1), y2 - (x2 - x1));
|
||||
m_ren->pie(prev.x2, prev.y2,
|
||||
x2 + (y2 - y1), y2 - (x2 - x1),
|
||||
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1));
|
||||
}
|
||||
else
|
||||
{
|
||||
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
|
||||
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
|
||||
dv.xb1, dv.yb1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
|
||||
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), dv.xb1, dv.yb1);
|
||||
m_ren->line1(prev,
|
||||
x1 + (y2 - y1),
|
||||
y1 - (x2 - x1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ren->line1(prev, x1 + (y2 - y1), y1 - (x2 - x1));
|
||||
}
|
||||
if ((dv.flags & 2) == 0 && m_line_join != outline_round_join)
|
||||
{
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
}
|
||||
|
||||
draw(dv, 1, m_src_vertices.size() - 2);
|
||||
|
||||
if ((dv.flags & 1) == 0)
|
||||
{
|
||||
if (m_line_join == outline_round_join)
|
||||
if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
|
||||
{
|
||||
m_ren->line3(dv.curr,
|
||||
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1),
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
}
|
||||
|
||||
draw(dv, 1, m_src_vertices.size() - 2);
|
||||
|
||||
if((dv.flags & 1) == 0)
|
||||
{
|
||||
if(m_line_join == outline_round_join)
|
||||
{
|
||||
m_ren->line3(dv.curr,
|
||||
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1),
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ren->line3(dv.curr, dv.xb1, dv.yb1,
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ren->line3(dv.curr,
|
||||
dv.xb1,
|
||||
dv.yb1,
|
||||
m_ren->line2(dv.curr,
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
|
||||
}
|
||||
if(m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ren->line2(dv.curr,
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
|
||||
}
|
||||
if (m_round_cap)
|
||||
{
|
||||
m_ren->semidot(cmp_dist_end,
|
||||
dv.curr.x2,
|
||||
dv.curr.y2,
|
||||
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
|
||||
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_src_vertices.remove_all();
|
||||
}
|
||||
m_src_vertices.remove_all();
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
|
804
deps/agg/include/agg_rasterizer_scanline_aa.h
vendored
804
deps/agg/include/agg_rasterizer_scanline_aa.h
vendored
|
@ -33,445 +33,477 @@
|
|||
#include "agg_rasterizer_sl_clip.h"
|
||||
#include "agg_gamma_functions.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-----------------------------------------------------------------cell_aa
|
||||
// A pixel cell. There're no constructors defined and it was done
|
||||
// intentionally in order to avoid extra overhead when allocating an
|
||||
// array of cells.
|
||||
struct cell_aa
|
||||
namespace agg
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int cover;
|
||||
int area;
|
||||
|
||||
void initial()
|
||||
|
||||
//-----------------------------------------------------------------cell_aa
|
||||
// A pixel cell. There're no constructors defined and it was done
|
||||
// intentionally in order to avoid extra overhead when allocating an
|
||||
// array of cells.
|
||||
struct cell_aa
|
||||
{
|
||||
x = 0x7FFFFFFF;
|
||||
y = 0x7FFFFFFF;
|
||||
cover = 0;
|
||||
area = 0;
|
||||
}
|
||||
int x;
|
||||
int y;
|
||||
int cover;
|
||||
int area;
|
||||
|
||||
void style(const cell_aa&) {}
|
||||
void initial()
|
||||
{
|
||||
x = 0x7FFFFFFF;
|
||||
y = 0x7FFFFFFF;
|
||||
cover = 0;
|
||||
area = 0;
|
||||
}
|
||||
|
||||
int not_equal(int ex, int ey, const cell_aa&) const { return (ex - x) | (ey - y); }
|
||||
};
|
||||
void style(const cell_aa&) {}
|
||||
|
||||
//==================================================rasterizer_scanline_aa
|
||||
// Polygon rasterizer that is used to render filled polygons with
|
||||
// high-quality Anti-Aliasing. Internally, by default, the class uses
|
||||
// integer coordinates in format 24.8, i.e. 24 bits for integer part
|
||||
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
|
||||
// used in the following way:
|
||||
//
|
||||
// 1. filling_rule(filling_rule_e ft) - optional.
|
||||
//
|
||||
// 2. gamma() - optional.
|
||||
//
|
||||
// 3. reset()
|
||||
//
|
||||
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
|
||||
// more than one contour, but each contour must consist of at least 3
|
||||
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
|
||||
// is the absolute minimum of vertices that define a triangle.
|
||||
// The algorithm does not check either the number of vertices nor
|
||||
// coincidence of their coordinates, but in the worst case it just
|
||||
// won't draw anything.
|
||||
// The orger of the vertices (clockwise or counterclockwise)
|
||||
// is important when using the non-zero filling rule (fill_non_zero).
|
||||
// In this case the vertex order of all the contours must be the same
|
||||
// if you want your intersecting polygons to be without "holes".
|
||||
// You actually can use different vertices order. If the contours do not
|
||||
// intersect each other the order is not important anyway. If they do,
|
||||
// contours with the same vertex order will be rendered without "holes"
|
||||
// while the intersecting contours with different orders will have "holes".
|
||||
//
|
||||
// filling_rule() and gamma() can be called anytime before "sweeping".
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip = rasterizer_sl_clip_int>
|
||||
class rasterizer_scanline_aa
|
||||
{
|
||||
enum status { status_initial, status_move_to, status_line_to, status_closed };
|
||||
|
||||
public:
|
||||
typedef Clip clip_type;
|
||||
typedef typename Clip::conv_type conv_type;
|
||||
typedef typename Clip::coord_type coord_type;
|
||||
|
||||
enum aa_scale_e {
|
||||
aa_shift = 8,
|
||||
aa_scale = 1 << aa_shift,
|
||||
aa_mask = aa_scale - 1,
|
||||
aa_scale2 = aa_scale * 2,
|
||||
aa_mask2 = aa_scale2 - 1
|
||||
int not_equal(int ex, int ey, const cell_aa&) const
|
||||
{
|
||||
return (ex - x) | (ey - y);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_scanline_aa()
|
||||
: m_outline()
|
||||
, m_clipper()
|
||||
, m_filling_rule(fill_non_zero)
|
||||
, m_auto_close(true)
|
||||
, m_start_x(0)
|
||||
, m_start_y(0)
|
||||
, m_status(status_initial)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < aa_scale; i++)
|
||||
m_gamma[i] = i;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaF>
|
||||
rasterizer_scanline_aa(const GammaF& gamma_function)
|
||||
: m_outline()
|
||||
, m_clipper(m_outline)
|
||||
, m_filling_rule(fill_non_zero)
|
||||
, m_auto_close(true)
|
||||
, m_start_x(0)
|
||||
, m_start_y(0)
|
||||
, m_status(status_initial)
|
||||
//==================================================rasterizer_scanline_aa
|
||||
// Polygon rasterizer that is used to render filled polygons with
|
||||
// high-quality Anti-Aliasing. Internally, by default, the class uses
|
||||
// integer coordinates in format 24.8, i.e. 24 bits for integer part
|
||||
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
|
||||
// used in the following way:
|
||||
//
|
||||
// 1. filling_rule(filling_rule_e ft) - optional.
|
||||
//
|
||||
// 2. gamma() - optional.
|
||||
//
|
||||
// 3. reset()
|
||||
//
|
||||
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
|
||||
// more than one contour, but each contour must consist of at least 3
|
||||
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
|
||||
// is the absolute minimum of vertices that define a triangle.
|
||||
// The algorithm does not check either the number of vertices nor
|
||||
// coincidence of their coordinates, but in the worst case it just
|
||||
// won't draw anything.
|
||||
// The orger of the vertices (clockwise or counterclockwise)
|
||||
// is important when using the non-zero filling rule (fill_non_zero).
|
||||
// In this case the vertex order of all the contours must be the same
|
||||
// if you want your intersecting polygons to be without "holes".
|
||||
// You actually can use different vertices order. If the contours do not
|
||||
// intersect each other the order is not important anyway. If they do,
|
||||
// contours with the same vertex order will be rendered without "holes"
|
||||
// while the intersecting contours with different orders will have "holes".
|
||||
//
|
||||
// filling_rule() and gamma() can be called anytime before "sweeping".
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
|
||||
{
|
||||
gamma(gamma_function);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset();
|
||||
void reset_clipping();
|
||||
void clip_box(double x1, double y1, double x2, double y2);
|
||||
void filling_rule(filling_rule_e filling_rule);
|
||||
void auto_close(bool flag) { m_auto_close = flag; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaF>
|
||||
void gamma(const GammaF& gamma_function)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < aa_scale; i++)
|
||||
enum status
|
||||
{
|
||||
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
|
||||
status_initial,
|
||||
status_move_to,
|
||||
status_line_to,
|
||||
status_closed
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Clip clip_type;
|
||||
typedef typename Clip::conv_type conv_type;
|
||||
typedef typename Clip::coord_type coord_type;
|
||||
|
||||
enum aa_scale_e
|
||||
{
|
||||
aa_shift = 8,
|
||||
aa_scale = 1 << aa_shift,
|
||||
aa_mask = aa_scale - 1,
|
||||
aa_scale2 = aa_scale * 2,
|
||||
aa_mask2 = aa_scale2 - 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_scanline_aa() :
|
||||
m_outline(),
|
||||
m_clipper(),
|
||||
m_filling_rule(fill_non_zero),
|
||||
m_auto_close(true),
|
||||
m_start_x(0),
|
||||
m_start_y(0),
|
||||
m_status(status_initial)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < aa_scale; i++) m_gamma[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned apply_gamma(unsigned cover) const { return m_gamma[cover]; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y);
|
||||
void line_to(int x, int y);
|
||||
void move_to_d(double x, double y);
|
||||
void line_to_d(double x, double y);
|
||||
void close_polygon();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
void edge(int x1, int y1, int x2, int y2);
|
||||
void edge_d(double x1, double y1, double x2, double y2);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id = 0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
if (m_outline.sorted())
|
||||
reset();
|
||||
while (!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaF>
|
||||
rasterizer_scanline_aa(const GammaF& gamma_function) :
|
||||
m_outline(),
|
||||
m_clipper(m_outline),
|
||||
m_filling_rule(fill_non_zero),
|
||||
m_auto_close(true),
|
||||
m_start_x(0),
|
||||
m_start_y(0),
|
||||
m_status(status_initial)
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
gamma(gamma_function);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int min_x() const { return m_outline.min_x(); }
|
||||
int min_y() const { return m_outline.min_y(); }
|
||||
int max_x() const { return m_outline.max_x(); }
|
||||
int max_y() const { return m_outline.max_y(); }
|
||||
//--------------------------------------------------------------------
|
||||
void reset();
|
||||
void reset_clipping();
|
||||
void clip_box(double x1, double y1, double x2, double y2);
|
||||
void filling_rule(filling_rule_e filling_rule);
|
||||
void auto_close(bool flag) { m_auto_close = flag; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void sort();
|
||||
bool rewind_scanlines();
|
||||
bool navigate_scanline(int y);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned calculate_alpha(int area) const
|
||||
{
|
||||
int cover = area >> (poly_subpixel_shift * 2 + 1 - aa_shift);
|
||||
|
||||
if (cover < 0)
|
||||
cover = -cover;
|
||||
if (m_filling_rule == fill_even_odd)
|
||||
//--------------------------------------------------------------------
|
||||
template<class GammaF> void gamma(const GammaF& gamma_function)
|
||||
{
|
||||
cover &= aa_mask2;
|
||||
if (cover > aa_scale)
|
||||
int i;
|
||||
for(i = 0; i < aa_scale; i++)
|
||||
{
|
||||
cover = aa_scale2 - cover;
|
||||
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
|
||||
}
|
||||
}
|
||||
if (cover > aa_mask)
|
||||
cover = aa_mask;
|
||||
return m_gamma[cover];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline>
|
||||
bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
for (;;)
|
||||
//--------------------------------------------------------------------
|
||||
unsigned apply_gamma(unsigned cover) const
|
||||
{
|
||||
if (m_scan_y > m_outline.max_y())
|
||||
return false;
|
||||
sl.reset_spans();
|
||||
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
|
||||
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
|
||||
unsigned cover = 0;
|
||||
return m_gamma[cover];
|
||||
}
|
||||
|
||||
while (num_cells)
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y);
|
||||
void line_to(int x, int y);
|
||||
void move_to_d(double x, double y);
|
||||
void line_to_d(double x, double y);
|
||||
void close_polygon();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
void edge(int x1, int y1, int x2, int y2);
|
||||
void edge_d(double x1, double y1, double x2, double y2);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
void add_path(VertexSource& vs, unsigned path_id=0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
if(m_outline.sorted()) reset();
|
||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
const cell_aa* cur_cell = *cells;
|
||||
int x = cur_cell->x;
|
||||
int area = cur_cell->area;
|
||||
unsigned alpha;
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
cover += cur_cell->cover;
|
||||
//--------------------------------------------------------------------
|
||||
int min_x() const { return m_outline.min_x(); }
|
||||
int min_y() const { return m_outline.min_y(); }
|
||||
int max_x() const { return m_outline.max_x(); }
|
||||
int max_y() const { return m_outline.max_y(); }
|
||||
|
||||
// accumulate all cells with the same X
|
||||
while (--num_cells)
|
||||
//--------------------------------------------------------------------
|
||||
void sort();
|
||||
bool rewind_scanlines();
|
||||
bool navigate_scanline(int y);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE unsigned calculate_alpha(int area) const
|
||||
{
|
||||
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
|
||||
|
||||
if(cover < 0) cover = -cover;
|
||||
if(m_filling_rule == fill_even_odd)
|
||||
{
|
||||
cover &= aa_mask2;
|
||||
if(cover > aa_scale)
|
||||
{
|
||||
cur_cell = *++cells;
|
||||
if (cur_cell->x != x)
|
||||
break;
|
||||
area += cur_cell->area;
|
||||
cover = aa_scale2 - cover;
|
||||
}
|
||||
}
|
||||
if(cover > aa_mask) cover = aa_mask;
|
||||
return m_gamma[cover];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(m_scan_y > m_outline.max_y()) return false;
|
||||
sl.reset_spans();
|
||||
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
|
||||
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
|
||||
unsigned cover = 0;
|
||||
|
||||
while(num_cells)
|
||||
{
|
||||
const cell_aa* cur_cell = *cells;
|
||||
int x = cur_cell->x;
|
||||
int area = cur_cell->area;
|
||||
unsigned alpha;
|
||||
|
||||
cover += cur_cell->cover;
|
||||
}
|
||||
|
||||
if (area)
|
||||
{
|
||||
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
|
||||
if (alpha)
|
||||
//accumulate all cells with the same X
|
||||
while(--num_cells)
|
||||
{
|
||||
sl.add_cell(x, alpha);
|
||||
cur_cell = *++cells;
|
||||
if(cur_cell->x != x) break;
|
||||
area += cur_cell->area;
|
||||
cover += cur_cell->cover;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
if (num_cells && cur_cell->x > x)
|
||||
{
|
||||
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
|
||||
if (alpha)
|
||||
if(area)
|
||||
{
|
||||
sl.add_span(x, cur_cell->x - x, alpha);
|
||||
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
|
||||
if(alpha)
|
||||
{
|
||||
sl.add_cell(x, alpha);
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
if(num_cells && cur_cell->x > x)
|
||||
{
|
||||
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
|
||||
if(alpha)
|
||||
{
|
||||
sl.add_span(x, cur_cell->x - x, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(sl.num_spans()) break;
|
||||
++m_scan_y;
|
||||
}
|
||||
|
||||
if (sl.num_spans())
|
||||
break;
|
||||
sl.finalize(m_scan_y);
|
||||
++m_scan_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
sl.finalize(m_scan_y);
|
||||
++m_scan_y;
|
||||
//--------------------------------------------------------------------
|
||||
bool hit_test(int tx, int ty);
|
||||
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
// Disable copying
|
||||
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
|
||||
const rasterizer_scanline_aa<Clip>&
|
||||
operator = (const rasterizer_scanline_aa<Clip>&);
|
||||
|
||||
private:
|
||||
rasterizer_cells_aa<cell_aa> m_outline;
|
||||
clip_type m_clipper;
|
||||
int m_gamma[aa_scale];
|
||||
filling_rule_e m_filling_rule;
|
||||
bool m_auto_close;
|
||||
coord_type m_start_x;
|
||||
coord_type m_start_y;
|
||||
unsigned m_status;
|
||||
int m_scan_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::reset()
|
||||
{
|
||||
m_outline.reset();
|
||||
m_status = status_initial;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
|
||||
{
|
||||
m_filling_rule = filling_rule;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
reset();
|
||||
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
|
||||
conv_type::upscale(x2), conv_type::upscale(y2));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::reset_clipping()
|
||||
{
|
||||
reset();
|
||||
m_clipper.reset_clipping();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::close_polygon()
|
||||
{
|
||||
if(m_status == status_line_to)
|
||||
{
|
||||
m_clipper.line_to(m_outline, m_start_x, m_start_y);
|
||||
m_status = status_closed;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
if(m_auto_close) close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::downscale(x),
|
||||
m_start_y = conv_type::downscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::downscale(x),
|
||||
conv_type::downscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
if(m_auto_close) close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::upscale(x),
|
||||
m_start_y = conv_type::upscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::upscale(x),
|
||||
conv_type::upscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
move_to_d(x, y);
|
||||
}
|
||||
else
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
line_to_d(x, y);
|
||||
}
|
||||
else
|
||||
if(is_close(cmd))
|
||||
{
|
||||
close_polygon();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::downscale(x2),
|
||||
conv_type::downscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::upscale(x2),
|
||||
conv_type::upscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::sort()
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
|
||||
{
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = m_outline.min_y();
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool hit_test(int tx, int ty);
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
// Disable copying
|
||||
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
|
||||
const rasterizer_scanline_aa<Clip>& operator=(const rasterizer_scanline_aa<Clip>&);
|
||||
|
||||
private:
|
||||
rasterizer_cells_aa<cell_aa> m_outline;
|
||||
clip_type m_clipper;
|
||||
int m_gamma[aa_scale];
|
||||
filling_rule_e m_filling_rule;
|
||||
bool m_auto_close;
|
||||
coord_type m_start_x;
|
||||
coord_type m_start_y;
|
||||
unsigned m_status;
|
||||
int m_scan_y;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::reset()
|
||||
{
|
||||
m_outline.reset();
|
||||
m_status = status_initial;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
|
||||
{
|
||||
m_filling_rule = filling_rule;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
reset();
|
||||
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1), conv_type::upscale(x2), conv_type::upscale(y2));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::reset_clipping()
|
||||
{
|
||||
reset();
|
||||
m_clipper.reset_clipping();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::close_polygon()
|
||||
{
|
||||
if (m_status == status_line_to)
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
|
||||
{
|
||||
m_clipper.line_to(m_outline, m_start_x, m_start_y);
|
||||
m_status = status_closed;
|
||||
if(m_auto_close) close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0 ||
|
||||
y < m_outline.min_y() ||
|
||||
y > m_outline.max_y())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
|
||||
{
|
||||
if (m_outline.sorted())
|
||||
reset();
|
||||
if (m_auto_close)
|
||||
close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::downscale(x), m_start_y = conv_type::downscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
|
||||
{
|
||||
m_clipper.line_to(m_outline, conv_type::downscale(x), conv_type::downscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
|
||||
{
|
||||
if (m_outline.sorted())
|
||||
reset();
|
||||
if (m_auto_close)
|
||||
close_polygon();
|
||||
m_clipper.move_to(m_start_x = conv_type::upscale(x), m_start_y = conv_type::upscale(y));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
|
||||
{
|
||||
m_clipper.line_to(m_outline, conv_type::upscale(x), conv_type::upscale(y));
|
||||
m_status = status_line_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if (is_move_to(cmd))
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
|
||||
{
|
||||
move_to_d(x, y);
|
||||
}
|
||||
else if (is_vertex(cmd))
|
||||
{
|
||||
line_to_d(x, y);
|
||||
}
|
||||
else if (is_close(cmd))
|
||||
{
|
||||
close_polygon();
|
||||
if(!navigate_scanline(ty)) return false;
|
||||
scanline_hit_test sl(tx);
|
||||
sweep_scanline(sl);
|
||||
return sl.hit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
if (m_outline.sorted())
|
||||
reset();
|
||||
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
|
||||
m_clipper.line_to(m_outline, conv_type::downscale(x2), conv_type::downscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
if (m_outline.sorted())
|
||||
reset();
|
||||
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
|
||||
m_clipper.line_to(m_outline, conv_type::upscale(x2), conv_type::upscale(y2));
|
||||
m_status = status_move_to;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_scanline_aa<Clip>::sort()
|
||||
{
|
||||
if (m_auto_close)
|
||||
close_polygon();
|
||||
m_outline.sort_cells();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
|
||||
{
|
||||
if (m_auto_close)
|
||||
close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if (m_outline.total_cells() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = m_outline.min_y();
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
|
||||
{
|
||||
if (m_auto_close)
|
||||
close_polygon();
|
||||
m_outline.sort_cells();
|
||||
if (m_outline.total_cells() == 0 || y < m_outline.min_y() || y > m_outline.max_y())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
|
||||
{
|
||||
if (!navigate_scanline(ty))
|
||||
return false;
|
||||
scanline_hit_test sl(tx);
|
||||
sweep_scanline(sl);
|
||||
return sl.hit();
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
491
deps/agg/include/agg_rasterizer_sl_clip.h
vendored
491
deps/agg/include/agg_rasterizer_sl_clip.h
vendored
|
@ -17,201 +17,226 @@
|
|||
|
||||
#include "agg_clip_liang_barsky.h"
|
||||
|
||||
namespace agg {
|
||||
//--------------------------------------------------------poly_max_coord_e
|
||||
enum poly_max_coord_e {
|
||||
poly_max_coord = (1 << 30) - 1 //----poly_max_coord
|
||||
};
|
||||
|
||||
//------------------------------------------------------------ras_conv_int
|
||||
struct ras_conv_int
|
||||
namespace agg
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c) { return iround(a * b / c); }
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------ras_conv_int_sat
|
||||
struct ras_conv_int_sat
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
//--------------------------------------------------------poly_max_coord_e
|
||||
enum poly_max_coord_e
|
||||
{
|
||||
return saturation<poly_max_coord>::iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return saturation<poly_max_coord>::iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
poly_max_coord = (1 << 30) - 1 //----poly_max_coord
|
||||
};
|
||||
|
||||
//---------------------------------------------------------ras_conv_int_3x
|
||||
struct ras_conv_int_3x
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c) { return iround(a * b / c); }
|
||||
static int xi(int v) { return v * 3; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------ras_conv_dbl
|
||||
struct ras_conv_dbl
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c) { return a * b / c; }
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------ras_conv_dbl_3x
|
||||
struct ras_conv_dbl_3x
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c) { return a * b / c; }
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------rasterizer_sl_clip
|
||||
template<class Conv>
|
||||
class rasterizer_sl_clip
|
||||
{
|
||||
public:
|
||||
typedef Conv conv_type;
|
||||
typedef typename Conv::coord_type coord_type;
|
||||
typedef rect_base<coord_type> rect_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_sl_clip()
|
||||
: m_clip_box(0, 0, 0, 0)
|
||||
, m_x1(0)
|
||||
, m_y1(0)
|
||||
, m_f1(0)
|
||||
, m_clipping(false)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping() { m_clipping = false; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
|
||||
//------------------------------------------------------------ras_conv_int
|
||||
struct ras_conv_int
|
||||
{
|
||||
m_clip_box = rect_type(x1, y1, x2, y2);
|
||||
m_clip_box.normalize();
|
||||
m_clipping = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(coord_type x1, coord_type y1)
|
||||
{
|
||||
m_x1 = x1;
|
||||
m_y1 = y1;
|
||||
if (m_clipping)
|
||||
m_f1 = clipping_flags(x1, y1, m_clip_box);
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
AGG_INLINE void
|
||||
line_clip_y(Rasterizer& ras, coord_type x1, coord_type y1, coord_type x2, coord_type y2, unsigned f1, unsigned f2)
|
||||
const
|
||||
{
|
||||
f1 &= 10;
|
||||
f2 &= 10;
|
||||
if ((f1 | f2) == 0)
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
// Fully visible
|
||||
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
|
||||
return iround(a * b / c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (f1 == f2)
|
||||
{
|
||||
// Invisible by Y
|
||||
return;
|
||||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
coord_type tx1 = x1;
|
||||
coord_type ty1 = y1;
|
||||
coord_type tx2 = x2;
|
||||
coord_type ty2 = y2;
|
||||
|
||||
if (f1 & 8) // y1 < clip.y1
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y1 - y1, x2 - x1, y2 - y1);
|
||||
ty1 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if (f1 & 2) // y1 > clip.y2
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y2 - y1, x2 - x1, y2 - y1);
|
||||
ty1 = m_clip_box.y2;
|
||||
}
|
||||
|
||||
if (f2 & 8) // y2 < clip.y1
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y1 - y1, x2 - x1, y2 - y1);
|
||||
ty2 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if (f2 & 2) // y2 > clip.y2
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y2 - y1, x2 - x1, y2 - y1);
|
||||
ty2 = m_clip_box.y2;
|
||||
}
|
||||
ras.line(Conv::xi(tx1), Conv::yi(ty1), Conv::xi(tx2), Conv::yi(ty2));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
//--------------------------------------------------------ras_conv_int_sat
|
||||
struct ras_conv_int_sat
|
||||
{
|
||||
if (m_clipping)
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
unsigned f2 = clipping_flags(x2, y2, m_clip_box);
|
||||
return saturation<poly_max_coord>::iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v)
|
||||
{
|
||||
return saturation<poly_max_coord>::iround(v * poly_subpixel_scale);
|
||||
}
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
if ((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
|
||||
//---------------------------------------------------------ras_conv_int_3x
|
||||
struct ras_conv_int_3x
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
return iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v * 3; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------ras_conv_dbl
|
||||
struct ras_conv_dbl
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c)
|
||||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------ras_conv_dbl_3x
|
||||
struct ras_conv_dbl_3x
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c)
|
||||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------rasterizer_sl_clip
|
||||
template<class Conv> class rasterizer_sl_clip
|
||||
{
|
||||
public:
|
||||
typedef Conv conv_type;
|
||||
typedef typename Conv::coord_type coord_type;
|
||||
typedef rect_base<coord_type> rect_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_sl_clip() :
|
||||
m_clip_box(0,0,0,0),
|
||||
m_x1(0),
|
||||
m_y1(0),
|
||||
m_f1(0),
|
||||
m_clipping(false)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping()
|
||||
{
|
||||
m_clipping = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
|
||||
{
|
||||
m_clip_box = rect_type(x1, y1, x2, y2);
|
||||
m_clip_box.normalize();
|
||||
m_clipping = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(coord_type x1, coord_type y1)
|
||||
{
|
||||
m_x1 = x1;
|
||||
m_y1 = y1;
|
||||
if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box);
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
AGG_INLINE void line_clip_y(Rasterizer& ras,
|
||||
coord_type x1, coord_type y1,
|
||||
coord_type x2, coord_type y2,
|
||||
unsigned f1, unsigned f2) const
|
||||
{
|
||||
f1 &= 10;
|
||||
f2 &= 10;
|
||||
if((f1 | f2) == 0)
|
||||
{
|
||||
// Invisible by Y
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
m_f1 = f2;
|
||||
return;
|
||||
// Fully visible
|
||||
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
|
||||
}
|
||||
|
||||
coord_type x1 = m_x1;
|
||||
coord_type y1 = m_y1;
|
||||
unsigned f1 = m_f1;
|
||||
coord_type y3, y4;
|
||||
unsigned f3, f4;
|
||||
|
||||
switch (((f1 & 5) << 1) | (f2 & 5))
|
||||
else
|
||||
{
|
||||
if(f1 == f2)
|
||||
{
|
||||
// Invisible by Y
|
||||
return;
|
||||
}
|
||||
|
||||
coord_type tx1 = x1;
|
||||
coord_type ty1 = y1;
|
||||
coord_type tx2 = x2;
|
||||
coord_type ty2 = y2;
|
||||
|
||||
if(f1 & 8) // y1 < clip.y1
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
|
||||
ty1 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if(f1 & 2) // y1 > clip.y2
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
|
||||
ty1 = m_clip_box.y2;
|
||||
}
|
||||
|
||||
if(f2 & 8) // y2 < clip.y1
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
|
||||
ty2 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if(f2 & 2) // y2 > clip.y2
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
|
||||
ty2 = m_clip_box.y2;
|
||||
}
|
||||
ras.line(Conv::xi(tx1), Conv::yi(ty1),
|
||||
Conv::xi(tx2), Conv::yi(ty2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
{
|
||||
if(m_clipping)
|
||||
{
|
||||
unsigned f2 = clipping_flags(x2, y2, m_clip_box);
|
||||
|
||||
if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
|
||||
{
|
||||
// Invisible by Y
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
m_f1 = f2;
|
||||
return;
|
||||
}
|
||||
|
||||
coord_type x1 = m_x1;
|
||||
coord_type y1 = m_y1;
|
||||
unsigned f1 = m_f1;
|
||||
coord_type y3, y4;
|
||||
unsigned f3, f4;
|
||||
|
||||
switch(((f1 & 5) << 1) | (f2 & 5))
|
||||
{
|
||||
case 0: // Visible by X
|
||||
line_clip_y(ras, x1, y1, x2, y2, f1, f2);
|
||||
break;
|
||||
|
||||
case 1: // x2 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2 - x1, y2 - y1, x2 - x1);
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 2: // x1 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2 - x1, y2 - y1, x2 - x1);
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
|
||||
|
@ -222,15 +247,15 @@ class rasterizer_sl_clip
|
|||
break;
|
||||
|
||||
case 4: // x2 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1 - x1, y2 - y1, x2 - x1);
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 6: // x1 > clip.x2 && x2 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2 - x1, y2 - y1, x2 - x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x1 - x1, y2 - y1, x2 - x1);
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
f4 = clipping_flags_y(y4, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
|
||||
|
@ -239,15 +264,15 @@ class rasterizer_sl_clip
|
|||
break;
|
||||
|
||||
case 8: // x1 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1 - x1, y2 - y1, x2 - x1);
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 9: // x1 < clip.x1 && x2 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1 - x1, y2 - y1, x2 - x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x2 - x1, y2 - y1, x2 - x1);
|
||||
case 9: // x1 < clip.x1 && x2 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
f4 = clipping_flags_y(y4, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
|
@ -258,69 +283,69 @@ class rasterizer_sl_clip
|
|||
case 12: // x1 < clip.x1 && x2 < clip.x1
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
|
||||
break;
|
||||
}
|
||||
m_f1 = f2;
|
||||
}
|
||||
m_f1 = f2;
|
||||
else
|
||||
{
|
||||
ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
|
||||
Conv::xi(x2), Conv::yi(y2));
|
||||
}
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
private:
|
||||
rect_type m_clip_box;
|
||||
coord_type m_x1;
|
||||
coord_type m_y1;
|
||||
unsigned m_f1;
|
||||
bool m_clipping;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------rasterizer_sl_no_clip
|
||||
class rasterizer_sl_no_clip
|
||||
{
|
||||
public:
|
||||
typedef ras_conv_int conv_type;
|
||||
typedef int coord_type;
|
||||
|
||||
rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
|
||||
|
||||
void reset_clipping() {}
|
||||
void clip_box(coord_type /*x1*/, coord_type /*y1*/, coord_type /*x2*/, coord_type /*y2*/) {}
|
||||
void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
|
||||
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
{
|
||||
ras.line(Conv::xi(m_x1), Conv::yi(m_y1), Conv::xi(x2), Conv::yi(y2));
|
||||
ras.line(m_x1, m_y1, x2, y2);
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
|
||||
private:
|
||||
rect_type m_clip_box;
|
||||
coord_type m_x1;
|
||||
coord_type m_y1;
|
||||
unsigned m_f1;
|
||||
bool m_clipping;
|
||||
};
|
||||
private:
|
||||
int m_x1, m_y1;
|
||||
};
|
||||
|
||||
//---------------------------------------------------rasterizer_sl_no_clip
|
||||
class rasterizer_sl_no_clip
|
||||
{
|
||||
public:
|
||||
typedef ras_conv_int conv_type;
|
||||
typedef int coord_type;
|
||||
|
||||
rasterizer_sl_no_clip()
|
||||
: m_x1(0)
|
||||
, m_y1(0)
|
||||
{}
|
||||
// -----rasterizer_sl_clip_int
|
||||
// -----rasterizer_sl_clip_int_sat
|
||||
// -----rasterizer_sl_clip_int_3x
|
||||
// -----rasterizer_sl_clip_dbl
|
||||
// -----rasterizer_sl_clip_dbl_3x
|
||||
//------------------------------------------------------------------------
|
||||
typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
|
||||
|
||||
void reset_clipping() {}
|
||||
void clip_box(coord_type /*x1*/, coord_type /*y1*/, coord_type /*x2*/, coord_type /*y2*/) {}
|
||||
void move_to(coord_type x1, coord_type y1)
|
||||
{
|
||||
m_x1 = x1;
|
||||
m_y1 = y1;
|
||||
}
|
||||
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
{
|
||||
ras.line(m_x1, m_y1, x2, y2);
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_x1, m_y1;
|
||||
};
|
||||
|
||||
// -----rasterizer_sl_clip_int
|
||||
// -----rasterizer_sl_clip_int_sat
|
||||
// -----rasterizer_sl_clip_int_3x
|
||||
// -----rasterizer_sl_clip_dbl
|
||||
// -----rasterizer_sl_clip_dbl_3x
|
||||
//------------------------------------------------------------------------
|
||||
typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
1367
deps/agg/include/agg_renderer_base.h
vendored
1367
deps/agg/include/agg_renderer_base.h
vendored
File diff suppressed because it is too large
Load diff
1882
deps/agg/include/agg_renderer_markers.h
vendored
1882
deps/agg/include/agg_renderer_markers.h
vendored
File diff suppressed because it is too large
Load diff
513
deps/agg/include/agg_renderer_mclip.h
vendored
513
deps/agg/include/agg_renderer_mclip.h
vendored
|
@ -24,303 +24,326 @@
|
|||
#include "agg_array.h"
|
||||
#include "agg_renderer_base.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//----------------------------------------------------------renderer_mclip
|
||||
template<class PixelFormat>
|
||||
class renderer_mclip
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef PixelFormat pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
typedef renderer_base<pixfmt_type> base_ren_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
explicit renderer_mclip(pixfmt_type& pixf)
|
||||
: m_ren(pixf)
|
||||
, m_curr_cb(0)
|
||||
, m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
|
||||
{}
|
||||
void attach(pixfmt_type& pixf)
|
||||
//----------------------------------------------------------renderer_mclip
|
||||
template<class PixelFormat> class renderer_mclip
|
||||
{
|
||||
m_ren.attach(pixf);
|
||||
reset_clipping(true);
|
||||
}
|
||||
public:
|
||||
typedef PixelFormat pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
typedef renderer_base<pixfmt_type> base_ren_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const pixfmt_type& ren() const { return m_ren.ren(); }
|
||||
pixfmt_type& ren() { return m_ren.ren(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_ren.width(); }
|
||||
unsigned height() const { return m_ren.height(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& clip_box() const { return m_ren.clip_box(); }
|
||||
int xmin() const { return m_ren.xmin(); }
|
||||
int ymin() const { return m_ren.ymin(); }
|
||||
int xmax() const { return m_ren.xmax(); }
|
||||
int ymax() const { return m_ren.ymax(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& bounding_clip_box() const { return m_bounds; }
|
||||
int bounding_xmin() const { return m_bounds.x1; }
|
||||
int bounding_ymin() const { return m_bounds.y1; }
|
||||
int bounding_xmax() const { return m_bounds.x2; }
|
||||
int bounding_ymax() const { return m_bounds.y2; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void first_clip_box()
|
||||
{
|
||||
m_curr_cb = 0;
|
||||
if (m_clip.size())
|
||||
//--------------------------------------------------------------------
|
||||
explicit renderer_mclip(pixfmt_type& pixf) :
|
||||
m_ren(pixf),
|
||||
m_curr_cb(0),
|
||||
m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
|
||||
{}
|
||||
void attach(pixfmt_type& pixf)
|
||||
{
|
||||
const rect_i& cb = m_clip[0];
|
||||
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
||||
m_ren.attach(pixf);
|
||||
reset_clipping(true);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool next_clip_box()
|
||||
{
|
||||
if (++m_curr_cb < m_clip.size())
|
||||
//--------------------------------------------------------------------
|
||||
const pixfmt_type& ren() const { return m_ren.ren(); }
|
||||
pixfmt_type& ren() { return m_ren.ren(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_ren.width(); }
|
||||
unsigned height() const { return m_ren.height(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& clip_box() const { return m_ren.clip_box(); }
|
||||
int xmin() const { return m_ren.xmin(); }
|
||||
int ymin() const { return m_ren.ymin(); }
|
||||
int xmax() const { return m_ren.xmax(); }
|
||||
int ymax() const { return m_ren.ymax(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& bounding_clip_box() const { return m_bounds; }
|
||||
int bounding_xmin() const { return m_bounds.x1; }
|
||||
int bounding_ymin() const { return m_bounds.y1; }
|
||||
int bounding_xmax() const { return m_bounds.x2; }
|
||||
int bounding_ymax() const { return m_bounds.y2; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void first_clip_box()
|
||||
{
|
||||
const rect_i& cb = m_clip[m_curr_cb];
|
||||
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
||||
return true;
|
||||
m_curr_cb = 0;
|
||||
if(m_clip.size())
|
||||
{
|
||||
const rect_i& cb = m_clip[0];
|
||||
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping(bool visibility)
|
||||
{
|
||||
m_ren.reset_clipping(visibility);
|
||||
m_clip.remove_all();
|
||||
m_curr_cb = 0;
|
||||
m_bounds = m_ren.clip_box();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_clip_box(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rect_i cb(x1, y1, x2, y2);
|
||||
cb.normalize();
|
||||
if (cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
|
||||
//--------------------------------------------------------------------
|
||||
bool next_clip_box()
|
||||
{
|
||||
m_clip.add(cb);
|
||||
if (cb.x1 < m_bounds.x1)
|
||||
m_bounds.x1 = cb.x1;
|
||||
if (cb.y1 < m_bounds.y1)
|
||||
m_bounds.y1 = cb.y1;
|
||||
if (cb.x2 > m_bounds.x2)
|
||||
m_bounds.x2 = cb.x2;
|
||||
if (cb.y2 > m_bounds.y2)
|
||||
m_bounds.y2 = cb.y2;
|
||||
if(++m_curr_cb < m_clip.size())
|
||||
{
|
||||
const rect_i& cb = m_clip[m_curr_cb];
|
||||
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(const color_type& c) { m_ren.clear(c); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping(bool visibility)
|
||||
{
|
||||
if (m_ren.inbox(x, y))
|
||||
m_ren.reset_clipping(visibility);
|
||||
m_clip.remove_all();
|
||||
m_curr_cb = 0;
|
||||
m_bounds = m_ren.clip_box();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_clip_box(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rect_i cb(x1, y1, x2, y2);
|
||||
cb.normalize();
|
||||
if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
|
||||
{
|
||||
m_ren.ren().copy_pixel(x, y, c);
|
||||
break;
|
||||
m_clip.add(cb);
|
||||
if(cb.x1 < m_bounds.x1) m_bounds.x1 = cb.x1;
|
||||
if(cb.y1 < m_bounds.y1) m_bounds.y1 = cb.y1;
|
||||
if(cb.x2 > m_bounds.x2) m_bounds.x2 = cb.x2;
|
||||
if(cb.y2 > m_bounds.y2) m_bounds.y2 = cb.y2;
|
||||
}
|
||||
} while (next_clip_box());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void clear(const color_type& c)
|
||||
{
|
||||
if (m_ren.inbox(x, y))
|
||||
m_ren.clear(c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.ren().blend_pixel(x, y, c, cover);
|
||||
break;
|
||||
if(m_ren.inbox(x, y))
|
||||
{
|
||||
m_ren.ren().copy_pixel(x, y, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (next_clip_box());
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_type pixel(int x, int y) const
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||
{
|
||||
if (m_ren.inbox(x, y))
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
return m_ren.ren().pixel(x, y);
|
||||
if(m_ren.inbox(x, y))
|
||||
{
|
||||
m_ren.ren().blend_pixel(x, y, c, cover);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (next_clip_box());
|
||||
return color_type::no_color();
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_hline(int x1, int y, int x2, const color_type& c)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
color_type pixel(int x, int y) const
|
||||
{
|
||||
m_ren.copy_hline(x1, y, x2, c);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
if(m_ren.inbox(x, y))
|
||||
{
|
||||
return m_ren.ren().pixel(x, y);
|
||||
}
|
||||
}
|
||||
while(next_clip_box());
|
||||
return color_type::no_color();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_vline(int x, int y1, int y2, const color_type& c)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void copy_hline(int x1, int y, int x2, const color_type& c)
|
||||
{
|
||||
m_ren.copy_vline(x, y1, y2, c);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.copy_hline(x1, y, x2, c);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x1, int y, int x2, const color_type& c, cover_type cover)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void copy_vline(int x, int y1, int y2, const color_type& c)
|
||||
{
|
||||
m_ren.blend_hline(x1, y, x2, c, cover);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.copy_vline(x, y1, y2, c);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y1, int y2, const color_type& c, cover_type cover)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x1, int y, int x2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
m_ren.blend_vline(x, y1, y2, c, cover);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_hline(x1, y, x2, c, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y1, int y2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
m_ren.copy_bar(x1, y1, x2, y2, c);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_vline(x, y1, y2, c, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_bar(int x1, int y1, int x2, int y2, const color_type& c, cover_type cover)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
|
||||
{
|
||||
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.copy_bar(x1, y1, x2, y2, c);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y, int len, const color_type& c, const cover_type* covers)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_bar(int x1, int y1, int x2, int y2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
m_ren.blend_solid_hspan(x, y, len, c, covers);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y, int len, const color_type& c, const cover_type* covers)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y, int len,
|
||||
const color_type& c, const cover_type* covers)
|
||||
{
|
||||
m_ren.blend_solid_vspan(x, y, len, c, covers);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_solid_hspan(x, y, len, c, covers);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y, int len, const color_type* colors)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y, int len,
|
||||
const color_type& c, const cover_type* covers)
|
||||
{
|
||||
m_ren.copy_color_hspan(x, y, len, colors);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_solid_vspan(x, y, len, c, covers);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x,
|
||||
int y,
|
||||
int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y, int len, const color_type* colors)
|
||||
{
|
||||
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.copy_color_hspan(x, y, len, colors);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x,
|
||||
int y,
|
||||
int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x, int y, int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
m_ren.blend_color_vspan(x, y, len, colors, covers, cover);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_from(const rendering_buffer& from, const rect_i* rc = 0, int x_to = 0, int y_to = 0)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x, int y, int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
m_ren.copy_from(from, rc, x_to, y_to);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_color_vspan(x, y, len, colors, covers, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from(const SrcPixelFormatRenderer& src,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
void copy_from(const rendering_buffer& from,
|
||||
const rect_i* rc=0,
|
||||
int x_to=0,
|
||||
int y_to=0)
|
||||
{
|
||||
m_ren.blend_from(src, rect_src_ptr, dx, dy, cover);
|
||||
} while (next_clip_box());
|
||||
}
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.copy_from(from, rc, x_to, y_to);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
private:
|
||||
renderer_mclip(const renderer_mclip<PixelFormat>&);
|
||||
const renderer_mclip<PixelFormat>& operator=(const renderer_mclip<PixelFormat>&);
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from(const SrcPixelFormatRenderer& src,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = cover_full)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_from(src, rect_src_ptr, dx, dy, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
base_ren_type m_ren;
|
||||
pod_bvector<rect_i, 4> m_clip;
|
||||
unsigned m_curr_cb;
|
||||
rect_i m_bounds;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
private:
|
||||
renderer_mclip(const renderer_mclip<PixelFormat>&);
|
||||
const renderer_mclip<PixelFormat>&
|
||||
operator = (const renderer_mclip<PixelFormat>&);
|
||||
|
||||
base_ren_type m_ren;
|
||||
pod_bvector<rect_i, 4> m_clip;
|
||||
unsigned m_curr_cb;
|
||||
rect_i m_bounds;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
3482
deps/agg/include/agg_renderer_outline_aa.h
vendored
3482
deps/agg/include/agg_renderer_outline_aa.h
vendored
File diff suppressed because it is too large
Load diff
1804
deps/agg/include/agg_renderer_outline_image.h
vendored
1804
deps/agg/include/agg_renderer_outline_image.h
vendored
File diff suppressed because it is too large
Load diff
336
deps/agg/include/agg_renderer_primitives.h
vendored
336
deps/agg/include/agg_renderer_primitives.h
vendored
|
@ -25,190 +25,200 @@
|
|||
#include "agg_dda_line.h"
|
||||
#include "agg_ellipse_bresenham.h"
|
||||
|
||||
namespace agg {
|
||||
//-----------------------------------------------------renderer_primitives
|
||||
template<class BaseRenderer>
|
||||
class renderer_primitives
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef BaseRenderer base_ren_type;
|
||||
typedef typename base_ren_type::color_type color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
explicit renderer_primitives(base_ren_type& ren)
|
||||
: m_ren(&ren)
|
||||
, m_fill_color()
|
||||
, m_line_color()
|
||||
, m_curr_x(0)
|
||||
, m_curr_y(0)
|
||||
{}
|
||||
void attach(base_ren_type& ren) { m_ren = &ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static int coord(double c) { return iround(c * line_bresenham_interpolator::subpixel_scale); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void fill_color(const color_type& c) { m_fill_color = c; }
|
||||
void line_color(const color_type& c) { m_line_color = c; }
|
||||
const color_type& fill_color() const { return m_fill_color; }
|
||||
const color_type& line_color() const { return m_line_color; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rectangle(int x1, int y1, int x2, int y2)
|
||||
//-----------------------------------------------------renderer_primitives
|
||||
template<class BaseRenderer> class renderer_primitives
|
||||
{
|
||||
m_ren->blend_hline(x1, y1, x2 - 1, m_line_color, cover_full);
|
||||
m_ren->blend_vline(x2, y1, y2 - 1, m_line_color, cover_full);
|
||||
m_ren->blend_hline(x1 + 1, y2, x2, m_line_color, cover_full);
|
||||
m_ren->blend_vline(x1, y1 + 1, y2, m_line_color, cover_full);
|
||||
}
|
||||
public:
|
||||
typedef BaseRenderer base_ren_type;
|
||||
typedef typename base_ren_type::color_type color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void solid_rectangle(int x1, int y1, int x2, int y2) { m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full); }
|
||||
//--------------------------------------------------------------------
|
||||
explicit renderer_primitives(base_ren_type& ren) :
|
||||
m_ren(&ren),
|
||||
m_fill_color(),
|
||||
m_line_color(),
|
||||
m_curr_x(0),
|
||||
m_curr_y(0)
|
||||
{}
|
||||
void attach(base_ren_type& ren) { m_ren = &ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void outlined_rectangle(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rectangle(x1, y1, x2, y2);
|
||||
m_ren->blend_bar(x1 + 1, y1 + 1, x2 - 1, y2 - 1, m_fill_color, cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void ellipse(int x, int y, int rx, int ry)
|
||||
{
|
||||
ellipse_bresenham_interpolator ei(rx, ry);
|
||||
int dx = 0;
|
||||
int dy = -ry;
|
||||
do
|
||||
//--------------------------------------------------------------------
|
||||
static int coord(double c)
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
|
||||
++ei;
|
||||
} while (dy < 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void solid_ellipse(int x, int y, int rx, int ry)
|
||||
{
|
||||
ellipse_bresenham_interpolator ei(rx, ry);
|
||||
int dx = 0;
|
||||
int dy = -ry;
|
||||
int dy0 = dy;
|
||||
int dx0 = dx;
|
||||
|
||||
do
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
if (dy != dy0)
|
||||
{
|
||||
m_ren->blend_hline(x - dx0, y + dy0, x + dx0, m_fill_color, cover_full);
|
||||
m_ren->blend_hline(x - dx0, y - dy0, x + dx0, m_fill_color, cover_full);
|
||||
}
|
||||
dx0 = dx;
|
||||
dy0 = dy;
|
||||
++ei;
|
||||
} while (dy < 0);
|
||||
m_ren->blend_hline(x - dx0, y + dy0, x + dx0, m_fill_color, cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void outlined_ellipse(int x, int y, int rx, int ry)
|
||||
{
|
||||
ellipse_bresenham_interpolator ei(rx, ry);
|
||||
int dx = 0;
|
||||
int dy = -ry;
|
||||
|
||||
do
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
|
||||
|
||||
if (ei.dy() && dx)
|
||||
{
|
||||
m_ren->blend_hline(x - dx + 1, y + dy, x + dx - 1, m_fill_color, cover_full);
|
||||
m_ren->blend_hline(x - dx + 1, y - dy, x + dx - 1, m_fill_color, cover_full);
|
||||
}
|
||||
++ei;
|
||||
} while (dy < 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line(int x1, int y1, int x2, int y2, bool last = false)
|
||||
{
|
||||
line_bresenham_interpolator li(x1, y1, x2, y2);
|
||||
|
||||
unsigned len = li.len();
|
||||
if (len == 0)
|
||||
{
|
||||
if (last)
|
||||
{
|
||||
m_ren->blend_pixel(li.line_lr(x1), li.line_lr(y1), m_line_color, cover_full);
|
||||
}
|
||||
return;
|
||||
return iround(c * line_bresenham_interpolator::subpixel_scale);
|
||||
}
|
||||
|
||||
if (last)
|
||||
++len;
|
||||
//--------------------------------------------------------------------
|
||||
void fill_color(const color_type& c) { m_fill_color = c; }
|
||||
void line_color(const color_type& c) { m_line_color = c; }
|
||||
const color_type& fill_color() const { return m_fill_color; }
|
||||
const color_type& line_color() const { return m_line_color; }
|
||||
|
||||
if (li.is_ver())
|
||||
//--------------------------------------------------------------------
|
||||
void rectangle(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
m_ren->blend_hline(x1, y1, x2-1, m_line_color, cover_full);
|
||||
m_ren->blend_vline(x2, y1, y2-1, m_line_color, cover_full);
|
||||
m_ren->blend_hline(x1+1, y2, x2, m_line_color, cover_full);
|
||||
m_ren->blend_vline(x1, y1+1, y2, m_line_color, cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void solid_rectangle(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void outlined_rectangle(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rectangle(x1, y1, x2, y2);
|
||||
m_ren->blend_bar(x1+1, y1+1, x2-1, y2-1, m_fill_color, cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void ellipse(int x, int y, int rx, int ry)
|
||||
{
|
||||
ellipse_bresenham_interpolator ei(rx, ry);
|
||||
int dx = 0;
|
||||
int dy = -ry;
|
||||
do
|
||||
{
|
||||
m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full);
|
||||
li.vstep();
|
||||
} while (--len);
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
|
||||
++ei;
|
||||
}
|
||||
while(dy < 0);
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void solid_ellipse(int x, int y, int rx, int ry)
|
||||
{
|
||||
ellipse_bresenham_interpolator ei(rx, ry);
|
||||
int dx = 0;
|
||||
int dy = -ry;
|
||||
int dy0 = dy;
|
||||
int dx0 = dx;
|
||||
|
||||
do
|
||||
{
|
||||
m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full);
|
||||
li.hstep();
|
||||
} while (--len);
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
if(dy != dy0)
|
||||
{
|
||||
m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
|
||||
m_ren->blend_hline(x-dx0, y-dy0, x+dx0, m_fill_color, cover_full);
|
||||
}
|
||||
dx0 = dx;
|
||||
dy0 = dy;
|
||||
++ei;
|
||||
}
|
||||
while(dy < 0);
|
||||
m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y)
|
||||
{
|
||||
m_curr_x = x;
|
||||
m_curr_y = y;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void outlined_ellipse(int x, int y, int rx, int ry)
|
||||
{
|
||||
ellipse_bresenham_interpolator ei(rx, ry);
|
||||
int dx = 0;
|
||||
int dy = -ry;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line_to(int x, int y, bool last = false)
|
||||
{
|
||||
line(m_curr_x, m_curr_y, x, y, last);
|
||||
m_curr_x = x;
|
||||
m_curr_y = y;
|
||||
}
|
||||
do
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const base_ren_type& ren() const { return *m_ren; }
|
||||
base_ren_type& ren() { return *m_ren; }
|
||||
m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
|
||||
m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rendering_buffer& rbuf() const { return m_ren->rbuf(); }
|
||||
rendering_buffer& rbuf() { return m_ren->rbuf(); }
|
||||
if(ei.dy() && dx)
|
||||
{
|
||||
m_ren->blend_hline(x-dx+1, y+dy, x+dx-1, m_fill_color, cover_full);
|
||||
m_ren->blend_hline(x-dx+1, y-dy, x+dx-1, m_fill_color, cover_full);
|
||||
}
|
||||
++ei;
|
||||
}
|
||||
while(dy < 0);
|
||||
}
|
||||
|
||||
private:
|
||||
base_ren_type* m_ren;
|
||||
color_type m_fill_color;
|
||||
color_type m_line_color;
|
||||
int m_curr_x;
|
||||
int m_curr_y;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
void line(int x1, int y1, int x2, int y2, bool last=false)
|
||||
{
|
||||
line_bresenham_interpolator li(x1, y1, x2, y2);
|
||||
|
||||
} // namespace agg
|
||||
unsigned len = li.len();
|
||||
if(len == 0)
|
||||
{
|
||||
if(last)
|
||||
{
|
||||
m_ren->blend_pixel(li.line_lr(x1), li.line_lr(y1), m_line_color, cover_full);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(last) ++len;
|
||||
|
||||
if(li.is_ver())
|
||||
{
|
||||
do
|
||||
{
|
||||
m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full);
|
||||
li.vstep();
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full);
|
||||
li.hstep();
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(int x, int y)
|
||||
{
|
||||
m_curr_x = x;
|
||||
m_curr_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void line_to(int x, int y, bool last=false)
|
||||
{
|
||||
line(m_curr_x, m_curr_y, x, y, last);
|
||||
m_curr_x = x;
|
||||
m_curr_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const base_ren_type& ren() const { return *m_ren; }
|
||||
base_ren_type& ren() { return *m_ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rendering_buffer& rbuf() const { return m_ren->rbuf(); }
|
||||
rendering_buffer& rbuf() { return m_ren->rbuf(); }
|
||||
|
||||
private:
|
||||
base_ren_type* m_ren;
|
||||
color_type m_fill_color;
|
||||
color_type m_line_color;
|
||||
int m_curr_x;
|
||||
int m_curr_y;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
422
deps/agg/include/agg_renderer_raster_text.h
vendored
422
deps/agg/include/agg_renderer_raster_text.h
vendored
|
@ -18,215 +18,247 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//==============================================renderer_raster_htext_solid
|
||||
template<class BaseRenderer, class GlyphGenerator>
|
||||
class renderer_raster_htext_solid
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef BaseRenderer ren_type;
|
||||
typedef GlyphGenerator glyph_gen_type;
|
||||
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
||||
typedef typename ren_type::color_type color_type;
|
||||
|
||||
renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph)
|
||||
: m_ren(&ren)
|
||||
, m_glyph(&glyph)
|
||||
{}
|
||||
void attach(ren_type& ren) { m_ren = &ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void color(const color_type& c) { m_color = c; }
|
||||
const color_type& color() const { return m_color; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void render_text(double x, double y, const CharT* str, bool flip = false)
|
||||
//==============================================renderer_raster_htext_solid
|
||||
template<class BaseRenderer, class GlyphGenerator>
|
||||
class renderer_raster_htext_solid
|
||||
{
|
||||
glyph_rect r;
|
||||
while (*str)
|
||||
{
|
||||
m_glyph->prepare(&r, x, y, *str, flip);
|
||||
if (r.x2 >= r.x1)
|
||||
{
|
||||
int i;
|
||||
if (flip)
|
||||
{
|
||||
for (i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1), m_color, m_glyph->span(r.y2 - i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1), m_color, m_glyph->span(i - r.y1));
|
||||
}
|
||||
}
|
||||
}
|
||||
x += r.dx;
|
||||
y += r.dy;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
public:
|
||||
typedef BaseRenderer ren_type;
|
||||
typedef GlyphGenerator glyph_gen_type;
|
||||
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
||||
typedef typename ren_type::color_type color_type;
|
||||
|
||||
private:
|
||||
ren_type* m_ren;
|
||||
glyph_gen_type* m_glyph;
|
||||
color_type m_color;
|
||||
};
|
||||
|
||||
//=============================================renderer_raster_vtext_solid
|
||||
template<class BaseRenderer, class GlyphGenerator>
|
||||
class renderer_raster_vtext_solid
|
||||
{
|
||||
public:
|
||||
typedef BaseRenderer ren_type;
|
||||
typedef GlyphGenerator glyph_gen_type;
|
||||
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
||||
typedef typename ren_type::color_type color_type;
|
||||
|
||||
renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph)
|
||||
: m_ren(&ren)
|
||||
, m_glyph(&glyph)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void color(const color_type& c) { m_color = c; }
|
||||
const color_type& color() const { return m_color; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void render_text(double x, double y, const CharT* str, bool flip = false)
|
||||
{
|
||||
glyph_rect r;
|
||||
while (*str)
|
||||
{
|
||||
m_glyph->prepare(&r, x, y, *str, !flip);
|
||||
if (r.x2 >= r.x1)
|
||||
{
|
||||
int i;
|
||||
if (flip)
|
||||
{
|
||||
for (i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1), m_color, m_glyph->span(i - r.y1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1), m_color, m_glyph->span(r.y2 - i));
|
||||
}
|
||||
}
|
||||
}
|
||||
x += r.dx;
|
||||
y += r.dy;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ren_type* m_ren;
|
||||
glyph_gen_type* m_glyph;
|
||||
color_type m_color;
|
||||
};
|
||||
|
||||
//===================================================renderer_raster_htext
|
||||
template<class ScanlineRenderer, class GlyphGenerator>
|
||||
class renderer_raster_htext
|
||||
{
|
||||
public:
|
||||
typedef ScanlineRenderer ren_type;
|
||||
typedef GlyphGenerator glyph_gen_type;
|
||||
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
||||
|
||||
class scanline_single_span
|
||||
{
|
||||
public:
|
||||
typedef agg::cover_type cover_type;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
struct const_span
|
||||
{
|
||||
int x;
|
||||
unsigned len;
|
||||
const cover_type* covers;
|
||||
|
||||
const_span() {}
|
||||
const_span(int x_, unsigned len_, const cover_type* covers_)
|
||||
: x(x_)
|
||||
, len(len_)
|
||||
, covers(covers_)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef const const_span* const_iterator;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
scanline_single_span(int x, int y, unsigned len, const cover_type* covers)
|
||||
: m_y(y)
|
||||
, m_span(x, len, covers)
|
||||
renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) :
|
||||
m_ren(&ren),
|
||||
m_glyph(&glyph)
|
||||
{}
|
||||
void attach(ren_type& ren) { m_ren = &ren; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return 1; }
|
||||
const_iterator begin() const { return &m_span; }
|
||||
//--------------------------------------------------------------------
|
||||
void color(const color_type& c) { m_color = c; }
|
||||
const color_type& color() const { return m_color; }
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------
|
||||
int m_y;
|
||||
const_span m_span;
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void render_text(double x, double y, const CharT* str, bool flip=false)
|
||||
{
|
||||
glyph_rect r;
|
||||
while(*str)
|
||||
{
|
||||
m_glyph->prepare(&r, x, y, *str, flip);
|
||||
if(r.x2 >= r.x1)
|
||||
{
|
||||
int i;
|
||||
if(flip)
|
||||
{
|
||||
for(i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
|
||||
m_color,
|
||||
m_glyph->span(r.y2 - i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
|
||||
m_color,
|
||||
m_glyph->span(i - r.y1));
|
||||
}
|
||||
}
|
||||
}
|
||||
x += r.dx;
|
||||
y += r.dy;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ren_type* m_ren;
|
||||
glyph_gen_type* m_glyph;
|
||||
color_type m_color;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph)
|
||||
: m_ren(&ren)
|
||||
, m_glyph(&glyph)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void render_text(double x, double y, const CharT* str, bool flip = false)
|
||||
|
||||
//=============================================renderer_raster_vtext_solid
|
||||
template<class BaseRenderer, class GlyphGenerator>
|
||||
class renderer_raster_vtext_solid
|
||||
{
|
||||
glyph_rect r;
|
||||
while (*str)
|
||||
public:
|
||||
typedef BaseRenderer ren_type;
|
||||
typedef GlyphGenerator glyph_gen_type;
|
||||
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
||||
typedef typename ren_type::color_type color_type;
|
||||
|
||||
renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph) :
|
||||
m_ren(&ren),
|
||||
m_glyph(&glyph)
|
||||
{
|
||||
m_glyph->prepare(&r, x, y, *str, flip);
|
||||
if (r.x2 >= r.x1)
|
||||
{
|
||||
m_ren->prepare();
|
||||
int i;
|
||||
if (flip)
|
||||
{
|
||||
for (i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->render(scanline_single_span(r.x1, i, (r.x2 - r.x1 + 1), m_glyph->span(r.y2 - i)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->render(scanline_single_span(r.x1, i, (r.x2 - r.x1 + 1), m_glyph->span(i - r.y1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
x += r.dx;
|
||||
y += r.dy;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ren_type* m_ren;
|
||||
glyph_gen_type* m_glyph;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
void color(const color_type& c) { m_color = c; }
|
||||
const color_type& color() const { return m_color; }
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void render_text(double x, double y, const CharT* str, bool flip=false)
|
||||
{
|
||||
glyph_rect r;
|
||||
while(*str)
|
||||
{
|
||||
m_glyph->prepare(&r, x, y, *str, !flip);
|
||||
if(r.x2 >= r.x1)
|
||||
{
|
||||
int i;
|
||||
if(flip)
|
||||
{
|
||||
for(i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
|
||||
m_color,
|
||||
m_glyph->span(i - r.y1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
|
||||
m_color,
|
||||
m_glyph->span(r.y2 - i));
|
||||
}
|
||||
}
|
||||
}
|
||||
x += r.dx;
|
||||
y += r.dy;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ren_type* m_ren;
|
||||
glyph_gen_type* m_glyph;
|
||||
color_type m_color;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===================================================renderer_raster_htext
|
||||
template<class ScanlineRenderer, class GlyphGenerator>
|
||||
class renderer_raster_htext
|
||||
{
|
||||
public:
|
||||
typedef ScanlineRenderer ren_type;
|
||||
typedef GlyphGenerator glyph_gen_type;
|
||||
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
||||
|
||||
class scanline_single_span
|
||||
{
|
||||
public:
|
||||
typedef agg::cover_type cover_type;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
struct const_span
|
||||
{
|
||||
int x;
|
||||
unsigned len;
|
||||
const cover_type* covers;
|
||||
|
||||
const_span() {}
|
||||
const_span(int x_, unsigned len_, const cover_type* covers_) :
|
||||
x(x_), len(len_), covers(covers_)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef const const_span* const_iterator;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
scanline_single_span(int x, int y, unsigned len,
|
||||
const cover_type* covers) :
|
||||
m_y(y),
|
||||
m_span(x, len, covers)
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return 1; }
|
||||
const_iterator begin() const { return &m_span; }
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------
|
||||
int m_y;
|
||||
const_span m_span;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) :
|
||||
m_ren(&ren),
|
||||
m_glyph(&glyph)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void render_text(double x, double y, const CharT* str, bool flip=false)
|
||||
{
|
||||
glyph_rect r;
|
||||
while(*str)
|
||||
{
|
||||
m_glyph->prepare(&r, x, y, *str, flip);
|
||||
if(r.x2 >= r.x1)
|
||||
{
|
||||
m_ren->prepare();
|
||||
int i;
|
||||
if(flip)
|
||||
{
|
||||
for(i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->render(
|
||||
scanline_single_span(r.x1,
|
||||
i,
|
||||
(r.x2 - r.x1 + 1),
|
||||
m_glyph->span(r.y2 - i)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = r.y1; i <= r.y2; i++)
|
||||
{
|
||||
m_ren->render(
|
||||
scanline_single_span(r.x1,
|
||||
i,
|
||||
(r.x2 - r.x1 + 1),
|
||||
m_glyph->span(i - r.y1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
x += r.dx;
|
||||
y += r.dy;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ren_type* m_ren;
|
||||
glyph_gen_type* m_glyph;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
1610
deps/agg/include/agg_renderer_scanline.h
vendored
1610
deps/agg/include/agg_renderer_scanline.h
vendored
File diff suppressed because it is too large
Load diff
467
deps/agg/include/agg_rendering_buffer.h
vendored
467
deps/agg/include/agg_rendering_buffer.h
vendored
|
@ -22,261 +22,284 @@
|
|||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//===========================================================row_accessor
|
||||
template<class T>
|
||||
class row_accessor
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef const_row_info<T> row_data;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
row_accessor()
|
||||
: m_buf(0)
|
||||
, m_start(0)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_stride(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
row_accessor(T* buf, unsigned width, unsigned height, int stride)
|
||||
: m_buf(0)
|
||||
, m_start(0)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_stride(0)
|
||||
//===========================================================row_accessor
|
||||
template<class T> class row_accessor
|
||||
{
|
||||
attach(buf, width, height, stride);
|
||||
}
|
||||
public:
|
||||
typedef const_row_info<T> row_data;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
m_buf = m_start = buf;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
if (stride < 0)
|
||||
//-------------------------------------------------------------------
|
||||
row_accessor() :
|
||||
m_buf(0),
|
||||
m_start(0),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
m_start = m_buf - int(height - 1) * stride;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* buf() { return m_buf; }
|
||||
AGG_INLINE const T* buf() const { return m_buf; }
|
||||
AGG_INLINE unsigned width() const { return m_width; }
|
||||
AGG_INLINE unsigned height() const { return m_height; }
|
||||
AGG_INLINE int stride() const { return m_stride; }
|
||||
AGG_INLINE unsigned stride_abs() const { return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* row_ptr(int, int y, unsigned) { return m_start + y * m_stride; }
|
||||
AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
|
||||
AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
|
||||
AGG_INLINE row_data row(int y) const { return row_data(0, m_width - 1, row_ptr(y)); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src)
|
||||
{
|
||||
unsigned h = height();
|
||||
if (src.height() < h)
|
||||
h = src.height();
|
||||
|
||||
unsigned l = stride_abs();
|
||||
if (src.stride_abs() < l)
|
||||
l = src.stride_abs();
|
||||
|
||||
l *= sizeof(T);
|
||||
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
for (y = 0; y < h; y++)
|
||||
//--------------------------------------------------------------------
|
||||
row_accessor(T* buf, unsigned width, unsigned height, int stride) :
|
||||
m_buf(0),
|
||||
m_start(0),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
||||
attach(buf, width, height, stride);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(T value)
|
||||
{
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
unsigned stride = stride_abs();
|
||||
for (y = 0; y < height(); y++)
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
T* p = row_ptr(0, y, w);
|
||||
unsigned x;
|
||||
for (x = 0; x < stride; x++)
|
||||
m_buf = m_start = buf;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
if(stride < 0)
|
||||
{
|
||||
*p++ = value;
|
||||
m_start = m_buf - int(height - 1) * stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
T* m_buf; // Pointer to rendering buffer
|
||||
T* m_start; // Pointer to first pixel depending on stride
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
int m_stride; // Number of bytes per row. Can be < 0
|
||||
};
|
||||
|
||||
//==========================================================row_ptr_cache
|
||||
template<class T>
|
||||
class row_ptr_cache
|
||||
{
|
||||
public:
|
||||
typedef const_row_info<T> row_data;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
row_ptr_cache()
|
||||
: m_buf(0)
|
||||
, m_rows()
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_stride(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
row_ptr_cache(T* buf, unsigned width, unsigned height, int stride)
|
||||
: m_buf(0)
|
||||
, m_rows()
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_stride(0)
|
||||
{
|
||||
attach(buf, width, height, stride);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
m_buf = buf;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
if (height > m_rows.size())
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* buf() { return m_buf; }
|
||||
AGG_INLINE const T* buf() const { return m_buf; }
|
||||
AGG_INLINE unsigned width() const { return m_width; }
|
||||
AGG_INLINE unsigned height() const { return m_height; }
|
||||
AGG_INLINE int stride() const { return m_stride; }
|
||||
AGG_INLINE unsigned stride_abs() const
|
||||
{
|
||||
m_rows.resize(height);
|
||||
}
|
||||
else if (height == 0)
|
||||
{
|
||||
return;
|
||||
return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
|
||||
}
|
||||
|
||||
T* row_ptr = m_buf;
|
||||
|
||||
if (stride < 0)
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* row_ptr(int, int y, unsigned)
|
||||
{
|
||||
row_ptr = m_buf - int(height - 1) * stride;
|
||||
return m_start + y * m_stride;
|
||||
}
|
||||
AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
|
||||
AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
|
||||
AGG_INLINE row_data row (int y) const
|
||||
{
|
||||
return row_data(0, m_width-1, row_ptr(y));
|
||||
}
|
||||
|
||||
T** rows = &m_rows[0];
|
||||
|
||||
while (height > 0)
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src)
|
||||
{
|
||||
*rows++ = row_ptr;
|
||||
row_ptr += stride;
|
||||
--height;
|
||||
}
|
||||
}
|
||||
unsigned h = height();
|
||||
if(src.height() < h) h = src.height();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* buf() { return m_buf; }
|
||||
AGG_INLINE const T* buf() const { return m_buf; }
|
||||
AGG_INLINE unsigned width() const { return m_width; }
|
||||
AGG_INLINE unsigned height() const { return m_height; }
|
||||
AGG_INLINE int stride() const { return m_stride; }
|
||||
AGG_INLINE unsigned stride_abs() const { return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); }
|
||||
unsigned l = stride_abs();
|
||||
if(src.stride_abs() < l) l = src.stride_abs();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* row_ptr(int, int y, unsigned) { return m_rows[y]; }
|
||||
AGG_INLINE T* row_ptr(int y) { return m_rows[y]; }
|
||||
AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; }
|
||||
AGG_INLINE row_data row(int y) const { return row_data(0, m_width - 1, m_rows[y]); }
|
||||
l *= sizeof(T);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
T const* const* rows() const { return &m_rows[0]; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src)
|
||||
{
|
||||
unsigned h = height();
|
||||
if (src.height() < h)
|
||||
h = src.height();
|
||||
|
||||
unsigned l = stride_abs();
|
||||
if (src.stride_abs() < l)
|
||||
l = src.stride_abs();
|
||||
|
||||
l *= sizeof(T);
|
||||
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(T value)
|
||||
{
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
unsigned stride = stride_abs();
|
||||
for (y = 0; y < height(); y++)
|
||||
{
|
||||
T* p = row_ptr(0, y, w);
|
||||
unsigned x;
|
||||
for (x = 0; x < stride; x++)
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
*p++ = value;
|
||||
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
T* m_buf; // Pointer to rendering buffer
|
||||
pod_array<T*> m_rows; // Pointers to each row of the buffer
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
int m_stride; // Number of bytes per row. Can be < 0
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
void clear(T value)
|
||||
{
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
unsigned stride = stride_abs();
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
T* p = row_ptr(0, y, w);
|
||||
unsigned x;
|
||||
for(x = 0; x < stride; x++)
|
||||
{
|
||||
*p++ = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================rendering_buffer
|
||||
//
|
||||
// The definition of the main type for accessing the rows in the frame
|
||||
// buffer. It provides functionality to navigate to the rows in a
|
||||
// rectangular matrix, from top to bottom or from bottom to top depending
|
||||
// on stride.
|
||||
//
|
||||
// row_accessor is cheap to create/destroy, but performs one multiplication
|
||||
// when calling row_ptr().
|
||||
//
|
||||
// row_ptr_cache creates an array of pointers to rows, so, the access
|
||||
// via row_ptr() may be faster. But it requires memory allocation
|
||||
// when creating. For example, on typical Intel Pentium hardware
|
||||
// row_ptr_cache speeds span_image_filter_rgb_nn up to 10%
|
||||
//
|
||||
// It's used only in short hand typedefs like pixfmt_rgba32 and can be
|
||||
// redefined in agg_config.h
|
||||
// In real applications you can use both, depending on your needs
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
T* m_buf; // Pointer to rendering buffer
|
||||
T* m_start; // Pointer to first pixel depending on stride
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
int m_stride; // Number of bytes per row. Can be < 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================row_ptr_cache
|
||||
template<class T> class row_ptr_cache
|
||||
{
|
||||
public:
|
||||
typedef const_row_info<T> row_data;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
row_ptr_cache() :
|
||||
m_buf(0),
|
||||
m_rows(),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) :
|
||||
m_buf(0),
|
||||
m_rows(),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
attach(buf, width, height, stride);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
m_buf = buf;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
if(height > m_rows.size())
|
||||
{
|
||||
m_rows.resize(height);
|
||||
}
|
||||
else if(height == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
T* row_ptr = m_buf;
|
||||
|
||||
if(stride < 0)
|
||||
{
|
||||
row_ptr = m_buf - int(height - 1) * stride;
|
||||
}
|
||||
|
||||
T** rows = &m_rows[0];
|
||||
|
||||
while(height > 0)
|
||||
{
|
||||
*rows++ = row_ptr;
|
||||
row_ptr += stride;
|
||||
--height;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* buf() { return m_buf; }
|
||||
AGG_INLINE const T* buf() const { return m_buf; }
|
||||
AGG_INLINE unsigned width() const { return m_width; }
|
||||
AGG_INLINE unsigned height() const { return m_height; }
|
||||
AGG_INLINE int stride() const { return m_stride; }
|
||||
AGG_INLINE unsigned stride_abs() const
|
||||
{
|
||||
return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE T* row_ptr(int, int y, unsigned)
|
||||
{
|
||||
return m_rows[y];
|
||||
}
|
||||
AGG_INLINE T* row_ptr(int y) { return m_rows[y]; }
|
||||
AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; }
|
||||
AGG_INLINE row_data row (int y) const
|
||||
{
|
||||
return row_data(0, m_width-1, m_rows[y]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
T const* const* rows() const { return &m_rows[0]; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src)
|
||||
{
|
||||
unsigned h = height();
|
||||
if(src.height() < h) h = src.height();
|
||||
|
||||
unsigned l = stride_abs();
|
||||
if(src.stride_abs() < l) l = src.stride_abs();
|
||||
|
||||
l *= sizeof(T);
|
||||
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(T value)
|
||||
{
|
||||
unsigned y;
|
||||
unsigned w = width();
|
||||
unsigned stride = stride_abs();
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
T* p = row_ptr(0, y, w);
|
||||
unsigned x;
|
||||
for(x = 0; x < stride; x++)
|
||||
{
|
||||
*p++ = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
T* m_buf; // Pointer to rendering buffer
|
||||
pod_array<T*> m_rows; // Pointers to each row of the buffer
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
int m_stride; // Number of bytes per row. Can be < 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//========================================================rendering_buffer
|
||||
//
|
||||
// The definition of the main type for accessing the rows in the frame
|
||||
// buffer. It provides functionality to navigate to the rows in a
|
||||
// rectangular matrix, from top to bottom or from bottom to top depending
|
||||
// on stride.
|
||||
//
|
||||
// row_accessor is cheap to create/destroy, but performs one multiplication
|
||||
// when calling row_ptr().
|
||||
//
|
||||
// row_ptr_cache creates an array of pointers to rows, so, the access
|
||||
// via row_ptr() may be faster. But it requires memory allocation
|
||||
// when creating. For example, on typical Intel Pentium hardware
|
||||
// row_ptr_cache speeds span_image_filter_rgb_nn up to 10%
|
||||
//
|
||||
// It's used only in short hand typedefs like pixfmt_rgba32 and can be
|
||||
// redefined in agg_config.h
|
||||
// In real applications you can use both, depending on your needs
|
||||
//------------------------------------------------------------------------
|
||||
#ifdef AGG_RENDERING_BUFFER
|
||||
typedef AGG_RENDERING_BUFFER rendering_buffer;
|
||||
typedef AGG_RENDERING_BUFFER rendering_buffer;
|
||||
#else
|
||||
typedef row_ptr_cache<int8u> rendering_buffer;
|
||||
// typedef row_accessor<int8u> rendering_buffer;
|
||||
typedef row_ptr_cache<int8u> rendering_buffer;
|
||||
//typedef row_accessor<int8u> rendering_buffer;
|
||||
#endif
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
176
deps/agg/include/agg_rendering_buffer_dynarow.h
vendored
176
deps/agg/include/agg_rendering_buffer_dynarow.h
vendored
|
@ -22,114 +22,116 @@
|
|||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//===============================================rendering_buffer_dynarow
|
||||
// Rendering buffer class with dynamic allocation of the rows.
|
||||
// The rows are allocated as needed when requesting for span_ptr().
|
||||
// The class automatically calculates min_x and max_x for each row.
|
||||
// Generally it's more efficient to use this class as a temporary buffer
|
||||
// for rendering a few lines and then to blend it with another buffer.
|
||||
//
|
||||
class rendering_buffer_dynarow
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef row_info<int8u> row_data;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
~rendering_buffer_dynarow() { init(0, 0, 0); }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
rendering_buffer_dynarow()
|
||||
: m_rows()
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_byte_width(0)
|
||||
{}
|
||||
|
||||
// Allocate and clear the buffer
|
||||
//--------------------------------------------------------------------
|
||||
rendering_buffer_dynarow(unsigned width, unsigned height, unsigned byte_width)
|
||||
: m_rows(height)
|
||||
, m_width(width)
|
||||
, m_height(height)
|
||||
, m_byte_width(byte_width)
|
||||
//===============================================rendering_buffer_dynarow
|
||||
// Rendering buffer class with dynamic allocation of the rows.
|
||||
// The rows are allocated as needed when requesting for span_ptr().
|
||||
// The class automatically calculates min_x and max_x for each row.
|
||||
// Generally it's more efficient to use this class as a temporary buffer
|
||||
// for rendering a few lines and then to blend it with another buffer.
|
||||
//
|
||||
class rendering_buffer_dynarow
|
||||
{
|
||||
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
||||
}
|
||||
public:
|
||||
typedef row_info<int8u> row_data;
|
||||
|
||||
// Allocate and clear the buffer
|
||||
//--------------------------------------------------------------------
|
||||
void init(unsigned width, unsigned height, unsigned byte_width)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < m_height; ++i)
|
||||
//-------------------------------------------------------------------
|
||||
~rendering_buffer_dynarow()
|
||||
{
|
||||
pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
|
||||
init(0,0,0);
|
||||
}
|
||||
if (width && height)
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
rendering_buffer_dynarow() :
|
||||
m_rows(),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_byte_width(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Allocate and clear the buffer
|
||||
//--------------------------------------------------------------------
|
||||
rendering_buffer_dynarow(unsigned width, unsigned height,
|
||||
unsigned byte_width) :
|
||||
m_rows(height),
|
||||
m_width(width),
|
||||
m_height(height),
|
||||
m_byte_width(byte_width)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_byte_width = byte_width;
|
||||
m_rows.resize(height);
|
||||
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_width; }
|
||||
unsigned height() const { return m_height; }
|
||||
unsigned byte_width() const { return m_byte_width; }
|
||||
|
||||
// The main function used for rendering. Returns pointer to the
|
||||
// pre-allocated span. Memory for the row is allocated as needed.
|
||||
//--------------------------------------------------------------------
|
||||
int8u* row_ptr(int x, int y, unsigned len)
|
||||
{
|
||||
row_data* r = &m_rows[y];
|
||||
int x2 = x + len - 1;
|
||||
if (r->ptr)
|
||||
// Allocate and clear the buffer
|
||||
//--------------------------------------------------------------------
|
||||
void init(unsigned width, unsigned height, unsigned byte_width)
|
||||
{
|
||||
if (x < r->x1)
|
||||
unsigned i;
|
||||
for(i = 0; i < m_height; ++i)
|
||||
{
|
||||
r->x1 = x;
|
||||
pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
|
||||
}
|
||||
if (x2 > r->x2)
|
||||
if(width && height)
|
||||
{
|
||||
r->x2 = x2;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_byte_width = byte_width;
|
||||
m_rows.resize(height);
|
||||
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_width; }
|
||||
unsigned height() const { return m_height; }
|
||||
unsigned byte_width() const { return m_byte_width; }
|
||||
|
||||
// The main function used for rendering. Returns pointer to the
|
||||
// pre-allocated span. Memory for the row is allocated as needed.
|
||||
//--------------------------------------------------------------------
|
||||
int8u* row_ptr(int x, int y, unsigned len)
|
||||
{
|
||||
int8u* p = pod_allocator<int8u>::allocate(m_byte_width);
|
||||
r->ptr = p;
|
||||
r->x1 = x;
|
||||
r->x2 = x2;
|
||||
memset(p, 0, m_byte_width);
|
||||
row_data* r = &m_rows[y];
|
||||
int x2 = x + len - 1;
|
||||
if(r->ptr)
|
||||
{
|
||||
if(x < r->x1) { r->x1 = x; }
|
||||
if(x2 > r->x2) { r->x2 = x2; }
|
||||
}
|
||||
else
|
||||
{
|
||||
int8u* p = pod_allocator<int8u>::allocate(m_byte_width);
|
||||
r->ptr = p;
|
||||
r->x1 = x;
|
||||
r->x2 = x2;
|
||||
memset(p, 0, m_byte_width);
|
||||
}
|
||||
return (int8u*)r->ptr;
|
||||
}
|
||||
return (int8u*)r->ptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const int8u* row_ptr(int y) const { return m_rows[y].ptr; }
|
||||
int8u* row_ptr(int y) { return row_ptr(0, y, m_width); }
|
||||
row_data row(int y) const { return m_rows[y]; }
|
||||
//--------------------------------------------------------------------
|
||||
const int8u* row_ptr(int y) const { return m_rows[y].ptr; }
|
||||
int8u* row_ptr(int y) { return row_ptr(0, y, m_width); }
|
||||
row_data row (int y) const { return m_rows[y]; }
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
// Prohibit copying
|
||||
rendering_buffer_dynarow(const rendering_buffer_dynarow&);
|
||||
const rendering_buffer_dynarow& operator=(const rendering_buffer_dynarow&);
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
// Prohibit copying
|
||||
rendering_buffer_dynarow(const rendering_buffer_dynarow&);
|
||||
const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&);
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
pod_array<row_data> m_rows; // Pointers to each row of the buffer
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
unsigned m_byte_width; // Width in bytes
|
||||
};
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
pod_array<row_data> m_rows; // Pointers to each row of the buffer
|
||||
unsigned m_width; // Width in pixels
|
||||
unsigned m_height; // Height in pixels
|
||||
unsigned m_byte_width; // Width in bytes
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
75
deps/agg/include/agg_rounded_rect.h
vendored
75
deps/agg/include/agg_rounded_rect.h
vendored
|
@ -23,47 +23,50 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_arc.h"
|
||||
|
||||
namespace agg {
|
||||
//------------------------------------------------------------rounded_rect
|
||||
//
|
||||
// See Implemantation agg_rounded_rect.cpp
|
||||
//
|
||||
class rounded_rect
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
rounded_rect() {}
|
||||
rounded_rect(double x1, double y1, double x2, double y2, double r);
|
||||
//------------------------------------------------------------rounded_rect
|
||||
//
|
||||
// See Implemantation agg_rounded_rect.cpp
|
||||
//
|
||||
class rounded_rect
|
||||
{
|
||||
public:
|
||||
rounded_rect() {}
|
||||
rounded_rect(double x1, double y1, double x2, double y2, double r);
|
||||
|
||||
void rect(double x1, double y1, double x2, double y2);
|
||||
void radius(double r);
|
||||
void radius(double rx, double ry);
|
||||
void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top);
|
||||
void radius(double rx1, double ry1, double rx2, double ry2, double rx3, double ry3, double rx4, double ry4);
|
||||
void normalize_radius();
|
||||
void rect(double x1, double y1, double x2, double y2);
|
||||
void radius(double r);
|
||||
void radius(double rx, double ry);
|
||||
void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top);
|
||||
void radius(double rx1, double ry1, double rx2, double ry2,
|
||||
double rx3, double ry3, double rx4, double ry4);
|
||||
void normalize_radius();
|
||||
|
||||
void approximation_scale(double s) { m_arc.approximation_scale(s); }
|
||||
double approximation_scale() const { return m_arc.approximation_scale(); }
|
||||
void approximation_scale(double s) { m_arc.approximation_scale(s); }
|
||||
double approximation_scale() const { return m_arc.approximation_scale(); }
|
||||
|
||||
void rewind(unsigned);
|
||||
unsigned vertex(double* x, double* y);
|
||||
void rewind(unsigned);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
double m_x1;
|
||||
double m_y1;
|
||||
double m_x2;
|
||||
double m_y2;
|
||||
double m_rx1;
|
||||
double m_ry1;
|
||||
double m_rx2;
|
||||
double m_ry2;
|
||||
double m_rx3;
|
||||
double m_ry3;
|
||||
double m_rx4;
|
||||
double m_ry4;
|
||||
unsigned m_status;
|
||||
arc m_arc;
|
||||
};
|
||||
private:
|
||||
double m_x1;
|
||||
double m_y1;
|
||||
double m_x2;
|
||||
double m_y2;
|
||||
double m_rx1;
|
||||
double m_ry1;
|
||||
double m_rx2;
|
||||
double m_ry2;
|
||||
double m_rx3;
|
||||
double m_ry3;
|
||||
double m_rx4;
|
||||
double m_ry4;
|
||||
unsigned m_status;
|
||||
arc m_arc;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
378
deps/agg/include/agg_scanline_bin.h
vendored
378
deps/agg/include/agg_scanline_bin.h
vendored
|
@ -30,215 +30,235 @@
|
|||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=============================================================scanline_bin
|
||||
//
|
||||
// This is binary scaline container which supports the interface
|
||||
// used in the rasterizer::render(). See description of agg_scanline_u8
|
||||
// for details.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_bin
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef int32 coord_type;
|
||||
|
||||
struct span
|
||||
//=============================================================scanline_bin
|
||||
//
|
||||
// This is binary scaline container which supports the interface
|
||||
// used in the rasterizer::render(). See description of agg_scanline_u8
|
||||
// for details.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_bin
|
||||
{
|
||||
int16 x;
|
||||
int16 len;
|
||||
public:
|
||||
typedef int32 coord_type;
|
||||
|
||||
struct span
|
||||
{
|
||||
int16 x;
|
||||
int16 len;
|
||||
};
|
||||
|
||||
typedef const span* const_iterator;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline_bin() :
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_spans(),
|
||||
m_cur_span(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if(max_len > m_spans.size())
|
||||
{
|
||||
m_spans.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cur_span = &m_spans[0];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned)
|
||||
{
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_cur_span->len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_cur_span;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = 1;
|
||||
}
|
||||
m_last_x = x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned)
|
||||
{
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_cur_span->len = (int16)(m_cur_span->len + len);
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_cur_span;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)len;
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const void*)
|
||||
{
|
||||
add_span(x, len, 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cur_span = &m_spans[0];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
|
||||
private:
|
||||
scanline_bin(const scanline_bin&);
|
||||
const scanline_bin operator = (const scanline_bin&);
|
||||
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
|
||||
typedef const span* const_iterator;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline_bin()
|
||||
: m_last_x(0x7FFFFFF0)
|
||||
, m_spans()
|
||||
, m_cur_span(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
|
||||
|
||||
|
||||
//===========================================================scanline32_bin
|
||||
class scanline32_bin
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if (max_len > m_spans.size())
|
||||
public:
|
||||
typedef int32 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
m_spans.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cur_span = &m_spans[0];
|
||||
}
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_) : x(x_), len(len_) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned)
|
||||
{
|
||||
if (x == m_last_x + 1)
|
||||
coord_type x;
|
||||
coord_type len;
|
||||
};
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
m_cur_span->len++;
|
||||
}
|
||||
else
|
||||
public:
|
||||
const_iterator(const span_array_type& spans) :
|
||||
m_spans(spans),
|
||||
m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator ++ () { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int, int)
|
||||
{
|
||||
++m_cur_span;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = 1;
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
m_last_x = x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned)
|
||||
{
|
||||
if (x == m_last_x + 1)
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned)
|
||||
{
|
||||
m_cur_span->len = (int16)(m_cur_span->len + len);
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), 1));
|
||||
}
|
||||
m_last_x = x;
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned)
|
||||
{
|
||||
++m_cur_span;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)len;
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), coord_type(len)));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const void*) { add_span(x, len, 0); }
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const void*)
|
||||
{
|
||||
add_span(x, len, 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y) { m_y = y; }
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cur_span = &m_spans[0];
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
|
||||
private:
|
||||
scanline_bin(const scanline_bin&);
|
||||
const scanline_bin operator=(const scanline_bin&);
|
||||
private:
|
||||
scanline32_bin(const scanline32_bin&);
|
||||
const scanline32_bin operator = (const scanline32_bin&);
|
||||
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
|
||||
//===========================================================scanline32_bin
|
||||
class scanline32_bin
|
||||
{
|
||||
public:
|
||||
typedef int32 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_)
|
||||
: x(x_)
|
||||
, len(len_)
|
||||
{}
|
||||
|
||||
coord_type x;
|
||||
coord_type len;
|
||||
};
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator(const span_array_type& spans)
|
||||
: m_spans(spans)
|
||||
, m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator++() { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
unsigned m_max_len;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_bin()
|
||||
: m_max_len(0)
|
||||
, m_last_x(0x7FFFFFF0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int, int)
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned)
|
||||
{
|
||||
if (x == m_last_x + 1)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), 1));
|
||||
}
|
||||
m_last_x = x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned)
|
||||
{
|
||||
if (x == m_last_x + 1)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), coord_type(len)));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const void*) { add_span(x, len, 0); }
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y) { m_y = y; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
|
||||
private:
|
||||
scanline32_bin(const scanline32_bin&);
|
||||
const scanline32_bin operator=(const scanline32_bin&);
|
||||
|
||||
unsigned m_max_len;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
2453
deps/agg/include/agg_scanline_boolean_algebra.h
vendored
2453
deps/agg/include/agg_scanline_boolean_algebra.h
vendored
File diff suppressed because it is too large
Load diff
490
deps/agg/include/agg_scanline_p.h
vendored
490
deps/agg/include/agg_scanline_p.h
vendored
|
@ -29,279 +29,301 @@
|
|||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=============================================================scanline_p8
|
||||
//
|
||||
// This is a general purpose scaline container which supports the interface
|
||||
// used in the rasterizer::render(). See description of scanline_u8
|
||||
// for details.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_p8
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef scanline_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int16 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
//=============================================================scanline_p8
|
||||
//
|
||||
// This is a general purpose scaline container which supports the interface
|
||||
// used in the rasterizer::render(). See description of scanline_u8
|
||||
// for details.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_p8
|
||||
{
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
public:
|
||||
typedef scanline_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int16 coord_type;
|
||||
|
||||
typedef span* iterator;
|
||||
typedef const span* const_iterator;
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
|
||||
scanline_p8()
|
||||
: m_last_x(0x7FFFFFF0)
|
||||
, m_covers()
|
||||
, m_cover_ptr(0)
|
||||
, m_spans()
|
||||
, m_cur_span(0)
|
||||
{}
|
||||
typedef span* iterator;
|
||||
typedef const span* const_iterator;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if (max_len > m_spans.size())
|
||||
scanline_p8() :
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_covers(),
|
||||
m_cover_ptr(0),
|
||||
m_spans(),
|
||||
m_cur_span(0)
|
||||
{
|
||||
m_spans.resize(max_len);
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = (cover_type)cover;
|
||||
if (x == m_last_x + 1 && m_cur_span->len > 0)
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
m_cur_span->len++;
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if(max_len > m_spans.size())
|
||||
{
|
||||
m_spans.resize(max_len);
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = 1;
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if (x == m_last_x + 1 && m_cur_span->len > 0)
|
||||
{
|
||||
m_cur_span->len += (int16)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)len;
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
{
|
||||
if (x == m_last_x + 1 && m_cur_span->len < 0 && cover == *m_cur_span->covers)
|
||||
{
|
||||
m_cur_span->len -= (int16)len;
|
||||
}
|
||||
else
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = (cover_type)cover;
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr++;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)(-int(len));
|
||||
if(x == m_last_x+1 && m_cur_span->len > 0)
|
||||
{
|
||||
m_cur_span->len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = 1;
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y) { m_y = y; }
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if(x == m_last_x+1 && m_cur_span->len > 0)
|
||||
{
|
||||
m_cur_span->len += (int16)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)len;
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
{
|
||||
if(x == m_last_x+1 &&
|
||||
m_cur_span->len < 0 &&
|
||||
cover == *m_cur_span->covers)
|
||||
{
|
||||
m_cur_span->len -= (int16)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_cover_ptr = (cover_type)cover;
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr++;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)(-int(len));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
private:
|
||||
scanline_p8(const self_type&);
|
||||
const self_type& operator=(const self_type&);
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
|
||||
//==========================================================scanline32_p8
|
||||
class scanline32_p8
|
||||
{
|
||||
public:
|
||||
typedef scanline32_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int32 coord_type;
|
||||
private:
|
||||
scanline_p8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
struct span
|
||||
{
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_, const cover_type* covers_)
|
||||
: x(x_)
|
||||
, len(len_)
|
||||
, covers(covers_)
|
||||
{}
|
||||
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator(const span_array_type& spans)
|
||||
: m_spans(spans)
|
||||
, m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator++() { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_p8()
|
||||
: m_max_len(0)
|
||||
, m_last_x(0x7FFFFFF0)
|
||||
, m_covers()
|
||||
, m_cover_ptr(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if (max_len > m_covers.size())
|
||||
{
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = cover_type(cover);
|
||||
if (x == m_last_x + 1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if (x == m_last_x + 1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
|
||||
|
||||
|
||||
//==========================================================scanline32_p8
|
||||
class scanline32_p8
|
||||
{
|
||||
if (x == m_last_x + 1 && m_spans.size() && m_spans.last().len < 0 && cover == *m_spans.last().covers)
|
||||
public:
|
||||
typedef scanline32_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int32 coord_type;
|
||||
|
||||
struct span
|
||||
{
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_, const cover_type* covers_) :
|
||||
x(x_), len(len_), covers(covers_) {}
|
||||
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator(const span_array_type& spans) :
|
||||
m_spans(spans),
|
||||
m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator ++ () { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_p8() :
|
||||
m_max_len(0),
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_covers(),
|
||||
m_cover_ptr(0)
|
||||
{
|
||||
m_spans.last().len -= coord_type(len);
|
||||
}
|
||||
else
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if(max_len > m_covers.size())
|
||||
{
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = cover_type(cover);
|
||||
m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
|
||||
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y) { m_y = y; }
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
{
|
||||
if(x == m_last_x+1 &&
|
||||
m_spans.size() &&
|
||||
m_spans.last().len < 0 &&
|
||||
cover == *m_spans.last().covers)
|
||||
{
|
||||
m_spans.last().len -= coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_cover_ptr = cover_type(cover);
|
||||
m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
private:
|
||||
scanline32_p8(const self_type&);
|
||||
const self_type& operator=(const self_type&);
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
unsigned m_max_len;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
|
||||
private:
|
||||
scanline32_p8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
unsigned m_max_len;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
|
1384
deps/agg/include/agg_scanline_storage_aa.h
vendored
1384
deps/agg/include/agg_scanline_storage_aa.h
vendored
File diff suppressed because it is too large
Load diff
943
deps/agg/include/agg_scanline_storage_bin.h
vendored
943
deps/agg/include/agg_scanline_storage_bin.h
vendored
File diff suppressed because it is too large
Load diff
893
deps/agg/include/agg_scanline_u.h
vendored
893
deps/agg/include/agg_scanline_u.h
vendored
|
@ -26,456 +26,475 @@
|
|||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
//=============================================================scanline_u8
|
||||
//
|
||||
// Unpacked scanline container class
|
||||
//
|
||||
// This class is used to transfer data from a scanline rasterizer
|
||||
// to the rendering buffer. It's organized very simple. The class stores
|
||||
// information of horizontal spans to render it into a pixel-map buffer.
|
||||
// Each span has staring X, length, and an array of bytes that determine the
|
||||
// cover-values for each pixel.
|
||||
// Before using this class you should know the minimal and maximal pixel
|
||||
// coordinates of your scanline. The protocol of using is:
|
||||
// 1. reset(min_x, max_x)
|
||||
// 2. add_cell() / add_span() - accumulate scanline.
|
||||
// When forming one scanline the next X coordinate must be always greater
|
||||
// than the last stored one, i.e. it works only with ordered coordinates.
|
||||
// 3. Call finalize(y) and render the scanline.
|
||||
// 3. Call reset_spans() to prepare for the new scanline.
|
||||
//
|
||||
// 4. Rendering:
|
||||
//
|
||||
// Scanline provides an iterator class that allows you to extract
|
||||
// the spans and the cover values for each pixel. Be aware that clipping
|
||||
// has not been done yet, so you should perform it yourself.
|
||||
// Use scanline_u8::iterator to render spans:
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// int y = sl.y(); // Y-coordinate of the scanline
|
||||
//
|
||||
// ************************************
|
||||
// ...Perform vertical clipping here...
|
||||
// ************************************
|
||||
//
|
||||
// scanline_u8::const_iterator span = sl.begin();
|
||||
//
|
||||
// unsigned char* row = m_rbuf->row(y); // The the address of the beginning
|
||||
// // of the current row
|
||||
//
|
||||
// unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that
|
||||
// // num_spans is always greater than 0.
|
||||
//
|
||||
// do
|
||||
// {
|
||||
// const scanline_u8::cover_type* covers =
|
||||
// span->covers; // The array of the cover values
|
||||
//
|
||||
// int num_pix = span->len; // Number of pixels of the span.
|
||||
// // Always greater than 0, still it's
|
||||
// // better to use "int" instead of
|
||||
// // "unsigned" because it's more
|
||||
// // convenient for clipping
|
||||
// int x = span->x;
|
||||
//
|
||||
// **************************************
|
||||
// ...Perform horizontal clipping here...
|
||||
// ...you have x, covers, and pix_count..
|
||||
// **************************************
|
||||
//
|
||||
// unsigned char* dst = row + x; // Calculate the start address of the row.
|
||||
// // In this case we assume a simple
|
||||
// // grayscale image 1-byte per pixel.
|
||||
// do
|
||||
// {
|
||||
// *dst++ = *covers++; // Hypotetical rendering.
|
||||
// }
|
||||
// while(--num_pix);
|
||||
//
|
||||
// ++span;
|
||||
// }
|
||||
// while(--num_spans); // num_spans cannot be 0, so this loop is quite safe
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// The question is: why should we accumulate the whole scanline when we
|
||||
// could render just separate spans when they're ready?
|
||||
// That's because using the scanline is generally faster. When is consists
|
||||
// of more than one span the conditions for the processor cash system
|
||||
// are better, because switching between two different areas of memory
|
||||
// (that can be very large) occurs less frequently.
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_u8
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef scanline_u8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int16 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
//=============================================================scanline_u8
|
||||
//
|
||||
// Unpacked scanline container class
|
||||
//
|
||||
// This class is used to transfer data from a scanline rasterizer
|
||||
// to the rendering buffer. It's organized very simple. The class stores
|
||||
// information of horizontal spans to render it into a pixel-map buffer.
|
||||
// Each span has staring X, length, and an array of bytes that determine the
|
||||
// cover-values for each pixel.
|
||||
// Before using this class you should know the minimal and maximal pixel
|
||||
// coordinates of your scanline. The protocol of using is:
|
||||
// 1. reset(min_x, max_x)
|
||||
// 2. add_cell() / add_span() - accumulate scanline.
|
||||
// When forming one scanline the next X coordinate must be always greater
|
||||
// than the last stored one, i.e. it works only with ordered coordinates.
|
||||
// 3. Call finalize(y) and render the scanline.
|
||||
// 3. Call reset_spans() to prepare for the new scanline.
|
||||
//
|
||||
// 4. Rendering:
|
||||
//
|
||||
// Scanline provides an iterator class that allows you to extract
|
||||
// the spans and the cover values for each pixel. Be aware that clipping
|
||||
// has not been done yet, so you should perform it yourself.
|
||||
// Use scanline_u8::iterator to render spans:
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// int y = sl.y(); // Y-coordinate of the scanline
|
||||
//
|
||||
// ************************************
|
||||
// ...Perform vertical clipping here...
|
||||
// ************************************
|
||||
//
|
||||
// scanline_u8::const_iterator span = sl.begin();
|
||||
//
|
||||
// unsigned char* row = m_rbuf->row(y); // The the address of the beginning
|
||||
// // of the current row
|
||||
//
|
||||
// unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that
|
||||
// // num_spans is always greater than 0.
|
||||
//
|
||||
// do
|
||||
// {
|
||||
// const scanline_u8::cover_type* covers =
|
||||
// span->covers; // The array of the cover values
|
||||
//
|
||||
// int num_pix = span->len; // Number of pixels of the span.
|
||||
// // Always greater than 0, still it's
|
||||
// // better to use "int" instead of
|
||||
// // "unsigned" because it's more
|
||||
// // convenient for clipping
|
||||
// int x = span->x;
|
||||
//
|
||||
// **************************************
|
||||
// ...Perform horizontal clipping here...
|
||||
// ...you have x, covers, and pix_count..
|
||||
// **************************************
|
||||
//
|
||||
// unsigned char* dst = row + x; // Calculate the start address of the row.
|
||||
// // In this case we assume a simple
|
||||
// // grayscale image 1-byte per pixel.
|
||||
// do
|
||||
// {
|
||||
// *dst++ = *covers++; // Hypotetical rendering.
|
||||
// }
|
||||
// while(--num_pix);
|
||||
//
|
||||
// ++span;
|
||||
// }
|
||||
// while(--num_spans); // num_spans cannot be 0, so this loop is quite safe
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// The question is: why should we accumulate the whole scanline when we
|
||||
// could render just separate spans when they're ready?
|
||||
// That's because using the scanline is generally faster. When is consists
|
||||
// of more than one span the conditions for the processor cash system
|
||||
// are better, because switching between two different areas of memory
|
||||
// (that can be very large) occurs less frequently.
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_u8
|
||||
{
|
||||
coord_type x;
|
||||
coord_type len;
|
||||
cover_type* covers;
|
||||
};
|
||||
public:
|
||||
typedef scanline_u8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int16 coord_type;
|
||||
|
||||
typedef span* iterator;
|
||||
typedef const span* const_iterator;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline_u8()
|
||||
: m_min_x(0)
|
||||
, m_last_x(0x7FFFFFF0)
|
||||
, m_cur_span(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 2;
|
||||
if (max_len > m_spans.size())
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
m_spans.resize(max_len);
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_min_x = min_x;
|
||||
m_cur_span = &m_spans[0];
|
||||
}
|
||||
coord_type x;
|
||||
coord_type len;
|
||||
cover_type* covers;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
x -= m_min_x;
|
||||
m_covers[x] = (cover_type)cover;
|
||||
if (x == m_last_x + 1)
|
||||
typedef span* iterator;
|
||||
typedef const span* const_iterator;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline_u8() :
|
||||
m_min_x(0),
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_cur_span(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
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 cover_type* covers)
|
||||
{
|
||||
x -= m_min_x;
|
||||
memcpy(&m_covers[x], covers, len * sizeof(cover_type));
|
||||
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[0];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
iterator begin() { return &m_spans[1]; }
|
||||
|
||||
private:
|
||||
scanline_u8(const self_type&);
|
||||
const self_type& operator=(const self_type&);
|
||||
|
||||
private:
|
||||
int m_min_x;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
|
||||
//==========================================================scanline_u8_am
|
||||
//
|
||||
// The scanline container with alpha-masking
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
template<class AlphaMask>
|
||||
class scanline_u8_am : public scanline_u8
|
||||
{
|
||||
public:
|
||||
typedef scanline_u8 base_type;
|
||||
typedef AlphaMask alpha_mask_type;
|
||||
typedef base_type::cover_type cover_type;
|
||||
typedef base_type::coord_type coord_type;
|
||||
|
||||
scanline_u8_am()
|
||||
: base_type()
|
||||
, m_alpha_mask(0)
|
||||
{}
|
||||
scanline_u8_am(const AlphaMask& am)
|
||||
: base_type()
|
||||
, m_alpha_mask(&am)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int span_y)
|
||||
{
|
||||
base_type::finalize(span_y);
|
||||
if (m_alpha_mask)
|
||||
{
|
||||
typename base_type::iterator span = base_type::begin();
|
||||
unsigned count = base_type::num_spans();
|
||||
do
|
||||
unsigned max_len = max_x - min_x + 2;
|
||||
if(max_len > m_spans.size())
|
||||
{
|
||||
m_alpha_mask->combine_hspan(span->x, base_type::y(), span->covers, span->len);
|
||||
++span;
|
||||
} while (--count);
|
||||
m_spans.resize(max_len);
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_min_x = min_x;
|
||||
m_cur_span = &m_spans[0];
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const AlphaMask* m_alpha_mask;
|
||||
};
|
||||
|
||||
//===========================================================scanline32_u8
|
||||
class scanline32_u8
|
||||
{
|
||||
public:
|
||||
typedef scanline32_u8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int32 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_, cover_type* covers_)
|
||||
: x(x_)
|
||||
, len(len_)
|
||||
, covers(covers_)
|
||||
{}
|
||||
|
||||
coord_type x;
|
||||
coord_type len;
|
||||
cover_type* covers;
|
||||
};
|
||||
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator(const span_array_type& spans)
|
||||
: m_spans(spans)
|
||||
, m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator++() { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
iterator(span_array_type& spans)
|
||||
: m_spans(spans)
|
||||
, m_span_idx(0)
|
||||
{}
|
||||
|
||||
span& operator*() { return m_spans[m_span_idx]; }
|
||||
span* operator->() { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator++() { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_u8()
|
||||
: m_min_x(0)
|
||||
, m_last_x(0x7FFFFFF0)
|
||||
, m_covers()
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 2;
|
||||
if (max_len > m_covers.size())
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_min_x = min_x;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
x -= m_min_x;
|
||||
m_covers[x] = cover_type(cover);
|
||||
if (x == m_last_x + 1)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x]));
|
||||
}
|
||||
m_last_x = x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
x -= m_min_x;
|
||||
memcpy(&m_covers[x], covers, len * sizeof(cover_type));
|
||||
if (x == m_last_x + 1)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x + m_min_x), coord_type(len), &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_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x + m_min_x), coord_type(len), &m_covers[x]));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y) { m_y = y; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
iterator begin() { return iterator(m_spans); }
|
||||
|
||||
private:
|
||||
scanline32_u8(const self_type&);
|
||||
const self_type& operator=(const self_type&);
|
||||
|
||||
private:
|
||||
int m_min_x;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
|
||||
//========================================================scanline32_u8_am
|
||||
//
|
||||
// The scanline container with alpha-masking
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
template<class AlphaMask>
|
||||
class scanline32_u8_am : public scanline32_u8
|
||||
{
|
||||
public:
|
||||
typedef scanline32_u8 base_type;
|
||||
typedef AlphaMask alpha_mask_type;
|
||||
typedef base_type::cover_type cover_type;
|
||||
typedef base_type::coord_type coord_type;
|
||||
|
||||
scanline32_u8_am()
|
||||
: base_type()
|
||||
, m_alpha_mask(0)
|
||||
{}
|
||||
scanline32_u8_am(const AlphaMask& am)
|
||||
: base_type()
|
||||
, m_alpha_mask(&am)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int span_y)
|
||||
{
|
||||
base_type::finalize(span_y);
|
||||
if (m_alpha_mask)
|
||||
{
|
||||
typename base_type::iterator span = base_type::begin();
|
||||
unsigned count = base_type::num_spans();
|
||||
do
|
||||
x -= m_min_x;
|
||||
m_covers[x] = (cover_type)cover;
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_alpha_mask->combine_hspan(span->x, base_type::y(), span->covers, span->len);
|
||||
++span;
|
||||
} while (--count);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const AlphaMask* m_alpha_mask;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
x -= m_min_x;
|
||||
memcpy(&m_covers[x], covers, len * sizeof(cover_type));
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
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[0];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
iterator begin() { return &m_spans[1]; }
|
||||
|
||||
private:
|
||||
scanline_u8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
private:
|
||||
int m_min_x;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================scanline_u8_am
|
||||
//
|
||||
// The scanline container with alpha-masking
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
template<class AlphaMask>
|
||||
class scanline_u8_am : public scanline_u8
|
||||
{
|
||||
public:
|
||||
typedef scanline_u8 base_type;
|
||||
typedef AlphaMask alpha_mask_type;
|
||||
typedef base_type::cover_type cover_type;
|
||||
typedef base_type::coord_type coord_type;
|
||||
|
||||
scanline_u8_am() : base_type(), m_alpha_mask(0) {}
|
||||
scanline_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int span_y)
|
||||
{
|
||||
base_type::finalize(span_y);
|
||||
if(m_alpha_mask)
|
||||
{
|
||||
typename base_type::iterator span = base_type::begin();
|
||||
unsigned count = base_type::num_spans();
|
||||
do
|
||||
{
|
||||
m_alpha_mask->combine_hspan(span->x,
|
||||
base_type::y(),
|
||||
span->covers,
|
||||
span->len);
|
||||
++span;
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const AlphaMask* m_alpha_mask;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//===========================================================scanline32_u8
|
||||
class scanline32_u8
|
||||
{
|
||||
public:
|
||||
typedef scanline32_u8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int32 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_, cover_type* covers_) :
|
||||
x(x_), len(len_), covers(covers_) {}
|
||||
|
||||
coord_type x;
|
||||
coord_type len;
|
||||
cover_type* covers;
|
||||
};
|
||||
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator(const span_array_type& spans) :
|
||||
m_spans(spans),
|
||||
m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator ++ () { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
iterator(span_array_type& spans) :
|
||||
m_spans(spans),
|
||||
m_span_idx(0)
|
||||
{}
|
||||
|
||||
span& operator*() { return m_spans[m_span_idx]; }
|
||||
span* operator->() { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator ++ () { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_u8() :
|
||||
m_min_x(0),
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_covers()
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 2;
|
||||
if(max_len > m_covers.size())
|
||||
{
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_min_x = min_x;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
x -= m_min_x;
|
||||
m_covers[x] = cover_type(cover);
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x]));
|
||||
}
|
||||
m_last_x = x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
x -= m_min_x;
|
||||
memcpy(&m_covers[x], covers, len * sizeof(cover_type));
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x + m_min_x),
|
||||
coord_type(len),
|
||||
&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_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x + m_min_x),
|
||||
coord_type(len),
|
||||
&m_covers[x]));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
iterator begin() { return iterator(m_spans); }
|
||||
|
||||
private:
|
||||
scanline32_u8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
private:
|
||||
int m_min_x;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//========================================================scanline32_u8_am
|
||||
//
|
||||
// The scanline container with alpha-masking
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
template<class AlphaMask>
|
||||
class scanline32_u8_am : public scanline32_u8
|
||||
{
|
||||
public:
|
||||
typedef scanline32_u8 base_type;
|
||||
typedef AlphaMask alpha_mask_type;
|
||||
typedef base_type::cover_type cover_type;
|
||||
typedef base_type::coord_type coord_type;
|
||||
|
||||
|
||||
scanline32_u8_am() : base_type(), m_alpha_mask(0) {}
|
||||
scanline32_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int span_y)
|
||||
{
|
||||
base_type::finalize(span_y);
|
||||
if(m_alpha_mask)
|
||||
{
|
||||
typename base_type::iterator span = base_type::begin();
|
||||
unsigned count = base_type::num_spans();
|
||||
do
|
||||
{
|
||||
m_alpha_mask->combine_hspan(span->x,
|
||||
base_type::y(),
|
||||
span->covers,
|
||||
span->len);
|
||||
++span;
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const AlphaMask* m_alpha_mask;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
70
deps/agg/include/agg_shorten_path.h
vendored
70
deps/agg/include/agg_shorten_path.h
vendored
|
@ -19,48 +19,48 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//===========================================================shorten_path
|
||||
template<class VertexSequence>
|
||||
void shorten_path(VertexSequence& vs, double s, unsigned closed = 0)
|
||||
namespace agg
|
||||
{
|
||||
typedef typename VertexSequence::value_type vertex_type;
|
||||
|
||||
if (s > 0.0 && vs.size() > 1)
|
||||
//===========================================================shorten_path
|
||||
template<class VertexSequence>
|
||||
void shorten_path(VertexSequence& vs, double s, unsigned closed = 0)
|
||||
{
|
||||
double d;
|
||||
int n = int(vs.size() - 2);
|
||||
while (n)
|
||||
typedef typename VertexSequence::value_type vertex_type;
|
||||
|
||||
if(s > 0.0 && vs.size() > 1)
|
||||
{
|
||||
d = vs[n].dist;
|
||||
if (d > s)
|
||||
break;
|
||||
vs.remove_last();
|
||||
s -= d;
|
||||
--n;
|
||||
}
|
||||
if (vs.size() < 2)
|
||||
{
|
||||
vs.remove_all();
|
||||
}
|
||||
else
|
||||
{
|
||||
n = vs.size() - 1;
|
||||
vertex_type& prev = vs[n - 1];
|
||||
vertex_type& last = vs[n];
|
||||
d = (prev.dist - s) / prev.dist;
|
||||
double x = prev.x + (last.x - prev.x) * d;
|
||||
double y = prev.y + (last.y - prev.y) * d;
|
||||
last.x = x;
|
||||
last.y = y;
|
||||
if (!prev(last))
|
||||
double d;
|
||||
int n = int(vs.size() - 2);
|
||||
while(n)
|
||||
{
|
||||
d = vs[n].dist;
|
||||
if(d > s) break;
|
||||
vs.remove_last();
|
||||
vs.close(closed != 0);
|
||||
s -= d;
|
||||
--n;
|
||||
}
|
||||
if(vs.size() < 2)
|
||||
{
|
||||
vs.remove_all();
|
||||
}
|
||||
else
|
||||
{
|
||||
n = vs.size() - 1;
|
||||
vertex_type& prev = vs[n-1];
|
||||
vertex_type& last = vs[n];
|
||||
d = (prev.dist - s) / prev.dist;
|
||||
double x = prev.x + (last.x - prev.x) * d;
|
||||
double y = prev.y + (last.y - prev.y) * d;
|
||||
last.x = x;
|
||||
last.y = y;
|
||||
if(!prev(last)) vs.remove_last();
|
||||
vs.close(closed != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
227
deps/agg/include/agg_simul_eq.h
vendored
227
deps/agg/include/agg_simul_eq.h
vendored
|
@ -22,119 +22,126 @@
|
|||
#include <cmath>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=============================================================swap_arrays
|
||||
template<class T>
|
||||
void swap_arrays(T* a1, T* a2, unsigned n)
|
||||
namespace agg
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < n; i++)
|
||||
|
||||
//=============================================================swap_arrays
|
||||
template<class T> void swap_arrays(T* a1, T* a2, unsigned n)
|
||||
{
|
||||
T tmp = *a1;
|
||||
*a1++ = *a2;
|
||||
*a2++ = tmp;
|
||||
unsigned i;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
T tmp = *a1;
|
||||
*a1++ = *a2;
|
||||
*a2++ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================matrix_pivot
|
||||
template<unsigned Rows, unsigned Cols>
|
||||
struct matrix_pivot
|
||||
{
|
||||
static int pivot(double m[Rows][Cols], unsigned row)
|
||||
{
|
||||
int k = int(row);
|
||||
double max_val, tmp;
|
||||
|
||||
max_val = -1.0;
|
||||
unsigned i;
|
||||
for(i = row; i < Rows; i++)
|
||||
{
|
||||
if((tmp = std::fabs(m[i][row])) > max_val && tmp != 0.0)
|
||||
{
|
||||
max_val = tmp;
|
||||
k = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(m[k][row] == 0.0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(k != int(row))
|
||||
{
|
||||
swap_arrays(m[k], m[row], Cols);
|
||||
return k;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//===============================================================simul_eq
|
||||
template<unsigned Size, unsigned RightCols>
|
||||
struct simul_eq
|
||||
{
|
||||
static bool solve(const double left[Size][Size],
|
||||
const double right[Size][RightCols],
|
||||
double result[Size][RightCols])
|
||||
{
|
||||
unsigned i, j, k;
|
||||
double a1;
|
||||
|
||||
double tmp[Size][Size + RightCols];
|
||||
|
||||
for(i = 0; i < Size; i++)
|
||||
{
|
||||
for(j = 0; j < Size; j++)
|
||||
{
|
||||
tmp[i][j] = left[i][j];
|
||||
}
|
||||
for(j = 0; j < RightCols; j++)
|
||||
{
|
||||
tmp[i][Size + j] = right[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for(k = 0; k < Size; k++)
|
||||
{
|
||||
if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0)
|
||||
{
|
||||
return false; // Singularity....
|
||||
}
|
||||
|
||||
a1 = tmp[k][k];
|
||||
|
||||
for(j = k; j < Size + RightCols; j++)
|
||||
{
|
||||
tmp[k][j] /= a1;
|
||||
}
|
||||
|
||||
for(i = k + 1; i < Size; i++)
|
||||
{
|
||||
a1 = tmp[i][k];
|
||||
for (j = k; j < Size + RightCols; j++)
|
||||
{
|
||||
tmp[i][j] -= a1 * tmp[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(k = 0; k < RightCols; k++)
|
||||
{
|
||||
int m;
|
||||
for(m = int(Size - 1); m >= 0; m--)
|
||||
{
|
||||
result[m][k] = tmp[m][Size + k];
|
||||
for(j = m + 1; j < Size; j++)
|
||||
{
|
||||
result[m][k] -= tmp[m][j] * result[j][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
//============================================================matrix_pivot
|
||||
template<unsigned Rows, unsigned Cols>
|
||||
struct matrix_pivot
|
||||
{
|
||||
static int pivot(double m[Rows][Cols], unsigned row)
|
||||
{
|
||||
int k = int(row);
|
||||
double max_val, tmp;
|
||||
|
||||
max_val = -1.0;
|
||||
unsigned i;
|
||||
for (i = row; i < Rows; i++)
|
||||
{
|
||||
if ((tmp = std::fabs(m[i][row])) > max_val && tmp != 0.0)
|
||||
{
|
||||
max_val = tmp;
|
||||
k = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (m[k][row] == 0.0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (k != int(row))
|
||||
{
|
||||
swap_arrays(m[k], m[row], Cols);
|
||||
return k;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//===============================================================simul_eq
|
||||
template<unsigned Size, unsigned RightCols>
|
||||
struct simul_eq
|
||||
{
|
||||
static bool
|
||||
solve(const double left[Size][Size], const double right[Size][RightCols], double result[Size][RightCols])
|
||||
{
|
||||
unsigned i, j, k;
|
||||
double a1;
|
||||
|
||||
double tmp[Size][Size + RightCols];
|
||||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
for (j = 0; j < Size; j++)
|
||||
{
|
||||
tmp[i][j] = left[i][j];
|
||||
}
|
||||
for (j = 0; j < RightCols; j++)
|
||||
{
|
||||
tmp[i][Size + j] = right[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < Size; k++)
|
||||
{
|
||||
if (matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0)
|
||||
{
|
||||
return false; // Singularity....
|
||||
}
|
||||
|
||||
a1 = tmp[k][k];
|
||||
|
||||
for (j = k; j < Size + RightCols; j++)
|
||||
{
|
||||
tmp[k][j] /= a1;
|
||||
}
|
||||
|
||||
for (i = k + 1; i < Size; i++)
|
||||
{
|
||||
a1 = tmp[i][k];
|
||||
for (j = k; j < Size + RightCols; j++)
|
||||
{
|
||||
tmp[i][j] -= a1 * tmp[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < RightCols; k++)
|
||||
{
|
||||
int m;
|
||||
for (m = int(Size - 1); m >= 0; m--)
|
||||
{
|
||||
result[m][k] = tmp[m][Size + k];
|
||||
for (j = m + 1; j < Size; j++)
|
||||
{
|
||||
result[m][k] -= tmp[m][j] * result[j][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
49
deps/agg/include/agg_span_allocator.h
vendored
49
deps/agg/include/agg_span_allocator.h
vendored
|
@ -18,34 +18,37 @@
|
|||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
//----------------------------------------------------------span_allocator
|
||||
template<class ColorT>
|
||||
class span_allocator
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE color_type* allocate(unsigned span_len)
|
||||
//----------------------------------------------------------span_allocator
|
||||
template<class ColorT> class span_allocator
|
||||
{
|
||||
if (span_len > m_span.size())
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE color_type* allocate(unsigned span_len)
|
||||
{
|
||||
// To reduce the number of reallocs we align the
|
||||
// span_len to 256 color elements.
|
||||
// Well, I just like this number and it looks reasonable.
|
||||
//-----------------------
|
||||
m_span.resize(((span_len + 255) >> 8) << 8);
|
||||
if(span_len > m_span.size())
|
||||
{
|
||||
// To reduce the number of reallocs we align the
|
||||
// span_len to 256 color elements.
|
||||
// Well, I just like this number and it looks reasonable.
|
||||
//-----------------------
|
||||
m_span.resize(((span_len + 255) >> 8) << 8);
|
||||
}
|
||||
return &m_span[0];
|
||||
}
|
||||
return &m_span[0];
|
||||
}
|
||||
|
||||
AGG_INLINE color_type* span() { return &m_span[0]; }
|
||||
AGG_INLINE unsigned max_span_len() const { return m_span.size(); }
|
||||
AGG_INLINE color_type* span() { return &m_span[0]; }
|
||||
AGG_INLINE unsigned max_span_len() const { return m_span.size(); }
|
||||
|
||||
private:
|
||||
pod_array<color_type> m_span;
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
pod_array<color_type> m_span;
|
||||
};
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
60
deps/agg/include/agg_span_converter.h
vendored
60
deps/agg/include/agg_span_converter.h
vendored
|
@ -18,41 +18,39 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
//----------------------------------------------------------span_converter
|
||||
template<class SpanGenerator, class SpanConverter>
|
||||
class span_converter
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef typename SpanGenerator::color_type color_type;
|
||||
|
||||
span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv)
|
||||
: m_span_gen(&span_gen)
|
||||
, m_span_cnv(&span_cnv)
|
||||
{}
|
||||
|
||||
void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; }
|
||||
void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
//----------------------------------------------------------span_converter
|
||||
template<class SpanGenerator, class SpanConverter> class span_converter
|
||||
{
|
||||
m_span_gen->prepare();
|
||||
m_span_cnv->prepare();
|
||||
}
|
||||
public:
|
||||
typedef typename SpanGenerator::color_type color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
m_span_gen->generate(span, x, y, len);
|
||||
m_span_cnv->generate(span, x, y, len);
|
||||
}
|
||||
span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv) :
|
||||
m_span_gen(&span_gen), m_span_cnv(&span_cnv) {}
|
||||
|
||||
private:
|
||||
SpanGenerator* m_span_gen;
|
||||
SpanConverter* m_span_cnv;
|
||||
};
|
||||
void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; }
|
||||
void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; }
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
m_span_gen->prepare();
|
||||
m_span_cnv->prepare();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
m_span_gen->generate(span, x, y, len);
|
||||
m_span_cnv->generate(span, x, y, len);
|
||||
}
|
||||
|
||||
private:
|
||||
SpanGenerator* m_span_gen;
|
||||
SpanConverter* m_span_cnv;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
310
deps/agg/include/agg_span_gouraud.h
vendored
310
deps/agg/include/agg_span_gouraud.h
vendored
|
@ -19,176 +19,154 @@
|
|||
#include "agg_basics.h"
|
||||
#include "agg_math.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//============================================================span_gouraud
|
||||
template<class ColorT>
|
||||
class span_gouraud
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
struct coord_type
|
||||
//============================================================span_gouraud
|
||||
template<class ColorT> class span_gouraud
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
color_type color;
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
struct coord_type
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
color_type color;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud() :
|
||||
m_vertex(0)
|
||||
{
|
||||
m_cmd[0] = path_cmd_stop;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud(const color_type& c1,
|
||||
const color_type& c2,
|
||||
const color_type& c3,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double d) :
|
||||
m_vertex(0)
|
||||
{
|
||||
colors(c1, c2, c3);
|
||||
triangle(x1, y1, x2, y2, x3, y3, d);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void colors(ColorT c1, ColorT c2, ColorT c3)
|
||||
{
|
||||
m_coord[0].color = c1;
|
||||
m_coord[1].color = c2;
|
||||
m_coord[2].color = c3;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Sets the triangle and dilates it if needed.
|
||||
// The trick here is to calculate beveled joins in the vertices of the
|
||||
// triangle and render it as a 6-vertex polygon.
|
||||
// It's necessary to achieve numerical stability.
|
||||
// However, the coordinates to interpolate colors are calculated
|
||||
// as miter joins (calc_intersection).
|
||||
void triangle(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double d)
|
||||
{
|
||||
m_coord[0].x = m_x[0] = x1;
|
||||
m_coord[0].y = m_y[0] = y1;
|
||||
m_coord[1].x = m_x[1] = x2;
|
||||
m_coord[1].y = m_y[1] = y2;
|
||||
m_coord[2].x = m_x[2] = x3;
|
||||
m_coord[2].y = m_y[2] = y3;
|
||||
m_cmd[0] = path_cmd_move_to;
|
||||
m_cmd[1] = path_cmd_line_to;
|
||||
m_cmd[2] = path_cmd_line_to;
|
||||
m_cmd[3] = path_cmd_stop;
|
||||
|
||||
if(d != 0.0)
|
||||
{
|
||||
dilate_triangle(m_coord[0].x, m_coord[0].y,
|
||||
m_coord[1].x, m_coord[1].y,
|
||||
m_coord[2].x, m_coord[2].y,
|
||||
m_x, m_y, d);
|
||||
|
||||
calc_intersection(m_x[4], m_y[4], m_x[5], m_y[5],
|
||||
m_x[0], m_y[0], m_x[1], m_y[1],
|
||||
&m_coord[0].x, &m_coord[0].y);
|
||||
|
||||
calc_intersection(m_x[0], m_y[0], m_x[1], m_y[1],
|
||||
m_x[2], m_y[2], m_x[3], m_y[3],
|
||||
&m_coord[1].x, &m_coord[1].y);
|
||||
|
||||
calc_intersection(m_x[2], m_y[2], m_x[3], m_y[3],
|
||||
m_x[4], m_y[4], m_x[5], m_y[5],
|
||||
&m_coord[2].x, &m_coord[2].y);
|
||||
m_cmd[3] = path_cmd_line_to;
|
||||
m_cmd[4] = path_cmd_line_to;
|
||||
m_cmd[5] = path_cmd_line_to;
|
||||
m_cmd[6] = path_cmd_stop;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Vertex Source Interface to feed the coordinates to the rasterizer
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_vertex = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
*x = m_x[m_vertex];
|
||||
*y = m_y[m_vertex];
|
||||
return m_cmd[m_vertex++];
|
||||
}
|
||||
|
||||
protected:
|
||||
//--------------------------------------------------------------------
|
||||
void arrange_vertices(coord_type* coord) const
|
||||
{
|
||||
coord[0] = m_coord[0];
|
||||
coord[1] = m_coord[1];
|
||||
coord[2] = m_coord[2];
|
||||
|
||||
if(m_coord[0].y > m_coord[2].y)
|
||||
{
|
||||
coord[0] = m_coord[2];
|
||||
coord[2] = m_coord[0];
|
||||
}
|
||||
|
||||
coord_type tmp;
|
||||
if(coord[0].y > coord[1].y)
|
||||
{
|
||||
tmp = coord[1];
|
||||
coord[1] = coord[0];
|
||||
coord[0] = tmp;
|
||||
}
|
||||
|
||||
if(coord[1].y > coord[2].y)
|
||||
{
|
||||
tmp = coord[2];
|
||||
coord[2] = coord[1];
|
||||
coord[1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
coord_type m_coord[3];
|
||||
double m_x[8];
|
||||
double m_y[8];
|
||||
unsigned m_cmd[8];
|
||||
unsigned m_vertex;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud()
|
||||
: m_vertex(0)
|
||||
{
|
||||
m_cmd[0] = path_cmd_stop;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud(const color_type& c1,
|
||||
const color_type& c2,
|
||||
const color_type& c3,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2,
|
||||
double x3,
|
||||
double y3,
|
||||
double d)
|
||||
: m_vertex(0)
|
||||
{
|
||||
colors(c1, c2, c3);
|
||||
triangle(x1, y1, x2, y2, x3, y3, d);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void colors(ColorT c1, ColorT c2, ColorT c3)
|
||||
{
|
||||
m_coord[0].color = c1;
|
||||
m_coord[1].color = c2;
|
||||
m_coord[2].color = c3;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Sets the triangle and dilates it if needed.
|
||||
// The trick here is to calculate beveled joins in the vertices of the
|
||||
// triangle and render it as a 6-vertex polygon.
|
||||
// It's necessary to achieve numerical stability.
|
||||
// However, the coordinates to interpolate colors are calculated
|
||||
// as miter joins (calc_intersection).
|
||||
void triangle(double x1, double y1, double x2, double y2, double x3, double y3, double d)
|
||||
{
|
||||
m_coord[0].x = m_x[0] = x1;
|
||||
m_coord[0].y = m_y[0] = y1;
|
||||
m_coord[1].x = m_x[1] = x2;
|
||||
m_coord[1].y = m_y[1] = y2;
|
||||
m_coord[2].x = m_x[2] = x3;
|
||||
m_coord[2].y = m_y[2] = y3;
|
||||
m_cmd[0] = path_cmd_move_to;
|
||||
m_cmd[1] = path_cmd_line_to;
|
||||
m_cmd[2] = path_cmd_line_to;
|
||||
m_cmd[3] = path_cmd_stop;
|
||||
|
||||
if (d != 0.0)
|
||||
{
|
||||
dilate_triangle(m_coord[0].x,
|
||||
m_coord[0].y,
|
||||
m_coord[1].x,
|
||||
m_coord[1].y,
|
||||
m_coord[2].x,
|
||||
m_coord[2].y,
|
||||
m_x,
|
||||
m_y,
|
||||
d);
|
||||
|
||||
calc_intersection(m_x[4],
|
||||
m_y[4],
|
||||
m_x[5],
|
||||
m_y[5],
|
||||
m_x[0],
|
||||
m_y[0],
|
||||
m_x[1],
|
||||
m_y[1],
|
||||
&m_coord[0].x,
|
||||
&m_coord[0].y);
|
||||
|
||||
calc_intersection(m_x[0],
|
||||
m_y[0],
|
||||
m_x[1],
|
||||
m_y[1],
|
||||
m_x[2],
|
||||
m_y[2],
|
||||
m_x[3],
|
||||
m_y[3],
|
||||
&m_coord[1].x,
|
||||
&m_coord[1].y);
|
||||
|
||||
calc_intersection(m_x[2],
|
||||
m_y[2],
|
||||
m_x[3],
|
||||
m_y[3],
|
||||
m_x[4],
|
||||
m_y[4],
|
||||
m_x[5],
|
||||
m_y[5],
|
||||
&m_coord[2].x,
|
||||
&m_coord[2].y);
|
||||
m_cmd[3] = path_cmd_line_to;
|
||||
m_cmd[4] = path_cmd_line_to;
|
||||
m_cmd[5] = path_cmd_line_to;
|
||||
m_cmd[6] = path_cmd_stop;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Vertex Source Interface to feed the coordinates to the rasterizer
|
||||
void rewind(unsigned) { m_vertex = 0; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
*x = m_x[m_vertex];
|
||||
*y = m_y[m_vertex];
|
||||
return m_cmd[m_vertex++];
|
||||
}
|
||||
|
||||
protected:
|
||||
//--------------------------------------------------------------------
|
||||
void arrange_vertices(coord_type* coord) const
|
||||
{
|
||||
coord[0] = m_coord[0];
|
||||
coord[1] = m_coord[1];
|
||||
coord[2] = m_coord[2];
|
||||
|
||||
if (m_coord[0].y > m_coord[2].y)
|
||||
{
|
||||
coord[0] = m_coord[2];
|
||||
coord[2] = m_coord[0];
|
||||
}
|
||||
|
||||
coord_type tmp;
|
||||
if (coord[0].y > coord[1].y)
|
||||
{
|
||||
tmp = coord[1];
|
||||
coord[1] = coord[0];
|
||||
coord[0] = tmp;
|
||||
}
|
||||
|
||||
if (coord[1].y > coord[2].y)
|
||||
{
|
||||
tmp = coord[2];
|
||||
coord[2] = coord[1];
|
||||
coord[1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
coord_type m_coord[3];
|
||||
double m_x[8];
|
||||
double m_y[8];
|
||||
unsigned m_cmd[8];
|
||||
unsigned m_vertex;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
401
deps/agg/include/agg_span_gouraud_gray.h
vendored
401
deps/agg/include/agg_span_gouraud_gray.h
vendored
|
@ -29,222 +29,213 @@
|
|||
#include "agg_dda_line.h"
|
||||
#include "agg_span_gouraud.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=======================================================span_gouraud_gray
|
||||
template<class ColorT>
|
||||
class span_gouraud_gray : public span_gouraud<ColorT>
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef span_gouraud<color_type> base_type;
|
||||
typedef typename base_type::coord_type coord_type;
|
||||
enum subpixel_scale_e { subpixel_shift = 4, subpixel_scale = 1 << subpixel_shift };
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
struct gray_calc
|
||||
//=======================================================span_gouraud_gray
|
||||
template<class ColorT> class span_gouraud_gray : public span_gouraud<ColorT>
|
||||
{
|
||||
void init(const coord_type& c1, const coord_type& c2)
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef span_gouraud<color_type> base_type;
|
||||
typedef typename base_type::coord_type coord_type;
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
m_x1 = c1.x - 0.5;
|
||||
m_y1 = c1.y - 0.5;
|
||||
m_dx = c2.x - c1.x;
|
||||
double dy = c2.y - c1.y;
|
||||
m_1dy = (std::fabs(dy) < 1e-10) ? 1e10 : 1.0 / dy;
|
||||
m_v1 = c1.color.v;
|
||||
m_a1 = c1.color.a;
|
||||
m_dv = c2.color.v - m_v1;
|
||||
m_da = c2.color.a - m_a1;
|
||||
subpixel_shift = 4,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
struct gray_calc
|
||||
{
|
||||
void init(const coord_type& c1, const coord_type& c2)
|
||||
{
|
||||
m_x1 = c1.x - 0.5;
|
||||
m_y1 = c1.y - 0.5;
|
||||
m_dx = c2.x - c1.x;
|
||||
double dy = c2.y - c1.y;
|
||||
m_1dy = (std::fabs(dy) < 1e-10) ? 1e10 : 1.0 / dy;
|
||||
m_v1 = c1.color.v;
|
||||
m_a1 = c1.color.a;
|
||||
m_dv = c2.color.v - m_v1;
|
||||
m_da = c2.color.a - m_a1;
|
||||
}
|
||||
|
||||
void calc(double y)
|
||||
{
|
||||
double k = (y - m_y1) * m_1dy;
|
||||
if(k < 0.0) k = 0.0;
|
||||
if(k > 1.0) k = 1.0;
|
||||
m_v = m_v1 + iround(m_dv * k);
|
||||
m_a = m_a1 + iround(m_da * k);
|
||||
m_x = iround((m_x1 + m_dx * k) * subpixel_scale);
|
||||
}
|
||||
|
||||
double m_x1;
|
||||
double m_y1;
|
||||
double m_dx;
|
||||
double m_1dy;
|
||||
int m_v1;
|
||||
int m_a1;
|
||||
int m_dv;
|
||||
int m_da;
|
||||
int m_v;
|
||||
int m_a;
|
||||
int m_x;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud_gray() {}
|
||||
span_gouraud_gray(const color_type& c1,
|
||||
const color_type& c2,
|
||||
const color_type& c3,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double d = 0) :
|
||||
base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
coord_type coord[3];
|
||||
base_type::arrange_vertices(coord);
|
||||
|
||||
m_y2 = int(coord[1].y);
|
||||
|
||||
m_swap = cross_product(coord[0].x, coord[0].y,
|
||||
coord[2].x, coord[2].y,
|
||||
coord[1].x, coord[1].y) < 0.0;
|
||||
|
||||
m_c1.init(coord[0], coord[2]);
|
||||
m_c2.init(coord[0], coord[1]);
|
||||
m_c3.init(coord[1], coord[2]);
|
||||
}
|
||||
|
||||
void calc(double y)
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
double k = (y - m_y1) * m_1dy;
|
||||
if (k < 0.0)
|
||||
k = 0.0;
|
||||
if (k > 1.0)
|
||||
k = 1.0;
|
||||
m_v = m_v1 + iround(m_dv * k);
|
||||
m_a = m_a1 + iround(m_da * k);
|
||||
m_x = iround((m_x1 + m_dx * k) * subpixel_scale);
|
||||
m_c1.calc(y);
|
||||
const gray_calc* pc1 = &m_c1;
|
||||
const gray_calc* pc2 = &m_c2;
|
||||
|
||||
if(y < m_y2)
|
||||
{
|
||||
// Bottom part of the triangle (first subtriangle)
|
||||
//-------------------------
|
||||
m_c2.calc(y + m_c2.m_1dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Upper part (second subtriangle)
|
||||
//-------------------------
|
||||
m_c3.calc(y - m_c3.m_1dy);
|
||||
pc2 = &m_c3;
|
||||
}
|
||||
|
||||
if(m_swap)
|
||||
{
|
||||
// It means that the triangle is oriented clockwise,
|
||||
// so that we need to swap the controlling structures
|
||||
//-------------------------
|
||||
const gray_calc* t = pc2;
|
||||
pc2 = pc1;
|
||||
pc1 = t;
|
||||
}
|
||||
|
||||
// Get the horizontal length with subpixel accuracy
|
||||
// and protect it from division by zero
|
||||
//-------------------------
|
||||
int nlen = std::abs(pc2->m_x - pc1->m_x);
|
||||
if(nlen <= 0) nlen = 1;
|
||||
|
||||
dda_line_interpolator<14> v(pc1->m_v, pc2->m_v, nlen);
|
||||
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
|
||||
|
||||
// Calculate the starting point of the gradient with subpixel
|
||||
// accuracy and correct (roll back) the interpolators.
|
||||
// This operation will also clip the beginning of the span
|
||||
// if necessary.
|
||||
//-------------------------
|
||||
int start = pc1->m_x - (x << subpixel_shift);
|
||||
v -= start;
|
||||
a -= start;
|
||||
nlen += start;
|
||||
|
||||
int vv, va;
|
||||
enum lim_e { lim = color_type::base_mask };
|
||||
|
||||
// Beginning part of the span. Since we rolled back the
|
||||
// interpolators, the color values may have overflow.
|
||||
// So that, we render the beginning part with checking
|
||||
// for overflow. It lasts until "start" is positive;
|
||||
// typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while(len && start > 0)
|
||||
{
|
||||
vv = v.y();
|
||||
va = a.y();
|
||||
if(vv < 0) vv = 0; if(vv > lim) vv = lim;
|
||||
if(va < 0) va = 0; if(va > lim) va = lim;
|
||||
span->v = (value_type)vv;
|
||||
span->a = (value_type)va;
|
||||
v += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
start -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Middle part, no checking for overflow.
|
||||
// Actual spans can be longer than the calculated length
|
||||
// because of anti-aliasing, thus, the interpolators can
|
||||
// overflow. But while "nlen" is positive we are safe.
|
||||
//-------------------------
|
||||
while(len && nlen > 0)
|
||||
{
|
||||
span->v = (value_type)v.y();
|
||||
span->a = (value_type)a.y();
|
||||
v += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Ending part; checking for overflow.
|
||||
// Typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while(len)
|
||||
{
|
||||
vv = v.y();
|
||||
va = a.y();
|
||||
if(vv < 0) vv = 0; if(vv > lim) vv = lim;
|
||||
if(va < 0) va = 0; if(va > lim) va = lim;
|
||||
span->v = (value_type)vv;
|
||||
span->a = (value_type)va;
|
||||
v += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
|
||||
double m_x1;
|
||||
double m_y1;
|
||||
double m_dx;
|
||||
double m_1dy;
|
||||
int m_v1;
|
||||
int m_a1;
|
||||
int m_dv;
|
||||
int m_da;
|
||||
int m_v;
|
||||
int m_a;
|
||||
int m_x;
|
||||
|
||||
private:
|
||||
bool m_swap;
|
||||
int m_y2;
|
||||
gray_calc m_c1;
|
||||
gray_calc m_c2;
|
||||
gray_calc m_c3;
|
||||
};
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud_gray() {}
|
||||
span_gouraud_gray(const color_type& c1,
|
||||
const color_type& c2,
|
||||
const color_type& c3,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2,
|
||||
double x3,
|
||||
double y3,
|
||||
double d = 0)
|
||||
: base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
coord_type coord[3];
|
||||
base_type::arrange_vertices(coord);
|
||||
|
||||
m_y2 = int(coord[1].y);
|
||||
|
||||
m_swap = cross_product(coord[0].x, coord[0].y, coord[2].x, coord[2].y, coord[1].x, coord[1].y) < 0.0;
|
||||
|
||||
m_c1.init(coord[0], coord[2]);
|
||||
m_c2.init(coord[0], coord[1]);
|
||||
m_c3.init(coord[1], coord[2]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
m_c1.calc(y);
|
||||
const gray_calc* pc1 = &m_c1;
|
||||
const gray_calc* pc2 = &m_c2;
|
||||
|
||||
if (y < m_y2)
|
||||
{
|
||||
// Bottom part of the triangle (first subtriangle)
|
||||
//-------------------------
|
||||
m_c2.calc(y + m_c2.m_1dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Upper part (second subtriangle)
|
||||
//-------------------------
|
||||
m_c3.calc(y - m_c3.m_1dy);
|
||||
pc2 = &m_c3;
|
||||
}
|
||||
|
||||
if (m_swap)
|
||||
{
|
||||
// It means that the triangle is oriented clockwise,
|
||||
// so that we need to swap the controlling structures
|
||||
//-------------------------
|
||||
const gray_calc* t = pc2;
|
||||
pc2 = pc1;
|
||||
pc1 = t;
|
||||
}
|
||||
|
||||
// Get the horizontal length with subpixel accuracy
|
||||
// and protect it from division by zero
|
||||
//-------------------------
|
||||
int nlen = std::abs(pc2->m_x - pc1->m_x);
|
||||
if (nlen <= 0)
|
||||
nlen = 1;
|
||||
|
||||
dda_line_interpolator<14> v(pc1->m_v, pc2->m_v, nlen);
|
||||
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
|
||||
|
||||
// Calculate the starting point of the gradient with subpixel
|
||||
// accuracy and correct (roll back) the interpolators.
|
||||
// This operation will also clip the beginning of the span
|
||||
// if necessary.
|
||||
//-------------------------
|
||||
int start = pc1->m_x - (x << subpixel_shift);
|
||||
v -= start;
|
||||
a -= start;
|
||||
nlen += start;
|
||||
|
||||
int vv, va;
|
||||
enum lim_e { lim = color_type::base_mask };
|
||||
|
||||
// Beginning part of the span. Since we rolled back the
|
||||
// interpolators, the color values may have overflow.
|
||||
// So that, we render the beginning part with checking
|
||||
// for overflow. It lasts until "start" is positive;
|
||||
// typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while (len && start > 0)
|
||||
{
|
||||
vv = v.y();
|
||||
va = a.y();
|
||||
if (vv < 0)
|
||||
vv = 0;
|
||||
if (vv > lim)
|
||||
vv = lim;
|
||||
if (va < 0)
|
||||
va = 0;
|
||||
if (va > lim)
|
||||
va = lim;
|
||||
span->v = (value_type)vv;
|
||||
span->a = (value_type)va;
|
||||
v += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
start -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Middle part, no checking for overflow.
|
||||
// Actual spans can be longer than the calculated length
|
||||
// because of anti-aliasing, thus, the interpolators can
|
||||
// overflow. But while "nlen" is positive we are safe.
|
||||
//-------------------------
|
||||
while (len && nlen > 0)
|
||||
{
|
||||
span->v = (value_type)v.y();
|
||||
span->a = (value_type)a.y();
|
||||
v += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Ending part; checking for overflow.
|
||||
// Typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while (len)
|
||||
{
|
||||
vv = v.y();
|
||||
va = a.y();
|
||||
if (vv < 0)
|
||||
vv = 0;
|
||||
if (vv > lim)
|
||||
vv = lim;
|
||||
if (va < 0)
|
||||
va = 0;
|
||||
if (va > lim)
|
||||
va = lim;
|
||||
span->v = (value_type)vv;
|
||||
span->a = (value_type)va;
|
||||
v += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_swap;
|
||||
int m_y2;
|
||||
gray_calc m_c1;
|
||||
gray_calc m_c2;
|
||||
gray_calc m_c3;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
484
deps/agg/include/agg_span_gouraud_rgba.h
vendored
484
deps/agg/include/agg_span_gouraud_rgba.h
vendored
|
@ -29,271 +29,249 @@
|
|||
#include "agg_dda_line.h"
|
||||
#include "agg_span_gouraud.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//=======================================================span_gouraud_rgba
|
||||
template<class ColorT>
|
||||
class span_gouraud_rgba : public span_gouraud<ColorT>
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
typedef typename ColorT::value_type value_type;
|
||||
typedef span_gouraud<color_type> base_type;
|
||||
typedef typename base_type::coord_type coord_type;
|
||||
enum subpixel_scale_e { subpixel_shift = 4, subpixel_scale = 1 << subpixel_shift };
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
struct rgba_calc
|
||||
//=======================================================span_gouraud_rgba
|
||||
template<class ColorT> class span_gouraud_rgba : public span_gouraud<ColorT>
|
||||
{
|
||||
void init(const coord_type& c1, const coord_type& c2)
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
typedef typename ColorT::value_type value_type;
|
||||
typedef span_gouraud<color_type> base_type;
|
||||
typedef typename base_type::coord_type coord_type;
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
m_x1 = c1.x - 0.5;
|
||||
m_y1 = c1.y - 0.5;
|
||||
m_dx = c2.x - c1.x;
|
||||
double dy = c2.y - c1.y;
|
||||
m_1dy = (dy < 1e-5) ? 1e5 : 1.0 / dy;
|
||||
m_r1 = c1.color.r;
|
||||
m_g1 = c1.color.g;
|
||||
m_b1 = c1.color.b;
|
||||
m_a1 = c1.color.a;
|
||||
m_dr = c2.color.r - m_r1;
|
||||
m_dg = c2.color.g - m_g1;
|
||||
m_db = c2.color.b - m_b1;
|
||||
m_da = c2.color.a - m_a1;
|
||||
subpixel_shift = 4,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
struct rgba_calc
|
||||
{
|
||||
void init(const coord_type& c1, const coord_type& c2)
|
||||
{
|
||||
m_x1 = c1.x - 0.5;
|
||||
m_y1 = c1.y - 0.5;
|
||||
m_dx = c2.x - c1.x;
|
||||
double dy = c2.y - c1.y;
|
||||
m_1dy = (dy < 1e-5) ? 1e5 : 1.0 / dy;
|
||||
m_r1 = c1.color.r;
|
||||
m_g1 = c1.color.g;
|
||||
m_b1 = c1.color.b;
|
||||
m_a1 = c1.color.a;
|
||||
m_dr = c2.color.r - m_r1;
|
||||
m_dg = c2.color.g - m_g1;
|
||||
m_db = c2.color.b - m_b1;
|
||||
m_da = c2.color.a - m_a1;
|
||||
}
|
||||
|
||||
void calc(double y)
|
||||
{
|
||||
double k = (y - m_y1) * m_1dy;
|
||||
if(k < 0.0) k = 0.0;
|
||||
if(k > 1.0) k = 1.0;
|
||||
m_r = m_r1 + iround(m_dr * k);
|
||||
m_g = m_g1 + iround(m_dg * k);
|
||||
m_b = m_b1 + iround(m_db * k);
|
||||
m_a = m_a1 + iround(m_da * k);
|
||||
m_x = iround((m_x1 + m_dx * k) * subpixel_scale);
|
||||
}
|
||||
|
||||
double m_x1;
|
||||
double m_y1;
|
||||
double m_dx;
|
||||
double m_1dy;
|
||||
int m_r1;
|
||||
int m_g1;
|
||||
int m_b1;
|
||||
int m_a1;
|
||||
int m_dr;
|
||||
int m_dg;
|
||||
int m_db;
|
||||
int m_da;
|
||||
int m_r;
|
||||
int m_g;
|
||||
int m_b;
|
||||
int m_a;
|
||||
int m_x;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud_rgba() {}
|
||||
span_gouraud_rgba(const color_type& c1,
|
||||
const color_type& c2,
|
||||
const color_type& c3,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double d = 0) :
|
||||
base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
coord_type coord[3];
|
||||
base_type::arrange_vertices(coord);
|
||||
|
||||
m_y2 = int(coord[1].y);
|
||||
|
||||
m_swap = cross_product(coord[0].x, coord[0].y,
|
||||
coord[2].x, coord[2].y,
|
||||
coord[1].x, coord[1].y) < 0.0;
|
||||
|
||||
m_rgba1.init(coord[0], coord[2]);
|
||||
m_rgba2.init(coord[0], coord[1]);
|
||||
m_rgba3.init(coord[1], coord[2]);
|
||||
}
|
||||
|
||||
void calc(double y)
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
double k = (y - m_y1) * m_1dy;
|
||||
if (k < 0.0)
|
||||
k = 0.0;
|
||||
if (k > 1.0)
|
||||
k = 1.0;
|
||||
m_r = m_r1 + iround(m_dr * k);
|
||||
m_g = m_g1 + iround(m_dg * k);
|
||||
m_b = m_b1 + iround(m_db * k);
|
||||
m_a = m_a1 + iround(m_da * k);
|
||||
m_x = iround((m_x1 + m_dx * k) * subpixel_scale);
|
||||
m_rgba1.calc(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
|
||||
const rgba_calc* pc1 = &m_rgba1;
|
||||
const rgba_calc* pc2 = &m_rgba2;
|
||||
|
||||
if(y <= m_y2)
|
||||
{
|
||||
// Bottom part of the triangle (first subtriangle)
|
||||
//-------------------------
|
||||
m_rgba2.calc(y + m_rgba2.m_1dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Upper part (second subtriangle)
|
||||
m_rgba3.calc(y - m_rgba3.m_1dy);
|
||||
//-------------------------
|
||||
pc2 = &m_rgba3;
|
||||
}
|
||||
|
||||
if(m_swap)
|
||||
{
|
||||
// It means that the triangle is oriented clockwise,
|
||||
// so that we need to swap the controlling structures
|
||||
//-------------------------
|
||||
const rgba_calc* t = pc2;
|
||||
pc2 = pc1;
|
||||
pc1 = t;
|
||||
}
|
||||
|
||||
// Get the horizontal length with subpixel accuracy
|
||||
// and protect it from division by zero
|
||||
//-------------------------
|
||||
int nlen = std::abs(pc2->m_x - pc1->m_x);
|
||||
if(nlen <= 0) nlen = 1;
|
||||
|
||||
dda_line_interpolator<14> r(pc1->m_r, pc2->m_r, nlen);
|
||||
dda_line_interpolator<14> g(pc1->m_g, pc2->m_g, nlen);
|
||||
dda_line_interpolator<14> b(pc1->m_b, pc2->m_b, nlen);
|
||||
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
|
||||
|
||||
// Calculate the starting point of the gradient with subpixel
|
||||
// accuracy and correct (roll back) the interpolators.
|
||||
// This operation will also clip the beginning of the span
|
||||
// if necessary.
|
||||
//-------------------------
|
||||
int start = pc1->m_x - (x << subpixel_shift);
|
||||
r -= start;
|
||||
g -= start;
|
||||
b -= start;
|
||||
a -= start;
|
||||
nlen += start;
|
||||
|
||||
int vr, vg, vb, va;
|
||||
enum lim_e { lim = color_type::base_mask };
|
||||
|
||||
// Beginning part of the span. Since we rolled back the
|
||||
// interpolators, the color values may have overflow.
|
||||
// So that, we render the beginning part with checking
|
||||
// for overflow. It lasts until "start" is positive;
|
||||
// typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while(len && start > 0)
|
||||
{
|
||||
vr = r.y();
|
||||
vg = g.y();
|
||||
vb = b.y();
|
||||
va = a.y();
|
||||
if(vr < 0) vr = 0; if(vr > lim) vr = lim;
|
||||
if(vg < 0) vg = 0; if(vg > lim) vg = lim;
|
||||
if(vb < 0) vb = 0; if(vb > lim) vb = lim;
|
||||
if(va < 0) va = 0; if(va > lim) va = lim;
|
||||
span->r = (value_type)vr;
|
||||
span->g = (value_type)vg;
|
||||
span->b = (value_type)vb;
|
||||
span->a = (value_type)va;
|
||||
r += subpixel_scale;
|
||||
g += subpixel_scale;
|
||||
b += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
start -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Middle part, no checking for overflow.
|
||||
// Actual spans can be longer than the calculated length
|
||||
// because of anti-aliasing, thus, the interpolators can
|
||||
// overflow. But while "nlen" is positive we are safe.
|
||||
//-------------------------
|
||||
while(len && nlen > 0)
|
||||
{
|
||||
span->r = (value_type)r.y();
|
||||
span->g = (value_type)g.y();
|
||||
span->b = (value_type)b.y();
|
||||
span->a = (value_type)a.y();
|
||||
r += subpixel_scale;
|
||||
g += subpixel_scale;
|
||||
b += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Ending part; checking for overflow.
|
||||
// Typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while(len)
|
||||
{
|
||||
vr = r.y();
|
||||
vg = g.y();
|
||||
vb = b.y();
|
||||
va = a.y();
|
||||
if(vr < 0) vr = 0; if(vr > lim) vr = lim;
|
||||
if(vg < 0) vg = 0; if(vg > lim) vg = lim;
|
||||
if(vb < 0) vb = 0; if(vb > lim) vb = lim;
|
||||
if(va < 0) va = 0; if(va > lim) va = lim;
|
||||
span->r = (value_type)vr;
|
||||
span->g = (value_type)vg;
|
||||
span->b = (value_type)vb;
|
||||
span->a = (value_type)va;
|
||||
r += subpixel_scale;
|
||||
g += subpixel_scale;
|
||||
b += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
|
||||
double m_x1;
|
||||
double m_y1;
|
||||
double m_dx;
|
||||
double m_1dy;
|
||||
int m_r1;
|
||||
int m_g1;
|
||||
int m_b1;
|
||||
int m_a1;
|
||||
int m_dr;
|
||||
int m_dg;
|
||||
int m_db;
|
||||
int m_da;
|
||||
int m_r;
|
||||
int m_g;
|
||||
int m_b;
|
||||
int m_a;
|
||||
int m_x;
|
||||
private:
|
||||
bool m_swap;
|
||||
int m_y2;
|
||||
rgba_calc m_rgba1;
|
||||
rgba_calc m_rgba2;
|
||||
rgba_calc m_rgba3;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gouraud_rgba() {}
|
||||
span_gouraud_rgba(const color_type& c1,
|
||||
const color_type& c2,
|
||||
const color_type& c3,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2,
|
||||
double x3,
|
||||
double y3,
|
||||
double d = 0)
|
||||
: base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
coord_type coord[3];
|
||||
base_type::arrange_vertices(coord);
|
||||
|
||||
m_y2 = int(coord[1].y);
|
||||
|
||||
m_swap = cross_product(coord[0].x, coord[0].y, coord[2].x, coord[2].y, coord[1].x, coord[1].y) < 0.0;
|
||||
|
||||
m_rgba1.init(coord[0], coord[2]);
|
||||
m_rgba2.init(coord[0], coord[1]);
|
||||
m_rgba3.init(coord[1], coord[2]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
m_rgba1.calc(y); //(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
|
||||
const rgba_calc* pc1 = &m_rgba1;
|
||||
const rgba_calc* pc2 = &m_rgba2;
|
||||
|
||||
if (y <= m_y2)
|
||||
{
|
||||
// Bottom part of the triangle (first subtriangle)
|
||||
//-------------------------
|
||||
m_rgba2.calc(y + m_rgba2.m_1dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Upper part (second subtriangle)
|
||||
m_rgba3.calc(y - m_rgba3.m_1dy);
|
||||
//-------------------------
|
||||
pc2 = &m_rgba3;
|
||||
}
|
||||
|
||||
if (m_swap)
|
||||
{
|
||||
// It means that the triangle is oriented clockwise,
|
||||
// so that we need to swap the controlling structures
|
||||
//-------------------------
|
||||
const rgba_calc* t = pc2;
|
||||
pc2 = pc1;
|
||||
pc1 = t;
|
||||
}
|
||||
|
||||
// Get the horizontal length with subpixel accuracy
|
||||
// and protect it from division by zero
|
||||
//-------------------------
|
||||
int nlen = std::abs(pc2->m_x - pc1->m_x);
|
||||
if (nlen <= 0)
|
||||
nlen = 1;
|
||||
|
||||
dda_line_interpolator<14> r(pc1->m_r, pc2->m_r, nlen);
|
||||
dda_line_interpolator<14> g(pc1->m_g, pc2->m_g, nlen);
|
||||
dda_line_interpolator<14> b(pc1->m_b, pc2->m_b, nlen);
|
||||
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
|
||||
|
||||
// Calculate the starting point of the gradient with subpixel
|
||||
// accuracy and correct (roll back) the interpolators.
|
||||
// This operation will also clip the beginning of the span
|
||||
// if necessary.
|
||||
//-------------------------
|
||||
int start = pc1->m_x - (x << subpixel_shift);
|
||||
r -= start;
|
||||
g -= start;
|
||||
b -= start;
|
||||
a -= start;
|
||||
nlen += start;
|
||||
|
||||
int vr, vg, vb, va;
|
||||
enum lim_e { lim = color_type::base_mask };
|
||||
|
||||
// Beginning part of the span. Since we rolled back the
|
||||
// interpolators, the color values may have overflow.
|
||||
// So that, we render the beginning part with checking
|
||||
// for overflow. It lasts until "start" is positive;
|
||||
// typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while (len && start > 0)
|
||||
{
|
||||
vr = r.y();
|
||||
vg = g.y();
|
||||
vb = b.y();
|
||||
va = a.y();
|
||||
if (vr < 0)
|
||||
vr = 0;
|
||||
if (vr > lim)
|
||||
vr = lim;
|
||||
if (vg < 0)
|
||||
vg = 0;
|
||||
if (vg > lim)
|
||||
vg = lim;
|
||||
if (vb < 0)
|
||||
vb = 0;
|
||||
if (vb > lim)
|
||||
vb = lim;
|
||||
if (va < 0)
|
||||
va = 0;
|
||||
if (va > lim)
|
||||
va = lim;
|
||||
span->r = (value_type)vr;
|
||||
span->g = (value_type)vg;
|
||||
span->b = (value_type)vb;
|
||||
span->a = (value_type)va;
|
||||
r += subpixel_scale;
|
||||
g += subpixel_scale;
|
||||
b += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
start -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Middle part, no checking for overflow.
|
||||
// Actual spans can be longer than the calculated length
|
||||
// because of anti-aliasing, thus, the interpolators can
|
||||
// overflow. But while "nlen" is positive we are safe.
|
||||
//-------------------------
|
||||
while (len && nlen > 0)
|
||||
{
|
||||
span->r = (value_type)r.y();
|
||||
span->g = (value_type)g.y();
|
||||
span->b = (value_type)b.y();
|
||||
span->a = (value_type)a.y();
|
||||
r += subpixel_scale;
|
||||
g += subpixel_scale;
|
||||
b += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
nlen -= subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
|
||||
// Ending part; checking for overflow.
|
||||
// Typically it's 1-2 pixels, but may be more in some cases.
|
||||
//-------------------------
|
||||
while (len)
|
||||
{
|
||||
vr = r.y();
|
||||
vg = g.y();
|
||||
vb = b.y();
|
||||
va = a.y();
|
||||
if (vr < 0)
|
||||
vr = 0;
|
||||
if (vr > lim)
|
||||
vr = lim;
|
||||
if (vg < 0)
|
||||
vg = 0;
|
||||
if (vg > lim)
|
||||
vg = lim;
|
||||
if (vb < 0)
|
||||
vb = 0;
|
||||
if (vb > lim)
|
||||
vb = lim;
|
||||
if (va < 0)
|
||||
va = 0;
|
||||
if (va > lim)
|
||||
va = lim;
|
||||
span->r = (value_type)vr;
|
||||
span->g = (value_type)vg;
|
||||
span->b = (value_type)vb;
|
||||
span->a = (value_type)va;
|
||||
r += subpixel_scale;
|
||||
g += subpixel_scale;
|
||||
b += subpixel_scale;
|
||||
a += subpixel_scale;
|
||||
++span;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_swap;
|
||||
int m_y2;
|
||||
rgba_calc m_rgba1;
|
||||
rgba_calc m_rgba2;
|
||||
rgba_calc m_rgba3;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
598
deps/agg/include/agg_span_gradient.h
vendored
598
deps/agg/include/agg_span_gradient.h
vendored
|
@ -23,326 +23,342 @@
|
|||
#include "agg_math.h"
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
enum gradient_subpixel_scale_e {
|
||||
gradient_subpixel_shift = 4, //-----gradient_subpixel_shift
|
||||
gradient_subpixel_scale = 1 << gradient_subpixel_shift, //-----gradient_subpixel_scale
|
||||
gradient_subpixel_mask = gradient_subpixel_scale - 1 //-----gradient_subpixel_mask
|
||||
};
|
||||
|
||||
//==========================================================span_gradient
|
||||
template<class ColorT, class Interpolator, class GradientF, class ColorF>
|
||||
class span_gradient
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef ColorT color_type;
|
||||
|
||||
enum downscale_shift_e { downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient(interpolator_type& inter,
|
||||
const GradientF& gradient_function,
|
||||
const ColorF& color_function,
|
||||
double d1,
|
||||
double d2)
|
||||
: m_interpolator(&inter)
|
||||
, m_gradient_function(&gradient_function)
|
||||
, m_color_function(&color_function)
|
||||
, m_d1(iround(d1 * gradient_subpixel_scale))
|
||||
, m_d2(iround(d2 * gradient_subpixel_scale))
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
interpolator_type& interpolator() { return *m_interpolator; }
|
||||
const GradientF& gradient_function() const { return *m_gradient_function; }
|
||||
const ColorF& color_function() const { return *m_color_function; }
|
||||
double d1() const { return double(m_d1) / gradient_subpixel_scale; }
|
||||
double d2() const { return double(m_d2) / gradient_subpixel_scale; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void interpolator(interpolator_type& i) { m_interpolator = &i; }
|
||||
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
|
||||
void color_function(const ColorF& cf) { m_color_function = &cf; }
|
||||
void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
|
||||
void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
enum gradient_subpixel_scale_e
|
||||
{
|
||||
int dd = m_d2 - m_d1;
|
||||
if (dd < 1)
|
||||
dd = 1;
|
||||
m_interpolator->begin(x + 0.5, y + 0.5, len);
|
||||
do
|
||||
gradient_subpixel_shift = 4, //-----gradient_subpixel_shift
|
||||
gradient_subpixel_scale = 1 << gradient_subpixel_shift, //-----gradient_subpixel_scale
|
||||
gradient_subpixel_mask = gradient_subpixel_scale - 1 //-----gradient_subpixel_mask
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================================span_gradient
|
||||
template<class ColorT,
|
||||
class Interpolator,
|
||||
class GradientF,
|
||||
class ColorF>
|
||||
class span_gradient
|
||||
{
|
||||
public:
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef ColorT color_type;
|
||||
|
||||
enum downscale_shift_e
|
||||
{
|
||||
m_interpolator->coordinates(&x, &y);
|
||||
int d = m_gradient_function->calculate(x >> downscale_shift, y >> downscale_shift, m_d2);
|
||||
d = ((d - m_d1) * (int)m_color_function->size()) / dd;
|
||||
if (d < 0)
|
||||
d = 0;
|
||||
if (d >= (int)m_color_function->size())
|
||||
d = m_color_function->size() - 1;
|
||||
*span++ = (*m_color_function)[d];
|
||||
++(*m_interpolator);
|
||||
} while (--len);
|
||||
}
|
||||
downscale_shift = interpolator_type::subpixel_shift -
|
||||
gradient_subpixel_shift
|
||||
};
|
||||
|
||||
private:
|
||||
interpolator_type* m_interpolator;
|
||||
const GradientF* m_gradient_function;
|
||||
const ColorF* m_color_function;
|
||||
int m_d1;
|
||||
int m_d2;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient() {}
|
||||
|
||||
//=====================================================gradient_linear_color
|
||||
template<class ColorT>
|
||||
struct gradient_linear_color
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient(interpolator_type& inter,
|
||||
const GradientF& gradient_function,
|
||||
const ColorF& color_function,
|
||||
double d1, double d2) :
|
||||
m_interpolator(&inter),
|
||||
m_gradient_function(&gradient_function),
|
||||
m_color_function(&color_function),
|
||||
m_d1(iround(d1 * gradient_subpixel_scale)),
|
||||
m_d2(iround(d2 * gradient_subpixel_scale))
|
||||
{}
|
||||
|
||||
gradient_linear_color() {}
|
||||
gradient_linear_color(const color_type& c1, const color_type& c2, unsigned size = 256)
|
||||
: m_c1(c1)
|
||||
, m_c2(c2)
|
||||
, m_size(size)
|
||||
{}
|
||||
//--------------------------------------------------------------------
|
||||
interpolator_type& interpolator() { return *m_interpolator; }
|
||||
const GradientF& gradient_function() const { return *m_gradient_function; }
|
||||
const ColorF& color_function() const { return *m_color_function; }
|
||||
double d1() const { return double(m_d1) / gradient_subpixel_scale; }
|
||||
double d2() const { return double(m_d2) / gradient_subpixel_scale; }
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
color_type operator[](unsigned v) const { return m_c1.gradient(m_c2, double(v) / double(m_size - 1)); }
|
||||
//--------------------------------------------------------------------
|
||||
void interpolator(interpolator_type& i) { m_interpolator = &i; }
|
||||
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
|
||||
void color_function(const ColorF& cf) { m_color_function = &cf; }
|
||||
void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
|
||||
void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
|
||||
|
||||
void colors(const color_type& c1, const color_type& c2, unsigned size = 256)
|
||||
{
|
||||
m_c1 = c1;
|
||||
m_c2 = c2;
|
||||
m_size = size;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
color_type m_c1;
|
||||
color_type m_c2;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
//==========================================================gradient_circle
|
||||
class gradient_circle
|
||||
{
|
||||
// Actually the same as radial. Just for compatibility
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int) { return int(fast_sqrt(x * x + y * y)); }
|
||||
};
|
||||
|
||||
//==========================================================gradient_radial
|
||||
class gradient_radial
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int) { return int(fast_sqrt(x * x + y * y)); }
|
||||
};
|
||||
|
||||
//========================================================gradient_radial_d
|
||||
class gradient_radial_d
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
{
|
||||
return uround(sqrt(double(x) * double(x) + double(y) * double(y)));
|
||||
}
|
||||
};
|
||||
|
||||
//====================================================gradient_radial_focus
|
||||
class gradient_radial_focus
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
gradient_radial_focus()
|
||||
: m_r(100 * gradient_subpixel_scale)
|
||||
, m_fx(0)
|
||||
, m_fy(0)
|
||||
{
|
||||
update_values();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
gradient_radial_focus(double r, double fx, double fy)
|
||||
: m_r(iround(r * gradient_subpixel_scale))
|
||||
, m_fx(iround(fx * gradient_subpixel_scale))
|
||||
, m_fy(iround(fy * gradient_subpixel_scale))
|
||||
{
|
||||
update_values();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void init(double r, double fx, double fy)
|
||||
{
|
||||
m_r = iround(r * gradient_subpixel_scale);
|
||||
m_fx = iround(fx * gradient_subpixel_scale);
|
||||
m_fy = iround(fy * gradient_subpixel_scale);
|
||||
update_values();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
double radius() const { return double(m_r) / gradient_subpixel_scale; }
|
||||
double focus_x() const { return double(m_fx) / gradient_subpixel_scale; }
|
||||
double focus_y() const { return double(m_fy) / gradient_subpixel_scale; }
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
int calculate(int x, int y, int) const
|
||||
{
|
||||
double dx = x - m_fx;
|
||||
double dy = y - m_fy;
|
||||
double d2 = dx * m_fy - dy * m_fx;
|
||||
double d3 = m_r2 * (dx * dx + dy * dy) - d2 * d2;
|
||||
return iround((dx * m_fx + dy * m_fy + sqrt(std::fabs(d3))) * m_mul);
|
||||
}
|
||||
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
void update_values()
|
||||
{
|
||||
// Calculate the invariant values. In case the focal center
|
||||
// lies exactly on the gradient circle the divisor degenerates
|
||||
// into zero. In this case we just move the focal center by
|
||||
// one subpixel unit possibly in the direction to the origin (0,0)
|
||||
// and calculate the values again.
|
||||
//-------------------------
|
||||
m_r2 = double(m_r) * double(m_r);
|
||||
m_fx2 = double(m_fx) * double(m_fx);
|
||||
m_fy2 = double(m_fy) * double(m_fy);
|
||||
double d = (m_r2 - (m_fx2 + m_fy2));
|
||||
if (d == 0)
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
if (m_fx)
|
||||
int dd = m_d2 - m_d1;
|
||||
if(dd < 1) dd = 1;
|
||||
m_interpolator->begin(x+0.5, y+0.5, len);
|
||||
do
|
||||
{
|
||||
if (m_fx < 0)
|
||||
++m_fx;
|
||||
else
|
||||
--m_fx;
|
||||
}
|
||||
if (m_fy)
|
||||
{
|
||||
if (m_fy < 0)
|
||||
++m_fy;
|
||||
else
|
||||
--m_fy;
|
||||
m_interpolator->coordinates(&x, &y);
|
||||
int d = m_gradient_function->calculate(x >> downscale_shift,
|
||||
y >> downscale_shift, m_d2);
|
||||
d = ((d - m_d1) * (int)m_color_function->size()) / dd;
|
||||
if(d < 0) d = 0;
|
||||
if(d >= (int)m_color_function->size()) d = m_color_function->size() - 1;
|
||||
*span++ = (*m_color_function)[d];
|
||||
++(*m_interpolator);
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
private:
|
||||
interpolator_type* m_interpolator;
|
||||
const GradientF* m_gradient_function;
|
||||
const ColorF* m_color_function;
|
||||
int m_d1;
|
||||
int m_d2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//=====================================================gradient_linear_color
|
||||
template<class ColorT>
|
||||
struct gradient_linear_color
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
|
||||
gradient_linear_color() {}
|
||||
gradient_linear_color(const color_type& c1, const color_type& c2,
|
||||
unsigned size = 256) :
|
||||
m_c1(c1), m_c2(c2), m_size(size) {}
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
color_type operator [] (unsigned v) const
|
||||
{
|
||||
return m_c1.gradient(m_c2, double(v) / double(m_size - 1));
|
||||
}
|
||||
|
||||
void colors(const color_type& c1, const color_type& c2, unsigned size = 256)
|
||||
{
|
||||
m_c1 = c1;
|
||||
m_c2 = c2;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
color_type m_c1;
|
||||
color_type m_c2;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================gradient_circle
|
||||
class gradient_circle
|
||||
{
|
||||
// Actually the same as radial. Just for compatibility
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
{
|
||||
return int(fast_sqrt(x*x + y*y));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==========================================================gradient_radial
|
||||
class gradient_radial
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
{
|
||||
return int(fast_sqrt(x*x + y*y));
|
||||
}
|
||||
};
|
||||
|
||||
//========================================================gradient_radial_d
|
||||
class gradient_radial_d
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
{
|
||||
return uround(sqrt(double(x)*double(x) + double(y)*double(y)));
|
||||
}
|
||||
};
|
||||
|
||||
//====================================================gradient_radial_focus
|
||||
class gradient_radial_focus
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
gradient_radial_focus() :
|
||||
m_r(100 * gradient_subpixel_scale),
|
||||
m_fx(0),
|
||||
m_fy(0)
|
||||
{
|
||||
update_values();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
gradient_radial_focus(double r, double fx, double fy) :
|
||||
m_r (iround(r * gradient_subpixel_scale)),
|
||||
m_fx(iround(fx * gradient_subpixel_scale)),
|
||||
m_fy(iround(fy * gradient_subpixel_scale))
|
||||
{
|
||||
update_values();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void init(double r, double fx, double fy)
|
||||
{
|
||||
m_r = iround(r * gradient_subpixel_scale);
|
||||
m_fx = iround(fx * gradient_subpixel_scale);
|
||||
m_fy = iround(fy * gradient_subpixel_scale);
|
||||
update_values();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
double radius() const { return double(m_r) / gradient_subpixel_scale; }
|
||||
double focus_x() const { return double(m_fx) / gradient_subpixel_scale; }
|
||||
double focus_y() const { return double(m_fy) / gradient_subpixel_scale; }
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
int calculate(int x, int y, int) const
|
||||
{
|
||||
double dx = x - m_fx;
|
||||
double dy = y - m_fy;
|
||||
double d2 = dx * m_fy - dy * m_fx;
|
||||
double d3 = m_r2 * (dx * dx + dy * dy) - d2 * d2;
|
||||
return iround((dx * m_fx + dy * m_fy + sqrt(std::fabs(d3))) * m_mul);
|
||||
}
|
||||
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
void update_values()
|
||||
{
|
||||
// Calculate the invariant values. In case the focal center
|
||||
// lies exactly on the gradient circle the divisor degenerates
|
||||
// into zero. In this case we just move the focal center by
|
||||
// one subpixel unit possibly in the direction to the origin (0,0)
|
||||
// and calculate the values again.
|
||||
//-------------------------
|
||||
m_r2 = double(m_r) * double(m_r);
|
||||
m_fx2 = double(m_fx) * double(m_fx);
|
||||
m_fy2 = double(m_fy) * double(m_fy);
|
||||
d = (m_r2 - (m_fx2 + m_fy2));
|
||||
double d = (m_r2 - (m_fx2 + m_fy2));
|
||||
if(d == 0)
|
||||
{
|
||||
if(m_fx) { if(m_fx < 0) ++m_fx; else --m_fx; }
|
||||
if(m_fy) { if(m_fy < 0) ++m_fy; else --m_fy; }
|
||||
m_fx2 = double(m_fx) * double(m_fx);
|
||||
m_fy2 = double(m_fy) * double(m_fy);
|
||||
d = (m_r2 - (m_fx2 + m_fy2));
|
||||
}
|
||||
m_mul = m_r / d;
|
||||
}
|
||||
m_mul = m_r / d;
|
||||
}
|
||||
|
||||
int m_r;
|
||||
int m_fx;
|
||||
int m_fy;
|
||||
double m_r2;
|
||||
double m_fx2;
|
||||
double m_fy2;
|
||||
double m_mul;
|
||||
};
|
||||
int m_r;
|
||||
int m_fx;
|
||||
int m_fy;
|
||||
double m_r2;
|
||||
double m_fx2;
|
||||
double m_fy2;
|
||||
double m_mul;
|
||||
};
|
||||
|
||||
//==============================================================gradient_x
|
||||
class gradient_x
|
||||
{
|
||||
public:
|
||||
static int calculate(int x, int, int) { return x; }
|
||||
};
|
||||
|
||||
//==============================================================gradient_y
|
||||
class gradient_y
|
||||
{
|
||||
public:
|
||||
static int calculate(int, int y, int) { return y; }
|
||||
};
|
||||
|
||||
//========================================================gradient_diamond
|
||||
class gradient_diamond
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
//==============================================================gradient_x
|
||||
class gradient_x
|
||||
{
|
||||
int ax = std::abs(x);
|
||||
int ay = std::abs(y);
|
||||
return ax > ay ? ax : ay;
|
||||
}
|
||||
};
|
||||
public:
|
||||
static int calculate(int x, int, int) { return x; }
|
||||
};
|
||||
|
||||
//=============================================================gradient_xy
|
||||
class gradient_xy
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int d) { return std::abs(x) * std::abs(y) / d; }
|
||||
};
|
||||
|
||||
//========================================================gradient_sqrt_xy
|
||||
class gradient_sqrt_xy
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int) { return fast_sqrt(std::abs(x) * std::abs(y)); }
|
||||
};
|
||||
|
||||
//==========================================================gradient_conic
|
||||
class gradient_conic
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int d)
|
||||
//==============================================================gradient_y
|
||||
class gradient_y
|
||||
{
|
||||
return uround(std::fabs(std::atan2(double(y), double(x))) * double(d) / pi);
|
||||
}
|
||||
};
|
||||
public:
|
||||
static int calculate(int, int y, int) { return y; }
|
||||
};
|
||||
|
||||
//=================================================gradient_repeat_adaptor
|
||||
template<class GradientF>
|
||||
class gradient_repeat_adaptor
|
||||
{
|
||||
public:
|
||||
gradient_repeat_adaptor(const GradientF& gradient)
|
||||
: m_gradient(&gradient)
|
||||
{}
|
||||
|
||||
AGG_INLINE int calculate(int x, int y, int d) const
|
||||
//========================================================gradient_diamond
|
||||
class gradient_diamond
|
||||
{
|
||||
int ret = m_gradient->calculate(x, y, d) % d;
|
||||
if (ret < 0)
|
||||
ret += d;
|
||||
return ret;
|
||||
}
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
{
|
||||
int ax = std::abs(x);
|
||||
int ay = std::abs(y);
|
||||
return ax > ay ? ax : ay;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
const GradientF* m_gradient;
|
||||
};
|
||||
|
||||
//================================================gradient_reflect_adaptor
|
||||
template<class GradientF>
|
||||
class gradient_reflect_adaptor
|
||||
{
|
||||
public:
|
||||
gradient_reflect_adaptor(const GradientF& gradient)
|
||||
: m_gradient(&gradient)
|
||||
{}
|
||||
|
||||
AGG_INLINE int calculate(int x, int y, int d) const
|
||||
//=============================================================gradient_xy
|
||||
class gradient_xy
|
||||
{
|
||||
int d2 = d << 1;
|
||||
int ret = m_gradient->calculate(x, y, d) % d2;
|
||||
if (ret < 0)
|
||||
ret += d2;
|
||||
if (ret >= d)
|
||||
ret = d2 - ret;
|
||||
return ret;
|
||||
}
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int d)
|
||||
{
|
||||
return std::abs(x) * std::abs(y) / d;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
const GradientF* m_gradient;
|
||||
};
|
||||
//========================================================gradient_sqrt_xy
|
||||
class gradient_sqrt_xy
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
{
|
||||
return fast_sqrt(std::abs(x) * std::abs(y));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
//==========================================================gradient_conic
|
||||
class gradient_conic
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int d)
|
||||
{
|
||||
return uround(std::fabs(std::atan2(double(y), double(x))) * double(d) / pi);
|
||||
}
|
||||
};
|
||||
|
||||
//=================================================gradient_repeat_adaptor
|
||||
template<class GradientF> class gradient_repeat_adaptor
|
||||
{
|
||||
public:
|
||||
gradient_repeat_adaptor(const GradientF& gradient) :
|
||||
m_gradient(&gradient) {}
|
||||
|
||||
AGG_INLINE int calculate(int x, int y, int d) const
|
||||
{
|
||||
int ret = m_gradient->calculate(x, y, d) % d;
|
||||
if(ret < 0) ret += d;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
const GradientF* m_gradient;
|
||||
};
|
||||
|
||||
//================================================gradient_reflect_adaptor
|
||||
template<class GradientF> class gradient_reflect_adaptor
|
||||
{
|
||||
public:
|
||||
gradient_reflect_adaptor(const GradientF& gradient) :
|
||||
m_gradient(&gradient) {}
|
||||
|
||||
AGG_INLINE int calculate(int x, int y, int d) const
|
||||
{
|
||||
int d2 = d << 1;
|
||||
int ret = m_gradient->calculate(x, y, d) % d2;
|
||||
if(ret < 0) ret += d2;
|
||||
if(ret >= d) ret = d2 - ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
const GradientF* m_gradient;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
186
deps/agg/include/agg_span_gradient_alpha.h
vendored
186
deps/agg/include/agg_span_gradient_alpha.h
vendored
|
@ -18,103 +18,109 @@
|
|||
|
||||
#include "agg_span_gradient.h"
|
||||
|
||||
namespace agg {
|
||||
//======================================================span_gradient_alpha
|
||||
template<class ColorT, class Interpolator, class GradientF, class AlphaF>
|
||||
class span_gradient_alpha
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type alpha_type;
|
||||
|
||||
enum downscale_shift_e { downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient_alpha() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient_alpha(interpolator_type& inter,
|
||||
const GradientF& gradient_function,
|
||||
const AlphaF& alpha_function,
|
||||
double d1,
|
||||
double d2)
|
||||
: m_interpolator(&inter)
|
||||
, m_gradient_function(&gradient_function)
|
||||
, m_alpha_function(&alpha_function)
|
||||
, m_d1(iround(d1 * gradient_subpixel_scale))
|
||||
, m_d2(iround(d2 * gradient_subpixel_scale))
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
interpolator_type& interpolator() { return *m_interpolator; }
|
||||
const GradientF& gradient_function() const { return *m_gradient_function; }
|
||||
const AlphaF& alpha_function() const { return *m_alpha_function; }
|
||||
double d1() const { return double(m_d1) / gradient_subpixel_scale; }
|
||||
double d2() const { return double(m_d2) / gradient_subpixel_scale; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void interpolator(interpolator_type& i) { m_interpolator = &i; }
|
||||
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
|
||||
void alpha_function(const AlphaF& af) { m_alpha_function = ⁡ }
|
||||
void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
|
||||
void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
//======================================================span_gradient_alpha
|
||||
template<class ColorT,
|
||||
class Interpolator,
|
||||
class GradientF,
|
||||
class AlphaF>
|
||||
class span_gradient_alpha
|
||||
{
|
||||
int dd = m_d2 - m_d1;
|
||||
if (dd < 1)
|
||||
dd = 1;
|
||||
m_interpolator->begin(x + 0.5, y + 0.5, len);
|
||||
do
|
||||
public:
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef ColorT color_type;
|
||||
typedef typename color_type::value_type alpha_type;
|
||||
|
||||
enum downscale_shift_e
|
||||
{
|
||||
m_interpolator->coordinates(&x, &y);
|
||||
int d = m_gradient_function->calculate(x >> downscale_shift, y >> downscale_shift, m_d2);
|
||||
d = ((d - m_d1) * (int)m_alpha_function->size()) / dd;
|
||||
if (d < 0)
|
||||
d = 0;
|
||||
if (d >= (int)m_alpha_function->size())
|
||||
d = m_alpha_function->size() - 1;
|
||||
span->a = (*m_alpha_function)[d];
|
||||
++span;
|
||||
++(*m_interpolator);
|
||||
} while (--len);
|
||||
}
|
||||
downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift
|
||||
};
|
||||
|
||||
private:
|
||||
interpolator_type* m_interpolator;
|
||||
const GradientF* m_gradient_function;
|
||||
const AlphaF* m_alpha_function;
|
||||
int m_d1;
|
||||
int m_d2;
|
||||
};
|
||||
|
||||
//=======================================================gradient_alpha_x
|
||||
template<class ColorT>
|
||||
struct gradient_alpha_x
|
||||
{
|
||||
typedef typename ColorT::value_type alpha_type;
|
||||
alpha_type operator[](alpha_type x) const { return x; }
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient_alpha() {}
|
||||
|
||||
//====================================================gradient_alpha_x_u8
|
||||
struct gradient_alpha_x_u8
|
||||
{
|
||||
typedef int8u alpha_type;
|
||||
alpha_type operator[](alpha_type x) const { return x; }
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
span_gradient_alpha(interpolator_type& inter,
|
||||
const GradientF& gradient_function,
|
||||
const AlphaF& alpha_function,
|
||||
double d1, double d2) :
|
||||
m_interpolator(&inter),
|
||||
m_gradient_function(&gradient_function),
|
||||
m_alpha_function(&alpha_function),
|
||||
m_d1(iround(d1 * gradient_subpixel_scale)),
|
||||
m_d2(iround(d2 * gradient_subpixel_scale))
|
||||
{}
|
||||
|
||||
//==========================================gradient_alpha_one_munus_x_u8
|
||||
struct gradient_alpha_one_munus_x_u8
|
||||
{
|
||||
typedef int8u alpha_type;
|
||||
alpha_type operator[](alpha_type x) const { return 255 - x; }
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
interpolator_type& interpolator() { return *m_interpolator; }
|
||||
const GradientF& gradient_function() const { return *m_gradient_function; }
|
||||
const AlphaF& alpha_function() const { return *m_alpha_function; }
|
||||
double d1() const { return double(m_d1) / gradient_subpixel_scale; }
|
||||
double d2() const { return double(m_d2) / gradient_subpixel_scale; }
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
void interpolator(interpolator_type& i) { m_interpolator = &i; }
|
||||
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
|
||||
void alpha_function(const AlphaF& af) { m_alpha_function = ⁡ }
|
||||
void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
|
||||
void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
int dd = m_d2 - m_d1;
|
||||
if(dd < 1) dd = 1;
|
||||
m_interpolator->begin(x+0.5, y+0.5, len);
|
||||
do
|
||||
{
|
||||
m_interpolator->coordinates(&x, &y);
|
||||
int d = m_gradient_function->calculate(x >> downscale_shift,
|
||||
y >> downscale_shift, m_d2);
|
||||
d = ((d - m_d1) * (int)m_alpha_function->size()) / dd;
|
||||
if(d < 0) d = 0;
|
||||
if(d >= (int)m_alpha_function->size()) d = m_alpha_function->size() - 1;
|
||||
span->a = (*m_alpha_function)[d];
|
||||
++span;
|
||||
++(*m_interpolator);
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
private:
|
||||
interpolator_type* m_interpolator;
|
||||
const GradientF* m_gradient_function;
|
||||
const AlphaF* m_alpha_function;
|
||||
int m_d1;
|
||||
int m_d2;
|
||||
};
|
||||
|
||||
|
||||
//=======================================================gradient_alpha_x
|
||||
template<class ColorT> struct gradient_alpha_x
|
||||
{
|
||||
typedef typename ColorT::value_type alpha_type;
|
||||
alpha_type operator [] (alpha_type x) const { return x; }
|
||||
};
|
||||
|
||||
//====================================================gradient_alpha_x_u8
|
||||
struct gradient_alpha_x_u8
|
||||
{
|
||||
typedef int8u alpha_type;
|
||||
alpha_type operator [] (alpha_type x) const { return x; }
|
||||
};
|
||||
|
||||
//==========================================gradient_alpha_one_munus_x_u8
|
||||
struct gradient_alpha_one_munus_x_u8
|
||||
{
|
||||
typedef int8u alpha_type;
|
||||
alpha_type operator [] (alpha_type x) const { return 255-x; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
398
deps/agg/include/agg_span_image_filter.h
vendored
398
deps/agg/include/agg_span_image_filter.h
vendored
|
@ -23,216 +23,224 @@
|
|||
#include "agg_image_filters.h"
|
||||
#include "agg_span_interpolator_linear.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//-------------------------------------------------------span_image_filter
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter() {}
|
||||
span_image_filter(source_type& src, interpolator_type& interpolator, const image_filter_lut* filter)
|
||||
: m_src(&src)
|
||||
, m_interpolator(&interpolator)
|
||||
, m_filter(filter)
|
||||
, m_dx_dbl(0.5)
|
||||
, m_dy_dbl(0.5)
|
||||
, m_dx_int(image_subpixel_scale / 2)
|
||||
, m_dy_int(image_subpixel_scale / 2)
|
||||
{}
|
||||
void attach(source_type& v) { m_src = &v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
source_type& source() { return *m_src; }
|
||||
const source_type& source() const { return *m_src; }
|
||||
const image_filter_lut& filter() const { return *m_filter; }
|
||||
int filter_dx_int() const { return m_dx_int; }
|
||||
int filter_dy_int() const { return m_dy_int; }
|
||||
double filter_dx_dbl() const { return m_dx_dbl; }
|
||||
double filter_dy_dbl() const { return m_dy_dbl; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void interpolator(interpolator_type& v) { m_interpolator = &v; }
|
||||
void filter(const image_filter_lut& v) { m_filter = &v; }
|
||||
void filter_offset(double dx, double dy)
|
||||
//-------------------------------------------------------span_image_filter
|
||||
template<class Source, class Interpolator> class span_image_filter
|
||||
{
|
||||
m_dx_dbl = dx;
|
||||
m_dy_dbl = dy;
|
||||
m_dx_int = iround(dx * image_subpixel_scale);
|
||||
m_dy_int = iround(dy * image_subpixel_scale);
|
||||
}
|
||||
void filter_offset(double d) { filter_offset(d, d); }
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
interpolator_type& interpolator() { return *m_interpolator; }
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter() {}
|
||||
span_image_filter(source_type& src,
|
||||
interpolator_type& interpolator,
|
||||
const image_filter_lut* filter) :
|
||||
m_src(&src),
|
||||
m_interpolator(&interpolator),
|
||||
m_filter(filter),
|
||||
m_dx_dbl(0.5),
|
||||
m_dy_dbl(0.5),
|
||||
m_dx_int(image_subpixel_scale / 2),
|
||||
m_dy_int(image_subpixel_scale / 2)
|
||||
{}
|
||||
void attach(source_type& v) { m_src = &v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
//--------------------------------------------------------------------
|
||||
source_type& source() { return *m_src; }
|
||||
const source_type& source() const { return *m_src; }
|
||||
const image_filter_lut& filter() const { return *m_filter; }
|
||||
int filter_dx_int() const { return m_dx_int; }
|
||||
int filter_dy_int() const { return m_dy_int; }
|
||||
double filter_dx_dbl() const { return m_dx_dbl; }
|
||||
double filter_dy_dbl() const { return m_dy_dbl; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
private:
|
||||
source_type* m_src;
|
||||
interpolator_type* m_interpolator;
|
||||
const image_filter_lut* m_filter;
|
||||
double m_dx_dbl;
|
||||
double m_dy_dbl;
|
||||
unsigned m_dx_int;
|
||||
unsigned m_dy_int;
|
||||
};
|
||||
|
||||
//==============================================span_image_resample_affine
|
||||
template<class Source>
|
||||
class span_image_resample_affine : public span_image_filter<Source, span_interpolator_linear<trans_affine>>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef span_interpolator_linear<trans_affine> interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_affine()
|
||||
: m_scale_limit(200.0)
|
||||
, m_blur_x(1.0)
|
||||
, m_blur_y(1.0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_affine(source_type& src, interpolator_type& inter, const image_filter_lut& filter)
|
||||
: base_type(src, inter, &filter)
|
||||
, m_scale_limit(200.0)
|
||||
, m_blur_x(1.0)
|
||||
, m_blur_y(1.0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int scale_limit() const { return uround(m_scale_limit); }
|
||||
void scale_limit(int v) { m_scale_limit = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double blur_x() const { return m_blur_x; }
|
||||
double blur_y() const { return m_blur_y; }
|
||||
void blur_x(double v) { m_blur_x = v; }
|
||||
void blur_y(double v) { m_blur_y = v; }
|
||||
void blur(double v) { m_blur_x = m_blur_y = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
double scale_x;
|
||||
double scale_y;
|
||||
|
||||
base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y);
|
||||
|
||||
if (scale_x * scale_y > m_scale_limit)
|
||||
//--------------------------------------------------------------------
|
||||
void interpolator(interpolator_type& v) { m_interpolator = &v; }
|
||||
void filter(const image_filter_lut& v) { m_filter = &v; }
|
||||
void filter_offset(double dx, double dy)
|
||||
{
|
||||
scale_x = scale_x * m_scale_limit / (scale_x * scale_y);
|
||||
scale_y = scale_y * m_scale_limit / (scale_x * scale_y);
|
||||
m_dx_dbl = dx;
|
||||
m_dy_dbl = dy;
|
||||
m_dx_int = iround(dx * image_subpixel_scale);
|
||||
m_dy_int = iround(dy * image_subpixel_scale);
|
||||
}
|
||||
void filter_offset(double d) { filter_offset(d, d); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
interpolator_type& interpolator() { return *m_interpolator; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
private:
|
||||
source_type* m_src;
|
||||
interpolator_type* m_interpolator;
|
||||
const image_filter_lut* m_filter;
|
||||
double m_dx_dbl;
|
||||
double m_dy_dbl;
|
||||
unsigned m_dx_int;
|
||||
unsigned m_dy_int;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//==============================================span_image_resample_affine
|
||||
template<class Source>
|
||||
class span_image_resample_affine :
|
||||
public span_image_filter<Source, span_interpolator_linear<trans_affine> >
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef span_interpolator_linear<trans_affine> interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_affine() :
|
||||
m_scale_limit(200.0),
|
||||
m_blur_x(1.0),
|
||||
m_blur_y(1.0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_affine(source_type& src,
|
||||
interpolator_type& inter,
|
||||
const image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter),
|
||||
m_scale_limit(200.0),
|
||||
m_blur_x(1.0),
|
||||
m_blur_y(1.0)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int scale_limit() const { return uround(m_scale_limit); }
|
||||
void scale_limit(int v) { m_scale_limit = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double blur_x() const { return m_blur_x; }
|
||||
double blur_y() const { return m_blur_y; }
|
||||
void blur_x(double v) { m_blur_x = v; }
|
||||
void blur_y(double v) { m_blur_y = v; }
|
||||
void blur(double v) { m_blur_x = m_blur_y = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
double scale_x;
|
||||
double scale_y;
|
||||
|
||||
base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y);
|
||||
|
||||
if(scale_x * scale_y > m_scale_limit)
|
||||
{
|
||||
scale_x = scale_x * m_scale_limit / (scale_x * scale_y);
|
||||
scale_y = scale_y * m_scale_limit / (scale_x * scale_y);
|
||||
}
|
||||
|
||||
if(scale_x < 1) scale_x = 1;
|
||||
if(scale_y < 1) scale_y = 1;
|
||||
|
||||
if(scale_x > m_scale_limit) scale_x = m_scale_limit;
|
||||
if(scale_y > m_scale_limit) scale_y = m_scale_limit;
|
||||
|
||||
scale_x *= m_blur_x;
|
||||
scale_y *= m_blur_y;
|
||||
|
||||
if(scale_x < 1) scale_x = 1;
|
||||
if(scale_y < 1) scale_y = 1;
|
||||
|
||||
m_rx = uround( scale_x * double(image_subpixel_scale));
|
||||
m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale));
|
||||
|
||||
m_ry = uround( scale_y * double(image_subpixel_scale));
|
||||
m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale));
|
||||
}
|
||||
|
||||
if (scale_x < 1)
|
||||
scale_x = 1;
|
||||
if (scale_y < 1)
|
||||
scale_y = 1;
|
||||
protected:
|
||||
int m_rx;
|
||||
int m_ry;
|
||||
int m_rx_inv;
|
||||
int m_ry_inv;
|
||||
|
||||
if (scale_x > m_scale_limit)
|
||||
scale_x = m_scale_limit;
|
||||
if (scale_y > m_scale_limit)
|
||||
scale_y = m_scale_limit;
|
||||
private:
|
||||
double m_scale_limit;
|
||||
double m_blur_x;
|
||||
double m_blur_y;
|
||||
};
|
||||
|
||||
scale_x *= m_blur_x;
|
||||
scale_y *= m_blur_y;
|
||||
|
||||
if (scale_x < 1)
|
||||
scale_x = 1;
|
||||
if (scale_y < 1)
|
||||
scale_y = 1;
|
||||
|
||||
m_rx = uround(scale_x * double(image_subpixel_scale));
|
||||
m_rx_inv = uround(1.0 / scale_x * double(image_subpixel_scale));
|
||||
|
||||
m_ry = uround(scale_y * double(image_subpixel_scale));
|
||||
m_ry_inv = uround(1.0 / scale_y * double(image_subpixel_scale));
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_rx;
|
||||
int m_ry;
|
||||
int m_rx_inv;
|
||||
int m_ry_inv;
|
||||
|
||||
private:
|
||||
double m_scale_limit;
|
||||
double m_blur_x;
|
||||
double m_blur_y;
|
||||
};
|
||||
|
||||
//=====================================================span_image_resample
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_resample : public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample()
|
||||
: m_scale_limit(20)
|
||||
, m_blur_x(image_subpixel_scale)
|
||||
, m_blur_y(image_subpixel_scale)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample(source_type& src, interpolator_type& inter, const image_filter_lut& filter)
|
||||
: base_type(src, inter, &filter)
|
||||
, m_scale_limit(20)
|
||||
, m_blur_x(image_subpixel_scale)
|
||||
, m_blur_y(image_subpixel_scale)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int scale_limit() const { return m_scale_limit; }
|
||||
void scale_limit(int v) { m_scale_limit = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double blur_x() const { return double(m_blur_x) / double(image_subpixel_scale); }
|
||||
double blur_y() const { return double(m_blur_y) / double(image_subpixel_scale); }
|
||||
void blur_x(double v) { m_blur_x = uround(v * double(image_subpixel_scale)); }
|
||||
void blur_y(double v) { m_blur_y = uround(v * double(image_subpixel_scale)); }
|
||||
void blur(double v) { m_blur_x = m_blur_y = uround(v * double(image_subpixel_scale)); }
|
||||
|
||||
protected:
|
||||
AGG_INLINE void adjust_scale(int* rx, int* ry)
|
||||
//=====================================================span_image_resample
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_resample :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
if (*rx < image_subpixel_scale)
|
||||
*rx = image_subpixel_scale;
|
||||
if (*ry < image_subpixel_scale)
|
||||
*ry = image_subpixel_scale;
|
||||
if (*rx > image_subpixel_scale * m_scale_limit)
|
||||
{
|
||||
*rx = image_subpixel_scale * m_scale_limit;
|
||||
}
|
||||
if (*ry > image_subpixel_scale * m_scale_limit)
|
||||
{
|
||||
*ry = image_subpixel_scale * m_scale_limit;
|
||||
}
|
||||
*rx = (*rx * m_blur_x) >> image_subpixel_shift;
|
||||
*ry = (*ry * m_blur_y) >> image_subpixel_shift;
|
||||
if (*rx < image_subpixel_scale)
|
||||
*rx = image_subpixel_scale;
|
||||
if (*ry < image_subpixel_scale)
|
||||
*ry = image_subpixel_scale;
|
||||
}
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
|
||||
int m_scale_limit;
|
||||
int m_blur_x;
|
||||
int m_blur_y;
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample() :
|
||||
m_scale_limit(20),
|
||||
m_blur_x(image_subpixel_scale),
|
||||
m_blur_y(image_subpixel_scale)
|
||||
{}
|
||||
|
||||
} // namespace agg
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample(source_type& src,
|
||||
interpolator_type& inter,
|
||||
const image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter),
|
||||
m_scale_limit(20),
|
||||
m_blur_x(image_subpixel_scale),
|
||||
m_blur_y(image_subpixel_scale)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int scale_limit() const { return m_scale_limit; }
|
||||
void scale_limit(int v) { m_scale_limit = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double blur_x() const { return double(m_blur_x) / double(image_subpixel_scale); }
|
||||
double blur_y() const { return double(m_blur_y) / double(image_subpixel_scale); }
|
||||
void blur_x(double v) { m_blur_x = uround(v * double(image_subpixel_scale)); }
|
||||
void blur_y(double v) { m_blur_y = uround(v * double(image_subpixel_scale)); }
|
||||
void blur(double v) { m_blur_x =
|
||||
m_blur_y = uround(v * double(image_subpixel_scale)); }
|
||||
|
||||
protected:
|
||||
AGG_INLINE void adjust_scale(int* rx, int* ry)
|
||||
{
|
||||
if(*rx < image_subpixel_scale) *rx = image_subpixel_scale;
|
||||
if(*ry < image_subpixel_scale) *ry = image_subpixel_scale;
|
||||
if(*rx > image_subpixel_scale * m_scale_limit)
|
||||
{
|
||||
*rx = image_subpixel_scale * m_scale_limit;
|
||||
}
|
||||
if(*ry > image_subpixel_scale * m_scale_limit)
|
||||
{
|
||||
*ry = image_subpixel_scale * m_scale_limit;
|
||||
}
|
||||
*rx = (*rx * m_blur_x) >> image_subpixel_shift;
|
||||
*ry = (*ry * m_blur_y) >> image_subpixel_shift;
|
||||
if(*rx < image_subpixel_scale) *rx = image_subpixel_scale;
|
||||
if(*ry < image_subpixel_scale) *ry = image_subpixel_scale;
|
||||
}
|
||||
|
||||
int m_scale_limit;
|
||||
int m_blur_x;
|
||||
int m_blur_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
1205
deps/agg/include/agg_span_image_filter_gray.h
vendored
1205
deps/agg/include/agg_span_image_filter_gray.h
vendored
File diff suppressed because it is too large
Load diff
1445
deps/agg/include/agg_span_image_filter_rgb.h
vendored
1445
deps/agg/include/agg_span_image_filter_rgb.h
vendored
File diff suppressed because it is too large
Load diff
1499
deps/agg/include/agg_span_image_filter_rgba.h
vendored
1499
deps/agg/include/agg_span_image_filter_rgba.h
vendored
File diff suppressed because it is too large
Load diff
89
deps/agg/include/agg_span_interpolator_adaptor.h
vendored
89
deps/agg/include/agg_span_interpolator_adaptor.h
vendored
|
@ -18,47 +18,60 @@
|
|||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//===============================================span_interpolator_adaptor
|
||||
template<class Interpolator, class Distortion>
|
||||
class span_interpolator_adaptor : public Interpolator
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef Interpolator base_type;
|
||||
typedef typename base_type::trans_type trans_type;
|
||||
typedef Distortion distortion_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_adaptor() {}
|
||||
span_interpolator_adaptor(const trans_type& trans, const distortion_type& dist)
|
||||
: base_type(trans)
|
||||
, m_distortion(&dist)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_adaptor(const trans_type& trans, const distortion_type& dist, double x, double y, unsigned len)
|
||||
: base_type(trans, x, y, len)
|
||||
, m_distortion(&dist)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const distortion_type& distortion() const { return *m_distortion; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void distortion(const distortion_type& dist) { m_distortion = dist; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
//===============================================span_interpolator_adaptor
|
||||
template<class Interpolator, class Distortion>
|
||||
class span_interpolator_adaptor : public Interpolator
|
||||
{
|
||||
base_type::coordinates(x, y);
|
||||
m_distortion->calculate(x, y);
|
||||
}
|
||||
public:
|
||||
typedef Interpolator base_type;
|
||||
typedef typename base_type::trans_type trans_type;
|
||||
typedef Distortion distortion_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_adaptor() {}
|
||||
span_interpolator_adaptor(const trans_type& trans,
|
||||
const distortion_type& dist) :
|
||||
base_type(trans),
|
||||
m_distortion(&dist)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_adaptor(const trans_type& trans,
|
||||
const distortion_type& dist,
|
||||
double x, double y, unsigned len) :
|
||||
base_type(trans, x, y, len),
|
||||
m_distortion(&dist)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const distortion_type& distortion() const
|
||||
{
|
||||
return *m_distortion;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void distortion(const distortion_type& dist)
|
||||
{
|
||||
m_distortion = dist;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
base_type::coordinates(x, y);
|
||||
m_distortion->calculate(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
const distortion_type* m_distortion;
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
const distortion_type* m_distortion;
|
||||
};
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
|
382
deps/agg/include/agg_span_interpolator_linear.h
vendored
382
deps/agg/include/agg_span_interpolator_linear.h
vendored
|
@ -20,199 +20,213 @@
|
|||
#include "agg_dda_line.h"
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
//================================================span_interpolator_linear
|
||||
template<class Transformer = trans_affine, unsigned SubpixelShift = 8>
|
||||
class span_interpolator_linear
|
||||
namespace agg
|
||||
{
|
||||
public:
|
||||
typedef Transformer trans_type;
|
||||
|
||||
enum subpixel_scale_e { subpixel_shift = SubpixelShift, subpixel_scale = 1 << subpixel_shift };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_linear() {}
|
||||
span_interpolator_linear(const trans_type& trans)
|
||||
: m_trans(&trans)
|
||||
{}
|
||||
span_interpolator_linear(const trans_type& trans, double x, double y, unsigned len)
|
||||
: m_trans(&trans)
|
||||
//================================================span_interpolator_linear
|
||||
template<class Transformer = trans_affine, unsigned SubpixelShift = 8>
|
||||
class span_interpolator_linear
|
||||
{
|
||||
begin(x, y, len);
|
||||
}
|
||||
public:
|
||||
typedef Transformer trans_type;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
const trans_type& transformer() const { return *m_trans; }
|
||||
void transformer(const trans_type& trans) { m_trans = &trans; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void begin(double x, double y, unsigned len)
|
||||
{
|
||||
double tx;
|
||||
double ty;
|
||||
|
||||
tx = x;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
int x1 = iround(tx * subpixel_scale);
|
||||
int y1 = iround(ty * subpixel_scale);
|
||||
|
||||
tx = x + len;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
int x2 = iround(tx * subpixel_scale);
|
||||
int y2 = iround(ty * subpixel_scale);
|
||||
|
||||
m_li_x = dda2_line_interpolator(x1, x2, len);
|
||||
m_li_y = dda2_line_interpolator(y1, y2, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void resynchronize(double xe, double ye, unsigned len)
|
||||
{
|
||||
m_trans->transform(&xe, &ye);
|
||||
m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len);
|
||||
m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++m_li_x;
|
||||
++m_li_y;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
*x = m_li_x.y();
|
||||
*y = m_li_y.y();
|
||||
}
|
||||
|
||||
private:
|
||||
const trans_type* m_trans;
|
||||
dda2_line_interpolator m_li_x;
|
||||
dda2_line_interpolator m_li_y;
|
||||
};
|
||||
|
||||
//=====================================span_interpolator_linear_subdiv
|
||||
template<class Transformer = trans_affine, unsigned SubpixelShift = 8>
|
||||
class span_interpolator_linear_subdiv
|
||||
{
|
||||
public:
|
||||
typedef Transformer trans_type;
|
||||
|
||||
enum subpixel_scale_e { subpixel_shift = SubpixelShift, subpixel_scale = 1 << subpixel_shift };
|
||||
|
||||
//----------------------------------------------------------------
|
||||
span_interpolator_linear_subdiv()
|
||||
: m_subdiv_shift(4)
|
||||
, m_subdiv_size(1 << m_subdiv_shift)
|
||||
, m_subdiv_mask(m_subdiv_size - 1)
|
||||
{}
|
||||
|
||||
span_interpolator_linear_subdiv(const trans_type& trans, unsigned subdiv_shift = 4)
|
||||
: m_subdiv_shift(subdiv_shift)
|
||||
, m_subdiv_size(1 << m_subdiv_shift)
|
||||
, m_subdiv_mask(m_subdiv_size - 1)
|
||||
, m_trans(&trans)
|
||||
{}
|
||||
|
||||
span_interpolator_linear_subdiv(const trans_type& trans,
|
||||
double x,
|
||||
double y,
|
||||
unsigned len,
|
||||
unsigned subdiv_shift = 4)
|
||||
: m_subdiv_shift(subdiv_shift)
|
||||
, m_subdiv_size(1 << m_subdiv_shift)
|
||||
, m_subdiv_mask(m_subdiv_size - 1)
|
||||
, m_trans(&trans)
|
||||
{
|
||||
begin(x, y, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
const trans_type& transformer() const { return *m_trans; }
|
||||
void transformer(const trans_type& trans) { m_trans = &trans; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
unsigned subdiv_shift() const { return m_subdiv_shift; }
|
||||
void subdiv_shift(unsigned shift)
|
||||
{
|
||||
m_subdiv_shift = shift;
|
||||
m_subdiv_size = 1 << m_subdiv_shift;
|
||||
m_subdiv_mask = m_subdiv_size - 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void begin(double x, double y, unsigned len)
|
||||
{
|
||||
double tx;
|
||||
double ty;
|
||||
m_pos = 1;
|
||||
m_src_x = iround(x * subpixel_scale) + subpixel_scale;
|
||||
m_src_y = y;
|
||||
m_len = len;
|
||||
|
||||
if (len > m_subdiv_size)
|
||||
len = m_subdiv_size;
|
||||
tx = x;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
int x1 = iround(tx * subpixel_scale);
|
||||
int y1 = iround(ty * subpixel_scale);
|
||||
|
||||
tx = x + len;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
|
||||
m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len);
|
||||
m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++m_li_x;
|
||||
++m_li_y;
|
||||
if (m_pos >= m_subdiv_size)
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
unsigned len = m_len;
|
||||
if (len > m_subdiv_size)
|
||||
len = m_subdiv_size;
|
||||
double tx = double(m_src_x) / double(subpixel_scale) + len;
|
||||
double ty = m_src_y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len);
|
||||
m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len);
|
||||
m_pos = 0;
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_linear() {}
|
||||
span_interpolator_linear(const trans_type& trans) : m_trans(&trans) {}
|
||||
span_interpolator_linear(const trans_type& trans,
|
||||
double x, double y, unsigned len) :
|
||||
m_trans(&trans)
|
||||
{
|
||||
begin(x, y, len);
|
||||
}
|
||||
m_src_x += subpixel_scale;
|
||||
++m_pos;
|
||||
--m_len;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
//----------------------------------------------------------------
|
||||
const trans_type& transformer() const { return *m_trans; }
|
||||
void transformer(const trans_type& trans) { m_trans = &trans; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void begin(double x, double y, unsigned len)
|
||||
{
|
||||
double tx;
|
||||
double ty;
|
||||
|
||||
tx = x;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
int x1 = iround(tx * subpixel_scale);
|
||||
int y1 = iround(ty * subpixel_scale);
|
||||
|
||||
tx = x + len;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
int x2 = iround(tx * subpixel_scale);
|
||||
int y2 = iround(ty * subpixel_scale);
|
||||
|
||||
m_li_x = dda2_line_interpolator(x1, x2, len);
|
||||
m_li_y = dda2_line_interpolator(y1, y2, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void resynchronize(double xe, double ye, unsigned len)
|
||||
{
|
||||
m_trans->transform(&xe, &ye);
|
||||
m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len);
|
||||
m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++m_li_x;
|
||||
++m_li_y;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
*x = m_li_x.y();
|
||||
*y = m_li_y.y();
|
||||
}
|
||||
|
||||
private:
|
||||
const trans_type* m_trans;
|
||||
dda2_line_interpolator m_li_x;
|
||||
dda2_line_interpolator m_li_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//=====================================span_interpolator_linear_subdiv
|
||||
template<class Transformer = trans_affine, unsigned SubpixelShift = 8>
|
||||
class span_interpolator_linear_subdiv
|
||||
{
|
||||
*x = m_li_x.y();
|
||||
*y = m_li_y.y();
|
||||
}
|
||||
public:
|
||||
typedef Transformer trans_type;
|
||||
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
span_interpolator_linear_subdiv() :
|
||||
m_subdiv_shift(4),
|
||||
m_subdiv_size(1 << m_subdiv_shift),
|
||||
m_subdiv_mask(m_subdiv_size - 1) {}
|
||||
|
||||
span_interpolator_linear_subdiv(const trans_type& trans,
|
||||
unsigned subdiv_shift = 4) :
|
||||
m_subdiv_shift(subdiv_shift),
|
||||
m_subdiv_size(1 << m_subdiv_shift),
|
||||
m_subdiv_mask(m_subdiv_size - 1),
|
||||
m_trans(&trans) {}
|
||||
|
||||
span_interpolator_linear_subdiv(const trans_type& trans,
|
||||
double x, double y, unsigned len,
|
||||
unsigned subdiv_shift = 4) :
|
||||
m_subdiv_shift(subdiv_shift),
|
||||
m_subdiv_size(1 << m_subdiv_shift),
|
||||
m_subdiv_mask(m_subdiv_size - 1),
|
||||
m_trans(&trans)
|
||||
{
|
||||
begin(x, y, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
const trans_type& transformer() const { return *m_trans; }
|
||||
void transformer(const trans_type& trans) { m_trans = &trans; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
unsigned subdiv_shift() const { return m_subdiv_shift; }
|
||||
void subdiv_shift(unsigned shift)
|
||||
{
|
||||
m_subdiv_shift = shift;
|
||||
m_subdiv_size = 1 << m_subdiv_shift;
|
||||
m_subdiv_mask = m_subdiv_size - 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void begin(double x, double y, unsigned len)
|
||||
{
|
||||
double tx;
|
||||
double ty;
|
||||
m_pos = 1;
|
||||
m_src_x = iround(x * subpixel_scale) + subpixel_scale;
|
||||
m_src_y = y;
|
||||
m_len = len;
|
||||
|
||||
if(len > m_subdiv_size) len = m_subdiv_size;
|
||||
tx = x;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
int x1 = iround(tx * subpixel_scale);
|
||||
int y1 = iround(ty * subpixel_scale);
|
||||
|
||||
tx = x + len;
|
||||
ty = y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
|
||||
m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len);
|
||||
m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++m_li_x;
|
||||
++m_li_y;
|
||||
if(m_pos >= m_subdiv_size)
|
||||
{
|
||||
unsigned len = m_len;
|
||||
if(len > m_subdiv_size) len = m_subdiv_size;
|
||||
double tx = double(m_src_x) / double(subpixel_scale) + len;
|
||||
double ty = m_src_y;
|
||||
m_trans->transform(&tx, &ty);
|
||||
m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len);
|
||||
m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len);
|
||||
m_pos = 0;
|
||||
}
|
||||
m_src_x += subpixel_scale;
|
||||
++m_pos;
|
||||
--m_len;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
*x = m_li_x.y();
|
||||
*y = m_li_y.y();
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_subdiv_shift;
|
||||
unsigned m_subdiv_size;
|
||||
unsigned m_subdiv_mask;
|
||||
const trans_type* m_trans;
|
||||
dda2_line_interpolator m_li_x;
|
||||
dda2_line_interpolator m_li_y;
|
||||
int m_src_x;
|
||||
double m_src_y;
|
||||
unsigned m_pos;
|
||||
unsigned m_len;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_subdiv_shift;
|
||||
unsigned m_subdiv_size;
|
||||
unsigned m_subdiv_mask;
|
||||
const trans_type* m_trans;
|
||||
dda2_line_interpolator m_li_x;
|
||||
dda2_line_interpolator m_li_y;
|
||||
int m_src_x;
|
||||
double m_src_y;
|
||||
unsigned m_pos;
|
||||
unsigned m_len;
|
||||
};
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue