Annotation of embedaddon/php/ext/gd/libgd/gd_arc_f_buggy.c, revision 1.1

1.1     ! misho       1: /* This is potentially great stuff, but fails against the test
        !             2:    program at the end. This would probably be much more
        !             3:    efficent than the implementation currently in gd.c if the
        !             4:    errors in the output were corrected. TBB */
        !             5: 
        !             6: #if 0
        !             7: 
        !             8: #include "gd.h"
        !             9: #include <math.h>
        !            10: 
        !            11: /* Courtesy of F J Franklin. */
        !            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;                      /* a * 2 */
        !            51:   long h;                      /* b * 2 */
        !            52: 
        !            53:   long x2;                     /* x * 2 */
        !            54:   long y2;                     /* y * 2 */
        !            55:   long lx2;                    /* x * 2 (line) */
        !            56:   long ly2;                    /* y * 2 (line) */
        !            57: 
        !            58:   long ws;                     /* (a * 2)^2 */
        !            59:   long hs;                     /* (b * 2)^2 */
        !            60: 
        !            61:   long whs;                    /* (a * 2)^2 * (b * 2)^2 */
        !            62: 
        !            63:   long g;                      /* decision variable */
        !            64:   long lg;                     /* decision variable (line) */
        !            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:   /* I'm assuming a chord-rule at the moment. Need to add origin to get a
        !           103:    * pie-rule, but will need to set chord-rule before recursion...
        !           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:   /* At this point we have only arcs that lies within a quadrant -
        !           213:    * map this to first quadrant...
        !           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;       /* Unfortunate limitations on integers makes */
        !           269:       hs = (hs + 1) / 2;       /* drawing large  ellipses problematic...    */
        !           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;                      /* Starting point is exactly on ellipse */
        !           296: 
        !           297:   g = x2 - 1;
        !           298:   g = g * g * hs + 4 * ws - whs;
        !           299: 
        !           300:   while ((x2 * hs) > (y2 * ws))        /* Keep |tangent| > 1 */
        !           301:     {
        !           302:       y2 += 2;
        !           303:       g += ws * 4 * (y2 + 1);
        !           304: 
        !           305:       if (g > 0)               /* Need to drop */
        !           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;                      /* Starting point is exactly on ellipse */
        !           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)               /* Need to drop */
        !           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;                    /* Bizarre case */
        !           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:     {                          /* the points are on different parts of the curve...
        !           385:                                 * this is too tricky to try to handle, so divide and conquer:
        !           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:     {                          /* This is the best bit... */
        !           408:       /* steep line + ellipse */
        !           409:       /* go up & left from pt[0] to pt[2] */
        !           410: 
        !           411:       x2 = w;
        !           412:       y2 = 0;                  /* Starting point is exactly on ellipse */
        !           413: 
        !           414:       g = x2 - 1;
        !           415:       g = g * g * hs + 4 * ws - whs;
        !           416: 
        !           417:       while ((x2 * hs) > (y2 * ws))    /* Keep |tangent| > 1 */
        !           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)            /* Need to drop */
        !           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)            /* Need to drop */
        !           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)           /* Need to drop */
        !           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:     {                          /* This is the best bit... */
        !           473:       /* gradual line + ellipse */
        !           474:       /* go down & right from pt[2] to pt[0] */
        !           475: 
        !           476:       x2 = 0;
        !           477:       y2 = h;                  /* Starting point is exactly on ellipse */
        !           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)            /* Need to drop */
        !           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)            /* Need to drop */
        !           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)           /* Need to drop */
        !           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;                      /* a * 2 */
        !           545:   long h;                      /* b * 2 */
        !           546: 
        !           547:   long x2;                     /* x * 2 */
        !           548:   long y2;                     /* y * 2 */
        !           549: 
        !           550:   long ws;                     /* (a * 2)^2 */
        !           551:   long hs;                     /* (b * 2)^2 */
        !           552: 
        !           553:   long whs;                    /* (a * 2)^2 * (b * 2)^2 */
        !           554: 
        !           555:   long g;                      /* decision variable */
        !           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;       /* Unfortunate limitations on integers makes */
        !           620:       hs = (hs + 1) / 2;       /* drawing large  ellipses problematic...    */
        !           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;                  /* Starting point is exactly on ellipse */
        !           635: 
        !           636:       g = x2 - 1;
        !           637:       g = g * g * hs + 4 * ws - whs;
        !           638: 
        !           639:       while ((x2 * hs) > (y2 * ws))    /* Keep |tangent| > 1 */
        !           640:        {
        !           641:          y2 += 2;
        !           642:          g += ws * 4 * (y2 + 1);
        !           643: 
        !           644:          if (g > 0)            /* Need to drop */
        !           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;                  /* Starting point is exactly on ellipse */
        !           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)            /* Need to drop */
        !           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:   /* filled arc - circle */
        !           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:   /* filled arc - ellipse */
        !           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:   /* reference lines */
        !           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:   /* TBB: Write img to test/arctest.png */
        !           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:   /* Destroy it */
        !           736:   gdImageDestroy (im);
        !           737: 
        !           738:   return 0;
        !           739: }
        !           740: 
        !           741: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>