Back to index

php5  5.3.10
gd_arc_f_buggy.c
Go to the documentation of this file.
00001 /* This is potentially great stuff, but fails against the test
00002    program at the end. This would probably be much more
00003    efficent than the implementation currently in gd.c if the
00004    errors in the output were corrected. TBB */
00005 
00006 #if 0
00007 
00008 #include "gd.h"
00009 #include <math.h>
00010 
00011 /* Courtesy of F J Franklin. */
00012 
00013 static gdPoint gdArcClosest (int width, int height, int angle);
00014 
00015 void
00016 gdImageFilledEllipse (gdImagePtr im, int cx, int cy, int width, int height, int color)
00017 {
00018   gdImageFilledArc (im, cx, cy, width, height, 0, 360, color, gdChord);
00019 }
00020 
00021 void
00022 gdImageFilledArc (gdImagePtr im, int cx, int cy, int width, int height, int s, int e, int color, int style)
00023 {
00024   gdPoint pt[7];
00025   gdPoint axis_pt[4];
00026 
00027   int angle;
00028 
00029   int have_s = 0;
00030   int have_e = 0;
00031 
00032   int flip_x = 0;
00033   int flip_y = 0;
00034 
00035   int conquer = 0;
00036 
00037   int i;
00038 
00039   int a;
00040   int b;
00041 
00042   int x;
00043   int y;
00044 
00045   long s_sin = 0;
00046   long s_cos = 0;
00047   long e_sin = 0;
00048   long e_cos = 0;
00049 
00050   long w;                   /* a * 2 */
00051   long h;                   /* b * 2 */
00052 
00053   long x2;                  /* x * 2 */
00054   long y2;                  /* y * 2 */
00055   long lx2;                 /* x * 2 (line) */
00056   long ly2;                 /* y * 2 (line) */
00057 
00058   long ws;                  /* (a * 2)^2 */
00059   long hs;                  /* (b * 2)^2 */
00060 
00061   long whs;                 /* (a * 2)^2 * (b * 2)^2 */
00062 
00063   long g;                   /* decision variable */
00064   long lg;                  /* decision variable (line) */
00065 
00066   width = (width & 1) ? (width + 1) : (width);
00067   height = (height & 1) ? (height + 1) : (height);
00068 
00069   a = width / 2;
00070   b = height / 2;
00071 
00072   axis_pt[0].x = a;
00073   axis_pt[0].y = 0;
00074   axis_pt[1].x = 0;
00075   axis_pt[1].y = b;
00076   axis_pt[2].x = -a;
00077   axis_pt[2].y = 0;
00078   axis_pt[3].x = 0;
00079   axis_pt[3].y = -b;
00080 
00081   if (s == e)
00082     return;
00083 
00084   if ((e - s) >= 360)
00085     {
00086       s = 0;
00087       e = 0;
00088     }
00089 
00090   while (s < 0)
00091     s += 360;
00092   while (s >= 360)
00093     s -= 360;
00094   while (e < 0)
00095     e += 360;
00096   while (e >= 360)
00097     e -= 360;
00098 
00099   if (e <= s)
00100     e += 360;
00101 
00102   /* I'm assuming a chord-rule at the moment. Need to add origin to get a
00103    * pie-rule, but will need to set chord-rule before recursion...
00104    */
00105 
00106   for (i = 0; i < 4; i++)
00107     {
00108       if ((s < (i + 1) * 90) && (e > (i + 1) * 90))
00109        {
00110          gdImageFilledArc (im, cx, cy, width, height, s, (i + 1) * 90, color, gdChord);
00111          pt[0] = gdArcClosest (width, height, s);
00112          pt[0].x += cx;
00113          pt[0].y += cy;
00114          pt[1].x = cx + axis_pt[(i + 1) & 3].x;
00115          pt[1].y = cy + axis_pt[(i + 1) & 3].y;
00116          if (e <= (i + 2) * 90)
00117            {
00118              gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, e, color, gdChord);
00119              pt[2] = gdArcClosest (width, height, e);
00120              pt[2].x += cx;
00121              pt[2].y += cy;
00122              if (style == gdChord)
00123               {
00124                 gdImageFilledPolygon (im, pt, 3, color);
00125                 gdImagePolygon (im, pt, 3, color);
00126               }
00127              else if (style == gdPie)
00128               {
00129                 pt[3].x = cx;
00130                 pt[3].y = cy;
00131                 gdImageFilledPolygon (im, pt, 4, color);
00132                 gdImagePolygon (im, pt, 4, color);
00133               }
00134            }
00135          else
00136            {
00137              gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, (i + 2) * 90, color, gdChord);
00138              pt[2].x = cx + axis_pt[(i + 2) & 3].x;
00139              pt[2].y = cy + axis_pt[(i + 2) & 3].y;
00140              if (e <= (i + 3) * 90)
00141               {
00142                 gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, e, color, gdChord);
00143                 pt[3] = gdArcClosest (width, height, e);
00144                 pt[3].x += cx;
00145                 pt[3].y += cy;
00146                 if (style == gdChord)
00147                   {
00148                     gdImageFilledPolygon (im, pt, 4, color);
00149                     gdImagePolygon (im, pt, 4, color);
00150                   }
00151                 else if (style == gdPie)
00152                   {
00153                     pt[4].x = cx;
00154                     pt[4].y = cy;
00155                     gdImageFilledPolygon (im, pt, 5, color);
00156                     gdImagePolygon (im, pt, 5, color);
00157                   }
00158               }
00159              else
00160               {
00161                 gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, (i + 3) * 90, color, gdChord);
00162                 pt[3].x = cx + axis_pt[(i + 3) & 3].x;
00163                 pt[3].y = cy + axis_pt[(i + 3) & 3].y;
00164                 if (e <= (i + 4) * 90)
00165                   {
00166                     gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, e, color, gdChord);
00167                     pt[4] = gdArcClosest (width, height, e);
00168                     pt[4].x += cx;
00169                     pt[4].y += cy;
00170                     if (style == gdChord)
00171                      {
00172                        gdImageFilledPolygon (im, pt, 5, color);
00173                        gdImagePolygon (im, pt, 5, color);
00174                      }
00175                     else if (style == gdPie)
00176                      {
00177                        pt[5].x = cx;
00178                        pt[5].y = cy;
00179                        gdImageFilledPolygon (im, pt, 6, color);
00180                        gdImagePolygon (im, pt, 6, color);
00181                      }
00182                   }
00183                 else
00184                   {
00185                     gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, (i + 4) * 90, color, gdChord);
00186                     pt[4].x = cx + axis_pt[(i + 4) & 3].x;
00187                     pt[4].y = cy + axis_pt[(i + 4) & 3].y;
00188 
00189                     gdImageFilledArc (im, cx, cy, width, height, (i + 4) * 90, e, color, gdChord);
00190                     pt[5] = gdArcClosest (width, height, e);
00191                     pt[5].x += cx;
00192                     pt[5].y += cy;
00193                     if (style == gdChord)
00194                      {
00195                        gdImageFilledPolygon (im, pt, 6, color);
00196                        gdImagePolygon (im, pt, 6, color);
00197                      }
00198                     else if (style == gdPie)
00199                      {
00200                        pt[6].x = cx;
00201                        pt[6].y = cy;
00202                        gdImageFilledPolygon (im, pt, 7, color);
00203                        gdImagePolygon (im, pt, 7, color);
00204                      }
00205                   }
00206               }
00207            }
00208          return;
00209        }
00210     }
00211 
00212   /* At this point we have only arcs that lies within a quadrant -
00213    * map this to first quadrant...
00214    */
00215 
00216   if ((s >= 90) && (e <= 180))
00217     {
00218       angle = s;
00219       s = 180 - e;
00220       e = 180 - angle;
00221       flip_x = 1;
00222     }
00223   if ((s >= 180) && (e <= 270))
00224     {
00225       s = s - 180;
00226       e = e - 180;
00227       flip_x = 1;
00228       flip_y = 1;
00229     }
00230   if ((s >= 270) && (e <= 360))
00231     {
00232       angle = s;
00233       s = 360 - e;
00234       e = 360 - angle;
00235       flip_y = 1;
00236     }
00237 
00238   if (s == 0)
00239     {
00240       s_sin = 0;
00241       s_cos = (long) ((double) 32768);
00242     }
00243   else
00244     {
00245       s_sin = (long) ((double) 32768 * sin ((double) s * M_PI / (double) 180));
00246       s_cos = (long) ((double) 32768 * cos ((double) s * M_PI / (double) 180));
00247     }
00248   if (e == 0)
00249     {
00250       e_sin = (long) ((double) 32768);
00251       e_cos = 0;
00252     }
00253   else
00254     {
00255       e_sin = (long) ((double) 32768 * sin ((double) e * M_PI / (double) 180));
00256       e_cos = (long) ((double) 32768 * cos ((double) e * M_PI / (double) 180));
00257     }
00258 
00259   w = (long) width;
00260   h = (long) height;
00261 
00262   ws = w * w;
00263   hs = h * h;
00264 
00265   whs = 1;
00266   while ((ws > 32768) || (hs > 32768))
00267     {
00268       ws = (ws + 1) / 2;    /* Unfortunate limitations on integers makes */
00269       hs = (hs + 1) / 2;    /* drawing large  ellipses problematic...    */
00270       whs *= 2;
00271     }
00272   while ((ws * hs) > (0x04000000L / whs))
00273     {
00274       ws = (ws + 1) / 2;
00275       hs = (hs + 1) / 2;
00276       whs *= 2;
00277     }
00278   whs *= ws * hs;
00279 
00280   pt[0].x = w / 2;
00281   pt[0].y = 0;
00282 
00283   pt[2].x = 0;
00284   pt[2].y = h / 2;
00285 
00286   have_s = 0;
00287   have_e = 0;
00288 
00289   if (s == 0)
00290     have_s = 1;
00291   if (e == 90)
00292     have_e = 1;
00293 
00294   x2 = w;
00295   y2 = 0;                   /* Starting point is exactly on ellipse */
00296 
00297   g = x2 - 1;
00298   g = g * g * hs + 4 * ws - whs;
00299 
00300   while ((x2 * hs) > (y2 * ws))    /* Keep |tangent| > 1 */
00301     {
00302       y2 += 2;
00303       g += ws * 4 * (y2 + 1);
00304 
00305       if (g > 0)            /* Need to drop */
00306        {
00307          x2 -= 2;
00308          g -= hs * 4 * x2;
00309        }
00310 
00311       if ((have_s == 0) && ((s_sin * x2) <= (y2 * s_cos)))
00312        {
00313          pt[0].x = (int) (x2 / 2);
00314          pt[0].y = (int) (y2 / 2);
00315          have_s = 1;
00316        }
00317 
00318       if ((have_e == 0) && ((e_sin * x2) <= (y2 * e_cos)))
00319        {
00320          pt[2].x = (int) (x2 / 2);
00321          pt[2].y = (int) (y2 / 2);
00322          have_e = 1;
00323        }
00324     }
00325   pt[1].x = (int) (x2 / 2);
00326   pt[1].y = (int) (y2 / 2);
00327 
00328   x2 = 0;
00329   y2 = h;                   /* Starting point is exactly on ellipse */
00330 
00331   g = y2 - 1;
00332   g = g * g * ws + 4 * hs - whs;
00333 
00334   while ((x2 * hs) < (y2 * ws))
00335     {
00336       x2 += 2;
00337       g += hs * 4 * (x2 + 1);
00338 
00339       if (g > 0)            /* Need to drop */
00340        {
00341          y2 -= 2;
00342          g -= ws * 4 * y2;
00343        }
00344 
00345       if ((have_s == 0) && ((s_sin * x2) >= (y2 * s_cos)))
00346        {
00347          pt[0].x = (int) (x2 / 2);
00348          pt[0].y = (int) (y2 / 2);
00349          have_s = 1;
00350        }
00351 
00352       if ((have_e == 0) && ((e_sin * x2) >= (y2 * e_cos)))
00353        {
00354          pt[2].x = (int) (x2 / 2);
00355          pt[2].y = (int) (y2 / 2);
00356          have_e = 1;
00357        }
00358     }
00359 
00360   if ((have_s == 0) || (have_e == 0))
00361     return;                 /* Bizarre case */
00362 
00363   if (style == gdPie)
00364     {
00365       pt[3] = pt[0];
00366       pt[4] = pt[1];
00367       pt[5] = pt[2];
00368 
00369       pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x);
00370       pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y);
00371       pt[1].x = cx;
00372       pt[1].y = cy;
00373       pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x);
00374       pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y);
00375       gdImageFilledPolygon (im, pt, 3, color);
00376       gdImagePolygon (im, pt, 3, color);
00377 
00378       pt[0] = pt[3];
00379       pt[1] = pt[4];
00380       pt[2] = pt[5];
00381     }
00382 
00383   if (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws)))
00384     {                       /* the points are on different parts of the curve...
00385                              * this is too tricky to try to handle, so divide and conquer:
00386                              */
00387       pt[3] = pt[0];
00388       pt[4] = pt[1];
00389       pt[5] = pt[2];
00390 
00391       pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x);
00392       pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y);
00393       pt[1].x = cx + (flip_x ? (-pt[1].x) : pt[1].x);
00394       pt[1].y = cy + (flip_y ? (-pt[1].y) : pt[1].y);
00395       pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x);
00396       pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y);
00397       gdImageFilledPolygon (im, pt, 3, color);
00398       gdImagePolygon (im, pt, 3, color);
00399 
00400       pt[0] = pt[3];
00401       pt[2] = pt[4];
00402 
00403       conquer = 1;
00404     }
00405 
00406   if (conquer || (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) > (e_sin * ws))))
00407     {                       /* This is the best bit... */
00408       /* steep line + ellipse */
00409       /* go up & left from pt[0] to pt[2] */
00410 
00411       x2 = w;
00412       y2 = 0;               /* Starting point is exactly on ellipse */
00413 
00414       g = x2 - 1;
00415       g = g * g * hs + 4 * ws - whs;
00416 
00417       while ((x2 * hs) > (y2 * ws))       /* Keep |tangent| > 1 */
00418        {
00419          if ((s_sin * x2) <= (y2 * s_cos))
00420            break;
00421 
00422          y2 += 2;
00423          g += ws * 4 * (y2 + 1);
00424 
00425          if (g > 0)         /* Need to drop */
00426            {
00427              x2 -= 2;
00428              g -= hs * 4 * x2;
00429            }
00430        }
00431 
00432       lx2 = x2;
00433       ly2 = y2;
00434 
00435       lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x);
00436       lg = (lx2 - 1) * (pt[0].y - pt[2].y) - (ly2 + 2) * (pt[0].x - pt[2].x) - lg;
00437 
00438       while (y2 < (2 * pt[2].y))
00439        {
00440          y2 += 2;
00441          g += ws * 4 * (y2 + 1);
00442 
00443          if (g > 0)         /* Need to drop */
00444            {
00445              x2 -= 2;
00446              g -= hs * 4 * x2;
00447            }
00448 
00449          ly2 += 2;
00450          lg -= 2 * (pt[0].x - pt[2].x);
00451 
00452          if (lg < 0)        /* Need to drop */
00453            {
00454              lx2 -= 2;
00455              lg -= 2 * (pt[0].y - pt[2].y);
00456            }
00457 
00458          y = (int) (y2 / 2);
00459          for (x = (int) (lx2 / 2); x <= (int) (x2 / 2); x++)
00460            {
00461              gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)),
00462                             ((flip_y) ? (cy - y) : (cy + y)), color);
00463            }
00464        }
00465     }
00466   if (conquer)
00467     {
00468       pt[0] = pt[4];
00469       pt[2] = pt[5];
00470     }
00471   if (conquer || (((s_cos * hs) < (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws))))
00472     {                       /* This is the best bit... */
00473       /* gradual line + ellipse */
00474       /* go down & right from pt[2] to pt[0] */
00475 
00476       x2 = 0;
00477       y2 = h;               /* Starting point is exactly on ellipse */
00478 
00479       g = y2 - 1;
00480       g = g * g * ws + 4 * hs - whs;
00481 
00482       while ((x2 * hs) < (y2 * ws))
00483        {
00484          x2 += 2;
00485          g += hs * 4 * (x2 + 1);
00486 
00487          if (g > 0)         /* Need to drop */
00488            {
00489              y2 -= 2;
00490              g -= ws * 4 * y2;
00491            }
00492 
00493          if ((e_sin * x2) >= (y2 * e_cos))
00494            break;
00495        }
00496 
00497       lx2 = x2;
00498       ly2 = y2;
00499 
00500       lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x);
00501       lg = (lx2 + 2) * (pt[0].y - pt[2].y) - (ly2 - 1) * (pt[0].x - pt[2].x) - lg;
00502 
00503       while (x2 < (2 * pt[0].x))
00504        {
00505          x2 += 2;
00506          g += hs * 4 * (x2 + 1);
00507 
00508          if (g > 0)         /* Need to drop */
00509            {
00510              y2 -= 2;
00511              g -= ws * 4 * y2;
00512            }
00513 
00514          lx2 += 2;
00515          lg += 2 * (pt[0].y - pt[2].y);
00516 
00517          if (lg < 0)        /* Need to drop */
00518            {
00519              ly2 -= 2;
00520              lg += 2 * (pt[0].x - pt[2].x);
00521            }
00522 
00523          x = (int) (x2 / 2);
00524          for (y = (int) (ly2 / 2); y <= (int) (y2 / 2); y++)
00525            {
00526              gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)),
00527                             ((flip_y) ? (cy - y) : (cy + y)), color);
00528            }
00529        }
00530     }
00531 }
00532 
00533 static gdPoint
00534 gdArcClosest (int width, int height, int angle)
00535 {
00536   gdPoint pt;
00537 
00538   int flip_x = 0;
00539   int flip_y = 0;
00540 
00541   long a_sin = 0;
00542   long a_cos = 0;
00543 
00544   long w;                   /* a * 2 */
00545   long h;                   /* b * 2 */
00546 
00547   long x2;                  /* x * 2 */
00548   long y2;                  /* y * 2 */
00549 
00550   long ws;                  /* (a * 2)^2 */
00551   long hs;                  /* (b * 2)^2 */
00552 
00553   long whs;                 /* (a * 2)^2 * (b * 2)^2 */
00554 
00555   long g;                   /* decision variable */
00556 
00557   w = (long) ((width & 1) ? (width + 1) : (width));
00558   h = (long) ((height & 1) ? (height + 1) : (height));
00559 
00560   while (angle < 0)
00561     angle += 360;
00562   while (angle >= 360)
00563     angle -= 360;
00564 
00565   if (angle == 0)
00566     {
00567       pt.x = w / 2;
00568       pt.y = 0;
00569       return (pt);
00570     }
00571   if (angle == 90)
00572     {
00573       pt.x = 0;
00574       pt.y = h / 2;
00575       return (pt);
00576     }
00577   if (angle == 180)
00578     {
00579       pt.x = -w / 2;
00580       pt.y = 0;
00581       return (pt);
00582     }
00583   if (angle == 270)
00584     {
00585       pt.x = 0;
00586       pt.y = -h / 2;
00587       return (pt);
00588     }
00589 
00590   pt.x = 0;
00591   pt.y = 0;
00592 
00593   if ((angle > 90) && (angle < 180))
00594     {
00595       angle = 180 - angle;
00596       flip_x = 1;
00597     }
00598   if ((angle > 180) && (angle < 270))
00599     {
00600       angle = angle - 180;
00601       flip_x = 1;
00602       flip_y = 1;
00603     }
00604   if ((angle > 270) && (angle < 360))
00605     {
00606       angle = 360 - angle;
00607       flip_y = 1;
00608     }
00609 
00610   a_sin = (long) ((double) 32768 * sin ((double) angle * M_PI / (double) 180));
00611   a_cos = (long) ((double) 32768 * cos ((double) angle * M_PI / (double) 180));
00612 
00613   ws = w * w;
00614   hs = h * h;
00615 
00616   whs = 1;
00617   while ((ws > 32768) || (hs > 32768))
00618     {
00619       ws = (ws + 1) / 2;    /* Unfortunate limitations on integers makes */
00620       hs = (hs + 1) / 2;    /* drawing large  ellipses problematic...    */
00621       whs *= 2;
00622     }
00623   while ((ws * hs) > (0x04000000L / whs))
00624     {
00625       ws = (ws + 1) / 2;
00626       hs = (hs + 1) / 2;
00627       whs *= 2;
00628     }
00629   whs *= ws * hs;
00630 
00631   if ((a_cos * hs) > (a_sin * ws))
00632     {
00633       x2 = w;
00634       y2 = 0;               /* Starting point is exactly on ellipse */
00635 
00636       g = x2 - 1;
00637       g = g * g * hs + 4 * ws - whs;
00638 
00639       while ((x2 * hs) > (y2 * ws))       /* Keep |tangent| > 1 */
00640        {
00641          y2 += 2;
00642          g += ws * 4 * (y2 + 1);
00643 
00644          if (g > 0)         /* Need to drop */
00645            {
00646              x2 -= 2;
00647              g -= hs * 4 * x2;
00648            }
00649 
00650          if ((a_sin * x2) <= (y2 * a_cos))
00651            {
00652              pt.x = (int) (x2 / 2);
00653              pt.y = (int) (y2 / 2);
00654              break;
00655            }
00656        }
00657     }
00658   else
00659     {
00660       x2 = 0;
00661       y2 = h;               /* Starting point is exactly on ellipse */
00662 
00663       g = y2 - 1;
00664       g = g * g * ws + 4 * hs - whs;
00665 
00666       while ((x2 * hs) < (y2 * ws))
00667        {
00668          x2 += 2;
00669          g += hs * 4 * (x2 + 1);
00670 
00671          if (g > 0)         /* Need to drop */
00672            {
00673              y2 -= 2;
00674              g -= ws * 4 * y2;
00675            }
00676 
00677          if ((a_sin * x2) >= (y2 * a_cos))
00678            {
00679              pt.x = (int) (x2 / 2);
00680              pt.y = (int) (y2 / 2);
00681              break;
00682            }
00683        }
00684     }
00685 
00686   if (flip_x)
00687     pt.x = -pt.x;
00688   if (flip_y)
00689     pt.y = -pt.y;
00690 
00691   return (pt);
00692 }
00693 
00694 #include "gd.h"
00695 #include <string.h>
00696 #include <math.h>
00697 
00698 #define WIDTH 500
00699 #define HEIGHT       300
00700 
00701 int
00702 main (int argc, char *argv[])
00703 {
00704   gdImagePtr im = gdImageCreate (WIDTH, HEIGHT);
00705   int white = gdImageColorResolve (im, 0xFF, 0xFF, 0xFF), black = gdImageColorResolve (im, 0, 0, 0),
00706     red = gdImageColorResolve (im, 0xFF, 0xA0, 0xA0);
00707   FILE *out;
00708 
00709   /* filled arc - circle */
00710   gdImageFilledArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, red, gdPie);
00711   gdImageArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, black);
00712 
00713   /* filled arc - ellipse */
00714   gdImageFilledArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, red, gdPie);
00715   gdImageArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, black);
00716 
00717 
00718   /* reference lines */
00719   gdImageLine (im, 0, HEIGHT / 4, WIDTH, HEIGHT / 4, black);
00720   gdImageLine (im, WIDTH / 5, 0, WIDTH / 5, HEIGHT, black);
00721   gdImageLine (im, WIDTH / 2, 0, WIDTH / 2, HEIGHT, black);
00722   gdImageLine (im, WIDTH / 2, HEIGHT / 4, WIDTH / 2 + 300, HEIGHT / 4 + 300, black);
00723   gdImageLine (im, WIDTH / 5, HEIGHT / 4, WIDTH / 5 + 300, HEIGHT / 4 + 300, black);
00724 
00725   /* TBB: Write img to test/arctest.png */
00726   out = fopen ("test/arctest.png", "wb");
00727   if (!out)
00728     {
00729       php_gd_error("Can't create test/arctest.png");
00730       exit (1);
00731     }
00732   gdImagePng (im, out);
00733   fclose (out);
00734   php_gd_error("Test image written to test/arctest.png");
00735   /* Destroy it */
00736   gdImageDestroy (im);
00737 
00738   return 0;
00739 }
00740 
00741 #endif