Merge commit '6ffe78c30063ed30f82b48b32c8069a7e69a6edf' into harfbuzz

Conflicts:
	tests/visual_tests/test.py
This commit is contained in:
Hermann Kraus 2013-03-16 18:23:17 +01:00
commit f11616c644
185 changed files with 16127 additions and 15176 deletions

View file

@ -663,15 +663,16 @@ def update_linux_project_files():
]
def iterate_dirs(headers_content, source_content, d):
for root, subFolders, files in os.walk(d):
for f in files:
if f.endswith(".h") or f.endswith(".hpp"):
headers_content.append(" ../%s \\" % os.path.join(root, f))
if f.endswith(".cpp") or f.endswith(".c"):
source_content.append(" ../%s \\" % os.path.join(root, f))
for sd in subFolders:
headers_content, source_content = \
iterate_dirs(headers_content, source_content, sd)
if not "uninstall-" in d:
for root, subFolders, files in os.walk(d):
for f in files:
if f.endswith(".h") or f.endswith(".hpp"):
headers_content.append(" ../%s \\" % os.path.join(root, f))
if f.endswith(".cpp") or f.endswith(".c"):
source_content.append(" ../%s \\" % os.path.join(root, f))
for sd in subFolders:
headers_content, source_content = \
iterate_dirs(headers_content, source_content, os.path.join(root, sd))
return headers_content, source_content
for d in directories:

View file

@ -10,12 +10,16 @@ test_env['LIBS'] = copy(env['LIBMAPNIK_LIBS'])
test_env.AppendUnique(LIBS='mapnik')
#test_env.AppendUnique(LIBS='sqlite3')
test_env.AppendUnique(CXXFLAGS='-g')
linkflags = copy(env['CUSTOM_LDFLAGS'])
linkflags
if env['PLATFORM'] == 'Darwin':
linkflags += ' -F/ -framework CoreFoundation'
for cpp_test in glob.glob('run*.cpp'):
name = cpp_test.replace('.cpp','')
source_files = [cpp_test]
test_env_local = test_env.Clone()
test_program = test_env_local.Program(name, source=source_files, LINKFLAGS=env['CUSTOM_LDFLAGS'])
test_program = test_env_local.Program(name, source=source_files, LINKFLAGS=linkflags)
Depends(test_program, env.subst('../src/%s' % env['MAPNIK_LIB_NAME']))
# build locally if installing
if 'install' in COMMAND_LINE_TARGETS:

View file

@ -0,0 +1 @@
MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))

View file

