/*-----------------------------------------------------------------------*/
/*                                 TIGA                                  */
/*       Copyright (c) 1987-1990 Texas Instruments Incorporated.         */
/*                         All Rights Reserved                           */
/*-----------------------------------------------------------------------*/
/*  TIGA - Graphics Manager Extension                                    */
/*-----------------------------------------------------------------------*/
/*                                                                       */
/* patnfill_piearc and fill_piearc functions                             */
/*                                                                       */
/*   The fill_piearc function draws a solid-filled pie-shaped wedge of   */
/*   an ellipse.  The patnfill_piearc function drawn a pattern-filled    */
/*   pie-shaped wedge of an ellipse.                                     */
/*                                                                       */
/*   The pie wedge is taken from the ellipse inscribed within the        */
/*   specified minimum enclosing rectangle.  The rectangle is described  */
/*   in terms of its width w, height h, and the x-y coordinates at its   */
/*   top left corner, (xleft,ytop).  The arc is specified in terms of a  */
/*   starting angle, tstart, and an arc extent angle, tarc.  Both angles */
/*   are specified in degrees of elliptical arc, with 360 degrees being  */
/*   one entire rotation.                                                */
/*---------------------------------------------------------------------- */
/* Usage:  fill_piearc(w, h, xleft, ytop, tstart, tarc);                 */
/*                                                                       */
/* Description of the arguments:                                         */
/*   long w, h;  { width and height of min. enclosing rect. for oval }   */
/*   long xleft, ytop;  { coordinates of left and top side of rect. }    */
/*   long tstart;  { arc starting angle, in degrees of elliptical arc }  */
/*   long tarc;  { arc extent angle, in degrees of elliptical arc }      */
/*-----------------------------------------------------------------------*/
/* Revision history:                                                     */
/*   1/29/87...Original version written...................Jerry Van Aken */
/*   6/17/87...Redefined arc start and end points.........Jerry Van Aken */
/*   9/16/88...Added TIGA direct mode and dstbm check.....Graham Short   */
/*   4/20/89...Replace fill_polygon calls w/ fill_convex..Jerry Van Aken */
/*   3/23/90...Decremented first arg to fill_convex.......Jerry Van Aken */
/*-----------------------------------------------------------------------*/

#define TRUE       1
#define FALSE      0
#define is_odd    &1

