** Polygon fill. Based on "Concave Polygon Scan Conversion" by Paul ** Heckbert from "Graphics Gems", Academic Press, 1990. ** */
| 138 | ** |
| 139 | */ |
| 140 | static void imageFilledPolygon(gdImagePtr im, shapeObj *p, int c) |
| 141 | { |
| 142 | typedef struct { /* a polygon edge */ |
| 143 | double x; /* x coordinate of edge's intersection with current scanline */ |
| 144 | double dx; /* change in x with respect to y */ |
| 145 | int i; /* point index */ |
| 146 | int l; /* line number */ |
| 147 | int s; /* scanline */ |
| 148 | } pEdge; |
| 149 | |
| 150 | pointObj *point1, *point2; |
| 151 | |
| 152 | int k, l, i, j, xl, xr, ymin, ymax, y, n,nvert, nact, m; |
| 153 | int wrong_order; |
| 154 | |
| 155 | pEdge *edge, *temp; |
| 156 | pEdge **active; |
| 157 | int *yhist, *edgeindex; |
| 158 | |
| 159 | if(p->numlines == 0) return; |
| 160 | n=0; |
| 161 | |
| 162 | for(i=0; i<p->numlines; i++) { |
| 163 | n += p->line[i].numpoints; |
| 164 | } |
| 165 | |
| 166 | if(n == 0) return; |
| 167 | |
| 168 | edge = (pEdge *) msSmallCalloc(n,sizeof(pEdge)); /* All edges in the polygon */ |
| 169 | edgeindex = (int *) msSmallCalloc(n,sizeof(int)); /* Index to edges sorted by scanline */ |
| 170 | active = (pEdge **) msSmallCalloc(n,sizeof(pEdge*)); /* Pointers to active edges for current scanline */ |
| 171 | |
| 172 | nvert=0; |
| 173 | |
| 174 | ymin= (int) ceil(p->line[0].point[0].y-0.5); |
| 175 | ymax= (int) floor(p->line[0].point[0].y-0.5); |
| 176 | |
| 177 | /* populate the edge table */ |
| 178 | for(l=0; l<p->numlines; l++) { |
| 179 | for(i=0; i < p->line[l].numpoints; i++) { |
| 180 | j = i < p->line[l].numpoints -1 ? i+1 : 0; |
| 181 | if (p->line[l].point[i].y < p->line[l].point[j].y ) { |
| 182 | point1 = &(p->line[l].point[i]); |
| 183 | point2 = &(p->line[l].point[j]); |
| 184 | } else { |
| 185 | point2 = &(p->line[l].point[i]); |
| 186 | point1 = &(p->line[l].point[j]); |
| 187 | } |
| 188 | |
| 189 | edge[nvert].dx = point2->y == point1->y ? 0 : (point2->x - point1->x) / (point2->y - point1->y); |
| 190 | edge[nvert].s = MS_NINT( p->line[l].point[i].y ); /* ceil( p->line[l].point[i].y - 0.5 ); */ |
| 191 | edge[nvert].x = point1->x; |
| 192 | edge[nvert].i = nvert; |
| 193 | edge[nvert].l = l; |
| 194 | |
| 195 | ymin = MS_MIN(ymin,edge[nvert].s); |
| 196 | ymax = MS_MAX(ymax,edge[nvert].s); |
| 197 |
no test coverage detected