@ -18,6 +18,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/process_cpu_clocks.hpp>
@ -35,7 +36,7 @@ typedef process_cpu_clock clock_type;
typedef clock_type::duration dur;
template <typename T>
void benchmark(T test, std::string const& name)
void benchmark(T & test_runner, std::string const& name)
{
try {
bool should_run_test = true;
@ -43,31 +44,33 @@ void benchmark(T test, std::string const& name)
should_run_test = test_set.find(test_num) != test_set.end();
}
if (should_run_test || dry_run) {
if (!test.validate()) {
if (!test_runner.validate()) {
std::clog << "test did not validate: " << name << "\n";
//throw std::runtime_error(std::string("test did not validate: ") + name);
}
if (dry_run) {
std::clog << test_num << ") " << (test.threads_ ? "threaded -> ": "")
std::clog << test_num << ") " << (test_runner.threads_ ? "threaded -> ": "")
<< name << "\n";
} else {
process_cpu_clock::time_point start;
dur elapsed;
if (test.threads_ > 0) {
if (test_runner.threads_ > 0) {
boost::thread_group tg;
for (unsigned i=0;i<test.threads_;++i)
for (unsigned i=0;i<test_runner.threads_;++i)
{
tg.create_thread(test);
boost::function<void()> _p;
_p = boost::bind(&T::operator(),&test_runner);
tg.create_thread(_p);
}
start = process_cpu_clock::now();
tg.join_all();
elapsed = process_cpu_clock::now() - start;
} else {
start = process_cpu_clock::now();
test();
test_runner();
elapsed = process_cpu_clock::now() - start;
}
std::clog << test_num << ") " << (test.threads_ ? "threaded -> ": "")
std::clog << test_num << ") " << (test_runner.threads_ ? "threaded -> ": "")
<< name << ": "
<< boost::chrono::duration_cast<milliseconds>(elapsed) << "\n";
}
@ -591,6 +594,60 @@ struct test10
}
};
#include <mapnik/wkt/wkt_factory.hpp>
#include "agg_conv_clipper.h"
#include "agg_path_storage.h"
#include <mapnik/geometry.hpp>
struct test11
{
unsigned iter_;
unsigned threads_;
boost::ptr_vector<geometry_type> paths_;
mapnik::box2d<double> extent_;
typedef agg::conv_clipper<mapnik::geometry_type, agg::path_storage> poly_clipper;
explicit test11(unsigned iterations,
unsigned threads,
std::string wkt_in,
mapnik::box2d<double> const& extent)
: iter_(iterations),
threads_(threads),
extent_(extent) {
if (!mapnik::from_wkt(wkt_in, paths_))
{
throw std::runtime_error("Failed to parse WKT");
}
}
bool validate()
{
return true;
}
void operator()()
{
agg::path_storage ps;
ps.move_to(extent_.minx(), extent_.miny());
ps.line_to(extent_.minx(), extent_.maxy());
ps.line_to(extent_.maxx(), extent_.maxy());
ps.line_to(extent_.maxx(), extent_.miny());
ps.close_polygon();
for (unsigned i=0;i<iter_;++i) {
BOOST_FOREACH( geometry_type & geom, paths_)
{
poly_clipper clipped(geom,ps,
agg::clipper_and,
agg::clipper_non_zero,
agg::clipper_non_zero,
1);
clipped.rewind(0);
unsigned cmd;
double x,y;
while ((cmd = geom.vertex(&x, &y)) != SEG_END) {}
}
}
}
};
int main( int argc, char** argv)
{
if (argc > 0) {
@ -720,6 +777,18 @@ int main( int argc, char** argv)
benchmark(runner,"rule caching using heap allocation");
}
{
std::string filename_("benchmark/data/polygon.wkt");
std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
if (!in.is_open())
throw std::runtime_error("could not open: '" + filename_ + "'");
std::string wkt_in( (std::istreambuf_iterator<char>(in) ),
(std::istreambuf_iterator<char>()) );
mapnik::box2d<double> clipping_box(0,0,40,40);
test11 runner(100000,10,wkt_in,clipping_box);
benchmark(runner,"clipping polygon with agg_conv_clipper");
}
std::cout << "...benchmark done\n";
return 0;
}

View file

@ -19,7 +19,7 @@
#ifndef AGG_ALPHA_MASK_U8_INCLUDED
#define AGG_ALPHA_MASK_U8_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"

View file

@ -20,7 +20,7 @@
#ifndef AGG_ARC_INCLUDED
#define AGG_ARC_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -15,8 +15,8 @@
#ifndef AGG_ARRAY_INCLUDED
#define AGG_ARRAY_INCLUDED
#include <stddef.h>
#include <string.h>
#include <cstddef>
#include <cstring>
#include "agg_basics.h"
namespace agg

View file

@ -16,7 +16,7 @@
#ifndef AGG_BASICS_INCLUDED
#define AGG_BASICS_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_config.h"
//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR

View file

@ -24,7 +24,7 @@
#ifndef AGG_COLOR_RGBA_INCLUDED
#define AGG_COLOR_RGBA_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -22,303 +22,305 @@
namespace agg
{
enum clipper_op_e { clipper_or,
clipper_and, clipper_xor, clipper_a_minus_b, clipper_b_minus_a };
enum clipper_PolyFillType {clipper_even_odd, clipper_non_zero, clipper_positive, clipper_negative};
enum clipper_op_e { clipper_or,
clipper_and, clipper_xor, clipper_a_minus_b, clipper_b_minus_a };
enum clipper_PolyFillType {clipper_even_odd, clipper_non_zero, clipper_positive, clipper_negative};
template<class VSA, class VSB> class conv_clipper
template<class VSA, class VSB> class conv_clipper
{
enum status { status_move_to, status_line_to, status_close_path, status_stop };
typedef VSA source_a_type;
typedef VSB source_b_type;
typedef conv_clipper<source_a_type, source_b_type> self_type;
private:
source_a_type* m_src_a;
source_b_type* m_src_b;
status m_status;
int m_vertex;
int m_contour;
int m_scaling_factor;
clipper_op_e m_operation;
pod_bvector<ClipperLib::IntPoint, 8> m_vertex_accumulator;
ClipperLib::Polygons m_poly_a;
ClipperLib::Polygons m_poly_b;
ClipperLib::Polygons m_result;
ClipperLib::Clipper m_clipper;
clipper_PolyFillType m_subjFillType;
clipper_PolyFillType m_clipFillType;
int Round(double val)
{
enum status { status_move_to, status_line_to, status_stop };
typedef VSA source_a_type;
typedef VSB source_b_type;
typedef conv_clipper<source_a_type, source_b_type> self_type;
if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5);
}
private:
source_a_type* m_src_a;
source_b_type* m_src_b;
status m_status;
int m_vertex;
int m_contour;
int m_scaling_factor;
clipper_op_e m_operation;
pod_bvector<ClipperLib::IntPoint, 8> m_vertex_accumulator;
ClipperLib::Polygons m_poly_a;
ClipperLib::Polygons m_poly_b;
ClipperLib::Polygons m_result;
ClipperLib::Clipper m_clipper;
clipper_PolyFillType m_subjFillType;
clipper_PolyFillType m_clipFillType;
double start_x_;
double start_y_;
int Round(double val)
{
if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5);
}
public:
public:
conv_clipper(source_a_type &a, source_b_type &b,
clipper_op_e op = clipper_or,
clipper_PolyFillType subjFillType = clipper_even_odd,
clipper_PolyFillType clipFillType = clipper_even_odd,
int scaling_factor = 2) :
m_src_a(&a),
m_src_b(&b),
m_status(status_move_to),
m_vertex(-1),
m_contour(-1),
m_operation(op),
m_subjFillType(subjFillType),
m_clipFillType(clipFillType),
start_x_(0),
start_y_(0)
{
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
}
clipper_op_e op = clipper_or,
clipper_PolyFillType subjFillType = clipper_even_odd,
clipper_PolyFillType clipFillType = clipper_even_odd,
int scaling_factor = 2) :
m_src_a(&a),
m_src_b(&b),
m_status(status_move_to),
m_vertex(-1),
m_contour(-1),
m_operation(op),
m_subjFillType(subjFillType),
m_clipFillType(clipFillType)
{
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
}
conv_clipper(source_a_type &a,
clipper_op_e op = clipper_and,
clipper_PolyFillType subjFillType = clipper_non_zero,
clipper_PolyFillType clipFillType = clipper_non_zero,
int scaling_factor = 6) :
m_src_a(&a),
m_status(status_move_to),
m_vertex(-1),
m_contour(-1),
m_operation(op),
m_subjFillType(subjFillType),
m_clipFillType(clipFillType),
start_x_(0),
start_y_(0)
{
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
}
~conv_clipper()
{
}
unsigned type() const { return m_src_a->type(); }
void attach1(VSA &source, clipper_PolyFillType subjFillType = clipper_even_odd)
{ m_src_a = &source; m_subjFillType = subjFillType; }
void attach2(VSB &source, clipper_PolyFillType clipFillType = clipper_even_odd)
{ m_src_b = &source; m_clipFillType = clipFillType; }
void operation(clipper_op_e v) { m_operation = v; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
bool next_contour();
bool next_vertex(double* x, double* y);
void start_extracting();
void add_vertex_(double &x, double &y);
void end_contour(ClipperLib::Polygons &p);
template<class VS> void add(VS &src, ClipperLib::Polygons &p){
unsigned cmd;
double x; double y; double start_x; double start_y;
bool starting_first_line;
start_x = 0.0;
start_y = 0.0;
starting_first_line = true;
p.resize(0);
cmd = src->vertex( &x , &y );
while(!is_stop(cmd))
{
if(is_vertex(cmd))
{
if(is_move_to(cmd))
{
if(!starting_first_line ) end_contour(p);
start_x = x;
start_y = y;
}
add_vertex_( x, y );
starting_first_line = false;
}
else if(is_end_poly(cmd))
{
if(!starting_first_line && is_closed(cmd))
add_vertex_( start_x, start_y );
}
cmd = src->vertex( &x, &y );
}
end_contour(p);
}
};
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::start_extracting()
clipper_op_e op = clipper_and,
clipper_PolyFillType subjFillType = clipper_non_zero,
clipper_PolyFillType clipFillType = clipper_non_zero,
int scaling_factor = 6) :
m_src_a(&a),
m_status(status_move_to),
m_vertex(-1),
m_contour(-1),
m_operation(op),
m_subjFillType(subjFillType),
m_clipFillType(clipFillType)
{
m_status = status_move_to;
m_contour = -1;
m_vertex = -1;
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::rewind(unsigned path_id)
~conv_clipper()
{
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 );
m_result.resize(0);
ClipperLib::PolyFillType pftSubj, pftClip;
switch (m_subjFillType)
{
case clipper_even_odd: pftSubj = ClipperLib::pftEvenOdd; break;
case clipper_non_zero: pftSubj = ClipperLib::pftNonZero; break;
case clipper_positive: pftSubj = ClipperLib::pftPositive; break;
default: pftSubj = ClipperLib::pftNegative;
}
switch (m_clipFillType)
{
case clipper_even_odd: pftClip = ClipperLib::pftEvenOdd; break;
case clipper_non_zero: pftClip = ClipperLib::pftNonZero; break;
case clipper_positive: pftClip = ClipperLib::pftPositive; break;
default: pftClip = ClipperLib::pftNegative;
}
m_clipper.Clear();
switch( m_operation ) {
case clipper_or:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctUnion , m_result , pftSubj, pftClip);
break;
}
case clipper_and:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctIntersection , m_result, pftSubj, pftClip );
break;
}
case clipper_xor:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctXor , m_result, pftSubj, pftClip );
break;
}
case clipper_a_minus_b:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip );
break;
}
case clipper_b_minus_a:
{
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip );
break;
}
}
start_extracting();
}
//------------------------------------------------------------------------------
unsigned type() const { return m_src_a->type(); }
void attach1(VSA &source, clipper_PolyFillType subjFillType = clipper_even_odd)
{ m_src_a = &source; m_subjFillType = subjFillType; }
void attach2(VSB &source, clipper_PolyFillType clipFillType = clipper_even_odd)
{ m_src_b = &source; m_clipFillType = clipFillType; }
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::end_contour( ClipperLib::Polygons &p)
{
unsigned i, len;
void operation(clipper_op_e v) { m_operation = v; }
if( m_vertex_accumulator.size() < 3 ) return;
len = p.size();
p.resize(len+1);
p[len].resize(m_vertex_accumulator.size());
for( i = 0 ; i < m_vertex_accumulator.size() ; i++ )
p[len][i] = m_vertex_accumulator[i];
m_vertex_accumulator.remove_all();
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
bool next_contour();
bool next_vertex(double* x, double* y);
void start_extracting();
void add_vertex_(double &x, double &y);
void end_contour(ClipperLib::Polygons &p);
template<class VS> void add(VS &src, ClipperLib::Polygons &p){
unsigned cmd;
double x; double y; double start_x; double start_y;
bool starting_first_line;
start_x = 0.0;
start_y = 0.0;
starting_first_line = true;
p.resize(0);
cmd = src->vertex( &x , &y );
while(!is_stop(cmd))
{
if(is_vertex(cmd))
{
if(is_move_to(cmd))
{
if(!starting_first_line ) end_contour(p);
start_x = x;
start_y = y;
}
add_vertex_( x, y );
starting_first_line = false;
}
else if(is_end_poly(cmd))
{
if(!starting_first_line && is_closed(cmd))
add_vertex_( start_x, start_y );
}
cmd = src->vertex( &x, &y );
}
end_contour(p);
}
//------------------------------------------------------------------------------
};
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::add_vertex_(double &x, double &y)
{
ClipperLib::IntPoint v;
//------------------------------------------------------------------------
v.X = Round(x * m_scaling_factor);
v.Y = Round(y * m_scaling_factor);
m_vertex_accumulator.add( v );
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
bool conv_clipper<VSA, VSB>::next_contour()
{
m_contour++;
if(m_contour >= (int)m_result.size()) return false;
m_vertex =-1;
return true;
}
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::start_extracting()
{
m_status = status_move_to;
m_contour = -1;
m_vertex = -1;
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
bool conv_clipper<VSA, VSB>::next_vertex(double *x, double *y)
{
m_vertex++;
if(m_vertex >= (int)m_result[m_contour].size()) return false;
*x = (double)m_result[ m_contour ][ m_vertex ].X / m_scaling_factor;
*y = (double)m_result[ m_contour ][ m_vertex ].Y / m_scaling_factor;
return true;
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::rewind(unsigned path_id)
{
m_src_a->rewind( path_id );
m_src_b->rewind( path_id );
//------------------------------------------------------------------------------
add( m_src_a , m_poly_a );
add( m_src_b , m_poly_b );
m_result.resize(0);
template<class VSA, class VSB>
unsigned conv_clipper<VSA, VSB>::vertex(double *x, double *y)
ClipperLib::PolyFillType pftSubj, pftClip;
switch (m_subjFillType)
{
if( m_status == status_move_to )
{
if( next_contour() )
{
if( next_vertex( x, y ) )
{
m_status =status_line_to;
start_x_ = *x;
start_y_ = *y;
return path_cmd_move_to;
}
else
{
*x = start_x_;
*y = start_y_;
m_status = status_stop;
return path_cmd_end_poly | path_flags_close;
}
}
else
return path_cmd_stop;
}
else
{
if( next_vertex( x, y ) )
{
return path_cmd_line_to;
}
else
{
m_status = status_move_to;
*x = start_x_;
*y = start_y_;
return path_cmd_end_poly | path_flags_close;
}
}
case clipper_even_odd: pftSubj = ClipperLib::pftEvenOdd; break;
case clipper_non_zero: pftSubj = ClipperLib::pftNonZero; break;
case clipper_positive: pftSubj = ClipperLib::pftPositive; break;
default: pftSubj = ClipperLib::pftNegative;
}
switch (m_clipFillType)
{
case clipper_even_odd: pftClip = ClipperLib::pftEvenOdd; break;
case clipper_non_zero: pftClip = ClipperLib::pftNonZero; break;
case clipper_positive: pftClip = ClipperLib::pftPositive; break;
default: pftClip = ClipperLib::pftNegative;
}
m_clipper.Clear();
switch( m_operation ) {
case clipper_or:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctUnion , m_result , pftSubj, pftClip);
break;
}
case clipper_and:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctIntersection , m_result, pftSubj, pftClip );
break;
}
case clipper_xor:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctXor , m_result, pftSubj, pftClip );
break;
}
case clipper_a_minus_b:
{
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip );
break;
}
case clipper_b_minus_a:
{
m_clipper.AddPolygons( m_poly_b , ClipperLib::ptSubject );
m_clipper.AddPolygons( m_poly_a , ClipperLib::ptClip );
m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip );
break;
}
}
start_extracting();
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::end_contour( ClipperLib::Polygons &p)
{
unsigned i, len;
if( m_vertex_accumulator.size() < 3 ) return;
len = p.size();
p.resize(len+1);
p[len].resize(m_vertex_accumulator.size());
for( i = 0 ; i < m_vertex_accumulator.size() ; i++ )
p[len][i] = m_vertex_accumulator[i];
m_vertex_accumulator.remove_all();
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::add_vertex_(double &x, double &y)
{
ClipperLib::IntPoint v;
v.X = Round(x * m_scaling_factor);
v.Y = Round(y * m_scaling_factor);
m_vertex_accumulator.add( v );
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
bool conv_clipper<VSA, VSB>::next_contour()
{
m_contour++;
if(m_contour >= (int)m_result.size()) return false;
m_vertex =-1;
return true;
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
bool conv_clipper<VSA, VSB>::next_vertex(double *x, double *y)
{
m_vertex++;
if(m_vertex >= (int)m_result[m_contour].size()) return false;
*x = (double)m_result[ m_contour ][ m_vertex ].X / m_scaling_factor;
*y = (double)m_result[ m_contour ][ m_vertex ].Y / m_scaling_factor;
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
template<class VSA, class VSB>
unsigned conv_clipper<VSA, VSB>::vertex(double *x, double *y)
{
switch (m_status)
{
case status_move_to:
{
if( next_contour() )
{
if ( next_vertex( x, y ) )
{
m_status = status_line_to;
return path_cmd_move_to;
}
else
{
m_status = status_close_path;
return path_cmd_line_to;
}
}
else
return path_cmd_stop;
}
case status_close_path:
{
*x = 0;
*y = 0;
m_status = status_move_to;
return path_cmd_end_poly | path_flags_close;
}
case status_stop:
{
return path_cmd_stop;
}
default:
{
if( next_vertex( x, y ) )
{
return path_cmd_line_to;
}
else
{
m_status = status_close_path;
return path_cmd_line_to;
}
}
}
}
//------------------------------------------------------------------------------

View file

@ -24,7 +24,7 @@
#ifndef AGG_CONV_GPC_INCLUDED
#define AGG_CONV_GPC_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
#include "agg_array.h"

View file

@ -20,7 +20,7 @@
#ifndef AGG_DDA_LINE_INCLUDED
#define AGG_DDA_LINE_INCLUDED
#include <stdlib.h>
#include <cstdlib>
#include "agg_basics.h"
namespace agg

View file

@ -21,7 +21,7 @@
#define AGG_ELLIPSE_INCLUDED
#include "agg_basics.h"
#include <math.h>
#include <cmath>
namespace agg
{

View file

@ -16,7 +16,7 @@
#ifndef AGG_FONT_CACHE_MANAGER_INCLUDED
#define AGG_FONT_CACHE_MANAGER_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_array.h"
namespace agg

View file

@ -16,7 +16,7 @@
#ifndef AGG_GAMMA_FUNCTIONS_INCLUDED
#define AGG_GAMMA_FUNCTIONS_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -16,7 +16,7 @@
#ifndef AGG_GAMMA_LUT_INCLUDED
#define AGG_GAMMA_LUT_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -16,7 +16,7 @@
#ifndef AGG_GLYPH_RASTER_BIN_INCLUDED
#define AGG_GLYPH_RASTER_BIN_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_basics.h"
namespace agg

View file

@ -15,7 +15,7 @@
#ifndef AGG_LINE_AA_BASICS_INCLUDED
#define AGG_LINE_AA_BASICS_INCLUDED
#include <stdlib.h>
#include <cstdlib>
#include "agg_basics.h"
namespace agg

View file

@ -19,7 +19,7 @@
#ifndef AGG_MATH_INCLUDED
#define AGG_MATH_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -16,8 +16,8 @@
#ifndef AGG_PATH_STORAGE_INCLUDED
#define AGG_PATH_STORAGE_INCLUDED
#include <string.h>
#include <math.h>
#include <cstring>
#include <cmath>
#include "agg_math.h"
#include "agg_array.h"
#include "agg_bezier_arc.h"

View file

@ -16,7 +16,7 @@
#ifndef AGG_PATH_STORAGE_INTEGER_INCLUDED
#define AGG_PATH_STORAGE_INTEGER_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_array.h"
namespace agg

View file

@ -17,7 +17,7 @@
#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_array.h"
#include "agg_rendering_buffer.h"

View file

@ -24,7 +24,7 @@
#ifndef AGG_PIXFMT_GRAY_INCLUDED
#define AGG_PIXFMT_GRAY_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_basics.h"
#include "agg_color_gray.h"
#include "agg_rendering_buffer.h"

View file

@ -24,7 +24,7 @@
#ifndef AGG_PIXFMT_RGB_INCLUDED
#define AGG_PIXFMT_RGB_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_basics.h"
#include "agg_color_rgba.h"
#include "agg_rendering_buffer.h"

View file

@ -24,7 +24,7 @@
#ifndef AGG_PIXFMT_RGB_PACKED_INCLUDED
#define AGG_PIXFMT_RGB_PACKED_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_basics.h"
#include "agg_color_rgba.h"
#include "agg_rendering_buffer.h"

View file

@ -25,8 +25,8 @@
#ifndef AGG_PIXFMT_RGBA_INCLUDED
#define AGG_PIXFMT_RGBA_INCLUDED
#include <string.h>
#include <math.h>
#include <cstring>
#include <cmath>
#include "agg_basics.h"
#include "agg_color_rgba.h"
#include "agg_rendering_buffer.h"

View file

@ -29,7 +29,7 @@
#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
#define AGG_RASTERIZER_CELLS_AA_INCLUDED
#include <string.h>
#include <cstring>
#include <cstdlib>
#include <limits>
#include "agg_math.h"

View file

@ -16,8 +16,8 @@
#ifndef AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED
#define AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED
#include <stdlib.h>
#include <math.h>
#include <cstdlib>
#include <cmath>
#include "agg_basics.h"

View file

@ -24,9 +24,9 @@
#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
#define AGG_SCANLINE_STORAGE_AA_INCLUDED
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include "agg_array.h"

View file

@ -25,9 +25,9 @@
#ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
#define AGG_SCANLINE_STORAGE_BIN_INCLUDED
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include "agg_array.h"

View file

@ -19,7 +19,7 @@
#ifndef AGG_SIMUL_EQ_INCLUDED
#define AGG_SIMUL_EQ_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -16,9 +16,9 @@
#ifndef AGG_SPAN_GRADIENT_INCLUDED
#define AGG_SPAN_GRADIENT_INCLUDED
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include "agg_basics.h"
#include "agg_math.h"
#include "agg_array.h"

View file

@ -19,7 +19,7 @@
#ifndef AGG_TRANS_AFFINE_INCLUDED
#define AGG_TRANS_AFFINE_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -16,7 +16,7 @@
#ifndef AGG_WARP_MAGNIFIER_INCLUDED
#define AGG_WARP_MAGNIFIER_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"

View file

@ -21,7 +21,7 @@
#ifndef AGG_TRANS_VIEWPORT_INCLUDED
#define AGG_TRANS_VIEWPORT_INCLUDED
#include <string.h>
#include <cstring>
#include "agg_trans_affine.h"

View file

@ -16,7 +16,7 @@
#ifndef AGG_VPGEN_SEGMENTATOR_INCLUDED
#define AGG_VPGEN_SEGMENTATOR_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_basics.h"
namespace agg

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -23,84 +23,84 @@
namespace agg
{
//------------------------------------------------------------------------
arc::arc(double x, double y,
double rx, double ry,
double a1, double a2,
bool ccw) :
m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0)
//------------------------------------------------------------------------
arc::arc(double x, double y,
double rx, double ry,
double a1, double a2,
bool ccw) :
m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0)
{
normalize(a1, a2, ccw);
}
//------------------------------------------------------------------------
void arc::init(double x, double y,
double rx, double ry,
double a1, double a2,
bool ccw)
{
m_x = x; m_y = y;
m_rx = rx; m_ry = ry;
normalize(a1, a2, ccw);
}
//------------------------------------------------------------------------
void arc::approximation_scale(double s)
{
m_scale = s;
if(m_initialized)
{
normalize(a1, a2, ccw);
normalize(m_start, m_end, m_ccw);
}
}
//------------------------------------------------------------------------
void arc::rewind(unsigned)
{
m_path_cmd = path_cmd_move_to;
m_angle = m_start;
}
//------------------------------------------------------------------------
unsigned arc::vertex(double* x, double* y)
{
if(is_stop(m_path_cmd)) return path_cmd_stop;
if((m_angle < m_end - m_da/4) != m_ccw)
{
*x = m_x + cos(m_end) * m_rx;
*y = m_y + sin(m_end) * m_ry;
m_path_cmd = path_cmd_stop;
return path_cmd_line_to;
}
//------------------------------------------------------------------------
void arc::init(double x, double y,
double rx, double ry,
double a1, double a2,
bool ccw)
*x = m_x + cos(m_angle) * m_rx;
*y = m_y + sin(m_angle) * m_ry;
m_angle += m_da;
unsigned pf = m_path_cmd;
m_path_cmd = path_cmd_line_to;
return pf;
}
//------------------------------------------------------------------------
void arc::normalize(double a1, double a2, bool ccw)
{
double ra = (fabs(m_rx) + fabs(m_ry)) / 2;
m_da = acos(ra / (ra + 0.125 / m_scale)) * 2;
if(ccw)
{
m_x = x; m_y = y;
m_rx = rx; m_ry = ry;
normalize(a1, a2, ccw);
while(a2 < a1) a2 += pi * 2.0;
}
//------------------------------------------------------------------------
void arc::approximation_scale(double s)
else
{
m_scale = s;
if(m_initialized)
{
normalize(m_start, m_end, m_ccw);
}
}
//------------------------------------------------------------------------
void arc::rewind(unsigned)
{
m_path_cmd = path_cmd_move_to;
m_angle = m_start;
}
//------------------------------------------------------------------------
unsigned arc::vertex(double* x, double* y)
{
if(is_stop(m_path_cmd)) return path_cmd_stop;
if((m_angle < m_end - m_da/4) != m_ccw)
{
*x = m_x + cos(m_end) * m_rx;
*y = m_y + sin(m_end) * m_ry;
m_path_cmd = path_cmd_stop;
return path_cmd_line_to;
}
*x = m_x + cos(m_angle) * m_rx;
*y = m_y + sin(m_angle) * m_ry;
m_angle += m_da;
unsigned pf = m_path_cmd;
m_path_cmd = path_cmd_line_to;
return pf;
}
//------------------------------------------------------------------------
void arc::normalize(double a1, double a2, bool ccw)
{
double ra = (fabs(m_rx) + fabs(m_ry)) / 2;
m_da = acos(ra / (ra + 0.125 / m_scale)) * 2;
if(ccw)
{
while(a2 < a1) a2 += pi * 2.0;
}
else
{
while(a1 < a2) a1 += pi * 2.0;
m_da = -m_da;
}
m_ccw = ccw;
m_start = a1;
m_end = a2;
m_initialized = true;
while(a1 < a2) a1 += pi * 2.0;
m_da = -m_da;
}
m_ccw = ccw;
m_start = a1;
m_end = a2;
m_initialized = true;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -13,7 +13,7 @@
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Simple arrowhead/arrowtail generator
// Simple arrowhead/arrowtail generator
//
//----------------------------------------------------------------------------
@ -22,89 +22,89 @@
namespace agg
{
//------------------------------------------------------------------------
arrowhead::arrowhead() :
m_head_d1(1.0),
m_head_d2(1.0),
m_head_d3(1.0),
m_head_d4(0.0),
m_tail_d1(1.0),
m_tail_d2(1.0),
m_tail_d3(1.0),
m_tail_d4(0.0),
m_head_flag(false),
m_tail_flag(false),
m_curr_id(0),
m_curr_coord(0)
//------------------------------------------------------------------------
arrowhead::arrowhead() :
m_head_d1(1.0),
m_head_d2(1.0),
m_head_d3(1.0),
m_head_d4(0.0),
m_tail_d1(1.0),
m_tail_d2(1.0),
m_tail_d3(1.0),
m_tail_d4(0.0),
m_head_flag(false),
m_tail_flag(false),
m_curr_id(0),
m_curr_coord(0)
{
}
//------------------------------------------------------------------------
void arrowhead::rewind(unsigned path_id)
{
m_curr_id = path_id;
m_curr_coord = 0;
if(path_id == 0)
{
}
//------------------------------------------------------------------------
void arrowhead::rewind(unsigned path_id)
{
m_curr_id = path_id;
m_curr_coord = 0;
if(path_id == 0)
if(!m_tail_flag)
{
if(!m_tail_flag)
{
m_cmd[0] = path_cmd_stop;
return;
}
m_coord[0] = m_tail_d1; m_coord[1] = 0.0;
m_coord[2] = m_tail_d1 - m_tail_d4; m_coord[3] = m_tail_d3;
m_coord[4] = -m_tail_d2 - m_tail_d4; m_coord[5] = m_tail_d3;
m_coord[6] = -m_tail_d2; m_coord[7] = 0.0;
m_coord[8] = -m_tail_d2 - m_tail_d4; m_coord[9] = -m_tail_d3;
m_coord[10] = m_tail_d1 - m_tail_d4; m_coord[11] = -m_tail_d3;
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_line_to;
m_cmd[4] = path_cmd_line_to;
m_cmd[5] = path_cmd_line_to;
m_cmd[7] = path_cmd_end_poly | path_flags_close | path_flags_ccw;
m_cmd[6] = path_cmd_stop;
m_cmd[0] = path_cmd_stop;
return;
}
m_coord[0] = m_tail_d1; m_coord[1] = 0.0;
m_coord[2] = m_tail_d1 - m_tail_d4; m_coord[3] = m_tail_d3;
m_coord[4] = -m_tail_d2 - m_tail_d4; m_coord[5] = m_tail_d3;
m_coord[6] = -m_tail_d2; m_coord[7] = 0.0;
m_coord[8] = -m_tail_d2 - m_tail_d4; m_coord[9] = -m_tail_d3;
m_coord[10] = m_tail_d1 - m_tail_d4; m_coord[11] = -m_tail_d3;
if(path_id == 1)
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_line_to;
m_cmd[4] = path_cmd_line_to;
m_cmd[5] = path_cmd_line_to;
m_cmd[7] = path_cmd_end_poly | path_flags_close | path_flags_ccw;
m_cmd[6] = path_cmd_stop;
return;
}
if(path_id == 1)
{
if(!m_head_flag)
{
if(!m_head_flag)
{
m_cmd[0] = path_cmd_stop;
return;
}
m_coord[0] = -m_head_d1; m_coord[1] = 0.0;
m_coord[2] = m_head_d2 + m_head_d4; m_coord[3] = -m_head_d3;
m_coord[4] = m_head_d2; m_coord[5] = 0.0;
m_coord[6] = m_head_d2 + m_head_d4; m_coord[7] = m_head_d3;
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_line_to;
m_cmd[4] = path_cmd_end_poly | path_flags_close | path_flags_ccw;
m_cmd[5] = path_cmd_stop;
m_cmd[0] = path_cmd_stop;
return;
}
m_coord[0] = -m_head_d1; m_coord[1] = 0.0;
m_coord[2] = m_head_d2 + m_head_d4; m_coord[3] = -m_head_d3;
m_coord[4] = m_head_d2; m_coord[5] = 0.0;
m_coord[6] = m_head_d2 + m_head_d4; m_coord[7] = m_head_d3;
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_line_to;
m_cmd[4] = path_cmd_end_poly | path_flags_close | path_flags_ccw;
m_cmd[5] = path_cmd_stop;
return;
}
}
//------------------------------------------------------------------------
unsigned arrowhead::vertex(double* x, double* y)
//------------------------------------------------------------------------
unsigned arrowhead::vertex(double* x, double* y)
{
if(m_curr_id < 2)
{
if(m_curr_id < 2)
{
unsigned curr_idx = m_curr_coord * 2;
*x = m_coord[curr_idx];
*y = m_coord[curr_idx + 1];
return m_cmd[m_curr_coord++];
}
return path_cmd_stop;
unsigned curr_idx = m_curr_coord * 2;
*x = m_coord[curr_idx];
*y = m_coord[curr_idx + 1];
return m_cmd[m_curr_coord++];
}
return path_cmd_stop;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -13,7 +13,7 @@
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
// 4, 7, 10, or 13 vertices.
//
//----------------------------------------------------------------------------
@ -26,233 +26,233 @@
namespace agg
{
// This epsilon is used to prevent us from adding degenerate curves
// (converging to a single point).
// The value isn't very critical. Function arc_to_bezier() has a limit
// of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve
// becomes inaccurate. But slight exceeding is quite appropriate.
//-------------------------------------------------bezier_arc_angle_epsilon
const double bezier_arc_angle_epsilon = 0.01;
// This epsilon is used to prevent us from adding degenerate curves
// (converging to a single point).
// The value isn't very critical. Function arc_to_bezier() has a limit
// of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve
// becomes inaccurate. But slight exceeding is quite appropriate.
//-------------------------------------------------bezier_arc_angle_epsilon
const double bezier_arc_angle_epsilon = 0.01;
//------------------------------------------------------------arc_to_bezier
void arc_to_bezier(double cx, double cy, double rx, double ry,
double start_angle, double sweep_angle,
double* curve)
//------------------------------------------------------------arc_to_bezier
void arc_to_bezier(double cx, double cy, double rx, double ry,
double start_angle, double sweep_angle,
double* curve)
{
double x0 = cos(sweep_angle / 2.0);
double y0 = sin(sweep_angle / 2.0);
double tx = (1.0 - x0) * 4.0 / 3.0;
double ty = y0 - tx * x0 / y0;
double px[4];
double py[4];
px[0] = x0;
py[0] = -y0;
px[1] = x0 + tx;
py[1] = -ty;
px[2] = x0 + tx;
py[2] = ty;
px[3] = x0;
py[3] = y0;
double sn = sin(start_angle + sweep_angle / 2.0);
double cs = cos(start_angle + sweep_angle / 2.0);
unsigned i;
for(i = 0; i < 4; i++)
{
double x0 = cos(sweep_angle / 2.0);
double y0 = sin(sweep_angle / 2.0);
double tx = (1.0 - x0) * 4.0 / 3.0;
double ty = y0 - tx * x0 / y0;
double px[4];
double py[4];
px[0] = x0;
py[0] = -y0;
px[1] = x0 + tx;
py[1] = -ty;
px[2] = x0 + tx;
py[2] = ty;
px[3] = x0;
py[3] = y0;
curve[i * 2] = cx + rx * (px[i] * cs - py[i] * sn);
curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs);
}
}
double sn = sin(start_angle + sweep_angle / 2.0);
double cs = cos(start_angle + sweep_angle / 2.0);
unsigned i;
for(i = 0; i < 4; i++)
{
curve[i * 2] = cx + rx * (px[i] * cs - py[i] * sn);
curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs);
}
//------------------------------------------------------------------------
void bezier_arc::init(double x, double y,
double rx, double ry,
double start_angle,
double sweep_angle)
{
start_angle = fmod(start_angle, 2.0 * pi);
if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi;
if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi;
if(fabs(sweep_angle) < 1e-10)
{
m_num_vertices = 4;
m_cmd = path_cmd_line_to;
m_vertices[0] = x + rx * cos(start_angle);
m_vertices[1] = y + ry * sin(start_angle);
m_vertices[2] = x + rx * cos(start_angle + sweep_angle);
m_vertices[3] = y + ry * sin(start_angle + sweep_angle);
return;
}
//------------------------------------------------------------------------
void bezier_arc::init(double x, double y,
double rx, double ry,
double start_angle,
double sweep_angle)
double total_sweep = 0.0;
double local_sweep = 0.0;
double prev_sweep;
m_num_vertices = 2;
m_cmd = path_cmd_curve4;
bool done = false;
do
{
start_angle = fmod(start_angle, 2.0 * pi);
if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi;
if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi;
if(fabs(sweep_angle) < 1e-10)
if(sweep_angle < 0.0)
{
m_num_vertices = 4;
m_cmd = path_cmd_line_to;
m_vertices[0] = x + rx * cos(start_angle);
m_vertices[1] = y + ry * sin(start_angle);
m_vertices[2] = x + rx * cos(start_angle + sweep_angle);
m_vertices[3] = y + ry * sin(start_angle + sweep_angle);
return;
prev_sweep = total_sweep;
local_sweep = -pi * 0.5;
total_sweep -= pi * 0.5;
if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon)
{
local_sweep = sweep_angle - prev_sweep;
done = true;
}
}
else
{
prev_sweep = total_sweep;
local_sweep = pi * 0.5;
total_sweep += pi * 0.5;
if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon)
{
local_sweep = sweep_angle - prev_sweep;
done = true;
}
}
double total_sweep = 0.0;
double local_sweep = 0.0;
double prev_sweep;
m_num_vertices = 2;
m_cmd = path_cmd_curve4;
bool done = false;
do
{
if(sweep_angle < 0.0)
{
prev_sweep = total_sweep;
local_sweep = -pi * 0.5;
total_sweep -= pi * 0.5;
if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon)
{
local_sweep = sweep_angle - prev_sweep;
done = true;
}
}
else
{
prev_sweep = total_sweep;
local_sweep = pi * 0.5;
total_sweep += pi * 0.5;
if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon)
{
local_sweep = sweep_angle - prev_sweep;
done = true;
}
}
arc_to_bezier(x, y, rx, ry,
start_angle,
local_sweep,
m_vertices + m_num_vertices - 2);
arc_to_bezier(x, y, rx, ry,
start_angle,
local_sweep,
m_vertices + m_num_vertices - 2);
m_num_vertices += 6;
start_angle += local_sweep;
}
while(!done && m_num_vertices < 26);
}
m_num_vertices += 6;
start_angle += local_sweep;
}
while(!done && m_num_vertices < 26);
//--------------------------------------------------------------------
void bezier_arc_svg::init(double x0, double y0,
double rx, double ry,
double angle,
bool large_arc_flag,
bool sweep_flag,
double x2, double y2)
{
m_radii_ok = true;
if(rx < 0.0) rx = -rx;
if(ry < 0.0) ry = -rx;
// Calculate the middle point between
// the current and the final points
//------------------------
double dx2 = (x0 - x2) / 2.0;
double dy2 = (y0 - y2) / 2.0;
double cos_a = cos(angle);
double sin_a = sin(angle);
// Calculate (x1, y1)
//------------------------
double x1 = cos_a * dx2 + sin_a * dy2;
double y1 = -sin_a * dx2 + cos_a * dy2;
// Ensure radii are large enough
//------------------------
double prx = rx * rx;
double pry = ry * ry;
double px1 = x1 * x1;
double py1 = y1 * y1;
// Check that radii are large enough
//------------------------
double radii_check = px1/prx + py1/pry;
if(radii_check > 1.0)
{
rx = sqrt(radii_check) * rx;
ry = sqrt(radii_check) * ry;
prx = rx * rx;
pry = ry * ry;
if(radii_check > 10.0) m_radii_ok = false;
}
// Calculate (cx1, cy1)
//------------------------
double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0;
double sq = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1);
double coef = sign * sqrt((sq < 0) ? 0 : sq);
double cx1 = coef * ((rx * y1) / ry);
double cy1 = coef * -((ry * x1) / rx);
//
// Calculate (cx, cy) from (cx1, cy1)
//------------------------
double sx2 = (x0 + x2) / 2.0;
double sy2 = (y0 + y2) / 2.0;
double cx = sx2 + (cos_a * cx1 - sin_a * cy1);
double cy = sy2 + (sin_a * cx1 + cos_a * cy1);
// Calculate the start_angle (angle1) and the sweep_angle (dangle)
//------------------------
double ux = (x1 - cx1) / rx;
double uy = (y1 - cy1) / ry;
double vx = (-x1 - cx1) / rx;
double vy = (-y1 - cy1) / ry;
double p, n;
//--------------------------------------------------------------------
void bezier_arc_svg::init(double x0, double y0,
double rx, double ry,
double angle,
bool large_arc_flag,
bool sweep_flag,
double x2, double y2)
// Calculate the angle start
//------------------------
n = sqrt(ux*ux + uy*uy);
p = ux; // (1 * ux) + (0 * uy)
sign = (uy < 0) ? -1.0 : 1.0;
double v = p / n;
if(v < -1.0) v = -1.0;
if(v > 1.0) v = 1.0;
double start_angle = sign * acos(v);
// Calculate the sweep angle
//------------------------
n = sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy));
p = ux * vx + uy * vy;
sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0;
v = p / n;
if(v < -1.0) v = -1.0;
if(v > 1.0) v = 1.0;
double sweep_angle = sign * acos(v);
if(!sweep_flag && sweep_angle > 0)
{
m_radii_ok = true;
if(rx < 0.0) rx = -rx;
if(ry < 0.0) ry = -rx;
// Calculate the middle point between
// the current and the final points
//------------------------
double dx2 = (x0 - x2) / 2.0;
double dy2 = (y0 - y2) / 2.0;
double cos_a = cos(angle);
double sin_a = sin(angle);
// Calculate (x1, y1)
//------------------------
double x1 = cos_a * dx2 + sin_a * dy2;
double y1 = -sin_a * dx2 + cos_a * dy2;
// Ensure radii are large enough
//------------------------
double prx = rx * rx;
double pry = ry * ry;
double px1 = x1 * x1;
double py1 = y1 * y1;
// Check that radii are large enough
//------------------------
double radii_check = px1/prx + py1/pry;
if(radii_check > 1.0)
{
rx = sqrt(radii_check) * rx;
ry = sqrt(radii_check) * ry;
prx = rx * rx;
pry = ry * ry;
if(radii_check > 10.0) m_radii_ok = false;
}
// Calculate (cx1, cy1)
//------------------------
double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0;
double sq = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1);
double coef = sign * sqrt((sq < 0) ? 0 : sq);
double cx1 = coef * ((rx * y1) / ry);
double cy1 = coef * -((ry * x1) / rx);
//
// Calculate (cx, cy) from (cx1, cy1)
//------------------------
double sx2 = (x0 + x2) / 2.0;
double sy2 = (y0 + y2) / 2.0;
double cx = sx2 + (cos_a * cx1 - sin_a * cy1);
double cy = sy2 + (sin_a * cx1 + cos_a * cy1);
// Calculate the start_angle (angle1) and the sweep_angle (dangle)
//------------------------
double ux = (x1 - cx1) / rx;
double uy = (y1 - cy1) / ry;
double vx = (-x1 - cx1) / rx;
double vy = (-y1 - cy1) / ry;
double p, n;
// Calculate the angle start
//------------------------
n = sqrt(ux*ux + uy*uy);
p = ux; // (1 * ux) + (0 * uy)
sign = (uy < 0) ? -1.0 : 1.0;
double v = p / n;
if(v < -1.0) v = -1.0;
if(v > 1.0) v = 1.0;
double start_angle = sign * acos(v);
// Calculate the sweep angle
//------------------------
n = sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy));
p = ux * vx + uy * vy;
sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0;
v = p / n;
if(v < -1.0) v = -1.0;
if(v > 1.0) v = 1.0;
double sweep_angle = sign * acos(v);
if(!sweep_flag && sweep_angle > 0)
{
sweep_angle -= pi * 2.0;
}
else
if (sweep_flag && sweep_angle < 0)
sweep_angle -= pi * 2.0;
}
else
if (sweep_flag && sweep_angle < 0)
{
sweep_angle += pi * 2.0;
}
// We can now build and transform the resulting arc
//------------------------
m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle);
trans_affine mtx = trans_affine_rotation(angle);
mtx *= trans_affine_translation(cx, cy);
for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2)
{
mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1);
}
// We can now build and transform the resulting arc
//------------------------
m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle);
trans_affine mtx = trans_affine_rotation(angle);
mtx *= trans_affine_translation(cx, cy);
// We must make sure that the starting and ending points
// exactly coincide with the initial (x0,y0) and (x2,y2)
m_arc.vertices()[0] = x0;
m_arc.vertices()[1] = y0;
if(m_arc.num_vertices() > 2)
{
m_arc.vertices()[m_arc.num_vertices() - 2] = x2;
m_arc.vertices()[m_arc.num_vertices() - 1] = y2;
}
for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2)
{
mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1);
}
// We must make sure that the starting and ending points
// exactly coincide with the initial (x0,y0) and (x2,y2)
m_arc.vertices()[0] = x0;
m_arc.vertices()[1] = y0;
if(m_arc.num_vertices() > 2)
{
m_arc.vertices()[m_arc.num_vertices() - 2] = x2;
m_arc.vertices()[m_arc.num_vertices() - 1] = y2;
}
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -21,242 +21,242 @@
namespace agg
{
//------------------------------------------------------------------------
bspline::bspline() :
m_max(0),
m_num(0),
m_x(0),
m_y(0),
m_last_idx(-1)
{
}
//------------------------------------------------------------------------
bspline::bspline() :
m_max(0),
m_num(0),
m_x(0),
m_y(0),
m_last_idx(-1)
{
}
//------------------------------------------------------------------------
bspline::bspline(int num) :
m_max(0),
m_num(0),
m_x(0),
m_y(0),
m_last_idx(-1)
//------------------------------------------------------------------------
bspline::bspline(int num) :
m_max(0),
m_num(0),
m_x(0),
m_y(0),
m_last_idx(-1)
{
init(num);
}
//------------------------------------------------------------------------
bspline::bspline(int num, const double* x, const double* y) :
m_max(0),
m_num(0),
m_x(0),
m_y(0),
m_last_idx(-1)
{
init(num, x, y);
}
//------------------------------------------------------------------------
void bspline::init(int max)
{
if(max > 2 && max > m_max)
{
m_am.resize(max * 3);
m_max = max;
m_x = &m_am[m_max];
m_y = &m_am[m_max * 2];
}
m_num = 0;
m_last_idx = -1;
}
//------------------------------------------------------------------------
void bspline::add_point(double x, double y)
{
if(m_num < m_max)
{
m_x[m_num] = x;
m_y[m_num] = y;
++m_num;
}
}
//------------------------------------------------------------------------
void bspline::prepare()
{
if(m_num > 2)
{
int i, k, n1;
double* temp;
double* r;
double* s;
double h, p, d, f, e;
for(k = 0; k < m_num; k++)
{
m_am[k] = 0.0;
}
n1 = 3 * m_num;
pod_array<double> al(n1);
temp = &al[0];
for(k = 0; k < n1; k++)
{
temp[k] = 0.0;
}
r = temp + m_num;
s = temp + m_num * 2;
n1 = m_num - 1;
d = m_x[1] - m_x[0];
e = (m_y[1] - m_y[0]) / d;
for(k = 1; k < n1; k++)
{
h = d;
d = m_x[k + 1] - m_x[k];
f = e;
e = (m_y[k + 1] - m_y[k]) / d;
al[k] = d / (d + h);
r[k] = 1.0 - al[k];
s[k] = 6.0 * (e - f) / (h + d);
}
for(k = 1; k < n1; k++)
{
p = 1.0 / (r[k] * al[k - 1] + 2.0);
al[k] *= -p;
s[k] = (s[k] - r[k] * s[k - 1]) * p;
}
m_am[n1] = 0.0;
al[n1 - 1] = s[n1 - 1];
m_am[n1 - 1] = al[n1 - 1];
for(k = n1 - 2, i = 0; i < m_num - 2; i++, k--)
{
al[k] = al[k] * al[k + 1] + s[k];
m_am[k] = al[k];
}
}
m_last_idx = -1;
}
//------------------------------------------------------------------------
void bspline::init(int num, const double* x, const double* y)
{
if(num > 2)
{
init(num);
}
//------------------------------------------------------------------------
bspline::bspline(int num, const double* x, const double* y) :
m_max(0),
m_num(0),
m_x(0),
m_y(0),
m_last_idx(-1)
{
init(num, x, y);
}
//------------------------------------------------------------------------
void bspline::init(int max)
{
if(max > 2 && max > m_max)
int i;
for(i = 0; i < num; i++)
{
m_am.resize(max * 3);
m_max = max;
m_x = &m_am[m_max];
m_y = &m_am[m_max * 2];
add_point(*x++, *y++);
}
m_num = 0;
m_last_idx = -1;
prepare();
}
m_last_idx = -1;
}
//------------------------------------------------------------------------
void bspline::add_point(double x, double y)
//------------------------------------------------------------------------
void bspline::bsearch(int n, const double *x, double x0, int *i)
{
int j = n - 1;
int k;
for(*i = 0; (j - *i) > 1; )
{
if(m_num < m_max)
if(x0 < x[k = (*i + j) >> 1]) j = k;
else *i = k;
}
}
//------------------------------------------------------------------------
double bspline::interpolation(double x, int i) const
{
int j = i + 1;
double d = m_x[i] - m_x[j];
double h = x - m_x[j];
double r = m_x[i] - x;
double p = d * d / 6.0;
return (m_am[j] * r * r * r + m_am[i] * h * h * h) / 6.0 / d +
((m_y[j] - m_am[j] * p) * r + (m_y[i] - m_am[i] * p) * h) / d;
}
//------------------------------------------------------------------------
double bspline::extrapolation_left(double x) const
{
double d = m_x[1] - m_x[0];
return (-d * m_am[1] / 6 + (m_y[1] - m_y[0]) / d) *
(x - m_x[0]) +
m_y[0];
}
//------------------------------------------------------------------------
double bspline::extrapolation_right(double x) const
{
double d = m_x[m_num - 1] - m_x[m_num - 2];
return (d * m_am[m_num - 2] / 6 + (m_y[m_num - 1] - m_y[m_num - 2]) / d) *
(x - m_x[m_num - 1]) +
m_y[m_num - 1];
}
//------------------------------------------------------------------------
double bspline::get(double x) const
{
if(m_num > 2)
{
int i;
// Extrapolation on the left
if(x < m_x[0]) return extrapolation_left(x);
// Extrapolation on the right
if(x >= m_x[m_num - 1]) return extrapolation_right(x);
// Interpolation
bsearch(m_num, m_x, x, &i);
return interpolation(x, i);
}
return 0.0;
}
//------------------------------------------------------------------------
double bspline::get_stateful(double x) const
{
if(m_num > 2)
{
// Extrapolation on the left
if(x < m_x[0]) return extrapolation_left(x);
// Extrapolation on the right
if(x >= m_x[m_num - 1]) return extrapolation_right(x);
if(m_last_idx >= 0)
{
m_x[m_num] = x;
m_y[m_num] = y;
++m_num;
}
}
//------------------------------------------------------------------------
void bspline::prepare()
{
if(m_num > 2)
{
int i, k, n1;
double* temp;
double* r;
double* s;
double h, p, d, f, e;
for(k = 0; k < m_num; k++)
// Check if x is not in current range
if(x < m_x[m_last_idx] || x > m_x[m_last_idx + 1])
{
m_am[k] = 0.0;
}
n1 = 3 * m_num;
pod_array<double> al(n1);
temp = &al[0];
for(k = 0; k < n1; k++)
{
temp[k] = 0.0;
}
r = temp + m_num;
s = temp + m_num * 2;
n1 = m_num - 1;
d = m_x[1] - m_x[0];
e = (m_y[1] - m_y[0]) / d;
for(k = 1; k < n1; k++)
{
h = d;
d = m_x[k + 1] - m_x[k];
f = e;
e = (m_y[k + 1] - m_y[k]) / d;
al[k] = d / (d + h);
r[k] = 1.0 - al[k];
s[k] = 6.0 * (e - f) / (h + d);
}
for(k = 1; k < n1; k++)
{
p = 1.0 / (r[k] * al[k - 1] + 2.0);
al[k] *= -p;
s[k] = (s[k] - r[k] * s[k - 1]) * p;
}
m_am[n1] = 0.0;
al[n1 - 1] = s[n1 - 1];
m_am[n1 - 1] = al[n1 - 1];
for(k = n1 - 2, i = 0; i < m_num - 2; i++, k--)
{
al[k] = al[k] * al[k + 1] + s[k];
m_am[k] = al[k];
}
}
m_last_idx = -1;
}
//------------------------------------------------------------------------
void bspline::init(int num, const double* x, const double* y)
{
if(num > 2)
{
init(num);
int i;
for(i = 0; i < num; i++)
{
add_point(*x++, *y++);
}
prepare();
}
m_last_idx = -1;
}
//------------------------------------------------------------------------
void bspline::bsearch(int n, const double *x, double x0, int *i)
{
int j = n - 1;
int k;
for(*i = 0; (j - *i) > 1; )
{
if(x0 < x[k = (*i + j) >> 1]) j = k;
else *i = k;
}
}
//------------------------------------------------------------------------
double bspline::interpolation(double x, int i) const
{
int j = i + 1;
double d = m_x[i] - m_x[j];
double h = x - m_x[j];
double r = m_x[i] - x;
double p = d * d / 6.0;
return (m_am[j] * r * r * r + m_am[i] * h * h * h) / 6.0 / d +
((m_y[j] - m_am[j] * p) * r + (m_y[i] - m_am[i] * p) * h) / d;
}
//------------------------------------------------------------------------
double bspline::extrapolation_left(double x) const
{
double d = m_x[1] - m_x[0];
return (-d * m_am[1] / 6 + (m_y[1] - m_y[0]) / d) *
(x - m_x[0]) +
m_y[0];
}
//------------------------------------------------------------------------
double bspline::extrapolation_right(double x) const
{
double d = m_x[m_num - 1] - m_x[m_num - 2];
return (d * m_am[m_num - 2] / 6 + (m_y[m_num - 1] - m_y[m_num - 2]) / d) *
(x - m_x[m_num - 1]) +
m_y[m_num - 1];
}
//------------------------------------------------------------------------
double bspline::get(double x) const
{
if(m_num > 2)
{
int i;
// Extrapolation on the left
if(x < m_x[0]) return extrapolation_left(x);
// Extrapolation on the right
if(x >= m_x[m_num - 1]) return extrapolation_right(x);
// Interpolation
bsearch(m_num, m_x, x, &i);
return interpolation(x, i);
}
return 0.0;
}
//------------------------------------------------------------------------
double bspline::get_stateful(double x) const
{
if(m_num > 2)
{
// Extrapolation on the left
if(x < m_x[0]) return extrapolation_left(x);
// Extrapolation on the right
if(x >= m_x[m_num - 1]) return extrapolation_right(x);
if(m_last_idx >= 0)
{
// Check if x is not in current range
if(x < m_x[m_last_idx] || x > m_x[m_last_idx + 1])
// Check if x between next points (most probably)
if(m_last_idx < m_num - 2 &&
x >= m_x[m_last_idx + 1] &&
x <= m_x[m_last_idx + 2])
{
// Check if x between next points (most probably)
if(m_last_idx < m_num - 2 &&
x >= m_x[m_last_idx + 1] &&
x <= m_x[m_last_idx + 2])
{
++m_last_idx;
}
else
if(m_last_idx > 0 &&
x >= m_x[m_last_idx - 1] &&
++m_last_idx;
}
else
if(m_last_idx > 0 &&
x >= m_x[m_last_idx - 1] &&
x <= m_x[m_last_idx])
{
// x is between pevious points
@ -267,18 +267,18 @@ namespace agg
// Else perform full search
bsearch(m_num, m_x, x, &m_last_idx);
}
}
return interpolation(x, m_last_idx);
}
else
{
// Interpolation
bsearch(m_num, m_x, x, &m_last_idx);
return interpolation(x, m_last_idx);
}
return interpolation(x, m_last_idx);
}
else
{
// Interpolation
bsearch(m_num, m_x, x, &m_last_idx);
return interpolation(x, m_last_idx);
}
return 0.0;
}
return 0.0;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -23,81 +23,81 @@
namespace agg
{
//--------------------------------------------------------------------
void image_filter_lut::realloc_lut(double radius)
//--------------------------------------------------------------------
void image_filter_lut::realloc_lut(double radius)
{
m_radius = radius;
m_diameter = uceil(radius) * 2;
m_start = -int(m_diameter / 2 - 1);
unsigned size = m_diameter << image_subpixel_shift;
if(size > m_weight_array.size())
{
m_radius = radius;
m_diameter = uceil(radius) * 2;
m_start = -int(m_diameter / 2 - 1);
unsigned size = m_diameter << image_subpixel_shift;
if(size > m_weight_array.size())
{
m_weight_array.resize(size);
}
m_weight_array.resize(size);
}
}
//--------------------------------------------------------------------
// This function normalizes integer values and corrects the rounding
// errors. It doesn't do anything with the source floating point values
// (m_weight_array_dbl), it corrects only integers according to the rule
// of 1.0 which means that any sum of pixel weights must be equal to 1.0.
// So, the filter function must produce a graph of the proper shape.
//--------------------------------------------------------------------
void image_filter_lut::normalize()
//--------------------------------------------------------------------
// This function normalizes integer values and corrects the rounding
// errors. It doesn't do anything with the source floating point values
// (m_weight_array_dbl), it corrects only integers according to the rule
// of 1.0 which means that any sum of pixel weights must be equal to 1.0.
// So, the filter function must produce a graph of the proper shape.
//--------------------------------------------------------------------
void image_filter_lut::normalize()
{
unsigned i;
int flip = 1;
for(i = 0; i < image_subpixel_scale; i++)
{
unsigned i;
int flip = 1;
for(i = 0; i < image_subpixel_scale; i++)
for(;;)
{
for(;;)
int sum = 0;
unsigned j;
for(j = 0; j < m_diameter; j++)
{
int sum = 0;
unsigned j;
for(j = 0; j < m_diameter; j++)
sum += m_weight_array[j * image_subpixel_scale + i];
}
if(sum == image_filter_scale) break;
double k = double(image_filter_scale) / double(sum);
sum = 0;
for(j = 0; j < m_diameter; j++)
{
sum += m_weight_array[j * image_subpixel_scale + i] =
iround(m_weight_array[j * image_subpixel_scale + i] * k);
}
sum -= image_filter_scale;
int inc = (sum > 0) ? -1 : 1;
for(j = 0; j < m_diameter && sum; j++)
{
flip ^= 1;
unsigned idx = flip ? m_diameter/2 + j/2 : m_diameter/2 - j/2;
int v = m_weight_array[idx * image_subpixel_scale + i];
if(v < image_filter_scale)
{
sum += m_weight_array[j * image_subpixel_scale + i];
}
if(sum == image_filter_scale) break;
double k = double(image_filter_scale) / double(sum);
sum = 0;
for(j = 0; j < m_diameter; j++)
{
sum += m_weight_array[j * image_subpixel_scale + i] =
iround(m_weight_array[j * image_subpixel_scale + i] * k);
}
sum -= image_filter_scale;
int inc = (sum > 0) ? -1 : 1;
for(j = 0; j < m_diameter && sum; j++)
{
flip ^= 1;
unsigned idx = flip ? m_diameter/2 + j/2 : m_diameter/2 - j/2;
int v = m_weight_array[idx * image_subpixel_scale + i];
if(v < image_filter_scale)
{
m_weight_array[idx * image_subpixel_scale + i] += inc;
sum += inc;
}
m_weight_array[idx * image_subpixel_scale + i] += inc;
sum += inc;
}
}
}
unsigned pivot = m_diameter << (image_subpixel_shift - 1);
for(i = 0; i < pivot; i++)
{
m_weight_array[pivot + i] = m_weight_array[pivot - i];
}
unsigned end = (diameter() << image_subpixel_shift) - 1;
m_weight_array[0] = m_weight_array[end];
}
unsigned pivot = m_diameter << (image_subpixel_shift - 1);
for(i = 0; i < pivot; i++)
{
m_weight_array[pivot + i] = m_weight_array[pivot - i];
}
unsigned end = (diameter() << image_subpixel_shift) - 1;
m_weight_array[0] = m_weight_array[end];
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -18,65 +18,65 @@
namespace agg
{
//-------------------------------------------------------------------------
// The number of the octant is determined as a 3-bit value as follows:
// bit 0 = vertical flag
// bit 1 = sx < 0
// bit 2 = sy < 0
//
// [N] shows the number of the orthogonal quadrant
// <M> shows the number of the diagonal quadrant
// <1>
// [1] | [0]
// . (3)011 | 001(1) .
// . | .
// . | .
// . | .
// (2)010 .|. 000(0)
// <2> ----------.+.----------- <0>
// (6)110 . | . 100(4)
// . | .
// . | .
// . | .
// (7)111 | 101(5)
// [2] | [3]
// <3>
// 0,1,2,3,4,5,6,7
const int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 };
const int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 };
//-------------------------------------------------------------------------
// The number of the octant is determined as a 3-bit value as follows:
// bit 0 = vertical flag
// bit 1 = sx < 0
// bit 2 = sy < 0
//
// [N] shows the number of the orthogonal quadrant
// <M> shows the number of the diagonal quadrant
// <1>
// [1] | [0]
// . (3)011 | 001(1) .
// . | .
// . | .
// . | .
// (2)010 .|. 000(0)
// <2> ----------.+.----------- <0>
// (6)110 . | . 100(4)
// . | .
// . | .
// . | .
// (7)111 | 101(5)
// [2] | [3]
// <3>
// 0,1,2,3,4,5,6,7
const int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 };
const int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 };
//-------------------------------------------------------------------------
void bisectrix(const line_parameters& l1,
const line_parameters& l2,
int* x, int* y)
//-------------------------------------------------------------------------
void bisectrix(const line_parameters& l1,
const line_parameters& l2,
int* x, int* y)
{
double k = double(l2.len) / double(l1.len);
double tx = l2.x2 - (l2.x1 - l1.x1) * k;
double ty = l2.y2 - (l2.y1 - l1.y1) * k;
//All bisectrices must be on the right of the line
//If the next point is on the left (l1 => l2.2)
//then the bisectix should be rotated by 180 degrees.
if(double(l2.x2 - l2.x1) * double(l2.y1 - l1.y1) <
double(l2.y2 - l2.y1) * double(l2.x1 - l1.x1) + 100.0)
{
double k = double(l2.len) / double(l1.len);
double tx = l2.x2 - (l2.x1 - l1.x1) * k;
double ty = l2.y2 - (l2.y1 - l1.y1) * k;
//All bisectrices must be on the right of the line
//If the next point is on the left (l1 => l2.2)
//then the bisectix should be rotated by 180 degrees.
if(double(l2.x2 - l2.x1) * double(l2.y1 - l1.y1) <
double(l2.y2 - l2.y1) * double(l2.x1 - l1.x1) + 100.0)
{
tx -= (tx - l2.x1) * 2.0;
ty -= (ty - l2.y1) * 2.0;
}
// Check if the bisectrix is too short
double dx = tx - l2.x1;
double dy = ty - l2.y1;
if((int)sqrt(dx * dx + dy * dy) < line_subpixel_scale)
{
*x = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) >> 1;
*y = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) >> 1;
return;
}
*x = iround(tx);
*y = iround(ty);
tx -= (tx - l2.x1) * 2.0;
ty -= (ty - l2.y1) * 2.0;
}
// Check if the bisectrix is too short
double dx = tx - l2.x1;
double dy = ty - l2.y1;
if((int)sqrt(dx * dx + dy * dy) < line_subpixel_scale)
{
*x = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) >> 1;
*y = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) >> 1;
return;
}
*x = iround(tx);
*y = iround(ty);
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -18,99 +18,99 @@
namespace agg
{
//---------------------------------------------------------------------
void line_profile_aa::width(double w)
//---------------------------------------------------------------------
void line_profile_aa::width(double w)
{
if(w < 0.0) w = 0.0;
if(w < m_smoother_width) w += w;
else w += m_smoother_width;
w *= 0.5;
w -= m_smoother_width;
double s = m_smoother_width;
if(w < 0.0)
{
if(w < 0.0) w = 0.0;
s += w;
w = 0.0;
}
set(w, s);
}
if(w < m_smoother_width) w += w;
else w += m_smoother_width;
w *= 0.5;
//---------------------------------------------------------------------
line_profile_aa::value_type* line_profile_aa::profile(double w)
{
m_subpixel_width = uround(w * subpixel_scale);
unsigned size = m_subpixel_width + subpixel_scale * 6;
if(size > m_profile.size())
{
m_profile.resize(size);
}
return &m_profile[0];
}
w -= m_smoother_width;
double s = m_smoother_width;
if(w < 0.0)
{
s += w;
w = 0.0;
}
set(w, s);
//---------------------------------------------------------------------
void line_profile_aa::set(double center_width, double smoother_width)
{
double base_val = 1.0;
if(center_width == 0.0) center_width = 1.0 / subpixel_scale;
if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale;
double width = center_width + smoother_width;
if(width < m_min_width)
{
double k = width / m_min_width;
base_val *= k;
center_width /= k;
smoother_width /= k;
}
value_type* ch = profile(center_width + smoother_width);
//---------------------------------------------------------------------
line_profile_aa::value_type* line_profile_aa::profile(double w)
unsigned subpixel_center_width = unsigned(center_width * subpixel_scale);
unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale);
value_type* ch_center = ch + subpixel_scale*2;
value_type* ch_smoother = ch_center + subpixel_center_width;
unsigned i;
unsigned val = m_gamma[unsigned(base_val * aa_mask)];
ch = ch_center;
for(i = 0; i < subpixel_center_width; i++)
{
m_subpixel_width = uround(w * subpixel_scale);
unsigned size = m_subpixel_width + subpixel_scale * 6;
if(size > m_profile.size())
{
m_profile.resize(size);
}
return &m_profile[0];
*ch++ = (value_type)val;
}
//---------------------------------------------------------------------
void line_profile_aa::set(double center_width, double smoother_width)
for(i = 0; i < subpixel_smoother_width; i++)
{
double base_val = 1.0;
if(center_width == 0.0) center_width = 1.0 / subpixel_scale;
if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale;
double width = center_width + smoother_width;
if(width < m_min_width)
{
double k = width / m_min_width;
base_val *= k;
center_width /= k;
smoother_width /= k;
}
value_type* ch = profile(center_width + smoother_width);
unsigned subpixel_center_width = unsigned(center_width * subpixel_scale);
unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale);
value_type* ch_center = ch + subpixel_scale*2;
value_type* ch_smoother = ch_center + subpixel_center_width;
unsigned i;
unsigned val = m_gamma[unsigned(base_val * aa_mask)];
ch = ch_center;
for(i = 0; i < subpixel_center_width; i++)
{
*ch++ = (value_type)val;
}
for(i = 0; i < subpixel_smoother_width; i++)
{
*ch_smoother++ =
m_gamma[unsigned((base_val -
base_val *
(double(i) / subpixel_smoother_width)) * aa_mask)];
}
unsigned n_smoother = profile_size() -
subpixel_smoother_width -
subpixel_center_width -
subpixel_scale*2;
val = m_gamma[0];
for(i = 0; i < n_smoother; i++)
{
*ch_smoother++ = (value_type)val;
}
ch = ch_center;
for(i = 0; i < subpixel_scale*2; i++)
{
*--ch = *ch_center++;
}
*ch_smoother++ =
m_gamma[unsigned((base_val -
base_val *
(double(i) / subpixel_smoother_width)) * aa_mask)];
}
unsigned n_smoother = profile_size() -
subpixel_smoother_width -
subpixel_center_width -
subpixel_scale*2;
val = m_gamma[0];
for(i = 0; i < n_smoother; i++)
{
*ch_smoother++ = (value_type)val;
}
ch = ch_center;
for(i = 0; i < subpixel_scale*2; i++)
{
*--ch = *ch_center++;
}
}
}

