1 /******************************************************************************
2  * $Id$
3  *
4  * Project:  MapServer
5  * Purpose:  Rendering utility functions
6  * Author:   Thomas Bonfort and the MapServer team.
7  *
8  ******************************************************************************
9  * Copyright (c) 1996-2011 Regents of the University of Minnesota.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies of this Software or works derived from this Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  *****************************************************************************/
29 
30 #include "mapserver.h"
31 #include "renderers/agg/include/agg_arc.h"
32 #include "renderers/agg/include/agg_basics.h"
33 
34 
35 
msRasterizeArc(double x0,double y0,double radius,double startAngle,double endAngle,int isSlice)36 shapeObj *msRasterizeArc(double x0, double y0, double radius, double startAngle, double endAngle, int isSlice)
37 {
38   static int allocated_size=100;
39   shapeObj *shape = (shapeObj*)calloc(1,sizeof(shapeObj));
40   MS_CHECK_ALLOC(shape, sizeof(shapeObj), NULL);
41   mapserver::arc arc ( x0, y0,radius,radius, startAngle*MS_DEG_TO_RAD, endAngle*MS_DEG_TO_RAD,true );
42   arc.approximation_scale ( 1 );
43   arc.rewind(1);
44   msInitShape(shape);
45 
46   lineObj *line = (lineObj*)calloc(1,sizeof(lineObj));
47   if (!line) {
48     msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" ,
49                __FILE__, __LINE__, (unsigned int)sizeof(lineObj));
50     free(shape);
51     return NULL;
52   }
53   shape->line = line;
54   shape->numlines = 1;
55   line->point = (pointObj*)calloc(allocated_size,sizeof(pointObj));
56   if (!line->point) {
57     msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" ,
58                __FILE__, __LINE__, (unsigned int)(allocated_size*sizeof(pointObj)));
59     free(line);
60     free(shape);
61     return NULL;
62   }
63 
64   line->numpoints = 0;
65 
66   double x,y;
67 
68   //first segment from center to first point of arc
69   if(isSlice) {
70     line->point[0].x = x0;
71     line->point[0].y = y0;
72     line->numpoints = 1;
73   }
74   while(arc.vertex(&x,&y) != mapserver::path_cmd_stop) {
75     if(line->numpoints == allocated_size) {
76       allocated_size *= 2;
77       line->point = (pointObj*)realloc(line->point, allocated_size * sizeof(pointObj));
78       if (!line->point) {
79         msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" ,
80                    __FILE__, __LINE__, (unsigned int)(allocated_size * sizeof(pointObj)));
81         free(line);
82         free(shape);
83         return NULL;
84       }
85     }
86     line->point[line->numpoints].x = x;
87     line->point[line->numpoints].y = y;
88     line->numpoints++;
89   }
90 
91   //make sure the shape is closed
92   if(line->point[line->numpoints-1].x != line->point[0].x ||
93       line->point[line->numpoints-1].y != line->point[0].y) {
94     if(line->numpoints == allocated_size) {
95       allocated_size *= 2;
96       line->point = (pointObj*)msSmallRealloc(line->point, allocated_size * sizeof(pointObj));
97     }
98     line->point[line->numpoints].x = line->point[0].x;
99     line->point[line->numpoints].y = line->point[0].y;
100     line->numpoints++;
101   }
102 
103   return shape;
104 }
105 
106 
107 
108