Annotation of embedaddon/php/ext/gd/libgd/gd_arc_f_buggy.c, revision 1.1.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>