View file

@ -9,8 +9,8 @@ namespace agg
template<class ColorT, class Order>
void comp_op_rgba_hue<ColorT,Order>::blend_pix(value_type* p,
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
{
if (cover < 255)
{
@ -41,8 +41,8 @@ void comp_op_rgba_hue<ColorT,Order>::blend_pix(value_type* p,
template<class ColorT, class Order>
void comp_op_rgba_saturation<ColorT,Order>::blend_pix(value_type* p,
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
{
if (cover < 255)
{
@ -73,8 +73,8 @@ void comp_op_rgba_saturation<ColorT,Order>::blend_pix(value_type* p,
template<class ColorT, class Order>
void comp_op_rgba_color<ColorT,Order>::blend_pix(value_type* p,
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
{
if (cover < 255)
{
@ -106,8 +106,8 @@ void comp_op_rgba_color<ColorT,Order>::blend_pix(value_type* p,
template<class ColorT, class Order>
void comp_op_rgba_value<ColorT,Order>::blend_pix(value_type* p,
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
unsigned sr, unsigned sg, unsigned sb,
unsigned sa, unsigned cover)
{
if (cover < 255)
{
@ -144,4 +144,4 @@ template struct comp_op_rgba_value<agg::rgba8, agg::order_rgba>;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -23,141 +23,141 @@
namespace agg
{
//------------------------------------------------------------------------
rounded_rect::rounded_rect(double x1, double y1, double x2, double y2, double r) :
m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2),
m_rx1(r), m_ry1(r), m_rx2(r), m_ry2(r),
m_rx3(r), m_ry3(r), m_rx4(r), m_ry4(r)
//------------------------------------------------------------------------
rounded_rect::rounded_rect(double x1, double y1, double x2, double y2, double r) :
m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2),
m_rx1(r), m_ry1(r), m_rx2(r), m_ry2(r),
m_rx3(r), m_ry3(r), m_rx4(r), m_ry4(r)
{
if(x1 > x2) { m_x1 = x2; m_x2 = x1; }
if(y1 > y2) { m_y1 = y2; m_y2 = y1; }
}
//--------------------------------------------------------------------
void rounded_rect::rect(double x1, double y1, double x2, double y2)
{
m_x1 = x1;
m_y1 = y1;
m_x2 = x2;
m_y2 = y2;
if(x1 > x2) { m_x1 = x2; m_x2 = x1; }
if(y1 > y2) { m_y1 = y2; m_y2 = y1; }
}
//--------------------------------------------------------------------
void rounded_rect::radius(double r)
{
m_rx1 = m_ry1 = m_rx2 = m_ry2 = m_rx3 = m_ry3 = m_rx4 = m_ry4 = r;
}
//--------------------------------------------------------------------
void rounded_rect::radius(double rx, double ry)
{
m_rx1 = m_rx2 = m_rx3 = m_rx4 = rx;
m_ry1 = m_ry2 = m_ry3 = m_ry4 = ry;
}
//--------------------------------------------------------------------
void rounded_rect::radius(double rx_bottom, double ry_bottom,
double rx_top, double ry_top)
{
m_rx1 = m_rx2 = rx_bottom;
m_rx3 = m_rx4 = rx_top;
m_ry1 = m_ry2 = ry_bottom;
m_ry3 = m_ry4 = ry_top;
}
//--------------------------------------------------------------------
void rounded_rect::radius(double rx1, double ry1, double rx2, double ry2,
double rx3, double ry3, double rx4, double ry4)
{
m_rx1 = rx1; m_ry1 = ry1; m_rx2 = rx2; m_ry2 = ry2;
m_rx3 = rx3; m_ry3 = ry3; m_rx4 = rx4; m_ry4 = ry4;
}
//--------------------------------------------------------------------
void rounded_rect::normalize_radius()
{
double dx = fabs(m_x2 - m_x1);
double dy = fabs(m_y2 - m_y1);
double k = 1.0;
double t;
t = dx / (m_rx1 + m_rx2); if(t < k) k = t;
t = dx / (m_rx3 + m_rx4); if(t < k) k = t;
t = dy / (m_ry1 + m_ry2); if(t < k) k = t;
t = dy / (m_ry3 + m_ry4); if(t < k) k = t;
if(k < 1.0)
{
if(x1 > x2) { m_x1 = x2; m_x2 = x1; }
if(y1 > y2) { m_y1 = y2; m_y2 = y1; }
m_rx1 *= k; m_ry1 *= k; m_rx2 *= k; m_ry2 *= k;
m_rx3 *= k; m_ry3 *= k; m_rx4 *= k; m_ry4 *= k;
}
}
//--------------------------------------------------------------------
void rounded_rect::rect(double x1, double y1, double x2, double y2)
//--------------------------------------------------------------------
void rounded_rect::rewind(unsigned)
{
m_status = 0;
}
//--------------------------------------------------------------------
unsigned rounded_rect::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_stop;
switch(m_status)
{
m_x1 = x1;
m_y1 = y1;
m_x2 = x2;
m_y2 = y2;
if(x1 > x2) { m_x1 = x2; m_x2 = x1; }
if(y1 > y2) { m_y1 = y2; m_y2 = y1; }
}
//--------------------------------------------------------------------
void rounded_rect::radius(double r)
{
m_rx1 = m_ry1 = m_rx2 = m_ry2 = m_rx3 = m_ry3 = m_rx4 = m_ry4 = r;
}
//--------------------------------------------------------------------
void rounded_rect::radius(double rx, double ry)
{
m_rx1 = m_rx2 = m_rx3 = m_rx4 = rx;
m_ry1 = m_ry2 = m_ry3 = m_ry4 = ry;
}
//--------------------------------------------------------------------
void rounded_rect::radius(double rx_bottom, double ry_bottom,
double rx_top, double ry_top)
{
m_rx1 = m_rx2 = rx_bottom;
m_rx3 = m_rx4 = rx_top;
m_ry1 = m_ry2 = ry_bottom;
m_ry3 = m_ry4 = ry_top;
}
//--------------------------------------------------------------------
void rounded_rect::radius(double rx1, double ry1, double rx2, double ry2,
double rx3, double ry3, double rx4, double ry4)
{
m_rx1 = rx1; m_ry1 = ry1; m_rx2 = rx2; m_ry2 = ry2;
m_rx3 = rx3; m_ry3 = ry3; m_rx4 = rx4; m_ry4 = ry4;
}
//--------------------------------------------------------------------
void rounded_rect::normalize_radius()
{
double dx = fabs(m_x2 - m_x1);
double dy = fabs(m_y2 - m_y1);
double k = 1.0;
double t;
t = dx / (m_rx1 + m_rx2); if(t < k) k = t;
t = dx / (m_rx3 + m_rx4); if(t < k) k = t;
t = dy / (m_ry1 + m_ry2); if(t < k) k = t;
t = dy / (m_ry3 + m_ry4); if(t < k) k = t;
if(k < 1.0)
{
m_rx1 *= k; m_ry1 *= k; m_rx2 *= k; m_ry2 *= k;
m_rx3 *= k; m_ry3 *= k; m_rx4 *= k; m_ry4 *= k;
}
}
//--------------------------------------------------------------------
void rounded_rect::rewind(unsigned)
{
m_status = 0;
}
//--------------------------------------------------------------------
unsigned rounded_rect::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_stop;
switch(m_status)
{
case 0:
m_arc.init(m_x1 + m_rx1, m_y1 + m_ry1, m_rx1, m_ry1,
pi, pi+pi*0.5);
m_arc.rewind(0);
m_status++;
case 1:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return cmd;
case 2:
m_arc.init(m_x2 - m_rx2, m_y1 + m_ry2, m_rx2, m_ry2,
pi+pi*0.5, 0.0);
m_arc.rewind(0);
m_status++;
case 3:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return path_cmd_line_to;
case 4:
m_arc.init(m_x2 - m_rx3, m_y2 - m_ry3, m_rx3, m_ry3,
0.0, pi*0.5);
m_arc.rewind(0);
m_status++;
case 5:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return path_cmd_line_to;
case 6:
m_arc.init(m_x1 + m_rx4, m_y2 - m_ry4, m_rx4, m_ry4,
pi*0.5, pi);
m_arc.rewind(0);
m_status++;
case 7:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return path_cmd_line_to;
case 8:
cmd = path_cmd_end_poly | path_flags_close | path_flags_ccw;
m_status++;
break;
}
return cmd;
case 0:
m_arc.init(m_x1 + m_rx1, m_y1 + m_ry1, m_rx1, m_ry1,
pi, pi+pi*0.5);
m_arc.rewind(0);
m_status++;
case 1:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return cmd;
case 2:
m_arc.init(m_x2 - m_rx2, m_y1 + m_ry2, m_rx2, m_ry2,
pi+pi*0.5, 0.0);
m_arc.rewind(0);
m_status++;
case 3:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return path_cmd_line_to;
case 4:
m_arc.init(m_x2 - m_rx3, m_y2 - m_ry3, m_rx3, m_ry3,
0.0, pi*0.5);
m_arc.rewind(0);
m_status++;
case 5:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return path_cmd_line_to;
case 6:
m_arc.init(m_x1 + m_rx4, m_y2 - m_ry4, m_rx4, m_ry4,
pi*0.5, pi);
m_arc.rewind(0);
m_status++;
case 7:
cmd = m_arc.vertex(x, y);
if(is_stop(cmd)) m_status++;
else return path_cmd_line_to;
case 8:
cmd = path_cmd_end_poly | path_flags_close | path_flags_ccw;
m_status++;
break;
}
return cmd;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -21,95 +21,95 @@
namespace agg
{
int16u g_sqrt_table[1024] = //----------g_sqrt_table
{
0,
2048,2896,3547,4096,4579,5017,5418,5793,6144,6476,6792,7094,7384,7663,7932,8192,8444,
8689,8927,9159,9385,9606,9822,10033,10240,10443,10642,10837,11029,11217,11403,11585,
11765,11942,12116,12288,12457,12625,12790,12953,13114,13273,13430,13585,13738,13890,
14040,14189,14336,14482,14626,14768,14910,15050,15188,15326,15462,15597,15731,15864,
15995,16126,16255,16384,16512,16638,16764,16888,17012,17135,17257,17378,17498,17618,
17736,17854,17971,18087,18203,18318,18432,18545,18658,18770,18882,18992,19102,19212,
19321,19429,19537,19644,19750,19856,19961,20066,20170,20274,20377,20480,20582,20684,
20785,20886,20986,21085,21185,21283,21382,21480,21577,21674,21771,21867,21962,22058,
22153,22247,22341,22435,22528,22621,22713,22806,22897,22989,23080,23170,23261,23351,
23440,23530,23619,23707,23796,23884,23971,24059,24146,24232,24319,24405,24491,24576,
24661,24746,24831,24915,24999,25083,25166,25249,25332,25415,25497,25580,25661,25743,
25824,25905,25986,26067,26147,26227,26307,26387,26466,26545,26624,26703,26781,26859,
26937,27015,27092,27170,27247,27324,27400,27477,27553,27629,27705,27780,27856,27931,
28006,28081,28155,28230,28304,28378,28452,28525,28599,28672,28745,28818,28891,28963,
29035,29108,29180,29251,29323,29394,29466,29537,29608,29678,29749,29819,29890,29960,
30030,30099,30169,30238,30308,30377,30446,30515,30583,30652,30720,30788,30856,30924,
30992,31059,31127,31194,31261,31328,31395,31462,31529,31595,31661,31727,31794,31859,
31925,31991,32056,32122,32187,32252,32317,32382,32446,32511,32575,32640,32704,32768,
32832,32896,32959,33023,33086,33150,33213,33276,33339,33402,33465,33527,33590,33652,
33714,33776,33839,33900,33962,34024,34086,34147,34208,34270,34331,34392,34453,34514,
34574,34635,34695,34756,34816,34876,34936,34996,35056,35116,35176,35235,35295,35354,
35413,35472,35531,35590,35649,35708,35767,35825,35884,35942,36001,36059,36117,36175,
36233,36291,36348,36406,36464,36521,36578,36636,36693,36750,36807,36864,36921,36978,
37034,37091,37147,37204,37260,37316,37372,37429,37485,37540,37596,37652,37708,37763,
37819,37874,37929,37985,38040,38095,38150,38205,38260,38315,38369,38424,38478,38533,
38587,38642,38696,38750,38804,38858,38912,38966,39020,39073,39127,39181,39234,39287,
39341,39394,39447,39500,39553,39606,39659,39712,39765,39818,39870,39923,39975,40028,
40080,40132,40185,40237,40289,40341,40393,40445,40497,40548,40600,40652,40703,40755,
40806,40857,40909,40960,41011,41062,41113,41164,41215,41266,41317,41368,41418,41469,
41519,41570,41620,41671,41721,41771,41821,41871,41922,41972,42021,42071,42121,42171,
42221,42270,42320,42369,42419,42468,42518,42567,42616,42665,42714,42763,42813,42861,
42910,42959,43008,43057,43105,43154,43203,43251,43300,43348,43396,43445,43493,43541,
43589,43637,43685,43733,43781,43829,43877,43925,43972,44020,44068,44115,44163,44210,
44258,44305,44352,44400,44447,44494,44541,44588,44635,44682,44729,44776,44823,44869,
44916,44963,45009,45056,45103,45149,45195,45242,45288,45334,45381,45427,45473,45519,
45565,45611,45657,45703,45749,45795,45840,45886,45932,45977,46023,46069,46114,46160,
46205,46250,46296,46341,46386,46431,46477,46522,46567,46612,46657,46702,46746,46791,
46836,46881,46926,46970,47015,47059,47104,47149,47193,47237,47282,47326,47370,47415,
47459,47503,47547,47591,47635,47679,47723,47767,47811,47855,47899,47942,47986,48030,
48074,48117,48161,48204,48248,48291,48335,48378,48421,48465,48508,48551,48594,48637,
48680,48723,48766,48809,48852,48895,48938,48981,49024,49067,49109,49152,49195,49237,
49280,49322,49365,49407,49450,49492,49535,49577,49619,49661,49704,49746,49788,49830,
49872,49914,49956,49998,50040,50082,50124,50166,50207,50249,50291,50332,50374,50416,
50457,50499,50540,50582,50623,50665,50706,50747,50789,50830,50871,50912,50954,50995,
51036,51077,51118,51159,51200,51241,51282,51323,51364,51404,51445,51486,51527,51567,
51608,51649,51689,51730,51770,51811,51851,51892,51932,51972,52013,52053,52093,52134,
52174,52214,52254,52294,52334,52374,52414,52454,52494,52534,52574,52614,52654,52694,
52734,52773,52813,52853,52892,52932,52972,53011,53051,53090,53130,53169,53209,53248,
53287,53327,53366,53405,53445,53484,53523,53562,53601,53640,53679,53719,53758,53797,
53836,53874,53913,53952,53991,54030,54069,54108,54146,54185,54224,54262,54301,54340,
54378,54417,54455,54494,54532,54571,54609,54647,54686,54724,54762,54801,54839,54877,
54915,54954,54992,55030,55068,55106,55144,55182,55220,55258,55296,55334,55372,55410,
55447,55485,55523,55561,55599,55636,55674,55712,55749,55787,55824,55862,55900,55937,
55975,56012,56049,56087,56124,56162,56199,56236,56273,56311,56348,56385,56422,56459,
56497,56534,56571,56608,56645,56682,56719,56756,56793,56830,56867,56903,56940,56977,
57014,57051,57087,57124,57161,57198,57234,57271,57307,57344,57381,57417,57454,57490,
57527,57563,57599,57636,57672,57709,57745,57781,57817,57854,57890,57926,57962,57999,
58035,58071,58107,58143,58179,58215,58251,58287,58323,58359,58395,58431,58467,58503,
58538,58574,58610,58646,58682,58717,58753,58789,58824,58860,58896,58931,58967,59002,
59038,59073,59109,59144,59180,59215,59251,59286,59321,59357,59392,59427,59463,59498,
59533,59568,59603,59639,59674,59709,59744,59779,59814,59849,59884,59919,59954,59989,
60024,60059,60094,60129,60164,60199,60233,60268,60303,60338,60373,60407,60442,60477,
60511,60546,60581,60615,60650,60684,60719,60753,60788,60822,60857,60891,60926,60960,
60995,61029,61063,61098,61132,61166,61201,61235,61269,61303,61338,61372,61406,61440,
61474,61508,61542,61576,61610,61644,61678,61712,61746,61780,61814,61848,61882,61916,
61950,61984,62018,62051,62085,62119,62153,62186,62220,62254,62287,62321,62355,62388,
62422,62456,62489,62523,62556,62590,62623,62657,62690,62724,62757,62790,62824,62857,
62891,62924,62957,62991,63024,63057,63090,63124,63157,63190,63223,63256,63289,63323,
63356,63389,63422,63455,63488,63521,63554,63587,63620,63653,63686,63719,63752,63785,
63817,63850,63883,63916,63949,63982,64014,64047,64080,64113,64145,64178,64211,64243,
64276,64309,64341,64374,64406,64439,64471,64504,64536,64569,64601,64634,64666,64699,
64731,64763,64796,64828,64861,64893,64925,64957,64990,65022,65054,65086,65119,65151,
65183,65215,65247,65279,65312,65344,65376,65408,65440,65472,65504
};
int16u g_sqrt_table[1024] = //----------g_sqrt_table
{
0,
2048,2896,3547,4096,4579,5017,5418,5793,6144,6476,6792,7094,7384,7663,7932,8192,8444,
8689,8927,9159,9385,9606,9822,10033,10240,10443,10642,10837,11029,11217,11403,11585,
11765,11942,12116,12288,12457,12625,12790,12953,13114,13273,13430,13585,13738,13890,
14040,14189,14336,14482,14626,14768,14910,15050,15188,15326,15462,15597,15731,15864,
15995,16126,16255,16384,16512,16638,16764,16888,17012,17135,17257,17378,17498,17618,
17736,17854,17971,18087,18203,18318,18432,18545,18658,18770,18882,18992,19102,19212,
19321,19429,19537,19644,19750,19856,19961,20066,20170,20274,20377,20480,20582,20684,
20785,20886,20986,21085,21185,21283,21382,21480,21577,21674,21771,21867,21962,22058,
22153,22247,22341,22435,22528,22621,22713,22806,22897,22989,23080,23170,23261,23351,
23440,23530,23619,23707,23796,23884,23971,24059,24146,24232,24319,24405,24491,24576,
24661,24746,24831,24915,24999,25083,25166,25249,25332,25415,25497,25580,25661,25743,
25824,25905,25986,26067,26147,26227,26307,26387,26466,26545,26624,26703,26781,26859,
26937,27015,27092,27170,27247,27324,27400,27477,27553,27629,27705,27780,27856,27931,
28006,28081,28155,28230,28304,28378,28452,28525,28599,28672,28745,28818,28891,28963,
29035,29108,29180,29251,29323,29394,29466,29537,29608,29678,29749,29819,29890,29960,
30030,30099,30169,30238,30308,30377,30446,30515,30583,30652,30720,30788,30856,30924,
30992,31059,31127,31194,31261,31328,31395,31462,31529,31595,31661,31727,31794,31859,
31925,31991,32056,32122,32187,32252,32317,32382,32446,32511,32575,32640,32704,32768,
32832,32896,32959,33023,33086,33150,33213,33276,33339,33402,33465,33527,33590,33652,
33714,33776,33839,33900,33962,34024,34086,34147,34208,34270,34331,34392,34453,34514,
34574,34635,34695,34756,34816,34876,34936,34996,35056,35116,35176,35235,35295,35354,
35413,35472,35531,35590,35649,35708,35767,35825,35884,35942,36001,36059,36117,36175,
36233,36291,36348,36406,36464,36521,36578,36636,36693,36750,36807,36864,36921,36978,
37034,37091,37147,37204,37260,37316,37372,37429,37485,37540,37596,37652,37708,37763,
37819,37874,37929,37985,38040,38095,38150,38205,38260,38315,38369,38424,38478,38533,
38587,38642,38696,38750,38804,38858,38912,38966,39020,39073,39127,39181,39234,39287,
39341,39394,39447,39500,39553,39606,39659,39712,39765,39818,39870,39923,39975,40028,
40080,40132,40185,40237,40289,40341,40393,40445,40497,40548,40600,40652,40703,40755,
40806,40857,40909,40960,41011,41062,41113,41164,41215,41266,41317,41368,41418,41469,
41519,41570,41620,41671,41721,41771,41821,41871,41922,41972,42021,42071,42121,42171,
42221,42270,42320,42369,42419,42468,42518,42567,42616,42665,42714,42763,42813,42861,
42910,42959,43008,43057,43105,43154,43203,43251,43300,43348,43396,43445,43493,43541,
43589,43637,43685,43733,43781,43829,43877,43925,43972,44020,44068,44115,44163,44210,
44258,44305,44352,44400,44447,44494,44541,44588,44635,44682,44729,44776,44823,44869,
44916,44963,45009,45056,45103,45149,45195,45242,45288,45334,45381,45427,45473,45519,
45565,45611,45657,45703,45749,45795,45840,45886,45932,45977,46023,46069,46114,46160,
46205,46250,46296,46341,46386,46431,46477,46522,46567,46612,46657,46702,46746,46791,
46836,46881,46926,46970,47015,47059,47104,47149,47193,47237,47282,47326,47370,47415,
47459,47503,47547,47591,47635,47679,47723,47767,47811,47855,47899,47942,47986,48030,
48074,48117,48161,48204,48248,48291,48335,48378,48421,48465,48508,48551,48594,48637,
48680,48723,48766,48809,48852,48895,48938,48981,49024,49067,49109,49152,49195,49237,
49280,49322,49365,49407,49450,49492,49535,49577,49619,49661,49704,49746,49788,49830,
49872,49914,49956,49998,50040,50082,50124,50166,50207,50249,50291,50332,50374,50416,
50457,50499,50540,50582,50623,50665,50706,50747,50789,50830,50871,50912,50954,50995,
51036,51077,51118,51159,51200,51241,51282,51323,51364,51404,51445,51486,51527,51567,
51608,51649,51689,51730,51770,51811,51851,51892,51932,51972,52013,52053,52093,52134,
52174,52214,52254,52294,52334,52374,52414,52454,52494,52534,52574,52614,52654,52694,
52734,52773,52813,52853,52892,52932,52972,53011,53051,53090,53130,53169,53209,53248,
53287,53327,53366,53405,53445,53484,53523,53562,53601,53640,53679,53719,53758,53797,
53836,53874,53913,53952,53991,54030,54069,54108,54146,54185,54224,54262,54301,54340,
54378,54417,54455,54494,54532,54571,54609,54647,54686,54724,54762,54801,54839,54877,
54915,54954,54992,55030,55068,55106,55144,55182,55220,55258,55296,55334,55372,55410,
55447,55485,55523,55561,55599,55636,55674,55712,55749,55787,55824,55862,55900,55937,
55975,56012,56049,56087,56124,56162,56199,56236,56273,56311,56348,56385,56422,56459,
56497,56534,56571,56608,56645,56682,56719,56756,56793,56830,56867,56903,56940,56977,
57014,57051,57087,57124,57161,57198,57234,57271,57307,57344,57381,57417,57454,57490,
57527,57563,57599,57636,57672,57709,57745,57781,57817,57854,57890,57926,57962,57999,
58035,58071,58107,58143,58179,58215,58251,58287,58323,58359,58395,58431,58467,58503,
58538,58574,58610,58646,58682,58717,58753,58789,58824,58860,58896,58931,58967,59002,
59038,59073,59109,59144,59180,59215,59251,59286,59321,59357,59392,59427,59463,59498,
59533,59568,59603,59639,59674,59709,59744,59779,59814,59849,59884,59919,59954,59989,
60024,60059,60094,60129,60164,60199,60233,60268,60303,60338,60373,60407,60442,60477,
60511,60546,60581,60615,60650,60684,60719,60753,60788,60822,60857,60891,60926,60960,
60995,61029,61063,61098,61132,61166,61201,61235,61269,61303,61338,61372,61406,61440,
61474,61508,61542,61576,61610,61644,61678,61712,61746,61780,61814,61848,61882,61916,
61950,61984,62018,62051,62085,62119,62153,62186,62220,62254,62287,62321,62355,62388,
62422,62456,62489,62523,62556,62590,62623,62657,62690,62724,62757,62790,62824,62857,
62891,62924,62957,62991,63024,63057,63090,63124,63157,63190,63223,63256,63289,63323,
63356,63389,63422,63455,63488,63521,63554,63587,63620,63653,63686,63719,63752,63785,
63817,63850,63883,63916,63949,63982,64014,64047,64080,64113,64145,64178,64211,64243,
64276,64309,64341,64374,64406,64439,64471,64504,64536,64569,64601,64634,64666,64699,
64731,64763,64796,64828,64861,64893,64925,64957,64990,65022,65054,65086,65119,65151,
65183,65215,65247,65279,65312,65344,65376,65408,65440,65472,65504
};
int8 g_elder_bit_table[256] = //---------g_elder_bit_table
{
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};
int8 g_elder_bit_table[256] = //---------g_elder_bit_table
{
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -22,173 +22,173 @@
namespace agg
{
const trans_affine trans_affine::identity;
const trans_affine trans_affine::identity;
//------------------------------------------------------------------------
const trans_affine& trans_affine::parl_to_parl(const double* src,
const double* dst)
{
sx = src[2] - src[0];
shy = src[3] - src[1];
shx = src[4] - src[0];
sy = src[5] - src[1];
tx = src[0];
ty = src[1];
invert();
multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1],
dst[4] - dst[0], dst[5] - dst[1],
dst[0], dst[1]));
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::parl_to_parl(const double* src,
const double* dst)
{
sx = src[2] - src[0];
shy = src[3] - src[1];
shx = src[4] - src[0];
sy = src[5] - src[1];
tx = src[0];
ty = src[1];
invert();
multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1],
dst[4] - dst[0], dst[5] - dst[1],
dst[0], dst[1]));
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::rect_to_parl(double x1, double y1,
double x2, double y2,
const double* parl)
{
double src[6];
src[0] = x1; src[1] = y1;
src[2] = x2; src[3] = y1;
src[4] = x2; src[5] = y2;
parl_to_parl(src, parl);
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::rect_to_parl(double x1, double y1,
double x2, double y2,
const double* parl)
{
double src[6];
src[0] = x1; src[1] = y1;
src[2] = x2; src[3] = y1;
src[4] = x2; src[5] = y2;
parl_to_parl(src, parl);
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::parl_to_rect(const double* parl,
double x1, double y1,
double x2, double y2)
{
double dst[6];
dst[0] = x1; dst[1] = y1;
dst[2] = x2; dst[3] = y1;
dst[4] = x2; dst[5] = y2;
parl_to_parl(parl, dst);
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::parl_to_rect(const double* parl,
double x1, double y1,
double x2, double y2)
{
double dst[6];
dst[0] = x1; dst[1] = y1;
dst[2] = x2; dst[3] = y1;
dst[4] = x2; dst[5] = y2;
parl_to_parl(parl, dst);
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::multiply(const trans_affine& m)
{
double t0 = sx * m.sx + shy * m.shx;
double t2 = shx * m.sx + sy * m.shx;
double t4 = tx * m.sx + ty * m.shx + m.tx;
shy = sx * m.shy + shy * m.sy;
sy = shx * m.shy + sy * m.sy;
ty = tx * m.shy + ty * m.sy + m.ty;
sx = t0;
shx = t2;
tx = t4;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::multiply(const trans_affine& m)
{
double t0 = sx * m.sx + shy * m.shx;
double t2 = shx * m.sx + sy * m.shx;
double t4 = tx * m.sx + ty * m.shx + m.tx;
shy = sx * m.shy + shy * m.sy;
sy = shx * m.shy + sy * m.sy;
ty = tx * m.shy + ty * m.sy + m.ty;
sx = t0;
shx = t2;
tx = t4;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::invert()
{
double d = determinant_reciprocal();
//------------------------------------------------------------------------
const trans_affine& trans_affine::invert()
{
double d = determinant_reciprocal();
double t0 = sy * d;
sy = sx * d;
shy = -shy * d;
shx = -shx * d;
double t0 = sy * d;
sy = sx * d;
shy = -shy * d;
shx = -shx * d;
double t4 = -tx * t0 - ty * shx;
ty = -tx * shy - ty * sy;
double t4 = -tx * t0 - ty * shx;
ty = -tx * shy - ty * sy;
sx = t0;
tx = t4;
return *this;
}
sx = t0;
tx = t4;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::flip_x()
{
sx = -sx;
shy = -shy;
tx = -tx;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::flip_x()
{
sx = -sx;
shy = -shy;
tx = -tx;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::flip_y()
{
shx = -shx;
sy = -sy;
ty = -ty;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::flip_y()
{
shx = -shx;
sy = -sy;
ty = -ty;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::reset()
{
sx = sy = 1.0;
shy = shx = tx = ty = 0.0;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::reset()
{
sx = sy = 1.0;
shy = shx = tx = ty = 0.0;
return *this;
}
//------------------------------------------------------------------------
bool trans_affine::is_identity(double epsilon) const
{
return is_equal_eps(sx, 1.0, epsilon) &&
is_equal_eps(shy, 0.0, epsilon) &&
is_equal_eps(shx, 0.0, epsilon) &&
is_equal_eps(sy, 1.0, epsilon) &&
is_equal_eps(tx, 0.0, epsilon) &&
is_equal_eps(ty, 0.0, epsilon);
}
//------------------------------------------------------------------------
bool trans_affine::is_identity(double epsilon) const
{
return is_equal_eps(sx, 1.0, epsilon) &&
is_equal_eps(shy, 0.0, epsilon) &&
is_equal_eps(shx, 0.0, epsilon) &&
is_equal_eps(sy, 1.0, epsilon) &&
is_equal_eps(tx, 0.0, epsilon) &&
is_equal_eps(ty, 0.0, epsilon);
}
//------------------------------------------------------------------------
bool trans_affine::is_valid(double epsilon) const
{
return fabs(sx) > epsilon && fabs(sy) > epsilon;
}
//------------------------------------------------------------------------
bool trans_affine::is_valid(double epsilon) const
{
return fabs(sx) > epsilon && fabs(sy) > epsilon;
}
//------------------------------------------------------------------------
bool trans_affine::is_equal(const trans_affine& m, double epsilon) const
{
return is_equal_eps(sx, m.sx, epsilon) &&
is_equal_eps(shy, m.shy, epsilon) &&
is_equal_eps(shx, m.shx, epsilon) &&
is_equal_eps(sy, m.sy, epsilon) &&
is_equal_eps(tx, m.tx, epsilon) &&
is_equal_eps(ty, m.ty, epsilon);
}
//------------------------------------------------------------------------
bool trans_affine::is_equal(const trans_affine& m, double epsilon) const
{
return is_equal_eps(sx, m.sx, epsilon) &&
is_equal_eps(shy, m.shy, epsilon) &&
is_equal_eps(shx, m.shx, epsilon) &&
is_equal_eps(sy, m.sy, epsilon) &&
is_equal_eps(tx, m.tx, epsilon) &&
is_equal_eps(ty, m.ty, epsilon);
}
//------------------------------------------------------------------------
double trans_affine::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);
}
//------------------------------------------------------------------------
double trans_affine::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_affine::translation(double* dx, double* dy) const
{
*dx = tx;
*dy = ty;
}
//------------------------------------------------------------------------
void trans_affine::translation(double* dx, double* dy) const
{
*dx = tx;
*dy = ty;
}
//------------------------------------------------------------------------
void trans_affine::scaling(double* x, double* y) const
{
double x1 = 0.0;
double y1 = 0.0;
double x2 = 1.0;
double y2 = 1.0;
trans_affine t(*this);
t *= trans_affine_rotation(-rotation());
t.transform(&x1, &y1);
t.transform(&x2, &y2);
*x = x2 - x1;
*y = y2 - y1;
}
//------------------------------------------------------------------------
void trans_affine::scaling(double* x, double* y) const
{
double x1 = 0.0;
double y1 = 0.0;
double x2 = 1.0;
double y2 = 1.0;
trans_affine t(*this);
t *= trans_affine_rotation(-rotation());
t.transform(&x1, &y1);
t.transform(&x2, &y2);
*x = x2 - x1;
*y = y2 - y1;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -19,176 +19,176 @@
namespace agg
{
//------------------------------------------------------------------------
trans_double_path::trans_double_path() :
m_base_length(0.0),
m_base_height(1.0),
m_kindex1(0.0),
m_kindex2(0.0),
m_status1(initial),
m_status2(initial),
m_preserve_x_scale(true)
//------------------------------------------------------------------------
trans_double_path::trans_double_path() :
m_base_length(0.0),
m_base_height(1.0),
m_kindex1(0.0),
m_kindex2(0.0),
m_status1(initial),
m_status2(initial),
m_preserve_x_scale(true)
{
}
//------------------------------------------------------------------------
void trans_double_path::reset()
{
m_src_vertices1.remove_all();
m_src_vertices2.remove_all();
m_kindex1 = 0.0;
m_kindex1 = 0.0;
m_status1 = initial;
m_status2 = initial;
}
//------------------------------------------------------------------------
void trans_double_path::move_to1(double x, double y)
{
if(m_status1 == initial)
{
m_src_vertices1.modify_last(vertex_dist(x, y));
m_status1 = making_path;
}
//------------------------------------------------------------------------
void trans_double_path::reset()
else
{
m_src_vertices1.remove_all();
m_src_vertices2.remove_all();
m_kindex1 = 0.0;
m_kindex1 = 0.0;
m_status1 = initial;
m_status2 = initial;
line_to1(x, y);
}
}
//------------------------------------------------------------------------
void trans_double_path::move_to1(double x, double y)
//------------------------------------------------------------------------
void trans_double_path::line_to1(double x, double y)
{
if(m_status1 == making_path)
{
if(m_status1 == initial)
m_src_vertices1.add(vertex_dist(x, y));
}
}
//------------------------------------------------------------------------
void trans_double_path::move_to2(double x, double y)
{
if(m_status2 == initial)
{
m_src_vertices2.modify_last(vertex_dist(x, y));
m_status2 = making_path;
}
else
{
line_to2(x, y);
}
}
//------------------------------------------------------------------------
void trans_double_path::line_to2(double x, double y)
{
if(m_status2 == making_path)
{
m_src_vertices2.add(vertex_dist(x, y));
}
}
//------------------------------------------------------------------------
double trans_double_path::finalize_path(vertex_storage& vertices)
{
unsigned i;
double dist;
double d;
vertices.close(false);
if(vertices.size() > 2)
{
if(vertices[vertices.size() - 2].dist * 10.0 <
vertices[vertices.size() - 3].dist)
{
m_src_vertices1.modify_last(vertex_dist(x, y));
m_status1 = making_path;
}
else
{
line_to1(x, y);
d = vertices[vertices.size() - 3].dist +
vertices[vertices.size() - 2].dist;
vertices[vertices.size() - 2] =
vertices[vertices.size() - 1];
vertices.remove_last();
vertices[vertices.size() - 2].dist = d;
}
}
//------------------------------------------------------------------------
void trans_double_path::line_to1(double x, double y)
dist = 0;
for(i = 0; i < vertices.size(); i++)
{
if(m_status1 == making_path)
{
m_src_vertices1.add(vertex_dist(x, y));
}
vertex_dist& v = vertices[i];
d = v.dist;
v.dist = dist;
dist += d;
}
return (vertices.size() - 1) / dist;
}
//------------------------------------------------------------------------
void trans_double_path::move_to2(double x, double y)
//------------------------------------------------------------------------
void trans_double_path::finalize_paths()
{
if(m_status1 == making_path && m_src_vertices1.size() > 1 &&
m_status2 == making_path && m_src_vertices2.size() > 1)
{
if(m_status2 == initial)
{
m_src_vertices2.modify_last(vertex_dist(x, y));
m_status2 = making_path;
}
else
{
line_to2(x, y);
}
m_kindex1 = finalize_path(m_src_vertices1);
m_kindex2 = finalize_path(m_src_vertices2);
m_status1 = ready;
m_status2 = ready;
}
}
//------------------------------------------------------------------------
void trans_double_path::line_to2(double x, double y)
//------------------------------------------------------------------------
double trans_double_path::total_length1() const
{
if(m_base_length >= 1e-10) return m_base_length;
return (m_status1 == ready) ?
m_src_vertices1[m_src_vertices1.size() - 1].dist :
0.0;
}
//------------------------------------------------------------------------
double trans_double_path::total_length2() const
{
if(m_base_length >= 1e-10) return m_base_length;
return (m_status2 == ready) ?
m_src_vertices2[m_src_vertices2.size() - 1].dist :
0.0;
}
//------------------------------------------------------------------------
void trans_double_path::transform1(const vertex_storage& vertices,
double kindex, double kx,
double *x, double* y) const
{
double x1 = 0.0;
double y1 = 0.0;
double dx = 1.0;
double dy = 1.0;
double d = 0.0;
double dd = 1.0;
*x *= kx;
if(*x < 0.0)
{
if(m_status2 == making_path)
{
m_src_vertices2.add(vertex_dist(x, y));
}
// Extrapolation on the left
//--------------------------
x1 = vertices[0].x;
y1 = vertices[0].y;
dx = vertices[1].x - x1;
dy = vertices[1].y - y1;
dd = vertices[1].dist - vertices[0].dist;
d = *x;
}
//------------------------------------------------------------------------
double trans_double_path::finalize_path(vertex_storage& vertices)
{
unsigned i;
double dist;
double d;
vertices.close(false);
if(vertices.size() > 2)
{
if(vertices[vertices.size() - 2].dist * 10.0 <
vertices[vertices.size() - 3].dist)
{
d = vertices[vertices.size() - 3].dist +
vertices[vertices.size() - 2].dist;
vertices[vertices.size() - 2] =
vertices[vertices.size() - 1];
vertices.remove_last();
vertices[vertices.size() - 2].dist = d;
}
}
dist = 0;
for(i = 0; i < vertices.size(); i++)
{
vertex_dist& v = vertices[i];
d = v.dist;
v.dist = dist;
dist += d;
}
return (vertices.size() - 1) / dist;
}
//------------------------------------------------------------------------
void trans_double_path::finalize_paths()
{
if(m_status1 == making_path && m_src_vertices1.size() > 1 &&
m_status2 == making_path && m_src_vertices2.size() > 1)
{
m_kindex1 = finalize_path(m_src_vertices1);
m_kindex2 = finalize_path(m_src_vertices2);
m_status1 = ready;
m_status2 = ready;
}
}
//------------------------------------------------------------------------
double trans_double_path::total_length1() const
{
if(m_base_length >= 1e-10) return m_base_length;
return (m_status1 == ready) ?
m_src_vertices1[m_src_vertices1.size() - 1].dist :
0.0;
}
//------------------------------------------------------------------------
double trans_double_path::total_length2() const
{
if(m_base_length >= 1e-10) return m_base_length;
return (m_status2 == ready) ?
m_src_vertices2[m_src_vertices2.size() - 1].dist :
0.0;
}
//------------------------------------------------------------------------
void trans_double_path::transform1(const vertex_storage& vertices,
double kindex, double kx,
double *x, double* y) const
{
double x1 = 0.0;
double y1 = 0.0;
double dx = 1.0;
double dy = 1.0;
double d = 0.0;
double dd = 1.0;
*x *= kx;
if(*x < 0.0)
{
// Extrapolation on the left
//--------------------------
x1 = vertices[0].x;
y1 = vertices[0].y;
dx = vertices[1].x - x1;
dy = vertices[1].y - y1;
dd = vertices[1].dist - vertices[0].dist;
d = *x;
}
else
else
if(*x > vertices[vertices.size() - 1].dist)
{
// Extrapolation on the right
@ -211,13 +211,13 @@ namespace agg
if(m_preserve_x_scale)
{
unsigned k;
for(i = 0; (j - i) > 1; )
for(i = 0; (j - i) > 1; )
{
if(*x < vertices[k = (i + j) >> 1].dist)
if(*x < vertices[k = (i + j) >> 1].dist)
{
j = k;
j = k;
}
else
else
{
i = k;
}
@ -238,36 +238,36 @@ namespace agg
dx = vertices[j].x - x1;
dy = vertices[j].y - y1;
}
*x = x1 + dx * d / dd;
*y = y1 + dy * d / dd;
}
*x = x1 + dx * d / dd;
*y = y1 + dy * d / dd;
}
//------------------------------------------------------------------------
void trans_double_path::transform(double *x, double *y) const
//------------------------------------------------------------------------
void trans_double_path::transform(double *x, double *y) const
{
if(m_status1 == ready && m_status2 == ready)
{
if(m_status1 == ready && m_status2 == ready)
if(m_base_length > 1e-10)
{
if(m_base_length > 1e-10)
{
*x *= m_src_vertices1[m_src_vertices1.size() - 1].dist /
m_base_length;
}
double x1 = *x;
double y1 = *y;
double x2 = *x;
double y2 = *y;
double dd = m_src_vertices2[m_src_vertices2.size() - 1].dist /
m_src_vertices1[m_src_vertices1.size() - 1].dist;
transform1(m_src_vertices1, m_kindex1, 1.0, &x1, &y1);
transform1(m_src_vertices2, m_kindex2, dd, &x2, &y2);
*x = x1 + *y * (x2 - x1) / m_base_height;
*y = y1 + *y * (y2 - y1) / m_base_height;
*x *= m_src_vertices1[m_src_vertices1.size() - 1].dist /
m_base_length;
}
double x1 = *x;
double y1 = *y;
double x2 = *x;
double y2 = *y;
double dd = m_src_vertices2[m_src_vertices2.size() - 1].dist /
m_src_vertices1[m_src_vertices1.size() - 1].dist;
transform1(m_src_vertices1, m_kindex1, 1.0, &x1, &y1);
transform1(m_src_vertices2, m_kindex2, dd, &x2, &y2);
*x = x1 + *y * (x2 - x1) / m_base_height;
*y = y1 + *y * (y2 - y1) / m_base_height;
}
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -20,127 +20,127 @@
namespace agg
{
//------------------------------------------------------------------------
trans_single_path::trans_single_path() :
m_base_length(0.0),
m_kindex(0.0),
m_status(initial),
m_preserve_x_scale(true)
{
}
//------------------------------------------------------------------------
trans_single_path::trans_single_path() :
m_base_length(0.0),
m_kindex(0.0),
m_status(initial),
m_preserve_x_scale(true)
{
}
//------------------------------------------------------------------------
void trans_single_path::reset()
{
m_src_vertices.remove_all();
m_kindex = 0.0;
m_status = initial;
}
//------------------------------------------------------------------------
void trans_single_path::reset()
{
m_src_vertices.remove_all();
m_kindex = 0.0;
m_status = initial;
}
//------------------------------------------------------------------------
void trans_single_path::move_to(double x, double y)
//------------------------------------------------------------------------
void trans_single_path::move_to(double x, double y)
{
if(m_status == initial)
{
if(m_status == initial)
m_src_vertices.modify_last(vertex_dist(x, y));
m_status = making_path;
}
else
{
line_to(x, y);
}
}
//------------------------------------------------------------------------
void trans_single_path::line_to(double x, double y)
{
if(m_status == making_path)
{
m_src_vertices.add(vertex_dist(x, y));
}
}
//------------------------------------------------------------------------
void trans_single_path::finalize_path()
{
if(m_status == making_path && m_src_vertices.size() > 1)
{
unsigned i;
double dist;
double d;
m_src_vertices.close(false);
if(m_src_vertices.size() > 2)
{
m_src_vertices.modify_last(vertex_dist(x, y));
m_status = making_path;
if(m_src_vertices[m_src_vertices.size() - 2].dist * 10.0 <
m_src_vertices[m_src_vertices.size() - 3].dist)
{
d = m_src_vertices[m_src_vertices.size() - 3].dist +
m_src_vertices[m_src_vertices.size() - 2].dist;
m_src_vertices[m_src_vertices.size() - 2] =
m_src_vertices[m_src_vertices.size() - 1];
m_src_vertices.remove_last();
m_src_vertices[m_src_vertices.size() - 2].dist = d;
}
}
dist = 0.0;
for(i = 0; i < m_src_vertices.size(); i++)
{
vertex_dist& v = m_src_vertices[i];
double d = v.dist;
v.dist = dist;
dist += d;
}
m_kindex = (m_src_vertices.size() - 1) / dist;
m_status = ready;
}
}
//------------------------------------------------------------------------
double trans_single_path::total_length() const
{
if(m_base_length >= 1e-10) return m_base_length;
return (m_status == ready) ?
m_src_vertices[m_src_vertices.size() - 1].dist :
0.0;
}
//------------------------------------------------------------------------
void trans_single_path::transform(double *x, double *y) const
{
if(m_status == ready)
{
if(m_base_length > 1e-10)
{
*x *= m_src_vertices[m_src_vertices.size() - 1].dist /
m_base_length;
}
double x1 = 0.0;
double y1 = 0.0;
double dx = 1.0;
double dy = 1.0;
double d = 0.0;
double dd = 1.0;
if(*x < 0.0)
{
// Extrapolation on the left
//--------------------------
x1 = m_src_vertices[0].x;
y1 = m_src_vertices[0].y;
dx = m_src_vertices[1].x - x1;
dy = m_src_vertices[1].y - y1;
dd = m_src_vertices[1].dist - m_src_vertices[0].dist;
d = *x;
}
else
{
line_to(x, y);
}
}
//------------------------------------------------------------------------
void trans_single_path::line_to(double x, double y)
{
if(m_status == making_path)
{
m_src_vertices.add(vertex_dist(x, y));
}
}
//------------------------------------------------------------------------
void trans_single_path::finalize_path()
{
if(m_status == making_path && m_src_vertices.size() > 1)
{
unsigned i;
double dist;
double d;
m_src_vertices.close(false);
if(m_src_vertices.size() > 2)
{
if(m_src_vertices[m_src_vertices.size() - 2].dist * 10.0 <
m_src_vertices[m_src_vertices.size() - 3].dist)
{
d = m_src_vertices[m_src_vertices.size() - 3].dist +
m_src_vertices[m_src_vertices.size() - 2].dist;
m_src_vertices[m_src_vertices.size() - 2] =
m_src_vertices[m_src_vertices.size() - 1];
m_src_vertices.remove_last();
m_src_vertices[m_src_vertices.size() - 2].dist = d;
}
}
dist = 0.0;
for(i = 0; i < m_src_vertices.size(); i++)
{
vertex_dist& v = m_src_vertices[i];
double d = v.dist;
v.dist = dist;
dist += d;
}
m_kindex = (m_src_vertices.size() - 1) / dist;
m_status = ready;
}
}
//------------------------------------------------------------------------
double trans_single_path::total_length() const
{
if(m_base_length >= 1e-10) return m_base_length;
return (m_status == ready) ?
m_src_vertices[m_src_vertices.size() - 1].dist :
0.0;
}
//------------------------------------------------------------------------
void trans_single_path::transform(double *x, double *y) const
{
if(m_status == ready)
{
if(m_base_length > 1e-10)
{
*x *= m_src_vertices[m_src_vertices.size() - 1].dist /
m_base_length;
}
double x1 = 0.0;
double y1 = 0.0;
double dx = 1.0;
double dy = 1.0;
double d = 0.0;
double dd = 1.0;
if(*x < 0.0)
{
// Extrapolation on the left
//--------------------------
x1 = m_src_vertices[0].x;
y1 = m_src_vertices[0].y;
dx = m_src_vertices[1].x - x1;
dy = m_src_vertices[1].y - y1;
dd = m_src_vertices[1].dist - m_src_vertices[0].dist;
d = *x;
}
else
if(*x > m_src_vertices[m_src_vertices.size() - 1].dist)
{
// Extrapolation on the right
@ -163,13 +163,13 @@ namespace agg
if(m_preserve_x_scale)
{
unsigned k;
for(i = 0; (j - i) > 1; )
for(i = 0; (j - i) > 1; )
{
if(*x < m_src_vertices[k = (i + j) >> 1].dist)
if(*x < m_src_vertices[k = (i + j) >> 1].dist)
{
j = k;
j = k;
}
else
else
{
i = k;
}
@ -190,12 +190,12 @@ namespace agg
dx = m_src_vertices[j].x - x1;
dy = m_src_vertices[j].y - y1;
}
double x2 = x1 + dx * d / dd;
double y2 = y1 + dy * d / dd;
*x = x2 - *y * dy / dd;
*y = y2 + *y * dx / dd;
}
double x2 = x1 + dx * d / dd;
double y2 = y1 + dy * d / dd;
*x = x2 - *y * dy / dd;
*y = y2 + *y * dx / dd;
}
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -19,52 +19,52 @@
namespace agg
{
//------------------------------------------------------------------------
void trans_warp_magnifier::transform(double* x, double* y) const
//------------------------------------------------------------------------
void trans_warp_magnifier::transform(double* x, double* y) const
{
double dx = *x - m_xc;
double dy = *y - m_yc;
double r = sqrt(dx * dx + dy * dy);
if(r < m_radius)
{
double dx = *x - m_xc;
double dy = *y - m_yc;
double r = sqrt(dx * dx + dy * dy);
if(r < m_radius)
{
*x = m_xc + dx * m_magn;
*y = m_yc + dy * m_magn;
return;
}
double m = (r + m_radius * (m_magn - 1.0)) / r;
*x = m_xc + dx * m;
*y = m_yc + dy * m;
*x = m_xc + dx * m_magn;
*y = m_yc + dy * m_magn;
return;
}
//------------------------------------------------------------------------
void trans_warp_magnifier::inverse_transform(double* x, double* y) const
double m = (r + m_radius * (m_magn - 1.0)) / r;
*x = m_xc + dx * m;
*y = m_yc + dy * m;
}
//------------------------------------------------------------------------
void trans_warp_magnifier::inverse_transform(double* x, double* y) const
{
// New version by Andrew Skalkin
//-----------------
double dx = *x - m_xc;
double dy = *y - m_yc;
double r = sqrt(dx * dx + dy * dy);
if(r < m_radius * m_magn)
{
// New version by Andrew Skalkin
//-----------------
double dx = *x - m_xc;
double dy = *y - m_yc;
double r = sqrt(dx * dx + dy * dy);
if(r < m_radius * m_magn)
{
*x = m_xc + dx / m_magn;
*y = m_yc + dy / m_magn;
}
else
{
double rnew = r - m_radius * (m_magn - 1.0);
*x = m_xc + rnew * dx / r;
*y = m_yc + rnew * dy / r;
}
// Old version
//-----------------
//trans_warp_magnifier t(*this);
//t.magnification(1.0 / m_magn);
//t.radius(m_radius * m_magn);
//t.transform(x, y);
*x = m_xc + dx / m_magn;
*y = m_yc + dy / m_magn;
}
else
{
double rnew = r - m_radius * (m_magn - 1.0);
*x = m_xc + rnew * dx / r;
*y = m_yc + rnew * dy / r;
}
// Old version
//-----------------
//trans_warp_magnifier t(*this);
//t.magnification(1.0 / m_magn);
//t.radius(m_radius * m_magn);
//t.transform(x, y);
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -18,176 +18,176 @@
namespace agg
{
//------------------------------------------------------------------------
vcgen_bspline::vcgen_bspline() :
m_src_vertices(),
m_spline_x(),
m_spline_y(),
m_interpolation_step(1.0/50.0),
m_closed(0),
m_status(initial),
m_src_vertex(0)
//------------------------------------------------------------------------
vcgen_bspline::vcgen_bspline() :
m_src_vertices(),
m_spline_x(),
m_spline_y(),
m_interpolation_step(1.0/50.0),
m_closed(0),
m_status(initial),
m_src_vertex(0)
{
}
//------------------------------------------------------------------------
void vcgen_bspline::remove_all()
{
m_src_vertices.remove_all();
m_closed = 0;
m_status = initial;
m_src_vertex = 0;
}
//------------------------------------------------------------------------
void vcgen_bspline::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
m_src_vertices.modify_last(point_d(x, y));
}
//------------------------------------------------------------------------
void vcgen_bspline::remove_all()
else
{
m_src_vertices.remove_all();
m_closed = 0;
m_status = initial;
m_src_vertex = 0;
}
//------------------------------------------------------------------------
void vcgen_bspline::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
if(is_vertex(cmd))
{
m_src_vertices.modify_last(point_d(x, y));
m_src_vertices.add(point_d(x, y));
}
else
{
if(is_vertex(cmd))
{
m_src_vertices.add(point_d(x, y));
}
else
{
m_closed = get_close_flag(cmd);
}
m_closed = get_close_flag(cmd);
}
}
}
//------------------------------------------------------------------------
void vcgen_bspline::rewind(unsigned)
//------------------------------------------------------------------------
void vcgen_bspline::rewind(unsigned)
{
m_cur_abscissa = 0.0;
m_max_abscissa = 0.0;
m_src_vertex = 0;
if(m_status == initial && m_src_vertices.size() > 2)
{
if(m_closed)
{
m_spline_x.init(m_src_vertices.size() + 8);
m_spline_y.init(m_src_vertices.size() + 8);
m_spline_x.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).x);
m_spline_y.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).y);
m_spline_x.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].x);
m_spline_y.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].y);
m_spline_x.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].x);
m_spline_y.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].y);
m_spline_x.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].x);
m_spline_y.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].y);
}
else
{
m_spline_x.init(m_src_vertices.size());
m_spline_y.init(m_src_vertices.size());
}
unsigned i;
for(i = 0; i < m_src_vertices.size(); i++)
{
double x = m_closed ? i + 4 : i;
m_spline_x.add_point(x, m_src_vertices[i].x);
m_spline_y.add_point(x, m_src_vertices[i].y);
}
m_cur_abscissa = 0.0;
m_max_abscissa = 0.0;
m_src_vertex = 0;
if(m_status == initial && m_src_vertices.size() > 2)
m_max_abscissa = m_src_vertices.size() - 1;
if(m_closed)
{
if(m_closed)
{
m_spline_x.init(m_src_vertices.size() + 8);
m_spline_y.init(m_src_vertices.size() + 8);
m_spline_x.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).x);
m_spline_y.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).y);
m_spline_x.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].x);
m_spline_y.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].y);
m_spline_x.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].x);
m_spline_y.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].y);
m_spline_x.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].x);
m_spline_y.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].y);
}
else
{
m_spline_x.init(m_src_vertices.size());
m_spline_y.init(m_src_vertices.size());
}
unsigned i;
for(i = 0; i < m_src_vertices.size(); i++)
{
double x = m_closed ? i + 4 : i;
m_spline_x.add_point(x, m_src_vertices[i].x);
m_spline_y.add_point(x, m_src_vertices[i].y);
}
m_cur_abscissa = 0.0;
m_max_abscissa = m_src_vertices.size() - 1;
if(m_closed)
{
m_cur_abscissa = 4.0;
m_max_abscissa += 5.0;
m_spline_x.add_point(m_src_vertices.size() + 4, m_src_vertices[0].x);
m_spline_y.add_point(m_src_vertices.size() + 4, m_src_vertices[0].y);
m_spline_x.add_point(m_src_vertices.size() + 5, m_src_vertices[1].x);
m_spline_y.add_point(m_src_vertices.size() + 5, m_src_vertices[1].y);
m_spline_x.add_point(m_src_vertices.size() + 6, m_src_vertices[2].x);
m_spline_y.add_point(m_src_vertices.size() + 6, m_src_vertices[2].y);
m_spline_x.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).x);
m_spline_y.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).y);
}
m_spline_x.prepare();
m_spline_y.prepare();
m_cur_abscissa = 4.0;
m_max_abscissa += 5.0;
m_spline_x.add_point(m_src_vertices.size() + 4, m_src_vertices[0].x);
m_spline_y.add_point(m_src_vertices.size() + 4, m_src_vertices[0].y);
m_spline_x.add_point(m_src_vertices.size() + 5, m_src_vertices[1].x);
m_spline_y.add_point(m_src_vertices.size() + 5, m_src_vertices[1].y);
m_spline_x.add_point(m_src_vertices.size() + 6, m_src_vertices[2].x);
m_spline_y.add_point(m_src_vertices.size() + 6, m_src_vertices[2].y);
m_spline_x.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).x);
m_spline_y.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).y);
}
m_status = ready;
m_spline_x.prepare();
m_spline_y.prepare();
}
m_status = ready;
}
//------------------------------------------------------------------------
unsigned vcgen_bspline::vertex(double* x, double* y)
//------------------------------------------------------------------------
unsigned vcgen_bspline::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
switch(m_status)
{
switch(m_status)
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2)
{
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2)
{
cmd = path_cmd_stop;
break;
}
if(m_src_vertices.size() == 2)
{
*x = m_src_vertices[m_src_vertex].x;
*y = m_src_vertices[m_src_vertex].y;
m_src_vertex++;
if(m_src_vertex == 1) return path_cmd_move_to;
if(m_src_vertex == 2) return path_cmd_line_to;
cmd = path_cmd_stop;
break;
}
cmd = path_cmd_move_to;
m_status = polygon;
m_src_vertex = 0;
case polygon:
if(m_cur_abscissa >= m_max_abscissa)
{
if(m_closed)
{
m_status = end_poly;
break;
}
else
{
*x = m_src_vertices[m_src_vertices.size() - 1].x;
*y = m_src_vertices[m_src_vertices.size() - 1].y;
m_status = end_poly;
return path_cmd_line_to;
}
}
*x = m_spline_x.get_stateful(m_cur_abscissa);
*y = m_spline_y.get_stateful(m_cur_abscissa);
m_src_vertex++;
m_cur_abscissa += m_interpolation_step;
return (m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to;
case end_poly:
m_status = stop;
return path_cmd_end_poly | m_closed;
case stop:
return path_cmd_stop;
cmd = path_cmd_stop;
break;
}
if(m_src_vertices.size() == 2)
{
*x = m_src_vertices[m_src_vertex].x;
*y = m_src_vertices[m_src_vertex].y;
m_src_vertex++;
if(m_src_vertex == 1) return path_cmd_move_to;
if(m_src_vertex == 2) return path_cmd_line_to;
cmd = path_cmd_stop;
break;
}
cmd = path_cmd_move_to;
m_status = polygon;
m_src_vertex = 0;
case polygon:
if(m_cur_abscissa >= m_max_abscissa)
{
if(m_closed)
{
m_status = end_poly;
break;
}
else
{
*x = m_src_vertices[m_src_vertices.size() - 1].x;
*y = m_src_vertices[m_src_vertices.size() - 1].y;
m_status = end_poly;
return path_cmd_line_to;
}
}
*x = m_spline_x.get_stateful(m_cur_abscissa);
*y = m_spline_y.get_stateful(m_cur_abscissa);
m_src_vertex++;
m_cur_abscissa += m_interpolation_step;
return (m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to;
case end_poly:
m_status = stop;
return path_cmd_end_poly | m_closed;
case stop:
return path_cmd_stop;
}
return cmd;
}
return cmd;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -23,143 +23,143 @@
namespace agg
{
//------------------------------------------------------------------------
vcgen_contour::vcgen_contour() :
m_stroker(),
m_width(1),
m_src_vertices(),
m_out_vertices(),
m_status(initial),
m_src_vertex(0),
m_closed(0),
m_orientation(0),
m_auto_detect(false)
{
}
//------------------------------------------------------------------------
vcgen_contour::vcgen_contour() :
m_stroker(),
m_width(1),
m_src_vertices(),
m_out_vertices(),
m_status(initial),
m_src_vertex(0),
m_closed(0),
m_orientation(0),
m_auto_detect(false)
{
}
//------------------------------------------------------------------------
void vcgen_contour::remove_all()
{
m_src_vertices.remove_all();
m_closed = 0;
m_orientation = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_contour::remove_all()
{
m_src_vertices.remove_all();
m_closed = 0;
m_orientation = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
//------------------------------------------------------------------------
void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
m_status = initial;
if(is_move_to(cmd))
m_src_vertices.modify_last(vertex_dist(x, y));
}
else
{
if(is_vertex(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
m_src_vertices.add(vertex_dist(x, y));
}
else
{
if(is_vertex(cmd))
if(is_end_poly(cmd))
{
m_src_vertices.add(vertex_dist(x, y));
m_closed = get_close_flag(cmd);
if(m_orientation == path_flags_none)
{
m_orientation = get_orientation(cmd);
}
}
}
}
}
//------------------------------------------------------------------------
void vcgen_contour::rewind(unsigned)
{
if(m_status == initial)
{
m_src_vertices.close(true);
if(m_auto_detect)
{
if(!is_oriented(m_orientation))
{
m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ?
path_flags_ccw :
path_flags_cw;
}
}
if(is_oriented(m_orientation))
{
m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width);
}
}
m_status = ready;
m_src_vertex = 0;
}
//------------------------------------------------------------------------
unsigned vcgen_contour::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
{
switch(m_status)
{
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
{
cmd = path_cmd_stop;
break;
}
m_status = outline;
cmd = path_cmd_move_to;
m_src_vertex = 0;
m_out_vertex = 0;
case outline:
if(m_src_vertex >= m_src_vertices.size())
{
m_status = end_poly;
break;
}
m_stroker.calc_join(m_out_vertices,
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.prev(m_src_vertex).dist,
m_src_vertices.curr(m_src_vertex).dist);
++m_src_vertex;
m_status = out_vertices;
m_out_vertex = 0;
case out_vertices:
if(m_out_vertex >= m_out_vertices.size())
{
m_status = outline;
}
else
{
if(is_end_poly(cmd))
{
m_closed = get_close_flag(cmd);
if(m_orientation == path_flags_none)
{
m_orientation = get_orientation(cmd);
}
}
const point_d& c = m_out_vertices[m_out_vertex++];
*x = c.x;
*y = c.y;
return cmd;
}
break;
case end_poly:
if(!m_closed) return path_cmd_stop;
m_status = stop;
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
case stop:
return path_cmd_stop;
}
}
//------------------------------------------------------------------------
void vcgen_contour::rewind(unsigned)
{
if(m_status == initial)
{
m_src_vertices.close(true);
if(m_auto_detect)
{
if(!is_oriented(m_orientation))
{
m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ?
path_flags_ccw :
path_flags_cw;
}
}
if(is_oriented(m_orientation))
{
m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width);
}
}
m_status = ready;
m_src_vertex = 0;
}
//------------------------------------------------------------------------
unsigned vcgen_contour::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
{
switch(m_status)
{
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
{
cmd = path_cmd_stop;
break;
}
m_status = outline;
cmd = path_cmd_move_to;
m_src_vertex = 0;
m_out_vertex = 0;
case outline:
if(m_src_vertex >= m_src_vertices.size())
{
m_status = end_poly;
break;
}
m_stroker.calc_join(m_out_vertices,
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.prev(m_src_vertex).dist,
m_src_vertices.curr(m_src_vertex).dist);
++m_src_vertex;
m_status = out_vertices;
m_out_vertex = 0;
case out_vertices:
if(m_out_vertex >= m_out_vertices.size())
{
m_status = outline;
}
else
{
const point_d& c = m_out_vertices[m_out_vertex++];
*x = c.x;
*y = c.y;
return cmd;
}
break;
case end_poly:
if(!m_closed) return path_cmd_stop;
m_status = stop;
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
case stop:
return path_cmd_stop;
}
}
return cmd;
}
return cmd;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -24,211 +24,211 @@
namespace agg
{
//------------------------------------------------------------------------
vcgen_dash::vcgen_dash() :
m_total_dash_len(0.0),
m_num_dashes(0),
m_dash_start(0.0),
m_shorten(0.0),
m_curr_dash_start(0.0),
m_curr_dash(0),
m_src_vertices(),
m_closed(0),
m_status(initial),
m_src_vertex(0)
//------------------------------------------------------------------------
vcgen_dash::vcgen_dash() :
m_total_dash_len(0.0),
m_num_dashes(0),
m_dash_start(0.0),
m_shorten(0.0),
m_curr_dash_start(0.0),
m_curr_dash(0),
m_src_vertices(),
m_closed(0),
m_status(initial),
m_src_vertex(0)
{
}
//------------------------------------------------------------------------
void vcgen_dash::remove_all_dashes()
{
m_total_dash_len = 0.0;
m_num_dashes = 0;
m_curr_dash_start = 0.0;
m_curr_dash = 0;
}
//------------------------------------------------------------------------
void vcgen_dash::add_dash(double dash_len, double gap_len)
{
if(m_num_dashes < max_dashes)
{
m_total_dash_len += dash_len + gap_len;
m_dashes[m_num_dashes++] = dash_len;
m_dashes[m_num_dashes++] = gap_len;
}
}
//------------------------------------------------------------------------
void vcgen_dash::dash_start(double ds)
{
m_dash_start = ds;
calc_dash_start(fabs(ds));
}
//------------------------------------------------------------------------
void vcgen_dash::remove_all_dashes()
//------------------------------------------------------------------------
void vcgen_dash::calc_dash_start(double ds)
{
m_curr_dash = 0;
m_curr_dash_start = 0.0;
while(ds > 0.0)
{
m_total_dash_len = 0.0;
m_num_dashes = 0;
m_curr_dash_start = 0.0;
m_curr_dash = 0;
}
//------------------------------------------------------------------------
void vcgen_dash::add_dash(double dash_len, double gap_len)
{
if(m_num_dashes < max_dashes)
if(ds > m_dashes[m_curr_dash])
{
m_total_dash_len += dash_len + gap_len;
m_dashes[m_num_dashes++] = dash_len;
m_dashes[m_num_dashes++] = gap_len;
}
}
//------------------------------------------------------------------------
void vcgen_dash::dash_start(double ds)
{
m_dash_start = ds;
calc_dash_start(fabs(ds));
}
//------------------------------------------------------------------------
void vcgen_dash::calc_dash_start(double ds)
{
m_curr_dash = 0;
m_curr_dash_start = 0.0;
while(ds > 0.0)
{
if(ds > m_dashes[m_curr_dash])
{
ds -= m_dashes[m_curr_dash];
++m_curr_dash;
m_curr_dash_start = 0.0;
if(m_curr_dash >= m_num_dashes) m_curr_dash = 0;
}
else
{
m_curr_dash_start = ds;
ds = 0.0;
}
}
}
//------------------------------------------------------------------------
void vcgen_dash::remove_all()
{
m_status = initial;
m_src_vertices.remove_all();
m_closed = 0;
}
//------------------------------------------------------------------------
void vcgen_dash::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
ds -= m_dashes[m_curr_dash];
++m_curr_dash;
m_curr_dash_start = 0.0;
if(m_curr_dash >= m_num_dashes) m_curr_dash = 0;
}
else
{
if(is_vertex(cmd))
{
m_src_vertices.add(vertex_dist(x, y));
}
else
{
m_closed = get_close_flag(cmd);
}
m_curr_dash_start = ds;
ds = 0.0;
}
}
}
//------------------------------------------------------------------------
void vcgen_dash::rewind(unsigned)
//------------------------------------------------------------------------
void vcgen_dash::remove_all()
{
m_status = initial;
m_src_vertices.remove_all();
m_closed = 0;
}
//------------------------------------------------------------------------
void vcgen_dash::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
if(m_status == initial)
{
m_src_vertices.close(m_closed != 0);
shorten_path(m_src_vertices, m_shorten, m_closed);
}
m_status = ready;
m_src_vertex = 0;
m_src_vertices.modify_last(vertex_dist(x, y));
}
//------------------------------------------------------------------------
unsigned vcgen_dash::vertex(double* x, double* y)
else
{
unsigned cmd = path_cmd_move_to;
while(!is_stop(cmd))
if(is_vertex(cmd))
{
switch(m_status)
m_src_vertices.add(vertex_dist(x, y));
}
else
{
m_closed = get_close_flag(cmd);
}
}
}
//------------------------------------------------------------------------
void vcgen_dash::rewind(unsigned)
{
if(m_status == initial)
{
m_src_vertices.close(m_closed != 0);
shorten_path(m_src_vertices, m_shorten, m_closed);
}
m_status = ready;
m_src_vertex = 0;
}
//------------------------------------------------------------------------
unsigned vcgen_dash::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_move_to;
while(!is_stop(cmd))
{
switch(m_status)
{
case initial:
rewind(0);
case ready:
if(m_num_dashes < 2 || m_src_vertices.size() < 2)
{
case initial:
rewind(0);
case ready:
if(m_num_dashes < 2 || m_src_vertices.size() < 2)
{
cmd = path_cmd_stop;
break;
}
m_status = polyline;
m_src_vertex = 1;
m_v1 = &m_src_vertices[0];
m_v2 = &m_src_vertices[1];
m_curr_rest = m_v1->dist;
*x = m_v1->x;
*y = m_v1->y;
if(m_dash_start >= 0.0) calc_dash_start(m_dash_start);
return path_cmd_move_to;
case polyline:
{
double dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start;
unsigned cmd = (m_curr_dash & 1) ?
path_cmd_move_to :
path_cmd_line_to;
if(m_curr_rest > dash_rest)
{
m_curr_rest -= dash_rest;
++m_curr_dash;
if(m_curr_dash >= m_num_dashes) m_curr_dash = 0;
m_curr_dash_start = 0.0;
*x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist;
*y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist;
}
else
{
m_curr_dash_start += m_curr_rest;
*x = m_v2->x;
*y = m_v2->y;
++m_src_vertex;
m_v1 = m_v2;
m_curr_rest = m_v1->dist;
if(m_closed)
{
if(m_src_vertex > m_src_vertices.size())
{
m_status = stop;
}
else
{
m_v2 = &m_src_vertices
[
(m_src_vertex >= m_src_vertices.size()) ? 0 :
m_src_vertex
];
}
}
else
{
if(m_src_vertex >= m_src_vertices.size())
{
m_status = stop;
}
else
{
m_v2 = &m_src_vertices[m_src_vertex];
}
}
}
return cmd;
}
break;
case stop:
cmd = path_cmd_stop;
break;
}
m_status = polyline;
m_src_vertex = 1;
m_v1 = &m_src_vertices[0];
m_v2 = &m_src_vertices[1];
m_curr_rest = m_v1->dist;
*x = m_v1->x;
*y = m_v1->y;
if(m_dash_start >= 0.0) calc_dash_start(m_dash_start);
return path_cmd_move_to;
case polyline:
{
double dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start;
unsigned cmd = (m_curr_dash & 1) ?
path_cmd_move_to :
path_cmd_line_to;
if(m_curr_rest > dash_rest)
{
m_curr_rest -= dash_rest;
++m_curr_dash;
if(m_curr_dash >= m_num_dashes) m_curr_dash = 0;
m_curr_dash_start = 0.0;
*x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist;
*y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist;
}
else
{
m_curr_dash_start += m_curr_rest;
*x = m_v2->x;
*y = m_v2->y;
++m_src_vertex;
m_v1 = m_v2;
m_curr_rest = m_v1->dist;
if(m_closed)
{
if(m_src_vertex > m_src_vertices.size())
{
m_status = stop;
}
else
{
m_v2 = &m_src_vertices
[
(m_src_vertex >= m_src_vertices.size()) ? 0 :
m_src_vertex
];
}
}
else
{
if(m_src_vertex >= m_src_vertices.size())
{
m_status = stop;
}
else
{
m_v2 = &m_src_vertices[m_src_vertex];
}
}
}
return cmd;
}
return path_cmd_stop;
break;
case stop:
cmd = path_cmd_stop;
break;
}
}
return path_cmd_stop;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -22,82 +22,82 @@
namespace agg
{
//------------------------------------------------------------------------
void vcgen_markers_term::remove_all()
//------------------------------------------------------------------------
void vcgen_markers_term::remove_all()
{
m_markers.remove_all();
}
//------------------------------------------------------------------------
void vcgen_markers_term::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
m_markers.remove_all();
if(m_markers.size() & 1)
{
// Initial state, the first coordinate was added.
// If two of more calls of start_vertex() occures
// we just modify the last one.
m_markers.modify_last(coord_type(x, y));
}
else
{
m_markers.add(coord_type(x, y));
}
}
//------------------------------------------------------------------------
void vcgen_markers_term::add_vertex(double x, double y, unsigned cmd)
else
{
if(is_move_to(cmd))
if(is_vertex(cmd))
{
if(m_markers.size() & 1)
{
// Initial state, the first coordinate was added.
// If two of more calls of start_vertex() occures
// we just modify the last one.
m_markers.modify_last(coord_type(x, y));
// Add three more points, 0,1,1,0
m_markers.add(coord_type(x, y));
m_markers.add(m_markers[m_markers.size() - 1]);
m_markers.add(m_markers[m_markers.size() - 3]);
}
else
{
m_markers.add(coord_type(x, y));
}
}
else
{
if(is_vertex(cmd))
{
if(m_markers.size() & 1)
if(m_markers.size())
{
// Initial state, the first coordinate was added.
// Add three more points, 0,1,1,0
m_markers.add(coord_type(x, y));
m_markers.add(m_markers[m_markers.size() - 1]);
m_markers.add(m_markers[m_markers.size() - 3]);
}
else
{
if(m_markers.size())
{
// Replace two last points: 0,1,1,0 -> 0,1,2,1
m_markers[m_markers.size() - 1] = m_markers[m_markers.size() - 2];
m_markers[m_markers.size() - 2] = coord_type(x, y);
}
// Replace two last points: 0,1,1,0 -> 0,1,2,1
m_markers[m_markers.size() - 1] = m_markers[m_markers.size() - 2];
m_markers[m_markers.size() - 2] = coord_type(x, y);
}
}
}
}
}
//------------------------------------------------------------------------
void vcgen_markers_term::rewind(unsigned path_id)
//------------------------------------------------------------------------
void vcgen_markers_term::rewind(unsigned path_id)
{
m_curr_id = path_id * 2;
m_curr_idx = m_curr_id;
}
//------------------------------------------------------------------------
unsigned vcgen_markers_term::vertex(double* x, double* y)
{
if(m_curr_id > 2 || m_curr_idx >= m_markers.size())
{
m_curr_id = path_id * 2;
m_curr_idx = m_curr_id;
return path_cmd_stop;
}
//------------------------------------------------------------------------
unsigned vcgen_markers_term::vertex(double* x, double* y)
const coord_type& c = m_markers[m_curr_idx];
*x = c.x;
*y = c.y;
if(m_curr_idx & 1)
{
if(m_curr_id > 2 || m_curr_idx >= m_markers.size())
{
return path_cmd_stop;
}
const coord_type& c = m_markers[m_curr_idx];
*x = c.x;
*y = c.y;
if(m_curr_idx & 1)
{
m_curr_idx += 3;
return path_cmd_line_to;
}
++m_curr_idx;
return path_cmd_move_to;
m_curr_idx += 3;
return path_cmd_line_to;
}
++m_curr_idx;
return path_cmd_move_to;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -22,204 +22,204 @@
namespace agg
{
//------------------------------------------------------------------------
vcgen_smooth_poly1::vcgen_smooth_poly1() :
m_src_vertices(),
m_smooth_value(0.5),
m_closed(0),
m_status(initial),
m_src_vertex(0)
//------------------------------------------------------------------------
vcgen_smooth_poly1::vcgen_smooth_poly1() :
m_src_vertices(),
m_smooth_value(0.5),
m_closed(0),
m_status(initial),
m_src_vertex(0)
{
}
//------------------------------------------------------------------------
void vcgen_smooth_poly1::remove_all()
{
m_src_vertices.remove_all();
m_closed = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
}
//------------------------------------------------------------------------
void vcgen_smooth_poly1::remove_all()
else
{
m_src_vertices.remove_all();
m_closed = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
if(is_vertex(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
m_src_vertices.add(vertex_dist(x, y));
}
else
{
if(is_vertex(cmd))
{
m_src_vertices.add(vertex_dist(x, y));
}
else
{
m_closed = get_close_flag(cmd);
}
m_closed = get_close_flag(cmd);
}
}
}
//------------------------------------------------------------------------
void vcgen_smooth_poly1::rewind(unsigned)
//------------------------------------------------------------------------
void vcgen_smooth_poly1::rewind(unsigned)
{
if(m_status == initial)
{
if(m_status == initial)
{
m_src_vertices.close(m_closed != 0);
}
m_status = ready;
m_src_vertex = 0;
m_src_vertices.close(m_closed != 0);
}
m_status = ready;
m_src_vertex = 0;
}
//------------------------------------------------------------------------
void vcgen_smooth_poly1::calculate(const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
const vertex_dist& v3)
//------------------------------------------------------------------------
void vcgen_smooth_poly1::calculate(const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
const vertex_dist& v3)
{
double k1 = v0.dist / (v0.dist + v1.dist);
double k2 = v1.dist / (v1.dist + v2.dist);
double xm1 = v0.x + (v2.x - v0.x) * k1;
double ym1 = v0.y + (v2.y - v0.y) * k1;
double xm2 = v1.x + (v3.x - v1.x) * k2;
double ym2 = v1.y + (v3.y - v1.y) * k2;
m_ctrl1_x = v1.x + m_smooth_value * (v2.x - xm1);
m_ctrl1_y = v1.y + m_smooth_value * (v2.y - ym1);
m_ctrl2_x = v2.x + m_smooth_value * (v1.x - xm2);
m_ctrl2_y = v2.y + m_smooth_value * (v1.y - ym2);
}
//------------------------------------------------------------------------
unsigned vcgen_smooth_poly1::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
{
double k1 = v0.dist / (v0.dist + v1.dist);
double k2 = v1.dist / (v1.dist + v2.dist);
double xm1 = v0.x + (v2.x - v0.x) * k1;
double ym1 = v0.y + (v2.y - v0.y) * k1;
double xm2 = v1.x + (v3.x - v1.x) * k2;
double ym2 = v1.y + (v3.y - v1.y) * k2;
m_ctrl1_x = v1.x + m_smooth_value * (v2.x - xm1);
m_ctrl1_y = v1.y + m_smooth_value * (v2.y - ym1);
m_ctrl2_x = v2.x + m_smooth_value * (v1.x - xm2);
m_ctrl2_y = v2.y + m_smooth_value * (v1.y - ym2);
}
//------------------------------------------------------------------------
unsigned vcgen_smooth_poly1::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
switch(m_status)
{
switch(m_status)
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2)
{
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2)
{
cmd = path_cmd_stop;
break;
}
if(m_src_vertices.size() == 2)
{
*x = m_src_vertices[m_src_vertex].x;
*y = m_src_vertices[m_src_vertex].y;
m_src_vertex++;
if(m_src_vertex == 1) return path_cmd_move_to;
if(m_src_vertex == 2) return path_cmd_line_to;
cmd = path_cmd_stop;
break;
}
cmd = path_cmd_move_to;
m_status = polygon;
m_src_vertex = 0;
case polygon:
if(m_closed)
{
if(m_src_vertex >= m_src_vertices.size())
{
*x = m_src_vertices[0].x;
*y = m_src_vertices[0].y;
m_status = end_poly;
return path_cmd_curve4;
}
}
else
{
if(m_src_vertex >= m_src_vertices.size() - 1)
{
*x = m_src_vertices[m_src_vertices.size() - 1].x;
*y = m_src_vertices[m_src_vertices.size() - 1].y;
m_status = end_poly;
return path_cmd_curve3;
}
}
calculate(m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.next(m_src_vertex + 1));
cmd = path_cmd_stop;
break;
}
if(m_src_vertices.size() == 2)
{
*x = m_src_vertices[m_src_vertex].x;
*y = m_src_vertices[m_src_vertex].y;
m_src_vertex++;
if(m_src_vertex == 1) return path_cmd_move_to;
if(m_src_vertex == 2) return path_cmd_line_to;
cmd = path_cmd_stop;
break;
}
if(m_closed)
cmd = path_cmd_move_to;
m_status = polygon;
m_src_vertex = 0;
case polygon:
if(m_closed)
{
if(m_src_vertex >= m_src_vertices.size())
{
m_status = ctrl1;
return ((m_src_vertex == 1) ?
path_cmd_move_to :
path_cmd_curve4);
}
else
{
if(m_src_vertex == 1)
{
m_status = ctrl_b;
return path_cmd_move_to;
}
if(m_src_vertex >= m_src_vertices.size() - 1)
{
m_status = ctrl_e;
return path_cmd_curve3;
}
m_status = ctrl1;
*x = m_src_vertices[0].x;
*y = m_src_vertices[0].y;
m_status = end_poly;
return path_cmd_curve4;
}
break;
case ctrl_b:
*x = m_ctrl2_x;
*y = m_ctrl2_y;
m_status = polygon;
return path_cmd_curve3;
case ctrl_e:
*x = m_ctrl1_x;
*y = m_ctrl1_y;
m_status = polygon;
return path_cmd_curve3;
case ctrl1:
*x = m_ctrl1_x;
*y = m_ctrl1_y;
m_status = ctrl2;
return path_cmd_curve4;
case ctrl2:
*x = m_ctrl2_x;
*y = m_ctrl2_y;
m_status = polygon;
return path_cmd_curve4;
case end_poly:
m_status = stop;
return path_cmd_end_poly | m_closed;
case stop:
return path_cmd_stop;
}
else
{
if(m_src_vertex >= m_src_vertices.size() - 1)
{
*x = m_src_vertices[m_src_vertices.size() - 1].x;
*y = m_src_vertices[m_src_vertices.size() - 1].y;
m_status = end_poly;
return path_cmd_curve3;
}
}
calculate(m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.next(m_src_vertex + 1));
*x = m_src_vertices[m_src_vertex].x;
*y = m_src_vertices[m_src_vertex].y;
m_src_vertex++;
if(m_closed)
{
m_status = ctrl1;
return ((m_src_vertex == 1) ?
path_cmd_move_to :
path_cmd_curve4);
}
else
{
if(m_src_vertex == 1)
{
m_status = ctrl_b;
return path_cmd_move_to;
}
if(m_src_vertex >= m_src_vertices.size() - 1)
{
m_status = ctrl_e;
return path_cmd_curve3;
}
m_status = ctrl1;
return path_cmd_curve4;
}
break;
case ctrl_b:
*x = m_ctrl2_x;
*y = m_ctrl2_y;
m_status = polygon;
return path_cmd_curve3;
case ctrl_e:
*x = m_ctrl1_x;
*y = m_ctrl1_y;
m_status = polygon;
return path_cmd_curve3;
case ctrl1:
*x = m_ctrl1_x;
*y = m_ctrl1_y;
m_status = ctrl2;
return path_cmd_curve4;
case ctrl2:
*x = m_ctrl2_x;
*y = m_ctrl2_y;
m_status = polygon;
return path_cmd_curve4;
case end_poly:
m_status = stop;
return path_cmd_end_poly | m_closed;
case stop:
return path_cmd_stop;
}
return cmd;
}
return cmd;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -23,191 +23,191 @@
namespace agg
{
//------------------------------------------------------------------------
vcgen_stroke::vcgen_stroke() :
m_stroker(),
m_src_vertices(),
m_out_vertices(),
m_shorten(0.0),
m_closed(0),
m_status(initial),
m_src_vertex(0),
m_out_vertex(0)
//------------------------------------------------------------------------
vcgen_stroke::vcgen_stroke() :
m_stroker(),
m_src_vertices(),
m_out_vertices(),
m_shorten(0.0),
m_closed(0),
m_status(initial),
m_src_vertex(0),
m_out_vertex(0)
{
}
//------------------------------------------------------------------------
void vcgen_stroke::remove_all()
{
m_src_vertices.remove_all();
m_closed = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_stroke::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
}
//------------------------------------------------------------------------
void vcgen_stroke::remove_all()
else
{
m_src_vertices.remove_all();
m_closed = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_stroke::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
if(is_vertex(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
m_src_vertices.add(vertex_dist(x, y));
}
else
{
if(is_vertex(cmd))
{
m_src_vertices.add(vertex_dist(x, y));
}
else
{
m_closed = get_close_flag(cmd);
}
m_closed = get_close_flag(cmd);
}
}
}
//------------------------------------------------------------------------
void vcgen_stroke::rewind(unsigned)
//------------------------------------------------------------------------
void vcgen_stroke::rewind(unsigned)
{
if(m_status == initial)
{
if(m_status == initial)
{
m_src_vertices.close(m_closed != 0);
shorten_path(m_src_vertices, m_shorten, m_closed);
if(m_src_vertices.size() < 3) m_closed = 0;
}
m_status = ready;
m_src_vertex = 0;
m_out_vertex = 0;
m_src_vertices.close(m_closed != 0);
shorten_path(m_src_vertices, m_shorten, m_closed);
if(m_src_vertices.size() < 3) m_closed = 0;
}
m_status = ready;
m_src_vertex = 0;
m_out_vertex = 0;
}
//------------------------------------------------------------------------
unsigned vcgen_stroke::vertex(double* x, double* y)
//------------------------------------------------------------------------
unsigned vcgen_stroke::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
switch(m_status)
{
switch(m_status)
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
{
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
{
cmd = path_cmd_stop;
break;
}
m_status = m_closed ? outline1 : cap1;
cmd = path_cmd_move_to;
m_src_vertex = 0;
m_out_vertex = 0;
break;
case cap1:
m_stroker.calc_cap(m_out_vertices,
m_src_vertices[0],
m_src_vertices[1],
m_src_vertices[0].dist);
m_src_vertex = 1;
m_prev_status = outline1;
m_status = out_vertices;
m_out_vertex = 0;
break;
case cap2:
m_stroker.calc_cap(m_out_vertices,
m_src_vertices[m_src_vertices.size() - 1],
m_src_vertices[m_src_vertices.size() - 2],
m_src_vertices[m_src_vertices.size() - 2].dist);
m_prev_status = outline2;
m_status = out_vertices;
m_out_vertex = 0;
break;
case outline1:
if(m_closed)
{
if(m_src_vertex >= m_src_vertices.size())
{
m_prev_status = close_first;
m_status = end_poly1;
break;
}
}
else
{
if(m_src_vertex >= m_src_vertices.size() - 1)
{
m_status = cap2;
break;
}
}
m_stroker.calc_join(m_out_vertices,
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.prev(m_src_vertex).dist,
m_src_vertices.curr(m_src_vertex).dist);
++m_src_vertex;
m_prev_status = m_status;
m_status = out_vertices;
m_out_vertex = 0;
break;
case close_first:
m_status = outline2;
cmd = path_cmd_move_to;
case outline2:
if(m_src_vertex <= unsigned(m_closed == 0))
{
m_status = end_poly2;
m_prev_status = stop;
break;
}
--m_src_vertex;
m_stroker.calc_join(m_out_vertices,
m_src_vertices.next(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex).dist,
m_src_vertices.prev(m_src_vertex).dist);
m_prev_status = m_status;
m_status = out_vertices;
m_out_vertex = 0;
break;
case out_vertices:
if(m_out_vertex >= m_out_vertices.size())
{
m_status = m_prev_status;
}
else
{
const point_d& c = m_out_vertices[m_out_vertex++];
*x = c.x;
*y = c.y;
return cmd;
}
break;
case end_poly1:
m_status = m_prev_status;
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
case end_poly2:
m_status = m_prev_status;
return path_cmd_end_poly | path_flags_close | path_flags_cw;
case stop:
cmd = path_cmd_stop;
break;
}
m_status = m_closed ? outline1 : cap1;
cmd = path_cmd_move_to;
m_src_vertex = 0;
m_out_vertex = 0;
break;
case cap1:
m_stroker.calc_cap(m_out_vertices,
m_src_vertices[0],
m_src_vertices[1],
m_src_vertices[0].dist);
m_src_vertex = 1;
m_prev_status = outline1;
m_status = out_vertices;
m_out_vertex = 0;
break;
case cap2:
m_stroker.calc_cap(m_out_vertices,
m_src_vertices[m_src_vertices.size() - 1],
m_src_vertices[m_src_vertices.size() - 2],
m_src_vertices[m_src_vertices.size() - 2].dist);
m_prev_status = outline2;
m_status = out_vertices;
m_out_vertex = 0;
break;
case outline1:
if(m_closed)
{
if(m_src_vertex >= m_src_vertices.size())
{
m_prev_status = close_first;
m_status = end_poly1;
break;
}
}
else
{
if(m_src_vertex >= m_src_vertices.size() - 1)
{
m_status = cap2;
break;
}
}
m_stroker.calc_join(m_out_vertices,
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.prev(m_src_vertex).dist,
m_src_vertices.curr(m_src_vertex).dist);
++m_src_vertex;
m_prev_status = m_status;
m_status = out_vertices;
m_out_vertex = 0;
break;
case close_first:
m_status = outline2;
cmd = path_cmd_move_to;
case outline2:
if(m_src_vertex <= unsigned(m_closed == 0))
{
m_status = end_poly2;
m_prev_status = stop;
break;
}
--m_src_vertex;
m_stroker.calc_join(m_out_vertices,
m_src_vertices.next(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex).dist,
m_src_vertices.prev(m_src_vertex).dist);
m_prev_status = m_status;
m_status = out_vertices;
m_out_vertex = 0;
break;
case out_vertices:
if(m_out_vertex >= m_out_vertices.size())
{
m_status = m_prev_status;
}
else
{
const point_d& c = m_out_vertices[m_out_vertex++];
*x = c.x;
*y = c.y;
return cmd;
}
break;
case end_poly1:
m_status = m_prev_status;
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
case end_poly2:
m_status = m_prev_status;
return path_cmd_end_poly | path_flags_close | path_flags_cw;
case stop:
cmd = path_cmd_stop;
break;
}
return cmd;
}
return cmd;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -19,115 +19,115 @@
namespace agg
{
//------------------------------------------------------------------------
// Determine the clipping code of the vertex according to the
// Cyrus-Beck line clipping algorithm
//
// | |
// 0110 | 0010 | 0011
// | |
// -------+--------+-------- clip_box.y2
// | |
// 0100 | 0000 | 0001
// | |
// -------+--------+-------- clip_box.y1
// | |
// 1100 | 1000 | 1001
// | |
// clip_box.x1 clip_box.x2
//
//
unsigned vpgen_clip_polygon::clipping_flags(double x, double y)
//------------------------------------------------------------------------
// Determine the clipping code of the vertex according to the
// Cyrus-Beck line clipping algorithm
//
// | |
// 0110 | 0010 | 0011
// | |
// -------+--------+-------- clip_box.y2
// | |
// 0100 | 0000 | 0001
// | |
// -------+--------+-------- clip_box.y1
// | |
// 1100 | 1000 | 1001
// | |
// clip_box.x1 clip_box.x2
//
//
unsigned vpgen_clip_polygon::clipping_flags(double x, double y)
{
if(x < m_clip_box.x1)
{
if(x < m_clip_box.x1)
{
if(y > m_clip_box.y2) return 6;
if(y < m_clip_box.y1) return 12;
return 4;
}
if(x > m_clip_box.x2)
{
if(y > m_clip_box.y2) return 3;
if(y < m_clip_box.y1) return 9;
return 1;
}
if(y > m_clip_box.y2) return 2;
if(y < m_clip_box.y1) return 8;
return 0;
if(y > m_clip_box.y2) return 6;
if(y < m_clip_box.y1) return 12;
return 4;
}
//----------------------------------------------------------------------------
void vpgen_clip_polygon::reset()
if(x > m_clip_box.x2)
{
m_vertex = 0;
m_num_vertices = 0;
if(y > m_clip_box.y2) return 3;
if(y < m_clip_box.y1) return 9;
return 1;
}
//----------------------------------------------------------------------------
void vpgen_clip_polygon::move_to(double x, double y)
if(y > m_clip_box.y2) return 2;
if(y < m_clip_box.y1) return 8;
return 0;
}
//----------------------------------------------------------------------------
void vpgen_clip_polygon::reset()
{
m_vertex = 0;
m_num_vertices = 0;
}
//----------------------------------------------------------------------------
void vpgen_clip_polygon::move_to(double x, double y)
{
m_vertex = 0;
m_num_vertices = 0;
m_clip_flags = clipping_flags(x, y);
if(m_clip_flags == 0)
{
m_vertex = 0;
m_num_vertices = 0;
m_clip_flags = clipping_flags(x, y);
if(m_clip_flags == 0)
m_x[0] = x;
m_y[0] = y;
m_num_vertices = 1;
}
m_x1 = x;
m_y1 = y;
m_cmd = path_cmd_move_to;
}
//----------------------------------------------------------------------------
void vpgen_clip_polygon::line_to(double x, double y)
{
m_vertex = 0;
m_num_vertices = 0;
unsigned flags = clipping_flags(x, y);
if(m_clip_flags == flags)
{
if(flags == 0)
{
m_x[0] = x;
m_y[0] = y;
m_num_vertices = 1;
}
m_x1 = x;
m_y1 = y;
m_cmd = path_cmd_move_to;
}
//----------------------------------------------------------------------------
void vpgen_clip_polygon::line_to(double x, double y)
else
{
m_vertex = 0;
m_num_vertices = 0;
unsigned flags = clipping_flags(x, y);
if(m_clip_flags == flags)
{
if(flags == 0)
{
m_x[0] = x;
m_y[0] = y;
m_num_vertices = 1;
}
}
else
{
m_num_vertices = clip_liang_barsky(m_x1, m_y1,
x, y,
m_clip_box,
m_x, m_y);
}
m_clip_flags = flags;
m_x1 = x;
m_y1 = y;
m_num_vertices = clip_liang_barsky(m_x1, m_y1,
x, y,
m_clip_box,
m_x, m_y);
}
m_clip_flags = flags;
m_x1 = x;
m_y1 = y;
}
//----------------------------------------------------------------------------
unsigned vpgen_clip_polygon::vertex(double* x, double* y)
//----------------------------------------------------------------------------
unsigned vpgen_clip_polygon::vertex(double* x, double* y)
{
if(m_vertex < m_num_vertices)
{
if(m_vertex < m_num_vertices)
{
*x = m_x[m_vertex];
*y = m_y[m_vertex];
++m_vertex;
unsigned cmd = m_cmd;
m_cmd = path_cmd_line_to;
return cmd;
}
return path_cmd_stop;
*x = m_x[m_vertex];
*y = m_y[m_vertex];
++m_vertex;
unsigned cmd = m_cmd;
m_cmd = path_cmd_line_to;
return cmd;
}
return path_cmd_stop;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -18,60 +18,60 @@
namespace agg
{
//----------------------------------------------------------------------------
void vpgen_clip_polyline::reset()
{
m_vertex = 0;
m_num_vertices = 0;
m_move_to = false;
}
//----------------------------------------------------------------------------
void vpgen_clip_polyline::move_to(double x, double y)
{
m_vertex = 0;
m_num_vertices = 0;
m_x1 = x;
m_y1 = y;
m_move_to = true;
}
//----------------------------------------------------------------------------
void vpgen_clip_polyline::line_to(double x, double y)
{
double x2 = x;
double y2 = y;
unsigned flags = clip_line_segment(&m_x1, &m_y1, &x2, &y2, m_clip_box);
m_vertex = 0;
m_num_vertices = 0;
if((flags & 4) == 0)
{
if((flags & 1) != 0 || m_move_to)
{
m_x[0] = m_x1;
m_y[0] = m_y1;
m_cmd[0] = path_cmd_move_to;
m_num_vertices = 1;
}
m_x[m_num_vertices] = x2;
m_y[m_num_vertices] = y2;
m_cmd[m_num_vertices++] = path_cmd_line_to;
m_move_to = (flags & 2) != 0;
}
m_x1 = x;
m_y1 = y;
}
//----------------------------------------------------------------------------
unsigned vpgen_clip_polyline::vertex(double* x, double* y)
{
if(m_vertex < m_num_vertices)
{
*x = m_x[m_vertex];
*y = m_y[m_vertex];
return m_cmd[m_vertex++];
}
return path_cmd_stop;
}
//----------------------------------------------------------------------------
void vpgen_clip_polyline::reset()
{
m_vertex = 0;
m_num_vertices = 0;
m_move_to = false;
}
//----------------------------------------------------------------------------
void vpgen_clip_polyline::move_to(double x, double y)
{
m_vertex = 0;
m_num_vertices = 0;
m_x1 = x;
m_y1 = y;
m_move_to = true;
}
//----------------------------------------------------------------------------
void vpgen_clip_polyline::line_to(double x, double y)
{
double x2 = x;
double y2 = y;
unsigned flags = clip_line_segment(&m_x1, &m_y1, &x2, &y2, m_clip_box);
m_vertex = 0;
m_num_vertices = 0;
if((flags & 4) == 0)
{
if((flags & 1) != 0 || m_move_to)
{
m_x[0] = m_x1;
m_y[0] = m_y1;
m_cmd[0] = path_cmd_move_to;
m_num_vertices = 1;
}
m_x[m_num_vertices] = x2;
m_y[m_num_vertices] = y2;
m_cmd[m_num_vertices++] = path_cmd_line_to;
m_move_to = (flags & 2) != 0;
}
m_x1 = x;
m_y1 = y;
}
//----------------------------------------------------------------------------
unsigned vpgen_clip_polyline::vertex(double* x, double* y)
{
if(m_vertex < m_num_vertices)
{
*x = m_x[m_vertex];
*y = m_y[m_vertex];
return m_cmd[m_vertex++];
}
return path_cmd_stop;
}
}

View file

@ -2,8 +2,8 @@
// 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.
// 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.
//
@ -19,49 +19,49 @@
namespace agg
{
void vpgen_segmentator::move_to(double x, double y)
{
m_x1 = x;
m_y1 = y;
m_dx = 0.0;
m_dy = 0.0;
m_dl = 2.0;
m_ddl = 2.0;
m_cmd = path_cmd_move_to;
}
void vpgen_segmentator::move_to(double x, double y)
{
m_x1 = x;
m_y1 = y;
m_dx = 0.0;
m_dy = 0.0;
m_dl = 2.0;
m_ddl = 2.0;
m_cmd = path_cmd_move_to;
}
void vpgen_segmentator::line_to(double x, double y)
{
m_x1 += m_dx;
m_y1 += m_dy;
m_dx = x - m_x1;
m_dy = y - m_y1;
double len = sqrt(m_dx * m_dx + m_dy * m_dy) * m_approximation_scale;
if(len < 1e-30) len = 1e-30;
m_ddl = 1.0 / len;
m_dl = (m_cmd == path_cmd_move_to) ? 0.0 : m_ddl;
if(m_cmd == path_cmd_stop) m_cmd = path_cmd_line_to;
}
void vpgen_segmentator::line_to(double x, double y)
{
m_x1 += m_dx;
m_y1 += m_dy;
m_dx = x - m_x1;
m_dy = y - m_y1;
double len = sqrt(m_dx * m_dx + m_dy * m_dy) * m_approximation_scale;
if(len < 1e-30) len = 1e-30;
m_ddl = 1.0 / len;
m_dl = (m_cmd == path_cmd_move_to) ? 0.0 : m_ddl;
if(m_cmd == path_cmd_stop) m_cmd = path_cmd_line_to;
}
unsigned vpgen_segmentator::vertex(double* x, double* y)
{
if(m_cmd == path_cmd_stop) return path_cmd_stop;
unsigned vpgen_segmentator::vertex(double* x, double* y)
{
if(m_cmd == path_cmd_stop) return path_cmd_stop;
unsigned cmd = m_cmd;
m_cmd = path_cmd_line_to;
if(m_dl >= 1.0 - m_ddl)
{
m_dl = 1.0;
m_cmd = path_cmd_stop;
*x = m_x1 + m_dx;
*y = m_y1 + m_dy;
return cmd;
}
*x = m_x1 + m_dx * m_dl;
*y = m_y1 + m_dy * m_dl;
m_dl += m_ddl;
unsigned cmd = m_cmd;
m_cmd = path_cmd_line_to;
if(m_dl >= 1.0 - m_ddl)
{
m_dl = 1.0;
m_cmd = path_cmd_stop;
*x = m_x1 + m_dx;
*y = m_y1 + m_dy;
return cmd;
}
*x = m_x1 + m_dx * m_dl;
*y = m_y1 + m_dy * m_dl;
m_dl += m_ddl;
return cmd;
}
}

View file

@ -1,338 +1,342 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 5.1.0 *
* Date : 1 February 2013 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2013 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: *
* "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
#ifndef clipper_hpp
#define clipper_hpp
#include <vector>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
namespace ClipperLib {
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
enum PolyType { ptSubject, ptClip };
//By far the most widely used winding rules for polygon filling are
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
//see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
typedef signed long long long64;
typedef unsigned long long ulong64;
struct IntPoint {
public:
long64 X;
long64 Y;
IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {};
friend std::ostream& operator <<(std::ostream &s, IntPoint &p);
};
typedef std::vector< IntPoint > Polygon;
typedef std::vector< Polygon > Polygons;
std::ostream& operator <<(std::ostream &s, Polygon &p);
std::ostream& operator <<(std::ostream &s, Polygons &p);
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
class PolyNode
{
public:
Polygon Contour;
PolyNodes Childs;
PolyNode* Parent;
PolyNode* GetNext();
bool IsHole();
int ChildCount();
private:
PolyNode* GetNextSiblingUp();
unsigned Index; //node index in Parent.Childs
void AddChild(PolyNode& child);
friend class Clipper; //to access Index
};
class PolyTree: public PolyNode
{
public:
~PolyTree(){Clear();};
PolyNode* GetFirst();
void Clear();
int Total();
private:
PolyNodes AllNodes;
friend class Clipper; //to access AllNodes
};
enum JoinType { jtSquare, jtRound, jtMiter };
bool Orientation(const Polygon &poly);
double Area(const Polygon &poly);
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
double delta, JoinType jointype = jtSquare, double MiterLimit = 2, bool AutoFix = true);
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd);
void CleanPolygon(Polygon& in_poly, Polygon& out_poly, double distance = 1.415);
void CleanPolygons(Polygons& in_polys, Polygons& out_polys, double distance = 1.415);
void PolyTreeToPolygons(PolyTree& polytree, Polygons& polygons);
void ReversePolygon(Polygon& p);
void ReversePolygons(Polygons& p);
//used internally ...
enum EdgeSide { esLeft = 1, esRight = 2};
enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 };
struct TEdge {
long64 xbot;
long64 ybot;
long64 xcurr;
long64 ycurr;
long64 xtop;
long64 ytop;
double dx;
long64 deltaX;
long64 deltaY;
long64 tmpX;
PolyType polyType;
EdgeSide side;
int windDelta; //1 or -1 depending on winding direction
int windCnt;
int windCnt2; //winding count of the opposite polytype
int outIdx;
TEdge *next;
TEdge *prev;
TEdge *nextInLML;
TEdge *nextInAEL;
TEdge *prevInAEL;
TEdge *nextInSEL;
TEdge *prevInSEL;
};
struct IntersectNode {
TEdge *edge1;
TEdge *edge2;
IntPoint pt;
IntersectNode *next;
};
struct LocalMinima {
long64 Y;
TEdge *leftBound;
TEdge *rightBound;
LocalMinima *next;
};
struct Scanbeam {
long64 Y;
Scanbeam *next;
};
struct OutPt; //forward declaration
struct OutRec {
int idx;
bool isHole;
OutRec *FirstLeft; //see comments in clipper.pas
PolyNode *polyNode;
OutPt *pts;
OutPt *bottomPt;
};
struct OutPt {
int idx;
IntPoint pt;
OutPt *next;
OutPt *prev;
};
struct JoinRec {
IntPoint pt1a;
IntPoint pt1b;
int poly1Idx;
IntPoint pt2a;
IntPoint pt2b;
int poly2Idx;
};
struct HorzJoinRec {
TEdge *edge;
int savedIdx;
};
struct IntRect { long64 left; long64 top; long64 right; long64 bottom; };
typedef std::vector < OutRec* > PolyOutList;
typedef std::vector < TEdge* > EdgeList;
typedef std::vector < JoinRec* > JoinList;
typedef std::vector < HorzJoinRec* > HorzJoinList;
//ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of
//polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase
{
public:
ClipperBase();
virtual ~ClipperBase();
bool AddPolygon(const Polygon &pg, PolyType polyType);
bool AddPolygons( const Polygons &ppg, PolyType polyType);
virtual void Clear();
IntRect GetBounds();
protected:
void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge *e);
void PopLocalMinima();
virtual void Reset();
void InsertLocalMinima(LocalMinima *newLm);
LocalMinima *m_CurrentLM;
LocalMinima *m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges;
};
class Clipper : public virtual ClipperBase
{
public:
Clipper();
~Clipper();
bool Execute(ClipType clipType,
Polygons &solution,
PolyFillType subjFillType = pftEvenOdd,
PolyFillType clipFillType = pftEvenOdd);
bool Execute(ClipType clipType,
PolyTree &polytree,
PolyFillType subjFillType = pftEvenOdd,
PolyFillType clipFillType = pftEvenOdd);
void Clear();
bool ReverseSolution() {return m_ReverseOutput;};
void ReverseSolution(bool value) {m_ReverseOutput = value;};
protected:
void Reset();
virtual bool ExecuteInternal();
private:
PolyOutList m_PolyOuts;
JoinList m_Joins;
HorzJoinList m_HorizJoins;
ClipType m_ClipType;
Scanbeam *m_Scanbeam;
TEdge *m_ActiveEdges;
TEdge *m_SortedEdges;
IntersectNode *m_IntersectNodes;
bool m_ExecuteLocked;
PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType;
bool m_ReverseOutput;
bool m_UsingPolyTree;
void DisposeScanbeamList();
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertScanbeam(const long64 Y);
long64 PopScanbeam();
void InsertLocalMinimaIntoAEL(const long64 botY);
void InsertEdgeIntoAEL(TEdge *edge);
void AddEdgeToSEL(TEdge *edge);
void CopyAELToSEL();
void DeleteFromSEL(TEdge *e);
void DeleteFromAEL(TEdge *e);
void UpdateEdgeIntoAEL(TEdge *&e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const long64 XPos);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DoMaxima(TEdge *e, long64 topY);
void ProcessHorizontals();
void ProcessHorizontal(TEdge *horzEdge);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
void AppendPolygon(TEdge *e1, TEdge *e2);
void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void IntersectEdges(TEdge *e1, TEdge *e2,
const IntPoint &pt, const IntersectProtects protects);
OutRec* CreateOutRec();
void AddOutPt(TEdge *e, const IntPoint &pt);
void DisposeAllPolyPts();
void DisposeOutRec(PolyOutList::size_type index);
bool ProcessIntersections(const long64 botY, const long64 topY);
void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt);
void BuildIntersectList(const long64 botY, const long64 topY);
void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const long64 topY);
void BuildResult(Polygons& polys);
void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *OutRec);
void DisposeIntersectNodes();
bool FixupIntersections();
void FixupOutPolygon(OutRec &outRec);
bool IsHole(TEdge *e);
void FixHoleLinkage(OutRec &outRec);
void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
void ClearJoins();
void AddHorzJoin(TEdge *e, int idx);
void ClearHorzJoins();
bool JoinPoints(const JoinRec *j, OutPt *&p1, OutPt *&p2);
void FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx);
void JoinCommonEdges();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
class clipperException : public std::exception
{
public:
clipperException(const char* description): m_descr(description) {}
virtual ~clipperException() throw() {}
virtual const char* what() const throw() {return m_descr.c_str();}
private:
std::string m_descr;
};
//------------------------------------------------------------------------------
} //ClipperLib namespace
#endif //clipper_hpp
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 5.1.3 *
* Date : 27 February 2013 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2013 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: *
* "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
#ifndef clipper_hpp
#define clipper_hpp
#include <vector>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
namespace ClipperLib {
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
enum PolyType { ptSubject, ptClip };
//By far the most widely used winding rules for polygon filling are
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
//see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
typedef signed long long long64;
typedef unsigned long long ulong64;
struct IntPoint {
public:
long64 X;
long64 Y;
IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {};
friend std::ostream& operator <<(std::ostream &s, IntPoint &p);
};
typedef std::vector< IntPoint > Polygon;
typedef std::vector< Polygon > Polygons;
std::ostream& operator <<(std::ostream &s, Polygon &p);
std::ostream& operator <<(std::ostream &s, Polygons &p);
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
class PolyNode
{
public:
PolyNode();
Polygon Contour;
PolyNodes Childs;
PolyNode* Parent;
PolyNode* GetNext() const;
bool IsHole() const;
int ChildCount() const;
private:
PolyNode* GetNextSiblingUp() const;
unsigned Index; //node index in Parent.Childs
void AddChild(PolyNode& child);
friend class Clipper; //to access Index
};
class PolyTree: public PolyNode
{
public:
~PolyTree(){Clear();};
PolyNode* GetFirst() const;
void Clear();
int Total() const;
private:
PolyNodes AllNodes;
friend class Clipper; //to access AllNodes
};
enum JoinType { jtSquare, jtRound, jtMiter };
bool Orientation(const Polygon &poly);
double Area(const Polygon &poly);
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
double delta, JoinType jointype = jtSquare, double limit = 0, bool autoFix = true);
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd);
void CleanPolygon(Polygon& in_poly, Polygon& out_poly, double distance = 1.415);
void CleanPolygons(Polygons& in_polys, Polygons& out_polys, double distance = 1.415);
void PolyTreeToPolygons(PolyTree& polytree, Polygons& polygons);
void ReversePolygon(Polygon& p);
void ReversePolygons(Polygons& p);
//used internally ...
enum EdgeSide { esLeft = 1, esRight = 2};
enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 };
struct TEdge {
long64 xbot;
long64 ybot;
long64 xcurr;
long64 ycurr;
long64 xtop;
long64 ytop;
double dx;
long64 deltaX;
long64 deltaY;
long64 tmpX;
PolyType polyType;
EdgeSide side;
int windDelta; //1 or -1 depending on winding direction
int windCnt;
int windCnt2; //winding count of the opposite polytype
int outIdx;
TEdge *next;
TEdge *prev;
TEdge *nextInLML;
TEdge *nextInAEL;
TEdge *prevInAEL;
TEdge *nextInSEL;
TEdge *prevInSEL;
};
struct IntersectNode {
TEdge *edge1;
TEdge *edge2;
IntPoint pt;
IntersectNode *next;
};
struct LocalMinima {
long64 Y;
TEdge *leftBound;
TEdge *rightBound;
LocalMinima *next;
};
struct Scanbeam {
long64 Y;
Scanbeam *next;
};
struct OutPt; //forward declaration
struct OutRec {
int idx;
bool isHole;
OutRec *FirstLeft; //see comments in clipper.pas
PolyNode *polyNode;
OutPt *pts;
OutPt *bottomPt;
};
struct OutPt {
int idx;
IntPoint pt;
OutPt *next;
OutPt *prev;
};
struct JoinRec {
IntPoint pt1a;
IntPoint pt1b;
int poly1Idx;
IntPoint pt2a;
IntPoint pt2b;
int poly2Idx;
};
struct HorzJoinRec {
TEdge *edge;
int savedIdx;
};
struct IntRect { long64 left; long64 top; long64 right; long64 bottom; };
typedef std::vector < OutRec* > PolyOutList;
typedef std::vector < TEdge* > EdgeList;
typedef std::vector < JoinRec* > JoinList;
typedef std::vector < HorzJoinRec* > HorzJoinList;
//ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of
//polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase
{
public:
ClipperBase();
virtual ~ClipperBase();
bool AddPolygon(const Polygon &pg, PolyType polyType);
bool AddPolygons( const Polygons &ppg, PolyType polyType);
virtual void Clear();
IntRect GetBounds();
protected:
void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge *e);
void PopLocalMinima();
virtual void Reset();
void InsertLocalMinima(LocalMinima *newLm);
LocalMinima *m_CurrentLM;
LocalMinima *m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges;
};
class Clipper : public virtual ClipperBase
{
public:
Clipper();
~Clipper();
bool Execute(ClipType clipType,
Polygons &solution,
PolyFillType subjFillType = pftEvenOdd,
PolyFillType clipFillType = pftEvenOdd);
bool Execute(ClipType clipType,
PolyTree &polytree,
PolyFillType subjFillType = pftEvenOdd,
PolyFillType clipFillType = pftEvenOdd);
void Clear();
bool ReverseSolution() {return m_ReverseOutput;};
void ReverseSolution(bool value) {m_ReverseOutput = value;};
protected:
void Reset();
virtual bool ExecuteInternal();
private:
PolyOutList m_PolyOuts;
JoinList m_Joins;
HorzJoinList m_HorizJoins;
ClipType m_ClipType;
Scanbeam *m_Scanbeam;
TEdge *m_ActiveEdges;
TEdge *m_SortedEdges;
IntersectNode *m_IntersectNodes;
bool m_ExecuteLocked;
PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType;
bool m_ReverseOutput;
bool m_UsingPolyTree;
void DisposeScanbeamList();
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertScanbeam(const long64 Y);
long64 PopScanbeam();
void InsertLocalMinimaIntoAEL(const long64 botY);
void InsertEdgeIntoAEL(TEdge *edge);
void AddEdgeToSEL(TEdge *edge);
void CopyAELToSEL();
void DeleteFromSEL(TEdge *e);
void DeleteFromAEL(TEdge *e);
void UpdateEdgeIntoAEL(TEdge *&e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const long64 XPos);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DoMaxima(TEdge *e, long64 topY);
void ProcessHorizontals();
void ProcessHorizontal(TEdge *horzEdge);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
void AppendPolygon(TEdge *e1, TEdge *e2);
void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void IntersectEdges(TEdge *e1, TEdge *e2,
const IntPoint &pt, const IntersectProtects protects);
OutRec* CreateOutRec();
void AddOutPt(TEdge *e, const IntPoint &pt);
void DisposeAllPolyPts();
void DisposeOutRec(PolyOutList::size_type index);
bool ProcessIntersections(const long64 botY, const long64 topY);
void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt);
void BuildIntersectList(const long64 botY, const long64 topY);
void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const long64 topY);
void BuildResult(Polygons& polys);
void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *OutRec);
void DisposeIntersectNodes();
bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outRec);
bool IsHole(TEdge *e);
void FixHoleLinkage(OutRec &outRec);
void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
void ClearJoins();
void AddHorzJoin(TEdge *e, int idx);
void ClearHorzJoins();
bool JoinPoints(const JoinRec *j, OutPt *&p1, OutPt *&p2);
void FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx);
void JoinCommonEdges();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
class clipperException : public std::exception
{
public:
clipperException(const char* description): m_descr(description) {}
virtual ~clipperException() throw() {}
virtual const char* what() const throw() {return m_descr.c_str();}
private:
std::string m_descr;
};
//------------------------------------------------------------------------------
} //ClipperLib namespace
#endif //clipper_hpp

