~ubuntu-branches/ubuntu/saucy/mapserver/saucy-security

« back to all changes in this revision

Viewing changes to renderers/agg/include/agg_conv_clipper.h

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2011-12-23 14:02:06 UTC
  • mfrom: (26.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20111223140206-n3h9t2hsa8hyslmu
Tags: 6.0.1-2
Added missed stuff for libmapscript-perl.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
*                                                                              *
 
3
* Author    :  Angus Johnson                                                   *
 
4
* Version   :  1.1                                                             *
 
5
* Date      :  4 April 2011                                                    *
 
6
* Website   :  http://www.angusj.com                                           *
 
7
* Copyright :  Angus Johnson 2010-2011                                         *
 
8
*                                                                              *
 
9
* License:                                                                     *
 
10
* Use, modification & distribution is subject to Boost Software License Ver 1. *
 
11
* http://www.boost.org/LICENSE_1_0.txt                                         *
 
12
*                                                                              *
 
13
*******************************************************************************/
 
14
 
 
15
#ifndef AGG_CONV_CLIPPER_INCLUDED
 
16
#define AGG_CONV_CLIPPER_INCLUDED
 
17
 
 
18
#include <cmath>
 
19
#include "agg_basics.h"
 
20
#include "agg_array.h"
 
21
#include "clipper.hpp"
 
22
 
 
23
namespace mapserver
 
24
{
 
25
  enum clipper_op_e { clipper_or,
 
26
    clipper_and, clipper_xor, clipper_a_minus_b, clipper_b_minus_a };
 
27
  enum clipper_PolyFillType {clipper_even_odd, clipper_non_zero};
 
28
 
 
29
  template<class VSA, class VSB> class conv_clipper
 
30
  {
 
31
    enum status { status_move_to, status_line_to, status_stop };
 
32
    typedef VSA source_a_type;
 
33
    typedef VSB source_b_type;
 
34
    typedef conv_clipper<source_a_type, source_b_type> self_type;
 
35
 
 
36
  private:
 
37
    source_a_type*                                                      m_src_a;
 
38
    source_b_type*                                                      m_src_b;
 
39
    status                                                                      m_status;
 
40
    int                                                                         m_vertex;
 
41
    int                                                                         m_contour;
 
42
        int                                                                             m_scaling_factor;
 
43
    clipper_op_e                                                        m_operation;
 
44
    pod_bvector<clipper::IntPoint, 8>           m_vertex_accumulator;
 
45
    clipper::Polygons                                           m_poly_a;
 
46
    clipper::Polygons                                           m_poly_b;
 
47
    clipper::Polygons                                           m_result;
 
48
    clipper::Clipper                                            m_clipper;
 
49
    clipper_PolyFillType                                        m_subjFillType;
 
50
    clipper_PolyFillType                                        m_clipFillType;
 
51
 
 
52
    int Round(double val)
 
53
    {
 
54
    if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5);
 
55
    }
 
56
 
 
57
  public:
 
58
    conv_clipper(source_a_type &a, source_b_type &b,
 
59
      clipper_op_e op = clipper_or,
 
60
      clipper_PolyFillType subjFillType = clipper_even_odd,
 
61
      clipper_PolyFillType clipFillType = clipper_even_odd,
 
62
          int scaling_factor = 2) :
 
63
        m_src_a(&a),
 
64
        m_src_b(&b),
 
65
        m_status(status_move_to),
 
66
        m_vertex(-1),
 
67
        m_contour(-1),
 
68
        m_operation(op),
 
69
        m_subjFillType(subjFillType),
 
70
        m_clipFillType(clipFillType)
 
71
    {
 
72
                m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
 
73
                m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
 
74
        }
 
75
 
 
76
    ~conv_clipper()
 
77
    {
 
78
    }
 
79
 
 
80
    void attach1(VSA &source, clipper_PolyFillType subjFillType = clipper_even_odd)
 
81
      { m_src_a = &source; m_subjFillType = subjFillType; }
 
82
    void attach2(VSB &source, clipper_PolyFillType clipFillType = clipper_even_odd)
 
83
      { m_src_b = &source; m_clipFillType = clipFillType; }
 
84
 
 
85
    void operation(clipper_op_e v) { m_operation = v; }
 
86
 
 
87
    void rewind(unsigned path_id);
 
88
    unsigned vertex(double* x, double* y);
 
89
  
 
90
    bool next_contour();
 
91
    bool next_vertex(double* x, double* y);
 
92
    void start_extracting();
 
93
    void add_vertex_(double &x, double &y);
 
94
    void end_contour(clipper::Polygons &p);
 
95
 
 
96
        template<class VS> void add(VS &src, clipper::Polygons &p){
 
97
                unsigned cmd;
 
98
                double x; double y; double start_x; double start_y;
 
99
                bool starting_first_line;
 
100
 
 
101
                start_x = 0.0;
 
102
                start_y = 0.0;
 
103
                starting_first_line = true;
 
104
                p.resize(0);
 
105
 
 
106
                cmd = src->vertex( &x , &y );
 
107
                while(!is_stop(cmd))
 
108
                {
 
109
                  if(is_vertex(cmd))
 
110
                  {
 
111
                        if(is_move_to(cmd))
 
112
                        {
 
113
                          if(!starting_first_line ) end_contour(p);
 
114
                          start_x = x;
 
115
                          start_y = y;
 
116
                        }
 
117
                        add_vertex_( x, y );
 
118
                        starting_first_line = false;
 
119
                  }
 
120
                  else if(is_end_poly(cmd))
 
121
                  {
 
122
                        if(!starting_first_line && is_closed(cmd))
 
123
                          add_vertex_( start_x, start_y );
 
124
                  }
 
125
                  cmd = src->vertex( &x, &y );
 
126
                }
 
127
                end_contour(p);
 
128
        }
 
129
  };
 
130
 
 
131
  //------------------------------------------------------------------------
 
132
 
 
133
  template<class VSA, class VSB> 
 
134
  void conv_clipper<VSA, VSB>::start_extracting()
 
135
  {
 
136
    m_status = status_move_to;
 
137
    m_contour = -1;
 
138
    m_vertex = -1;
 
139
  }
 
140
  //------------------------------------------------------------------------------
 
141
 
 
142
  template<class VSA, class VSB>
 
143
  void conv_clipper<VSA, VSB>::rewind(unsigned path_id)
 
144
  {
 
145
    m_src_a->rewind( path_id );
 
146
    m_src_b->rewind( path_id );
 
147
 
 
148
    add( m_src_a , m_poly_a );
 
149
    add( m_src_b , m_poly_b );
 
150
    m_result.resize(0);
 
151
 
 
152
    clipper::PolyFillType pftSubj = (m_subjFillType == clipper_even_odd) ?
 
153
      clipper::pftEvenOdd : clipper::pftNonZero;
 
154
    clipper::PolyFillType pftClip = (m_clipFillType == clipper_even_odd) ?
 
155
      clipper::pftEvenOdd : clipper::pftNonZero;
 
156
 
 
157
    m_clipper.Clear();
 
158
    switch( m_operation ) {
 
159
      case clipper_or:
 
160
        {
 
161
        m_clipper.AddPolygons( m_poly_a , clipper::ptSubject );
 
162
        m_clipper.AddPolygons( m_poly_b , clipper::ptClip );
 
163
        m_clipper.Execute( clipper::ctUnion , m_result , pftSubj, pftClip);
 
164
                break;
 
165
        }
 
166
      case clipper_and:
 
167
        {
 
168
        m_clipper.AddPolygons( m_poly_a , clipper::ptSubject );
 
169
        m_clipper.AddPolygons( m_poly_b , clipper::ptClip );
 
170
        m_clipper.Execute( clipper::ctIntersection , m_result, pftSubj, pftClip );
 
171
                break;
 
172
        }
 
173
      case clipper_xor:
 
174
        {
 
175
        m_clipper.AddPolygons( m_poly_a , clipper::ptSubject );
 
176
        m_clipper.AddPolygons( m_poly_b , clipper::ptClip );
 
177
        m_clipper.Execute( clipper::ctXor , m_result, pftSubj, pftClip );
 
178
                break;
 
179
        }
 
180
      case clipper_a_minus_b:
 
181
        {
 
182
        m_clipper.AddPolygons( m_poly_a , clipper::ptSubject );
 
183
        m_clipper.AddPolygons( m_poly_b , clipper::ptClip );
 
184
        m_clipper.Execute( clipper::ctDifference , m_result, pftSubj, pftClip );
 
185
                break;
 
186
        }
 
187
      case clipper_b_minus_a:
 
188
        {
 
189
        m_clipper.AddPolygons( m_poly_b , clipper::ptSubject );
 
190
        m_clipper.AddPolygons( m_poly_a , clipper::ptClip );
 
191
        m_clipper.Execute( clipper::ctDifference , m_result, pftSubj, pftClip );
 
192
                break;
 
193
        }
 
194
    }
 
195
    start_extracting();
 
196
  }
 
197
  //------------------------------------------------------------------------------
 
198
 
 
199
  template<class VSA, class VSB>
 
200
  void conv_clipper<VSA, VSB>::end_contour( clipper::Polygons &p)
 
201
  {
 
202
  unsigned i, len;
 
203
 
 
204
  if( m_vertex_accumulator.size() < 3 ) return;
 
205
  len = p.size();
 
206
  p.resize(len+1);
 
207
  p[len].resize(m_vertex_accumulator.size());
 
208
  for( i = 0 ; i < m_vertex_accumulator.size() ; i++ )
 
209
    p[len][i] = m_vertex_accumulator[i];
 
210
  m_vertex_accumulator.remove_all();
 
211
  }
 
212
  //------------------------------------------------------------------------------
 
213
 
 
214
  template<class VSA, class VSB> 
 
215
  void conv_clipper<VSA, VSB>::add_vertex_(double &x, double &y)
 
216
  {
 
217
          clipper::IntPoint v;
 
218
 
 
219
          v.X = Round(x * m_scaling_factor);
 
220
          v.Y = Round(y * m_scaling_factor);
 
221
          m_vertex_accumulator.add( v );
 
222
  }
 
223
  //------------------------------------------------------------------------------
 
224
 
 
225
  template<class VSA, class VSB> 
 
226
  bool conv_clipper<VSA, VSB>::next_contour()
 
227
  {   
 
228
        m_contour++;
 
229
        if(m_contour >= (int)m_result.size()) return false;
 
230
        m_vertex =-1;
 
231
        return true;
 
232
}
 
233
//------------------------------------------------------------------------------
 
234
 
 
235
  template<class VSA, class VSB> 
 
236
  bool conv_clipper<VSA, VSB>::next_vertex(double *x, double *y)
 
237
  {
 
238
    m_vertex++;
 
239
    if(m_vertex >= (int)m_result[m_contour].size()) return false;
 
240
    *x = (double)m_result[ m_contour ][ m_vertex ].X / m_scaling_factor;
 
241
    *y = (double)m_result[ m_contour ][ m_vertex ].Y / m_scaling_factor;
 
242
    return true;
 
243
  }
 
244
  //------------------------------------------------------------------------------
 
245
 
 
246
  template<class VSA, class VSB>
 
247
  unsigned conv_clipper<VSA, VSB>::vertex(double *x, double *y)
 
248
{
 
249
  if(  m_status == status_move_to )
 
250
  {
 
251
    if( next_contour() )
 
252
    {
 
253
      if(  next_vertex( x, y ) )
 
254
      {
 
255
        m_status =status_line_to;
 
256
        return path_cmd_move_to;
 
257
      }
 
258
          else
 
259
          {
 
260
        m_status = status_stop;
 
261
        return path_cmd_end_poly | path_flags_close;
 
262
      }
 
263
    }
 
264
        else
 
265
      return path_cmd_stop;
 
266
  }
 
267
  else
 
268
  {
 
269
    if(  next_vertex( x, y ) )
 
270
    {
 
271
      return path_cmd_line_to;
 
272
    }
 
273
        else
 
274
    {
 
275
      m_status = status_move_to;
 
276
      return path_cmd_end_poly | path_flags_close;
 
277
    }
 
278
  }
 
279
}
 
280
//------------------------------------------------------------------------------
 
281
 
 
282
 
 
283
} //namespace agg
 
284
#endif //AGG_CONV_CLIPPER_INCLUDED