This source file includes following definitions.
- gdImageFilledEllipse
- gdImageFilledArc
- gdArcClosest
- main
1
2
3
4
5
6 #if 0
7
8 #include "gd.h"
9 #include <math.h>
10
11
12
13 static gdPoint gdArcClosest (int width, int height, int angle);
14
15 void
16 gdImageFilledEllipse (gdImagePtr im, int cx, int cy, int width, int height, int color)
17 {
18 gdImageFilledArc (im, cx, cy, width, height, 0, 360, color, gdChord);
19 }
20
21 void
22 gdImageFilledArc (gdImagePtr im, int cx, int cy, int width, int height, int s, int e, int color, int style)
23 {
24 gdPoint pt[7];
25 gdPoint axis_pt[4];
26
27 int angle;
28
29 int have_s = 0;
30 int have_e = 0;
31
32 int flip_x = 0;
33 int flip_y = 0;
34
35 int conquer = 0;
36
37 int i;
38
39 int a;
40 int b;
41
42 int x;
43 int y;
44
45 long s_sin = 0;
46 long s_cos = 0;
47 long e_sin = 0;
48 long e_cos = 0;
49
50 long w;
51 long h;
52
53 long x2;
54 long y2;
55 long lx2;
56 long ly2;
57
58 long ws;
59 long hs;
60
61 long whs;
62
63 long g;
64 long lg;
65
66 width = (width & 1) ? (width + 1) : (width);
67 height = (height & 1) ? (height + 1) : (height);
68
69 a = width / 2;
70 b = height / 2;
71
72 axis_pt[0].x = a;
73 axis_pt[0].y = 0;
74 axis_pt[1].x = 0;
75 axis_pt[1].y = b;
76 axis_pt[2].x = -a;
77 axis_pt[2].y = 0;
78 axis_pt[3].x = 0;
79 axis_pt[3].y = -b;
80
81 if (s == e)
82 return;
83
84 if ((e - s) >= 360)
85 {
86 s = 0;
87 e = 0;
88 }
89
90 while (s < 0)
91 s += 360;
92 while (s >= 360)
93 s -= 360;
94 while (e < 0)
95 e += 360;
96 while (e >= 360)
97 e -= 360;
98
99 if (e <= s)
100 e += 360;
101
102
103
104
105
106 for (i = 0; i < 4; i++)
107 {
108 if ((s < (i + 1) * 90) && (e > (i + 1) * 90))
109 {
110 gdImageFilledArc (im, cx, cy, width, height, s, (i + 1) * 90, color, gdChord);
111 pt[0] = gdArcClosest (width, height, s);
112 pt[0].x += cx;
113 pt[0].y += cy;
114 pt[1].x = cx + axis_pt[(i + 1) & 3].x;
115 pt[1].y = cy + axis_pt[(i + 1) & 3].y;
116 if (e <= (i + 2) * 90)
117 {
118 gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, e, color, gdChord);
119 pt[2] = gdArcClosest (width, height, e);
120 pt[2].x += cx;
121 pt[2].y += cy;
122 if (style == gdChord)
123 {
124 gdImageFilledPolygon (im, pt, 3, color);
125 gdImagePolygon (im, pt, 3, color);
126 }
127 else if (style == gdPie)
128 {
129 pt[3].x = cx;
130 pt[3].y = cy;
131 gdImageFilledPolygon (im, pt, 4, color);
132 gdImagePolygon (im, pt, 4, color);
133 }
134 }
135 else
136 {
137 gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, (i + 2) * 90, color, gdChord);
138 pt[2].x = cx + axis_pt[(i + 2) & 3].x;
139 pt[2].y = cy + axis_pt[(i + 2) & 3].y;
140 if (e <= (i + 3) * 90)
141 {
142 gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, e, color, gdChord);
143 pt[3] = gdArcClosest (width, height, e);
144 pt[3].x += cx;
145 pt[3].y += cy;
146 if (style == gdChord)
147 {
148 gdImageFilledPolygon (im, pt, 4, color);
149 gdImagePolygon (im, pt, 4, color);
150 }
151 else if (style == gdPie)
152 {
153 pt[4].x = cx;
154 pt[4].y = cy;
155 gdImageFilledPolygon (im, pt, 5, color);
156 gdImagePolygon (im, pt, 5, color);
157 }
158 }
159 else
160 {
161 gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, (i + 3) * 90, color, gdChord);
162 pt[3].x = cx + axis_pt[(i + 3) & 3].x;
163 pt[3].y = cy + axis_pt[(i + 3) & 3].y;
164 if (e <= (i + 4) * 90)
165 {
166 gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, e, color, gdChord);
167 pt[4] = gdArcClosest (width, height, e);
168 pt[4].x += cx;
169 pt[4].y += cy;
170 if (style == gdChord)
171 {
172 gdImageFilledPolygon (im, pt, 5, color);
173 gdImagePolygon (im, pt, 5, color);
174 }
175 else if (style == gdPie)
176 {
177 pt[5].x = cx;
178 pt[5].y = cy;
179 gdImageFilledPolygon (im, pt, 6, color);
180 gdImagePolygon (im, pt, 6, color);
181 }
182 }
183 else
184 {
185 gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, (i + 4) * 90, color, gdChord);
186 pt[4].x = cx + axis_pt[(i + 4) & 3].x;
187 pt[4].y = cy + axis_pt[(i + 4) & 3].y;
188
189 gdImageFilledArc (im, cx, cy, width, height, (i + 4) * 90, e, color, gdChord);
190 pt[5] = gdArcClosest (width, height, e);
191 pt[5].x += cx;
192 pt[5].y += cy;
193 if (style == gdChord)
194 {
195 gdImageFilledPolygon (im, pt, 6, color);
196 gdImagePolygon (im, pt, 6, color);
197 }
198 else if (style == gdPie)
199 {
200 pt[6].x = cx;
201 pt[6].y = cy;
202 gdImageFilledPolygon (im, pt, 7, color);
203 gdImagePolygon (im, pt, 7, color);
204 }
205 }
206 }
207 }
208 return;
209 }
210 }
211
212
213
214
215
216 if ((s >= 90) && (e <= 180))
217 {
218 angle = s;
219 s = 180 - e;
220 e = 180 - angle;
221 flip_x = 1;
222 }
223 if ((s >= 180) && (e <= 270))
224 {
225 s = s - 180;
226 e = e - 180;
227 flip_x = 1;
228 flip_y = 1;
229 }
230 if ((s >= 270) && (e <= 360))
231 {
232 angle = s;
233 s = 360 - e;
234 e = 360 - angle;
235 flip_y = 1;
236 }
237
238 if (s == 0)
239 {
240 s_sin = 0;
241 s_cos = (long) ((double) 32768);
242 }
243 else
244 {
245 s_sin = (long) ((double) 32768 * sin ((double) s * M_PI / (double) 180));
246 s_cos = (long) ((double) 32768 * cos ((double) s * M_PI / (double) 180));
247 }
248 if (e == 0)
249 {
250 e_sin = (long) ((double) 32768);
251 e_cos = 0;
252 }
253 else
254 {
255 e_sin = (long) ((double) 32768 * sin ((double) e * M_PI / (double) 180));
256 e_cos = (long) ((double) 32768 * cos ((double) e * M_PI / (double) 180));
257 }
258
259 w = (long) width;
260 h = (long) height;
261
262 ws = w * w;
263 hs = h * h;
264
265 whs = 1;
266 while ((ws > 32768) || (hs > 32768))
267 {
268 ws = (ws + 1) / 2;
269 hs = (hs + 1) / 2;
270 whs *= 2;
271 }
272 while ((ws * hs) > (0x04000000L / whs))
273 {
274 ws = (ws + 1) / 2;
275 hs = (hs + 1) / 2;
276 whs *= 2;
277 }
278 whs *= ws * hs;
279
280 pt[0].x = w / 2;
281 pt[0].y = 0;
282
283 pt[2].x = 0;
284 pt[2].y = h / 2;
285
286 have_s = 0;
287 have_e = 0;
288
289 if (s == 0)
290 have_s = 1;
291 if (e == 90)
292 have_e = 1;
293
294 x2 = w;
295 y2 = 0;
296
297 g = x2 - 1;
298 g = g * g * hs + 4 * ws - whs;
299
300 while ((x2 * hs) > (y2 * ws))
301 {
302 y2 += 2;
303 g += ws * 4 * (y2 + 1);
304
305 if (g > 0)
306 {
307 x2 -= 2;
308 g -= hs * 4 * x2;
309 }
310
311 if ((have_s == 0) && ((s_sin * x2) <= (y2 * s_cos)))
312 {
313 pt[0].x = (int) (x2 / 2);
314 pt[0].y = (int) (y2 / 2);
315 have_s = 1;
316 }
317
318 if ((have_e == 0) && ((e_sin * x2) <= (y2 * e_cos)))
319 {
320 pt[2].x = (int) (x2 / 2);
321 pt[2].y = (int) (y2 / 2);
322 have_e = 1;
323 }
324 }
325 pt[1].x = (int) (x2 / 2);
326 pt[1].y = (int) (y2 / 2);
327
328 x2 = 0;
329 y2 = h;
330
331 g = y2 - 1;
332 g = g * g * ws + 4 * hs - whs;
333
334 while ((x2 * hs) < (y2 * ws))
335 {
336 x2 += 2;
337 g += hs * 4 * (x2 + 1);
338
339 if (g > 0)
340 {
341 y2 -= 2;
342 g -= ws * 4 * y2;
343 }
344
345 if ((have_s == 0) && ((s_sin * x2) >= (y2 * s_cos)))
346 {
347 pt[0].x = (int) (x2 / 2);
348 pt[0].y = (int) (y2 / 2);
349 have_s = 1;
350 }
351
352 if ((have_e == 0) && ((e_sin * x2) >= (y2 * e_cos)))
353 {
354 pt[2].x = (int) (x2 / 2);
355 pt[2].y = (int) (y2 / 2);
356 have_e = 1;
357 }
358 }
359
360 if ((have_s == 0) || (have_e == 0))
361 return;
362
363 if (style == gdPie)
364 {
365 pt[3] = pt[0];
366 pt[4] = pt[1];
367 pt[5] = pt[2];
368
369 pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x);
370 pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y);
371 pt[1].x = cx;
372 pt[1].y = cy;
373 pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x);
374 pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y);
375 gdImageFilledPolygon (im, pt, 3, color);
376 gdImagePolygon (im, pt, 3, color);
377
378 pt[0] = pt[3];
379 pt[1] = pt[4];
380 pt[2] = pt[5];
381 }
382
383 if (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws)))
384 {
385
386
387 pt[3] = pt[0];
388 pt[4] = pt[1];
389 pt[5] = pt[2];
390
391 pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x);
392 pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y);
393 pt[1].x = cx + (flip_x ? (-pt[1].x) : pt[1].x);
394 pt[1].y = cy + (flip_y ? (-pt[1].y) : pt[1].y);
395 pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x);
396 pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y);
397 gdImageFilledPolygon (im, pt, 3, color);
398 gdImagePolygon (im, pt, 3, color);
399
400 pt[0] = pt[3];
401 pt[2] = pt[4];
402
403 conquer = 1;
404 }
405
406 if (conquer || (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) > (e_sin * ws))))
407 {
408
409
410
411 x2 = w;
412 y2 = 0;
413
414 g = x2 - 1;
415 g = g * g * hs + 4 * ws - whs;
416
417 while ((x2 * hs) > (y2 * ws))
418 {
419 if ((s_sin * x2) <= (y2 * s_cos))
420 break;
421
422 y2 += 2;
423 g += ws * 4 * (y2 + 1);
424
425 if (g > 0)
426 {
427 x2 -= 2;
428 g -= hs * 4 * x2;
429 }
430 }
431
432 lx2 = x2;
433 ly2 = y2;
434
435 lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x);
436 lg = (lx2 - 1) * (pt[0].y - pt[2].y) - (ly2 + 2) * (pt[0].x - pt[2].x) - lg;
437
438 while (y2 < (2 * pt[2].y))
439 {
440 y2 += 2;
441 g += ws * 4 * (y2 + 1);
442
443 if (g > 0)
444 {
445 x2 -= 2;
446 g -= hs * 4 * x2;
447 }
448
449 ly2 += 2;
450 lg -= 2 * (pt[0].x - pt[2].x);
451
452 if (lg < 0)
453 {
454 lx2 -= 2;
455 lg -= 2 * (pt[0].y - pt[2].y);
456 }
457
458 y = (int) (y2 / 2);
459 for (x = (int) (lx2 / 2); x <= (int) (x2 / 2); x++)
460 {
461 gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)),
462 ((flip_y) ? (cy - y) : (cy + y)), color);
463 }
464 }
465 }
466 if (conquer)
467 {
468 pt[0] = pt[4];
469 pt[2] = pt[5];
470 }
471 if (conquer || (((s_cos * hs) < (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws))))
472 {
473
474
475
476 x2 = 0;
477 y2 = h;
478
479 g = y2 - 1;
480 g = g * g * ws + 4 * hs - whs;
481
482 while ((x2 * hs) < (y2 * ws))
483 {
484 x2 += 2;
485 g += hs * 4 * (x2 + 1);
486
487 if (g > 0)
488 {
489 y2 -= 2;
490 g -= ws * 4 * y2;
491 }
492
493 if ((e_sin * x2) >= (y2 * e_cos))
494 break;
495 }
496
497 lx2 = x2;
498 ly2 = y2;
499
500 lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x);
501 lg = (lx2 + 2) * (pt[0].y - pt[2].y) - (ly2 - 1) * (pt[0].x - pt[2].x) - lg;
502
503 while (x2 < (2 * pt[0].x))
504 {
505 x2 += 2;
506 g += hs * 4 * (x2 + 1);
507
508 if (g > 0)
509 {
510 y2 -= 2;
511 g -= ws * 4 * y2;
512 }
513
514 lx2 += 2;
515 lg += 2 * (pt[0].y - pt[2].y);
516
517 if (lg < 0)
518 {
519 ly2 -= 2;
520 lg += 2 * (pt[0].x - pt[2].x);
521 }
522
523 x = (int) (x2 / 2);
524 for (y = (int) (ly2 / 2); y <= (int) (y2 / 2); y++)
525 {
526 gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)),
527 ((flip_y) ? (cy - y) : (cy + y)), color);
528 }
529 }
530 }
531 }
532
533 static gdPoint
534 gdArcClosest (int width, int height, int angle)
535 {
536 gdPoint pt;
537
538 int flip_x = 0;
539 int flip_y = 0;
540
541 long a_sin = 0;
542 long a_cos = 0;
543
544 long w;
545 long h;
546
547 long x2;
548 long y2;
549
550 long ws;
551 long hs;
552
553 long whs;
554
555 long g;
556
557 w = (long) ((width & 1) ? (width + 1) : (width));
558 h = (long) ((height & 1) ? (height + 1) : (height));
559
560 while (angle < 0)
561 angle += 360;
562 while (angle >= 360)
563 angle -= 360;
564
565 if (angle == 0)
566 {
567 pt.x = w / 2;
568 pt.y = 0;
569 return (pt);
570 }
571 if (angle == 90)
572 {
573 pt.x = 0;
574 pt.y = h / 2;
575 return (pt);
576 }
577 if (angle == 180)
578 {
579 pt.x = -w / 2;
580 pt.y = 0;
581 return (pt);
582 }
583 if (angle == 270)
584 {
585 pt.x = 0;
586 pt.y = -h / 2;
587 return (pt);
588 }
589
590 pt.x = 0;
591 pt.y = 0;
592
593 if ((angle > 90) && (angle < 180))
594 {
595 angle = 180 - angle;
596 flip_x = 1;
597 }
598 if ((angle > 180) && (angle < 270))
599 {
600 angle = angle - 180;
601 flip_x = 1;
602 flip_y = 1;
603 }
604 if ((angle > 270) && (angle < 360))
605 {
606 angle = 360 - angle;
607 flip_y = 1;
608 }
609
610 a_sin = (long) ((double) 32768 * sin ((double) angle * M_PI / (double) 180));
611 a_cos = (long) ((double) 32768 * cos ((double) angle * M_PI / (double) 180));
612
613 ws = w * w;
614 hs = h * h;
615
616 whs = 1;
617 while ((ws > 32768) || (hs > 32768))
618 {
619 ws = (ws + 1) / 2;
620 hs = (hs + 1) / 2;
621 whs *= 2;
622 }
623 while ((ws * hs) > (0x04000000L / whs))
624 {
625 ws = (ws + 1) / 2;
626 hs = (hs + 1) / 2;
627 whs *= 2;
628 }
629 whs *= ws * hs;
630
631 if ((a_cos * hs) > (a_sin * ws))
632 {
633 x2 = w;
634 y2 = 0;
635
636 g = x2 - 1;
637 g = g * g * hs + 4 * ws - whs;
638
639 while ((x2 * hs) > (y2 * ws))
640 {
641 y2 += 2;
642 g += ws * 4 * (y2 + 1);
643
644 if (g > 0)
645 {
646 x2 -= 2;
647 g -= hs * 4 * x2;
648 }
649
650 if ((a_sin * x2) <= (y2 * a_cos))
651 {
652 pt.x = (int) (x2 / 2);
653 pt.y = (int) (y2 / 2);
654 break;
655 }
656 }
657 }
658 else
659 {
660 x2 = 0;
661 y2 = h;
662
663 g = y2 - 1;
664 g = g * g * ws + 4 * hs - whs;
665
666 while ((x2 * hs) < (y2 * ws))
667 {
668 x2 += 2;
669 g += hs * 4 * (x2 + 1);
670
671 if (g > 0)
672 {
673 y2 -= 2;
674 g -= ws * 4 * y2;
675 }
676
677 if ((a_sin * x2) >= (y2 * a_cos))
678 {
679 pt.x = (int) (x2 / 2);
680 pt.y = (int) (y2 / 2);
681 break;
682 }
683 }
684 }
685
686 if (flip_x)
687 pt.x = -pt.x;
688 if (flip_y)
689 pt.y = -pt.y;
690
691 return (pt);
692 }
693
694 #include "gd.h"
695 #include <string.h>
696 #include <math.h>
697
698 #define WIDTH 500
699 #define HEIGHT 300
700
701 int
702 main (int argc, char *argv[])
703 {
704 gdImagePtr im = gdImageCreate (WIDTH, HEIGHT);
705 int white = gdImageColorResolve (im, 0xFF, 0xFF, 0xFF), black = gdImageColorResolve (im, 0, 0, 0),
706 red = gdImageColorResolve (im, 0xFF, 0xA0, 0xA0);
707 FILE *out;
708
709
710 gdImageFilledArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, red, gdPie);
711 gdImageArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, black);
712
713
714 gdImageFilledArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, red, gdPie);
715 gdImageArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, black);
716
717
718
719 gdImageLine (im, 0, HEIGHT / 4, WIDTH, HEIGHT / 4, black);
720 gdImageLine (im, WIDTH / 5, 0, WIDTH / 5, HEIGHT, black);
721 gdImageLine (im, WIDTH / 2, 0, WIDTH / 2, HEIGHT, black);
722 gdImageLine (im, WIDTH / 2, HEIGHT / 4, WIDTH / 2 + 300, HEIGHT / 4 + 300, black);
723 gdImageLine (im, WIDTH / 5, HEIGHT / 4, WIDTH / 5 + 300, HEIGHT / 4 + 300, black);
724
725
726 out = fopen ("test/arctest.png", "wb");
727 if (!out)
728 {
729 php_gd_error("Can't create test/arctest.png");
730 exit (1);
731 }
732 gdImagePng (im, out);
733 fclose (out);
734 php_gd_error("Test image written to test/arctest.png");
735
736 gdImageDestroy (im);
737
738 return 0;
739 }
740
741 #endif