File diff suppressed because it is too large Load diff

View file

@ -68,6 +68,10 @@ public:
T miny() const;
T maxx() const;
T maxy() const;
void set_minx(T v);
void set_miny(T v);
void set_maxx(T v);
void set_maxy(T v);
T width() const;
T height() const;
void width(T w);

View file

@ -245,6 +245,7 @@ double path_length(PathType & path)
double length = 0;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
if (command == SEG_CLOSE) continue;
length += distance(x0,y0,x1,y1);
x0 = x1;
y0 = y1;
@ -268,6 +269,7 @@ bool middle_point(PathType & path, double & x, double & y)
double dist = 0.0;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
if (command == SEG_CLOSE) continue;
double seg_length = distance(x0, y0, x1, y1);
if ( dist + seg_length >= mid_length)
@ -307,6 +309,7 @@ bool centroid(PathType & path, double & x, double & y)
unsigned count = 1;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
if (command == SEG_CLOSE) continue;
double dx0 = x0 - start_x;
double dy0 = y0 - start_y;
double dx1 = x1 - start_x;
@ -370,6 +373,7 @@ bool centroid_geoms(Iter start, Iter end, double & x, double & y)
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
if (command == SEG_CLOSE) continue;
double dx0 = x0 - start_x;
double dy0 = y0 - start_y;
double dx1 = x1 - start_x;

View file

@ -122,37 +122,9 @@ public:
push_vertex(x,y,SEG_MOVETO);
}
void close(coord_type x, coord_type y)
void close_path()
{
push_vertex(x,y,SEG_CLOSE);
}
void set_close()
{
if (cont_.size() > 3)
{
unsigned cmd;
double x,y;
int index = cont_.size() - 1;
unsigned last_cmd = cont_.get_vertex(index,&x,&y);
if (last_cmd == SEG_LINETO)
{
double last_x = x;
double last_y = y;
for (int pos = index - 1; pos >=0 ; --pos)
{
cmd = cont_.get_vertex(pos,&x,&y);
if (cmd == SEG_MOVETO)
{
if (x == last_x && y == last_y)
{
cont_.set_command(index , SEG_CLOSE);
}
break;
}
}
}
}
push_vertex(0,0,SEG_CLOSE);
}
unsigned vertex(double* x, double* y) const

View file

@ -405,16 +405,13 @@ void apply_filter(Src & src, agg_stack_blur const& op)
}
template <typename Src>
void apply_filter(Src & src, hsla const& op)
void apply_filter(Src & src, hsla const& transform)
{
using namespace boost::gil;
Tinter tint;
tint.h0 = .1;
tint.s0 = .3;
tint.l1 = .9;
bool tinting = !tint.is_identity();
bool set_alpha = !tint.is_alpha_identity();
// todo - should filters be able to report if they should be run?
bool tinting = !transform.is_identity();
bool set_alpha = !transform.is_alpha_identity();
// todo - filters be able to report if they
// should be run to avoid overhead of temp buffer
if (tinting || set_alpha)
{
rgba8_view_t src_view = rgba8_view(src);
@ -423,44 +420,74 @@ void apply_filter(Src & src, hsla const& op)
rgba8_view_t::x_iterator src_it = src_view.row_begin(y);
for (int x=0; x<src_view.width(); ++x)
{
uint8_t & r = get_color(src_it[x], red_t());
uint8_t & g = get_color(src_it[x], green_t());
uint8_t & b = get_color(src_it[x], blue_t());
uint8_t & a = get_color(src_it[x], alpha_t());
uint8_t a_original = a;
if (set_alpha)
double a2 = a/255.0;
double a1 = a2;
if (set_alpha && a2 > 0.01)
{
double a2 = tint.a0 + (a/255.0 * (tint.a1 - tint.a0));
if (a2 > 1) a2 = 1;
if (a2 < 0) a2 = 0;
a = static_cast<unsigned>(std::floor(a2 * 255.0));
a2 = transform.a0 + (a2 * (transform.a1 - transform.a0));
a = static_cast<unsigned>(std::floor((a2 * 255.0) +.5));
if (a > 255) a = 255;
if (a < 0) a = 0;
}
if (a > 1 && tinting)
if (tinting && a2 > 0.01)
{
double h;
double s;
double l;
uint8_t & r = get_color(src_it[x], red_t());
uint8_t & g = get_color(src_it[x], green_t());
uint8_t & b = get_color(src_it[x], blue_t());
// demultiply
r /= a_original;
g /= a_original;
b /= a_original;
if (a1 <= 0.0)
{
r = g = b = 0;
continue;
}
else if (a1 < 1)
{
r /= a1;
g /= a1;
b /= a1;
}
rgb2hsl(r,g,b,h,s,l);
double h2 = tint.h0 + (h * (tint.h1 - tint.h0));
double s2 = tint.s0 + (s * (tint.s1 - tint.s0));
double l2 = tint.l0 + (l * (tint.l1 - tint.l0));
if (h2 > 1) h2 = 1;
else if (h2 < 0) h2 = 0;
if (s2 > 1) s2 = 1;
else if (s2 < 0) s2 = 0;
if (l2 > 1) l2 = 1;
else if (l2 < 0) l2 = 0;
double h2 = transform.h0 + (h * (transform.h1 - transform.h0));
double s2 = transform.s0 + (s * (transform.s1 - transform.s0));
double l2 = transform.l0 + (l * (transform.l1 - transform.l0));
if (h2 > 1) { std::clog << "h2: " << h2 << "\n"; h2 = 1; }
else if (h2 < 0) { std::clog << "h2: " << h2 << "\n"; h2 = 0; }
if (s2 > 1) { std::clog << "h2: " << h2 << "\n"; s2 = 1; }
else if (s2 < 0) { std::clog << "s2: " << s2 << "\n"; s2 = 0; }
if (l2 > 1) { std::clog << "h2: " << h2 << "\n"; l2 = 1; }
else if (l2 < 0) { std::clog << "l2: " << l2 << "\n"; l2 = 0; }
hsl2rgb(h2,s2,l2,r,g,b);
// premultiply
// we only work with premultiplied source,
// thus all color values must be <= alpha
r *= a;
g *= a;
b *= a;
r *= a2;
g *= a2;
b *= a2;
}
else
{
// demultiply
if (a1 <= 0.0)
{
r = g = b = 0;
continue;
}
else if (a1 < 1)
{
r /= a1;
g /= a1;
b /= a1;
}
// premultiply
// we only work with premultiplied source,
// thus all color values must be <= alpha
r *= a2;
g *= a2;
b *= a2;
}
}
}

View file

@ -25,10 +25,12 @@
// boost
#include <boost/spirit/include/qi.hpp>
// mapnik
#include <mapnik/css_color_grammar.hpp>
// stl
#include <vector>
namespace mapnik {
namespace qi = boost::spirit::qi;
@ -41,9 +43,12 @@ struct image_filter_grammar :
qi::rule<Iterator, ContType(), qi::ascii::space_type> start;
qi::rule<Iterator, ContType(), qi::ascii::space_type> filter;
qi::rule<Iterator, qi::locals<int,int>, void(ContType&), qi::ascii::space_type> agg_blur_filter;
qi::rule<Iterator, qi::locals<std::string>, void(ContType&), qi::ascii::space_type> hsla_filter;
qi::rule<Iterator, std::string(), qi::ascii::space_type> string_arg;
qi::rule<Iterator, qi::locals<double,double,double,double,double,double,double,double>,
void(ContType&), qi::ascii::space_type> hsla_filter;
qi::rule<Iterator, qi::locals<mapnik::color,mapnik::color>, void(ContType&), qi::ascii::space_type> colorize_alpha_filter;
qi::rule<Iterator, qi::ascii::space_type> no_args;
qi::uint_parser< unsigned, 10, 1, 3 > radius_;
css_color_grammar<Iterator> css_color_;
};
}

View file

@ -25,10 +25,10 @@
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/color.hpp>
// boost
#include <boost/variant.hpp>
#include <boost/variant/variant_fwd.hpp>
// stl
#include <vector>
#include <ostream>
@ -56,9 +56,54 @@ struct agg_stack_blur
struct hsla
{
hsla(std::string const& tint_string)
: tinter(tint_string) {}
std::string tinter;
hsla(double _h0, double _h1,
double _s0, double _s1,
double _l0, double _l1,
double _a0, double _a1) :
h0(_h0),
h1(_h1),
s0(_s0),
s1(_s1),
l0(_l0),
l1(_l1),
a0(_a0),
a1(_a1) {}
inline bool is_identity() const {
return (h0 == 0 &&
h1 == 1 &&
s0 == 0 &&
s1 == 1 &&
l0 == 0 &&
l1 == 1);
}
inline bool is_alpha_identity() const {
return (a0 == 0 &&
a1 == 1);
}
std::string to_string() const {
std::ostringstream s;
s << h0 << "x" << h1 << ";"
<< s0 << "x" << s1 << ";"
<< l0 << "x" << l1 << ";"
<< a0 << "x" << a1;
return s.str();
}
double h0;
double h1;
double s0;
double s1;
double l0;
double l1;
double a0;
double a1;
};
struct colorize_alpha
{
colorize_alpha(mapnik::color const& c0, mapnik::color const& c1)
{
// TODO: implement me!
}
};
typedef boost::variant<filter::blur,
@ -71,7 +116,8 @@ typedef boost::variant<filter::blur,
filter::x_gradient,
filter::y_gradient,
filter::invert,
filter::hsla> filter_type;
filter::hsla,
filter::colorize_alpha> filter_type;
inline std::ostream& operator<< (std::ostream& os, blur)
{
@ -93,7 +139,10 @@ inline std::ostream& operator<< (std::ostream& os, agg_stack_blur const& filter)
inline std::ostream& operator<< (std::ostream& os, hsla const& filter)
{
os << "hsla(" << filter.tinter << ')';
os << "hsla(" << filter.h0 << 'x' << filter.h1 << ':'
<< filter.s0 << 'x' << filter.s1 << ':'
<< filter.l0 << 'x' << filter.l1 << ':'
<< filter.a0 << 'x' << filter.a1 << ')';
return os;
}

View file

@ -29,13 +29,11 @@
// spirit::qi
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
namespace mapnik { namespace json {
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
namespace fusion = boost::fusion;
namespace standard_wide = boost::spirit::standard_wide;
using standard_wide::space_type;
@ -67,7 +65,7 @@ struct close_path
void operator() (T path) const
{
BOOST_ASSERT( path!=0 );
path->set_close();
path->close_path();
}
};

View file

@ -174,7 +174,7 @@ public:
last_x = next_x;
last_y = next_y;
}
if (agg::is_stop(cmd))
if (agg::is_stop(cmd) || cmd == SEG_CLOSE)
{
done_ = true;
return false;

View file

@ -172,8 +172,6 @@ wkb_buffer_ptr to_polygon_wkb( GeometryType const& g, wkbByteOrder byte_order)
double x = 0;
double y = 0;
double start_x = 0;
double start_y = 0;
std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings
for (unsigned i=0; i< num_points; ++i)
{
@ -181,17 +179,15 @@ wkb_buffer_ptr to_polygon_wkb( GeometryType const& g, wkbByteOrder byte_order)
if (command == SEG_MOVETO)
{
rings.push_back(new linear_ring); // start new loop
start_x = x;
start_y = y;
rings.back().push_back(std::make_pair(x,y));
size += 4; // num_points
size += 2 * 8; // point
}
else if (command == SEG_CLOSE)
else if (command == SEG_LINETO)
{
x = start_x;
y = start_y;
rings.back().push_back(std::make_pair(x,y));
size += 2 * 8; // point
}
rings.back().push_back(std::make_pair(x,y));
size += 2 * 8; // point
}
unsigned num_rings = rings.size();
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);

View file

@ -27,41 +27,6 @@
namespace mapnik {
struct Tinter {
double h0;
double h1;
double s0;
double s1;
double l0;
double l1;
double a0;
double a1;
Tinter() :
h0(0),
h1(1),
s0(0),
s1(1),
l0(0),
l1(1),
a0(0),
a1(1) { }
bool is_identity() {
return (h0 == 0 &&
h1 == 1 &&
s0 == 0 &&
s1 == 1 &&
l0 == 0 &&
l1 == 1);
}
bool is_alpha_identity() {
return (a0 == 0 &&
a1 == 1);
}
};
static inline void rgb2hsl(unsigned char red, unsigned char green, unsigned char blue,
double & h, double & s, double & l) {
double r = red/255.0;

View file

@ -71,7 +71,7 @@ namespace mapnik { namespace wkt {
void operator() (T path) const
{
BOOST_ASSERT( path!=0 );
path->set_close();
path->close_path();
}
};

View file

@ -61,7 +61,8 @@ occi_featureset::occi_featureset(StatelessConnectionPool* pool,
bool use_connection_pool,
bool use_wkb,
unsigned prefetch_rows)
: tr_(new transcoder(encoding)),
: rs_(NULL),
tr_(new transcoder(encoding)),
feature_id_(1),
ctx_(ctx),
use_wkb_(use_wkb)
@ -82,6 +83,8 @@ occi_featureset::occi_featureset(StatelessConnectionPool* pool,
catch (SQLException &ex)
{
MAPNIK_LOG_ERROR(occi) << "OCCI Plugin: error processing " << sqlstring << " : " << ex.getMessage();
rs_ = NULL;
}
}
@ -91,9 +94,9 @@ occi_featureset::~occi_featureset()
feature_ptr occi_featureset::next()
{
if (rs_ && rs_->next())
if (rs_ != NULL && rs_->next())
{
feature_ptr feature(feature_factory::create(ctx_,feature_id_));
feature_ptr feature(feature_factory::create(ctx_, feature_id_));
++feature_id_;
if (use_wkb_)
@ -101,13 +104,13 @@ feature_ptr occi_featureset::next()
Blob blob = rs_->getBlob(1);
blob.open(oracle::occi::OCCI_LOB_READONLY);
int size = blob.length();
unsigned int size = blob.length();
if (buffer_.size() < size)
{
buffer_.resize(size);
}
oracle::occi::Stream* instream = blob.getStream(1,0);
oracle::occi::Stream* instream = blob.getStream(1, 0);
instream->readBuffer(buffer_.data(), size);
blob.closeStream(instream);
blob.close();

View file

@ -111,21 +111,21 @@ void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature)
std::auto_ptr<geometry_type> poly(new geometry_type(mapnik::Polygon));
poly->move_to(exterior->getX(0), exterior->getY(0));
for (int i = 1; i < num_points - 1; ++i)
for (int i = 1; i < num_points; ++i)
{
poly->line_to(exterior->getX(i), exterior->getY(i));
}
poly->close(exterior->getX(num_points-1), exterior->getY(num_points-1));
poly->close_path();
for (int r = 0; r < num_interior; ++r)
{
OGRLinearRing* interior = geom->getInteriorRing(r);
num_points = interior->getNumPoints();
poly->move_to(interior->getX(0), interior->getY(0));
for (int i = 1; i < num_points - 1; ++i)
for (int i = 1; i < num_points; ++i)
{
poly->line_to(interior->getX(i), interior->getY(i));
}
poly->close(interior->getX(num_points-1), interior->getY(num_points-1));
poly->close_path();
}
feature->paths().push_back(poly);
}

View file

@ -177,22 +177,13 @@ void shape_io::read_polygon(shape_file::record_type & record, mapnik::geometry_c
poly->move_to(x, y);
double start_x = x;
double start_y = y;
for (int j=start+1;j<end-1;j++)
for (int j=start+1;j<end;j++)
{
x = record.read_double();
y = record.read_double();
poly->line_to(x, y);
}
x = record.read_double();
y = record.read_double();
if (x == start_x && y == start_y)
{
poly->close(x, y);
}
else
{
poly->line_to(x, y);
}
poly->close_path();
geom.push_back(poly);
}
}

View file

@ -270,13 +270,12 @@ void agg_renderer<T>::end_style_processing(feature_type_style const& st)
{
composite(pixmap_.data(),current_buffer_->data(), src_over, st.get_opacity(), 0, 0, false);
}
// apply any 'direct' image filters
mapnik::filter::filter_visitor<image_32> visitor(pixmap_);
BOOST_FOREACH(mapnik::filter::filter_type const& filter_tag, st.direct_image_filters())
{
boost::apply_visitor(visitor, filter_tag);
}
}
// apply any 'direct' image filters
mapnik::filter::filter_visitor<image_32> visitor(pixmap_);
BOOST_FOREACH(mapnik::filter::filter_type const& filter_tag, st.direct_image_filters())
{
boost::apply_visitor(visitor, filter_tag);
}
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End processing style";
}

View file

@ -99,11 +99,15 @@ void agg_renderer<T>::process(building_symbolizer const& sym,
{
frame->move_to(x,y);
}
else if (cm == SEG_LINETO || cm == SEG_CLOSE)
else if (cm == SEG_LINETO)
{
frame->line_to(x,y);
face_segments.push_back(segment_t(x0,y0,x,y));
}
else if (cm == SEG_CLOSE)
{
frame->close_path();
}
x0 = x;
y0 = y;
}
@ -140,11 +144,16 @@ void agg_renderer<T>::process(building_symbolizer const& sym,
frame->move_to(x,y+height);
roof->move_to(x,y+height);
}
else if (cm == SEG_LINETO || cm == SEG_CLOSE)
else if (cm == SEG_LINETO)
{
frame->line_to(x,y+height);
roof->line_to(x,y+height);
}
else if (cm == SEG_CLOSE)
{
frame->close_path();
roof->close_path();
}
}
path_type path(t_,*frame,prj_trans);

View file

@ -128,6 +128,30 @@ T box2d<T>::maxy() const
return maxy_;
}
template<typename T>
void box2d<T>::set_minx(T v)
{
minx_ = v;
}
template<typename T>
void box2d<T>::set_miny(T v)
{
miny_ = v;
}
template<typename T>
void box2d<T>::set_maxx(T v)
{
maxx_ = v;
}
template<typename T>
void box2d<T>::set_maxy(T v)
{
maxy_ = v;
}
template <typename T>
#if !defined(__SUNPRO_CC)
inline

View file

@ -377,11 +377,15 @@ void cairo_renderer_base::process(building_symbolizer const& sym,
{
frame->move_to(x,y);
}
else if (cm == SEG_LINETO || cm == SEG_CLOSE)
else if (cm == SEG_LINETO)
{
frame->line_to(x,y);
face_segments.push_back(segment_t(x0,y0,x,y));
}
else if (cm == SEG_CLOSE)
{
frame->close_path();
}
x0 = x;
y0 = y;
}
@ -416,11 +420,16 @@ void cairo_renderer_base::process(building_symbolizer const& sym,
frame->move_to(x,y+height);
roof->move_to(x,y+height);
}
else if (cm == SEG_LINETO || cm == SEG_CLOSE)
else if (cm == SEG_LINETO)
{
frame->line_to(x,y+height);
roof->line_to(x,y+height);
}
else if (cm == SEG_CLOSE)
{
frame->close_path();
roof->close_path();
}
}
path_type path(t_, *frame, prj_trans);