#include <gsptypes.h>
#include <gspglobs.h>

 /* Declare external functions */
 extern void arc_fill();
 extern void onarc();

 static struct params *p, myparams;
 static int patnfill;  /* TRUE if patnfill_piearc; else FALSE */
 static long w, h;  /* width and height of ellipse's enclosing rect */
 static long xleft, ytop;  /* top left corner of enclosing rectangle */
 static long tstart, tarc;  /* user-specified arc start and extent */
 static long xc, yc;  /* center of oval relative to encl. retangle */

 /*-------------------- fill_piearc() --------------------------*/

 fill_piearc(arg1, arg2, arg3, arg4, arg5, arg6)
 long arg1, arg2, arg3, arg4, arg5, arg6;
 {
    patnfill = FALSE;
    w      = arg1;
    h      = arg2;
    xleft  = arg3;
    ytop   = arg4;
    tstart = arg5;
    tarc   = arg6;
    fill_eliparc();
 }

 dm_fill_piearc(data_ptr)
 short *data_ptr;
 {
    patnfill = FALSE;
    w      = *data_ptr++;
    h      = *data_ptr++;
    xleft  = *data_ptr++;
    ytop   = *data_ptr++;
    tstart = *data_ptr++;
    tarc   = *data_ptr;
    fill_eliparc();
}

 /*------------------ patnfill_piearc() ------------------------*/

 patnfill_piearc(arg1, arg2, arg3, arg4, arg5, arg6)
 long arg1, arg2, arg3, arg4, arg5, arg6;
 {
    patnfill = TRUE;
    w      = arg1;
    h      = arg2;
    xleft  = arg3;
    ytop   = arg4;
    tstart = arg5;
    tarc   = arg6;
    fill_eliparc();
 }

 dm_patnfill_piearc(data_ptr)
 short *data_ptr;
 {
    patnfill = TRUE;
    w      = *data_ptr++;
    h      = *data_ptr++;
    xleft  = *data_ptr++;
    ytop   = *data_ptr++;
    tstart = *data_ptr++;
    tarc   = *data_ptr;
    fill_eliparc();
}

 /*-------------------- fill_eliparc() --------------------------*/

 fill_eliparc()
 {
    long qs, qe;  /* start and end quadrants (q = 0, 1, 2 or 3) */
    long q;       /* current quadrant of ellipse */
    long qtemp;
    /* Coordinates specified relative to top left corner of minimum
     * enclosing rectangle for ellipse.
     */
    long xs, ys;  /* arc start point coordinates */
    long xe, ye;  /* arc end point coordinates */

    /* abort if the drawing bitmap is not pointing to the screen */
    if( env.dstbm )
         return;

    p = &myparams;
    p->width = w;
    p->height = h;
    p->patn = patnfill;

    /* Convert starting angle and arc angle to start and end points. */
    if (tarc >= 0) {
        onarc(w, h,      tstart, &xs, &ys, &qs);
        onarc(w, h, tstart+tarc, &xe, &ye, &qe);
    } else {
        onarc(w, h, tstart+tarc, &xs, &ys, &qs);
        onarc(w, h,      tstart, &xe, &ye, &qe);
    }

    /* calculate center point of oval */
    xc = w >> 1;
    yc = h >> 1;

    /* fill pie-shaped wedge defined by arc */
    if (qs == qe && tarc < 180 && tarc > -180)
         /* Entire arc is contained within a single quadrant. */
         if (qs is_odd)
            arc_slice(qs, xs, ys, xe, ye);
         else
            arc_slice(qs, xe, ye, xs, ys);
    else {            /* Arc spans more than one quadrant. */
        /* Draw portion of arc lying in starting quadrant qs. */
        switch (qs) {
        case 0:
                 arc_slice(qs, xc, h, xs, ys);
                 break;
        case 1:
                 arc_slice(qs, xs, ys, 0, yc);
                 break;
        case 2:
                 arc_slice(qs, xc, 0, xs, ys);
                 break;
        case 3:
                 arc_slice(qs, xs, ys, w, yc);
                 break;
        }
        /* draw portion of arc lying in ending quadrant qe */
        switch (qe) {
        case 0:
                 arc_slice(qe, xe, ye, w, yc);
                 break;
        case 1:
                 arc_slice(qe, xc, h, xe, ye);
                 break;
        case 2:
                 arc_slice(qe, xe, ye, 0, yc);
                 break;
        case 3:
                 arc_slice(qe, xc, 0, xe, ye);
                 break;
        }
        /* quadrants between qs and qe get filled in completely */
        if (qe <= qs)
            qe += 4;
        for (q = qs + 1; q < qe; ++q)
            switch (qtemp = (q & 3)) {
            case 0:
                     arc_slice(qtemp, xc, h, w, yc);
                     break;
            case 1:
                     arc_slice(qtemp, xc, h, 0, yc);
                     break;
            case 2:
                     arc_slice(qtemp, xc, 0, 0, yc);
                     break;
            case 3:
                     arc_slice(qtemp, xc, 0, w, yc);
                     break;
            }
    }
 }

 /*-------------------- arc_slice() --------------------------*/
 /* arc drawn from (xs,ys) to (xe,ye) within a single quadrant */

 arc_slice(q, xs, ys, xe, ye)
 long q;  /* quadrant number */
 long xs, ys;  /* arc start coordinates (relative to encl. rect.) */
 long xe, ye;  /* arc end coordinates (relative to encl. rect.) */
 {
    /* Coordinates given relative to top left corner of screen.
     * Assume arc is drawn clockwise from (x1,y1) to (x2,y2).
     */
    long x1, y1;  /* arc end point in clockwise direction */
    long x2, y2;  /* arc end point in counterclockwise direction */
    long xm, ym;  /* inside corner of arc fill region */
    short xy[10];

    if (q == 0 || q == 3) {         /* in quadrant 0 or 3 */
        p->deltax = 0;
        p->xcount = xe - xs;
        p->xnorm = xs;
    } else {                        /* in quadrant 1 or 2 */
        p->deltax = -1;
        p->xcount = xs - xe;
        p->xnorm = w - xs;
    }
    if (q < 2) {                    /* in quadrant 0 or 1 */
        p->deltay = -1;
        p->ycount = ys - ye;
        p->ynorm = ys;
    } else {                        /* in quadrant 2 or 3 */
        p->deltay = 1;
        p->ycount = ye - ys;
        p->ynorm = h - ys;
    }
    p->xcoord = xleft + xs;
    p->ycoord = ytop + ys;
    if (q is_odd) {                 /* in quadrant 1 or 3 */
        x1 = p->xcoord;
        y1 = p->ycoord;
        x2 = xleft + xe;
        y2 = ytop + ye;
        xm = x1;
        ym = y2;
    } else {                        /* in quadrant 0 or 2 */
        x1 = xleft + xe;
        y1 = ytop + ye;
        x2 = p->xcoord;
        y2 = p->ycoord;
        xm = x2;
        ym = y1;
    }
    xy[0] = xc + xleft;  /* Set up xy array for polygon fills */
    xy[1] = yc + ytop;
    xy[2] = x1;
    xy[3] = y1;
    xy[4] = xm;
    xy[5] = ym;
    xy[6] = x2;
    xy[7] = y2;
    xy[8] = xy[0];
    xy[9] = xy[1];
    if (patnfill)                /* Fill polygons with pattern */
    {
	patnfill_convex(3, xy);
	patnfill_convex(3, &xy[4]);
    }
    else                         /* Fill polygons with solid color */
    {
	fill_convex(3, xy);
	fill_convex(3, &xy[4]);
    }
    if (q < 2)                   /* Adjust starting y value if q=0,1 */
        --p->ycoord;
    arc_fill(p);                 /* Fill region bounded by arc */
 }



