mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-12-11 16:00:17 -07:00
Unneccessary AGG sources removed. Added libpng and zlib sources and static build in cmake.
This commit is contained in:
parent
6b5c0073a7
commit
e6e078cbf7
377 changed files with 108760 additions and 31984 deletions
|
|
@ -332,18 +332,39 @@ add_library(semver STATIC
|
|||
${LIBDIR}/semver/semver.c
|
||||
)
|
||||
|
||||
# ##############################################################################
|
||||
# Configure rasterizer target
|
||||
# ##############################################################################
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
option(RASTERIZER_USE_SYSTEM_LIBPNG "Use the libpng present in system instead of
|
||||
the provided copy." OFF)
|
||||
|
||||
add_library(rasterizer STATIC
|
||||
${LIBDIR}/libslic3r/Rasterizer/Rasterizer.hpp
|
||||
${LIBDIR}/libslic3r/Rasterizer/Rasterizer.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(rasterizer ${PNG_LIBRARIES})
|
||||
target_include_directories(rasterizer PRIVATE ${PNG_INCLUDE_DIRS})
|
||||
target_compile_definitions(rasterizer PRIVATE ${PNG_DEFINITIONS})
|
||||
target_link_libraries(libslic3r rasterizer)
|
||||
if(RASTERIZER_USE_SYSTEM_LIBPNG)
|
||||
find_package(PNG REQUIRED)
|
||||
target_link_libraries(rasterizer PRIVATE ${PNG_LIBRARIES})
|
||||
target_include_directories(rasterizer PRIVATE ${PNG_INCLUDE_DIRS})
|
||||
target_compile_definitions(rasterizer PRIVATE ${PNG_DEFINITIONS})
|
||||
else()
|
||||
add_subdirectory( ${LIBDIR}/png/zlib)
|
||||
add_subdirectory( ${LIBDIR}/png/libpng )
|
||||
|
||||
target_include_directories( png_static PRIVATE
|
||||
${LIBDIR}/png/zlib
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/png/zlib
|
||||
)
|
||||
|
||||
target_link_libraries(rasterizer PRIVATE png_static zlibstatic)
|
||||
endif()
|
||||
|
||||
target_link_libraries(libslic3r rasterizer )
|
||||
|
||||
# ##############################################################################
|
||||
|
||||
|
||||
# Generate the Slic3r Perl module (XS) typemap file.
|
||||
set(MyTypemap ${CMAKE_CURRENT_BINARY_DIR}/typemap)
|
||||
|
|
|
|||
2
xs/src/agg/AUTHORS
Normal file
2
xs/src/agg/AUTHORS
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Anti-Grain Geometry - Version 2.4
|
||||
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
||||
|
|
@ -1,499 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// scanline_u8 class
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_ALPHA_MASK_U8_INCLUDED
|
||||
#define AGG_ALPHA_MASK_U8_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//===================================================one_component_mask_u8
|
||||
struct one_component_mask_u8
|
||||
{
|
||||
static unsigned calculate(const int8u* p) { return *p; }
|
||||
};
|
||||
|
||||
|
||||
//=====================================================rgb_to_gray_mask_u8
|
||||
template<unsigned R, unsigned G, unsigned B>
|
||||
struct rgb_to_gray_mask_u8
|
||||
{
|
||||
static unsigned calculate(const int8u* p)
|
||||
{
|
||||
return (p[R]*77 + p[G]*150 + p[B]*29) >> 8;
|
||||
}
|
||||
};
|
||||
|
||||
//==========================================================alpha_mask_u8
|
||||
template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
|
||||
class alpha_mask_u8
|
||||
{
|
||||
public:
|
||||
typedef int8u cover_type;
|
||||
typedef alpha_mask_u8<Step, Offset, MaskF> self_type;
|
||||
enum cover_scale_e
|
||||
{
|
||||
cover_shift = 8,
|
||||
cover_none = 0,
|
||||
cover_full = 255
|
||||
};
|
||||
|
||||
alpha_mask_u8() : m_rbuf(0) {}
|
||||
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
|
||||
{
|
||||
if(x >= 0 && y >= 0 &&
|
||||
x < (int)m_rbuf->width() &&
|
||||
y < (int)m_rbuf->height())
|
||||
{
|
||||
return (cover_type)m_mask_function.calculate(
|
||||
m_rbuf->row_ptr(y) + x * Step + Offset);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
cover_type combine_pixel(int x, int y, cover_type val) const
|
||||
{
|
||||
if(x >= 0 && y >= 0 &&
|
||||
x < (int)m_rbuf->width() &&
|
||||
y < (int)m_rbuf->height())
|
||||
{
|
||||
return (cover_type)((cover_full + val *
|
||||
m_mask_function.calculate(
|
||||
m_rbuf->row_ptr(y) + x * Step + Offset)) >>
|
||||
cover_shift);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
|
||||
if(y < 0 || y > ymax)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
|
||||
if(x < 0)
|
||||
{
|
||||
count += x;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers, 0, -x * sizeof(cover_type));
|
||||
covers -= x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if(x + count > xmax)
|
||||
{
|
||||
int rest = x + count - xmax - 1;
|
||||
count -= rest;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*covers++ = (cover_type)m_mask_function.calculate(mask);
|
||||
mask += Step;
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
|
||||
if(y < 0 || y > ymax)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
|
||||
if(x < 0)
|
||||
{
|
||||
count += x;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers, 0, -x * sizeof(cover_type));
|
||||
covers -= x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if(x + count > xmax)
|
||||
{
|
||||
int rest = x + count - xmax - 1;
|
||||
count -= rest;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*covers = (cover_type)((cover_full + (*covers) *
|
||||
m_mask_function.calculate(mask)) >>
|
||||
cover_shift);
|
||||
++covers;
|
||||
mask += Step;
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
|
||||
if(x < 0 || x > xmax)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
|
||||
if(y < 0)
|
||||
{
|
||||
count += y;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers, 0, -y * sizeof(cover_type));
|
||||
covers -= y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if(y + count > ymax)
|
||||
{
|
||||
int rest = y + count - ymax - 1;
|
||||
count -= rest;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*covers++ = (cover_type)m_mask_function.calculate(mask);
|
||||
mask += m_rbuf->stride();
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
|
||||
if(x < 0 || x > xmax)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
|
||||
if(y < 0)
|
||||
{
|
||||
count += y;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers, 0, -y * sizeof(cover_type));
|
||||
covers -= y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if(y + count > ymax)
|
||||
{
|
||||
int rest = y + count - ymax - 1;
|
||||
count -= rest;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*covers = (cover_type)((cover_full + (*covers) *
|
||||
m_mask_function.calculate(mask)) >>
|
||||
cover_shift);
|
||||
++covers;
|
||||
mask += m_rbuf->stride();
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
alpha_mask_u8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
rendering_buffer* m_rbuf;
|
||||
MaskF m_mask_function;
|
||||
};
|
||||
|
||||
|
||||
typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8
|
||||
|
||||
typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r
|
||||
typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g
|
||||
typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b
|
||||
|
||||
typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r
|
||||
typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g
|
||||
typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b
|
||||
|
||||
typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r
|
||||
typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g
|
||||
typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b
|
||||
typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a
|
||||
|
||||
typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r
|
||||
typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g
|
||||
typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b
|
||||
typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a
|
||||
|
||||
typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r
|
||||
typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g
|
||||
typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b
|
||||
typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a
|
||||
|
||||
typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r
|
||||
typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g
|
||||
typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b
|
||||
typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a
|
||||
|
||||
typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray
|
||||
typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray
|
||||
typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray
|
||||
typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray
|
||||
typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray
|
||||
typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray
|
||||
|
||||
|
||||
|
||||
//==========================================================amask_no_clip_u8
|
||||
template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
|
||||
class amask_no_clip_u8
|
||||
{
|
||||
public:
|
||||
typedef int8u cover_type;
|
||||
typedef amask_no_clip_u8<Step, Offset, MaskF> self_type;
|
||||
enum cover_scale_e
|
||||
{
|
||||
cover_shift = 8,
|
||||
cover_none = 0,
|
||||
cover_full = 255
|
||||
};
|
||||
|
||||
amask_no_clip_u8() : m_rbuf(0) {}
|
||||
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
|
||||
{
|
||||
*dst++ = (cover_type)m_mask_function.calculate(mask);
|
||||
mask += Step;
|
||||
}
|
||||
while(--num_pix);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*dst = (cover_type)((cover_full + (*dst) *
|
||||
m_mask_function.calculate(mask)) >>
|
||||
cover_shift);
|
||||
++dst;
|
||||
mask += Step;
|
||||
}
|
||||
while(--num_pix);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*dst++ = (cover_type)m_mask_function.calculate(mask);
|
||||
mask += m_rbuf->stride();
|
||||
}
|
||||
while(--num_pix);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*dst = (cover_type)((cover_full + (*dst) *
|
||||
m_mask_function.calculate(mask)) >>
|
||||
cover_shift);
|
||||
++dst;
|
||||
mask += m_rbuf->stride();
|
||||
}
|
||||
while(--num_pix);
|
||||
}
|
||||
|
||||
private:
|
||||
amask_no_clip_u8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
rendering_buffer* m_rbuf;
|
||||
MaskF m_mask_function;
|
||||
};
|
||||
|
||||
|
||||
typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8
|
||||
|
||||
typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r
|
||||
typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g
|
||||
typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b
|
||||
|
||||
typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r
|
||||
typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g
|
||||
typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b
|
||||
|
||||
typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r
|
||||
typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g
|
||||
typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b
|
||||
typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a
|
||||
|
||||
typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r
|
||||
typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g
|
||||
typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b
|
||||
typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a
|
||||
|
||||
typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r
|
||||
typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g
|
||||
typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b
|
||||
typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a
|
||||
|
||||
typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r
|
||||
typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g
|
||||
typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b
|
||||
typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a
|
||||
|
||||
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray
|
||||
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray
|
||||
typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray
|
||||
typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray
|
||||
typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray
|
||||
typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Arc vertex generator
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_ARC_INCLUDED
|
||||
#define AGG_ARC_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=====================================================================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 init(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 rewind(unsigned);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Simple arrowhead/arrowtail generator
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_ARROWHEAD_INCLUDED
|
||||
#define AGG_ARROWHEAD_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//===============================================================arrowhead
|
||||
//
|
||||
// See implementation agg_arrowhead.cpp
|
||||
//
|
||||
class arrowhead
|
||||
{
|
||||
public:
|
||||
arrowhead();
|
||||
|
||||
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 head() { m_head_flag = true; }
|
||||
void no_head() { m_head_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 tail() { m_tail_flag = true; }
|
||||
void no_tail() { m_tail_flag = false; }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
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
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_BITSET_ITERATOR_INCLUDED
|
||||
#define AGG_BITSET_ITERATOR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
class bitset_iterator
|
||||
{
|
||||
public:
|
||||
bitset_iterator(const int8u* bits, unsigned offset = 0) :
|
||||
m_bits(bits + (offset >> 3)),
|
||||
m_mask(0x80 >> (offset & 7))
|
||||
{}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
m_mask >>= 1;
|
||||
if(m_mask == 0)
|
||||
{
|
||||
++m_bits;
|
||||
m_mask = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned bit() const
|
||||
{
|
||||
return (*m_bits) & m_mask;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_bits;
|
||||
int8u m_mask;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,116 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// bounding_rect function template
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_BOUNDING_RECT_INCLUDED
|
||||
#define AGG_BOUNDING_RECT_INCLUDED
|
||||
|
||||
#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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
vs.rewind(gi[start + i]);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class bspline
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_BSPLINE_INCLUDED
|
||||
#define AGG_BSPLINE_INCLUDED
|
||||
|
||||
#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
|
||||
{
|
||||
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, const double* x, const double* y);
|
||||
|
||||
double get(double x) const;
|
||||
double get_stateful(double x) const;
|
||||
|
||||
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;
|
||||
|
||||
int m_max;
|
||||
int m_num;
|
||||
double* m_x;
|
||||
double* m_y;
|
||||
pod_array<double> m_am;
|
||||
mutable int m_last_idx;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED
|
||||
#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//------------------------------------------------------------null_markers
|
||||
struct null_markers
|
||||
{
|
||||
void remove_all() {}
|
||||
void add_vertex(double, double, unsigned) {}
|
||||
void prepare_src() {}
|
||||
|
||||
void rewind(unsigned) {}
|
||||
unsigned vertex(double*, double*) { return path_cmd_stop; }
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------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)
|
||||
{}
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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(;;)
|
||||
{
|
||||
cmd = m_source->vertex(x, y);
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
m_last_cmd = cmd;
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
m_start_x = *x;
|
||||
m_start_y = *y;
|
||||
break;
|
||||
}
|
||||
m_generator.add_vertex(*x, *y, cmd);
|
||||
m_markers.add_vertex(*x, *y, path_cmd_line_to);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_stop(cmd))
|
||||
{
|
||||
m_last_cmd = path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
if(is_end_poly(cmd))
|
||||
{
|
||||
m_generator.add_vertex(*x, *y, cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_generator.rewind(0);
|
||||
m_status = generate;
|
||||
|
||||
case generate:
|
||||
cmd = m_generator.vertex(x, y);
|
||||
if(is_stop(cmd))
|
||||
{
|
||||
m_status = accumulate;
|
||||
break;
|
||||
}
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_ADAPTOR_VPGEN_INCLUDED
|
||||
#define AGG_CONV_ADAPTOR_VPGEN_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//======================================================conv_adaptor_vpgen
|
||||
template<class VertexSource, class VPGen> class conv_adaptor_vpgen
|
||||
{
|
||||
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);
|
||||
|
||||
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(;;)
|
||||
{
|
||||
cmd = m_vpgen.vertex(x, y);
|
||||
if(!is_stop(cmd)) break;
|
||||
|
||||
if(m_poly_flags && !m_vpgen.auto_unclose())
|
||||
{
|
||||
*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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_BSPLINE_INCLUDED
|
||||
#define AGG_CONV_BSPLINE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_bspline> base_type;
|
||||
|
||||
conv_bspline(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs) {}
|
||||
|
||||
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>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Polygon clipping converter
|
||||
// There an optimized Liang-Basky algorithm is used.
|
||||
// The algorithm doesn't optimize the degenerate edges, i.e. it will never
|
||||
// break a closed polygon into two or more ones, instead, there will be
|
||||
// degenerate edges coinciding with the respective clipping boundaries.
|
||||
// This is a sub-optimal solution, because that optimization would require
|
||||
// extra, rather expensive math while the rasterizer tolerates it quite well,
|
||||
// without any considerable overhead.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_CLIP_POLYGON_INCLUDED
|
||||
#define AGG_CONV_CLIP_POLYGON_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon> base_type;
|
||||
|
||||
conv_clip_polygon(VertexSource& vs) :
|
||||
conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs) {}
|
||||
|
||||
void clip_box(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
base_type::vpgen().clip_box(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
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(); }
|
||||
|
||||
private:
|
||||
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
|
||||
const conv_clip_polygon<VertexSource>&
|
||||
operator = (const conv_clip_polygon<VertexSource>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// polyline clipping converter
|
||||
// There an optimized Liang-Basky algorithm is used.
|
||||
// The algorithm doesn't optimize the degenerate edges, i.e. it will never
|
||||
// break a closed polyline into two or more ones, instead, there will be
|
||||
// degenerate edges coinciding with the respective clipping boundaries.
|
||||
// This is a sub-optimal solution, because that optimization would require
|
||||
// extra, rather expensive math while the rasterizer tolerates it quite well,
|
||||
// without any considerable overhead.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_CLIP_polyline_INCLUDED
|
||||
#define AGG_CONV_CLIP_polyline_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> base_type;
|
||||
|
||||
conv_clip_polyline(VertexSource& vs) :
|
||||
conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs) {}
|
||||
|
||||
void clip_box(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
base_type::vpgen().clip_box(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
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(); }
|
||||
|
||||
private:
|
||||
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
|
||||
const conv_clip_polyline<VertexSource>&
|
||||
operator = (const conv_clip_polyline<VertexSource>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_CLOSE_POLYGON_INCLUDED
|
||||
#define AGG_CONV_CLOSE_POLYGON_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//======================================================conv_close_polygon
|
||||
template<class VertexSource> class conv_close_polygon
|
||||
{
|
||||
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(;;)
|
||||
{
|
||||
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
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_CONCAT_INCLUDED
|
||||
#define AGG_CONV_CONCAT_INCLUDED
|
||||
|
||||
#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
|
||||
{
|
||||
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)
|
||||
{
|
||||
m_source1->rewind(path_id);
|
||||
m_source2->rewind(0);
|
||||
m_status = 0;
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// conv_stroke
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_CONTOUR_INCLUDED
|
||||
#define AGG_CONV_CONTOUR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type;
|
||||
|
||||
conv_contour(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
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(); }
|
||||
|
||||
private:
|
||||
conv_contour(const conv_contour<VertexSource>&);
|
||||
const conv_contour<VertexSource>&
|
||||
operator = (const conv_contour<VertexSource>&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// classes conv_curve
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_CURVE_INCLUDED
|
||||
#define AGG_CONV_CURVE_INCLUDED
|
||||
|
||||
#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
|
||||
{
|
||||
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) {}
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
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.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;
|
||||
|
||||
case path_cmd_curve4:
|
||||
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.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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// conv_dash
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_DASH_INCLUDED
|
||||
#define AGG_CONV_DASH_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
void remove_all_dashes()
|
||||
{
|
||||
base_type::generator().remove_all_dashes();
|
||||
}
|
||||
|
||||
void add_dash(double dash_len, double gap_len)
|
||||
{
|
||||
base_type::generator().add_dash(dash_len, gap_len);
|
||||
}
|
||||
|
||||
void dash_start(double ds)
|
||||
{
|
||||
base_type::generator().dash_start(ds);
|
||||
}
|
||||
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
private:
|
||||
conv_dash(const conv_dash<VertexSource, Markers>&);
|
||||
const conv_dash<VertexSource, Markers>&
|
||||
operator = (const conv_dash<VertexSource, Markers>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,432 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// General Polygon Clipper based on the GPC library by Alan Murta
|
||||
// Union, Intersection, XOR, A-B, B-A
|
||||
// Contact the author if you intend to use it in commercial applications!
|
||||
// http://www.cs.man.ac.uk/aig/staff/alan/software/
|
||||
// Alan Murta (email: gpc@cs.man.ac.uk)
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_GPC_INCLUDED
|
||||
#define AGG_CONV_GPC_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
#include "agg_array.h"
|
||||
|
||||
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
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
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++)
|
||||
{
|
||||
const gpc_vertex& s = m_vertex_accumulator[i];
|
||||
d->x = s.x;
|
||||
d->y = s.y;
|
||||
++d;
|
||||
}
|
||||
}
|
||||
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))
|
||||
{
|
||||
m_status = status_line_to;
|
||||
return path_cmd_move_to;
|
||||
}
|
||||
m_status = status_stop;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// conv_marker
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_MARKER_INCLUDED
|
||||
#define AGG_CONV_MARKER_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//-------------------------------------------------------------conv_marker
|
||||
template<class MarkerLocator, class MarkerShapes>
|
||||
class conv_marker
|
||||
{
|
||||
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)
|
||||
{
|
||||
cmd = path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
m_marker_locator->rewind(m_marker);
|
||||
++m_marker;
|
||||
m_num_markers = 0;
|
||||
m_status = markers;
|
||||
|
||||
case markers:
|
||||
if(is_stop(m_marker_locator->vertex(&x1, &y1)))
|
||||
{
|
||||
m_status = initial;
|
||||
break;
|
||||
}
|
||||
if(is_stop(m_marker_locator->vertex(&x2, &y2)))
|
||||
{
|
||||
m_status = initial;
|
||||
break;
|
||||
}
|
||||
++m_num_markers;
|
||||
m_mtx = m_transform;
|
||||
m_mtx *= trans_affine_rotation(atan2(y2 - y1, x2 - x1));
|
||||
m_mtx *= trans_affine_translation(x1, y1);
|
||||
m_marker_shapes->rewind(m_marker - 1);
|
||||
m_status = polygon;
|
||||
|
||||
case polygon:
|
||||
cmd = m_marker_shapes->vertex(x, y);
|
||||
if(is_stop(cmd))
|
||||
{
|
||||
cmd = path_cmd_move_to;
|
||||
m_status = markers;
|
||||
break;
|
||||
}
|
||||
m_mtx.transform(x, y);
|
||||
return cmd;
|
||||
|
||||
case stop:
|
||||
cmd = path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_MARKER_ADAPTOR_INCLUDED
|
||||
#define AGG_CONV_MARKER_ADAPTOR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
private:
|
||||
conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&);
|
||||
const conv_marker_adaptor<VertexSource, Markers>&
|
||||
operator = (const conv_marker_adaptor<VertexSource, Markers>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_SEGMENTATOR_INCLUDED
|
||||
#define AGG_CONV_SEGMENTATOR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_segmentator> base_type;
|
||||
|
||||
conv_segmentator(VertexSource& vs) :
|
||||
conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs) {}
|
||||
|
||||
void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); }
|
||||
double approximation_scale() const { return base_type::vpgen().approximation_scale(); }
|
||||
|
||||
private:
|
||||
conv_segmentator(const conv_segmentator<VertexSource>&);
|
||||
const conv_segmentator<VertexSource>&
|
||||
operator = (const conv_segmentator<VertexSource>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_SHORTEN_PATH_INCLUDED
|
||||
#define AGG_CONV_SHORTEN_PATH_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
public:
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> base_type;
|
||||
|
||||
conv_shorten_path(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
void shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
private:
|
||||
conv_shorten_path(const conv_shorten_path<VertexSource>&);
|
||||
const conv_shorten_path<VertexSource>&
|
||||
operator = (const conv_shorten_path<VertexSource>&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Smooth polygon generator
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_SMOOTH_POLY1_INCLUDED
|
||||
#define AGG_CONV_SMOOTH_POLY1_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_vcgen_smooth_poly1.h"
|
||||
#include "agg_conv_adaptor_vcgen.h"
|
||||
#include "agg_conv_curve.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------conv_smooth_poly1
|
||||
template<class VertexSource>
|
||||
struct conv_smooth_poly1 :
|
||||
public conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1>
|
||||
{
|
||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1> base_type;
|
||||
|
||||
conv_smooth_poly1(VertexSource& vs) :
|
||||
conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1>(vs)
|
||||
{
|
||||
}
|
||||
|
||||
void smooth_value(double v) { base_type::generator().smooth_value(v); }
|
||||
double smooth_value() const { return base_type::generator().smooth_value(); }
|
||||
|
||||
private:
|
||||
conv_smooth_poly1(const conv_smooth_poly1<VertexSource>&);
|
||||
const conv_smooth_poly1<VertexSource>&
|
||||
operator = (const conv_smooth_poly1<VertexSource>&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------conv_smooth_poly1_curve
|
||||
template<class VertexSource>
|
||||
struct conv_smooth_poly1_curve :
|
||||
public conv_curve<conv_smooth_poly1<VertexSource> >
|
||||
{
|
||||
conv_smooth_poly1_curve(VertexSource& vs) :
|
||||
conv_curve<conv_smooth_poly1<VertexSource> >(m_smooth),
|
||||
m_smooth(vs)
|
||||
{
|
||||
}
|
||||
|
||||
void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
|
||||
double smooth_value() const { return m_smooth.generator().smooth_value(); }
|
||||
|
||||
private:
|
||||
conv_smooth_poly1_curve(const conv_smooth_poly1_curve<VertexSource>&);
|
||||
const conv_smooth_poly1_curve<VertexSource>&
|
||||
operator = (const conv_smooth_poly1_curve<VertexSource>&);
|
||||
|
||||
conv_smooth_poly1<VertexSource> m_smooth;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// conv_stroke
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_STROKE_INCLUDED
|
||||
#define AGG_CONV_STROKE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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>
|
||||
{
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
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 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); }
|
||||
|
||||
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 shorten(double s) { base_type::generator().shorten(s); }
|
||||
double shorten() const { return base_type::generator().shorten(); }
|
||||
|
||||
private:
|
||||
conv_stroke(const conv_stroke<VertexSource, Markers>&);
|
||||
const conv_stroke<VertexSource, Markers>&
|
||||
operator = (const conv_stroke<VertexSource, Markers>&);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CONV_UNCLOSE_POLYGON_INCLUDED
|
||||
#define AGG_CONV_UNCLOSE_POLYGON_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//====================================================conv_unclose_polygon
|
||||
template<class VertexSource> class conv_unclose_polygon
|
||||
{
|
||||
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)
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
if(is_end_poly(cmd)) cmd &= ~path_flags_close;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private:
|
||||
conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
|
||||
const conv_unclose_polygon<VertexSource>&
|
||||
operator = (const conv_unclose_polygon<VertexSource>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,693 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
// Copyright (C) 2005 Tony Juricic (tonygeek@yahoo.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_CURVES_INCLUDED
|
||||
#define AGG_CURVES_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
// See Implementation agg_curves.cpp
|
||||
|
||||
//--------------------------------------------curve_approximation_method_e
|
||||
enum curve_approximation_method_e
|
||||
{
|
||||
curve_inc,
|
||||
curve_div
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------curve3_inc
|
||||
class curve3_inc
|
||||
{
|
||||
public:
|
||||
curve3_inc() :
|
||||
m_num_steps(0), m_step(0), m_scale(1.0) { }
|
||||
|
||||
curve3_inc(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3) :
|
||||
m_num_steps(0), m_step(0), m_scale(1.0)
|
||||
{
|
||||
init(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
void reset() { m_num_steps = 0; m_step = -1; }
|
||||
void init(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3);
|
||||
|
||||
void approximation_method(curve_approximation_method_e) {}
|
||||
curve_approximation_method_e approximation_method() const { return curve_inc; }
|
||||
|
||||
void approximation_scale(double s);
|
||||
double approximation_scale() const;
|
||||
|
||||
void angle_tolerance(double) {}
|
||||
double angle_tolerance() const { return 0.0; }
|
||||
|
||||
void cusp_limit(double) {}
|
||||
double cusp_limit() const { return 0.0; }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
int m_num_steps;
|
||||
int m_step;
|
||||
double m_scale;
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
double m_end_x;
|
||||
double m_end_y;
|
||||
double m_fx;
|
||||
double m_fy;
|
||||
double m_dfx;
|
||||
double m_dfy;
|
||||
double m_ddfx;
|
||||
double m_ddfy;
|
||||
double m_saved_fx;
|
||||
double m_saved_fy;
|
||||
double m_saved_dfx;
|
||||
double m_saved_dfy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------curve3_div
|
||||
class curve3_div
|
||||
{
|
||||
public:
|
||||
curve3_div() :
|
||||
m_approximation_scale(1.0),
|
||||
m_angle_tolerance(0.0),
|
||||
m_count(0)
|
||||
{}
|
||||
|
||||
curve3_div(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3) :
|
||||
m_approximation_scale(1.0),
|
||||
m_angle_tolerance(0.0),
|
||||
m_count(0)
|
||||
{
|
||||
init(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
void reset() { m_points.remove_all(); m_count = 0; }
|
||||
void init(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3);
|
||||
|
||||
void approximation_method(curve_approximation_method_e) {}
|
||||
curve_approximation_method_e approximation_method() const { return curve_div; }
|
||||
|
||||
void approximation_scale(double s) { m_approximation_scale = s; }
|
||||
double approximation_scale() const { return m_approximation_scale; }
|
||||
|
||||
void angle_tolerance(double a) { m_angle_tolerance = a; }
|
||||
double angle_tolerance() const { return m_angle_tolerance; }
|
||||
|
||||
void cusp_limit(double) {}
|
||||
double cusp_limit() const { return 0.0; }
|
||||
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_count >= m_points.size()) return path_cmd_stop;
|
||||
const point_d& p = m_points[m_count++];
|
||||
*x = p.x;
|
||||
*y = p.y;
|
||||
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
|
||||
}
|
||||
|
||||
private:
|
||||
void bezier(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3);
|
||||
void recursive_bezier(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
unsigned level);
|
||||
|
||||
double m_approximation_scale;
|
||||
double m_distance_tolerance_square;
|
||||
double m_angle_tolerance;
|
||||
unsigned m_count;
|
||||
pod_bvector<point_d> m_points;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------curve4_points
|
||||
struct curve4_points
|
||||
{
|
||||
double cp[8];
|
||||
curve4_points() {}
|
||||
curve4_points(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4)
|
||||
{
|
||||
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
|
||||
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
|
||||
}
|
||||
void init(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4)
|
||||
{
|
||||
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
|
||||
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
|
||||
}
|
||||
double operator [] (unsigned i) const { return cp[i]; }
|
||||
double& operator [] (unsigned i) { return cp[i]; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------curve4_inc
|
||||
class curve4_inc
|
||||
{
|
||||
public:
|
||||
curve4_inc() :
|
||||
m_num_steps(0), m_step(0), m_scale(1.0) { }
|
||||
|
||||
curve4_inc(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4) :
|
||||
m_num_steps(0), m_step(0), m_scale(1.0)
|
||||
{
|
||||
init(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
}
|
||||
|
||||
curve4_inc(const curve4_points& cp) :
|
||||
m_num_steps(0), m_step(0), m_scale(1.0)
|
||||
{
|
||||
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
void reset() { m_num_steps = 0; m_step = -1; }
|
||||
void init(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4);
|
||||
|
||||
void init(const curve4_points& cp)
|
||||
{
|
||||
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
void approximation_method(curve_approximation_method_e) {}
|
||||
curve_approximation_method_e approximation_method() const { return curve_inc; }
|
||||
|
||||
void approximation_scale(double s);
|
||||
double approximation_scale() const;
|
||||
|
||||
void angle_tolerance(double) {}
|
||||
double angle_tolerance() const { return 0.0; }
|
||||
|
||||
void cusp_limit(double) {}
|
||||
double cusp_limit() const { return 0.0; }
|
||||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
int m_num_steps;
|
||||
int m_step;
|
||||
double m_scale;
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
double m_end_x;
|
||||
double m_end_y;
|
||||
double m_fx;
|
||||
double m_fy;
|
||||
double m_dfx;
|
||||
double m_dfy;
|
||||
double m_ddfx;
|
||||
double m_ddfy;
|
||||
double m_dddfx;
|
||||
double m_dddfy;
|
||||
double m_saved_fx;
|
||||
double m_saved_fy;
|
||||
double m_saved_dfx;
|
||||
double m_saved_dfy;
|
||||
double m_saved_ddfx;
|
||||
double m_saved_ddfy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------catrom_to_bezier
|
||||
inline curve4_points catrom_to_bezier(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4)
|
||||
{
|
||||
// Trans. matrix Catmull-Rom to Bezier
|
||||
//
|
||||
// 0 1 0 0
|
||||
// -1/6 1 1/6 0
|
||||
// 0 1/6 1 -1/6
|
||||
// 0 0 1 0
|
||||
//
|
||||
return curve4_points(
|
||||
x2,
|
||||
y2,
|
||||
(-x1 + 6*x2 + x3) / 6,
|
||||
(-y1 + 6*y2 + y3) / 6,
|
||||
( x2 + 6*x3 - x4) / 6,
|
||||
( y2 + 6*y3 - y4) / 6,
|
||||
x3,
|
||||
y3);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
inline curve4_points
|
||||
catrom_to_bezier(const curve4_points& cp)
|
||||
{
|
||||
return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3],
|
||||
cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------ubspline_to_bezier
|
||||
inline curve4_points ubspline_to_bezier(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4)
|
||||
{
|
||||
// Trans. matrix Uniform BSpline to Bezier
|
||||
//
|
||||
// 1/6 4/6 1/6 0
|
||||
// 0 4/6 2/6 0
|
||||
// 0 2/6 4/6 0
|
||||
// 0 1/6 4/6 1/6
|
||||
//
|
||||
return curve4_points(
|
||||
(x1 + 4*x2 + x3) / 6,
|
||||
(y1 + 4*y2 + y3) / 6,
|
||||
(4*x2 + 2*x3) / 6,
|
||||
(4*y2 + 2*y3) / 6,
|
||||
(2*x2 + 4*x3) / 6,
|
||||
(2*y2 + 4*y3) / 6,
|
||||
(x2 + 4*x3 + x4) / 6,
|
||||
(y2 + 4*y3 + y4) / 6);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
inline curve4_points
|
||||
ubspline_to_bezier(const curve4_points& cp)
|
||||
{
|
||||
return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3],
|
||||
cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------hermite_to_bezier
|
||||
inline curve4_points hermite_to_bezier(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4)
|
||||
{
|
||||
// Trans. matrix Hermite to Bezier
|
||||
//
|
||||
// 1 0 0 0
|
||||
// 1 0 1/3 0
|
||||
// 0 1 0 -1/3
|
||||
// 0 1 0 0
|
||||
//
|
||||
return curve4_points(
|
||||
x1,
|
||||
y1,
|
||||
(3*x1 + x3) / 3,
|
||||
(3*y1 + y3) / 3,
|
||||
(3*x2 - x4) / 3,
|
||||
(3*y2 - y4) / 3,
|
||||
x2,
|
||||
y2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
inline curve4_points
|
||||
hermite_to_bezier(const curve4_points& cp)
|
||||
{
|
||||
return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3],
|
||||
cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------curve4_div
|
||||
class curve4_div
|
||||
{
|
||||
public:
|
||||
curve4_div() :
|
||||
m_approximation_scale(1.0),
|
||||
m_angle_tolerance(0.0),
|
||||
m_cusp_limit(0.0),
|
||||
m_count(0)
|
||||
{}
|
||||
|
||||
curve4_div(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4) :
|
||||
m_approximation_scale(1.0),
|
||||
m_angle_tolerance(0.0),
|
||||
m_cusp_limit(0.0),
|
||||
m_count(0)
|
||||
{
|
||||
init(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
}
|
||||
|
||||
curve4_div(const curve4_points& cp) :
|
||||
m_approximation_scale(1.0),
|
||||
m_angle_tolerance(0.0),
|
||||
m_count(0)
|
||||
{
|
||||
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
void reset() { m_points.remove_all(); m_count = 0; }
|
||||
void init(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4);
|
||||
|
||||
void init(const curve4_points& cp)
|
||||
{
|
||||
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
void approximation_method(curve_approximation_method_e) {}
|
||||
|
||||
curve_approximation_method_e approximation_method() const
|
||||
{
|
||||
return curve_div;
|
||||
}
|
||||
|
||||
void approximation_scale(double s) { m_approximation_scale = s; }
|
||||
double approximation_scale() const { return m_approximation_scale; }
|
||||
|
||||
void angle_tolerance(double a) { m_angle_tolerance = a; }
|
||||
double angle_tolerance() const { return m_angle_tolerance; }
|
||||
|
||||
void cusp_limit(double v)
|
||||
{
|
||||
m_cusp_limit = (v == 0.0) ? 0.0 : pi - v;
|
||||
}
|
||||
|
||||
double cusp_limit() const
|
||||
{
|
||||
return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit;
|
||||
}
|
||||
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_count >= m_points.size()) return path_cmd_stop;
|
||||
const point_d& p = m_points[m_count++];
|
||||
*x = p.x;
|
||||
*y = p.y;
|
||||
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
|
||||
}
|
||||
|
||||
private:
|
||||
void bezier(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4);
|
||||
|
||||
void recursive_bezier(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4,
|
||||
unsigned level);
|
||||
|
||||
double m_approximation_scale;
|
||||
double m_distance_tolerance_square;
|
||||
double m_angle_tolerance;
|
||||
double m_cusp_limit;
|
||||
unsigned m_count;
|
||||
pod_bvector<point_d> m_points;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------curve3
|
||||
class curve3
|
||||
{
|
||||
public:
|
||||
curve3() : m_approximation_method(curve_div) {}
|
||||
curve3(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3) :
|
||||
m_approximation_method(curve_div)
|
||||
{
|
||||
init(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_curve_inc.reset();
|
||||
m_curve_div.reset();
|
||||
}
|
||||
|
||||
void init(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
if(m_approximation_method == curve_inc)
|
||||
{
|
||||
m_curve_inc.init(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_curve_div.init(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
}
|
||||
|
||||
void approximation_method(curve_approximation_method_e v)
|
||||
{
|
||||
m_approximation_method = v;
|
||||
}
|
||||
|
||||
curve_approximation_method_e approximation_method() const
|
||||
{
|
||||
return m_approximation_method;
|
||||
}
|
||||
|
||||
void approximation_scale(double s)
|
||||
{
|
||||
m_curve_inc.approximation_scale(s);
|
||||
m_curve_div.approximation_scale(s);
|
||||
}
|
||||
|
||||
double approximation_scale() const
|
||||
{
|
||||
return m_curve_inc.approximation_scale();
|
||||
}
|
||||
|
||||
void angle_tolerance(double a)
|
||||
{
|
||||
m_curve_div.angle_tolerance(a);
|
||||
}
|
||||
|
||||
double angle_tolerance() const
|
||||
{
|
||||
return m_curve_div.angle_tolerance();
|
||||
}
|
||||
|
||||
void cusp_limit(double v)
|
||||
{
|
||||
m_curve_div.cusp_limit(v);
|
||||
}
|
||||
|
||||
double cusp_limit() const
|
||||
{
|
||||
return m_curve_div.cusp_limit();
|
||||
}
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
if(m_approximation_method == curve_inc)
|
||||
{
|
||||
m_curve_inc.rewind(path_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_curve_div.rewind(path_id);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_approximation_method == curve_inc)
|
||||
{
|
||||
return m_curve_inc.vertex(x, y);
|
||||
}
|
||||
return m_curve_div.vertex(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
curve3_inc m_curve_inc;
|
||||
curve3_div m_curve_div;
|
||||
curve_approximation_method_e m_approximation_method;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------curve4
|
||||
class curve4
|
||||
{
|
||||
public:
|
||||
curve4() : m_approximation_method(curve_div) {}
|
||||
curve4(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4) :
|
||||
m_approximation_method(curve_div)
|
||||
{
|
||||
init(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
}
|
||||
|
||||
curve4(const curve4_points& cp) :
|
||||
m_approximation_method(curve_div)
|
||||
{
|
||||
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_curve_inc.reset();
|
||||
m_curve_div.reset();
|
||||
}
|
||||
|
||||
void init(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x4, double y4)
|
||||
{
|
||||
if(m_approximation_method == curve_inc)
|
||||
{
|
||||
m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
}
|
||||
}
|
||||
|
||||
void init(const curve4_points& cp)
|
||||
{
|
||||
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
|
||||
}
|
||||
|
||||
void approximation_method(curve_approximation_method_e v)
|
||||
{
|
||||
m_approximation_method = v;
|
||||
}
|
||||
|
||||
curve_approximation_method_e approximation_method() const
|
||||
{
|
||||
return m_approximation_method;
|
||||
}
|
||||
|
||||
void approximation_scale(double s)
|
||||
{
|
||||
m_curve_inc.approximation_scale(s);
|
||||
m_curve_div.approximation_scale(s);
|
||||
}
|
||||
double approximation_scale() const { return m_curve_inc.approximation_scale(); }
|
||||
|
||||
void angle_tolerance(double v)
|
||||
{
|
||||
m_curve_div.angle_tolerance(v);
|
||||
}
|
||||
|
||||
double angle_tolerance() const
|
||||
{
|
||||
return m_curve_div.angle_tolerance();
|
||||
}
|
||||
|
||||
void cusp_limit(double v)
|
||||
{
|
||||
m_curve_div.cusp_limit(v);
|
||||
}
|
||||
|
||||
double cusp_limit() const
|
||||
{
|
||||
return m_curve_div.cusp_limit();
|
||||
}
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
if(m_approximation_method == curve_inc)
|
||||
{
|
||||
m_curve_inc.rewind(path_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_curve_div.rewind(path_id);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_approximation_method == curve_inc)
|
||||
{
|
||||
return m_curve_inc.vertex(x, y);
|
||||
}
|
||||
return m_curve_div.vertex(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
curve4_inc m_curve_inc;
|
||||
curve4_div m_curve_div;
|
||||
curve_approximation_method_e m_approximation_method;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,290 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// classes dda_line_interpolator, dda2_line_interpolator
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_DDA_LINE_INCLUDED
|
||||
#define AGG_DDA_LINE_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//===================================================dda_line_interpolator
|
||||
template<int FractionShift, int YShift=0> class dda_line_interpolator
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
dda_line_interpolator() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
dda_line_interpolator(int y1, int y2, unsigned count) :
|
||||
m_y(y1),
|
||||
m_inc(((y2 - y1) << FractionShift) / 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)
|
||||
{
|
||||
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
|
||||
{
|
||||
public:
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = 8,
|
||||
subpixel_scale = 1 << subpixel_shift,
|
||||
subpixel_mask = subpixel_scale - 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
|
||||
m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class ellipse
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_ELLIPSE_INCLUDED
|
||||
#define AGG_ELLIPSE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------ellipse
|
||||
class ellipse
|
||||
{
|
||||
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);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::approximation_scale(double scale)
|
||||
{
|
||||
m_scale = scale;
|
||||
calc_num_steps();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void ellipse::calc_num_steps()
|
||||
{
|
||||
double ra = (fabs(m_rx) + fabs(m_ry)) / 2;
|
||||
double da = 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 + cos(angle) * m_rx;
|
||||
*y = m_y + sin(angle) * m_ry;
|
||||
m_step++;
|
||||
return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Simple Bresenham interpolator for ellipsees
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED
|
||||
#define AGG_ELLIPSE_BRESENHAM_INCLUDED
|
||||
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//------------------------------------------ellipse_bresenham_interpolator
|
||||
class ellipse_bresenham_interpolator
|
||||
{
|
||||
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++ ()
|
||||
{
|
||||
int mx, my, mxy, min_m;
|
||||
int fx, fy, fxy;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_EMBEDDED_RASTER_FONTS_INCLUDED
|
||||
#define AGG_EMBEDDED_RASTER_FONTS_INCLUDED
|
||||
|
||||
#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[];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,409 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_FONT_CACHE_MANAGER_INCLUDED
|
||||
#define AGG_FONT_CACHE_MANAGER_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#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
|
||||
{
|
||||
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)
|
||||
{
|
||||
m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
|
||||
strcpy(m_font_signature, font_signature);
|
||||
memset(m_glyphs, 0, sizeof(m_glyphs));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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
|
||||
{
|
||||
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||
if(m_glyphs[msb])
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
obj_allocator<font_cache>::deallocate(m_fonts[i]);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const font_cache* font() const
|
||||
{
|
||||
return m_cur_font;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const glyph_cache* find_glyph(unsigned glyph_code) const
|
||||
{
|
||||
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;
|
||||
return m_last_glyph = gl;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
case glyph_data_gray8:
|
||||
m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
|
||||
break;
|
||||
|
||||
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; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool add_kerning(double* x, double* 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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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())
|
||||
{
|
||||
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
|
||||
|
||||
|
|
@ -1,311 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_FONT_CACHE_MANAGER2_INCLUDED
|
||||
#define AGG_FONT_CACHE_MANAGER2_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <string.h>
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg {
|
||||
|
||||
namespace fman {
|
||||
//---------------------------------------------------------glyph_data_type
|
||||
enum glyph_data_type
|
||||
{
|
||||
glyph_data_invalid = 0,
|
||||
glyph_data_mono = 1,
|
||||
glyph_data_gray8 = 2,
|
||||
glyph_data_outline = 3
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------cached_glyph
|
||||
struct cached_glyph
|
||||
{
|
||||
void * cached_font;
|
||||
unsigned glyph_code;
|
||||
unsigned glyph_index;
|
||||
int8u* data;
|
||||
unsigned data_size;
|
||||
glyph_data_type data_type;
|
||||
rect_i bounds;
|
||||
double advance_x;
|
||||
double advance_y;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------cached_glyphs
|
||||
class cached_glyphs
|
||||
{
|
||||
public:
|
||||
enum block_size_e { block_size = 16384-16 };
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
cached_glyphs()
|
||||
: m_allocator(block_size)
|
||||
{ memset(m_glyphs, 0, sizeof(m_glyphs)); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const cached_glyph* find_glyph(unsigned glyph_code) const
|
||||
{
|
||||
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||
if(m_glyphs[msb])
|
||||
{
|
||||
return m_glyphs[msb][glyph_code & 0xFF];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
cached_glyph* cache_glyph(
|
||||
void * cached_font,
|
||||
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] =
|
||||
(cached_glyph**)m_allocator.allocate(sizeof(cached_glyph*) * 256,
|
||||
sizeof(cached_glyph*));
|
||||
memset(m_glyphs[msb], 0, sizeof(cached_glyph*) * 256);
|
||||
}
|
||||
|
||||
unsigned lsb = glyph_code & 0xFF;
|
||||
if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite
|
||||
|
||||
cached_glyph* glyph =
|
||||
(cached_glyph*)m_allocator.allocate(sizeof(cached_glyph),
|
||||
sizeof(double));
|
||||
|
||||
glyph->cached_font = cached_font;
|
||||
glyph->glyph_code = glyph_code;
|
||||
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;
|
||||
cached_glyph** m_glyphs[256];
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
struct cached_font
|
||||
{
|
||||
cached_font(
|
||||
font_engine_type& engine,
|
||||
typename FontEngine::loaded_face *face,
|
||||
double height,
|
||||
double width,
|
||||
bool hinting,
|
||||
glyph_rendering rendering )
|
||||
: m_engine( engine )
|
||||
, m_face( face )
|
||||
, m_height( height )
|
||||
, m_width( width )
|
||||
, m_hinting( hinting )
|
||||
, m_rendering( rendering )
|
||||
{
|
||||
select_face();
|
||||
m_face_height=m_face->height();
|
||||
m_face_width=m_face->width();
|
||||
m_face_ascent=m_face->ascent();
|
||||
m_face_descent=m_face->descent();
|
||||
m_face_ascent_b=m_face->ascent_b();
|
||||
m_face_descent_b=m_face->descent_b();
|
||||
}
|
||||
|
||||
double height() const
|
||||
{
|
||||
return m_face_height;
|
||||
}
|
||||
|
||||
double width() const
|
||||
{
|
||||
return m_face_width;
|
||||
}
|
||||
|
||||
double ascent() const
|
||||
{
|
||||
return m_face_ascent;
|
||||
}
|
||||
|
||||
double descent() const
|
||||
{
|
||||
return m_face_descent;
|
||||
}
|
||||
|
||||
double ascent_b() const
|
||||
{
|
||||
return m_face_ascent_b;
|
||||
}
|
||||
|
||||
double descent_b() const
|
||||
{
|
||||
return m_face_descent_b;
|
||||
}
|
||||
|
||||
bool add_kerning( const cached_glyph *first, const cached_glyph *second, double* x, double* y)
|
||||
{
|
||||
if( !first || !second )
|
||||
return false;
|
||||
select_face();
|
||||
return m_face->add_kerning(
|
||||
first->glyph_index, second->glyph_index, x, y );
|
||||
}
|
||||
|
||||
void select_face()
|
||||
{
|
||||
m_face->select_instance( m_height, m_width, m_hinting, m_rendering );
|
||||
}
|
||||
|
||||
const cached_glyph *get_glyph(unsigned cp)
|
||||
{
|
||||
const cached_glyph *glyph=m_glyphs.find_glyph(cp);
|
||||
if( glyph==0 )
|
||||
{
|
||||
typename FontEngine::prepared_glyph prepared;
|
||||
select_face();
|
||||
bool success=m_face->prepare_glyph(cp, &prepared);
|
||||
if( success )
|
||||
{
|
||||
glyph=m_glyphs.cache_glyph(
|
||||
this,
|
||||
prepared.glyph_code,
|
||||
prepared.glyph_index,
|
||||
prepared.data_size,
|
||||
prepared.data_type,
|
||||
prepared.bounds,
|
||||
prepared.advance_x,
|
||||
prepared.advance_y );
|
||||
assert( glyph!=0 );
|
||||
m_face->write_glyph_to(&prepared,glyph->data);
|
||||
}
|
||||
}
|
||||
return glyph;
|
||||
}
|
||||
|
||||
font_engine_type& m_engine;
|
||||
typename FontEngine::loaded_face *m_face;
|
||||
double m_height;
|
||||
double m_width;
|
||||
bool m_hinting;
|
||||
glyph_rendering m_rendering;
|
||||
double m_face_height;
|
||||
double m_face_width;
|
||||
double m_face_ascent;
|
||||
double m_face_descent;
|
||||
double m_face_ascent_b;
|
||||
double m_face_descent_b;
|
||||
cached_glyphs m_glyphs;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_manager(font_engine_type& engine, unsigned max_fonts=32)
|
||||
:m_engine(engine)
|
||||
{ }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init_embedded_adaptors(const cached_glyph* 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;
|
||||
|
||||
case glyph_data_gray8:
|
||||
m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
|
||||
break;
|
||||
|
||||
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; }
|
||||
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
font_cache_manager(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
font_engine_type& m_engine;
|
||||
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
|
||||
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_GLYPH_RASTER_BIN_INCLUDED
|
||||
#define AGG_GLYPH_RASTER_BIN_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//========================================================glyph_raster_bin
|
||||
template<class ColorT> class glyph_raster_bin
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_GRADIENT_LUT_INCLUDED
|
||||
#define AGG_GRADIENT_LUT_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
#include "agg_dda_line.h"
|
||||
#include "agg_color_rgba.h"
|
||||
#include "agg_color_gray.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//======================================================color_interpolator
|
||||
template<class ColorT> struct color_interpolator
|
||||
{
|
||||
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 ++ ()
|
||||
{
|
||||
++r; ++g; ++b; ++a;
|
||||
}
|
||||
|
||||
color_type color() const
|
||||
{
|
||||
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);
|
||||
void 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)
|
||||
{
|
||||
if(offset < 0.0) offset = 0.0;
|
||||
if(offset > 1.0) offset = 1.0;
|
||||
}
|
||||
};
|
||||
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>
|
||||
void 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Class gsv_text
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_GSV_TEXT_INCLUDED
|
||||
#define AGG_GSV_TEXT_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
#include "agg_conv_stroke.h"
|
||||
#include "agg_conv_transform.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
|
||||
//---------------------------------------------------------------gsv_text
|
||||
//
|
||||
// See Implementation agg_gsv_text.cpp
|
||||
//
|
||||
class gsv_text
|
||||
{
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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, 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)
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,481 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_IMAGE_ACCESSORS_INCLUDED
|
||||
#define AGG_IMAGE_ACCESSORS_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------image_accessor_clip
|
||||
template<class PixFmt> class image_accessor_clip
|
||||
{
|
||||
public:
|
||||
typedef PixFmt pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::order_type order_type;
|
||||
typedef typename pixfmt_type::value_type value_type;
|
||||
enum pix_width_e { pix_width = pixfmt_type::pix_width };
|
||||
|
||||
image_accessor_clip() {}
|
||||
explicit image_accessor_clip(pixfmt_type& pixf,
|
||||
const color_type& bk) :
|
||||
m_pixf(&pixf)
|
||||
{
|
||||
pixfmt_type::make_pix(m_bk_buf, bk);
|
||||
}
|
||||
|
||||
void attach(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[pix_width];
|
||||
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(pixfmt_type& pixf) :
|
||||
m_pixf(&pixf)
|
||||
{}
|
||||
|
||||
void attach(pixfmt_type& pixf)
|
||||
{
|
||||
m_pixf = &pixf;
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* next_x()
|
||||
{
|
||||
return m_pix_ptr += pix_width;
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* next_y()
|
||||
{
|
||||
++m_y;
|
||||
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
||||
}
|
||||
|
||||
private:
|
||||
const pixfmt_type* m_pixf;
|
||||
int m_x, m_y;
|
||||
const int8u* m_pix_ptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------image_accessor_clone
|
||||
template<class PixFmt> class image_accessor_clone
|
||||
{
|
||||
public:
|
||||
typedef PixFmt pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::order_type order_type;
|
||||
typedef typename pixfmt_type::value_type value_type;
|
||||
enum pix_width_e { pix_width = pixfmt_type::pix_width };
|
||||
|
||||
image_accessor_clone() {}
|
||||
explicit image_accessor_clone(pixfmt_type& pixf) :
|
||||
m_pixf(&pixf)
|
||||
{}
|
||||
|
||||
void attach(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+len <= (int)m_pixf->width())
|
||||
{
|
||||
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
||||
}
|
||||
m_pix_ptr = 0;
|
||||
return pixel();
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* next_x()
|
||||
{
|
||||
if(m_pix_ptr) return m_pix_ptr += pix_width;
|
||||
++m_x;
|
||||
return pixel();
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* next_y()
|
||||
{
|
||||
++m_y;
|
||||
m_x = m_x0;
|
||||
if(m_pix_ptr &&
|
||||
m_y >= 0 && m_y < (int)m_pixf->height())
|
||||
{
|
||||
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
||||
}
|
||||
m_pix_ptr = 0;
|
||||
return pixel();
|
||||
}
|
||||
|
||||
private:
|
||||
const pixfmt_type* m_pixf;
|
||||
int m_x, m_x0, m_y;
|
||||
const int8u* m_pix_ptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------image_accessor_wrap
|
||||
template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
|
||||
{
|
||||
public:
|
||||
typedef PixFmt pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::order_type order_type;
|
||||
typedef typename pixfmt_type::value_type value_type;
|
||||
enum pix_width_e { pix_width = pixfmt_type::pix_width };
|
||||
|
||||
image_accessor_wrap() {}
|
||||
explicit image_accessor_wrap(pixfmt_type& pixf) :
|
||||
m_pixf(&pixf),
|
||||
m_wrap_x(pixf.width()),
|
||||
m_wrap_y(pixf.height())
|
||||
{}
|
||||
|
||||
void attach(pixfmt_type& pixf)
|
||||
{
|
||||
m_pixf = &pixf;
|
||||
}
|
||||
|
||||
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
||||
{
|
||||
m_x = x;
|
||||
m_row_ptr = m_pixf->pix_ptr(0, 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->pix_ptr(0, ++m_wrap_y);
|
||||
return m_row_ptr + m_wrap_x(m_x) * pix_width;
|
||||
}
|
||||
|
||||
private:
|
||||
const pixfmt_type* m_pixf;
|
||||
const int8u* m_row_ptr;
|
||||
int m_x;
|
||||
WrapX m_wrap_x;
|
||||
WrapY m_wrap_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------wrap_mode_repeat
|
||||
class wrap_mode_repeat
|
||||
{
|
||||
public:
|
||||
wrap_mode_repeat() {}
|
||||
wrap_mode_repeat(unsigned size) :
|
||||
m_size(size),
|
||||
m_add(size * (0x3FFFFFFF / size)),
|
||||
m_value(0)
|
||||
{}
|
||||
|
||||
AGG_INLINE unsigned operator() (int v)
|
||||
{
|
||||
return m_value = (unsigned(v) + m_add) % m_size;
|
||||
}
|
||||
|
||||
AGG_INLINE unsigned operator++ ()
|
||||
{
|
||||
++m_value;
|
||||
if(m_value >= m_size) m_value = 0;
|
||||
return m_value;
|
||||
}
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned m_add;
|
||||
unsigned m_value;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------wrap_mode_repeat_pow2
|
||||
class wrap_mode_repeat_pow2
|
||||
{
|
||||
public:
|
||||
wrap_mode_repeat_pow2() {}
|
||||
wrap_mode_repeat_pow2(unsigned size) : m_value(0)
|
||||
{
|
||||
m_mask = 1;
|
||||
while(m_mask < size) m_mask = (m_mask << 1) | 1;
|
||||
m_mask >>= 1;
|
||||
}
|
||||
AGG_INLINE unsigned operator() (int v)
|
||||
{
|
||||
return m_value = unsigned(v) & m_mask;
|
||||
}
|
||||
AGG_INLINE unsigned operator++ ()
|
||||
{
|
||||
++m_value;
|
||||
if(m_value > m_mask) m_value = 0;
|
||||
return m_value;
|
||||
}
|
||||
private:
|
||||
unsigned m_mask;
|
||||
unsigned m_value;
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------wrap_mode_repeat_auto_pow2
|
||||
class wrap_mode_repeat_auto_pow2
|
||||
{
|
||||
public:
|
||||
wrap_mode_repeat_auto_pow2() {}
|
||||
wrap_mode_repeat_auto_pow2(unsigned size) :
|
||||
m_size(size),
|
||||
m_add(size * (0x3FFFFFFF / size)),
|
||||
m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
|
||||
m_value(0)
|
||||
{}
|
||||
|
||||
AGG_INLINE unsigned operator() (int v)
|
||||
{
|
||||
if(m_mask) return m_value = unsigned(v) & m_mask;
|
||||
return m_value = (unsigned(v) + m_add) % m_size;
|
||||
}
|
||||
AGG_INLINE unsigned operator++ ()
|
||||
{
|
||||
++m_value;
|
||||
if(m_value >= m_size) m_value = 0;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned m_add;
|
||||
unsigned m_mask;
|
||||
unsigned m_value;
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------wrap_mode_reflect
|
||||
class wrap_mode_reflect
|
||||
{
|
||||
public:
|
||||
wrap_mode_reflect() {}
|
||||
wrap_mode_reflect(unsigned size) :
|
||||
m_size(size),
|
||||
m_size2(size * 2),
|
||||
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
|
||||
m_value(0)
|
||||
{}
|
||||
|
||||
AGG_INLINE unsigned operator() (int v)
|
||||
{
|
||||
m_value = (unsigned(v) + m_add) % m_size2;
|
||||
if(m_value >= m_size) return m_size2 - m_value - 1;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
AGG_INLINE unsigned operator++ ()
|
||||
{
|
||||
++m_value;
|
||||
if(m_value >= m_size2) m_value = 0;
|
||||
if(m_value >= m_size) return m_size2 - m_value - 1;
|
||||
return m_value;
|
||||
}
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned m_size2;
|
||||
unsigned m_add;
|
||||
unsigned m_value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------wrap_mode_reflect_pow2
|
||||
class wrap_mode_reflect_pow2
|
||||
{
|
||||
public:
|
||||
wrap_mode_reflect_pow2() {}
|
||||
wrap_mode_reflect_pow2(unsigned size) : m_value(0)
|
||||
{
|
||||
m_mask = 1;
|
||||
m_size = 1;
|
||||
while(m_mask < size)
|
||||
{
|
||||
m_mask = (m_mask << 1) | 1;
|
||||
m_size <<= 1;
|
||||
}
|
||||
}
|
||||
AGG_INLINE unsigned operator() (int v)
|
||||
{
|
||||
m_value = unsigned(v) & m_mask;
|
||||
if(m_value >= m_size) return m_mask - m_value;
|
||||
return m_value;
|
||||
}
|
||||
AGG_INLINE unsigned operator++ ()
|
||||
{
|
||||
++m_value;
|
||||
m_value &= m_mask;
|
||||
if(m_value >= m_size) return m_mask - m_value;
|
||||
return m_value;
|
||||
}
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned m_mask;
|
||||
unsigned m_value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------wrap_mode_reflect_auto_pow2
|
||||
class wrap_mode_reflect_auto_pow2
|
||||
{
|
||||
public:
|
||||
wrap_mode_reflect_auto_pow2() {}
|
||||
wrap_mode_reflect_auto_pow2(unsigned size) :
|
||||
m_size(size),
|
||||
m_size2(size * 2),
|
||||
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
|
||||
m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
|
||||
m_value(0)
|
||||
{}
|
||||
|
||||
AGG_INLINE unsigned operator() (int v)
|
||||
{
|
||||
m_value = m_mask ? unsigned(v) & m_mask :
|
||||
(unsigned(v) + m_add) % m_size2;
|
||||
if(m_value >= m_size) return m_size2 - m_value - 1;
|
||||
return m_value;
|
||||
}
|
||||
AGG_INLINE unsigned operator++ ()
|
||||
{
|
||||
++m_value;
|
||||
if(m_value >= m_size2) m_value = 0;
|
||||
if(m_value >= m_size) return m_size2 - m_value - 1;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned m_size2;
|
||||
unsigned m_add;
|
||||
unsigned m_mask;
|
||||
unsigned m_value;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,449 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Image transformation filters,
|
||||
// Filtering classes (image_filter_lut, image_filter),
|
||||
// Basic filter shape classes
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_IMAGE_FILTERS_INCLUDED
|
||||
#define AGG_IMAGE_FILTERS_INCLUDED
|
||||
|
||||
#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
|
||||
{
|
||||
public:
|
||||
template<class FilterF> void calculate(const FilterF& filter,
|
||||
bool normalization=true)
|
||||
{
|
||||
filter; // prevent erroneous C4100 in MSVC
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
|
||||
|
||||
template<class FilterF> image_filter_lut(const FilterF& filter,
|
||||
bool normalization=true)
|
||||
{
|
||||
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 * 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 * 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) {t = x - 1.5; return 0.5 * t * t;}
|
||||
return 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------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_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_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
|
||||
{
|
||||
if(x == 0.0) return 1.0;
|
||||
x *= pi;
|
||||
return 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) return 0.0;
|
||||
x *= pi;
|
||||
double xr = x / m_radius;
|
||||
return (sin(x) / x) * (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
|
||||
{
|
||||
if(x == 0.0) return 1.0;
|
||||
if(x > m_radius) return 0.0;
|
||||
x *= pi;
|
||||
double xr = x / m_radius;
|
||||
return (sin(x) / x) * (0.42 + 0.5*cos(xr) + 0.08*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_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_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_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
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_LINE_AA_BASICS_INCLUDED
|
||||
#define AGG_LINE_AA_BASICS_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
#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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------line_dbl_hr
|
||||
AGG_INLINE int line_dbl_hr(int x)
|
||||
{
|
||||
return x << line_subpixel_shift;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------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(abs(x2_ - x1_)),
|
||||
dy(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 = abs(lp1.x2 - lp1.x1);
|
||||
lp1.dy = abs(lp1.y2 - lp1.y1);
|
||||
|
||||
lp2.x1 = xmid;
|
||||
lp2.y1 = ymid;
|
||||
lp2.len = len2;
|
||||
lp2.dx = abs(lp2.x2 - lp2.x1);
|
||||
lp2.dy = 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,526 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Stroke math
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_STROKE_MATH_INCLUDED
|
||||
#define AGG_STROKE_MATH_INCLUDED
|
||||
|
||||
#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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 / 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 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
|
||||
double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
|
||||
double da = a1 - a2;
|
||||
int i, n;
|
||||
|
||||
da = 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 + cos(a1) * m_width, y + 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++)
|
||||
{
|
||||
add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
|
||||
a1 -= da;
|
||||
}
|
||||
}
|
||||
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))
|
||||
{
|
||||
// Calculation of the intersection succeeded
|
||||
//---------------------
|
||||
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;
|
||||
}
|
||||
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))
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
case miter_join_revert:
|
||||
// For the compatibility with SVG, PDF, etc,
|
||||
// we use a simple bevel join instead of
|
||||
// "smart" bevel
|
||||
//-------------------
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||
break;
|
||||
|
||||
case miter_join_round:
|
||||
calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
|
||||
break;
|
||||
|
||||
default:
|
||||
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
|
||||
//----------------
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
double x1 = v1.x + dx1;
|
||||
double y1 = v1.y - dy1;
|
||||
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);
|
||||
}
|
||||
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 = 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 = atan2(dy1, -dx1);
|
||||
a1 += da;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
add_vertex(vc, v0.x + cos(a1) * m_width,
|
||||
v0.y + sin(a1) * m_width);
|
||||
a1 += da;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a1 = atan2(-dy1, dx1);
|
||||
a1 -= da;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
add_vertex(vc, v0.x + cos(a1) * m_width,
|
||||
v0.y + sin(a1) * m_width);
|
||||
a1 -= da;
|
||||
}
|
||||
}
|
||||
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))
|
||||
{
|
||||
// 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);
|
||||
break;
|
||||
|
||||
case inner_jag:
|
||||
case inner_round:
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 + dx2, v1.y - dy2);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
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 + 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)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
|
||||
case round_join:
|
||||
calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
|
||||
break;
|
||||
|
||||
default: // Bevel join
|
||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_PATH_LENGTH_INCLUDED
|
||||
#define AGG_PATH_LENGTH_INCLUDED
|
||||
|
||||
#include "agg_math.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
template<class VertexSource>
|
||||
double path_length(VertexSource& vs, unsigned path_id = 0)
|
||||
{
|
||||
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(is_vertex(cmd))
|
||||
{
|
||||
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
|
||||
{
|
||||
if(is_close(cmd) && !first)
|
||||
{
|
||||
len += calc_distance(x1, y1, start_x, start_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,295 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PATH_STORAGE_INTEGER_INCLUDED
|
||||
#define AGG_PATH_STORAGE_INTEGER_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//---------------------------------------------------------vertex_integer
|
||||
template<class T, unsigned CoordShift=6> struct vertex_integer
|
||||
{
|
||||
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
|
||||
{
|
||||
*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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------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++)
|
||||
{
|
||||
memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
|
||||
ptr += sizeof(vertex_integer_type);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_vertex_idx = 0;
|
||||
m_closed = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rect_d bounding_rect() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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
|
||||
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_PATTERN_FILTERS_RGBA8_INCLUDED
|
||||
#define AGG_PATTERN_FILTERS_RGBA8_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_line_aa_basics.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=======================================================pattern_filter_nn
|
||||
template<class ColorT> struct pattern_filter_nn
|
||||
{
|
||||
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)
|
||||
{
|
||||
*p = buf[y >> line_subpixel_shift]
|
||||
[x >> line_subpixel_shift];
|
||||
}
|
||||
};
|
||||
|
||||
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
|
||||
typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
|
||||
|
||||
|
||||
//===========================================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 unsigned dilation() { return 1; }
|
||||
|
||||
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)
|
||||
{
|
||||
calc_type r, g, b, a;
|
||||
r = g = b = a = 0;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
weight = x * (line_subpixel_scale - y);
|
||||
r += weight * ptr->r;
|
||||
g += weight * ptr->g;
|
||||
b += weight * ptr->b;
|
||||
a += weight * ptr->a;
|
||||
|
||||
ptr = buf[y_lr + 1] + x_lr;
|
||||
|
||||
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)color_type::downshift(r, line_subpixel_shift * 2);
|
||||
p->g = (value_type)color_type::downshift(g, line_subpixel_shift * 2);
|
||||
p->b = (value_type)color_type::downshift(b, line_subpixel_shift * 2);
|
||||
p->a = (value_type)color_type::downshift(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;
|
||||
typedef pattern_filter_bilinear_rgba<rgba32> pattern_filter_bilinear_rgba32;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,240 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
||||
#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_array.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//==================================================pixfmt_amask_adaptor
|
||||
template<class PixFmt, class AlphaMask> class pixfmt_amask_adaptor
|
||||
{
|
||||
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)
|
||||
{
|
||||
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, amask_type& mask) :
|
||||
m_pixf(&pixf), m_mask(&mask), m_span()
|
||||
{}
|
||||
|
||||
void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||
void attach_alpha_mask(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,157 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PIXFMT_TRANSPOSER_INCLUDED
|
||||
#define AGG_PIXFMT_TRANSPOSER_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//=======================================================pixfmt_transposer
|
||||
template<class PixFmt> class pixfmt_transposer
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -1,665 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.3
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// The author gratefully acknowleges the support of David Turner,
|
||||
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
|
||||
// libray - in producing this work. See http://www.freetype.org for details.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_COMPOUND_AA_INCLUDED
|
||||
#define AGG_RASTERIZER_COMPOUND_AA_INCLUDED
|
||||
|
||||
#include <limits>
|
||||
#include "agg_rasterizer_cells_aa.h"
|
||||
#include "agg_rasterizer_sl_clip.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------cell_style_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_style_aa
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int cover;
|
||||
int area;
|
||||
int16 left, right;
|
||||
|
||||
void initial()
|
||||
{
|
||||
x = std::numeric_limits<int>::max();
|
||||
y = std::numeric_limits<int>::max();
|
||||
cover = 0;
|
||||
area = 0;
|
||||
left = -1;
|
||||
right = -1;
|
||||
}
|
||||
|
||||
void style(const cell_style_aa& c)
|
||||
{
|
||||
left = c.left;
|
||||
right = c.right;
|
||||
}
|
||||
|
||||
int not_equal(int ex, int ey, const cell_style_aa& c) const
|
||||
{
|
||||
return ((unsigned)ex - (unsigned)x) | ((unsigned)ey - (unsigned)y) |
|
||||
((unsigned)left - (unsigned)c.left) | ((unsigned)right - (unsigned)c.right);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===========================================================layer_order_e
|
||||
enum layer_order_e
|
||||
{
|
||||
layer_unsorted, //------layer_unsorted
|
||||
layer_direct, //------layer_direct
|
||||
layer_inverse //------layer_inverse
|
||||
};
|
||||
|
||||
|
||||
//==================================================rasterizer_compound_aa
|
||||
template<class Clip=rasterizer_sl_clip_int> class rasterizer_compound_aa
|
||||
{
|
||||
struct style_info
|
||||
{
|
||||
unsigned start_cell;
|
||||
unsigned num_cells;
|
||||
int last_x;
|
||||
};
|
||||
|
||||
struct cell_info
|
||||
{
|
||||
int x, area, cover;
|
||||
};
|
||||
|
||||
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_compound_aa() :
|
||||
m_outline(),
|
||||
m_clipper(),
|
||||
m_filling_rule(fill_non_zero),
|
||||
m_layer_order(layer_direct),
|
||||
m_styles(), // Active Styles
|
||||
m_ast(), // Active Style Table (unique values)
|
||||
m_asm(), // Active Style Mask
|
||||
m_cells(),
|
||||
m_cover_buf(),
|
||||
m_min_style(std::numeric_limits<int>::max()),
|
||||
m_max_style(std::numeric_limits<int>::min()),
|
||||
m_start_x(0),
|
||||
m_start_y(0),
|
||||
m_scan_y(std::numeric_limits<int>::max()),
|
||||
m_sl_start(0),
|
||||
m_sl_len(0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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 layer_order(layer_order_e order);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void styles(int left, int right);
|
||||
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 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)))
|
||||
{
|
||||
add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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(); }
|
||||
int min_style() const { return m_min_style; }
|
||||
int max_style() const { return m_max_style; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void sort();
|
||||
bool rewind_scanlines();
|
||||
unsigned sweep_styles();
|
||||
int scanline_start() const { return m_sl_start; }
|
||||
unsigned scanline_length() const { return m_sl_len; }
|
||||
unsigned style(unsigned style_idx) const;
|
||||
|
||||
cover_type* allocate_cover_buffer(unsigned len);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool navigate_scanline(int y);
|
||||
bool hit_test(int tx, int ty);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
cover = aa_scale2 - cover;
|
||||
}
|
||||
}
|
||||
if(cover > aa_mask) cover = aa_mask;
|
||||
return cover;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Sweeps one scanline with one style index. The style ID can be
|
||||
// determined by calling style().
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl, int style_idx)
|
||||
{
|
||||
int scan_y = m_scan_y - 1;
|
||||
if(scan_y > m_outline.max_y()) return false;
|
||||
|
||||
sl.reset_spans();
|
||||
|
||||
if(style_idx < 0)
|
||||
{
|
||||
style_idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
style_idx++;
|
||||
}
|
||||
|
||||
const style_info& st = m_styles[m_ast[style_idx]];
|
||||
|
||||
unsigned num_cells = st.num_cells;
|
||||
cell_info* cell = &m_cells[st.start_cell];
|
||||
|
||||
int cover = 0;
|
||||
while(num_cells--)
|
||||
{
|
||||
unsigned alpha;
|
||||
int x = cell->x;
|
||||
int area = cell->area;
|
||||
|
||||
cover += cell->cover;
|
||||
|
||||
++cell;
|
||||
|
||||
if(area)
|
||||
{
|
||||
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
|
||||
sl.add_cell(x, alpha);
|
||||
x++;
|
||||
}
|
||||
|
||||
if(num_cells && cell->x > x)
|
||||
{
|
||||
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
|
||||
if(alpha)
|
||||
{
|
||||
sl.add_span(x, cell->x - x, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(sl.num_spans() == 0) return false;
|
||||
sl.finalize(scan_y);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void add_style(int style_id);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Disable copying
|
||||
rasterizer_compound_aa(const rasterizer_compound_aa<Clip>&);
|
||||
const rasterizer_compound_aa<Clip>&
|
||||
operator = (const rasterizer_compound_aa<Clip>&);
|
||||
|
||||
private:
|
||||
rasterizer_cells_aa<cell_style_aa> m_outline;
|
||||
clip_type m_clipper;
|
||||
filling_rule_e m_filling_rule;
|
||||
layer_order_e m_layer_order;
|
||||
pod_vector<style_info> m_styles; // Active Styles
|
||||
pod_vector<unsigned> m_ast; // Active Style Table (unique values)
|
||||
pod_vector<int8u> m_asm; // Active Style Mask
|
||||
pod_vector<cell_info> m_cells;
|
||||
pod_vector<cover_type> m_cover_buf;
|
||||
|
||||
int m_min_style;
|
||||
int m_max_style;
|
||||
coord_type m_start_x;
|
||||
coord_type m_start_y;
|
||||
int m_scan_y;
|
||||
int m_sl_start;
|
||||
unsigned m_sl_len;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::reset()
|
||||
{
|
||||
m_outline.reset();
|
||||
m_min_style = std::numeric_limits<int>::max();
|
||||
m_max_style = std::numeric_limits<int>::min();
|
||||
m_scan_y = std::numeric_limits<int>::max();
|
||||
m_sl_start = 0;
|
||||
m_sl_len = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::filling_rule(filling_rule_e filling_rule)
|
||||
{
|
||||
m_filling_rule = filling_rule;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::layer_order(layer_order_e order)
|
||||
{
|
||||
m_layer_order = order;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_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_compound_aa<Clip>::reset_clipping()
|
||||
{
|
||||
reset();
|
||||
m_clipper.reset_clipping();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::styles(int left, int right)
|
||||
{
|
||||
cell_style_aa cell;
|
||||
cell.initial();
|
||||
cell.left = (int16)left;
|
||||
cell.right = (int16)right;
|
||||
m_outline.style(cell);
|
||||
if(left >= 0 && left < m_min_style) m_min_style = left;
|
||||
if(left >= 0 && left > m_max_style) m_max_style = left;
|
||||
if(right >= 0 && right < m_min_style) m_min_style = right;
|
||||
if(right >= 0 && right > m_max_style) m_max_style = right;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::move_to(int x, int y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(m_start_x = conv_type::downscale(x),
|
||||
m_start_y = conv_type::downscale(y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::line_to(int x, int y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::downscale(x),
|
||||
conv_type::downscale(y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::move_to_d(double x, double y)
|
||||
{
|
||||
if(m_outline.sorted()) reset();
|
||||
m_clipper.move_to(m_start_x = conv_type::upscale(x),
|
||||
m_start_y = conv_type::upscale(y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_aa<Clip>::line_to_d(double x, double y)
|
||||
{
|
||||
m_clipper.line_to(m_outline,
|
||||
conv_type::upscale(x),
|
||||
conv_type::upscale(y));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_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))
|
||||
{
|
||||
m_clipper.line_to(m_outline, m_start_x, m_start_y);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_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));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
void rasterizer_compound_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));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE void rasterizer_compound_aa<Clip>::sort()
|
||||
{
|
||||
m_outline.sort_cells();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_compound_aa<Clip>::rewind_scanlines()
|
||||
{
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(m_max_style < m_min_style)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = m_outline.min_y();
|
||||
m_styles.allocate(m_max_style - m_min_style + 2, 128);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE void rasterizer_compound_aa<Clip>::add_style(int style_id)
|
||||
{
|
||||
if(style_id < 0) style_id = 0;
|
||||
else style_id -= m_min_style - 1;
|
||||
|
||||
unsigned nbyte = style_id >> 3;
|
||||
unsigned mask = 1 << (style_id & 7);
|
||||
|
||||
style_info* style = &m_styles[style_id];
|
||||
if((m_asm[nbyte] & mask) == 0)
|
||||
{
|
||||
m_ast.add(style_id);
|
||||
m_asm[nbyte] |= mask;
|
||||
style->start_cell = 0;
|
||||
style->num_cells = 0;
|
||||
style->last_x = std::numeric_limits<int>::min();
|
||||
}
|
||||
++style->start_cell;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Returns the number of styles
|
||||
template<class Clip>
|
||||
unsigned rasterizer_compound_aa<Clip>::sweep_styles()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(m_scan_y > m_outline.max_y()) return 0;
|
||||
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
|
||||
const cell_style_aa* const* cells = m_outline.scanline_cells(m_scan_y);
|
||||
unsigned num_styles = m_max_style - m_min_style + 2;
|
||||
const cell_style_aa* curr_cell;
|
||||
unsigned style_id;
|
||||
style_info* style;
|
||||
cell_info* cell;
|
||||
|
||||
m_cells.allocate(num_cells * 2, 256); // Each cell can have two styles
|
||||
m_ast.capacity(num_styles, 64);
|
||||
m_asm.allocate((num_styles + 7) >> 3, 8);
|
||||
m_asm.zero();
|
||||
|
||||
if(num_cells)
|
||||
{
|
||||
// Pre-add zero (for no-fill style, that is, -1).
|
||||
// We need that to ensure that the "-1 style" would go first.
|
||||
m_asm[0] |= 1;
|
||||
m_ast.add(0);
|
||||
style = &m_styles[0];
|
||||
style->start_cell = 0;
|
||||
style->num_cells = 0;
|
||||
style->last_x = std::numeric_limits<int>::min();
|
||||
|
||||
m_sl_start = cells[0]->x;
|
||||
m_sl_len = cells[num_cells-1]->x - m_sl_start + 1;
|
||||
while(num_cells--)
|
||||
{
|
||||
curr_cell = *cells++;
|
||||
add_style(curr_cell->left);
|
||||
add_style(curr_cell->right);
|
||||
}
|
||||
|
||||
// Convert the Y-histogram into the array of starting indexes
|
||||
unsigned i;
|
||||
unsigned start_cell = 0;
|
||||
for(i = 0; i < m_ast.size(); i++)
|
||||
{
|
||||
style_info& st = m_styles[m_ast[i]];
|
||||
unsigned v = st.start_cell;
|
||||
st.start_cell = start_cell;
|
||||
start_cell += v;
|
||||
}
|
||||
|
||||
cells = m_outline.scanline_cells(m_scan_y);
|
||||
num_cells = m_outline.scanline_num_cells(m_scan_y);
|
||||
|
||||
while(num_cells--)
|
||||
{
|
||||
curr_cell = *cells++;
|
||||
style_id = (curr_cell->left < 0) ? 0 :
|
||||
curr_cell->left - m_min_style + 1;
|
||||
|
||||
style = &m_styles[style_id];
|
||||
if(curr_cell->x == style->last_x)
|
||||
{
|
||||
cell = &m_cells[style->start_cell + style->num_cells - 1];
|
||||
cell->area += curr_cell->area;
|
||||
cell->cover += curr_cell->cover;
|
||||
}
|
||||
else
|
||||
{
|
||||
cell = &m_cells[style->start_cell + style->num_cells];
|
||||
cell->x = curr_cell->x;
|
||||
cell->area = curr_cell->area;
|
||||
cell->cover = curr_cell->cover;
|
||||
style->last_x = curr_cell->x;
|
||||
style->num_cells++;
|
||||
}
|
||||
|
||||
style_id = (curr_cell->right < 0) ? 0 :
|
||||
curr_cell->right - m_min_style + 1;
|
||||
|
||||
style = &m_styles[style_id];
|
||||
if(curr_cell->x == style->last_x)
|
||||
{
|
||||
cell = &m_cells[style->start_cell + style->num_cells - 1];
|
||||
cell->area -= curr_cell->area;
|
||||
cell->cover -= curr_cell->cover;
|
||||
}
|
||||
else
|
||||
{
|
||||
cell = &m_cells[style->start_cell + style->num_cells];
|
||||
cell->x = curr_cell->x;
|
||||
cell->area = -curr_cell->area;
|
||||
cell->cover = -curr_cell->cover;
|
||||
style->last_x = curr_cell->x;
|
||||
style->num_cells++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_ast.size() > 1) break;
|
||||
++m_scan_y;
|
||||
}
|
||||
++m_scan_y;
|
||||
|
||||
if(m_layer_order != layer_unsorted)
|
||||
{
|
||||
range_adaptor<pod_vector<unsigned> > ra(m_ast, 1, m_ast.size() - 1);
|
||||
if(m_layer_order == layer_direct) quick_sort(ra, unsigned_greater);
|
||||
else quick_sort(ra, unsigned_less);
|
||||
}
|
||||
|
||||
return m_ast.size() - 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Returns style ID depending of the existing style index
|
||||
template<class Clip>
|
||||
AGG_INLINE
|
||||
unsigned rasterizer_compound_aa<Clip>::style(unsigned style_idx) const
|
||||
{
|
||||
return m_ast[style_idx + 1] + m_min_style - 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
AGG_INLINE bool rasterizer_compound_aa<Clip>::navigate_scanline(int y)
|
||||
{
|
||||
m_outline.sort_cells();
|
||||
if(m_outline.total_cells() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(m_max_style < m_min_style)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(y < m_outline.min_y() || y > m_outline.max_y())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_scan_y = y;
|
||||
m_styles.allocate(m_max_style - m_min_style + 2, 128);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
bool rasterizer_compound_aa<Clip>::hit_test(int tx, int ty)
|
||||
{
|
||||
if(!navigate_scanline(ty))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned num_styles = sweep_styles();
|
||||
if(num_styles <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
scanline_hit_test sl(tx);
|
||||
sweep_scanline(sl, -1);
|
||||
return sl.hit();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip>
|
||||
cover_type* rasterizer_compound_aa<Clip>::allocate_cover_buffer(unsigned len)
|
||||
{
|
||||
m_cover_buf.allocate(len, 256);
|
||||
return &m_cover_buf[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_OUTLINE_INCLUDED
|
||||
#define AGG_RASTERIZER_OUTLINE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//======================================================rasterizer_outline
|
||||
template<class Renderer> class rasterizer_outline
|
||||
{
|
||||
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)
|
||||
{
|
||||
m_vertices = 1;
|
||||
m_ren->move_to(m_start_x = x, m_start_y = y);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
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)))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,599 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_OUTLINE_AA_INCLUDED
|
||||
#define AGG_RASTERIZER_OUTLINE_AA_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_line_aa_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool cmp_dist_start(int d) { 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;
|
||||
|
||||
line_aa_vertex() {}
|
||||
line_aa_vertex(int x_, int y_) :
|
||||
x(x_),
|
||||
y(y_),
|
||||
len(0)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------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
|
||||
};
|
||||
|
||||
//=======================================================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;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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(false);
|
||||
move_to_d(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
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)))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
const vertex_storage_type::value_type* v;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
}
|
||||
break;
|
||||
|
||||
case outline_round_join:
|
||||
dv.flags >>= 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)
|
||||
{
|
||||
if(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);
|
||||
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 & 2) == 0 && m_line_join != outline_round_join)
|
||||
{
|
||||
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
|
||||
}
|
||||
draw(dv, 0, m_src_vertices.size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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 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);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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->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;
|
||||
}
|
||||
}
|
||||
m_src_vertices.remove_all();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,711 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class renderer_markers
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_MARKERS_INCLUDED
|
||||
#define AGG_RENDERER_MARKERS_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_renderer_primitives.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//---------------------------------------------------------------marker_e
|
||||
enum marker_e
|
||||
{
|
||||
marker_square,
|
||||
marker_diamond,
|
||||
marker_circle,
|
||||
marker_crossed_circle,
|
||||
marker_semiellipse_left,
|
||||
marker_semiellipse_right,
|
||||
marker_semiellipse_up,
|
||||
marker_semiellipse_down,
|
||||
marker_triangle_left,
|
||||
marker_triangle_right,
|
||||
marker_triangle_up,
|
||||
marker_triangle_down,
|
||||
marker_four_rays,
|
||||
marker_cross,
|
||||
marker_x,
|
||||
marker_dash,
|
||||
marker_dot,
|
||||
marker_pixel,
|
||||
|
||||
end_of_markers
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------renderer_markers
|
||||
template<class BaseRenderer> class renderer_markers :
|
||||
public renderer_primitives<BaseRenderer>
|
||||
{
|
||||
public:
|
||||
typedef renderer_primitives<BaseRenderer> base_type;
|
||||
typedef BaseRenderer base_ren_type;
|
||||
typedef typename base_ren_type::color_type color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_markers(base_ren_type& rbuf) :
|
||||
base_type(rbuf)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool visible(int x, int y, int r) const
|
||||
{
|
||||
rect_i rc(x-r, y-r, x+y, y+r);
|
||||
return rc.clip(base_type::ren().bounding_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void square(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r) base_type::outlined_rectangle(x-r, y-r, x+r, y+r);
|
||||
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void diamond(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
|
||||
|
||||
if(dx)
|
||||
{
|
||||
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++dy;
|
||||
++dx;
|
||||
}
|
||||
while(dy <= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void circle(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r) base_type::outlined_ellipse(x, y, r, r);
|
||||
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void crossed_circle(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
base_type::outlined_ellipse(x, y, r, r);
|
||||
int r6 = r + (r >> 1);
|
||||
if(r <= 2) r6++;
|
||||
r >>= 1;
|
||||
base_type::ren().blend_hline(x-r6, y, x-r, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_hline(x+r, y, x+r6, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_vline(x, y-r6, y-r, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_vline(x, y+r, y+r6, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void semiellipse_left(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int r8 = r * 4 / 5;
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
|
||||
do
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
|
||||
|
||||
if(ei.dy() && dx)
|
||||
{
|
||||
base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++ei;
|
||||
}
|
||||
while(dy < r8);
|
||||
base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void semiellipse_right(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int r8 = r * 4 / 5;
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
|
||||
do
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
|
||||
|
||||
if(ei.dy() && dx)
|
||||
{
|
||||
base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++ei;
|
||||
}
|
||||
while(dy < r8);
|
||||
base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void semiellipse_up(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int r8 = r * 4 / 5;
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
|
||||
do
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
|
||||
|
||||
if(ei.dy() && dx)
|
||||
{
|
||||
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++ei;
|
||||
}
|
||||
while(dy < r8);
|
||||
base_type::ren().blend_hline(x-dx, y-dy-1, x+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void semiellipse_down(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int r8 = r * 4 / 5;
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
|
||||
do
|
||||
{
|
||||
dx += ei.dx();
|
||||
dy += ei.dy();
|
||||
|
||||
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
|
||||
|
||||
if(ei.dy() && dx)
|
||||
{
|
||||
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++ei;
|
||||
}
|
||||
while(dy < r8);
|
||||
base_type::ren().blend_hline(x-dx, y+dy+1, x+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void triangle_left(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
int flip = 0;
|
||||
int r6 = r * 3 / 5;
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
|
||||
|
||||
if(dx)
|
||||
{
|
||||
base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++dy;
|
||||
dx += flip;
|
||||
flip ^= 1;
|
||||
}
|
||||
while(dy < r6);
|
||||
base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void triangle_right(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
int flip = 0;
|
||||
int r6 = r * 3 / 5;
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
|
||||
|
||||
if(dx)
|
||||
{
|
||||
base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++dy;
|
||||
dx += flip;
|
||||
flip ^= 1;
|
||||
}
|
||||
while(dy < r6);
|
||||
base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void triangle_up(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
int flip = 0;
|
||||
int r6 = r * 3 / 5;
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
|
||||
|
||||
if(dx)
|
||||
{
|
||||
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++dy;
|
||||
dx += flip;
|
||||
flip ^= 1;
|
||||
}
|
||||
while(dy < r6);
|
||||
base_type::ren().blend_hline(x-dx, y-dy, x+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void triangle_down(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
int flip = 0;
|
||||
int r6 = r * 3 / 5;
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
|
||||
|
||||
if(dx)
|
||||
{
|
||||
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++dy;
|
||||
dx += flip;
|
||||
flip ^= 1;
|
||||
}
|
||||
while(dy < r6);
|
||||
base_type::ren().blend_hline(x-dx, y+dy, x+dx, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void four_rays(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int dy = -r;
|
||||
int dx = 0;
|
||||
int flip = 0;
|
||||
int r3 = -(r / 3);
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
|
||||
|
||||
if(dx)
|
||||
{
|
||||
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
|
||||
base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
|
||||
base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
|
||||
}
|
||||
++dy;
|
||||
dx += flip;
|
||||
flip ^= 1;
|
||||
}
|
||||
while(dy <= r3);
|
||||
base_type::solid_rectangle(x+r3+1, y+r3+1, x-r3-1, y-r3-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void cross(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
base_type::ren().blend_vline(x, y-r, y+r, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void xing(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r)
|
||||
{
|
||||
int dy = -r * 7 / 10;
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(x + dy, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dy, y + dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x + dy, y - dy, base_type::line_color(), cover_full);
|
||||
base_type::ren().blend_pixel(x - dy, y - dy, base_type::line_color(), cover_full);
|
||||
++dy;
|
||||
}
|
||||
while(dy < 0);
|
||||
}
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void dash(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r) base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full);
|
||||
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void dot(int x, int y, int r)
|
||||
{
|
||||
if(visible(x, y, r))
|
||||
{
|
||||
if(r) base_type::solid_ellipse(x, y, r, r);
|
||||
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void pixel(int x, int y, int)
|
||||
{
|
||||
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void marker(int x, int y, int r, marker_e type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case marker_square: square(x, y, r); break;
|
||||
case marker_diamond: diamond(x, y, r); break;
|
||||
case marker_circle: circle(x, y, r); break;
|
||||
case marker_crossed_circle: crossed_circle(x, y, r); break;
|
||||
case marker_semiellipse_left: semiellipse_left(x, y, r); break;
|
||||
case marker_semiellipse_right: semiellipse_right(x, y, r); break;
|
||||
case marker_semiellipse_up: semiellipse_up(x, y, r); break;
|
||||
case marker_semiellipse_down: semiellipse_down(x, y, r); break;
|
||||
case marker_triangle_left: triangle_left(x, y, r); break;
|
||||
case marker_triangle_right: triangle_right(x, y, r); break;
|
||||
case marker_triangle_up: triangle_up(x, y, r); break;
|
||||
case marker_triangle_down: triangle_down(x, y, r); break;
|
||||
case marker_four_rays: four_rays(x, y, r); break;
|
||||
case marker_cross: cross(x, y, r); break;
|
||||
case marker_x: xing(x, y, r); break;
|
||||
case marker_dash: dash(x, y, r); break;
|
||||
case marker_dot: dot(x, y, r); break;
|
||||
case marker_pixel: pixel(x, y, r); break;
|
||||
case end_of_markers: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class T>
|
||||
void markers(int n, const T* x, const T* y, T r, marker_e type)
|
||||
{
|
||||
if(n <= 0) return;
|
||||
if(r == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
base_type::ren().blend_pixel(int(*x), int(*y), base_type::fill_color(), cover_full);
|
||||
++x;
|
||||
++y;
|
||||
}
|
||||
while(--n);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case marker_square: do { square (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_diamond: do { diamond (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_circle: do { circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_four_rays: do { four_rays (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_cross: do { cross (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_x: do { xing (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_dash: do { dash (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_dot: do { dot (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case marker_pixel: do { pixel (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
|
||||
case end_of_markers: break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class T>
|
||||
void markers(int n, const T* x, const T* y, const T* r, marker_e type)
|
||||
{
|
||||
if(n <= 0) return;
|
||||
switch(type)
|
||||
{
|
||||
case marker_square: do { square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_diamond: do { diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_circle: do { circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_four_rays: do { four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_cross: do { cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_x: do { xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_dash: do { dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_dot: do { dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case marker_pixel: do { pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
|
||||
case end_of_markers: break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class T>
|
||||
void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, marker_e type)
|
||||
{
|
||||
if(n <= 0) return;
|
||||
switch(type)
|
||||
{
|
||||
case marker_square: do { base_type::fill_color(*fc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_diamond: do { base_type::fill_color(*fc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_circle: do { base_type::fill_color(*fc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_crossed_circle: do { base_type::fill_color(*fc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_semiellipse_left: do { base_type::fill_color(*fc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_semiellipse_right: do { base_type::fill_color(*fc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_semiellipse_up: do { base_type::fill_color(*fc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_semiellipse_down: do { base_type::fill_color(*fc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_triangle_left: do { base_type::fill_color(*fc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_triangle_right: do { base_type::fill_color(*fc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_triangle_up: do { base_type::fill_color(*fc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_triangle_down: do { base_type::fill_color(*fc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_four_rays: do { base_type::fill_color(*fc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_cross: do { base_type::fill_color(*fc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_x: do { base_type::fill_color(*fc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_dash: do { base_type::fill_color(*fc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_dot: do { base_type::fill_color(*fc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case marker_pixel: do { base_type::fill_color(*fc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
|
||||
case end_of_markers: break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class T>
|
||||
void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, const color_type* lc, marker_e type)
|
||||
{
|
||||
if(n <= 0) return;
|
||||
switch(type)
|
||||
{
|
||||
case marker_square: do { base_type::fill_color(*fc); base_type::line_color(*lc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_diamond: do { base_type::fill_color(*fc); base_type::line_color(*lc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_crossed_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_semiellipse_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_semiellipse_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_semiellipse_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_semiellipse_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_triangle_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_triangle_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_triangle_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_triangle_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_four_rays: do { base_type::fill_color(*fc); base_type::line_color(*lc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_cross: do { base_type::fill_color(*fc); base_type::line_color(*lc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_x: do { base_type::fill_color(*fc); base_type::line_color(*lc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_dash: do { base_type::fill_color(*fc); base_type::line_color(*lc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_dot: do { base_type::fill_color(*fc); base_type::line_color(*lc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case marker_pixel: do { base_type::fill_color(*fc); base_type::line_color(*lc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
|
||||
case end_of_markers: break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,349 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class renderer_mclip
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_MCLIP_INCLUDED
|
||||
#define AGG_RENDERER_MCLIP_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_array.h"
|
||||
#include "agg_renderer_base.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//----------------------------------------------------------renderer_mclip
|
||||
template<class PixelFormat> class renderer_mclip
|
||||
{
|
||||
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)
|
||||
{
|
||||
m_ren.attach(pixf);
|
||||
reset_clipping(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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())
|
||||
{
|
||||
const rect_i& cb = m_clip[0];
|
||||
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool next_clip_box()
|
||||
{
|
||||
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 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)))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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
|
||||
{
|
||||
if(m_ren.inbox(x, y))
|
||||
{
|
||||
m_ren.ren().copy_pixel(x, y, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
if(m_ren.inbox(x, y))
|
||||
{
|
||||
m_ren.ren().blend_pixel(x, y, c, cover);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_type pixel(int x, int y) const
|
||||
{
|
||||
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_hline(int x1, int y, int x2, const color_type& c)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.copy_hline(x1, y, x2, c);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_vline(int x, int y1, int y2, const color_type& c)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.copy_vline(x, y1, y2, 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
|
||||
{
|
||||
m_ren.blend_hline(x1, y, x2, c, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y1, int y2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
first_clip_box();
|
||||
do
|
||||
{
|
||||
m_ren.blend_vline(x, y1, y2, 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
|
||||
{
|
||||
m_ren.copy_bar(x1, y1, x2, y2, c);
|
||||
}
|
||||
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
|
||||
{
|
||||
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
|
||||
}
|
||||
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
|
||||
{
|
||||
m_ren.blend_solid_hspan(x, y, len, c, covers);
|
||||
}
|
||||
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
|
||||
{
|
||||
m_ren.blend_solid_vspan(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
|
||||
{
|
||||
m_ren.copy_color_hspan(x, y, len, colors);
|
||||
}
|
||||
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
|
||||
{
|
||||
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
|
||||
}
|
||||
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
|
||||
{
|
||||
m_ren.blend_color_vspan(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
|
||||
{
|
||||
m_ren.copy_from(from, rc, x_to, y_to);
|
||||
}
|
||||
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
|
||||
{
|
||||
m_ren.blend_from(src, rect_src_ptr, dx, dy, cover);
|
||||
}
|
||||
while(next_clip_box());
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,224 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class renderer_primitives
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_PRIMITIVES_INCLUDED
|
||||
#define AGG_RENDERER_PRIMITIVES_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_renderer_base.h"
|
||||
#include "agg_dda_line.h"
|
||||
#include "agg_ellipse_bresenham.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//-----------------------------------------------------renderer_primitives
|
||||
template<class BaseRenderer> class renderer_primitives
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_RASTER_TEXT_INCLUDED
|
||||
#define AGG_RENDERER_RASTER_TEXT_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//==============================================renderer_raster_htext_solid
|
||||
template<class BaseRenderer, class GlyphGenerator>
|
||||
class renderer_raster_htext_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_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)
|
||||
{
|
||||
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_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)
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
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
|
||||
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class rendering_buffer_dynarow
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
|
||||
#define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
|
||||
|
||||
#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
|
||||
{
|
||||
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)
|
||||
{
|
||||
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
||||
}
|
||||
|
||||
// Allocate and clear the buffer
|
||||
//--------------------------------------------------------------------
|
||||
void init(unsigned width, unsigned height, unsigned byte_width)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < m_height; ++i)
|
||||
{
|
||||
pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
|
||||
}
|
||||
if(width && height)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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:
|
||||
//--------------------------------------------------------------------
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Rounded rectangle vertex generator
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_ROUNDED_RECT_INCLUDED
|
||||
#define AGG_ROUNDED_RECT_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_arc.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//------------------------------------------------------------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 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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Class scanline_bin - binary scanline.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SCANLINE_BIN_INCLUDED
|
||||
#define AGG_SCANLINE_BIN_INCLUDED
|
||||
|
||||
#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
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===========================================================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;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,816 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
|
||||
#define AGG_SCANLINE_STORAGE_AA_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <limits>
|
||||
#include "agg_array.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//----------------------------------------------scanline_cell_storage
|
||||
template<class T> class scanline_cell_storage
|
||||
{
|
||||
struct extra_span
|
||||
{
|
||||
unsigned len;
|
||||
T* ptr;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
~scanline_cell_storage()
|
||||
{
|
||||
remove_all();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
scanline_cell_storage() :
|
||||
m_cells(128-2),
|
||||
m_extra_storage()
|
||||
{}
|
||||
|
||||
|
||||
// Copying
|
||||
//---------------------------------------------------------------
|
||||
scanline_cell_storage(const scanline_cell_storage<T>& v) :
|
||||
m_cells(v.m_cells),
|
||||
m_extra_storage()
|
||||
{
|
||||
copy_extra_storage(v);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
const scanline_cell_storage<T>&
|
||||
operator = (const scanline_cell_storage<T>& v)
|
||||
{
|
||||
remove_all();
|
||||
m_cells = v.m_cells;
|
||||
copy_extra_storage(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
void remove_all()
|
||||
{
|
||||
int i;
|
||||
for(i = m_extra_storage.size()-1; i >= 0; --i)
|
||||
{
|
||||
pod_allocator<T>::deallocate(m_extra_storage[i].ptr,
|
||||
m_extra_storage[i].len);
|
||||
}
|
||||
m_extra_storage.remove_all();
|
||||
m_cells.remove_all();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
int add_cells(const T* cells, unsigned num_cells)
|
||||
{
|
||||
int idx = m_cells.allocate_continuous_block(num_cells);
|
||||
if(idx >= 0)
|
||||
{
|
||||
T* ptr = &m_cells[idx];
|
||||
memcpy(ptr, cells, sizeof(T) * num_cells);
|
||||
return idx;
|
||||
}
|
||||
extra_span s;
|
||||
s.len = num_cells;
|
||||
s.ptr = pod_allocator<T>::allocate(num_cells);
|
||||
memcpy(s.ptr, cells, sizeof(T) * num_cells);
|
||||
m_extra_storage.add(s);
|
||||
return -int(m_extra_storage.size());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
const T* operator [] (int idx) const
|
||||
{
|
||||
if(idx >= 0)
|
||||
{
|
||||
if((unsigned)idx >= m_cells.size()) return 0;
|
||||
return &m_cells[(unsigned)idx];
|
||||
}
|
||||
unsigned i = unsigned(-idx - 1);
|
||||
if(i >= m_extra_storage.size()) return 0;
|
||||
return m_extra_storage[i].ptr;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
T* operator [] (int idx)
|
||||
{
|
||||
if(idx >= 0)
|
||||
{
|
||||
if((unsigned)idx >= m_cells.size()) return 0;
|
||||
return &m_cells[(unsigned)idx];
|
||||
}
|
||||
unsigned i = unsigned(-idx - 1);
|
||||
if(i >= m_extra_storage.size()) return 0;
|
||||
return m_extra_storage[i].ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void copy_extra_storage(const scanline_cell_storage<T>& v)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < v.m_extra_storage.size(); ++i)
|
||||
{
|
||||
const extra_span& src = v.m_extra_storage[i];
|
||||
extra_span dst;
|
||||
dst.len = src.len;
|
||||
dst.ptr = pod_allocator<T>::allocate(dst.len);
|
||||
memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));
|
||||
m_extra_storage.add(dst);
|
||||
}
|
||||
}
|
||||
|
||||
pod_bvector<T, 12> m_cells;
|
||||
pod_bvector<extra_span, 6> m_extra_storage;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------scanline_storage_aa
|
||||
template<class T> class scanline_storage_aa
|
||||
{
|
||||
public:
|
||||
typedef T cover_type;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
struct span_data
|
||||
{
|
||||
int32 x;
|
||||
int32 len; // If negative, it's a solid span, covers is valid
|
||||
int covers_id; // The index of the cells in the scanline_cell_storage
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
struct scanline_data
|
||||
{
|
||||
int y;
|
||||
unsigned num_spans;
|
||||
unsigned start_span;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
class embedded_scanline
|
||||
{
|
||||
public:
|
||||
|
||||
//-----------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
struct span
|
||||
{
|
||||
int32 x;
|
||||
int32 len; // If negative, it's a solid span, covers is valid
|
||||
const T* covers;
|
||||
};
|
||||
|
||||
const_iterator() : m_storage(0) {}
|
||||
const_iterator(embedded_scanline& sl) :
|
||||
m_storage(sl.m_storage),
|
||||
m_span_idx(sl.m_scanline.start_span)
|
||||
{
|
||||
init_span();
|
||||
}
|
||||
|
||||
const span& operator*() const { return m_span; }
|
||||
const span* operator->() const { return &m_span; }
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
++m_span_idx;
|
||||
init_span();
|
||||
}
|
||||
|
||||
private:
|
||||
void init_span()
|
||||
{
|
||||
const span_data& s = m_storage->span_by_index(m_span_idx);
|
||||
m_span.x = s.x;
|
||||
m_span.len = s.len;
|
||||
m_span.covers = m_storage->covers_by_index(s.covers_id);
|
||||
}
|
||||
|
||||
scanline_storage_aa* m_storage;
|
||||
unsigned m_span_idx;
|
||||
span m_span;
|
||||
};
|
||||
|
||||
friend class const_iterator;
|
||||
|
||||
|
||||
//-----------------------------------------------------------
|
||||
embedded_scanline(const scanline_storage_aa& storage) :
|
||||
m_storage(&storage)
|
||||
{
|
||||
init(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
void reset(int, int) {}
|
||||
unsigned num_spans() const { return m_scanline.num_spans; }
|
||||
int y() const { return m_scanline.y; }
|
||||
const_iterator begin() const { return const_iterator(*this); }
|
||||
|
||||
//-----------------------------------------------------------
|
||||
void init(unsigned scanline_idx)
|
||||
{
|
||||
m_scanline_idx = scanline_idx;
|
||||
m_scanline = m_storage->scanline_by_index(m_scanline_idx);
|
||||
}
|
||||
|
||||
private:
|
||||
const scanline_storage_aa* m_storage;
|
||||
scanline_data m_scanline;
|
||||
unsigned m_scanline_idx;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
scanline_storage_aa() :
|
||||
m_covers(),
|
||||
m_spans(256-2), // Block increment size
|
||||
m_scanlines(),
|
||||
m_min_x(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min()),
|
||||
m_cur_scanline(0)
|
||||
{
|
||||
m_fake_scanline.y = 0;
|
||||
m_fake_scanline.num_spans = 0;
|
||||
m_fake_scanline.start_span = 0;
|
||||
m_fake_span.x = 0;
|
||||
m_fake_span.len = 0;
|
||||
m_fake_span.covers_id = 0;
|
||||
}
|
||||
|
||||
// Renderer Interface
|
||||
//---------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
m_covers.remove_all();
|
||||
m_scanlines.remove_all();
|
||||
m_spans.remove_all();
|
||||
m_min_x = std::numeric_limits<int>::max();
|
||||
m_min_y = std::numeric_limits<int>::max();
|
||||
m_max_x = std::numeric_limits<int>::min();
|
||||
m_max_y = std::numeric_limits<int>::min();
|
||||
m_cur_scanline = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
template<class Scanline> void render(const Scanline& sl)
|
||||
{
|
||||
scanline_data sl_this;
|
||||
|
||||
int y = sl.y();
|
||||
if(y < m_min_y) m_min_y = y;
|
||||
if(y > m_max_y) m_max_y = y;
|
||||
|
||||
sl_this.y = y;
|
||||
sl_this.num_spans = sl.num_spans();
|
||||
sl_this.start_span = m_spans.size();
|
||||
typename Scanline::const_iterator span_iterator = sl.begin();
|
||||
|
||||
unsigned num_spans = sl_this.num_spans;
|
||||
for(;;)
|
||||
{
|
||||
span_data sp;
|
||||
|
||||
sp.x = span_iterator->x;
|
||||
sp.len = span_iterator->len;
|
||||
int len = abs(int(sp.len));
|
||||
sp.covers_id =
|
||||
m_covers.add_cells(span_iterator->covers,
|
||||
unsigned(len));
|
||||
m_spans.add(sp);
|
||||
int x1 = sp.x;
|
||||
int x2 = sp.x + len - 1;
|
||||
if(x1 < m_min_x) m_min_x = x1;
|
||||
if(x2 > m_max_x) m_max_x = x2;
|
||||
if(--num_spans == 0) break;
|
||||
++span_iterator;
|
||||
}
|
||||
m_scanlines.add(sl_this);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Iterate scanlines interface
|
||||
int min_x() const { return m_min_x; }
|
||||
int min_y() const { return m_min_y; }
|
||||
int max_x() const { return m_max_x; }
|
||||
int max_y() const { return m_max_y; }
|
||||
|
||||
//---------------------------------------------------------------
|
||||
bool rewind_scanlines()
|
||||
{
|
||||
m_cur_scanline = 0;
|
||||
return m_scanlines.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
sl.reset_spans();
|
||||
for(;;)
|
||||
{
|
||||
if(m_cur_scanline >= m_scanlines.size()) return false;
|
||||
const scanline_data& sl_this = m_scanlines[m_cur_scanline];
|
||||
|
||||
unsigned num_spans = sl_this.num_spans;
|
||||
unsigned span_idx = sl_this.start_span;
|
||||
do
|
||||
{
|
||||
const span_data& sp = m_spans[span_idx++];
|
||||
const T* covers = covers_by_index(sp.covers_id);
|
||||
if(sp.len < 0)
|
||||
{
|
||||
sl.add_span(sp.x, unsigned(-sp.len), *covers);
|
||||
}
|
||||
else
|
||||
{
|
||||
sl.add_cells(sp.x, sp.len, covers);
|
||||
}
|
||||
}
|
||||
while(--num_spans);
|
||||
++m_cur_scanline;
|
||||
if(sl.num_spans())
|
||||
{
|
||||
sl.finalize(sl_this.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Specialization for embedded_scanline
|
||||
bool sweep_scanline(embedded_scanline& sl)
|
||||
{
|
||||
do
|
||||
{
|
||||
if(m_cur_scanline >= m_scanlines.size()) return false;
|
||||
sl.init(m_cur_scanline);
|
||||
++m_cur_scanline;
|
||||
}
|
||||
while(sl.num_spans() == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
unsigned byte_size() const
|
||||
{
|
||||
unsigned i;
|
||||
unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
|
||||
|
||||
for(i = 0; i < m_scanlines.size(); ++i)
|
||||
{
|
||||
size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans
|
||||
|
||||
const scanline_data& sl_this = m_scanlines[i];
|
||||
|
||||
unsigned num_spans = sl_this.num_spans;
|
||||
unsigned span_idx = sl_this.start_span;
|
||||
do
|
||||
{
|
||||
const span_data& sp = m_spans[span_idx++];
|
||||
|
||||
size += sizeof(int32) * 2; // X, span_len
|
||||
if(sp.len < 0)
|
||||
{
|
||||
size += sizeof(T); // cover
|
||||
}
|
||||
else
|
||||
{
|
||||
size += sizeof(T) * unsigned(sp.len); // covers
|
||||
}
|
||||
}
|
||||
while(--num_spans);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
static void write_int32(int8u* dst, int32 val)
|
||||
{
|
||||
dst[0] = ((const int8u*)&val)[0];
|
||||
dst[1] = ((const int8u*)&val)[1];
|
||||
dst[2] = ((const int8u*)&val)[2];
|
||||
dst[3] = ((const int8u*)&val)[3];
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
void serialize(int8u* data) const
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
write_int32(data, min_x()); // min_x
|
||||
data += sizeof(int32);
|
||||
write_int32(data, min_y()); // min_y
|
||||
data += sizeof(int32);
|
||||
write_int32(data, max_x()); // max_x
|
||||
data += sizeof(int32);
|
||||
write_int32(data, max_y()); // max_y
|
||||
data += sizeof(int32);
|
||||
|
||||
for(i = 0; i < m_scanlines.size(); ++i)
|
||||
{
|
||||
const scanline_data& sl_this = m_scanlines[i];
|
||||
|
||||
int8u* size_ptr = data;
|
||||
data += sizeof(int32); // Reserve space for scanline size in bytes
|
||||
|
||||
write_int32(data, sl_this.y); // Y
|
||||
data += sizeof(int32);
|
||||
|
||||
write_int32(data, sl_this.num_spans); // num_spans
|
||||
data += sizeof(int32);
|
||||
|
||||
unsigned num_spans = sl_this.num_spans;
|
||||
unsigned span_idx = sl_this.start_span;
|
||||
do
|
||||
{
|
||||
const span_data& sp = m_spans[span_idx++];
|
||||
const T* covers = covers_by_index(sp.covers_id);
|
||||
|
||||
write_int32(data, sp.x); // X
|
||||
data += sizeof(int32);
|
||||
|
||||
write_int32(data, sp.len); // span_len
|
||||
data += sizeof(int32);
|
||||
|
||||
if(sp.len < 0)
|
||||
{
|
||||
memcpy(data, covers, sizeof(T));
|
||||
data += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data, covers, unsigned(sp.len) * sizeof(T));
|
||||
data += sizeof(T) * unsigned(sp.len);
|
||||
}
|
||||
}
|
||||
while(--num_spans);
|
||||
write_int32(size_ptr, int32(unsigned(data - size_ptr)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
const scanline_data& scanline_by_index(unsigned i) const
|
||||
{
|
||||
return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
const span_data& span_by_index(unsigned i) const
|
||||
{
|
||||
return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
const T* covers_by_index(int i) const
|
||||
{
|
||||
return m_covers[i];
|
||||
}
|
||||
|
||||
private:
|
||||
scanline_cell_storage<T> m_covers;
|
||||
pod_bvector<span_data, 10> m_spans;
|
||||
pod_bvector<scanline_data, 8> m_scanlines;
|
||||
span_data m_fake_span;
|
||||
scanline_data m_fake_scanline;
|
||||
int m_min_x;
|
||||
int m_min_y;
|
||||
int m_max_x;
|
||||
int m_max_y;
|
||||
unsigned m_cur_scanline;
|
||||
};
|
||||
|
||||
|
||||
typedef scanline_storage_aa<int8u> scanline_storage_aa8; //--------scanline_storage_aa8
|
||||
typedef scanline_storage_aa<int16u> scanline_storage_aa16; //--------scanline_storage_aa16
|
||||
typedef scanline_storage_aa<int32u> scanline_storage_aa32; //--------scanline_storage_aa32
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------serialized_scanlines_adaptor_aa
|
||||
template<class T> class serialized_scanlines_adaptor_aa
|
||||
{
|
||||
public:
|
||||
typedef T cover_type;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
class embedded_scanline
|
||||
{
|
||||
public:
|
||||
typedef T cover_type;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
struct span
|
||||
{
|
||||
int32 x;
|
||||
int32 len; // If negative, it's a solid span, "covers" is valid
|
||||
const T* covers;
|
||||
};
|
||||
|
||||
const_iterator() : m_ptr(0) {}
|
||||
const_iterator(const embedded_scanline* sl) :
|
||||
m_ptr(sl->m_ptr),
|
||||
m_dx(sl->m_dx)
|
||||
{
|
||||
init_span();
|
||||
}
|
||||
|
||||
const span& operator*() const { return m_span; }
|
||||
const span* operator->() const { return &m_span; }
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
if(m_span.len < 0)
|
||||
{
|
||||
m_ptr += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ptr += m_span.len * sizeof(T);
|
||||
}
|
||||
init_span();
|
||||
}
|
||||
|
||||
private:
|
||||
int read_int32()
|
||||
{
|
||||
int32 val;
|
||||
((int8u*)&val)[0] = *m_ptr++;
|
||||
((int8u*)&val)[1] = *m_ptr++;
|
||||
((int8u*)&val)[2] = *m_ptr++;
|
||||
((int8u*)&val)[3] = *m_ptr++;
|
||||
return val;
|
||||
}
|
||||
|
||||
void init_span()
|
||||
{
|
||||
m_span.x = read_int32() + m_dx;
|
||||
m_span.len = read_int32();
|
||||
m_span.covers = m_ptr;
|
||||
}
|
||||
|
||||
const int8u* m_ptr;
|
||||
span m_span;
|
||||
int m_dx;
|
||||
};
|
||||
|
||||
friend class const_iterator;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
void reset(int, int) {}
|
||||
unsigned num_spans() const { return m_num_spans; }
|
||||
int y() const { return m_y; }
|
||||
const_iterator begin() const { return const_iterator(this); }
|
||||
|
||||
|
||||
private:
|
||||
//-----------------------------------------------------------------
|
||||
int read_int32()
|
||||
{
|
||||
int32 val;
|
||||
((int8u*)&val)[0] = *m_ptr++;
|
||||
((int8u*)&val)[1] = *m_ptr++;
|
||||
((int8u*)&val)[2] = *m_ptr++;
|
||||
((int8u*)&val)[3] = *m_ptr++;
|
||||
return val;
|
||||
}
|
||||
|
||||
public:
|
||||
//-----------------------------------------------------------------
|
||||
void init(const int8u* ptr, int dx, int dy)
|
||||
{
|
||||
m_ptr = ptr;
|
||||
m_y = read_int32() + dy;
|
||||
m_num_spans = unsigned(read_int32());
|
||||
m_dx = dx;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_ptr;
|
||||
int m_y;
|
||||
unsigned m_num_spans;
|
||||
int m_dx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
serialized_scanlines_adaptor_aa() :
|
||||
m_data(0),
|
||||
m_end(0),
|
||||
m_ptr(0),
|
||||
m_dx(0),
|
||||
m_dy(0),
|
||||
m_min_x(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min())
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
serialized_scanlines_adaptor_aa(const int8u* data, unsigned size,
|
||||
double dx, double dy) :
|
||||
m_data(data),
|
||||
m_end(data + size),
|
||||
m_ptr(data),
|
||||
m_dx(iround(dx)),
|
||||
m_dy(iround(dy)),
|
||||
m_min_x(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min())
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(const int8u* data, unsigned size, double dx, double dy)
|
||||
{
|
||||
m_data = data;
|
||||
m_end = data + size;
|
||||
m_ptr = data;
|
||||
m_dx = iround(dx);
|
||||
m_dy = iround(dy);
|
||||
m_min_x = std::numeric_limits<int>::max();
|
||||
m_min_y = std::numeric_limits<int>::max();
|
||||
m_max_x = std::numeric_limits<int>::min();
|
||||
m_max_y = std::numeric_limits<int>::min();
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
int read_int32()
|
||||
{
|
||||
int32 val;
|
||||
((int8u*)&val)[0] = *m_ptr++;
|
||||
((int8u*)&val)[1] = *m_ptr++;
|
||||
((int8u*)&val)[2] = *m_ptr++;
|
||||
((int8u*)&val)[3] = *m_ptr++;
|
||||
return val;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned read_int32u()
|
||||
{
|
||||
int32u val;
|
||||
((int8u*)&val)[0] = *m_ptr++;
|
||||
((int8u*)&val)[1] = *m_ptr++;
|
||||
((int8u*)&val)[2] = *m_ptr++;
|
||||
((int8u*)&val)[3] = *m_ptr++;
|
||||
return val;
|
||||
}
|
||||
|
||||
public:
|
||||
// Iterate scanlines interface
|
||||
//--------------------------------------------------------------------
|
||||
bool rewind_scanlines()
|
||||
{
|
||||
m_ptr = m_data;
|
||||
if(m_ptr < m_end)
|
||||
{
|
||||
m_min_x = read_int32() + m_dx;
|
||||
m_min_y = read_int32() + m_dy;
|
||||
m_max_x = read_int32() + m_dx;
|
||||
m_max_y = read_int32() + m_dy;
|
||||
}
|
||||
return m_ptr < m_end;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int min_x() const { return m_min_x; }
|
||||
int min_y() const { return m_min_y; }
|
||||
int max_x() const { return m_max_x; }
|
||||
int max_y() const { return m_max_y; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
sl.reset_spans();
|
||||
for(;;)
|
||||
{
|
||||
if(m_ptr >= m_end) return false;
|
||||
|
||||
read_int32(); // Skip scanline size in bytes
|
||||
int y = read_int32() + m_dy;
|
||||
unsigned num_spans = read_int32();
|
||||
|
||||
do
|
||||
{
|
||||
int x = read_int32() + m_dx;
|
||||
int len = read_int32();
|
||||
|
||||
if(len < 0)
|
||||
{
|
||||
sl.add_span(x, unsigned(-len), *m_ptr);
|
||||
m_ptr += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
sl.add_cells(x, len, m_ptr);
|
||||
m_ptr += len * sizeof(T);
|
||||
}
|
||||
}
|
||||
while(--num_spans);
|
||||
|
||||
if(sl.num_spans())
|
||||
{
|
||||
sl.finalize(y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Specialization for embedded_scanline
|
||||
bool sweep_scanline(embedded_scanline& sl)
|
||||
{
|
||||
do
|
||||
{
|
||||
if(m_ptr >= m_end) return false;
|
||||
|
||||
unsigned byte_size = read_int32u();
|
||||
sl.init(m_ptr, m_dx, m_dy);
|
||||
m_ptr += byte_size - sizeof(int32);
|
||||
}
|
||||
while(sl.num_spans() == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_data;
|
||||
const int8u* m_end;
|
||||
const int8u* m_ptr;
|
||||
int m_dx;
|
||||
int m_dy;
|
||||
int m_min_x;
|
||||
int m_min_y;
|
||||
int m_max_x;
|
||||
int m_max_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef serialized_scanlines_adaptor_aa<int8u> serialized_scanlines_adaptor_aa8; //----serialized_scanlines_adaptor_aa8
|
||||
typedef serialized_scanlines_adaptor_aa<int16u> serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16
|
||||
typedef serialized_scanlines_adaptor_aa<int32u> serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,587 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
|
||||
#define AGG_SCANLINE_STORAGE_BIN_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <limits>
|
||||
#include "agg_array.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------scanline_storage_bin
|
||||
class scanline_storage_bin
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------
|
||||
struct span_data
|
||||
{
|
||||
int32 x;
|
||||
int32 len;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
struct scanline_data
|
||||
{
|
||||
int y;
|
||||
unsigned num_spans;
|
||||
unsigned start_span;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
class embedded_scanline
|
||||
{
|
||||
public:
|
||||
|
||||
//-----------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator() : m_storage(0) {}
|
||||
const_iterator(const embedded_scanline* sl) :
|
||||
m_storage(sl->m_storage),
|
||||
m_span_idx(sl->m_scanline.start_span)
|
||||
{
|
||||
m_span = m_storage->span_by_index(m_span_idx);
|
||||
}
|
||||
|
||||
const span_data& operator*() const { return m_span; }
|
||||
const span_data* operator->() const { return &m_span; }
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
++m_span_idx;
|
||||
m_span = m_storage->span_by_index(m_span_idx);
|
||||
}
|
||||
|
||||
private:
|
||||
const scanline_storage_bin* m_storage;
|
||||
unsigned m_span_idx;
|
||||
span_data m_span;
|
||||
};
|
||||
|
||||
friend class const_iterator;
|
||||
|
||||
|
||||
//-----------------------------------------------------------
|
||||
embedded_scanline(scanline_storage_bin& storage) :
|
||||
m_storage(&storage)
|
||||
{
|
||||
setup(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
void reset(int, int) {}
|
||||
unsigned num_spans() const { return m_scanline.num_spans; }
|
||||
int y() const { return m_scanline.y; }
|
||||
const_iterator begin() const { return const_iterator(this); }
|
||||
|
||||
//-----------------------------------------------------------
|
||||
void setup(unsigned scanline_idx)
|
||||
{
|
||||
m_scanline_idx = scanline_idx;
|
||||
m_scanline = m_storage->scanline_by_index(m_scanline_idx);
|
||||
}
|
||||
|
||||
private:
|
||||
scanline_storage_bin* m_storage;
|
||||
scanline_data m_scanline;
|
||||
unsigned m_scanline_idx;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
scanline_storage_bin() :
|
||||
m_spans(256-2), // Block increment size
|
||||
m_scanlines(),
|
||||
m_min_x(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min()),
|
||||
m_cur_scanline(0)
|
||||
{
|
||||
m_fake_scanline.y = 0;
|
||||
m_fake_scanline.num_spans = 0;
|
||||
m_fake_scanline.start_span = 0;
|
||||
m_fake_span.x = 0;
|
||||
m_fake_span.len = 0;
|
||||
}
|
||||
|
||||
// Renderer Interface
|
||||
//---------------------------------------------------------------
|
||||
void prepare()
|
||||
{
|
||||
m_scanlines.remove_all();
|
||||
m_spans.remove_all();
|
||||
m_min_x = std::numeric_limits<int>::max();
|
||||
m_min_y = std::numeric_limits<int>::max();
|
||||
m_max_x = std::numeric_limits<int>::min();
|
||||
m_max_y = std::numeric_limits<int>::min();
|
||||
m_cur_scanline = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
template<class Scanline> void render(const Scanline& sl)
|
||||
{
|
||||
scanline_data sl_this;
|
||||
|
||||
int y = sl.y();
|
||||
if(y < m_min_y) m_min_y = y;
|
||||
if(y > m_max_y) m_max_y = y;
|
||||
|
||||
sl_this.y = y;
|
||||
sl_this.num_spans = sl.num_spans();
|
||||
sl_this.start_span = m_spans.size();
|
||||
typename Scanline::const_iterator span_iterator = sl.begin();
|
||||
|
||||
unsigned num_spans = sl_this.num_spans;
|
||||
for(;;)
|
||||
{
|
||||
span_data sp;
|
||||
sp.x = span_iterator->x;
|
||||
sp.len = (int32)abs((int)(span_iterator->len));
|
||||
m_spans.add(sp);
|
||||
int x1 = sp.x;
|
||||
int x2 = sp.x + sp.len - 1;
|
||||
if(x1 < m_min_x) m_min_x = x1;
|
||||
if(x2 > m_max_x) m_max_x = x2;
|
||||
if(--num_spans == 0) break;
|
||||
++span_iterator;
|
||||
}
|
||||
m_scanlines.add(sl_this);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Iterate scanlines interface
|
||||
int min_x() const { return m_min_x; }
|
||||
int min_y() const { return m_min_y; }
|
||||
int max_x() const { return m_max_x; }
|
||||
int max_y() const { return m_max_y; }
|
||||
|
||||
//---------------------------------------------------------------
|
||||
bool rewind_scanlines()
|
||||
{
|
||||
m_cur_scanline = 0;
|
||||
return m_scanlines.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
sl.reset_spans();
|
||||
for(;;)
|
||||
{
|
||||
if(m_cur_scanline >= m_scanlines.size()) return false;
|
||||
const scanline_data& sl_this = m_scanlines[m_cur_scanline];
|
||||
|
||||
unsigned num_spans = sl_this.num_spans;
|
||||
unsigned span_idx = sl_this.start_span;
|
||||
do
|
||||
{
|
||||
const span_data& sp = m_spans[span_idx++];
|
||||
sl.add_span(sp.x, sp.len, cover_full);
|
||||
}
|
||||
while(--num_spans);
|
||||
|
||||
++m_cur_scanline;
|
||||
if(sl.num_spans())
|
||||
{
|
||||
sl.finalize(sl_this.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Specialization for embedded_scanline
|
||||
bool sweep_scanline(embedded_scanline& sl)
|
||||
{
|
||||
do
|
||||
{
|
||||
if(m_cur_scanline >= m_scanlines.size()) return false;
|
||||
sl.setup(m_cur_scanline);
|
||||
++m_cur_scanline;
|
||||
}
|
||||
while(sl.num_spans() == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
unsigned byte_size() const
|
||||
{
|
||||
unsigned i;
|
||||
unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
|
||||
|
||||
for(i = 0; i < m_scanlines.size(); ++i)
|
||||
{
|
||||
size += sizeof(int32) * 2 + // Y, num_spans
|
||||
unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
static void write_int32(int8u* dst, int32 val)
|
||||
{
|
||||
dst[0] = ((const int8u*)&val)[0];
|
||||
dst[1] = ((const int8u*)&val)[1];
|
||||
dst[2] = ((const int8u*)&val)[2];
|
||||
dst[3] = ((const int8u*)&val)[3];
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
void serialize(int8u* data) const
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
write_int32(data, min_x()); // min_x
|
||||
data += sizeof(int32);
|
||||
write_int32(data, min_y()); // min_y
|
||||
data += sizeof(int32);
|
||||
write_int32(data, max_x()); // max_x
|
||||
data += sizeof(int32);
|
||||
write_int32(data, max_y()); // max_y
|
||||
data += sizeof(int32);
|
||||
|
||||
for(i = 0; i < m_scanlines.size(); ++i)
|
||||
{
|
||||
const scanline_data& sl_this = m_scanlines[i];
|
||||
|
||||
write_int32(data, sl_this.y); // Y
|
||||
data += sizeof(int32);
|
||||
|
||||
write_int32(data, sl_this.num_spans); // num_spans
|
||||
data += sizeof(int32);
|
||||
|
||||
unsigned num_spans = sl_this.num_spans;
|
||||
unsigned span_idx = sl_this.start_span;
|
||||
do
|
||||
{
|
||||
const span_data& sp = m_spans[span_idx++];
|
||||
|
||||
write_int32(data, sp.x); // X
|
||||
data += sizeof(int32);
|
||||
|
||||
write_int32(data, sp.len); // len
|
||||
data += sizeof(int32);
|
||||
}
|
||||
while(--num_spans);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
const scanline_data& scanline_by_index(unsigned i) const
|
||||
{
|
||||
return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
const span_data& span_by_index(unsigned i) const
|
||||
{
|
||||
return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
pod_bvector<span_data, 10> m_spans;
|
||||
pod_bvector<scanline_data, 8> m_scanlines;
|
||||
span_data m_fake_span;
|
||||
scanline_data m_fake_scanline;
|
||||
int m_min_x;
|
||||
int m_min_y;
|
||||
int m_max_x;
|
||||
int m_max_y;
|
||||
unsigned m_cur_scanline;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------serialized_scanlines_adaptor_bin
|
||||
class serialized_scanlines_adaptor_bin
|
||||
{
|
||||
public:
|
||||
typedef bool cover_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class embedded_scanline
|
||||
{
|
||||
public:
|
||||
|
||||
//----------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
struct span
|
||||
{
|
||||
int32 x;
|
||||
int32 len;
|
||||
};
|
||||
|
||||
const_iterator() : m_ptr(0) {}
|
||||
const_iterator(const embedded_scanline* sl) :
|
||||
m_ptr(sl->m_ptr),
|
||||
m_dx(sl->m_dx)
|
||||
{
|
||||
m_span.x = read_int32() + m_dx;
|
||||
m_span.len = read_int32();
|
||||
}
|
||||
|
||||
const span& operator*() const { return m_span; }
|
||||
const span* operator->() const { return &m_span; }
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
m_span.x = read_int32() + m_dx;
|
||||
m_span.len = read_int32();
|
||||
}
|
||||
|
||||
private:
|
||||
int read_int32()
|
||||
{
|
||||
int32 val;
|
||||
((int8u*)&val)[0] = *m_ptr++;
|
||||
((int8u*)&val)[1] = *m_ptr++;
|
||||
((int8u*)&val)[2] = *m_ptr++;
|
||||
((int8u*)&val)[3] = *m_ptr++;
|
||||
return val;
|
||||
}
|
||||
|
||||
const int8u* m_ptr;
|
||||
span m_span;
|
||||
int m_dx;
|
||||
};
|
||||
|
||||
friend class const_iterator;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void reset(int, int) {}
|
||||
unsigned num_spans() const { return m_num_spans; }
|
||||
int y() const { return m_y; }
|
||||
const_iterator begin() const { return const_iterator(this); }
|
||||
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------
|
||||
int read_int32()
|
||||
{
|
||||
int32 val;
|
||||
((int8u*)&val)[0] = *m_ptr++;
|
||||
((int8u*)&val)[1] = *m_ptr++;
|
||||
((int8u*)&val)[2] = *m_ptr++;
|
||||
((int8u*)&val)[3] = *m_ptr++;
|
||||
return val;
|
||||
}
|
||||
|
||||
public:
|
||||
//----------------------------------------------------------------
|
||||
void init(const int8u* ptr, int dx, int dy)
|
||||
{
|
||||
m_ptr = ptr;
|
||||
m_y = read_int32() + dy;
|
||||
m_num_spans = unsigned(read_int32());
|
||||
m_dx = dx;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_ptr;
|
||||
int m_y;
|
||||
unsigned m_num_spans;
|
||||
int m_dx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
serialized_scanlines_adaptor_bin() :
|
||||
m_data(0),
|
||||
m_end(0),
|
||||
m_ptr(0),
|
||||
m_dx(0),
|
||||
m_dy(0),
|
||||
m_min_x(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min())
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
serialized_scanlines_adaptor_bin(const int8u* data, unsigned size,
|
||||
double dx, double dy) :
|
||||
m_data(data),
|
||||
m_end(data + size),
|
||||
m_ptr(data),
|
||||
m_dx(iround(dx)),
|
||||
m_dy(iround(dy)),
|
||||
m_min_x(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min())
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(const int8u* data, unsigned size, double dx, double dy)
|
||||
{
|
||||
m_data = data;
|
||||
m_end = data + size;
|
||||
m_ptr = data;
|
||||
m_dx = iround(dx);
|
||||
m_dy = iround(dy);
|
||||
m_min_x = std::numeric_limits<int>::max();
|
||||
m_min_y = std::numeric_limits<int>::max();
|
||||
m_max_x = std::numeric_limits<int>::min();
|
||||
m_max_y = std::numeric_limits<int>::min();
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
int read_int32()
|
||||
{
|
||||
int32 val;
|
||||
((int8u*)&val)[0] = *m_ptr++;
|
||||
((int8u*)&val)[1] = *m_ptr++;
|
||||
((int8u*)&val)[2] = *m_ptr++;
|
||||
((int8u*)&val)[3] = *m_ptr++;
|
||||
return val;
|
||||
}
|
||||
|
||||
public:
|
||||
// Iterate scanlines interface
|
||||
//--------------------------------------------------------------------
|
||||
bool rewind_scanlines()
|
||||
{
|
||||
m_ptr = m_data;
|
||||
if(m_ptr < m_end)
|
||||
{
|
||||
m_min_x = read_int32() + m_dx;
|
||||
m_min_y = read_int32() + m_dy;
|
||||
m_max_x = read_int32() + m_dx;
|
||||
m_max_y = read_int32() + m_dy;
|
||||
}
|
||||
return m_ptr < m_end;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int min_x() const { return m_min_x; }
|
||||
int min_y() const { return m_min_y; }
|
||||
int max_x() const { return m_max_x; }
|
||||
int max_y() const { return m_max_y; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class Scanline> bool sweep_scanline(Scanline& sl)
|
||||
{
|
||||
sl.reset_spans();
|
||||
for(;;)
|
||||
{
|
||||
if(m_ptr >= m_end) return false;
|
||||
|
||||
int y = read_int32() + m_dy;
|
||||
unsigned num_spans = read_int32();
|
||||
|
||||
do
|
||||
{
|
||||
int x = read_int32() + m_dx;
|
||||
int len = read_int32();
|
||||
|
||||
if(len < 0) len = -len;
|
||||
sl.add_span(x, unsigned(len), cover_full);
|
||||
}
|
||||
while(--num_spans);
|
||||
|
||||
if(sl.num_spans())
|
||||
{
|
||||
sl.finalize(y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Specialization for embedded_scanline
|
||||
bool sweep_scanline(embedded_scanline& sl)
|
||||
{
|
||||
do
|
||||
{
|
||||
if(m_ptr >= m_end) return false;
|
||||
|
||||
sl.init(m_ptr, m_dx, m_dy);
|
||||
|
||||
// Jump to the next scanline
|
||||
//--------------------------
|
||||
read_int32(); // Y
|
||||
int num_spans = read_int32(); // num_spans
|
||||
m_ptr += num_spans * sizeof(int32) * 2;
|
||||
}
|
||||
while(sl.num_spans() == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const int8u* m_data;
|
||||
const int8u* m_end;
|
||||
const int8u* m_ptr;
|
||||
int m_dx;
|
||||
int m_dy;
|
||||
int m_min_x;
|
||||
int m_min_y;
|
||||
int m_max_x;
|
||||
int m_max_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,499 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SCANLINE_U_INCLUDED
|
||||
#define AGG_SCANLINE_U_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//=============================================================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
|
||||
{
|
||||
public:
|
||||
typedef scanline_u8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int16 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
coord_type x;
|
||||
coord_type len;
|
||||
cover_type* covers;
|
||||
};
|
||||
|
||||
typedef span* iterator;
|
||||
typedef const span* const_iterator;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline_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())
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
x -= m_min_x;
|
||||
m_covers[x] = (cover_type)cover;
|
||||
if(x == m_last_x+1)
|
||||
{
|
||||
m_cur_span->len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->x = (coord_type)(x + m_min_x);
|
||||
m_cur_span->len = 1;
|
||||
m_cur_span->covers = &m_covers[x];
|
||||
}
|
||||
m_last_x = x;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const 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(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:
|
||||
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(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:
|
||||
AlphaMask* m_alpha_mask;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SHORTEN_PATH_INCLUDED
|
||||
#define AGG_SHORTEN_PATH_INCLUDED
|
||||
|
||||
#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)
|
||||
{
|
||||
typedef typename VertexSequence::value_type vertex_type;
|
||||
|
||||
if(s > 0.0 && vs.size() > 1)
|
||||
{
|
||||
double d;
|
||||
int n = int(vs.size() - 2);
|
||||
while(n)
|
||||
{
|
||||
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)) vs.remove_last();
|
||||
vs.close(closed != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Solving simultaneous equations
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SIMUL_EQ_INCLUDED
|
||||
#define AGG_SIMUL_EQ_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=============================================================swap_arrays
|
||||
template<class T> void swap_arrays(T* a1, T* a2, unsigned n)
|
||||
{
|
||||
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 = 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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_ALLOCATOR_INCLUDED
|
||||
#define AGG_SPAN_ALLOCATOR_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//----------------------------------------------------------span_allocator
|
||||
template<class ColorT> class span_allocator
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE color_type* allocate(unsigned span_len)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_CONVERTER_INCLUDED
|
||||
#define AGG_SPAN_CONVERTER_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//----------------------------------------------------------span_converter
|
||||
template<class SpanGenerator, class SpanConverter> class span_converter
|
||||
{
|
||||
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()
|
||||
{
|
||||
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
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_GOURAUD_INCLUDED
|
||||
#define AGG_SPAN_GOURAUD_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_math.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//============================================================span_gouraud
|
||||
template<class ColorT> class span_gouraud
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_GOURAUD_GRAY_INCLUDED
|
||||
#define AGG_SPAN_GOURAUD_GRAY_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_color_gray.h"
|
||||
#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>
|
||||
{
|
||||
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
|
||||
{
|
||||
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 = (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 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 = 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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_GOURAUD_RGBA_INCLUDED
|
||||
#define AGG_SPAN_GOURAUD_RGBA_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_color_rgba.h"
|
||||
#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>
|
||||
{
|
||||
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
|
||||
{
|
||||
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 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 = 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,377 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_GRADIENT_INCLUDED
|
||||
#define AGG_SPAN_GRADIENT_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "agg_basics.h"
|
||||
#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
|
||||
{
|
||||
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,
|
||||
GradientF& gradient_function,
|
||||
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(GradientF& gf) { m_gradient_function = &gf; }
|
||||
void color_function(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)
|
||||
{
|
||||
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_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;
|
||||
GradientF* m_gradient_function;
|
||||
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)
|
||||
// VFALCO 4/28/09
|
||||
,m_mult(1/(double(size)-1))
|
||||
// VFALCO
|
||||
{}
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
color_type operator [] (unsigned v) const
|
||||
{
|
||||
// VFALCO 4/28/09
|
||||
//return m_c1.gradient(m_c2, double(v) / double(m_size - 1));
|
||||
return m_c1.gradient(m_c2, double(v) * m_mult );
|
||||
// VFALCO
|
||||
}
|
||||
|
||||
void colors(const color_type& c1, const color_type& c2, unsigned size = 256)
|
||||
{
|
||||
m_c1 = c1;
|
||||
m_c2 = c2;
|
||||
m_size = size;
|
||||
// VFALCO 4/28/09
|
||||
m_mult=1/(double(size)-1);
|
||||
// VFALCO
|
||||
}
|
||||
|
||||
color_type m_c1;
|
||||
color_type m_c2;
|
||||
unsigned m_size;
|
||||
// VFALCO 4/28/09
|
||||
double m_mult;
|
||||
// VFALCO
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================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(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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int ax = abs(x);
|
||||
int ay = abs(y);
|
||||
return ax > ay ? ax : ay;
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================gradient_xy
|
||||
class gradient_xy
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int d)
|
||||
{
|
||||
return abs(x) * abs(y) / d;
|
||||
}
|
||||
};
|
||||
|
||||
//========================================================gradient_sqrt_xy
|
||||
class gradient_sqrt_xy
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int)
|
||||
{
|
||||
return fast_sqrt(abs(x) * abs(y));
|
||||
}
|
||||
};
|
||||
|
||||
//==========================================================gradient_conic
|
||||
class gradient_conic
|
||||
{
|
||||
public:
|
||||
static AGG_INLINE int calculate(int x, int y, int d)
|
||||
{
|
||||
return uround(fabs(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
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_GRADIENT_ALPHA_INCLUDED
|
||||
#define AGG_SPAN_GRADIENT_ALPHA_INCLUDED
|
||||
|
||||
#include "agg_span_gradient.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//======================================================span_gradient_alpha
|
||||
template<class ColorT,
|
||||
class Interpolator,
|
||||
class GradientF,
|
||||
class AlphaF>
|
||||
class span_gradient_alpha
|
||||
{
|
||||
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,
|
||||
GradientF& gradient_function,
|
||||
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)
|
||||
{
|
||||
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;
|
||||
GradientF* m_gradient_function;
|
||||
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
|
||||
|
|
@ -1,362 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// AGG Contribution Pack - Gradients 1 (AGG CP - Gradients 1)
|
||||
// http://milan.marusinec.sk/aggcp
|
||||
//
|
||||
// For Anti-Grain Geometry - Version 2.4
|
||||
// http://www.antigrain.org
|
||||
//
|
||||
// Contribution Created By:
|
||||
// Milan Marusinec alias Milano
|
||||
// milan@marusinec.sk
|
||||
// Copyright (c) 2007-2008
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// [History] -----------------------------------------------------------------
|
||||
//
|
||||
// 02.02.2008-Milano: Ported from Object Pascal code of AggPas
|
||||
//
|
||||
#ifndef AGG_SPAN_GRADIENT_CONTOUR_INCLUDED
|
||||
#define AGG_SPAN_GRADIENT_CONTOUR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_trans_affine.h"
|
||||
#include "agg_path_storage.h"
|
||||
#include "agg_pixfmt_gray.h"
|
||||
#include "agg_conv_transform.h"
|
||||
#include "agg_conv_curve.h"
|
||||
#include "agg_bounding_rect.h"
|
||||
#include "agg_renderer_base.h"
|
||||
#include "agg_renderer_primitives.h"
|
||||
#include "agg_rasterizer_outline.h"
|
||||
#include "agg_span_gradient.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//==========================================================gradient_contour
|
||||
class gradient_contour
|
||||
{
|
||||
private:
|
||||
int8u* m_buffer;
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_frame;
|
||||
|
||||
double m_d1;
|
||||
double m_d2;
|
||||
|
||||
public:
|
||||
gradient_contour() :
|
||||
m_buffer(NULL),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_frame(10),
|
||||
m_d1(0),
|
||||
m_d2(100)
|
||||
{
|
||||
}
|
||||
|
||||
gradient_contour(double d1, double d2) :
|
||||
m_buffer(NULL),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_frame(10),
|
||||
m_d1(d1),
|
||||
m_d2(d2)
|
||||
{
|
||||
}
|
||||
|
||||
~gradient_contour()
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
delete [] m_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
int8u* contour_create(path_storage* ps );
|
||||
|
||||
int contour_width() { return m_width; }
|
||||
int contour_height() { return m_height; }
|
||||
|
||||
void d1(double d ) { m_d1 = d; }
|
||||
void d2(double d ) { m_d2 = d; }
|
||||
|
||||
void frame(int f ) { m_frame = f; }
|
||||
int frame() { return m_frame; }
|
||||
|
||||
int calculate(int x, int y, int d) const
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
int px = x >> agg::gradient_subpixel_shift;
|
||||
int py = y >> agg::gradient_subpixel_shift;
|
||||
|
||||
px %= m_width;
|
||||
|
||||
if (px < 0)
|
||||
{
|
||||
px += m_width;
|
||||
}
|
||||
|
||||
py %= m_height;
|
||||
|
||||
if (py < 0 )
|
||||
{
|
||||
py += m_height;
|
||||
}
|
||||
|
||||
return iround(m_buffer[py * m_width + px ] * (m_d2 / 256 ) + m_d1 ) << gradient_subpixel_shift;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static AGG_INLINE int square(int x ) { return x * x; }
|
||||
|
||||
// DT algorithm by: Pedro Felzenszwalb
|
||||
void dt(float* spanf, float* spang, float* spanr, int* spann ,int length )
|
||||
{
|
||||
int k = 0;
|
||||
float s;
|
||||
|
||||
spann[0 ] = 0;
|
||||
spang[0 ] = -FLT_MAX;
|
||||
spang[1 ] = FLT_MAX;
|
||||
|
||||
for (int q = 1; q <= length - 1; q++)
|
||||
{
|
||||
s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] );
|
||||
|
||||
while (s <= spang[k ])
|
||||
{
|
||||
k--;
|
||||
s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] );
|
||||
}
|
||||
|
||||
k++;
|
||||
spann[k ] = q;
|
||||
spang[k ] = s;
|
||||
spang[k + 1 ] = FLT_MAX;
|
||||
|
||||
}
|
||||
|
||||
k = 0;
|
||||
|
||||
for (int q = 0; q <= length - 1; q++)
|
||||
{
|
||||
while (spang[k + 1 ] < q )
|
||||
{
|
||||
k++;
|
||||
}
|
||||
|
||||
spanr[q ] = square(q - spann[k ] ) + spanf[spann[k ] ];
|
||||
}
|
||||
}
|
||||
|
||||
// DT algorithm by: Pedro Felzenszwalb
|
||||
int8u* gradient_contour::contour_create(path_storage* ps )
|
||||
{
|
||||
int8u* result = NULL;
|
||||
|
||||
if (ps)
|
||||
{
|
||||
// I. Render Black And White NonAA Stroke of the Path
|
||||
// Path Bounding Box + Some Frame Space Around [configurable]
|
||||
agg::conv_curve<agg::path_storage> conv(*ps);
|
||||
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
if (agg::bounding_rect_single(conv ,0 ,&x1 ,&y1 ,&x2 ,&y2 ))
|
||||
{
|
||||
// Create BW Rendering Surface
|
||||
int width = int(ceil(x2 - x1 ) ) + m_frame * 2 + 1;
|
||||
int height = int(ceil(y2 - y1 ) ) + m_frame * 2 + 1;
|
||||
|
||||
int8u* buffer = new int8u[width * height];
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
memset(buffer ,255 ,width * height );
|
||||
|
||||
// Setup VG Engine & Render
|
||||
agg::rendering_buffer rb;
|
||||
rb.attach(buffer ,width ,height ,width );
|
||||
|
||||
agg::pixfmt_gray8 pf(rb);
|
||||
agg::renderer_base<agg::pixfmt_gray8> renb(pf );
|
||||
|
||||
agg::renderer_primitives<agg::renderer_base<agg::pixfmt_gray8> > prim(renb );
|
||||
agg::rasterizer_outline<renderer_primitives<agg::renderer_base<agg::pixfmt_gray8> > > ras(prim );
|
||||
|
||||
agg::trans_affine mtx;
|
||||
mtx *= agg::trans_affine_translation(-x1 + m_frame, -y1 + m_frame );
|
||||
|
||||
agg::conv_transform<agg::conv_curve<agg::path_storage> > trans(conv ,mtx );
|
||||
|
||||
prim.line_color(agg::rgba8(0 ,0 ,0 ,255 ) );
|
||||
ras.add_path(trans );
|
||||
|
||||
// II. Distance Transform
|
||||
// Create Float Buffer + 0 vs infinity assignment
|
||||
float* image = new float[width * height];
|
||||
|
||||
if (image)
|
||||
{
|
||||
for (int y = 0, l = 0; y < height; y++ )
|
||||
{
|
||||
for (int x = 0; x < width; x++, l++ )
|
||||
{
|
||||
if (buffer[l ] == 0)
|
||||
{
|
||||
image[l ] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
image[l ] = FLT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// DT of 2d
|
||||
// SubBuff<float> max width,height
|
||||
int length = width;
|
||||
|
||||
if (height > length)
|
||||
{
|
||||
length = height;
|
||||
}
|
||||
|
||||
float* spanf = new float[length];
|
||||
float* spang = new float[length + 1];
|
||||
float* spanr = new float[length];
|
||||
int* spann = new int[length];
|
||||
|
||||
if ((spanf) && (spang) && (spanr) && (spann))
|
||||
{
|
||||
// Transform along columns
|
||||
for (int x = 0; x < width; x++ )
|
||||
{
|
||||
for (int y = 0; y < height; y++ )
|
||||
{
|
||||
spanf[y] = image[y * width + x];
|
||||
}
|
||||
|
||||
// DT of 1d
|
||||
dt(spanf ,spang ,spanr ,spann ,height );
|
||||
|
||||
for (int y = 0; y < height; y++ )
|
||||
{
|
||||
image[y * width + x] = spanr[y];
|
||||
}
|
||||
}
|
||||
|
||||
// Transform along rows
|
||||
for (int y = 0; y < height; y++ )
|
||||
{
|
||||
for (int x = 0; x < width; x++ )
|
||||
{
|
||||
spanf[x] = image[y * width + x];
|
||||
}
|
||||
|
||||
// DT of 1d
|
||||
dt(spanf ,spang ,spanr ,spann ,width );
|
||||
|
||||
for (int x = 0; x < width; x++ )
|
||||
{
|
||||
image[y * width + x] = spanr[x];
|
||||
}
|
||||
}
|
||||
|
||||
// Take Square Roots, Min & Max
|
||||
float min = sqrt(image[0] );
|
||||
float max = min;
|
||||
|
||||
for (int y = 0, l = 0; y < height; y++ )
|
||||
{
|
||||
for (int x = 0; x < width; x++, l++ )
|
||||
{
|
||||
image[l] = sqrt(image[l]);
|
||||
|
||||
if (min > image[l])
|
||||
{
|
||||
min = image[l];
|
||||
}
|
||||
|
||||
if (max < image[l])
|
||||
{
|
||||
max = image[l];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// III. Convert To Grayscale
|
||||
if (min == max)
|
||||
{
|
||||
memset(buffer ,0 ,width * height );
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale = 255 / (max - min );
|
||||
|
||||
for (int y = 0, l = 0; y < height; y++ )
|
||||
{
|
||||
for (int x = 0; x < width; x++ ,l++ )
|
||||
{
|
||||
buffer[l] = int8u(int((image[l] - min ) * scale ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
if (m_buffer)
|
||||
{
|
||||
delete [] m_buffer;
|
||||
}
|
||||
|
||||
m_buffer = buffer;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
buffer = NULL;
|
||||
result = m_buffer;
|
||||
|
||||
}
|
||||
|
||||
if (spanf) { delete [] spanf; }
|
||||
if (spang) { delete [] spang; }
|
||||
if (spanr) { delete [] spanr; }
|
||||
if (spann) { delete [] spann; }
|
||||
|
||||
delete [] image;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// AGG Contribution Pack - Gradients 1 (AGG CP - Gradients 1)
|
||||
// http://milan.marusinec.sk/aggcp
|
||||
//
|
||||
// For Anti-Grain Geometry - Version 2.4
|
||||
// http://www.antigrain.org
|
||||
//
|
||||
// Contribution Created By:
|
||||
// Milan Marusinec alias Milano
|
||||
// milan@marusinec.sk
|
||||
// Copyright (c) 2007-2008
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// [History] -----------------------------------------------------------------
|
||||
//
|
||||
// 03.02.2008-Milano: Ported from Object Pascal code of AggPas
|
||||
//
|
||||
#ifndef AGG_SPAN_GRADIENT_IMAGE_INCLUDED
|
||||
#define AGG_SPAN_GRADIENT_IMAGE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_span_gradient.h"
|
||||
#include "agg_color_rgba.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//==========================================================one_color_function
|
||||
template<class ColorT> class one_color_function
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
color_type m_color;
|
||||
|
||||
one_color_function() :
|
||||
m_color()
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned size() { return 1; }
|
||||
|
||||
const color_type& operator [] (unsigned i) const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
color_type* operator [] (unsigned i)
|
||||
{
|
||||
return &m_color;
|
||||
}
|
||||
};
|
||||
|
||||
//==========================================================gradient_image
|
||||
template<class ColorT> class gradient_image
|
||||
{
|
||||
private:
|
||||
//------------ fields
|
||||
typedef ColorT color_type;
|
||||
typedef agg::pixfmt_rgba32 pixfmt_type;
|
||||
|
||||
agg::rgba8* m_buffer;
|
||||
|
||||
int m_alocdx;
|
||||
int m_alocdy;
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
color_type* m_color;
|
||||
|
||||
one_color_function<color_type> m_color_function;
|
||||
|
||||
public:
|
||||
gradient_image() :
|
||||
m_color_function(),
|
||||
m_buffer(NULL),
|
||||
m_alocdx(0),
|
||||
m_alocdy(0),
|
||||
m_width(0),
|
||||
m_height(0)
|
||||
{
|
||||
m_color = m_color_function[0 ];
|
||||
}
|
||||
|
||||
~gradient_image()
|
||||
{
|
||||
if (m_buffer) { delete [] m_buffer; }
|
||||
}
|
||||
|
||||
void* image_create(int width, int height )
|
||||
{
|
||||
void* result = NULL;
|
||||
|
||||
if (width > m_alocdx || height > m_alocdy)
|
||||
{
|
||||
if (m_buffer) { delete [] m_buffer; }
|
||||
|
||||
m_buffer = NULL;
|
||||
m_buffer = new agg::rgba8[width * height];
|
||||
|
||||
if (m_buffer)
|
||||
{
|
||||
m_alocdx = width;
|
||||
m_alocdy = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_alocdx = 0;
|
||||
m_alocdy = 0;
|
||||
};
|
||||
};
|
||||
|
||||
if (m_buffer)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
for (int rows = 0; rows < height; rows++)
|
||||
{
|
||||
agg::rgba8* row = &m_buffer[rows * m_alocdx ];
|
||||
memset(row ,0 ,m_width * 4 );
|
||||
};
|
||||
|
||||
result = m_buffer;
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
void* image_buffer() { return m_buffer; }
|
||||
int image_width() { return m_width; }
|
||||
int image_height() { return m_height; }
|
||||
int image_stride() { return m_alocdx * 4; }
|
||||
|
||||
int calculate(int x, int y, int d) const
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
int px = x >> agg::gradient_subpixel_shift;
|
||||
int py = y >> agg::gradient_subpixel_shift;
|
||||
|
||||
px %= m_width;
|
||||
|
||||
if (px < 0)
|
||||
{
|
||||
px += m_width;
|
||||
}
|
||||
|
||||
py %= m_height;
|
||||
|
||||
if (py < 0 )
|
||||
{
|
||||
py += m_height;
|
||||
}
|
||||
|
||||
rgba8* pixel = &m_buffer[py * m_alocdx + px ];
|
||||
|
||||
m_color->r = pixel->r;
|
||||
m_color->g = pixel->g;
|
||||
m_color->b = pixel->b;
|
||||
m_color->a = pixel->a;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_color->r = 0;
|
||||
m_color->g = 0;
|
||||
m_color->b = 0;
|
||||
m_color->a = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const one_color_function<color_type>& color_function() const
|
||||
{
|
||||
return m_color_function;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Image transformations with filtering. Span generator base class
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SPAN_IMAGE_FILTER_INCLUDED
|
||||
#define AGG_SPAN_IMAGE_FILTER_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter() {}
|
||||
span_image_filter(source_type& src,
|
||||
interpolator_type& interpolator,
|
||||
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(image_filter_lut& v) { m_filter = &v; }
|
||||
void filter_offset(double dx, double dy)
|
||||
{
|
||||
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;
|
||||
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,
|
||||
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);
|
||||
|
||||
double scale_xy = scale_x * scale_y;
|
||||
if (scale_xy > m_scale_limit)
|
||||
{
|
||||
scale_x = scale_x * m_scale_limit / scale_xy;
|
||||
scale_y = scale_y * m_scale_limit / scale_xy;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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,
|
||||
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
|
||||
|
|
@ -1,723 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED
|
||||
#define AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_color_gray.h"
|
||||
#include "agg_span_image_filter.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//==============================================span_image_filter_gray_nn
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_gray_nn :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_gray_nn() {}
|
||||
span_image_filter_gray_nn(source_type& src,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
span->v = *(const value_type*)
|
||||
base_type::source().span(x >> image_subpixel_shift,
|
||||
y >> image_subpixel_shift,
|
||||
1);
|
||||
span->a = color_type::full_value();
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=========================================span_image_filter_gray_bilinear
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_gray_bilinear :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_gray_bilinear() {}
|
||||
span_image_filter_gray_bilinear(source_type& src,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
long_type fg;
|
||||
const value_type *fg_ptr;
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
fg = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
|
||||
fg += *fg_ptr * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr);
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
fg += *fg_ptr * x_hr * (image_subpixel_scale - y_hr);
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
fg += *fg_ptr * (image_subpixel_scale - x_hr) * y_hr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
fg += *fg_ptr * x_hr * y_hr;
|
||||
|
||||
span->v = color_type::downshift(fg, image_subpixel_shift * 2);
|
||||
span->a = color_type::full_value();
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//====================================span_image_filter_gray_bilinear_clip
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_gray_bilinear_clip :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_gray_bilinear_clip() {}
|
||||
span_image_filter_gray_bilinear_clip(source_type& src,
|
||||
const color_type& back_color,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0),
|
||||
m_back_color(back_color)
|
||||
{}
|
||||
const color_type& background_color() const { return m_back_color; }
|
||||
void background_color(const color_type& v) { m_back_color = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
long_type fg;
|
||||
long_type src_alpha;
|
||||
value_type back_v = m_back_color.v;
|
||||
value_type back_a = m_back_color.a;
|
||||
|
||||
const value_type *fg_ptr;
|
||||
|
||||
int maxx = base_type::source().width() - 1;
|
||||
int maxy = base_type::source().height() - 1;
|
||||
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr < maxx && y_lr < maxy)
|
||||
{
|
||||
fg = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr;
|
||||
|
||||
fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr);
|
||||
fg += *fg_ptr++ * (image_subpixel_scale - y_hr) * x_hr;
|
||||
|
||||
++y_lr;
|
||||
fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr;
|
||||
|
||||
fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * y_hr;
|
||||
fg += *fg_ptr++ * x_hr * y_hr;
|
||||
|
||||
fg = color_type::downshift(fg, image_subpixel_shift * 2);
|
||||
src_alpha = color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned weight;
|
||||
if(x_lr < -1 || y_lr < -1 ||
|
||||
x_lr > maxx || y_lr > maxy)
|
||||
{
|
||||
fg = back_v;
|
||||
src_alpha = back_a;
|
||||
}
|
||||
else
|
||||
{
|
||||
fg = src_alpha = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) *
|
||||
(image_subpixel_scale - y_hr);
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg += weight *
|
||||
*((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg += back_v * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr++;
|
||||
|
||||
weight = x_hr * (image_subpixel_scale - y_hr);
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg += weight *
|
||||
*((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg += back_v * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr--;
|
||||
y_lr++;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) * y_hr;
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg += weight *
|
||||
*((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg += back_v * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr++;
|
||||
|
||||
weight = x_hr * y_hr;
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg += weight *
|
||||
*((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg += back_v * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
fg = color_type::downshift(fg, image_subpixel_shift * 2);
|
||||
src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2);
|
||||
}
|
||||
}
|
||||
|
||||
span->v = (value_type)fg;
|
||||
span->a = (value_type)src_alpha;
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
private:
|
||||
color_type m_back_color;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==============================================span_image_filter_gray_2x2
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_gray_2x2 :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_gray_2x2() {}
|
||||
span_image_filter_gray_2x2(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg;
|
||||
|
||||
const value_type *fg_ptr;
|
||||
const int16* weight_array = base_type::filter().weight_array() +
|
||||
((base_type::filter().diameter()/2 - 1) <<
|
||||
image_subpixel_shift);
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
unsigned weight;
|
||||
fg = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
|
||||
weight = (weight_array[x_hr + image_subpixel_scale] *
|
||||
weight_array[y_hr + image_subpixel_scale] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = (weight_array[x_hr] *
|
||||
weight_array[y_hr + image_subpixel_scale] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
weight = (weight_array[x_hr + image_subpixel_scale] *
|
||||
weight_array[y_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = (weight_array[x_hr] *
|
||||
weight_array[y_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg += weight * *fg_ptr;
|
||||
|
||||
fg >>= image_filter_shift;
|
||||
if(fg > color_type::full_value()) fg = color_type::full_value();
|
||||
|
||||
span->v = (value_type)fg;
|
||||
span->a = color_type::full_value();
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================span_image_filter_gray
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_gray :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_gray() {}
|
||||
span_image_filter_gray(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg;
|
||||
const value_type *fg_ptr;
|
||||
|
||||
unsigned diameter = base_type::filter().diameter();
|
||||
int start = base_type::filter().start();
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
|
||||
int x_count;
|
||||
int weight_y;
|
||||
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
|
||||
x -= base_type::filter_dx_int();
|
||||
y -= base_type::filter_dy_int();
|
||||
|
||||
int x_hr = x;
|
||||
int y_hr = y;
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
fg = 0;
|
||||
|
||||
int x_fract = x_hr & image_subpixel_mask;
|
||||
unsigned y_count = diameter;
|
||||
|
||||
y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
|
||||
y_lr + start,
|
||||
diameter);
|
||||
for(;;)
|
||||
{
|
||||
x_count = diameter;
|
||||
weight_y = weight_array[y_hr];
|
||||
x_hr = image_subpixel_mask - x_fract;
|
||||
for(;;)
|
||||
{
|
||||
fg += *fg_ptr *
|
||||
((weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift);
|
||||
if(--x_count == 0) break;
|
||||
x_hr += image_subpixel_scale;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
|
||||
if(--y_count == 0) break;
|
||||
y_hr += image_subpixel_scale;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg >>= image_filter_shift;
|
||||
if(fg < 0) fg = 0;
|
||||
if(fg > color_type::full_value()) fg = color_type::full_value();
|
||||
span->v = (value_type)fg;
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=========================================span_image_resample_gray_affine
|
||||
template<class Source>
|
||||
class span_image_resample_gray_affine :
|
||||
public span_image_resample_affine<Source>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef span_image_resample_affine<source_type> base_type;
|
||||
typedef typename base_type::interpolator_type interpolator_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
downscale_shift = image_filter_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_gray_affine() {}
|
||||
span_image_resample_gray_affine(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, filter)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg;
|
||||
|
||||
int diameter = base_type::filter().diameter();
|
||||
int filter_scale = diameter << image_subpixel_shift;
|
||||
int radius_x = (diameter * base_type::m_rx) >> 1;
|
||||
int radius_y = (diameter * base_type::m_ry) >> 1;
|
||||
int len_x_lr =
|
||||
(diameter * base_type::m_rx + image_subpixel_mask) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
|
||||
x += base_type::filter_dx_int() - radius_x;
|
||||
y += base_type::filter_dy_int() - radius_y;
|
||||
|
||||
fg = 0;
|
||||
|
||||
int y_lr = y >> image_subpixel_shift;
|
||||
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
|
||||
base_type::m_ry_inv) >>
|
||||
image_subpixel_shift;
|
||||
int total_weight = 0;
|
||||
int x_lr = x >> image_subpixel_shift;
|
||||
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
|
||||
base_type::m_rx_inv) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
int x_hr2 = x_hr;
|
||||
const value_type* fg_ptr =
|
||||
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
|
||||
for(;;)
|
||||
{
|
||||
int weight_y = weight_array[y_hr];
|
||||
x_hr = x_hr2;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
downscale_shift;
|
||||
|
||||
fg += *fg_ptr * weight;
|
||||
total_weight += weight;
|
||||
x_hr += base_type::m_rx_inv;
|
||||
if(x_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
y_hr += base_type::m_ry_inv;
|
||||
if(y_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg /= total_weight;
|
||||
if(fg < 0) fg = 0;
|
||||
if(fg > color_type::full_value()) fg = color_type::full_value();
|
||||
|
||||
span->v = (value_type)fg;
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//================================================span_image_resample_gray
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_resample_gray :
|
||||
public span_image_resample<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_resample<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
downscale_shift = image_filter_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_gray() {}
|
||||
span_image_resample_gray(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, filter)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
long_type fg;
|
||||
|
||||
int diameter = base_type::filter().diameter();
|
||||
int filter_scale = diameter << image_subpixel_shift;
|
||||
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
do
|
||||
{
|
||||
int rx;
|
||||
int ry;
|
||||
int rx_inv = image_subpixel_scale;
|
||||
int ry_inv = image_subpixel_scale;
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
base_type::interpolator().local_scale(&rx, &ry);
|
||||
base_type::adjust_scale(&rx, &ry);
|
||||
|
||||
rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
|
||||
ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
|
||||
|
||||
int radius_x = (diameter * rx) >> 1;
|
||||
int radius_y = (diameter * ry) >> 1;
|
||||
int len_x_lr =
|
||||
(diameter * rx + image_subpixel_mask) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
x += base_type::filter_dx_int() - radius_x;
|
||||
y += base_type::filter_dy_int() - radius_y;
|
||||
|
||||
fg = 0;
|
||||
|
||||
int y_lr = y >> image_subpixel_shift;
|
||||
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
|
||||
ry_inv) >>
|
||||
image_subpixel_shift;
|
||||
int total_weight = 0;
|
||||
int x_lr = x >> image_subpixel_shift;
|
||||
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
|
||||
rx_inv) >>
|
||||
image_subpixel_shift;
|
||||
int x_hr2 = x_hr;
|
||||
const value_type* fg_ptr =
|
||||
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int weight_y = weight_array[y_hr];
|
||||
x_hr = x_hr2;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
downscale_shift;
|
||||
fg += *fg_ptr * weight;
|
||||
total_weight += weight;
|
||||
x_hr += rx_inv;
|
||||
if(x_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
y_hr += ry_inv;
|
||||
if(y_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg /= total_weight;
|
||||
if(fg < 0) fg = 0;
|
||||
if(fg > color_type::full_value()) fg = color_type::full_value();
|
||||
|
||||
span->v = (value_type)fg;
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,861 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
|
||||
#define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_color_rgba.h"
|
||||
#include "agg_span_image_filter.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//===============================================span_image_filter_rgb_nn
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgb_nn :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgb_nn() {}
|
||||
span_image_filter_rgb_nn(source_type& src,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
const value_type* fg_ptr = (const value_type*)
|
||||
base_type::source().span(x >> image_subpixel_shift,
|
||||
y >> image_subpixel_shift,
|
||||
1);
|
||||
span->r = fg_ptr[order_type::R];
|
||||
span->g = fg_ptr[order_type::G];
|
||||
span->b = fg_ptr[order_type::B];
|
||||
span->a = color_type::full_value();
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================span_image_filter_rgb_bilinear
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgb_bilinear :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgb_bilinear() {}
|
||||
span_image_filter_rgb_bilinear(source_type& src,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
long_type fg[3];
|
||||
const value_type *fg_ptr;
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
unsigned weight;
|
||||
|
||||
fg[0] = fg[1] = fg[2] = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
|
||||
weight = (image_subpixel_scale - x_hr) *
|
||||
(image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = x_hr * (image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
weight = (image_subpixel_scale - x_hr) * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = x_hr * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
span->r = color_type::downshift(fg[order_type::R], image_subpixel_shift * 2);
|
||||
span->g = color_type::downshift(fg[order_type::G], image_subpixel_shift * 2);
|
||||
span->b = color_type::downshift(fg[order_type::B], image_subpixel_shift * 2);
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=====================================span_image_filter_rgb_bilinear_clip
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgb_bilinear_clip :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgb_bilinear_clip() {}
|
||||
span_image_filter_rgb_bilinear_clip(source_type& src,
|
||||
const color_type& back_color,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0),
|
||||
m_back_color(back_color)
|
||||
{}
|
||||
const color_type& background_color() const { return m_back_color; }
|
||||
void background_color(const color_type& v) { m_back_color = v; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
long_type fg[3];
|
||||
long_type src_alpha;
|
||||
value_type back_r = m_back_color.r;
|
||||
value_type back_g = m_back_color.g;
|
||||
value_type back_b = m_back_color.b;
|
||||
value_type back_a = m_back_color.a;
|
||||
|
||||
const value_type *fg_ptr;
|
||||
|
||||
int maxx = base_type::source().width() - 1;
|
||||
int maxy = base_type::source().height() - 1;
|
||||
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
unsigned weight;
|
||||
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr < maxx && y_lr < maxy)
|
||||
{
|
||||
fg[0] = fg[1] = fg[2] = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) *
|
||||
(image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
|
||||
weight = x_hr * (image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
|
||||
++y_lr;
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
|
||||
weight = x_hr * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2);
|
||||
fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2);
|
||||
fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2);
|
||||
src_alpha = color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x_lr < -1 || y_lr < -1 ||
|
||||
x_lr > maxx || y_lr > maxy)
|
||||
{
|
||||
fg[order_type::R] = back_r;
|
||||
fg[order_type::G] = back_g;
|
||||
fg[order_type::B] = back_b;
|
||||
src_alpha = back_a;
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[0] = fg[1] = fg[2] = src_alpha = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) *
|
||||
(image_subpixel_scale - y_hr);
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr++;
|
||||
|
||||
weight = x_hr * (image_subpixel_scale - y_hr);
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr--;
|
||||
y_lr++;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) * y_hr;
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr++;
|
||||
|
||||
weight = x_hr * y_hr;
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
src_alpha += weight * color_type::full_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
src_alpha += back_a * weight;
|
||||
}
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2);
|
||||
fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2);
|
||||
fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2);
|
||||
src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2);
|
||||
}
|
||||
}
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = (value_type)src_alpha;
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
private:
|
||||
color_type m_back_color;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//===============================================span_image_filter_rgb_2x2
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgb_2x2 :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgb_2x2() {}
|
||||
span_image_filter_rgb_2x2(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[3];
|
||||
|
||||
const value_type *fg_ptr;
|
||||
const int16* weight_array = base_type::filter().weight_array() +
|
||||
((base_type::filter().diameter()/2 - 1) <<
|
||||
image_subpixel_shift);
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
unsigned weight;
|
||||
fg[0] = fg[1] = fg[2] = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
|
||||
weight = (weight_array[x_hr + image_subpixel_scale] *
|
||||
weight_array[y_hr + image_subpixel_scale] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = (weight_array[x_hr] *
|
||||
weight_array[y_hr + image_subpixel_scale] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
weight = (weight_array[x_hr + image_subpixel_scale] *
|
||||
weight_array[y_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = (weight_array[x_hr] *
|
||||
weight_array[y_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_filter_shift);
|
||||
fg[1] = color_type::downshift(fg[1], image_filter_shift);
|
||||
fg[2] = color_type::downshift(fg[2], image_filter_shift);
|
||||
|
||||
if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
|
||||
if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
|
||||
if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//===================================================span_image_filter_rgb
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgb :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgb() {}
|
||||
span_image_filter_rgb(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[3];
|
||||
const value_type *fg_ptr;
|
||||
|
||||
unsigned diameter = base_type::filter().diameter();
|
||||
int start = base_type::filter().start();
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
|
||||
int x_count;
|
||||
int weight_y;
|
||||
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
|
||||
x -= base_type::filter_dx_int();
|
||||
y -= base_type::filter_dy_int();
|
||||
|
||||
int x_hr = x;
|
||||
int y_hr = y;
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
fg[0] = fg[1] = fg[2] = 0;
|
||||
|
||||
int x_fract = x_hr & image_subpixel_mask;
|
||||
unsigned y_count = diameter;
|
||||
|
||||
y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
|
||||
y_lr + start,
|
||||
diameter);
|
||||
for(;;)
|
||||
{
|
||||
x_count = diameter;
|
||||
weight_y = weight_array[y_hr];
|
||||
x_hr = image_subpixel_mask - x_fract;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr;
|
||||
|
||||
if(--x_count == 0) break;
|
||||
x_hr += image_subpixel_scale;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
|
||||
if(--y_count == 0) break;
|
||||
y_hr += image_subpixel_scale;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_filter_shift);
|
||||
fg[1] = color_type::downshift(fg[1], image_filter_shift);
|
||||
fg[2] = color_type::downshift(fg[2], image_filter_shift);
|
||||
|
||||
if(fg[0] < 0) fg[0] = 0;
|
||||
if(fg[1] < 0) fg[1] = 0;
|
||||
if(fg[2] < 0) fg[2] = 0;
|
||||
|
||||
if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
|
||||
if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
|
||||
if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================span_image_resample_rgb_affine
|
||||
template<class Source>
|
||||
class span_image_resample_rgb_affine :
|
||||
public span_image_resample_affine<Source>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef span_image_resample_affine<source_type> base_type;
|
||||
typedef typename base_type::interpolator_type interpolator_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
downscale_shift = image_filter_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_rgb_affine() {}
|
||||
span_image_resample_rgb_affine(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, filter)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[3];
|
||||
|
||||
int diameter = base_type::filter().diameter();
|
||||
int filter_scale = diameter << image_subpixel_shift;
|
||||
int radius_x = (diameter * base_type::m_rx) >> 1;
|
||||
int radius_y = (diameter * base_type::m_ry) >> 1;
|
||||
int len_x_lr =
|
||||
(diameter * base_type::m_rx + image_subpixel_mask) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
|
||||
x += base_type::filter_dx_int() - radius_x;
|
||||
y += base_type::filter_dy_int() - radius_y;
|
||||
|
||||
fg[0] = fg[1] = fg[2] = 0;
|
||||
|
||||
int y_lr = y >> image_subpixel_shift;
|
||||
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
|
||||
base_type::m_ry_inv) >>
|
||||
image_subpixel_shift;
|
||||
int total_weight = 0;
|
||||
int x_lr = x >> image_subpixel_shift;
|
||||
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
|
||||
base_type::m_rx_inv) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
int x_hr2 = x_hr;
|
||||
const value_type* fg_ptr =
|
||||
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
|
||||
for(;;)
|
||||
{
|
||||
int weight_y = weight_array[y_hr];
|
||||
x_hr = x_hr2;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
downscale_shift;
|
||||
|
||||
fg[0] += *fg_ptr++ * weight;
|
||||
fg[1] += *fg_ptr++ * weight;
|
||||
fg[2] += *fg_ptr * weight;
|
||||
total_weight += weight;
|
||||
x_hr += base_type::m_rx_inv;
|
||||
if(x_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
y_hr += base_type::m_ry_inv;
|
||||
if(y_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg[0] /= total_weight;
|
||||
fg[1] /= total_weight;
|
||||
fg[2] /= total_weight;
|
||||
|
||||
if(fg[0] < 0) fg[0] = 0;
|
||||
if(fg[1] < 0) fg[1] = 0;
|
||||
if(fg[2] < 0) fg[2] = 0;
|
||||
|
||||
if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
|
||||
if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
|
||||
if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=================================================span_image_resample_rgb
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_resample_rgb :
|
||||
public span_image_resample<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_resample<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
downscale_shift = image_filter_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_rgb() {}
|
||||
span_image_resample_rgb(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, filter)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
long_type fg[3];
|
||||
|
||||
int diameter = base_type::filter().diameter();
|
||||
int filter_scale = diameter << image_subpixel_shift;
|
||||
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
do
|
||||
{
|
||||
int rx;
|
||||
int ry;
|
||||
int rx_inv = image_subpixel_scale;
|
||||
int ry_inv = image_subpixel_scale;
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
base_type::interpolator().local_scale(&rx, &ry);
|
||||
base_type::adjust_scale(&rx, &ry);
|
||||
|
||||
rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
|
||||
ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
|
||||
|
||||
int radius_x = (diameter * rx) >> 1;
|
||||
int radius_y = (diameter * ry) >> 1;
|
||||
int len_x_lr =
|
||||
(diameter * rx + image_subpixel_mask) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
x += base_type::filter_dx_int() - radius_x;
|
||||
y += base_type::filter_dy_int() - radius_y;
|
||||
|
||||
fg[0] = fg[1] = fg[2] = 0;
|
||||
|
||||
int y_lr = y >> image_subpixel_shift;
|
||||
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
|
||||
ry_inv) >>
|
||||
image_subpixel_shift;
|
||||
int total_weight = 0;
|
||||
int x_lr = x >> image_subpixel_shift;
|
||||
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
|
||||
rx_inv) >>
|
||||
image_subpixel_shift;
|
||||
int x_hr2 = x_hr;
|
||||
const value_type* fg_ptr =
|
||||
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int weight_y = weight_array[y_hr];
|
||||
x_hr = x_hr2;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
downscale_shift;
|
||||
fg[0] += *fg_ptr++ * weight;
|
||||
fg[1] += *fg_ptr++ * weight;
|
||||
fg[2] += *fg_ptr * weight;
|
||||
total_weight += weight;
|
||||
x_hr += rx_inv;
|
||||
if(x_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
y_hr += ry_inv;
|
||||
if(y_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg[0] /= total_weight;
|
||||
fg[1] /= total_weight;
|
||||
fg[2] /= total_weight;
|
||||
|
||||
if(fg[0] < 0) fg[0] = 0;
|
||||
if(fg[1] < 0) fg[1] = 0;
|
||||
if(fg[2] < 0) fg[2] = 0;
|
||||
|
||||
if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
|
||||
if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
|
||||
if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = color_type::full_value();
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,890 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED
|
||||
#define AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_color_rgba.h"
|
||||
#include "agg_span_image_filter.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//==============================================span_image_filter_rgba_nn
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgba_nn :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgba_nn() {}
|
||||
span_image_filter_rgba_nn(source_type& src,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
const value_type* fg_ptr = (const value_type*)
|
||||
base_type::source().span(x >> image_subpixel_shift,
|
||||
y >> image_subpixel_shift,
|
||||
1);
|
||||
span->r = fg_ptr[order_type::R];
|
||||
span->g = fg_ptr[order_type::G];
|
||||
span->b = fg_ptr[order_type::B];
|
||||
span->a = fg_ptr[order_type::A];
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=========================================span_image_filter_rgba_bilinear
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgba_bilinear :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgba_bilinear() {}
|
||||
span_image_filter_rgba_bilinear(source_type& src,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[4];
|
||||
const value_type *fg_ptr;
|
||||
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
unsigned weight;
|
||||
|
||||
fg[0] =
|
||||
fg[1] =
|
||||
fg[2] =
|
||||
fg[3] = image_subpixel_scale * image_subpixel_scale / 2;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
|
||||
weight = (image_subpixel_scale - x_hr) *
|
||||
(image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = x_hr * (image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
weight = (image_subpixel_scale - x_hr) * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = x_hr * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
span->r = value_type(color_type::downshift(fg[order_type::R], image_subpixel_shift * 2));
|
||||
span->g = value_type(color_type::downshift(fg[order_type::G], image_subpixel_shift * 2));
|
||||
span->b = value_type(color_type::downshift(fg[order_type::B], image_subpixel_shift * 2));
|
||||
span->a = value_type(color_type::downshift(fg[order_type::A], image_subpixel_shift * 2));
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//====================================span_image_filter_rgba_bilinear_clip
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgba_bilinear_clip :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgba_bilinear_clip() {}
|
||||
span_image_filter_rgba_bilinear_clip(source_type& src,
|
||||
const color_type& back_color,
|
||||
interpolator_type& inter) :
|
||||
base_type(src, inter, 0),
|
||||
m_back_color(back_color)
|
||||
{}
|
||||
const color_type& background_color() const { return m_back_color; }
|
||||
void background_color(const color_type& v) { m_back_color = v; }
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[4];
|
||||
value_type back_r = m_back_color.r;
|
||||
value_type back_g = m_back_color.g;
|
||||
value_type back_b = m_back_color.b;
|
||||
value_type back_a = m_back_color.a;
|
||||
|
||||
const value_type *fg_ptr;
|
||||
int maxx = base_type::source().width() - 1;
|
||||
int maxy = base_type::source().height() - 1;
|
||||
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
unsigned weight;
|
||||
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr < maxx && y_lr < maxy)
|
||||
{
|
||||
fg[0] = fg[1] = fg[2] = fg[3] = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + (x_lr << 2);
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) *
|
||||
(image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
|
||||
weight = x_hr * (image_subpixel_scale - y_hr);
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
|
||||
++y_lr;
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + (x_lr << 2);
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
|
||||
weight = x_hr * y_hr;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2);
|
||||
fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2);
|
||||
fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2);
|
||||
fg[3] = color_type::downshift(fg[3], image_subpixel_shift * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x_lr < -1 || y_lr < -1 ||
|
||||
x_lr > maxx || y_lr > maxy)
|
||||
{
|
||||
fg[order_type::R] = back_r;
|
||||
fg[order_type::G] = back_g;
|
||||
fg[order_type::B] = back_b;
|
||||
fg[order_type::A] = back_a;
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[0] = fg[1] = fg[2] = fg[3] = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) *
|
||||
(image_subpixel_scale - y_hr);
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + (x_lr << 2);
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
fg[order_type::A] += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr++;
|
||||
|
||||
weight = x_hr * (image_subpixel_scale - y_hr);
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + (x_lr << 2);
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
fg[order_type::A] += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr--;
|
||||
y_lr++;
|
||||
|
||||
weight = (image_subpixel_scale - x_hr) * y_hr;
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + (x_lr << 2);
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
fg[order_type::A] += back_a * weight;
|
||||
}
|
||||
|
||||
x_lr++;
|
||||
|
||||
weight = x_hr * y_hr;
|
||||
if(x_lr >= 0 && y_lr >= 0 &&
|
||||
x_lr <= maxx && y_lr <= maxy)
|
||||
{
|
||||
fg_ptr = (const value_type*)
|
||||
base_type::source().row_ptr(y_lr) + (x_lr << 2);
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fg[order_type::R] += back_r * weight;
|
||||
fg[order_type::G] += back_g * weight;
|
||||
fg[order_type::B] += back_b * weight;
|
||||
fg[order_type::A] += back_a * weight;
|
||||
}
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2);
|
||||
fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2);
|
||||
fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2);
|
||||
fg[3] = color_type::downshift(fg[3], image_subpixel_shift * 2);
|
||||
}
|
||||
}
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = (value_type)fg[order_type::A];
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
private:
|
||||
color_type m_back_color;
|
||||
};
|
||||
|
||||
|
||||
//==============================================span_image_filter_rgba_2x2
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgba_2x2 :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgba_2x2() {}
|
||||
span_image_filter_rgba_2x2(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[4];
|
||||
|
||||
const value_type *fg_ptr;
|
||||
const int16* weight_array = base_type::filter().weight_array() +
|
||||
((base_type::filter().diameter()/2 - 1) <<
|
||||
image_subpixel_shift);
|
||||
|
||||
do
|
||||
{
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
|
||||
base_type::interpolator().coordinates(&x_hr, &y_hr);
|
||||
|
||||
x_hr -= base_type::filter_dx_int();
|
||||
y_hr -= base_type::filter_dy_int();
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
unsigned weight;
|
||||
fg[0] = fg[1] = fg[2] = fg[3] = 0;
|
||||
|
||||
x_hr &= image_subpixel_mask;
|
||||
y_hr &= image_subpixel_mask;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
|
||||
weight = (weight_array[x_hr + image_subpixel_scale] *
|
||||
weight_array[y_hr + image_subpixel_scale] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = (weight_array[x_hr] *
|
||||
weight_array[y_hr + image_subpixel_scale] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
weight = (weight_array[x_hr + image_subpixel_scale] *
|
||||
weight_array[y_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
weight = (weight_array[x_hr] *
|
||||
weight_array[y_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_filter_shift);
|
||||
fg[1] = color_type::downshift(fg[1], image_filter_shift);
|
||||
fg[2] = color_type::downshift(fg[2], image_filter_shift);
|
||||
fg[3] = color_type::downshift(fg[3], image_filter_shift);
|
||||
|
||||
if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value();
|
||||
if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
|
||||
if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
|
||||
if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = (value_type)fg[order_type::A];
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================span_image_filter_rgba
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_filter_rgba :
|
||||
public span_image_filter<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_filter<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_filter_rgba() {}
|
||||
span_image_filter_rgba(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, &filter)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[4];
|
||||
const value_type *fg_ptr;
|
||||
|
||||
unsigned diameter = base_type::filter().diameter();
|
||||
int start = base_type::filter().start();
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
|
||||
int x_count;
|
||||
int weight_y;
|
||||
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
|
||||
x -= base_type::filter_dx_int();
|
||||
y -= base_type::filter_dy_int();
|
||||
|
||||
int x_hr = x;
|
||||
int y_hr = y;
|
||||
|
||||
int x_lr = x_hr >> image_subpixel_shift;
|
||||
int y_lr = y_hr >> image_subpixel_shift;
|
||||
|
||||
fg[0] = fg[1] = fg[2] = fg[3] = 0;
|
||||
|
||||
int x_fract = x_hr & image_subpixel_mask;
|
||||
unsigned y_count = diameter;
|
||||
|
||||
y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
|
||||
fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
|
||||
y_lr + start,
|
||||
diameter);
|
||||
for(;;)
|
||||
{
|
||||
x_count = diameter;
|
||||
weight_y = weight_array[y_hr];
|
||||
x_hr = image_subpixel_mask - x_fract;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
image_filter_shift;
|
||||
|
||||
fg[0] += weight * *fg_ptr++;
|
||||
fg[1] += weight * *fg_ptr++;
|
||||
fg[2] += weight * *fg_ptr++;
|
||||
fg[3] += weight * *fg_ptr;
|
||||
|
||||
if(--x_count == 0) break;
|
||||
x_hr += image_subpixel_scale;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
|
||||
if(--y_count == 0) break;
|
||||
y_hr += image_subpixel_scale;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg[0] = color_type::downshift(fg[0], image_filter_shift);
|
||||
fg[1] = color_type::downshift(fg[1], image_filter_shift);
|
||||
fg[2] = color_type::downshift(fg[2], image_filter_shift);
|
||||
fg[3] = color_type::downshift(fg[3], image_filter_shift);
|
||||
|
||||
if(fg[0] < 0) fg[0] = 0;
|
||||
if(fg[1] < 0) fg[1] = 0;
|
||||
if(fg[2] < 0) fg[2] = 0;
|
||||
if(fg[3] < 0) fg[3] = 0;
|
||||
|
||||
if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value();
|
||||
if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
|
||||
if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
|
||||
if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = (value_type)fg[order_type::A];
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//========================================span_image_resample_rgba_affine
|
||||
template<class Source>
|
||||
class span_image_resample_rgba_affine :
|
||||
public span_image_resample_affine<Source>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef span_image_resample_affine<source_type> base_type;
|
||||
typedef typename base_type::interpolator_type interpolator_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
downscale_shift = image_filter_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_rgba_affine() {}
|
||||
span_image_resample_rgba_affine(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, filter)
|
||||
{}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
|
||||
long_type fg[4];
|
||||
|
||||
int diameter = base_type::filter().diameter();
|
||||
int filter_scale = diameter << image_subpixel_shift;
|
||||
int radius_x = (diameter * base_type::m_rx) >> 1;
|
||||
int radius_y = (diameter * base_type::m_ry) >> 1;
|
||||
int len_x_lr =
|
||||
(diameter * base_type::m_rx + image_subpixel_mask) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
|
||||
do
|
||||
{
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
|
||||
x += base_type::filter_dx_int() - radius_x;
|
||||
y += base_type::filter_dy_int() - radius_y;
|
||||
|
||||
fg[0] = fg[1] = fg[2] = fg[3] = 0;
|
||||
|
||||
int y_lr = y >> image_subpixel_shift;
|
||||
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
|
||||
base_type::m_ry_inv) >>
|
||||
image_subpixel_shift;
|
||||
int total_weight = 0;
|
||||
int x_lr = x >> image_subpixel_shift;
|
||||
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
|
||||
base_type::m_rx_inv) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
int x_hr2 = x_hr;
|
||||
const value_type* fg_ptr =
|
||||
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
|
||||
for(;;)
|
||||
{
|
||||
int weight_y = weight_array[y_hr];
|
||||
x_hr = x_hr2;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
downscale_shift;
|
||||
|
||||
fg[0] += *fg_ptr++ * weight;
|
||||
fg[1] += *fg_ptr++ * weight;
|
||||
fg[2] += *fg_ptr++ * weight;
|
||||
fg[3] += *fg_ptr++ * weight;
|
||||
total_weight += weight;
|
||||
x_hr += base_type::m_rx_inv;
|
||||
if(x_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
y_hr += base_type::m_ry_inv;
|
||||
if(y_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg[0] /= total_weight;
|
||||
fg[1] /= total_weight;
|
||||
fg[2] /= total_weight;
|
||||
fg[3] /= total_weight;
|
||||
|
||||
if(fg[0] < 0) fg[0] = 0;
|
||||
if(fg[1] < 0) fg[1] = 0;
|
||||
if(fg[2] < 0) fg[2] = 0;
|
||||
if(fg[3] < 0) fg[3] = 0;
|
||||
|
||||
if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value();
|
||||
if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
|
||||
if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
|
||||
if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = (value_type)fg[order_type::A];
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==============================================span_image_resample_rgba
|
||||
template<class Source, class Interpolator>
|
||||
class span_image_resample_rgba :
|
||||
public span_image_resample<Source, Interpolator>
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef span_image_resample<source_type, interpolator_type> base_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
enum base_scale_e
|
||||
{
|
||||
downscale_shift = image_filter_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_image_resample_rgba() {}
|
||||
span_image_resample_rgba(source_type& src,
|
||||
interpolator_type& inter,
|
||||
image_filter_lut& filter) :
|
||||
base_type(src, inter, filter)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
|
||||
y + base_type::filter_dy_dbl(), len);
|
||||
long_type fg[4];
|
||||
|
||||
int diameter = base_type::filter().diameter();
|
||||
int filter_scale = diameter << image_subpixel_shift;
|
||||
|
||||
const int16* weight_array = base_type::filter().weight_array();
|
||||
do
|
||||
{
|
||||
int rx;
|
||||
int ry;
|
||||
int rx_inv = image_subpixel_scale;
|
||||
int ry_inv = image_subpixel_scale;
|
||||
base_type::interpolator().coordinates(&x, &y);
|
||||
base_type::interpolator().local_scale(&rx, &ry);
|
||||
base_type::adjust_scale(&rx, &ry);
|
||||
|
||||
rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
|
||||
ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
|
||||
|
||||
int radius_x = (diameter * rx) >> 1;
|
||||
int radius_y = (diameter * ry) >> 1;
|
||||
int len_x_lr =
|
||||
(diameter * rx + image_subpixel_mask) >>
|
||||
image_subpixel_shift;
|
||||
|
||||
x += base_type::filter_dx_int() - radius_x;
|
||||
y += base_type::filter_dy_int() - radius_y;
|
||||
|
||||
fg[0] = fg[1] = fg[2] = fg[3] = 0;
|
||||
|
||||
int y_lr = y >> image_subpixel_shift;
|
||||
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
|
||||
ry_inv) >>
|
||||
image_subpixel_shift;
|
||||
int total_weight = 0;
|
||||
int x_lr = x >> image_subpixel_shift;
|
||||
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
|
||||
rx_inv) >>
|
||||
image_subpixel_shift;
|
||||
int x_hr2 = x_hr;
|
||||
const value_type* fg_ptr =
|
||||
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int weight_y = weight_array[y_hr];
|
||||
x_hr = x_hr2;
|
||||
for(;;)
|
||||
{
|
||||
int weight = (weight_y * weight_array[x_hr] +
|
||||
image_filter_scale / 2) >>
|
||||
downscale_shift;
|
||||
fg[0] += *fg_ptr++ * weight;
|
||||
fg[1] += *fg_ptr++ * weight;
|
||||
fg[2] += *fg_ptr++ * weight;
|
||||
fg[3] += *fg_ptr++ * weight;
|
||||
total_weight += weight;
|
||||
x_hr += rx_inv;
|
||||
if(x_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_x();
|
||||
}
|
||||
y_hr += ry_inv;
|
||||
if(y_hr >= filter_scale) break;
|
||||
fg_ptr = (const value_type*)base_type::source().next_y();
|
||||
}
|
||||
|
||||
fg[0] /= total_weight;
|
||||
fg[1] /= total_weight;
|
||||
fg[2] /= total_weight;
|
||||
fg[3] /= total_weight;
|
||||
|
||||
if(fg[0] < 0) fg[0] = 0;
|
||||
if(fg[1] < 0) fg[1] = 0;
|
||||
if(fg[2] < 0) fg[2] = 0;
|
||||
if(fg[3] < 0) fg[3] = 0;
|
||||
|
||||
if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value();
|
||||
if(fg[order_type::R] > fg[order_type::R]) fg[order_type::R] = fg[order_type::R];
|
||||
if(fg[order_type::G] > fg[order_type::G]) fg[order_type::G] = fg[order_type::G];
|
||||
if(fg[order_type::B] > fg[order_type::B]) fg[order_type::B] = fg[order_type::B];
|
||||
|
||||
span->r = (value_type)fg[order_type::R];
|
||||
span->g = (value_type)fg[order_type::G];
|
||||
span->b = (value_type)fg[order_type::B];
|
||||
span->a = (value_type)fg[order_type::A];
|
||||
|
||||
++span;
|
||||
++base_type::interpolator();
|
||||
} while(--len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_INTERPOLATOR_ADAPTOR_INCLUDED
|
||||
#define AGG_SPAN_INTERPOLATOR_ADAPTOR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//===============================================span_interpolator_adaptor
|
||||
template<class Interpolator, class Distortion>
|
||||
class span_interpolator_adaptor : public Interpolator
|
||||
{
|
||||
public:
|
||||
typedef Interpolator base_type;
|
||||
typedef typename base_type::trans_type trans_type;
|
||||
typedef Distortion distortion_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_adaptor() {}
|
||||
span_interpolator_adaptor(trans_type& trans,
|
||||
distortion_type& dist) :
|
||||
base_type(trans),
|
||||
m_distortion(&dist)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_adaptor(trans_type& trans,
|
||||
distortion_type& dist,
|
||||
double x, double y, unsigned len) :
|
||||
base_type(trans, x, y, len),
|
||||
m_distortion(&dist)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
distortion_type& distortion() const
|
||||
{
|
||||
return *m_distortion;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void distortion(distortion_type& dist)
|
||||
{
|
||||
m_distortion = dist;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
base_type::coordinates(x, y);
|
||||
m_distortion->calculate(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------
|
||||
distortion_type* m_distortion;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED
|
||||
#define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#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
|
||||
{
|
||||
public:
|
||||
typedef Transformer trans_type;
|
||||
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_linear() {}
|
||||
span_interpolator_linear(trans_type& trans) : m_trans(&trans) {}
|
||||
span_interpolator_linear(trans_type& trans,
|
||||
double x, double y, unsigned len) :
|
||||
m_trans(&trans)
|
||||
{
|
||||
begin(x, y, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
const trans_type& transformer() const { return *m_trans; }
|
||||
void transformer(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:
|
||||
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(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(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;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1,462 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED
|
||||
#define AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED
|
||||
|
||||
#include "agg_trans_perspective.h"
|
||||
#include "agg_dda_line.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
|
||||
|
||||
//===========================================span_interpolator_persp_exact
|
||||
template<unsigned SubpixelShift = 8>
|
||||
class span_interpolator_persp_exact
|
||||
{
|
||||
public:
|
||||
typedef trans_perspective trans_type;
|
||||
typedef trans_perspective::iterator_x iterator_type;
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_persp_exact() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Arbitrary quadrangle transformations
|
||||
span_interpolator_persp_exact(const double* src, const double* dst)
|
||||
{
|
||||
quad_to_quad(src, dst);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Direct transformations
|
||||
span_interpolator_persp_exact(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
rect_to_quad(x1, y1, x2, y2, quad);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Reverse transformations
|
||||
span_interpolator_persp_exact(const double* quad,
|
||||
double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
quad_to_rect(quad, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the transformations using two arbitrary quadrangles.
|
||||
void quad_to_quad(const double* src, const double* dst)
|
||||
{
|
||||
m_trans_dir.quad_to_quad(src, dst);
|
||||
m_trans_inv.quad_to_quad(dst, src);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the direct transformations, i.e., rectangle -> quadrangle
|
||||
void rect_to_quad(double x1, double y1, double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
double src[8];
|
||||
src[0] = src[6] = x1;
|
||||
src[2] = src[4] = x2;
|
||||
src[1] = src[3] = y1;
|
||||
src[5] = src[7] = y2;
|
||||
quad_to_quad(src, quad);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the reverse transformations, i.e., quadrangle -> rectangle
|
||||
void quad_to_rect(const double* quad,
|
||||
double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dst[8];
|
||||
dst[0] = dst[6] = x1;
|
||||
dst[2] = dst[4] = x2;
|
||||
dst[1] = dst[3] = y1;
|
||||
dst[5] = dst[7] = y2;
|
||||
quad_to_quad(quad, dst);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Check if the equations were solved successfully
|
||||
bool is_valid() const { return m_trans_dir.is_valid(); }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void begin(double x, double y, unsigned len)
|
||||
{
|
||||
m_iterator = m_trans_dir.begin(x, y, 1.0);
|
||||
double xt = m_iterator.x;
|
||||
double yt = m_iterator.y;
|
||||
|
||||
double dx;
|
||||
double dy;
|
||||
const double delta = 1/double(subpixel_scale);
|
||||
dx = xt + delta;
|
||||
dy = yt;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
dx = xt;
|
||||
dy = yt + delta;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
x += len;
|
||||
xt = x;
|
||||
yt = y;
|
||||
m_trans_dir.transform(&xt, &yt);
|
||||
|
||||
dx = xt + delta;
|
||||
dy = yt;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
dx = xt;
|
||||
dy = yt + delta;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
m_scale_x = dda2_line_interpolator(sx1, sx2, len);
|
||||
m_scale_y = dda2_line_interpolator(sy1, sy2, len);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void resynchronize(double xe, double ye, unsigned len)
|
||||
{
|
||||
// Assume x1,y1 are equal to the ones at the previous end point
|
||||
int sx1 = m_scale_x.y();
|
||||
int sy1 = m_scale_y.y();
|
||||
|
||||
// Calculate transformed coordinates at x2,y2
|
||||
double xt = xe;
|
||||
double yt = ye;
|
||||
m_trans_dir.transform(&xt, &yt);
|
||||
|
||||
const double delta = 1/double(subpixel_scale);
|
||||
double dx;
|
||||
double dy;
|
||||
|
||||
// Calculate scale by X at x2,y2
|
||||
dx = xt + delta;
|
||||
dy = yt;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= xe;
|
||||
dy -= ye;
|
||||
int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Calculate scale by Y at x2,y2
|
||||
dx = xt;
|
||||
dy = yt + delta;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= xe;
|
||||
dy -= ye;
|
||||
int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Initialize the interpolators
|
||||
m_scale_x = dda2_line_interpolator(sx1, sx2, len);
|
||||
m_scale_y = dda2_line_interpolator(sy1, sy2, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++m_iterator;
|
||||
++m_scale_x;
|
||||
++m_scale_y;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
*x = iround(m_iterator.x * subpixel_scale);
|
||||
*y = iround(m_iterator.y * subpixel_scale);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void local_scale(int* x, int* y)
|
||||
{
|
||||
*x = m_scale_x.y();
|
||||
*y = m_scale_y.y();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void transform(double* x, double* y) const
|
||||
{
|
||||
m_trans_dir.transform(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
trans_type m_trans_dir;
|
||||
trans_type m_trans_inv;
|
||||
iterator_type m_iterator;
|
||||
dda2_line_interpolator m_scale_x;
|
||||
dda2_line_interpolator m_scale_y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//============================================span_interpolator_persp_lerp
|
||||
template<unsigned SubpixelShift = 8>
|
||||
class span_interpolator_persp_lerp
|
||||
{
|
||||
public:
|
||||
typedef trans_perspective trans_type;
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_persp_lerp() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Arbitrary quadrangle transformations
|
||||
span_interpolator_persp_lerp(const double* src, const double* dst)
|
||||
{
|
||||
quad_to_quad(src, dst);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Direct transformations
|
||||
span_interpolator_persp_lerp(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
rect_to_quad(x1, y1, x2, y2, quad);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Reverse transformations
|
||||
span_interpolator_persp_lerp(const double* quad,
|
||||
double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
quad_to_rect(quad, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the transformations using two arbitrary quadrangles.
|
||||
void quad_to_quad(const double* src, const double* dst)
|
||||
{
|
||||
m_trans_dir.quad_to_quad(src, dst);
|
||||
m_trans_inv.quad_to_quad(dst, src);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the direct transformations, i.e., rectangle -> quadrangle
|
||||
void rect_to_quad(double x1, double y1, double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
double src[8];
|
||||
src[0] = src[6] = x1;
|
||||
src[2] = src[4] = x2;
|
||||
src[1] = src[3] = y1;
|
||||
src[5] = src[7] = y2;
|
||||
quad_to_quad(src, quad);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the reverse transformations, i.e., quadrangle -> rectangle
|
||||
void quad_to_rect(const double* quad,
|
||||
double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dst[8];
|
||||
dst[0] = dst[6] = x1;
|
||||
dst[2] = dst[4] = x2;
|
||||
dst[1] = dst[3] = y1;
|
||||
dst[5] = dst[7] = y2;
|
||||
quad_to_quad(quad, dst);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Check if the equations were solved successfully
|
||||
bool is_valid() const { return m_trans_dir.is_valid(); }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void begin(double x, double y, unsigned len)
|
||||
{
|
||||
// Calculate transformed coordinates at x1,y1
|
||||
double xt = x;
|
||||
double yt = y;
|
||||
m_trans_dir.transform(&xt, &yt);
|
||||
int x1 = iround(xt * subpixel_scale);
|
||||
int y1 = iround(yt * subpixel_scale);
|
||||
|
||||
double dx;
|
||||
double dy;
|
||||
const double delta = 1/double(subpixel_scale);
|
||||
|
||||
// Calculate scale by X at x1,y1
|
||||
dx = xt + delta;
|
||||
dy = yt;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Calculate scale by Y at x1,y1
|
||||
dx = xt;
|
||||
dy = yt + delta;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Calculate transformed coordinates at x2,y2
|
||||
x += len;
|
||||
xt = x;
|
||||
yt = y;
|
||||
m_trans_dir.transform(&xt, &yt);
|
||||
int x2 = iround(xt * subpixel_scale);
|
||||
int y2 = iround(yt * subpixel_scale);
|
||||
|
||||
// Calculate scale by X at x2,y2
|
||||
dx = xt + delta;
|
||||
dy = yt;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Calculate scale by Y at x2,y2
|
||||
dx = xt;
|
||||
dy = yt + delta;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= x;
|
||||
dy -= y;
|
||||
int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Initialize the interpolators
|
||||
m_coord_x = dda2_line_interpolator(x1, x2, len);
|
||||
m_coord_y = dda2_line_interpolator(y1, y2, len);
|
||||
m_scale_x = dda2_line_interpolator(sx1, sx2, len);
|
||||
m_scale_y = dda2_line_interpolator(sy1, sy2, len);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void resynchronize(double xe, double ye, unsigned len)
|
||||
{
|
||||
// Assume x1,y1 are equal to the ones at the previous end point
|
||||
int x1 = m_coord_x.y();
|
||||
int y1 = m_coord_y.y();
|
||||
int sx1 = m_scale_x.y();
|
||||
int sy1 = m_scale_y.y();
|
||||
|
||||
// Calculate transformed coordinates at x2,y2
|
||||
double xt = xe;
|
||||
double yt = ye;
|
||||
m_trans_dir.transform(&xt, &yt);
|
||||
int x2 = iround(xt * subpixel_scale);
|
||||
int y2 = iround(yt * subpixel_scale);
|
||||
|
||||
const double delta = 1/double(subpixel_scale);
|
||||
double dx;
|
||||
double dy;
|
||||
|
||||
// Calculate scale by X at x2,y2
|
||||
dx = xt + delta;
|
||||
dy = yt;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= xe;
|
||||
dy -= ye;
|
||||
int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Calculate scale by Y at x2,y2
|
||||
dx = xt;
|
||||
dy = yt + delta;
|
||||
m_trans_inv.transform(&dx, &dy);
|
||||
dx -= xe;
|
||||
dy -= ye;
|
||||
int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
|
||||
|
||||
// Initialize the interpolators
|
||||
m_coord_x = dda2_line_interpolator(x1, x2, len);
|
||||
m_coord_y = dda2_line_interpolator(y1, y2, len);
|
||||
m_scale_x = dda2_line_interpolator(sx1, sx2, len);
|
||||
m_scale_y = dda2_line_interpolator(sy1, sy2, len);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++m_coord_x;
|
||||
++m_coord_y;
|
||||
++m_scale_x;
|
||||
++m_scale_y;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
*x = m_coord_x.y();
|
||||
*y = m_coord_y.y();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void local_scale(int* x, int* y)
|
||||
{
|
||||
*x = m_scale_x.y();
|
||||
*y = m_scale_y.y();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void transform(double* x, double* y) const
|
||||
{
|
||||
m_trans_dir.transform(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
trans_type m_trans_dir;
|
||||
trans_type m_trans_inv;
|
||||
dda2_line_interpolator m_coord_x;
|
||||
dda2_line_interpolator m_coord_y;
|
||||
dda2_line_interpolator m_scale_x;
|
||||
dda2_line_interpolator m_scale_y;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Horizontal span interpolator for use with an arbitrary transformer
|
||||
// The efficiency highly depends on the operations done in the transformer
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED
|
||||
#define AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//=================================================span_interpolator_trans
|
||||
template<class Transformer, unsigned SubpixelShift = 8>
|
||||
class span_interpolator_trans
|
||||
{
|
||||
public:
|
||||
typedef Transformer trans_type;
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_trans() {}
|
||||
span_interpolator_trans(trans_type& trans) : m_trans(&trans) {}
|
||||
span_interpolator_trans(trans_type& trans,
|
||||
double x, double y, unsigned) :
|
||||
m_trans(&trans)
|
||||
{
|
||||
begin(x, y, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
const trans_type& transformer() const { return *m_trans; }
|
||||
void transformer(const trans_type& trans) { m_trans = &trans; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void begin(double x, double y, unsigned)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_trans->transform(&x, &y);
|
||||
m_ix = iround(x * subpixel_scale);
|
||||
m_iy = iround(y * subpixel_scale);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
m_x += 1.0;
|
||||
double x = m_x;
|
||||
double y = m_y;
|
||||
m_trans->transform(&x, &y);
|
||||
m_ix = iround(x * subpixel_scale);
|
||||
m_iy = iround(y * subpixel_scale);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
*x = m_ix;
|
||||
*y = m_iy;
|
||||
}
|
||||
|
||||
private:
|
||||
trans_type* m_trans;
|
||||
double m_x;
|
||||
double m_y;
|
||||
int m_ix;
|
||||
int m_iy;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef AGG_SPAN_PATTERN_GRAY_INCLUDED
|
||||
#define AGG_SPAN_PATTERN_GRAY_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=======================================================span_pattern_gray
|
||||
template<class Source> class span_pattern_gray
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_pattern_gray() {}
|
||||
span_pattern_gray(source_type& src,
|
||||
unsigned offset_x, unsigned offset_y) :
|
||||
m_src(&src),
|
||||
m_offset_x(offset_x),
|
||||
m_offset_y(offset_y),
|
||||
m_alpha(color_type::base_mask)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(source_type& v) { m_src = &v; }
|
||||
source_type& source() { return *m_src; }
|
||||
const source_type& source() const { return *m_src; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void offset_x(unsigned v) { m_offset_x = v; }
|
||||
void offset_y(unsigned v) { m_offset_y = v; }
|
||||
unsigned offset_x() const { return m_offset_x; }
|
||||
unsigned offset_y() const { return m_offset_y; }
|
||||
void alpha(value_type v) { m_alpha = v; }
|
||||
value_type alpha() const { return m_alpha; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
x += m_offset_x;
|
||||
y += m_offset_y;
|
||||
const value_type* p = (const value_type*)m_src->span(x, y, len);
|
||||
do
|
||||
{
|
||||
span->v = *p;
|
||||
span->a = m_alpha;
|
||||
p = m_src->next_x();
|
||||
++span;
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
private:
|
||||
source_type* m_src;
|
||||
unsigned m_offset_x;
|
||||
unsigned m_offset_y;
|
||||
value_type m_alpha;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef AGG_SPAN_PATTERN_RGB_INCLUDED
|
||||
#define AGG_SPAN_PATTERN_RGB_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//========================================================span_pattern_rgb
|
||||
template<class Source> class span_pattern_rgb
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_pattern_rgb() {}
|
||||
span_pattern_rgb(source_type& src,
|
||||
unsigned offset_x, unsigned offset_y) :
|
||||
m_src(&src),
|
||||
m_offset_x(offset_x),
|
||||
m_offset_y(offset_y),
|
||||
m_alpha(color_type::base_mask)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(source_type& v) { m_src = &v; }
|
||||
source_type& source() { return *m_src; }
|
||||
const source_type& source() const { return *m_src; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void offset_x(unsigned v) { m_offset_x = v; }
|
||||
void offset_y(unsigned v) { m_offset_y = v; }
|
||||
unsigned offset_x() const { return m_offset_x; }
|
||||
unsigned offset_y() const { return m_offset_y; }
|
||||
void alpha(value_type v) { m_alpha = v; }
|
||||
value_type alpha() const { return m_alpha; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
x += m_offset_x;
|
||||
y += m_offset_y;
|
||||
const value_type* p = (const value_type*)m_src->span(x, y, len);
|
||||
do
|
||||
{
|
||||
span->r = p[order_type::R];
|
||||
span->g = p[order_type::G];
|
||||
span->b = p[order_type::B];
|
||||
span->a = m_alpha;
|
||||
p = m_src->next_x();
|
||||
++span;
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
private:
|
||||
source_type* m_src;
|
||||
unsigned m_offset_x;
|
||||
unsigned m_offset_y;
|
||||
value_type m_alpha;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef AGG_SPAN_PATTERN_RGBA_INCLUDED
|
||||
#define AGG_SPAN_PATTERN_RGBA_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//======================================================span_pattern_rgba
|
||||
template<class Source> class span_pattern_rgba
|
||||
{
|
||||
public:
|
||||
typedef Source source_type;
|
||||
typedef typename source_type::color_type color_type;
|
||||
typedef typename source_type::order_type order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_pattern_rgba() {}
|
||||
span_pattern_rgba(source_type& src,
|
||||
unsigned offset_x, unsigned offset_y) :
|
||||
m_src(&src),
|
||||
m_offset_x(offset_x),
|
||||
m_offset_y(offset_y)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(source_type& v) { m_src = &v; }
|
||||
source_type& source() { return *m_src; }
|
||||
const source_type& source() const { return *m_src; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void offset_x(unsigned v) { m_offset_x = v; }
|
||||
void offset_y(unsigned v) { m_offset_y = v; }
|
||||
unsigned offset_x() const { return m_offset_x; }
|
||||
unsigned offset_y() const { return m_offset_y; }
|
||||
void alpha(value_type) {}
|
||||
value_type alpha() const { return 0; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
x += m_offset_x;
|
||||
y += m_offset_y;
|
||||
const value_type* p = (const value_type*)m_src->span(x, y, len);
|
||||
do
|
||||
{
|
||||
span->r = p[order_type::R];
|
||||
span->g = p[order_type::G];
|
||||
span->b = p[order_type::B];
|
||||
span->a = p[order_type::A];
|
||||
p = (const value_type*)m_src->next_x();
|
||||
++span;
|
||||
}
|
||||
while(--len);
|
||||
}
|
||||
|
||||
private:
|
||||
source_type* m_src;
|
||||
unsigned m_offset_x;
|
||||
unsigned m_offset_y;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// span_solid_rgba8
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_SPAN_SOLID_INCLUDED
|
||||
#define AGG_SPAN_SOLID_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//--------------------------------------------------------------span_solid
|
||||
template<class ColorT> class span_solid
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void color(const color_type& c) { m_color = c; }
|
||||
const color_type& color() const { return m_color; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void prepare() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void generate(color_type* span, int x, int y, unsigned len)
|
||||
{
|
||||
do { *span++ = m_color; } while(--len);
|
||||
}
|
||||
|
||||
private:
|
||||
color_type m_color;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SPAN_SUBDIV_ADAPTOR_INCLUDED
|
||||
#define AGG_SPAN_SUBDIV_ADAPTOR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=================================================span_subdiv_adaptor
|
||||
template<class Interpolator, unsigned SubpixelShift = 8>
|
||||
class span_subdiv_adaptor
|
||||
{
|
||||
public:
|
||||
typedef Interpolator interpolator_type;
|
||||
typedef typename interpolator_type::trans_type trans_type;
|
||||
|
||||
enum sublixel_scale_e
|
||||
{
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
span_subdiv_adaptor() :
|
||||
m_subdiv_shift(4),
|
||||
m_subdiv_size(1 << m_subdiv_shift),
|
||||
m_subdiv_mask(m_subdiv_size - 1) {}
|
||||
|
||||
span_subdiv_adaptor(interpolator_type& interpolator,
|
||||
unsigned subdiv_shift = 4) :
|
||||
m_subdiv_shift(subdiv_shift),
|
||||
m_subdiv_size(1 << m_subdiv_shift),
|
||||
m_subdiv_mask(m_subdiv_size - 1),
|
||||
m_interpolator(&interpolator) {}
|
||||
|
||||
span_subdiv_adaptor(interpolator_type& interpolator,
|
||||
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_interpolator(&interpolator)
|
||||
{
|
||||
begin(x, y, len);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
const interpolator_type& interpolator() const { return *m_interpolator; }
|
||||
void interpolator(interpolator_type& intr) { m_interpolator = &intr; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
const trans_type& transformer() const
|
||||
{
|
||||
return *m_interpolator->transformer();
|
||||
}
|
||||
void transformer(const trans_type& trans)
|
||||
{
|
||||
m_interpolator->transformer(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)
|
||||
{
|
||||
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;
|
||||
m_interpolator->begin(x, y, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++(*m_interpolator);
|
||||
if(m_pos >= m_subdiv_size)
|
||||
{
|
||||
unsigned len = m_len;
|
||||
if(len > m_subdiv_size) len = m_subdiv_size;
|
||||
m_interpolator->resynchronize(double(m_src_x) / double(subpixel_scale) + len,
|
||||
m_src_y,
|
||||
len);
|
||||
m_pos = 0;
|
||||
}
|
||||
m_src_x += subpixel_scale;
|
||||
++m_pos;
|
||||
--m_len;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
m_interpolator->coordinates(x, y);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void local_scale(int* x, int* y) const
|
||||
{
|
||||
m_interpolator->local_scale(x, y);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
unsigned m_subdiv_shift;
|
||||
unsigned m_subdiv_size;
|
||||
unsigned m_subdiv_mask;
|
||||
interpolator_type* m_interpolator;
|
||||
int m_src_x;
|
||||
double m_src_y;
|
||||
unsigned m_pos;
|
||||
unsigned m_len;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Bilinear 2D transformations
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_TRANS_BILINEAR_INCLUDED
|
||||
#define AGG_TRANS_BILINEAR_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_simul_eq.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//==========================================================trans_bilinear
|
||||
class trans_bilinear
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
trans_bilinear() : m_valid(false) {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Arbitrary quadrangle transformations
|
||||
trans_bilinear(const double* src, const double* dst)
|
||||
{
|
||||
quad_to_quad(src, dst);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Direct transformations
|
||||
trans_bilinear(double x1, double y1, double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
rect_to_quad(x1, y1, x2, y2, quad);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Reverse transformations
|
||||
trans_bilinear(const double* quad,
|
||||
double x1, double y1, double x2, double y2)
|
||||
{
|
||||
quad_to_rect(quad, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the transformations using two arbitrary quadrangles.
|
||||
void quad_to_quad(const double* src, const double* dst)
|
||||
{
|
||||
double left[4][4];
|
||||
double right[4][2];
|
||||
|
||||
unsigned i;
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
unsigned ix = i * 2;
|
||||
unsigned iy = ix + 1;
|
||||
left[i][0] = 1.0;
|
||||
left[i][1] = src[ix] * src[iy];
|
||||
left[i][2] = src[ix];
|
||||
left[i][3] = src[iy];
|
||||
|
||||
right[i][0] = dst[ix];
|
||||
right[i][1] = dst[iy];
|
||||
}
|
||||
m_valid = simul_eq<4, 2>::solve(left, right, m_mtx);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the direct transformations, i.e., rectangle -> quadrangle
|
||||
void rect_to_quad(double x1, double y1, double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
double src[8];
|
||||
src[0] = src[6] = x1;
|
||||
src[2] = src[4] = x2;
|
||||
src[1] = src[3] = y1;
|
||||
src[5] = src[7] = y2;
|
||||
quad_to_quad(src, quad);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Set the reverse transformations, i.e., quadrangle -> rectangle
|
||||
void quad_to_rect(const double* quad,
|
||||
double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dst[8];
|
||||
dst[0] = dst[6] = x1;
|
||||
dst[2] = dst[4] = x2;
|
||||
dst[1] = dst[3] = y1;
|
||||
dst[5] = dst[7] = y2;
|
||||
quad_to_quad(quad, dst);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Check if the equations were solved successfully
|
||||
bool is_valid() const { return m_valid; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Transform a point (x, y)
|
||||
void transform(double* x, double* y) const
|
||||
{
|
||||
double tx = *x;
|
||||
double ty = *y;
|
||||
double xy = tx * ty;
|
||||
*x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty;
|
||||
*y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class iterator_x
|
||||
{
|
||||
double inc_x;
|
||||
double inc_y;
|
||||
|
||||
public:
|
||||
double x;
|
||||
double y;
|
||||
|
||||
iterator_x() {}
|
||||
iterator_x(double tx, double ty, double step, const double m[4][2]) :
|
||||
inc_x(m[1][0] * step * ty + m[2][0] * step),
|
||||
inc_y(m[1][1] * step * ty + m[2][1] * step),
|
||||
x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty),
|
||||
y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty)
|
||||
{
|
||||
}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
x += inc_x;
|
||||
y += inc_y;
|
||||
}
|
||||
};
|
||||
|
||||
iterator_x begin(double x, double y, double step) const
|
||||
{
|
||||
return iterator_x(x, y, step, m_mtx);
|
||||
}
|
||||
|
||||
private:
|
||||
double m_mtx[4][2];
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_TRANS_DOUBLE_PATH_INCLUDED
|
||||
#define AGG_TRANS_DOUBLE_PATH_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
// See also: agg_trans_double_path.cpp
|
||||
//
|
||||
//-------------------------------------------------------trans_double_path
|
||||
class trans_double_path
|
||||
{
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
making_path,
|
||||
ready
|
||||
};
|
||||
|
||||
public:
|
||||
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
|
||||
|
||||
trans_double_path();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void base_length(double v) { m_base_length = v; }
|
||||
double base_length() const { return m_base_length; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void base_height(double v) { m_base_height = v; }
|
||||
double base_height() const { return m_base_height; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void preserve_x_scale(bool f) { m_preserve_x_scale = f; }
|
||||
bool preserve_x_scale() const { return m_preserve_x_scale; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset();
|
||||
void move_to1(double x, double y);
|
||||
void line_to1(double x, double y);
|
||||
void move_to2(double x, double y);
|
||||
void line_to2(double x, double y);
|
||||
void finalize_paths();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class VertexSource1, class VertexSource2>
|
||||
void add_paths(VertexSource1& vs1, VertexSource2& vs2,
|
||||
unsigned path1_id=0, unsigned path2_id=0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
unsigned cmd;
|
||||
|
||||
vs1.rewind(path1_id);
|
||||
while(!is_stop(cmd = vs1.vertex(&x, &y)))
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
move_to1(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
line_to1(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vs2.rewind(path2_id);
|
||||
while(!is_stop(cmd = vs2.vertex(&x, &y)))
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
move_to2(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
line_to2(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
finalize_paths();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double total_length1() const;
|
||||
double total_length2() const;
|
||||
void transform(double *x, double *y) const;
|
||||
|
||||
private:
|
||||
double finalize_path(vertex_storage& vertices);
|
||||
void transform1(const vertex_storage& vertices,
|
||||
double kindex, double kx,
|
||||
double *x, double* y) const;
|
||||
|
||||
vertex_storage m_src_vertices1;
|
||||
vertex_storage m_src_vertices2;
|
||||
double m_base_length;
|
||||
double m_base_height;
|
||||
double m_kindex1;
|
||||
double m_kindex2;
|
||||
status_e m_status1;
|
||||
status_e m_status2;
|
||||
bool m_preserve_x_scale;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,731 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Perspective 2D transformations
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_TRANS_PERSPECTIVE_INCLUDED
|
||||
#define AGG_TRANS_PERSPECTIVE_INCLUDED
|
||||
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//=======================================================trans_perspective
|
||||
struct trans_perspective
|
||||
{
|
||||
double sx, shy, w0, shx, sy, w1, tx, ty, w2;
|
||||
|
||||
//------------------------------------------------------- Construction
|
||||
// Identity matrix
|
||||
trans_perspective() :
|
||||
sx (1), shy(0), w0(0),
|
||||
shx(0), sy (1), w1(0),
|
||||
tx (0), ty (0), w2(1) {}
|
||||
|
||||
// Custom matrix
|
||||
trans_perspective(double v0, double v1, double v2,
|
||||
double v3, double v4, double v5,
|
||||
double v6, double v7, double v8) :
|
||||
sx (v0), shy(v1), w0(v2),
|
||||
shx(v3), sy (v4), w1(v5),
|
||||
tx (v6), ty (v7), w2(v8) {}
|
||||
|
||||
// Custom matrix from m[9]
|
||||
explicit trans_perspective(const double* m) :
|
||||
sx (m[0]), shy(m[1]), w0(m[2]),
|
||||
shx(m[3]), sy (m[4]), w1(m[5]),
|
||||
tx (m[6]), ty (m[7]), w2(m[8]) {}
|
||||
|
||||
// From affine
|
||||
explicit trans_perspective(const trans_affine& a) :
|
||||
sx (a.sx ), shy(a.shy), w0(0),
|
||||
shx(a.shx), sy (a.sy ), w1(0),
|
||||
tx (a.tx ), ty (a.ty ), w2(1) {}
|
||||
|
||||
// Rectangle to quadrilateral
|
||||
trans_perspective(double x1, double y1, double x2, double y2,
|
||||
const double* quad);
|
||||
|
||||
// Quadrilateral to rectangle
|
||||
trans_perspective(const double* quad,
|
||||
double x1, double y1, double x2, double y2);
|
||||
|
||||
// Arbitrary quadrilateral transformations
|
||||
trans_perspective(const double* src, const double* dst);
|
||||
|
||||
//-------------------------------------- Quadrilateral transformations
|
||||
// The arguments are double[8] that are mapped to quadrilaterals:
|
||||
// x1,y1, x2,y2, x3,y3, x4,y4
|
||||
bool quad_to_quad(const double* qs, const double* qd);
|
||||
|
||||
bool rect_to_quad(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* q);
|
||||
|
||||
bool quad_to_rect(const double* q,
|
||||
double x1, double y1,
|
||||
double x2, double y2);
|
||||
|
||||
// Map square (0,0,1,1) to the quadrilateral and vice versa
|
||||
bool square_to_quad(const double* q);
|
||||
bool quad_to_square(const double* q);
|
||||
|
||||
|
||||
//--------------------------------------------------------- Operations
|
||||
// Reset - load an identity matrix
|
||||
const trans_perspective& reset();
|
||||
|
||||
// Invert matrix. Returns false in degenerate case
|
||||
bool invert();
|
||||
|
||||
// Direct transformations operations
|
||||
const trans_perspective& translate(double x, double y);
|
||||
const trans_perspective& rotate(double a);
|
||||
const trans_perspective& scale(double s);
|
||||
const trans_perspective& scale(double x, double y);
|
||||
|
||||
// Multiply the matrix by another one
|
||||
const trans_perspective& multiply(const trans_perspective& m);
|
||||
|
||||
// Multiply "m" by "this" and assign the result to "this"
|
||||
const trans_perspective& premultiply(const trans_perspective& m);
|
||||
|
||||
// Multiply matrix to inverse of another one
|
||||
const trans_perspective& multiply_inv(const trans_perspective& m);
|
||||
|
||||
// Multiply inverse of "m" by "this" and assign the result to "this"
|
||||
const trans_perspective& premultiply_inv(const trans_perspective& m);
|
||||
|
||||
// Multiply the matrix by another one
|
||||
const trans_perspective& multiply(const trans_affine& m);
|
||||
|
||||
// Multiply "m" by "this" and assign the result to "this"
|
||||
const trans_perspective& premultiply(const trans_affine& m);
|
||||
|
||||
// Multiply the matrix by inverse of another one
|
||||
const trans_perspective& multiply_inv(const trans_affine& m);
|
||||
|
||||
// Multiply inverse of "m" by "this" and assign the result to "this"
|
||||
const trans_perspective& premultiply_inv(const trans_affine& m);
|
||||
|
||||
//--------------------------------------------------------- Load/Store
|
||||
void store_to(double* m) const;
|
||||
const trans_perspective& load_from(const double* m);
|
||||
|
||||
//---------------------------------------------------------- Operators
|
||||
// Multiply the matrix by another one
|
||||
const trans_perspective& operator *= (const trans_perspective& m)
|
||||
{
|
||||
return multiply(m);
|
||||
}
|
||||
const trans_perspective& operator *= (const trans_affine& m)
|
||||
{
|
||||
return multiply(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by inverse of another one
|
||||
const trans_perspective& operator /= (const trans_perspective& m)
|
||||
{
|
||||
return multiply_inv(m);
|
||||
}
|
||||
const trans_perspective& operator /= (const trans_affine& m)
|
||||
{
|
||||
return multiply_inv(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by another one and return
|
||||
// the result in a separete matrix.
|
||||
trans_perspective operator * (const trans_perspective& m) const
|
||||
{
|
||||
return trans_perspective(*this).multiply(m);
|
||||
}
|
||||
trans_perspective operator * (const trans_affine& m) const
|
||||
{
|
||||
return trans_perspective(*this).multiply(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by inverse of another one
|
||||
// and return the result in a separete matrix.
|
||||
trans_perspective operator / (const trans_perspective& m) const
|
||||
{
|
||||
return trans_perspective(*this).multiply_inv(m);
|
||||
}
|
||||
trans_perspective operator / (const trans_affine& m) const
|
||||
{
|
||||
return trans_perspective(*this).multiply_inv(m);
|
||||
}
|
||||
|
||||
// Calculate and return the inverse matrix
|
||||
trans_perspective operator ~ () const
|
||||
{
|
||||
trans_perspective ret = *this;
|
||||
ret.invert();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Equal operator with default epsilon
|
||||
bool operator == (const trans_perspective& m) const
|
||||
{
|
||||
return is_equal(m, affine_epsilon);
|
||||
}
|
||||
|
||||
// Not Equal operator with default epsilon
|
||||
bool operator != (const trans_perspective& m) const
|
||||
{
|
||||
return !is_equal(m, affine_epsilon);
|
||||
}
|
||||
|
||||
//---------------------------------------------------- Transformations
|
||||
// Direct transformation of x and y
|
||||
void transform(double* x, double* y) const;
|
||||
|
||||
// Direct transformation of x and y, affine part only
|
||||
void transform_affine(double* x, double* y) const;
|
||||
|
||||
// Direct transformation of x and y, 2x2 matrix only, no translation
|
||||
void transform_2x2(double* x, double* y) const;
|
||||
|
||||
// Inverse transformation of x and y. It works slow because
|
||||
// it explicitly inverts the matrix on every call. For massive
|
||||
// operations it's better to invert() the matrix and then use
|
||||
// direct transformations.
|
||||
void inverse_transform(double* x, double* y) const;
|
||||
|
||||
|
||||
//---------------------------------------------------------- Auxiliary
|
||||
const trans_perspective& from_affine(const trans_affine& a);
|
||||
double determinant() const;
|
||||
double determinant_reciprocal() const;
|
||||
|
||||
bool is_valid(double epsilon = affine_epsilon) const;
|
||||
bool is_identity(double epsilon = affine_epsilon) const;
|
||||
bool is_equal(const trans_perspective& m,
|
||||
double epsilon = affine_epsilon) const;
|
||||
|
||||
// Determine the major affine parameters. Use with caution
|
||||
// considering possible degenerate cases.
|
||||
double scale() const;
|
||||
double rotation() const;
|
||||
void translation(double* dx, double* dy) const;
|
||||
void scaling(double* x, double* y) const;
|
||||
void scaling_abs(double* x, double* y) const;
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class iterator_x
|
||||
{
|
||||
double den;
|
||||
double den_step;
|
||||
double nom_x;
|
||||
double nom_x_step;
|
||||
double nom_y;
|
||||
double nom_y_step;
|
||||
|
||||
public:
|
||||
double x;
|
||||
double y;
|
||||
|
||||
iterator_x() {}
|
||||
iterator_x(double px, double py, double step, const trans_perspective& m) :
|
||||
den(px * m.w0 + py * m.w1 + m.w2),
|
||||
den_step(m.w0 * step),
|
||||
nom_x(px * m.sx + py * m.shx + m.tx),
|
||||
nom_x_step(step * m.sx),
|
||||
nom_y(px * m.shy + py * m.sy + m.ty),
|
||||
nom_y_step(step * m.shy),
|
||||
x(nom_x / den),
|
||||
y(nom_y / den)
|
||||
{}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
den += den_step;
|
||||
nom_x += nom_x_step;
|
||||
nom_y += nom_y_step;
|
||||
double d = 1.0 / den;
|
||||
x = nom_x * d;
|
||||
y = nom_y * d;
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
iterator_x begin(double x, double y, double step) const
|
||||
{
|
||||
return iterator_x(x, y, step, *this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::square_to_quad(const double* q)
|
||||
{
|
||||
double dx = q[0] - q[2] + q[4] - q[6];
|
||||
double dy = q[1] - q[3] + q[5] - q[7];
|
||||
if(dx == 0.0 && dy == 0.0)
|
||||
{
|
||||
// Affine case (parallelogram)
|
||||
//---------------
|
||||
sx = q[2] - q[0];
|
||||
shy = q[3] - q[1];
|
||||
w0 = 0.0;
|
||||
shx = q[4] - q[2];
|
||||
sy = q[5] - q[3];
|
||||
w1 = 0.0;
|
||||
tx = q[0];
|
||||
ty = q[1];
|
||||
w2 = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double dx1 = q[2] - q[4];
|
||||
double dy1 = q[3] - q[5];
|
||||
double dx2 = q[6] - q[4];
|
||||
double dy2 = q[7] - q[5];
|
||||
double den = dx1 * dy2 - dx2 * dy1;
|
||||
if(den == 0.0)
|
||||
{
|
||||
// Singular case
|
||||
//---------------
|
||||
sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0;
|
||||
return false;
|
||||
}
|
||||
// General case
|
||||
//---------------
|
||||
double u = (dx * dy2 - dy * dx2) / den;
|
||||
double v = (dy * dx1 - dx * dy1) / den;
|
||||
sx = q[2] - q[0] + u * q[2];
|
||||
shy = q[3] - q[1] + u * q[3];
|
||||
w0 = u;
|
||||
shx = q[6] - q[0] + v * q[6];
|
||||
sy = q[7] - q[1] + v * q[7];
|
||||
w1 = v;
|
||||
tx = q[0];
|
||||
ty = q[1];
|
||||
w2 = 1.0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::invert()
|
||||
{
|
||||
double d0 = sy * w2 - w1 * ty;
|
||||
double d1 = w0 * ty - shy * w2;
|
||||
double d2 = shy * w1 - w0 * sy;
|
||||
double d = sx * d0 + shx * d1 + tx * d2;
|
||||
if(d == 0.0)
|
||||
{
|
||||
sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0;
|
||||
return false;
|
||||
}
|
||||
d = 1.0 / d;
|
||||
trans_perspective a = *this;
|
||||
sx = d * d0;
|
||||
shy = d * d1;
|
||||
w0 = d * d2;
|
||||
shx = d * (a.w1 *a.tx - a.shx*a.w2);
|
||||
sy = d * (a.sx *a.w2 - a.w0 *a.tx);
|
||||
w1 = d * (a.w0 *a.shx - a.sx *a.w1);
|
||||
tx = d * (a.shx*a.ty - a.sy *a.tx);
|
||||
ty = d * (a.shy*a.tx - a.sx *a.ty);
|
||||
w2 = d * (a.sx *a.sy - a.shy*a.shx);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::quad_to_square(const double* q)
|
||||
{
|
||||
if(!square_to_quad(q)) return false;
|
||||
invert();
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::quad_to_quad(const double* qs,
|
||||
const double* qd)
|
||||
{
|
||||
trans_perspective p;
|
||||
if(! quad_to_square(qs)) return false;
|
||||
if(!p.square_to_quad(qd)) return false;
|
||||
multiply(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::rect_to_quad(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* q)
|
||||
{
|
||||
double r[8];
|
||||
r[0] = r[6] = x1;
|
||||
r[2] = r[4] = x2;
|
||||
r[1] = r[3] = y1;
|
||||
r[5] = r[7] = y2;
|
||||
return quad_to_quad(r, q);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::quad_to_rect(const double* q,
|
||||
double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
double r[8];
|
||||
r[0] = r[6] = x1;
|
||||
r[2] = r[4] = x2;
|
||||
r[1] = r[3] = y1;
|
||||
r[5] = r[7] = y2;
|
||||
return quad_to_quad(q, r);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline trans_perspective::trans_perspective(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
rect_to_quad(x1, y1, x2, y2, quad);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline trans_perspective::trans_perspective(const double* quad,
|
||||
double x1, double y1,
|
||||
double x2, double y2)
|
||||
{
|
||||
quad_to_rect(quad, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline trans_perspective::trans_perspective(const double* src,
|
||||
const double* dst)
|
||||
{
|
||||
quad_to_quad(src, dst);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective& trans_perspective::reset()
|
||||
{
|
||||
sx = 1; shy = 0; w0 = 0;
|
||||
shx = 0; sy = 1; w1 = 0;
|
||||
tx = 0; ty = 0; w2 = 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective&
|
||||
trans_perspective::multiply(const trans_perspective& a)
|
||||
{
|
||||
trans_perspective b = *this;
|
||||
sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0;
|
||||
shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1;
|
||||
tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2;
|
||||
shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0;
|
||||
sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1;
|
||||
ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2;
|
||||
w0 = a.w0 *b.sx + a.w1 *b.shy + a.w2*b.w0;
|
||||
w1 = a.w0 *b.shx + a.w1 *b.sy + a.w2*b.w1;
|
||||
w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2*b.w2;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective&
|
||||
trans_perspective::multiply(const trans_affine& a)
|
||||
{
|
||||
trans_perspective b = *this;
|
||||
sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0;
|
||||
shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1;
|
||||
tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2;
|
||||
shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0;
|
||||
sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1;
|
||||
ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective&
|
||||
trans_perspective::premultiply(const trans_perspective& b)
|
||||
{
|
||||
trans_perspective a = *this;
|
||||
sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0;
|
||||
shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1;
|
||||
tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2;
|
||||
shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0;
|
||||
sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1;
|
||||
ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2;
|
||||
w0 = a.w0 *b.sx + a.w1 *b.shy + a.w2*b.w0;
|
||||
w1 = a.w0 *b.shx + a.w1 *b.sy + a.w2*b.w1;
|
||||
w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2*b.w2;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective&
|
||||
trans_perspective::premultiply(const trans_affine& b)
|
||||
{
|
||||
trans_perspective a = *this;
|
||||
sx = a.sx *b.sx + a.shx*b.shy;
|
||||
shx = a.sx *b.shx + a.shx*b.sy;
|
||||
tx = a.sx *b.tx + a.shx*b.ty + a.tx;
|
||||
shy = a.shy*b.sx + a.sy *b.shy;
|
||||
sy = a.shy*b.shx + a.sy *b.sy;
|
||||
ty = a.shy*b.tx + a.sy *b.ty + a.ty;
|
||||
w0 = a.w0 *b.sx + a.w1 *b.shy;
|
||||
w1 = a.w0 *b.shx + a.w1 *b.sy;
|
||||
w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const trans_perspective&
|
||||
trans_perspective::multiply_inv(const trans_perspective& m)
|
||||
{
|
||||
trans_perspective t = m;
|
||||
t.invert();
|
||||
return multiply(t);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const trans_perspective&
|
||||
trans_perspective::multiply_inv(const trans_affine& m)
|
||||
{
|
||||
trans_affine t = m;
|
||||
t.invert();
|
||||
return multiply(t);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const trans_perspective&
|
||||
trans_perspective::premultiply_inv(const trans_perspective& m)
|
||||
{
|
||||
trans_perspective t = m;
|
||||
t.invert();
|
||||
return *this = t.multiply(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const trans_perspective&
|
||||
trans_perspective::premultiply_inv(const trans_affine& m)
|
||||
{
|
||||
trans_perspective t(m);
|
||||
t.invert();
|
||||
return *this = t.multiply(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective&
|
||||
trans_perspective::translate(double x, double y)
|
||||
{
|
||||
tx += x;
|
||||
ty += y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective& trans_perspective::rotate(double a)
|
||||
{
|
||||
multiply(trans_affine_rotation(a));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective& trans_perspective::scale(double s)
|
||||
{
|
||||
multiply(trans_affine_scaling(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective& trans_perspective::scale(double x, double y)
|
||||
{
|
||||
multiply(trans_affine_scaling(x, y));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_perspective::transform(double* px, double* py) const
|
||||
{
|
||||
double x = *px;
|
||||
double y = *py;
|
||||
double m = 1.0 / (x*w0 + y*w1 + w2);
|
||||
*px = m * (x*sx + y*shx + tx);
|
||||
*py = m * (x*shy + y*sy + ty);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_perspective::transform_affine(double* x, double* y) const
|
||||
{
|
||||
double tmp = *x;
|
||||
*x = tmp * sx + *y * shx + tx;
|
||||
*y = tmp * shy + *y * sy + ty;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_perspective::transform_2x2(double* x, double* y) const
|
||||
{
|
||||
double tmp = *x;
|
||||
*x = tmp * sx + *y * shx;
|
||||
*y = tmp * shy + *y * sy;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_perspective::inverse_transform(double* x, double* y) const
|
||||
{
|
||||
trans_perspective t(*this);
|
||||
if(t.invert()) t.transform(x, y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_perspective::store_to(double* m) const
|
||||
{
|
||||
*m++ = sx; *m++ = shy; *m++ = w0;
|
||||
*m++ = shx; *m++ = sy; *m++ = w1;
|
||||
*m++ = tx; *m++ = ty; *m++ = w2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective& trans_perspective::load_from(const double* m)
|
||||
{
|
||||
sx = *m++; shy = *m++; w0 = *m++;
|
||||
shx = *m++; sy = *m++; w1 = *m++;
|
||||
tx = *m++; ty = *m++; w2 = *m++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_perspective&
|
||||
trans_perspective::from_affine(const trans_affine& a)
|
||||
{
|
||||
sx = a.sx; shy = a.shy; w0 = 0;
|
||||
shx = a.shx; sy = a.sy; w1 = 0;
|
||||
tx = a.tx; ty = a.ty; w2 = 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline double trans_perspective::determinant() const
|
||||
{
|
||||
return sx * (sy * w2 - ty * w1) +
|
||||
shx * (ty * w0 - shy * w2) +
|
||||
tx * (shy * w1 - sy * w0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline double trans_perspective::determinant_reciprocal() const
|
||||
{
|
||||
return 1.0 / determinant();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::is_valid(double epsilon) const
|
||||
{
|
||||
return fabs(sx) > epsilon && fabs(sy) > epsilon && fabs(w2) > epsilon;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::is_identity(double epsilon) const
|
||||
{
|
||||
return is_equal_eps(sx, 1.0, epsilon) &&
|
||||
is_equal_eps(shy, 0.0, epsilon) &&
|
||||
is_equal_eps(w0, 0.0, epsilon) &&
|
||||
is_equal_eps(shx, 0.0, epsilon) &&
|
||||
is_equal_eps(sy, 1.0, epsilon) &&
|
||||
is_equal_eps(w1, 0.0, epsilon) &&
|
||||
is_equal_eps(tx, 0.0, epsilon) &&
|
||||
is_equal_eps(ty, 0.0, epsilon) &&
|
||||
is_equal_eps(w2, 1.0, epsilon);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool trans_perspective::is_equal(const trans_perspective& m,
|
||||
double epsilon) const
|
||||
{
|
||||
return is_equal_eps(sx, m.sx, epsilon) &&
|
||||
is_equal_eps(shy, m.shy, epsilon) &&
|
||||
is_equal_eps(w0, m.w0, epsilon) &&
|
||||
is_equal_eps(shx, m.shx, epsilon) &&
|
||||
is_equal_eps(sy, m.sy, epsilon) &&
|
||||
is_equal_eps(w1, m.w1, epsilon) &&
|
||||
is_equal_eps(tx, m.tx, epsilon) &&
|
||||
is_equal_eps(ty, m.ty, epsilon) &&
|
||||
is_equal_eps(w2, m.w2, epsilon);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline double trans_perspective::scale() const
|
||||
{
|
||||
double x = 0.707106781 * sx + 0.707106781 * shx;
|
||||
double y = 0.707106781 * shy + 0.707106781 * sy;
|
||||
return sqrt(x*x + y*y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline double trans_perspective::rotation() const
|
||||
{
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x2 = 1.0;
|
||||
double y2 = 0.0;
|
||||
transform(&x1, &y1);
|
||||
transform(&x2, &y2);
|
||||
return atan2(y2-y1, x2-x1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void trans_perspective::translation(double* dx, double* dy) const
|
||||
{
|
||||
*dx = tx;
|
||||
*dy = ty;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void trans_perspective::scaling(double* x, double* y) const
|
||||
{
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x2 = 1.0;
|
||||
double y2 = 1.0;
|
||||
trans_perspective t(*this);
|
||||
t *= trans_affine_rotation(-rotation());
|
||||
t.transform(&x1, &y1);
|
||||
t.transform(&x2, &y2);
|
||||
*x = x2 - x1;
|
||||
*y = y2 - y1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void trans_perspective::scaling_abs(double* x, double* y) const
|
||||
{
|
||||
*x = sqrt(sx * sx + shx * shx);
|
||||
*y = sqrt(shy * shy + sy * sy);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_TRANS_SINGLE_PATH_INCLUDED
|
||||
#define AGG_TRANS_SINGLE_PATH_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
// See also: agg_trans_single_path.cpp
|
||||
//
|
||||
//-------------------------------------------------------trans_single_path
|
||||
class trans_single_path
|
||||
{
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
making_path,
|
||||
ready
|
||||
};
|
||||
|
||||
public:
|
||||
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
|
||||
|
||||
trans_single_path();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void base_length(double v) { m_base_length = v; }
|
||||
double base_length() const { return m_base_length; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void preserve_x_scale(bool f) { m_preserve_x_scale = f; }
|
||||
bool preserve_x_scale() const { return m_preserve_x_scale; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset();
|
||||
void move_to(double x, double y);
|
||||
void line_to(double x, double y);
|
||||
void finalize_path();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
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)))
|
||||
{
|
||||
if(is_move_to(cmd))
|
||||
{
|
||||
move_to(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
line_to(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
finalize_path();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
double total_length() const;
|
||||
void transform(double *x, double *y) const;
|
||||
|
||||
private:
|
||||
vertex_storage m_src_vertices;
|
||||
double m_base_length;
|
||||
double m_kindex;
|
||||
status_e m_status;
|
||||
bool m_preserve_x_scale;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Viewport transformer - simple orthogonal conversions from world coordinates
|
||||
// to screen (device) ones.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_TRANS_VIEWPORT_INCLUDED
|
||||
#define AGG_TRANS_VIEWPORT_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
enum aspect_ratio_e
|
||||
{
|
||||
aspect_ratio_stretch,
|
||||
aspect_ratio_meet,
|
||||
aspect_ratio_slice
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------trans_viewport
|
||||
class trans_viewport
|
||||
{
|
||||
public:
|
||||
//-------------------------------------------------------------------
|
||||
trans_viewport() :
|
||||
m_world_x1(0.0),
|
||||
m_world_y1(0.0),
|
||||
m_world_x2(1.0),
|
||||
m_world_y2(1.0),
|
||||
m_device_x1(0.0),
|
||||
m_device_y1(0.0),
|
||||
m_device_x2(1.0),
|
||||
m_device_y2(1.0),
|
||||
m_aspect(aspect_ratio_stretch),
|
||||
m_is_valid(true),
|
||||
m_align_x(0.5),
|
||||
m_align_y(0.5),
|
||||
m_wx1(0.0),
|
||||
m_wy1(0.0),
|
||||
m_wx2(1.0),
|
||||
m_wy2(1.0),
|
||||
m_dx1(0.0),
|
||||
m_dy1(0.0),
|
||||
m_kx(1.0),
|
||||
m_ky(1.0)
|
||||
{}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void preserve_aspect_ratio(double alignx,
|
||||
double aligny,
|
||||
aspect_ratio_e aspect)
|
||||
{
|
||||
m_align_x = alignx;
|
||||
m_align_y = aligny;
|
||||
m_aspect = aspect;
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void device_viewport(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
m_device_x1 = x1;
|
||||
m_device_y1 = y1;
|
||||
m_device_x2 = x2;
|
||||
m_device_y2 = y2;
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void world_viewport(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
m_world_x1 = x1;
|
||||
m_world_y1 = y1;
|
||||
m_world_x2 = x2;
|
||||
m_world_y2 = y2;
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void device_viewport(double* x1, double* y1, double* x2, double* y2) const
|
||||
{
|
||||
*x1 = m_device_x1;
|
||||
*y1 = m_device_y1;
|
||||
*x2 = m_device_x2;
|
||||
*y2 = m_device_y2;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void world_viewport(double* x1, double* y1, double* x2, double* y2) const
|
||||
{
|
||||
*x1 = m_world_x1;
|
||||
*y1 = m_world_y1;
|
||||
*x2 = m_world_x2;
|
||||
*y2 = m_world_y2;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void world_viewport_actual(double* x1, double* y1,
|
||||
double* x2, double* y2) const
|
||||
{
|
||||
*x1 = m_wx1;
|
||||
*y1 = m_wy1;
|
||||
*x2 = m_wx2;
|
||||
*y2 = m_wy2;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
bool is_valid() const { return m_is_valid; }
|
||||
double align_x() const { return m_align_x; }
|
||||
double align_y() const { return m_align_y; }
|
||||
aspect_ratio_e aspect_ratio() const { return m_aspect; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void transform(double* x, double* y) const
|
||||
{
|
||||
*x = (*x - m_wx1) * m_kx + m_dx1;
|
||||
*y = (*y - m_wy1) * m_ky + m_dy1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void transform_scale_only(double* x, double* y) const
|
||||
{
|
||||
*x *= m_kx;
|
||||
*y *= m_ky;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void inverse_transform(double* x, double* y) const
|
||||
{
|
||||
*x = (*x - m_dx1) / m_kx + m_wx1;
|
||||
*y = (*y - m_dy1) / m_ky + m_wy1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
void inverse_transform_scale_only(double* x, double* y) const
|
||||
{
|
||||
*x /= m_kx;
|
||||
*y /= m_ky;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
double device_dx() const { return m_dx1 - m_wx1 * m_kx; }
|
||||
double device_dy() const { return m_dy1 - m_wy1 * m_ky; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
double scale_x() const
|
||||
{
|
||||
return m_kx;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
double scale_y() const
|
||||
{
|
||||
return m_ky;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
double scale() const
|
||||
{
|
||||
return (m_kx + m_ky) * 0.5;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
trans_affine to_affine() const
|
||||
{
|
||||
trans_affine mtx = trans_affine_translation(-m_wx1, -m_wy1);
|
||||
mtx *= trans_affine_scaling(m_kx, m_ky);
|
||||
mtx *= trans_affine_translation(m_dx1, m_dy1);
|
||||
return mtx;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
trans_affine to_affine_scale_only() const
|
||||
{
|
||||
return trans_affine_scaling(m_kx, m_ky);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
unsigned byte_size() const
|
||||
{
|
||||
return sizeof(*this);
|
||||
}
|
||||
|
||||
void serialize(int8u* ptr) const
|
||||
{
|
||||
memcpy(ptr, this, sizeof(*this));
|
||||
}
|
||||
|
||||
void deserialize(const int8u* ptr)
|
||||
{
|
||||
memcpy(this, ptr, sizeof(*this));
|
||||
}
|
||||
|
||||
private:
|
||||
void update();
|
||||
|
||||
double m_world_x1;
|
||||
double m_world_y1;
|
||||
double m_world_x2;
|
||||
double m_world_y2;
|
||||
double m_device_x1;
|
||||
double m_device_y1;
|
||||
double m_device_x2;
|
||||
double m_device_y2;
|
||||
aspect_ratio_e m_aspect;
|
||||
bool m_is_valid;
|
||||
double m_align_x;
|
||||
double m_align_y;
|
||||
double m_wx1;
|
||||
double m_wy1;
|
||||
double m_wx2;
|
||||
double m_wy2;
|
||||
double m_dx1;
|
||||
double m_dy1;
|
||||
double m_kx;
|
||||
double m_ky;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
inline void trans_viewport::update()
|
||||
{
|
||||
const double epsilon = 1e-30;
|
||||
if(fabs(m_world_x1 - m_world_x2) < epsilon ||
|
||||
fabs(m_world_y1 - m_world_y2) < epsilon ||
|
||||
fabs(m_device_x1 - m_device_x2) < epsilon ||
|
||||
fabs(m_device_y1 - m_device_y2) < epsilon)
|
||||
{
|
||||
m_wx1 = m_world_x1;
|
||||
m_wy1 = m_world_y1;
|
||||
m_wx2 = m_world_x1 + 1.0;
|
||||
m_wy2 = m_world_y2 + 1.0;
|
||||
m_dx1 = m_device_x1;
|
||||
m_dy1 = m_device_y1;
|
||||
m_kx = 1.0;
|
||||
m_ky = 1.0;
|
||||
m_is_valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
double world_x1 = m_world_x1;
|
||||
double world_y1 = m_world_y1;
|
||||
double world_x2 = m_world_x2;
|
||||
double world_y2 = m_world_y2;
|
||||
double device_x1 = m_device_x1;
|
||||
double device_y1 = m_device_y1;
|
||||
double device_x2 = m_device_x2;
|
||||
double device_y2 = m_device_y2;
|
||||
if(m_aspect != aspect_ratio_stretch)
|
||||
{
|
||||
double d;
|
||||
m_kx = (device_x2 - device_x1) / (world_x2 - world_x1);
|
||||
m_ky = (device_y2 - device_y1) / (world_y2 - world_y1);
|
||||
|
||||
if((m_aspect == aspect_ratio_meet) == (m_kx < m_ky))
|
||||
{
|
||||
d = (world_y2 - world_y1) * m_ky / m_kx;
|
||||
world_y1 += (world_y2 - world_y1 - d) * m_align_y;
|
||||
world_y2 = world_y1 + d;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = (world_x2 - world_x1) * m_kx / m_ky;
|
||||
world_x1 += (world_x2 - world_x1 - d) * m_align_x;
|
||||
world_x2 = world_x1 + d;
|
||||
}
|
||||
}
|
||||
m_wx1 = world_x1;
|
||||
m_wy1 = world_y1;
|
||||
m_wx2 = world_x2;
|
||||
m_wy2 = world_y2;
|
||||
m_dx1 = device_x1;
|
||||
m_dy1 = device_y1;
|
||||
m_kx = (device_x2 - device_x1) / (world_x2 - world_x1);
|
||||
m_ky = (device_y2 - device_y1) / (world_y2 - world_y1);
|
||||
m_is_valid = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_WARP_MAGNIFIER_INCLUDED
|
||||
#define AGG_WARP_MAGNIFIER_INCLUDED
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//----------------------------------------------------trans_warp_magnifier
|
||||
//
|
||||
// See Inmplementation agg_trans_warp_magnifier.cpp
|
||||
//
|
||||
class trans_warp_magnifier
|
||||
{
|
||||
public:
|
||||
trans_warp_magnifier() : m_xc(0.0), m_yc(0.0), m_magn(1.0), m_radius(1.0) {}
|
||||
|
||||
void center(double x, double y) { m_xc = x; m_yc = y; }
|
||||
void magnification(double m) { m_magn = m; }
|
||||
void radius(double r) { m_radius = r; }
|
||||
|
||||
double xc() const { return m_xc; }
|
||||
double yc() const { return m_yc; }
|
||||
double magnification() const { return m_magn; }
|
||||
double radius() const { return m_radius; }
|
||||
|
||||
void transform(double* x, double* y) const;
|
||||
void inverse_transform(double* x, double* y) const;
|
||||
|
||||
private:
|
||||
double m_xc;
|
||||
double m_yc;
|
||||
double m_magn;
|
||||
double m_radius;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_VCGEN_BSPLINE_INCLUDED
|
||||
#define AGG_VCGEN_BSPLINE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_array.h"
|
||||
#include "agg_bspline.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//==========================================================vcgen_bspline
|
||||
class vcgen_bspline
|
||||
{
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
ready,
|
||||
polygon,
|
||||
end_poly,
|
||||
stop
|
||||
};
|
||||
|
||||
public:
|
||||
typedef pod_bvector<point_d, 6> vertex_storage;
|
||||
|
||||
vcgen_bspline();
|
||||
|
||||
void interpolation_step(double v) { m_interpolation_step = v; }
|
||||
double interpolation_step() const { return m_interpolation_step; }
|
||||
|
||||
// Vertex Generator Interface
|
||||
void remove_all();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
vcgen_bspline(const vcgen_bspline&);
|
||||
const vcgen_bspline& operator = (const vcgen_bspline&);
|
||||
|
||||
vertex_storage m_src_vertices;
|
||||
bspline m_spline_x;
|
||||
bspline m_spline_y;
|
||||
double m_interpolation_step;
|
||||
unsigned m_closed;
|
||||
status_e m_status;
|
||||
unsigned m_src_vertex;
|
||||
double m_cur_abscissa;
|
||||
double m_max_abscissa;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_VCGEN_CONTOUR_INCLUDED
|
||||
#define AGG_VCGEN_CONTOUR_INCLUDED
|
||||
|
||||
#include "agg_math_stroke.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//----------------------------------------------------------vcgen_contour
|
||||
//
|
||||
// See Implementation agg_vcgen_contour.cpp
|
||||
//
|
||||
class vcgen_contour
|
||||
{
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
ready,
|
||||
outline,
|
||||
out_vertices,
|
||||
end_poly,
|
||||
stop
|
||||
};
|
||||
|
||||
public:
|
||||
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
|
||||
typedef pod_bvector<point_d, 6> coord_storage;
|
||||
|
||||
vcgen_contour();
|
||||
|
||||
void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); }
|
||||
void line_join(line_join_e lj) { m_stroker.line_join(lj); }
|
||||
void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); }
|
||||
|
||||
line_cap_e line_cap() const { return m_stroker.line_cap(); }
|
||||
line_join_e line_join() const { return m_stroker.line_join(); }
|
||||
inner_join_e inner_join() const { return m_stroker.inner_join(); }
|
||||
|
||||
void width(double w) { m_stroker.width(m_width = w); }
|
||||
void miter_limit(double ml) { m_stroker.miter_limit(ml); }
|
||||
void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); }
|
||||
void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); }
|
||||
void approximation_scale(double as) { m_stroker.approximation_scale(as); }
|
||||
|
||||
double width() const { return m_width; }
|
||||
double miter_limit() const { return m_stroker.miter_limit(); }
|
||||
double inner_miter_limit() const { return m_stroker.inner_miter_limit(); }
|
||||
double approximation_scale() const { return m_stroker.approximation_scale(); }
|
||||
|
||||
void auto_detect_orientation(bool v) { m_auto_detect = v; }
|
||||
bool auto_detect_orientation() const { return m_auto_detect; }
|
||||
|
||||
// Generator interface
|
||||
void remove_all();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
vcgen_contour(const vcgen_contour&);
|
||||
const vcgen_contour& operator = (const vcgen_contour&);
|
||||
|
||||
math_stroke<coord_storage> m_stroker;
|
||||
double m_width;
|
||||
vertex_storage m_src_vertices;
|
||||
coord_storage m_out_vertices;
|
||||
status_e m_status;
|
||||
unsigned m_src_vertex;
|
||||
unsigned m_out_vertex;
|
||||
unsigned m_closed;
|
||||
unsigned m_orientation;
|
||||
bool m_auto_detect;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Line dash generator
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_VCGEN_DASH_INCLUDED
|
||||
#define AGG_VCGEN_DASH_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//---------------------------------------------------------------vcgen_dash
|
||||
//
|
||||
// See Implementation agg_vcgen_dash.cpp
|
||||
//
|
||||
class vcgen_dash
|
||||
{
|
||||
enum max_dashes_e
|
||||
{
|
||||
max_dashes = 32
|
||||
};
|
||||
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
ready,
|
||||
polyline,
|
||||
stop
|
||||
};
|
||||
|
||||
public:
|
||||
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
|
||||
|
||||
vcgen_dash();
|
||||
|
||||
void remove_all_dashes();
|
||||
void add_dash(double dash_len, double gap_len);
|
||||
void dash_start(double ds);
|
||||
|
||||
void shorten(double s) { m_shorten = s; }
|
||||
double shorten() const { return m_shorten; }
|
||||
|
||||
// Vertex Generator Interface
|
||||
void remove_all();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
vcgen_dash(const vcgen_dash&);
|
||||
const vcgen_dash& operator = (const vcgen_dash&);
|
||||
|
||||
void calc_dash_start(double ds);
|
||||
|
||||
double m_dashes[max_dashes];
|
||||
double m_total_dash_len;
|
||||
unsigned m_num_dashes;
|
||||
double m_dash_start;
|
||||
double m_shorten;
|
||||
double m_curr_dash_start;
|
||||
unsigned m_curr_dash;
|
||||
double m_curr_rest;
|
||||
const vertex_dist* m_v1;
|
||||
const vertex_dist* m_v2;
|
||||
|
||||
vertex_storage m_src_vertices;
|
||||
unsigned m_closed;
|
||||
status_e m_status;
|
||||
unsigned m_src_vertex;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_VCGEN_MARKERS_TERM_INCLUDED
|
||||
#define AGG_VCGEN_MARKERS_TERM_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//======================================================vcgen_markers_term
|
||||
//
|
||||
// See Implemantation agg_vcgen_markers_term.cpp
|
||||
// Terminal markers generator (arrowhead/arrowtail)
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class vcgen_markers_term
|
||||
{
|
||||
public:
|
||||
vcgen_markers_term() : m_curr_id(0), m_curr_idx(0) {}
|
||||
|
||||
// Vertex Generator Interface
|
||||
void remove_all();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
vcgen_markers_term(const vcgen_markers_term&);
|
||||
const vcgen_markers_term& operator = (const vcgen_markers_term&);
|
||||
|
||||
struct coord_type
|
||||
{
|
||||
double x, y;
|
||||
|
||||
coord_type() {}
|
||||
coord_type(double x_, double y_) : x(x_), y(y_) {}
|
||||
};
|
||||
|
||||
typedef pod_bvector<coord_type, 6> coord_storage;
|
||||
|
||||
coord_storage m_markers;
|
||||
unsigned m_curr_id;
|
||||
unsigned m_curr_idx;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_VCGEN_SMOOTH_POLY1_INCLUDED
|
||||
#define AGG_VCGEN_SMOOTH_POLY1_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_vertex_sequence.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//======================================================vcgen_smooth_poly1
|
||||
//
|
||||
// See Implementation agg_vcgen_smooth_poly1.cpp
|
||||
// Smooth polygon generator
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class vcgen_smooth_poly1
|
||||
{
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
ready,
|
||||
polygon,
|
||||
ctrl_b,
|
||||
ctrl_e,
|
||||
ctrl1,
|
||||
ctrl2,
|
||||
end_poly,
|
||||
stop
|
||||
};
|
||||
|
||||
public:
|
||||
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
|
||||
|
||||
vcgen_smooth_poly1();
|
||||
|
||||
void smooth_value(double v) { m_smooth_value = v * 0.5; }
|
||||
double smooth_value() const { return m_smooth_value * 2.0; }
|
||||
|
||||
// Vertex Generator Interface
|
||||
void remove_all();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
vcgen_smooth_poly1(const vcgen_smooth_poly1&);
|
||||
const vcgen_smooth_poly1& operator = (const vcgen_smooth_poly1&);
|
||||
|
||||
void calculate(const vertex_dist& v0,
|
||||
const vertex_dist& v1,
|
||||
const vertex_dist& v2,
|
||||
const vertex_dist& v3);
|
||||
|
||||
vertex_storage m_src_vertices;
|
||||
double m_smooth_value;
|
||||
unsigned m_closed;
|
||||
status_e m_status;
|
||||
unsigned m_src_vertex;
|
||||
double m_ctrl1_x;
|
||||
double m_ctrl1_y;
|
||||
double m_ctrl2_x;
|
||||
double m_ctrl2_y;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_VCGEN_STROKE_INCLUDED
|
||||
#define AGG_VCGEN_STROKE_INCLUDED
|
||||
|
||||
#include "agg_math_stroke.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//============================================================vcgen_stroke
|
||||
//
|
||||
// See Implementation agg_vcgen_stroke.cpp
|
||||
// Stroke generator
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class vcgen_stroke
|
||||
{
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
ready,
|
||||
cap1,
|
||||
cap2,
|
||||
outline1,
|
||||
close_first,
|
||||
outline2,
|
||||
out_vertices,
|
||||
end_poly1,
|
||||
end_poly2,
|
||||
stop
|
||||
};
|
||||
|
||||
public:
|
||||
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
|
||||
typedef pod_bvector<point_d, 6> coord_storage;
|
||||
|
||||
vcgen_stroke();
|
||||
|
||||
void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); }
|
||||
void line_join(line_join_e lj) { m_stroker.line_join(lj); }
|
||||
void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); }
|
||||
|
||||
line_cap_e line_cap() const { return m_stroker.line_cap(); }
|
||||
line_join_e line_join() const { return m_stroker.line_join(); }
|
||||
inner_join_e inner_join() const { return m_stroker.inner_join(); }
|
||||
|
||||
void width(double w) { m_stroker.width(w); }
|
||||
void miter_limit(double ml) { m_stroker.miter_limit(ml); }
|
||||
void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); }
|
||||
void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); }
|
||||
void approximation_scale(double as) { m_stroker.approximation_scale(as); }
|
||||
|
||||
double width() const { return m_stroker.width(); }
|
||||
double miter_limit() const { return m_stroker.miter_limit(); }
|
||||
double inner_miter_limit() const { return m_stroker.inner_miter_limit(); }
|
||||
double approximation_scale() const { return m_stroker.approximation_scale(); }
|
||||
|
||||
void shorten(double s) { m_shorten = s; }
|
||||
double shorten() const { return m_shorten; }
|
||||
|
||||
// Vertex Generator Interface
|
||||
void remove_all();
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
// Vertex Source Interface
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
private:
|
||||
vcgen_stroke(const vcgen_stroke&);
|
||||
const vcgen_stroke& operator = (const vcgen_stroke&);
|
||||
|
||||
math_stroke<coord_storage> m_stroker;
|
||||
vertex_storage m_src_vertices;
|
||||
coord_storage m_out_vertices;
|
||||
double m_shorten;
|
||||
unsigned m_closed;
|
||||
status_e m_status;
|
||||
status_e m_prev_status;
|
||||
unsigned m_src_vertex;
|
||||
unsigned m_out_vertex;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue