home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / ppc / ppcArc.c < prev    next >
C/C++ Source or Header  |  1991-07-16  |  36KB  |  1,630 lines

  1. /*
  2.  * Copyright IBM Corporation 1987,1988,1989
  3.  *
  4.  * All Rights Reserved
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and that 
  9.  * both that copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of IBM not be
  11.  * used in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  18.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20.  * SOFTWARE.
  21.  *
  22. */
  23.  
  24. /* PPCZEROARCS-
  25. Tom Paquin 2/19/89
  26.  
  27.     The idea is to draw solid, zero-width circles and ellipses
  28. using Bresenham or similar techniques, while preserving X semantics.
  29. Zero widths can be drawn easily without regard to intersection points of
  30. polyarcs.
  31.     I use Art Kauffman's modified algorithm for quadrants 2 and 1 
  32. (respectively) while reflecting in X and Y, but not the 45s like bresenham.  
  33. I generate spans or runs for Quadrant 2 and points for Quadrant 1.  
  34.     For bounding boxes of even width (EG (0,0) to (3,3)) the reflection
  35. hasn't an integer center.  I choose floor(center) for left and upper
  36. reflections and ceiling(center) for right and lower reflections. (Lower is
  37. increasing Y.)  This can create 4 pseudo-center points.  I refer to this 
  38. technique as the Jeff Shift (Jeff Weinstien).  Jeffshifted circles will not 
  39. draw the top dead center and bottom dead center runs in a circle, so we 
  40. predraw them for Jeffshifted circles.
  41.     For potentially clipped circles, I generate Spans since the spans
  42. routines clip.  For cases where the circle's box resides wholly within the
  43. composite clip, I merely draw.  For cases I cannot easily handle, I crap
  44. out to mi, which is HORRENDOUSLY slow, especially if you've no FP hardware.
  45. */
  46.  
  47.  
  48. /* $Header: /andrew/X11/r3src/release/server/ddx/ibm/ppc/RCS/ppcArc.c,v 9.9 89/04/29 23:59:59 jeff Exp $ */
  49. /* $Source: /andrew/X11/r3src/release/server/ddx/ibm/ppc/RCS/ppcArc.c,v $ */
  50.  
  51. #ifndef lint
  52. static char *rcsid = "$Header: /andrew/X11/r3src/release/server/ddx/ibm/ppc/RCS/ppcArc.c,v 9.9 89/04/29 23:59:59 jeff Exp $";
  53. #endif
  54.  
  55.  
  56. #include "X.h"
  57. #include "Xprotostr.h"
  58. #include "gcstruct.h"
  59. #include "regionstr.h"
  60. #include "scrnintstr.h"
  61. #include "windowstr.h"
  62. #include "miscstruct.h"
  63. #include "misc.h"
  64.  
  65. #include "OScompiler.h"
  66.  
  67. #include "ppc.h"
  68.  
  69. /* FULLCIRCLE is 360 * 64 (sixty-fourths of a degree) */
  70. #define FULLCIRCLE ( 360 << 6 )
  71.  
  72. void ppcFillIntegerFullArc();
  73. void ppcIntegerFullArc() ;
  74. void DrawFullArcOnSpans();
  75. void DrawFullArcOnHW();
  76. void FillFullArcOnSpans();
  77. void FillFullArcOnHW();
  78. void ppcIntegerArc();
  79. void GetPts();
  80. void DrawArcOnSpans();
  81. extern int mfbGCPrivateIndex;
  82.  
  83. typedef struct MyPointStruct {
  84.     short x;
  85.     short y;
  86.     } MyPointRec, *MyPointPtr;
  87.  
  88. typedef struct MyBoxStruct {
  89.     signed long int x1, y1, x2, y2;
  90. } MyBoxRec, *MyBoxPtr;
  91.  
  92. void
  93. ppcPolyZeroArc(pWindow, pGC, narcs, parcs)
  94. WindowPtr    pWindow;
  95. GCPtr        pGC;
  96. int        narcs;
  97. xArc        *parcs;
  98. { /* This routine should only be called when LineStyle==Solid and LineWidth=0 */
  99. register xArc    *thisarc;
  100. int        box_w, box_h, angle;
  101. int        (* checkcursor)(), *semaphore, CursorIsSaved;
  102.  
  103. ppcScrnPrivPtr  pScrPriv = (ppcScrnPrivPtr) 
  104.             pWindow->drawable.pScreen->devPrivate;
  105.  
  106. CursorIsSaved = 0;
  107. semaphore = pScrPriv->CursorSemaphore;
  108. checkcursor = pScrPriv->CheckCursor;
  109.  
  110. if ( ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu  == GXnoop ) return ;
  111.  
  112. while (narcs--)
  113.     {
  114.     thisarc = parcs++;
  115. /*
  116.     printf("w = %d, h = %d, a1 = %d, a2 = %d\n", thisarc->width,
  117.             thisarc->height, thisarc->angle1, thisarc->angle2);
  118. */
  119.  
  120.     box_w = thisarc->width;
  121.     box_h = thisarc->height;
  122.     angle = thisarc->angle2;
  123.     
  124.         CursorIsSaved |= !(*semaphore) && (* checkcursor)( 
  125.                     thisarc->x, thisarc->y,
  126.                     thisarc->width, thisarc->height ) ;
  127.         (*semaphore)++ ;
  128.  
  129.     if ( (angle >= FULLCIRCLE) || (angle <= -FULLCIRCLE) )
  130.         {
  131.         if ( ( box_w == box_h) || 
  132.                 ( ( box_w < 4096 ) && ( box_h < 4096 ) ) )
  133.             ppcIntegerFullArc(pWindow, pGC, thisarc);
  134.         else    /* algorithm doesn't work because we'll
  135.                flood a 32-bit int */
  136.             miPolyArc(pWindow, pGC, 1, thisarc);
  137.         }
  138.     else
  139.         { 
  140.         ppcIntegerArc(pWindow, pGC, thisarc);
  141.         }
  142.         (*semaphore)-- ;
  143.     }
  144.     if ( ( !(*semaphore)) && CursorIsSaved ) (* pScrPriv->ReplaceCursor)() ;
  145. return ;
  146. }
  147.  
  148. void
  149. ppcPolyFillArc(pWindow, pGC, narcs, parcs)
  150. WindowPtr    pWindow;
  151. GCPtr        pGC;
  152. int        narcs;
  153. xArc        *parcs;
  154. { /* This routine should only be called when FillStyle==FillSolid */
  155. register xArc    *thisarc;
  156. int        box_w, box_h, angle;
  157. int        (* checkcursor)(), *semaphore, CursorIsSaved;
  158.  
  159. ppcScrnPrivPtr  pScrPriv = (ppcScrnPrivPtr) 
  160.             pWindow->drawable.pScreen->devPrivate;
  161.  
  162. CursorIsSaved = 0;
  163. semaphore = pScrPriv->CursorSemaphore;
  164. checkcursor = pScrPriv->CheckCursor;
  165.  
  166. if ( ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu  == GXnoop ) return ;
  167.  
  168. while (narcs--)
  169.     {
  170.     thisarc = parcs++;
  171.  
  172.     box_w = thisarc->width;
  173.     box_h = thisarc->height;
  174.     angle = thisarc->angle2;
  175.     
  176.         CursorIsSaved |= !(*semaphore) && (* checkcursor)( 
  177.                     thisarc->x, thisarc->y,
  178.                     thisarc->width, thisarc->height ) ;
  179.         (*semaphore)++ ;
  180.  
  181.     if ( (angle >= FULLCIRCLE) || (angle <= -FULLCIRCLE) )
  182.         {
  183.         if ( ( box_w == box_h) || 
  184.                 ( ( box_w < 4096 ) && ( box_h < 4096 ) ) )
  185.             ppcFillIntegerFullArc(pWindow, pGC, thisarc);
  186.         else
  187.             miPolyFillArc(pWindow, pGC, 1, thisarc);
  188.         }
  189.     else 
  190.         { 
  191.         miPolyFillArc(pWindow, pGC, 1, thisarc);
  192.         }
  193.         (*semaphore)-- ;
  194.     }
  195.     if ( ( !(*semaphore)) && CursorIsSaved ) (* pScrPriv->ReplaceCursor)() ;
  196. return ;
  197. }
  198.  
  199. static void
  200. ppcFillIntegerFullArc(pWindow, pGC, pArc)
  201. WindowPtr     pWindow;
  202. GCPtr        pGC;
  203. xArc        *pArc;
  204. {
  205. BoxRec        bbox;
  206. RegionPtr       pCC;
  207. ScreenPtr    pScreen;
  208. xRectangle    rect;
  209.  
  210.  
  211. if (pArc->width == 0) return;
  212. if (pArc->height == 0) return;
  213.  
  214. /* set up the box and convert to screen coordinates */
  215. bbox.x2 = (rect.x = bbox.x1 = pWindow->drawable.x + pArc->x) 
  216.             + (rect.width = pArc->width ) ;
  217. bbox.y2 = (rect.y = bbox.y1 = pWindow->drawable.y + pArc->y) 
  218.             + (rect.height = pArc->height );
  219.  
  220. if ( pGC->fillStyle != FillSolid )
  221.     {
  222.     FillFullArcOnSpans(pWindow, pGC, &rect);
  223.     return;
  224.     }
  225.  
  226. pCC = ((ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr)->pCompositeClip;
  227. pScreen = pWindow->drawable.pScreen;
  228.  
  229. switch ( (*pScreen->RectIn)(pCC, &bbox))
  230.     {
  231.     case rgnOUT:
  232.         /* nothing to draw, abandon ship */
  233.         return;
  234.     case rgnIN:
  235.         /* blast away, mateys! */
  236.         FillFullArcOnHW( 
  237.             ((ppcScrnPriv *)pScreen->devPrivate)->solidFill,
  238.             &rect, 
  239.             ((ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr)->colorRrop.fgPixel,
  240.             ((ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr)->colorRrop.alu,
  241.             ((ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr)->colorRrop.planemask );
  242.         break;
  243.     case rgnPART:
  244.         /* avast! time to use finesse. */
  245.         FillFullArcOnSpans(pWindow, pGC, &rect);
  246.         break;
  247.     }
  248. return ;
  249. }
  250.  
  251. #define PAINT(X,Y,WIDTH)            \
  252.     {                    \
  253.     xR = cxR + (X);                \
  254.     xL = cxL - (X) - (WIDTH) + 1;        \
  255.     yU = cyU - (Y) ;            \
  256.     yL = cyL + (Y) ;            \
  257.     /* Quadrant 1 */ (*paint)(color, alu, pm, xR, yU, WIDTH, 1) ; \
  258.     /* Quadrant 2 */ (*paint)(color, alu, pm, xL, yU, WIDTH, 1) ; \
  259.     /* Quadrant 3 */ (*paint)(color, alu, pm, xL, yL, WIDTH, 1) ; \
  260.     /* Quadrant 4 */ (*paint)(color, alu, pm, xR, yL, WIDTH, 1) ; \
  261.     }
  262.  
  263. #define SPAN(X,Y,W)    \
  264.     {        \
  265.     ppt->x = X; ppt->y = Y; *pwidth = W;    \
  266.     ppt++; pwidth++; nspans++;        \
  267.     }
  268.  
  269. static void
  270. ppcIntegerFullArc(pWindow, pGC, pArc)
  271. WindowPtr     pWindow;
  272. GCPtr        pGC;
  273. xArc        *pArc;
  274. {
  275. BoxRec        bbox;
  276. RegionPtr       pCC;
  277. ScreenPtr    pScreen;
  278. xRectangle    rect;
  279.  
  280. if (pArc->width == 0) return;
  281. if (pArc->height == 0) return;
  282.  
  283. /* set up the box and convert to screen coordinates */
  284. bbox.x2 = (rect.x = bbox.x1 = pWindow->drawable.x + pArc->x) 
  285.             + (rect.width = pArc->width ) ;
  286. bbox.y2 = (rect.y = bbox.y1 = pWindow->drawable.y + pArc->y) 
  287.             + (rect.height = pArc->height );
  288.  
  289. if ( pGC->fillStyle != FillSolid )
  290.     {
  291.     DrawFullArcOnSpans(pWindow, pGC, &rect);
  292.     return;
  293.     }
  294.  
  295. pCC = ((ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr)->pCompositeClip;
  296. pScreen = pWindow->drawable.pScreen;
  297.  
  298. switch ( (*pScreen->RectIn)(pCC, &bbox))
  299.     {
  300.     case rgnOUT:
  301.         /* nothing to draw, abandon ship */
  302.         return;
  303.     case rgnIN:
  304.         /* blast away, mateys! */
  305.         DrawFullArcOnHW( 
  306.             ((ppcScrnPriv *)pScreen->devPrivate)->solidFill,
  307.             &rect, 
  308.             ((ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr)->colorRrop.fgPixel,
  309.             ((ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr)->colorRrop.alu,
  310.             ((ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr)->colorRrop.planemask );
  311.         break;
  312.     case rgnPART:
  313.         /* avast! time to use finesse. */
  314.         /**** WHICH ONE IS FASTER???    ****/
  315.         DrawFullArcOnSpans(pWindow, pGC, &rect);
  316.         break;
  317.     }
  318. return ;
  319. }
  320.  
  321. static void
  322. ppcIntegerArc(pWindow, pGC, pArc)
  323.     WindowPtr     pWindow;
  324.     GCPtr        pGC;
  325.     xArc        *pArc;
  326.     {
  327.  
  328.     if (pArc->width == 0) return;
  329.     if (pArc->height == 0) return;
  330.  
  331.     if ( (pArc->width != pArc->height) && 
  332.             ( ( pArc->width > 2048 ) || ( pArc->height > 2048 ) ) )
  333.         {
  334.         miPolyArc(pWindow, pGC, 1, pArc);
  335.         }
  336.     else
  337.         {
  338.         DrawArcOnSpans(pWindow, pGC, pArc);
  339.         }
  340.     return ;
  341.     }
  342.  
  343. #define HALFCIRCLE ( FULLCIRCLE >> 1 )
  344. #define QUARTERCIRCLE ( FULLCIRCLE >> 2 )
  345.  
  346. extern unsigned short ppcSinTab[];
  347.  
  348. static int 
  349. isin(theta)
  350.     int theta;
  351.     {
  352.     int ret, tmptheta;
  353.     int savtheta;
  354.  
  355.     savtheta = theta;
  356.     /* Compilers can't seem to handle modulo of a negative number */
  357.     theta %= FULLCIRCLE;
  358.     if ( theta < 0 )
  359.         theta += FULLCIRCLE;
  360.  
  361. /*
  362.     printf("theta = %d\n", theta);
  363. */
  364.  
  365.     if ( ( tmptheta = theta % HALFCIRCLE ) > QUARTERCIRCLE )
  366.         ret = ppcSinTab[(HALFCIRCLE - tmptheta) >> 1];
  367.     else
  368.         ret = ppcSinTab[(tmptheta) >> 1];
  369.  
  370. /*
  371.     printf("tmptheta = %d, ret = %d\n", tmptheta, ret);
  372. */
  373.         
  374.     if ( theta > HALFCIRCLE )
  375.         {
  376. /*
  377.         printf("sin(%d) is %d\n", savtheta, -ret);
  378. */
  379.         return ( -ret );
  380.         }
  381.     else
  382.         {
  383. /*
  384.         printf("sin(%d) is %d\n", savtheta, ret);
  385. */
  386.         return ( ret );
  387.         }
  388.  
  389.     }
  390.  
  391. #define icos(x) isin((x)+QUARTERCIRCLE)
  392.  
  393. static void
  394. GetPts(pArc, a, b)
  395.     xArc *pArc;
  396.     MyPointRec *a, *b;
  397.     {
  398.     long int    rx, ry, a1, a2;
  399.  
  400.     if (pArc->angle2 < 0)
  401.         {
  402.         a1 = pArc->angle1 + pArc->angle2;
  403.         a2 = pArc->angle1;
  404.         }
  405.     else 
  406.         {
  407.         a1 = pArc->angle1;
  408.         a2 = pArc->angle1 + pArc->angle2;
  409.         }
  410.  
  411.     rx = pArc->width >> 1;
  412.     ry = pArc->height >> 1;
  413.  
  414. /*
  415.     printf("rx = %d, ry = %d, a1 = %d, a2 = %d\n", rx, ry, a1, a2);
  416. */
  417.     a->x = ( ( rx * icos(a1) ) + ( 1 << 14 ) ) >> 15;
  418.     a->y = - ( ( ( ry * isin(a1) ) + ( 1 << 14 ) ) >> 15 );
  419.     b->x = ( ( rx * icos(a2) ) + ( 1 << 14 ) ) >> 15;
  420.     b->y = - ( ( ( ry * isin(a2) ) + ( 1 << 14 ) ) >> 15 );
  421. /*
  422.     printf("a = (%d, %d), b = (%d, %d)\n", a->x, a->y, b->x, b->y);
  423. */
  424.  
  425.     return ;
  426.     }
  427.  
  428. static int lastradius = -1;
  429. static MyPointPtr circlePts = 0;
  430. static int *circleWidths = 0;
  431. static int ncirclespans;
  432.  
  433. static MyPointRec    *ellipsePts = 0;
  434. static int        *ellipseWidths = 0;
  435. static int        nellipsespans = 0;
  436. static int        lasta = -1, lastb = -1;
  437.  
  438. static MyPointRec    *quadPts = 0;
  439. static int        *quadWidths = 0;
  440. static int        nquadspans = 0;
  441.  
  442. static void
  443. ComputeCQuad( r )
  444.     int r;
  445. {
  446. register int     dv;
  447. short        moves, x, y;
  448. int        startx, lasty, width;
  449. MyPointPtr    ppt;
  450. int        nspans;
  451. int        *pwidth;
  452.  
  453. if ( r == lastradius )
  454.     return;
  455.  
  456. Xfree(circlePts);
  457. Xfree(circleWidths);
  458.  
  459. moves = -( y = r );
  460. x = 0;
  461. dv = 1-r;
  462. width = 0;
  463. startx = x+1;
  464. lasty = y;
  465.  
  466.  
  467. /* allocate space for the spans */
  468. ppt = (MyPointPtr) Xalloc( ( ( 2 + 2 * r ) * sizeof(MyPointRec)));
  469. if (ppt == 0)
  470.     {
  471.     ErrorF("ppcZeroCircle: ComputeCQuad: cannot malloc ppt");
  472.     return ;
  473.     }
  474.  
  475. pwidth = (int *) Xalloc( ( 2 + 2 * r ) * sizeof(int) );
  476. if (pwidth == 0)
  477.     {
  478.     Xfree(ppt);
  479.     ErrorF("ppcZeroCircle: ComputeCQuad: cannot malloc pwidth");
  480.     return ;
  481.     }
  482.  
  483. circlePts = ppt;
  484. circleWidths = pwidth;
  485. lastradius = r;
  486.  
  487. nspans = 0;
  488.  
  489. /* Draw 2 octants and reflect them.  Do not draw first Pel.  Draw Last Pel.  */
  490.  
  491. /* OCTANT 2 */
  492. while(moves<0)
  493.     {
  494.     if (dv >= 0)
  495.         { /* go diagonal */
  496.         x++; y--;
  497.         moves += 2;
  498.         dv += ( ((x-y) << 1) + 1 );
  499.         SPAN(startx, lasty, width);
  500.         startx = x;    
  501.         lasty = y;    
  502.         width = 1;
  503.         }
  504.        else { /* go axial */
  505.         x++;
  506.         moves++;
  507.         dv += ( (x<<1) + 1 );
  508.         width++;    
  509.         }
  510.     }
  511.  
  512. if (width) SPAN(startx, lasty, width);
  513.  
  514. /* OCTANT 1 */
  515. dv -= (x + y);
  516. moves -= r ;
  517.  
  518. while (moves < 0)
  519.     {
  520.     if (dv<0)
  521.         { /* go diagonal */
  522.         x++; y--;
  523.         moves += 2;
  524.         dv += ( ((x-y) << 1) + 1 );
  525.         SPAN(x, y, 1);
  526.         lasty = y;    
  527.         }
  528.        else { /* go axial */
  529.         y--;
  530.         moves++;
  531.         dv += ( 1 - (y<<1));
  532.         SPAN(x, y, 1);
  533.         }
  534.     }
  535.  
  536. ncirclespans = nspans - 1;
  537. return ;
  538. }
  539.  
  540. static void
  541. ComputeEQuad(a, b)
  542.     int a, b;
  543.     {
  544.     long int     TwoBsq, TwoAsq, dv1, dv2, TwoBsqX, TwoAsqY;
  545.     int        x, y, startx;
  546.     int        r, *pwidth, *pwidthInit, nspans;
  547.     MyPointRec    *ppt, *pptInit;
  548.  
  549.     if ( a == lasta && b == lastb )
  550.         return;
  551.  
  552.     x = 0; y = b;
  553.     startx = 1;
  554.     r = ( a>b ? a : b );
  555.  
  556.     pptInit = ppt = 
  557.         (MyPointPtr) Xalloc( ( ( 14 + 8 * r ) * sizeof(MyPointRec)));
  558.     if (ppt == 0)
  559.         {
  560.         ErrorF("ComputeEQuad: cannot malloc ppt");
  561.         return ;
  562.         }
  563.  
  564.     pwidthInit = pwidth = 
  565.             (int *) Xalloc( ( ( 14 + 8 * r ) * sizeof(int)) );
  566.     if (pwidth == 0)
  567.         {
  568.         Xfree(ppt);
  569.         ErrorF("ComputeEQuad: cannot malloc pwidth");
  570.         return ;
  571.         }
  572.  
  573.     Xfree(ellipsePts);
  574.     Xfree(ellipseWidths);
  575.  
  576.     nspans = 0;
  577.  
  578.     TwoBsq = (b * b) << 1 ;
  579.     TwoAsq = (a * a) << 1 ;
  580.     TwoBsqX = 0; /* x is still zero */
  581.     TwoAsqY = TwoAsq * y;
  582.  
  583.     dv2 = - (b * TwoAsq);     /* use dv2 as a temp to hold -2b(aa) */
  584.     dv1 = (TwoBsq >> 1) + (dv2 >> 1) + (TwoAsq >> 3);
  585.     dv2 += (TwoBsq >> 3) + (TwoAsq >> 1) ;
  586.  
  587.     /*START LOOP */
  588.     while (dv2 < 0)
  589.         {
  590.         /* REGION 1 */
  591.         x++;
  592.         TwoBsqX += TwoBsq;
  593.         if (dv1 < 0)
  594.             { /* MOVE AXIAL */
  595.             dv1 += TwoBsqX + (TwoBsq >> 1);
  596.             dv2 += TwoBsqX;
  597.             }
  598.         else 
  599.             { /* MOVE DIAGONAL */
  600.             ppt->x = startx;
  601.             ppt->y = y;
  602.             *pwidth = x - startx;
  603.             ppt++; pwidth++; nspans++;
  604.             startx = x;
  605.             y--;
  606.             TwoAsqY -= TwoAsq;
  607.             dv1 += TwoBsqX - TwoAsqY + (TwoBsq >> 1);
  608.             dv2 += (TwoAsq >> 1) - TwoAsqY + TwoBsqX ;
  609.             }
  610.         }
  611.  
  612.         ppt->x = startx;
  613.         ppt->y = y;
  614.         *pwidth = x - startx + 1;
  615.         ppt++; pwidth++; nspans++;
  616.  
  617.     while (y>1)
  618.         {
  619.         /* REGION 2 */
  620.         y--;
  621.         TwoAsqY -= TwoAsq;
  622.         if (dv2 < 0)
  623.             {  /* diagonal move */
  624.             x++;
  625.             TwoBsqX += TwoBsq;
  626.             dv2 += (TwoAsq>>1) - TwoAsqY + TwoBsqX;
  627.             }
  628.         else 
  629.             {  /* axial move */
  630.             dv2 += (TwoAsq >> 1) - TwoAsqY;
  631.             }
  632.         ppt->x = x;
  633.         ppt->y = y;
  634.         *pwidth = 1;
  635.         ppt++; pwidth++; nspans++;
  636.         }
  637.  
  638.     nellipsespans = nspans;
  639.     ellipsePts = pptInit;
  640.     ellipseWidths = pwidthInit;
  641.     return ;
  642.     }
  643.  
  644. static void
  645. ComputeQuad( a, b )
  646.     int a, b;
  647.     {
  648.     if ( a == b )
  649.         {
  650.         ComputeCQuad( a );
  651.         quadPts = circlePts;
  652.         quadWidths = circleWidths;
  653.         nquadspans = ncirclespans;
  654.         }
  655.     else
  656.         {
  657.         ComputeEQuad( a, b );
  658.         quadPts = ellipsePts;
  659.         quadWidths = ellipseWidths;
  660.         nquadspans = nellipsespans;
  661.         }
  662.     }
  663.  
  664. static void
  665. DrawFullArcOnHW(paint, pRect, color, alu, pm)
  666.     register void     (*paint)();
  667.     xRectangle    *pRect;
  668.     int        color;
  669.     int         alu;
  670.     int        pm;
  671.     {
  672.     int        cxL, cxR, cyL, cyU;
  673.     int        xR, xL, yU, yL;
  674.     int        nspans, *pwidth;
  675.     MyPointPtr    ppt;
  676.     int        a, b;
  677.  
  678.     a = ( pRect->width - 1 ) >> 1;
  679.     b = ( pRect->height - 1 ) >> 1;
  680.  
  681.     if ( pRect->width & 1)
  682.         {
  683.         cxL = cxR = pRect->x + a;
  684.         (*paint)(color, alu, pm, cxL, pRect->y, 1, 1) ;
  685.         (*paint)(color, alu, pm, cxL, pRect->y + pRect->height - 1, 1, 1) ;
  686.         }
  687.     else
  688.         {
  689.         cxL = pRect->x + a;
  690.         cxR = pRect->x + a + 1;
  691.         (*paint)(color, alu, pm, cxL, pRect->y, 2, 1) ;
  692.         (*paint)(color, alu, pm, cxL, pRect->y + pRect->height - 1, 2, 1) ;
  693.         }
  694.  
  695.     if ( pRect->height & 1)
  696.         {
  697.         cyL = cyU = pRect->y + b;
  698.         (*paint)(color, alu, pm, pRect->x, cyU, 1, 1) ;
  699.         (*paint)(color, alu, pm, pRect->x + pRect->width - 1, cyU, 1, 1) ;
  700.         }
  701.     else
  702.         {
  703.         cyU = pRect->y + b;
  704.         cyL = pRect->y + b + 1;
  705.         (*paint)(color, alu, pm, pRect->x, cyU, 1, 2) ;
  706.         (*paint)(color, alu, pm, pRect->x + pRect->width - 1, cyU, 1, 2) ;
  707.         }
  708.  
  709.     ComputeQuad(a,b);
  710.  
  711.     for( nspans = nquadspans, ppt = quadPts, pwidth = quadWidths;
  712.             nspans > 0; nspans--, ppt++, pwidth++ )
  713.         {
  714.         PAINT(ppt->x, ppt->y, *pwidth);
  715.         }
  716.  
  717.     return ;
  718.     }
  719.  
  720. static void
  721. FillFullArcOnHW(paint, pRect, color, alu, pm)
  722.     register void     (*paint)();
  723.     xRectangle    *pRect;
  724.     int        color;
  725.     int         alu;
  726.     int        pm;
  727.     {
  728.     int        cxL, cxR, cyL, cyU;
  729.     int        xL, yU, yL;
  730.     int        nspans, *pwidth;
  731.     MyPointPtr    ppt;
  732.     int        a, b, w;
  733.  
  734.     a = ( pRect->width - 1 ) >> 1;
  735.     b = ( pRect->height - 1 ) >> 1;
  736.  
  737.     if ( pRect->width & 1 )
  738.         {
  739.         cxL = cxR = pRect->x + a;
  740.         }
  741.     else
  742.         {
  743.         cxL = pRect->x + a;
  744.         cxR = pRect->x + a + 1;
  745.         }
  746.         
  747.     if ( pRect->height & 1)
  748.         {
  749.         cyL = cyU = pRect->y + b;
  750.         (*paint)(color, alu, pm, pRect->x, cyU, pRect->width, 1) ;
  751.         }
  752.     else
  753.         {
  754.         cyU = pRect->y + b;
  755.         cyL = pRect->y + b + 1;
  756.         (*paint)(color, alu, pm, pRect->x, cyU, pRect->width, 2) ;
  757.         }
  758.  
  759.     ComputeQuad(a,b);
  760.  
  761.     for( nspans = nquadspans, ppt = quadPts, pwidth = quadWidths;
  762.             nspans > 0; nspans--, ppt++, pwidth++ )
  763.         {
  764.         xL = cxL - ppt->x - *pwidth + 1;
  765.         yU = cyU - ppt->y;
  766.         yL = cyL + ppt->y;
  767.         if ( cxL == cxR )
  768.             w = ( ( ppt->x + *pwidth - 1 ) << 1 ) + 1;
  769.         else
  770.             w = ( ( ppt->x + *pwidth - 1 ) << 1 ) + 2;
  771.  
  772.         (*paint)(color, alu, pm, xL, yU, w, 1);
  773.         (*paint)(color, alu, pm, xL, yL, w, 1);
  774.         }
  775.  
  776.     return ;
  777.     }
  778.  
  779. static void
  780. DrawFullArcOnSpans(pWindow, pGC, pRect)
  781.     WindowPtr    pWindow;
  782.     GCPtr        pGC;
  783.     xRectangle    *pRect;
  784.     {
  785.     int        cxL, cxR, cyL, cyU;
  786.     int        xR, xL, yU, yL;
  787.     MyPointPtr    pptInit, ppt, pptsrc, p1, p2, p3, p4;
  788.     int        nspans, *pwidthInit, *pwidth, *pwidthsrc;
  789.     int        i;
  790.     int        a, b;
  791.  
  792.     a = ( pRect->width - 1 ) >> 1;
  793.     b = ( pRect->height - 1 ) >> 1;
  794.     nspans = 0;
  795.  
  796.     ComputeQuad(a,b);
  797.  
  798.     /* allocate space for the spans */
  799.     pptInit = ppt = (MyPointPtr) Xalloc( ( ( 8 + nquadspans * 4 ) * sizeof(MyPointRec)));
  800.     if (ppt == 0)
  801.         {
  802.         ErrorF("ppcZeroCircle: DrawCircleOnSpans: cannot malloc ppt");
  803.         return ;
  804.         }
  805.  
  806.     pwidthInit = pwidth = (int *) Xalloc( ( ( 8 + nquadspans * 4 ) * sizeof(int)) );
  807.     if (pwidth == 0)
  808.         {
  809.         Xfree(ppt);
  810.         ErrorF("ppcZeroCircle: DrawCircleOnSpans: cannot malloc pwidth");
  811.         return ;
  812.         }
  813.  
  814.     /* take care of joining point of reflection; worry about Jeffshift */
  815.  
  816.     if ( pRect->width & 1)
  817.         {
  818.         cxL = cxR = pRect->x + a;
  819.  
  820.         ppt->x = cxL; ppt->y = pRect->y;
  821.         *pwidth = 1;
  822.         ppt++; pwidth++; nspans++;
  823.  
  824.         ppt->x = cxL; ppt->y = pRect->y + pRect->height - 1;
  825.         *pwidth = 1;
  826.         ppt++; pwidth++; nspans++;
  827.         }
  828.     else
  829.         {
  830.         cxL = pRect->x + a;
  831.         cxR = pRect->x + a + 1;
  832.         ppt->x = cxL; ppt->y = pRect->y;
  833.         *pwidth = 2;
  834.         ppt++; pwidth++; nspans++;
  835.  
  836.         ppt->x = cxL; ppt->y = pRect->y + pRect->height - 1;
  837.         *pwidth = 2;
  838.         ppt++; pwidth++; nspans++;
  839.         }
  840.  
  841.     if ( pRect->height & 1)
  842.         {
  843.         cyL = cyU = pRect->y + b;
  844.  
  845.         ppt->x = pRect->x; ppt->y = cyU;
  846.         *pwidth = 1;
  847.         ppt++; pwidth++; nspans++;
  848.  
  849.         ppt->x = pRect->x + pRect->width - 1; ppt->y = cyU;
  850.         *pwidth = 1;
  851.         ppt++; pwidth++; nspans++;
  852.         }
  853.     else
  854.         {
  855.         cyU = pRect->y + b;
  856.         cyL = pRect->y + b + 1;
  857.  
  858.         ppt->x = pRect->x; ppt->y = cyU;
  859.         *pwidth = 1;
  860.         ppt++; pwidth++; nspans++;
  861.         ppt->x = pRect->x; ppt->y = cyL;
  862.         *pwidth = 1;
  863.         ppt++; pwidth++; nspans++;
  864.  
  865.         ppt->x = pRect->x + pRect->width - 1; ppt->y = cyU;
  866.         *pwidth = 1;
  867.         ppt++; pwidth++; nspans++;
  868.         ppt->x = pRect->x + pRect->width - 1; ppt->y = cyL;
  869.         *pwidth = 1;
  870.         ppt++; pwidth++; nspans++;
  871.         }
  872.  
  873.     MOVE( quadWidths, pwidth, nquadspans * sizeof(int) );
  874.     pwidth += nquadspans;
  875.     MOVE( quadWidths, pwidth, nquadspans * sizeof(int) );
  876.     pwidth += nquadspans;
  877.     MOVE( quadWidths, pwidth, nquadspans * sizeof(int) );
  878.     pwidth += nquadspans;
  879.     MOVE( quadWidths, pwidth, nquadspans * sizeof(int) );
  880.  
  881.     for( i = nquadspans, p1 = ppt, p2 = p1 + nquadspans, 
  882.             p3 = p2 + nquadspans, p4 = p3 + nquadspans, 
  883.             pptsrc = quadPts, pwidthsrc = quadWidths; 
  884.         i > 0; 
  885.         i--, p1++, p2++, p3++, p4++, pptsrc++, pwidthsrc++ )
  886.         {
  887.  
  888.         xR = cxR + pptsrc->x;
  889.         xL = cxL - pptsrc->x - *pwidthsrc + 1;
  890.         yU = cyU - pptsrc->y ;
  891.         yL = cyL + pptsrc->y ;
  892.         /* Quadrant 1 */ p1->x = xR; p1->y = yU;
  893.         /* Quadrant 2 */ p2->x = xL; p2->y = yU;
  894.         /* Quadrant 3 */ p3->x = xL; p3->y = yL;
  895.         /* Quadrant 4 */ p4->x = xR; p4->y = yL;
  896.     
  897.         }
  898.  
  899.     (* pGC->ops->FillSpans)( pWindow, pGC, nspans + (nquadspans << 2), 
  900.                     pptInit, pwidthInit, FALSE );
  901.  
  902.     Xfree(pptInit);
  903.     Xfree(pwidthInit);
  904.  
  905.     return ;
  906.     }
  907.  
  908. static void
  909. FillFullArcOnSpans(pWindow, pGC, pRect)
  910.     WindowPtr    pWindow;
  911.     GCPtr        pGC;
  912.     xRectangle    *pRect;
  913.     {
  914.     int        cxL, cxR, cyL, cyU;
  915.     int        xL, yU, yL;
  916.     MyPointPtr    pptInit, ppt, pptsrc;
  917.     int        nspans, *pwidthInit, *pwidth, *pwidthsrc;
  918.     int        i;
  919.     int        a, b, w;
  920.  
  921.     a = ( pRect->width - 1 ) >> 1;
  922.     b = ( pRect->height - 1 ) >> 1;
  923.     nspans = 0;
  924.  
  925.     ComputeQuad(a,b);
  926.  
  927.     /* allocate space for the spans */
  928.     pptInit = ppt = (MyPointPtr) Xalloc( ( ( 8 + nquadspans * 2 ) * sizeof(MyPointRec)));
  929.     if (ppt == 0)
  930.         {
  931.         ErrorF("ppcZeroCircle: DrawCircleOnSpans: cannot malloc ppt");
  932.         return ;
  933.         }
  934.  
  935.     pwidthInit = pwidth = (int *) Xalloc( ( ( 8 + nquadspans * 2 ) * sizeof(int)) );
  936.     if (pwidth == 0)
  937.         {
  938.         Xfree(ppt);
  939.         ErrorF("ppcZeroCircle: DrawCircleOnSpans: cannot malloc pwidth");
  940.         return ;
  941.         }
  942.  
  943.     /* take care of joining point of reflection; worry about Jeffshift */
  944.  
  945.     if ( pRect->width & 1)
  946.         {
  947.         cxL = cxR = pRect->x + a;
  948.         }
  949.     else
  950.         {
  951.         cxL = pRect->x + a;
  952.         cxR = pRect->x + a + 1;
  953.         }
  954.  
  955.     if ( pRect->height & 1)
  956.         {
  957.         cyL = cyU = pRect->y + b;
  958.  
  959.         ppt->x = pRect->x; ppt->y = cyU;
  960.         *pwidth = pRect->width;
  961.         ppt++; pwidth++; nspans++;
  962.         }
  963.     else
  964.         {
  965.         cyU = pRect->y + b;
  966.         cyL = pRect->y + b + 1;
  967.  
  968.         ppt->x = pRect->x; ppt->y = cyU;
  969.         *pwidth = pRect->width;
  970.         ppt++; pwidth++; nspans++;
  971.         ppt->x = pRect->x; ppt->y = cyL;
  972.         *pwidth = pRect->width;
  973.         ppt++; pwidth++; nspans++;
  974.  
  975.         }
  976.  
  977.     for( i = nquadspans, pptsrc = quadPts, pwidthsrc = quadWidths; 
  978.         i > 0; 
  979.         i--, pptsrc++, pwidthsrc++ )
  980.         {
  981.  
  982.         xL = cxL - pptsrc->x - *pwidthsrc + 1;
  983.         yU = cyU - pptsrc->y ;
  984.         yL = cyL + pptsrc->y ;
  985.  
  986.         if ( cxL == cxR )
  987.             w = ( ( pptsrc->x + *pwidthsrc - 1 ) << 1 ) + 1;
  988.         else
  989.             w = ( ( pptsrc->x + *pwidthsrc - 1 ) << 1 ) + 2;
  990.  
  991.         ppt->x = xL; ppt->y = yU;
  992.         *pwidth = w;
  993.         ppt++; pwidth++;
  994.  
  995.         ppt->x = xL; ppt->y = yL;
  996.         *pwidth = w;
  997.         ppt++; pwidth++;
  998.         }
  999.  
  1000.     (* pGC->ops->FillSpans)( pWindow, pGC, nspans + (nquadspans << 1), 
  1001.                     pptInit, pwidthInit, FALSE );
  1002.  
  1003.     Xfree(pptInit);
  1004.     Xfree(pwidthInit);
  1005.  
  1006.     return ;
  1007.     }
  1008.  
  1009. static void
  1010. DrawArcOnSpans(pWindow, pGC, pArc)
  1011. WindowPtr    pWindow;
  1012. GCPtr        pGC;
  1013. xArc        *pArc;
  1014. {
  1015. int        cxL, cxR, cyL, cyU;
  1016. int        xR, xL, yU, yL;
  1017. MyPointPtr    pptInit, ppt, pptsrc, p1, p2, p3, p4;
  1018. int        nspans, *pwidthInit, *pwidth, *pwidthsrc;
  1019. int        i;
  1020. int        aQuad, bQuad;
  1021. MyPointRec    pta, ptb;
  1022. int        shortArc = 0, longArc = 0;
  1023. int        q, tmpspans, *tmppwidth;
  1024. int        topPt = 0, botPt = 0;
  1025. int        leftPt = 0, rightPt = 0;
  1026. int        x1, x2, y1, y2;
  1027. int        a, b;
  1028.  
  1029. x2 = (x1 = pWindow->drawable.x + pArc->x) + pArc->width -1;
  1030. y2 = (y1 = pWindow->drawable.y + pArc->y) + pArc->height -1;
  1031.  
  1032. a = ( pArc->width - 1 ) >> 1;
  1033. b = ( pArc->height - 1 ) >> 1;
  1034.  
  1035. if ( pArc->width & 1)
  1036.     {
  1037.     cxL = cxR = pArc->x + a;
  1038.     }
  1039. else
  1040.     {
  1041.     cxL = pArc->x + a;
  1042.     cxR = pArc->x + a + 1;
  1043.     }
  1044.  
  1045. if ( pArc->height & 1)
  1046.     {
  1047.     cyL = cyU = pArc->y + b;
  1048.     }
  1049. else
  1050.     {
  1051.     cyU = pArc->y + b;
  1052.     cyL = pArc->y + b + 1;
  1053.     }
  1054.  
  1055. ComputeQuad( a, b );
  1056.  
  1057. /* allocate space for the spans */
  1058. pptInit = ppt = (MyPointPtr) Xalloc( ( ( 6 + nquadspans * 4 ) * sizeof(MyPointRec)));
  1059. if (ppt == 0)
  1060.     {
  1061.     ErrorF("ppcZeroCircle: DrawCArcOnSpans: cannot malloc ppt");
  1062.     return ;
  1063.     }
  1064.  
  1065. pwidthInit = pwidth = (int *) Xalloc( ( ( 6 + nquadspans * 4 ) * sizeof(int)) );
  1066. if (pwidth == 0)
  1067.     {
  1068.     Xfree(ppt);
  1069.     ErrorF("ppcZeroCircle: DrawCArcOnSpans: cannot malloc pwidth");
  1070.     return ;
  1071.     }
  1072.  
  1073. nspans = 0;
  1074.  
  1075. GetPts(pArc, &pta, &ptb);
  1076.  
  1077. if ( pta.x > a )
  1078.     pta.x = a;
  1079. if ( pta.y > b )
  1080.     pta.y = b;
  1081.  
  1082. if ( ptb.x > a )
  1083.     ptb.x = a;
  1084. if ( ptb.y > b )
  1085.     ptb.y = b;
  1086.  
  1087. #define QUAD(X,Y) (((X)>=0) ? ((Y)>0 ? 4 : 1) : ((Y)>0 ? 3:2))
  1088.  
  1089. aQuad = QUAD(pta.x, pta.y);
  1090. bQuad = QUAD(ptb.x, ptb.y);
  1091.  
  1092. /*
  1093. printf("a = (%d,%d), b = (%d,%d)\n", pta.x, pta.y, ptb.x, ptb.y );
  1094. printf("aQuad = %d, bQuad = %d\n", aQuad, bQuad);
  1095. */
  1096.  
  1097. if ( bQuad == aQuad )
  1098.     {
  1099.     if ( pta.y > 0 )
  1100.         {
  1101.         if( pta.x > ptb.x )
  1102.             {
  1103.             longArc = 1;
  1104.             }
  1105.         else
  1106.             shortArc = 1;
  1107.         }
  1108.     else
  1109.         {
  1110.         if( pta.x < ptb.x )
  1111.             {
  1112.             longArc = 1;
  1113.             }
  1114.         else
  1115.             shortArc = 1;
  1116.         }
  1117.     }
  1118.  
  1119. if( shortArc ) /* arc is within one quadrant */
  1120.     {
  1121. /*
  1122. printf("shortArc\n");
  1123. */
  1124.     switch( aQuad )
  1125.         {
  1126.         case 1:
  1127.             pptsrc = quadPts + b - MAX(-pta.y, -ptb.y);
  1128.             pwidthsrc = quadWidths + b - MAX(-pta.y, -ptb.y);
  1129.             nspans = ABS( pta.y - ptb.y ) + 1;
  1130.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++ )
  1131.                 {
  1132.                 ppt->x = cxR + pptsrc->x;
  1133.                 ppt->y = cyU - pptsrc->y;
  1134.                 }
  1135.             break;
  1136.         case 2:
  1137.             pptsrc = quadPts + b - MAX(-pta.y, -ptb.y);
  1138.             pwidth = pwidthsrc = quadWidths + b - MAX(-pta.y, -ptb.y);
  1139.             nspans = ABS( pta.y - ptb.y ) + 1;
  1140.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++, pwidth++ )
  1141.                 {
  1142.                 ppt->x = cxL - pptsrc->x - *pwidth + 1;
  1143.                 ppt->y = cyU - pptsrc->y;
  1144.                 }
  1145.             break;
  1146.         case 3:
  1147.             pptsrc = quadPts + b - MAX(pta.y, ptb.y);
  1148.             pwidth = pwidthsrc = quadWidths + b - MAX(pta.y, ptb.y);
  1149.             nspans = ABS( pta.y - ptb.y ) + 1;
  1150.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++, pwidth++ )
  1151.                 {
  1152.                 ppt->x = cxL - pptsrc->x - *pwidth + 1;
  1153.                 ppt->y = cyL + pptsrc->y;
  1154.                 }
  1155.             break;
  1156.         case 4:
  1157.             pptsrc = quadPts + b - MAX(pta.y, ptb.y);
  1158.             pwidthsrc = quadWidths + b - MAX(pta.y, ptb.y);
  1159.             nspans = ABS( pta.y - ptb.y ) + 1;
  1160.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++, pwidth++ )
  1161.                 {
  1162.                 ppt->x = cxR + pptsrc->x;
  1163.                 ppt->y = cyL + pptsrc->y;
  1164.                 }
  1165.             break;
  1166.         }
  1167.     (* pGC->ops->FillSpans)( pWindow, pGC, nspans, pptInit, pwidthsrc, FALSE );
  1168.     
  1169.     }
  1170. else if ( longArc )
  1171.     {
  1172. /*
  1173. printf("longArc\n");
  1174. */
  1175.  
  1176.     /* take care of joining point of reflection; worry about Jeffshift */
  1177.     ppt->x = x1; ppt->y = cyU; *pwidth = 1;
  1178.     ppt++; pwidth++;
  1179.     ppt->x = x2; ppt->y = cyU; *pwidth = 1;
  1180.     ppt++; pwidth++;
  1181.  
  1182.     if (cxL == cxR)
  1183.         {
  1184.         ppt->x = cxL; ppt->y = y1; *pwidth = 1;
  1185.         ppt++; pwidth++;
  1186.         ppt->x = cxL; ppt->y = y2; *pwidth = 1;
  1187.         ppt++; pwidth++;
  1188.         nspans = 4;
  1189.         }
  1190.     else 
  1191.         {  /* Jeffshift */
  1192.         ppt->x = cxL; ppt->y = y1; *pwidth = 2;
  1193.         ppt++; pwidth++;
  1194.         ppt->x = cxL; ppt->y = y2; *pwidth = 2;
  1195.         ppt++; pwidth++;
  1196.         ppt->x = x1; ppt->y = cyL; *pwidth = 1;
  1197.         ppt++; pwidth++;
  1198.         ppt->x = x2; ppt->y = cyL; *pwidth = 1;
  1199.         ppt++; pwidth++;
  1200.         nspans = 6;
  1201.         }
  1202.  
  1203.     MOVE( quadWidths, pwidth, nquadspans * sizeof(int) );
  1204.     pwidth += nquadspans;
  1205.     MOVE( quadWidths, pwidth, nquadspans * sizeof(int) );
  1206.     pwidth += nquadspans;
  1207.     MOVE( quadWidths, pwidth, nquadspans * sizeof(int) );
  1208.     pwidth += nquadspans;
  1209.  
  1210.     nspans = nquadspans * 3 + nspans;
  1211.  
  1212.     switch ( aQuad )
  1213.         {
  1214.         case 1:
  1215.             for( i = nquadspans, p2 = ppt,
  1216.                     p3 = p2 + nquadspans,
  1217.                     p4 = p3 + nquadspans,
  1218.                     p1 = p4 + nquadspans,
  1219.                     pptsrc = quadPts,
  1220.                     pwidthsrc = quadWidths;
  1221.                 i > 0;
  1222.                 i--, p2++, p3++, p4++, pptsrc++,
  1223.                     pwidthsrc++ )
  1224.                 {
  1225.  
  1226.                 xR = cxR + pptsrc->x;
  1227.                 xL = cxL - pptsrc->x - *pwidthsrc + 1;
  1228.                 yU = cyU - pptsrc->y ;
  1229.                 yL = cyL + pptsrc->y ;
  1230.                 /* Quadrant 2 */ p2->x = xL; p2->y = yU;
  1231.                 /* Quadrant 3 */ p3->x = xL; p3->y = yL;
  1232.                 /* Quadrant 4 */ p4->x = xR; p4->y = yL;
  1233.                 if ( ( (-(pptsrc->y)) < MIN(pta.y, ptb.y) ) 
  1234.                     || ( (-(pptsrc->y)) > MAX(pta.y, ptb.y) ) )
  1235.                     {
  1236.                     /* Quadrant 1 */ 
  1237.                     p1->x = xR; p1->y = yU;
  1238.                     p1++;
  1239.                     *pwidth = *pwidthsrc;
  1240.                     pwidth++;
  1241.                     nspans++;
  1242.                     }
  1243.                 }
  1244.             break;
  1245.  
  1246.         case 2:
  1247.             for( i = nquadspans, p1 = ppt,
  1248.                     p3 = p1 + nquadspans,
  1249.                     p4 = p3 + nquadspans,
  1250.                     p2 = p4 + nquadspans,
  1251.                     pptsrc = quadPts,
  1252.                     pwidthsrc = quadWidths;
  1253.                 i > 0;
  1254.                 i--, p1++, p3++, p4++, pptsrc++,
  1255.                     pwidthsrc++ )
  1256.                 {
  1257.  
  1258.                 xR = cxR + pptsrc->x;
  1259.                 xL = cxL - pptsrc->x - *pwidthsrc + 1;
  1260.                 yU = cyU - pptsrc->y ;
  1261.                 yL = cyL + pptsrc->y ;
  1262.                 /* Quadrant 1 */ p1->x = xR; p1->y = yU;
  1263.                 /* Quadrant 3 */ p3->x = xL; p3->y = yL;
  1264.                 /* Quadrant 4 */ p4->x = xR; p4->y = yL;
  1265.                 if ( ( (-(pptsrc->y)) < MIN(pta.y, ptb.y) ) 
  1266.                     || ( (-(pptsrc->y)) > MAX(pta.y, ptb.y) ) )
  1267.                     {
  1268.                     /* Quadrant 2 */ 
  1269.                     p2->x = xL; p2->y = yU;
  1270.                     p2++;
  1271.                     *pwidth = *pwidthsrc;
  1272.                     pwidth++;
  1273.                     nspans++;
  1274.                     }
  1275.                 }
  1276.             break;
  1277.  
  1278.         case 3:
  1279.             for( i = nquadspans, p1 = ppt,
  1280.                     p2 = p1 + nquadspans,
  1281.                     p4 = p2 + nquadspans,
  1282.                     p3 = p4 + nquadspans,
  1283.                     pptsrc = quadPts,
  1284.                     pwidthsrc = quadWidths;
  1285.                 i > 0;
  1286.                 i--, p1++, p2++, p4++, pptsrc++,
  1287.                     pwidthsrc++ )
  1288.                 {
  1289.  
  1290.                 xR = cxR + pptsrc->x;
  1291.                 xL = cxL - pptsrc->x - *pwidthsrc + 1;
  1292.                 yU = cyU - pptsrc->y ;
  1293.                 yL = cyL + pptsrc->y ;
  1294.                 /* Quadrant 1 */ p1->x = xR; p1->y = yU;
  1295.                 /* Quadrant 2 */ p2->x = xL; p2->y = yU;
  1296.                 /* Quadrant 4 */ p4->x = xR; p4->y = yL;
  1297.                 if ( ( pptsrc->y < MIN(pta.y, ptb.y) ) 
  1298.                     || ( pptsrc->y > MAX(pta.y, ptb.y) ) )
  1299.                     {
  1300.                     /* Quadrant 3 */ 
  1301.                     p3->x = xL; p3->y = yL;
  1302.                     p3++;
  1303.                     *pwidth = *pwidthsrc;
  1304.                     pwidth++;
  1305.                     nspans++;
  1306.                     }
  1307.                 }
  1308.             break;
  1309.             
  1310.         case 4:
  1311.             for( i = nquadspans, p1 = ppt,
  1312.                     p2 = p1 + nquadspans,
  1313.                     p3 = p2 + nquadspans,
  1314.                     p4 = p3 + nquadspans,
  1315.                     pptsrc = quadPts,
  1316.                     pwidthsrc = quadWidths;
  1317.                 i > 0;
  1318.                 i--, p1++, p2++, p3++, pptsrc++,
  1319.                     pwidthsrc++ )
  1320.                 {
  1321.  
  1322.                 xR = cxR + pptsrc->x;
  1323.                 xL = cxL - pptsrc->x - *pwidthsrc + 1;
  1324.                 yU = cyU - pptsrc->y ;
  1325.                 yL = cyL + pptsrc->y ;
  1326.                 /* Quadrant 1 */ p1->x = xR; p1->y = yU;
  1327.                 /* Quadrant 2 */ p2->x = xL; p2->y = yU;
  1328.                 /* Quadrant 3 */ p3->x = xL; p3->y = yL;
  1329.                 if ( ( pptsrc->y < MIN(pta.y, ptb.y) ) 
  1330.                     || ( pptsrc->y > MAX(pta.y, ptb.y) ) )
  1331.                     {
  1332.                     /* Quadrant 4 */ 
  1333.                     p4->x = xR; p4->y = yL;
  1334.                     p4++;
  1335.                     *pwidth = *pwidthsrc;
  1336.                     pwidth++;
  1337.                     nspans++;
  1338.                     }
  1339.                 }
  1340.             break;
  1341.  
  1342.         }
  1343.     (* pGC->ops->FillSpans)( pWindow, pGC, nspans, pptInit, pwidthInit, FALSE );
  1344.     }
  1345. else /* start and end of arc are not in same quadrant */
  1346.     {
  1347. /*
  1348. printf("mediumArc\n");
  1349. */
  1350.     /* first we draw the starting part of the arc */
  1351.     switch ( aQuad )
  1352.         {
  1353.         case 1:
  1354.             pptsrc = quadPts;
  1355.             pwidthsrc = quadWidths;
  1356.             nspans = MIN(pta.y + b + 1, b);
  1357.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++ )
  1358.                 {
  1359.                 ppt->x = cxR + pptsrc->x;
  1360.                 ppt->y = cyU - pptsrc->y;
  1361.                 }
  1362.             topPt = 1;
  1363.             break;
  1364.         case 2:
  1365.             pptsrc = quadPts + b + pta.y;
  1366.             tmppwidth = pwidthsrc = quadWidths + b + pta.y;
  1367.             nspans = -pta.y;
  1368.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++, tmppwidth++ )
  1369.                 {
  1370.                 ppt->x = cxL - pptsrc->x - *tmppwidth + 1;
  1371.                 ppt->y = cyU - pptsrc->y;
  1372.                 }
  1373.             leftPt = 1;
  1374.             break;
  1375.         case 3:
  1376.             pptsrc = quadPts;
  1377.             tmppwidth = pwidthsrc = quadWidths;
  1378.             nspans = MIN(b - pta.y + 1, b);
  1379.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++, tmppwidth++ )
  1380.                 {
  1381.                 ppt->x = cxL - pptsrc->x - *tmppwidth + 1;
  1382.                 ppt->y = cyL + pptsrc->y;
  1383.                 }
  1384.             botPt = 1;
  1385.             break;
  1386.         case 4:
  1387.             pptsrc = quadPts + b - pta.y;
  1388.             pwidthsrc = quadWidths + b - pta.y;
  1389.             nspans = pta.y;
  1390.             for ( i = 0; i < nspans; i++, pptsrc++, ppt++ )
  1391.                 {
  1392.                 ppt->x = cxR + pptsrc->x;
  1393.                 ppt->y = cyL + pptsrc->y;
  1394.                 }
  1395.             rightPt = 1;
  1396.             break;
  1397.         }
  1398. /*
  1399.     printf("medium: first move\n");
  1400. */
  1401.  
  1402.     MOVE( pwidthsrc, pwidth, nspans * sizeof(int) );
  1403.     pwidth += nspans;
  1404.  
  1405. #ifdef notdef
  1406.     if ( ( *( pwidth - 1 ) ) > 5 )
  1407.         {
  1408.     printf("ppt->x = %d, ppt->y = %d, *pwidth = %d\n", 
  1409.         (ppt-1)->x, (ppt-1)->y, *(pwidth-1) );
  1410.     printf("medium: first move\n");
  1411.     printf("aQuad = %d\n", aQuad);
  1412.     printf("pwidthsrc = 0x%x, pwidth = 0x%x, nspans = %d\n",
  1413.         pwidthsrc, pwidth, nspans );
  1414.     printf("a = %d, b = %d, pta = (%d,%d)\n", a, b, pta.x, pta.y);
  1415.         }
  1416. #endif
  1417.  
  1418.     /* next we draw the end of the arc */
  1419.     switch ( bQuad)
  1420.         {
  1421.         case 1:
  1422.             pptsrc = quadPts + b + ptb.y;
  1423.             pwidthsrc = quadWidths + b + ptb.y;
  1424.             tmpspans = -ptb.y;
  1425.             for ( i = 0; i < tmpspans; i++, pptsrc++, ppt++ )
  1426.                 {
  1427.                 ppt->x = cxR + pptsrc->x;
  1428.                 ppt->y = cyU - pptsrc->y;
  1429.                 }
  1430.             rightPt = 1;
  1431.             break;
  1432.         case 2:
  1433.             pptsrc = quadPts;
  1434.             tmppwidth = pwidthsrc = quadWidths;
  1435.             tmpspans = MIN(b + ptb.y + 1, b);
  1436.             for ( i = 0; i < tmpspans; i++, pptsrc++, ppt++, tmppwidth++ )
  1437.                 {
  1438.                 ppt->x = cxL - pptsrc->x - *tmppwidth + 1;
  1439.                 ppt->y = cyU - pptsrc->y;
  1440.                 }
  1441.             topPt = 1;
  1442.             break;
  1443.         case 3:
  1444.             pptsrc = quadPts + b - ptb.y;
  1445.             tmppwidth = pwidthsrc = quadWidths + b - ptb.y;
  1446.             tmpspans = ptb.y;
  1447.             for ( i = 0; i < tmpspans; i++, pptsrc++, ppt++, tmppwidth++ )
  1448.                 {
  1449.                 ppt->x = cxL - pptsrc->x - *tmppwidth + 1;
  1450.                 ppt->y = cyL + pptsrc->y;
  1451.                 }
  1452.             leftPt = 1;
  1453.             break;
  1454.         case 4:
  1455.             pptsrc = quadPts;
  1456.             pwidthsrc = quadWidths;
  1457.             tmpspans = MIN(b - ptb.y + 1, b);
  1458.             for ( i = 0; i < tmpspans; i++, pptsrc++, ppt++ )
  1459.                 {
  1460.                 ppt->x = cxR + pptsrc->x;
  1461.                 ppt->y = cyL + pptsrc->y;
  1462.                 }
  1463.             botPt = 1;
  1464.             break;
  1465.         }
  1466.  
  1467.  
  1468.  
  1469.     MOVE( pwidthsrc, pwidth, tmpspans * sizeof(int) );
  1470.     pwidth += tmpspans;
  1471.     nspans += tmpspans;
  1472.  
  1473. #ifdef notdef
  1474.     if ( ( *( pwidth - 1 ) ) > 5 )
  1475.         {
  1476.     printf("ppt->x = %d, ppt->y = %d, *pwidth = %d\n", 
  1477.         (ppt-1)->x, (ppt-1)->y, *(pwidth-1) );
  1478.     printf("medium: second move\n");
  1479.     printf("bQuad = %d\n", bQuad);
  1480.     printf("pwidthsrc = 0x%x, pwidth = 0x%x, tmpspans = %d\n",
  1481.         pwidthsrc, pwidth, tmpspans );
  1482.     printf("a = %d, b = %d, ptb = (%d,%d)\n", a, b, ptb.x, ptb.y);
  1483.         }
  1484. #endif
  1485.  
  1486.     
  1487.     /*
  1488.      * Fill the whole quads.
  1489.      */
  1490.     q = aQuad + 1;
  1491.     if ( q == 5 ) q = 1;
  1492.     while ( q != bQuad )
  1493.         {
  1494.         switch ( q )
  1495.             {
  1496.             case 1:
  1497.                 pptsrc = quadPts;
  1498.                 pwidthsrc = quadWidths;
  1499.                 for ( i = 0; i < nquadspans; i++, pptsrc++, ppt++ )
  1500.                     {
  1501.                     ppt->x = cxR + pptsrc->x;
  1502.                     ppt->y = cyU - pptsrc->y;
  1503.                     }
  1504.                 topPt = 1;
  1505.                 rightPt = 1;
  1506.                 break;
  1507.             case 2:
  1508.                 pptsrc = quadPts;
  1509.                 tmppwidth = pwidthsrc = quadWidths;
  1510.                 for ( i = 0; i < nquadspans; i++, pptsrc++, ppt++, tmppwidth++ )
  1511.                     {
  1512.                     ppt->x = cxL - pptsrc->x - *tmppwidth + 1;
  1513.                     ppt->y = cyU - pptsrc->y;
  1514.                     }
  1515.                 topPt = 1;
  1516.                 leftPt = 1;
  1517.                 break;
  1518.             case 3:
  1519.                 pptsrc = quadPts;
  1520.                 tmppwidth = pwidthsrc = quadWidths;
  1521.                 for ( i = 0; i < nquadspans; i++, pptsrc++, ppt++, tmppwidth++ )
  1522.                     {
  1523.                     ppt->x = cxL - pptsrc->x - *tmppwidth + 1;
  1524.                     ppt->y = cyL + pptsrc->y;
  1525.                     }
  1526.                 botPt = 1;
  1527.                 leftPt = 1;
  1528.                 break;
  1529.             case 4:
  1530.                 pptsrc = quadPts;
  1531.                 pwidthsrc = quadWidths;
  1532.                 for ( i = 0; i < nquadspans; i++, pptsrc++, ppt++ )
  1533.                     {
  1534.                     ppt->x = cxR + pptsrc->x;
  1535.                     ppt->y = cyL + pptsrc->y;
  1536.                     }
  1537.                 botPt = 1;
  1538.                 rightPt = 1;
  1539.                 break;
  1540.             }
  1541. /*
  1542.         printf("medium: third move\n");
  1543. */
  1544.         MOVE( pwidthsrc, pwidth, nquadspans * sizeof(int) );
  1545.         pwidth += nquadspans;
  1546.         nspans += nquadspans;
  1547.  
  1548.         q++;
  1549.         if ( q == 5 ) q = 1;
  1550.         }
  1551.  
  1552.     /* take care of joining point of reflection; worry about Jeffshift */
  1553.  
  1554.  
  1555.     if (cxL == cxR)
  1556.         {
  1557.         if ( topPt )
  1558.             {
  1559.             ppt->x = cxL; ppt->y = y1; *pwidth = 1;
  1560.             ppt++; pwidth++;
  1561.             nspans++;
  1562.             }
  1563.         if ( botPt )
  1564.             {
  1565.             ppt->x = cxL; ppt->y = y2; *pwidth = 1;
  1566.             ppt++; pwidth++;
  1567.             nspans++;
  1568.             }
  1569.         }
  1570.     else 
  1571.         {  /* Jeffshift */
  1572.         if ( topPt )
  1573.             {
  1574.             ppt->x = cxL; ppt->y = y1; *pwidth = 2;
  1575.             ppt++; pwidth++;
  1576.             nspans++;
  1577.             }
  1578.         if ( botPt )
  1579.             {
  1580.             ppt->x = cxL; ppt->y = y2; *pwidth = 2;
  1581.             ppt++; pwidth++;
  1582.             nspans++;
  1583.             }
  1584.         }
  1585.     if ( cyU == cyL )
  1586.         {  /* no jeffshift */
  1587.         if ( leftPt )
  1588.             {
  1589.             ppt->x = x1; ppt->y = cyL; *pwidth = 1;
  1590.             ppt++; pwidth++;
  1591.             nspans++;
  1592.             }
  1593.         if ( rightPt )
  1594.             {
  1595.             ppt->x = x2; ppt->y = cyL; *pwidth = 1;
  1596.             ppt++; pwidth++;
  1597.             nspans++;
  1598.             }
  1599.         }
  1600.     else
  1601.         {  /* jeffshift */
  1602.         if ( leftPt )
  1603.             {
  1604.             ppt->x = x1; ppt->y = cyL; *pwidth = 1;
  1605.             ppt++; pwidth++;
  1606.             nspans++;
  1607.             ppt->x = x1; ppt->y = cyU; *pwidth = 1;
  1608.             ppt++; pwidth++;
  1609.             nspans++;
  1610.             }
  1611.         if ( rightPt )
  1612.             {
  1613.             ppt->x = x2; ppt->y = cyL; *pwidth = 1;
  1614.             ppt++; pwidth++;
  1615.             nspans++;
  1616.             ppt->x = x2; ppt->y = cyU; *pwidth = 1;
  1617.             ppt++; pwidth++;
  1618.             nspans++;
  1619.             }
  1620.  
  1621.         }
  1622.     (* pGC->ops->FillSpans)( pWindow, pGC, nspans, pptInit, pwidthInit, FALSE );
  1623.     }
  1624.  
  1625. Xfree(pptInit);
  1626. Xfree(pwidthInit);
  1627.  
  1628. return ;
  1629. }
  1630.