View file

@ -44,10 +44,17 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
using qi::_1;
using qi::_a;
using qi::_b;
using qi::_c;
using qi::_d;
using qi::_e;
using qi::_f;
using qi::_g;
using qi::_h;
using qi::_r1;
using qi::eps;
using qi::char_;
using qi::lexeme;
using qi::double_;
using boost::spirit::ascii::string;
using phoenix::push_back;
using phoenix::construct;
@ -62,42 +69,55 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
#endif
filter =
lit("emboss")[push_back(_val,construct<mapnik::filter::emboss>())]
lit("emboss") >> no_args [push_back(_val,construct<mapnik::filter::emboss>())]
|
lit("blur")[push_back(_val,construct<mapnik::filter::blur>())]
lit("blur") >> no_args [push_back(_val,construct<mapnik::filter::blur>())]
|
lit("gray")[push_back(_val,construct<mapnik::filter::gray>())]
lit("gray") >> no_args [push_back(_val,construct<mapnik::filter::gray>())]
|
lit("edge-detect")[push_back(_val,construct<mapnik::filter::edge_detect>())]
lit("edge-detect") >> no_args [push_back(_val,construct<mapnik::filter::edge_detect>())]
|
lit("sobel")[push_back(_val,construct<mapnik::filter::sobel>())]
lit("sobel") >> no_args [push_back(_val,construct<mapnik::filter::sobel>())]
|
lit("sharpen")[push_back(_val,construct<mapnik::filter::sharpen>())]
lit("sharpen") >> no_args [push_back(_val,construct<mapnik::filter::sharpen>())]
|
lit("x-gradient")[push_back(_val,construct<mapnik::filter::x_gradient>())]
lit("x-gradient") >> no_args [push_back(_val,construct<mapnik::filter::x_gradient>())]
|
lit("y-gradient")[push_back(_val,construct<mapnik::filter::y_gradient>())]
lit("y-gradient") >> no_args [push_back(_val,construct<mapnik::filter::y_gradient>())]
|
lit("invert")[push_back(_val,construct<mapnik::filter::invert>())]
lit("invert") >> no_args [push_back(_val,construct<mapnik::filter::invert>())]
|
agg_blur_filter(_val)
|
hsla_filter(_val)
|
colorize_alpha_filter(_val)
;
agg_blur_filter = (lit("agg-stack-blur")[_a = 1, _b = 1]
>> -( lit('(') >> radius_[_a = _1]
>> lit(',')
>> radius_[_b = _1]
>> lit(')')))
agg_blur_filter = lit("agg-stack-blur")[_a = 1, _b = 1]
>> -( lit('(') >> -( radius_[_a = _1][_b = _1]
>> -(lit(',') >> radius_[_b = _1]))
>> lit(')'))
[push_back(_r1,construct<mapnik::filter::agg_stack_blur>(_a,_b))]
;
hsla_filter = (lit("hsla") >> lit('(') >> string_arg[_a = _1] >> lit(')'))
[push_back(_r1,construct<mapnik::filter::hsla>(_a))]
hsla_filter = lit("hsla")
>> lit('(')
>> double_[_a = _1] >> lit('x') >> double_[_b = _1] >> lit(';')
>> double_[_c = _1] >> lit('x') >> double_[_d = _1] >> lit(';')
>> double_[_e = _1] >> lit('x') >> double_[_f = _1] >> lit(';')
>> double_[_g = _1] >> lit('x') >> double_[_h = _1] >> lit(')')
[push_back(_r1, construct<mapnik::filter::hsla>(_a,_b,_c,_d,_e,_f,_g,_h))]
;
string_arg = +~char_(')');
colorize_alpha_filter = lit("colorize-alpha")
>> lit('(')
>> css_color_[_a = _1] >> lit(',')
>> css_color_[_b = _1] >> lit(')')
[push_back(_r1,construct<mapnik::filter::colorize_alpha>(_a,_b))]
;
no_args = -(lit('(') >> lit(')'));
}
template struct mapnik::image_filter_grammar<std::string::const_iterator,std::vector<mapnik::filter::filter_type> >;

View file

@ -28,6 +28,11 @@
// boost
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <iostream> // for clog, endl, etc
#include <string> // for string
namespace mapnik { namespace json {
@ -52,9 +57,9 @@ geometry_grammar<Iterator>::geometry_grammar()
using qi::_pass;
using qi::fail;
using qi::on_error;
using phoenix::new_;
using phoenix::push_back;
using phoenix::construct;
using boost::phoenix::new_;
using boost::phoenix::push_back;
using boost::phoenix::construct;
// Nabialek trick - FIXME: how to bind argument to dispatch rule?
// geometry = lit("\"geometry\"")
// >> lit(':') >> lit('{')
@ -144,11 +149,11 @@ geometry_grammar<Iterator>::geometry_grammar()
(
geometry
, std::clog
<< phoenix::val("Error! Expecting ")
<< boost::phoenix::val("Error! Expecting ")
<< _4 // what failed?
<< phoenix::val(" here: \"")
<< boost::phoenix::val(" here: \"")
<< construct<std::string>(_3, _2) // iterators to error-pos, end
<< phoenix::val("\"")
<< boost::phoenix::val("\"")
<< std::endl
);
}

View file

@ -353,25 +353,14 @@ private:
CoordinateArray ar(num_points);
read_coords(ar);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points - 1; ++j)
for (int j = 1; j < num_points ; ++j)
{
poly->line_to(ar[j].x, ar[j].y);
}
if (ar[0].x == ar[num_points-1].x &&
ar[0].y == ar[num_points-1].y)
{
poly->close(ar[num_points-1].x, ar[num_points-1].y);
}
else
{
// leave un-closed polygon intact - don't attempt to close them
poly->line_to(ar[num_points-1].x, ar[num_points-1].y);
}
poly->set_close();
poly->close_path();
}
}
if (poly->size() > 2) // ignore if polygon has less than 3 vertices
if (poly->size() > 3) // ignore if polygon has less than (3 + close_path) vertices
paths.push_back(poly);
}
}
@ -400,20 +389,11 @@ private:
CoordinateArray ar(num_points);
read_coords_xyz(ar);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points - 1; ++j)
for (int j = 1; j < num_points; ++j)
{
poly->line_to(ar[j].x, ar[j].y);
}
if (ar[0].x == ar[num_points-1].x &&
ar[0].y == ar[num_points-1].y)
{
poly->close(ar[num_points-1].x, ar[num_points-1].y);
}
else
{
// leave un-closed polygon intact- don't attempt to close them
poly->line_to(ar[num_points-1].x, ar[num_points-1].y);
}
poly->close_path();
}
}
if (poly->size() > 2) // ignore if polygon has less than 3 vertices

View file

@ -66,8 +66,6 @@ wkt_generator<OutputIterator, Geometry>::wkt_generator(bool single)
using boost::spirit::karma::_b;
using boost::spirit::karma::_c;
using boost::spirit::karma::_r1;
using boost::spirit::karma::_r2;
using boost::spirit::karma::_r3;
using boost::spirit::karma::eps;
using boost::spirit::karma::string;
@ -98,15 +96,12 @@ wkt_generator<OutputIterator, Geometry>::wkt_generator(bool single)
;
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO)
<< eps[_r1 += 1][_a = _r2 = _x(_val)][ _b = _r3 = _y(_val)]
<< eps[_r1 += 1][_a = _x(_val)][ _b = _y(_val)]
<< string[ if_ (_r1 > 1) [_1 = "),("]
.else_[_1 = "("]]
|
&uint_(mapnik::SEG_LINETO)
<< lit(',') << eps[_a = _x(_val)][_b = _y(_val)]
|
&uint_(mapnik::SEG_CLOSE)
<< lit(',') << eps[_a = _r2][_b = _r3]
)
<< coordinate[_1 = _a]
<< lit(' ')

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

View file

@ -0,0 +1 @@
PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","3857"],AXIS["X",EAST],AXIS["Y",NORTH]]

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,73 @@
{
"keys": [
"",
"1"
],
"data": {},
"grid": [
" !!!! !!!! !!!! !!!! !!!! !!!! ",
" ! ! ! ! ! ! ! ",
" ! ",
" ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ",
" ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ",
" ",
" ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ",
" ! ",
" ! ",
" ! ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ",
" ",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ",
" ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ",
" ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! !!!! !!!! !!!! !!!! !!!! !!!! ",
" ! ! ! ",
" ! ! ! ! ! ! ",
" !!!! !!!! !!!! !!!! !!!! !!!! ! ",
" ! ! ! ! ! ",
" ! ! ! ! ! ",
" ! !!!! !!!! !!!! !!!! !!!! !!!! ",
" ! ! ! ! ! ! ",
" ! ! ! ! ",
" !!!! !!!! !!!! !!!! !!!! !!!! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ",
" ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ",
" ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ",
" ",
" ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ",
" ! ",
" ! ",
" ! ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ",
" ",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ",
" ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ",
" ! ! ",
" ! ! ! ! ! ! ! ! ",
" !!!! !!!! !!!! !!!! !!!! !!!! ! ",
" ! ! ! ",
" ! ! ! ! ! ! ",
" ! !!!! !!!! !!!! !!!! !!!! !!!! ",
" ! ! ! ! ! ",
" ! ! ! ! ! ",
" !!!! !!!! !!!! !!!! !!!! !!!! ! ",
" ! ! ! ! ! ",
" ! ! ! ! "
]
}

View file

@ -0,0 +1,159 @@
{
"keys": [
"",
"1"
],
"data": {},
"grid": [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ! ! ! ! ",
" !! ! !! ! ! !! ! !! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! ! ! ! ",
" ! ! ! ! ! !! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ",
"! !!!! !!!! ! !!! ! !!!! !!!! !!!! ",
" ! ! ! ! ! ! ! ! ! ",
" ! !! ! ! ! !! ! !! ! ",
" ! ! ! ! ! ! ! ! !",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" !! ! !! ! ! ! !! !! ! !",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
"! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! !",
" ! ! ! ! ! ! ! ! ! ",
" !!!! !!!! ! !!!! ! !!! !!!! !!!! ",
" ! ! ! ! ! ! !! ! !",
" !! ! ! ! ! !! ! !! ",
" ! ! ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ! ",
" !! ! !! ! ! ! !! ! !! ! ",
" ! ! ! !! ! !! ! ",
" ! ! ! ! ! ! ! ! ! !",
" !!!! !!!! ! !!!! ! !!! !!!! !!!! ",
" ! ! ! ! ! ! ! ",
" !! ! ! ! ! !! ! !! ! !",
" ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ! ",
"! !!!! ! !!!! ! !!!! !!!! !!!! !!!! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! ! !",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" !! ! !! ! ! ! !! !! ! !",
" !! ! ! ! ! !! ! ",
" ! ! ! ! ! ! ! ! ! ",
"! !!!! ! !!!! ! !!! ! !!!! !!!! !!!! ",
" ! ! ! ! ! ! ! ! ",
" ! !! ! ! ! ! ! !! ! !! ! ",
" ! ! ! ! ! ! ! !",
" ! ! ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! ! ! ! ! ! !",
" !! ! ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ! ! ! ",
" !! ! !! ! ! ! !! ! !! ! ",
" !! ! ! !! ! !! ! ",
" ! ! ! ! ! ! ! ! !",
" !!!! !!!! ! !!!! ! !!! !!!! !!!! ",
" ! ! ! ! ! ! ! ! ! ",
" !! ! !! ! ! ! !! ! !! ! !",
" ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ! ",
"! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! !",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ! ",
" !! ! !! ! ! ! ! !! !! ! !",
" !! ! ! ! ! !! !! ",
" ! ! ! ! ! ! ! ! ! ! ",
"! !!!! !!!! ! !!! ! !!!! !!!! !!!! ",
" ! ! ! ! ! ! ! ",
" ! !! ! !! ! ! !! ! !! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! ! ! ! ! ",
" !! ! ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
"! ! ! ! ! ! ! ! ! ! ! ",
" !! ! ! ! ! ! !! ! ! ",
" !! ! ! !! ! !! !! ",
" ! ! ! ! ! ! ! ! ! !",
" ! ! !! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" !! ! !! ! ! ! !! ! !! ! !",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
"! !!!!!! !!!!!! !!!!!! !!!!! !!!!!! !!!!!! ",
" ! ! ! ! ! ! ",
" ! ! ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! ! !",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! !! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! !",
" ! ! ! ! ",
" ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]
}

View file

@ -0,0 +1,109 @@
{
"keys": [
"",
"1"
],
"data": {},
"grid": [
" !!!!!! !!!!!! !!!!! !!!!!! !!!!!! !!!!!! ",
" ! !! !! ! !! ! ! !! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! !! !! ! ! ! ! !! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! !! !! ! ! ! ! !! ",
" ! ! ! !! !! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! !! ! ! ! ",
" ! ! ! ! !! ! ! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! !! ! ! ! ! ! ! ",
" ! ! ! !! !! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" !! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" !!!! !!!! ! !!! ! !!!! !!!! !!!! ",
" ! ! !! ! ! ! ! ! ! ",
" ! ! ! ! !! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! !!!! !!!! !!!! ! !!!! ! !!!! !!!! ",
" ! ! ! !! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! !! !! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! !! !! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! !! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! !! !! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! !! !! ! ! ! ! ",
" ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! ",
" ! ! ! !! ! !! ! ! ! ! ! ! ",
" ! ! ! !! !! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! !! ! ! ! ",
" ! ! ! ! !! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ",
" ! !!!! !!!! !!!! ! !!! ! !!!! !!!! ",
" ! ! ! ! ! !! ! ! ! ! ! ! ",
" ! ! ! ! ! !! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ",
" !!!! !!!! ! !!! ! !!!! !!!! !!!! ",
" ! ! !! !! !! ! ! !! ",
" ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" !! ! ! ! ! ! ! !! ! ! ",
" ! ! ! ! ! ! ! ! ! ",
" ! ! ! ! ! ! ",
" ! ! ! ! ! ",
" ! ! ! ! ! ! "
]
}

View file

@ -0,0 +1,73 @@
{
"keys": [
"",
"1"
],
"data": {},
"grid": [
" !!!!!!!! ",
" !!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!! "
]
}

View file

@ -0,0 +1,159 @@
{
"keys": [
"",
"1"
],
"data": {},
"grid": [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" !!!!!!!! ",
" !!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!! ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]
}

View file

@ -0,0 +1,109 @@
{
"keys": [
"",
"1"
],
"data": {},
"grid": [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" !!!!!!!! ",
" !!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!! ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Some files were not shown because too many files have changed in this diff Show more