diff --git a/deps/agg/include/agg_conv_clipper.h b/deps/agg/include/agg_conv_clipper.h index 976ceee85..3ac9d951e 100755 --- a/deps/agg/include/agg_conv_clipper.h +++ b/deps/agg/include/agg_conv_clipper.h @@ -1,375 +1,312 @@ -/******************************************************************************* - * * - * Author : Angus Johnson * - * Version : 1.1 * - * Date : 4 April 2011 * - * Website : http://www.angusj.com * - * Copyright : Angus Johnson 2010-2011 * - * * - * License: * - * Use, modification & distribution is subject to Boost Software License Ver 1. * - * http://www.boost.org/LICENSE_1_0.txt * - * * - *******************************************************************************/ - -#ifndef AGG_CONV_CLIPPER_INCLUDED -#define AGG_CONV_CLIPPER_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_array.h" -#include "clipper.hpp" - -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}; - - template class conv_clipper - { - enum status { status_move_to, status_line_to, status_next }; - typedef VSA source_a_type; - typedef VSB source_b_type; - typedef conv_clipper 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_expoly; - int m_scaling_factor; - clipper_op_e m_operation; - pod_bvector m_vertex_accumulator; - ClipperLib::Polygons m_poly_a; - ClipperLib::Polygons m_poly_b; - ClipperLib::ExPolygons m_result; - ClipperLib::Clipper m_clipper; - clipper_PolyFillType m_subjFillType; - clipper_PolyFillType m_clipFillType; - - int Round(double val) - { - if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5); - } - - 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_next), - m_vertex(-1), - m_contour(-1), - m_expoly(-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_next), - m_vertex(-1), - m_contour(-1), - m_expoly(-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)); - } - unsigned type() const { return m_src_a->type(); } - ~conv_clipper() - { - } - - - 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_poly(); - 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); - void reverse(bool reverse); - - template 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 - void conv_clipper::reverse(bool reverse) - { - m_clipper.ReverseSolution(true); - }; - - template - void conv_clipper::start_extracting() - { - m_status = status_next; - m_expoly = -1; - m_contour = -1; - m_vertex = -1; - } - //------------------------------------------------------------------------------ - - template - void conv_clipper::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); - - 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(); - } - //------------------------------------------------------------------------------ - - template - void conv_clipper::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 - void conv_clipper::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 - bool conv_clipper::next_poly() - { - m_expoly++; - - if (m_expoly >= (int) m_result.size()) - return false; - - //std::cout << "next poly: " << m_expoly << " " << m_result.size() << " "<< m_result[m_expoly].outer.size() <<"\n"; - m_contour = -2; - m_vertex = -1; - return true; - } - - template - bool conv_clipper::next_contour() - { - - m_contour++; - if (m_contour < 0){ - // outer ring - //if (!m_result[m_expoly].outer) - // return false; - } else { - // inner rings - if(m_contour >= (int)m_result[m_expoly].holes.size()) - return false; - } - // std::cout << "next contour: " << m_contour << "\n"; - m_vertex =-1; - return true; - } -//------------------------------------------------------------------------------ - - template - bool conv_clipper::next_vertex(double *x, double *y) - { - - m_vertex++; - //std::cout << "next vertex: " << m_vertex << "\n"; - - if (m_contour < 0) - { - if (m_vertex >= (int) m_result[m_expoly].outer.size()) - return false; - *x = (double) m_result[m_expoly].outer[m_vertex].X / m_scaling_factor; - *y = (double) m_result[m_expoly].outer[m_vertex].Y / m_scaling_factor; - } - else - { - if (m_vertex >= (int) m_result[m_expoly].holes[m_contour].size()) - return false; - *x = (double) m_result[m_expoly].holes[m_contour][m_vertex].X - / m_scaling_factor; - *y = (double) m_result[m_expoly].holes[m_contour][m_vertex].Y - / m_scaling_factor; - } - return true; - } - //------------------------------------------------------------------------------ - - template - unsigned conv_clipper::vertex(double *x, double *y) - { - if (m_status == status_next) - { - if (next_poly()) - m_status = status_move_to; - else - return path_cmd_stop; - } - - if (m_status == status_move_to) - { - if (next_contour()) - { - if (next_vertex(x, y)) - { - m_status = status_line_to; - return path_cmd_move_to; - } - } - - if (next_poly()) - { - m_status = status_move_to; - // return two times SEG_CLOSE to indicate - // that all holes of this ExPolygon are finished - 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; - return path_cmd_end_poly | path_flags_close; - } - } - } -//------------------------------------------------------------------------------ - - -} //namespace agg -#endif //AGG_CONV_CLIPPER_INCLUDED +/******************************************************************************* + * * + * Author : Angus Johnson * + * Version : 1.1 * + * Date : 4 April 2011 * + * Website : http://www.angusj.com * + * Copyright : Angus Johnson 2010-2011 * + * * + * License: * + * Use, modification & distribution is subject to Boost Software License Ver 1. * + * http://www.boost.org/LICENSE_1_0.txt * + * * + *******************************************************************************/ + +#ifndef AGG_CONV_CLIPPER_INCLUDED +#define AGG_CONV_CLIPPER_INCLUDED + +#include +#include "agg_basics.h" +#include "agg_array.h" +#include "clipper.hpp" + +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}; + + template class conv_clipper + { + enum status { status_move_to, status_line_to, status_stop }; + typedef VSA source_a_type; + typedef VSB source_b_type; + typedef conv_clipper 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 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) + { + if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5); + } + + 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) + { + 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) + { + 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 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 + void conv_clipper::start_extracting() + { + m_status = status_move_to; + m_contour = -1; + m_vertex = -1; + } + //------------------------------------------------------------------------------ + + template + void conv_clipper::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); + + 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(); + } + //------------------------------------------------------------------------------ + + template + void conv_clipper::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 + void conv_clipper::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 + bool conv_clipper::next_contour() + { + m_contour++; + if(m_contour >= (int)m_result.size()) return false; + m_vertex =-1; + return true; + } +//------------------------------------------------------------------------------ + + template + bool conv_clipper::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 + unsigned conv_clipper::vertex(double *x, double *y) + { + if( m_status == status_move_to ) + { + if( next_contour() ) + { + if( next_vertex( x, y ) ) + { + m_status =status_line_to; + return path_cmd_move_to; + } + else + { + 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; + return path_cmd_end_poly | path_flags_close; + } + } + } +//------------------------------------------------------------------------------ + + +} //namespace agg +#endif //AGG_CONV_CLIPPER_INCLUDED diff --git a/include/mapnik/vertex_converters.hpp b/include/mapnik/vertex_converters.hpp index 88cc9e263..7a172f5b0 100644 --- a/include/mapnik/vertex_converters.hpp +++ b/include/mapnik/vertex_converters.hpp @@ -203,7 +203,7 @@ struct converter_traits ps->line_to(box.maxx(),box.miny()); ps->close_polygon(); geom.attach2(*ps, agg::clipper_non_zero); - geom.reverse(true); + //geom.reverse(true); } };