Annotation of researchv9/X11/src/X.V11R1/server/ddx/mi/miarc.c, revision 1.1

1.1     ! root        1: /***********************************************************
        !             2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
        !             3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
        !             4: 
        !             5:                         All Rights Reserved
        !             6: 
        !             7: Permission to use, copy, modify, and distribute this software and its 
        !             8: documentation for any purpose and without fee is hereby granted, 
        !             9: provided that the above copyright notice appear in all copies and that
        !            10: both that copyright notice and this permission notice appear in 
        !            11: supporting documentation, and that the names of Digital or MIT not be
        !            12: used in advertising or publicity pertaining to distribution of the
        !            13: software without specific, written prior permission.  
        !            14: 
        !            15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            21: SOFTWARE.
        !            22: 
        !            23: ******************************************************************/
        !            24: /* $Header: miarc.c,v 1.46 87/08/31 16:39:34 toddb Exp $ */
        !            25: /* Author: Todd Newman */
        !            26: #include "X.h"
        !            27: #include "Xprotostr.h"
        !            28: #include "misc.h"
        !            29: #include "gcstruct.h"
        !            30: #include "scrnintstr.h"
        !            31: #include "pixmapstr.h"
        !            32: #include "windowstr.h"
        !            33: #include "mifpoly.h"
        !            34: 
        !            35: extern double sqrt(), cos(), sin(), atan();
        !            36: /* these are from our <math.h>, but I'm told some systems don't have
        !            37:  * math.h and that they're not in all versions of math.h.  Psi! */
        !            38: #define M_PI   3.14159265358979323846
        !            39: #define M_PI_2 1.57079632679489661923
        !            40: 
        !            41: 
        !            42: #define SAMESIGN(a, b)  ((((a) >= 0) && ((b) >= 0)) ||\
        !            43:                          (((a) <= 0) && ((b) <= 0)))
        !            44: 
        !            45: /* This contains the information needed to draw one arc of a polyarc.
        !            46:  * An array of them can be allocated if the polyarc has more than 1 part */
        !            47: typedef struct
        !            48: {
        !            49:     int                cpt;
        !            50:     DDXPointPtr        pPts;
        !            51: } POLYARCINFO;
        !            52: 
        !            53: #define GCValsFunction         0
        !            54: #define GCValsForeground       1
        !            55: #define GCValsBackground       2
        !            56: #define GCValsLineWidth        3
        !            57: #define GCValsCapStyle                 4
        !            58: #define GCValsJoinStyle                5
        !            59: #define GCValsArcMode          6
        !            60: static int gcvals[]= {GXcopy, 1, 0, 0, 0, 0, 0};
        !            61: 
        !            62: /* MIPOLYARC -- Public entry for the polyarc call.
        !            63:  * Strategy: Similar in many ways to that for wide lines.
        !            64:  * In general, we will each arc segment as a polyline. (We can make the arc
        !            65:  * arbitrarily smooth by increasing the number of segments and shortening
        !            66:  * the length of each segment.)
        !            67:  * If there's only 1 arc, or if the arc is draw with zero width lines, we 
        !            68:  * don't have to worry about the rasterop or join styles.   
        !            69:  * Otherwise, we set up pDrawTo and pGCTo according to the rasterop, then
        !            70:  * draw using pGCTo and pDrawTo.  If the raster-op was "tricky," that is,
        !            71:  * if it involves the destination, then we use PushPixels to move the bits
        !            72:  * from the scratch drawable to pDraw. (See the wide line code for a
        !            73:  * fuller explanation of this.)
        !            74:  */
        !            75: void
        !            76: miPolyArc(pDraw, pGC, narcs, parcs)
        !            77:     DrawablePtr        pDraw;
        !            78:     GCPtr      pGC;
        !            79:     int                narcs;
        !            80:     xArc       *parcs;
        !            81: {
        !            82:     register int               i, j;
        !            83:     register DDXPointPtr       ppt;    /* Points for the current arc */
        !            84:     register DDXPointPtr       pAllPts; /* Points for all arcs so far */
        !            85:     register int               cpt,    /* count of points in current arc */
        !            86:                                cptAll; /* count of points in all arcs */
        !            87:     DDXPointPtr                        pPts;   /* Points for the current arc */
        !            88:     int                                xMin, xMax, yMin, yMax, yOrg, xOrg, dx, dy,
        !            89:                                ifirst, ilast, count, gcmode, arcmode, width;
        !            90:     Bool                       fAllOne, fTricky;
        !            91:     PixmapPtr                  pDrawTo;
        !            92:     GCPtr                      pGCTo;
        !            93:     POLYARCINFO                *polyarcs;
        !            94:     DDXPointRec                        LastPt;
        !            95: 
        !            96: 
        !            97:     width = pGC->lineWidth;
        !            98:     if(width == 0 || narcs == 1)
        !            99:     {
        !           100:        /* don't have to worry about overlap or joinstyles */
        !           101:         for(i = 0; i < narcs; i++)
        !           102:        {
        !           103:            pPts = (DDXPointPtr)NULL;
        !           104:            if( cpt = miGetArcPts(&parcs[i], 0, &pPts))
        !           105:            {
        !           106:                (*pGC->Polylines)(pDraw, pGC, CoordModeOrigin, cpt, pPts);
        !           107:                Xfree(pPts);
        !           108:            }
        !           109:        }
        !           110:     }
        !           111:     else 
        !           112:     {
        !           113:        count = 0;
        !           114:        ifirst = 0;
        !           115:        fAllOne = FALSE;
        !           116:        pPts = (DDXPointPtr) NULL;
        !           117:        pAllPts = (DDXPointPtr) NULL;
        !           118:        polyarcs = (POLYARCINFO *)ALLOCATE_LOCAL(narcs * sizeof(POLYARCINFO));
        !           119:        if(!polyarcs)
        !           120:            return;
        !           121: 
        !           122:        xMin = yMin = MAXSHORT;
        !           123:        xMax = yMax = MINSHORT;
        !           124: 
        !           125:        /* Get all points for all the arcs. */
        !           126:        for(i = 0; i < narcs; i++)
        !           127:        {
        !           128:            pPts = (DDXPointPtr) NULL;
        !           129:            if((cpt = miGetArcPts(&parcs[i], 0, &pPts)) == 0)
        !           130:            {
        !           131:                /* One of the arcs was empty. Give up */
        !           132:                while(--i >= 0)
        !           133:                {
        !           134:                    Xfree(polyarcs[i].pPts);
        !           135:                }
        !           136:                DEALLOCATE_LOCAL(polyarcs);
        !           137:                return;
        !           138:            }
        !           139:            polyarcs[i].cpt = cpt;
        !           140:            polyarcs[i].pPts = pPts;
        !           141:            ppt = pPts;
        !           142:            for(j = 0; j < cpt; j++)
        !           143:            {
        !           144:                xMin = min(xMin, ppt->x);
        !           145:                yMin = min(yMin, ppt->y);
        !           146:                xMax = max(xMax, ppt->x);
        !           147:                yMax = max(yMax, ppt->y);
        !           148:                ppt++;
        !           149:            }
        !           150:        }
        !           151:        /* Set up pDrawTo and pGCTo based on the rasterop */
        !           152:        switch(pGC->alu)
        !           153:        {
        !           154:          case GXclear:         /* 0 */
        !           155:          case GXcopy:          /* src */
        !           156:          case GXcopyInverted:  /* NOT src */
        !           157:          case GXset:           /* 1 */
        !           158:            fTricky = FALSE;
        !           159:            pDrawTo = (PixmapPtr) pDraw;
        !           160:            pGCTo = pGC;
        !           161:            if(pGCTo->arcMode != ArcChord)
        !           162:            {
        !           163:                arcmode = pGCTo->arcMode;
        !           164:                DoChangeGC(pGCTo, GCArcMode, &gcvals[GCValsArcMode], 0);
        !           165:                ValidateGC(pDrawTo, pGCTo);
        !           166:            }
        !           167:            else
        !           168:                arcmode = ArcChord;
        !           169: 
        !           170:            break;
        !           171:          case GXand:           /* src AND dst */
        !           172:          case GXandReverse:    /* src AND NOT dst */
        !           173:          case GXandInverted:   /* NOT src AND dst */
        !           174:          case GXnoop:          /* dst */
        !           175:          case GXxor:           /* src XOR dst */
        !           176:          case GXor:            /* src OR dst */
        !           177:          case GXnor:           /* NOT src AND NOT dst */
        !           178:          case GXequiv:         /* NOT src XOR dst */
        !           179:          case GXinvert:                /* NOT dst */
        !           180:          case GXorReverse:             /* src OR NOT dst */
        !           181:          case GXorInverted:    /* NOT src OR dst */
        !           182:          case GXnand:          /* NOT src OR NOT dst */
        !           183:            fTricky = TRUE;
        !           184: 
        !           185:            pGCTo = GetScratchGC(1, pDraw->pScreen);
        !           186:            gcvals[GCValsLineWidth] = pGC->lineWidth;
        !           187:            gcvals[GCValsCapStyle] = pGC->capStyle;
        !           188:            gcvals[GCValsJoinStyle] = pGC->joinStyle;
        !           189: 
        !           190:            /* Also what about arcmode?? */
        !           191:            gcmode = GCFunction | GCForeground | GCBackground | GCLineWidth |
        !           192:                     GCCapStyle | GCJoinStyle;
        !           193:            DoChangeGC(pGCTo, gcmode, gcvals, 0);
        !           194:     
        !           195:            xOrg = xMin - (width + 1)/2;
        !           196:            yOrg = yMin - (width + 1)/2;
        !           197:            dx = xMax - xMin + width + 1;
        !           198:            dy = yMax - yMin + width + 1;
        !           199:            for(i = 0; i < narcs; i++)
        !           200:            {
        !           201:                cpt = polyarcs[i].cpt;
        !           202:                ppt = polyarcs[i].pPts;
        !           203:                for(j = 0; j < cpt; j++)
        !           204:                {
        !           205:                    ppt->x -= xOrg;
        !           206:                    ppt->y -= yOrg;
        !           207:                    ppt++;
        !           208:                }
        !           209:            }
        !           210: 
        !           211:            /* allocate a 1 bit deep pixmap of the appropriate size, and
        !           212:             * validate it */
        !           213:            pDrawTo = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
        !           214:              (pDraw->pScreen, dx, dy, 1, XYBitmap);
        !           215:            ValidateGC(pDrawTo, pGCTo);
        !           216:            miClearDrawable(pDrawTo, pGCTo);
        !           217:        }
        !           218: 
        !           219:        ilast = narcs - 1;
        !           220: 
        !           221:        /* If the last arc joins with the first, find all the final arcs
        !           222:         * that join together and join them with the initial ones.
        !           223:         */
        !           224:        if(PtEqual(polyarcs[0].pPts[0],
        !           225:                    polyarcs[ilast].pPts[polyarcs[ilast].cpt - 1]) )
        !           226:        {
        !           227:            count = 1;
        !           228:            while(PtEqual (polyarcs[ilast].pPts[0],
        !           229:              polyarcs[ilast - 1].pPts[polyarcs[ilast - 1].cpt - 1]) )
        !           230:            {
        !           231:                if(ilast <= 1)
        !           232:                {
        !           233:                    fAllOne = TRUE;
        !           234:                    break;
        !           235:                }
        !           236:                else
        !           237:                {
        !           238:                    ilast--;
        !           239:                    count++;
        !           240:                }
        !           241:            }
        !           242:            if(!fAllOne)
        !           243:            {
        !           244:                while(PtEqual(polyarcs[ifirst].pPts[polyarcs[ifirst].cpt -1],
        !           245:                              polyarcs[ifirst + 1].pPts[0]))
        !           246:                    ifirst++;
        !           247:                cptAll = polyarcs[ilast].cpt;
        !           248:                pAllPts = polyarcs[ilast].pPts;
        !           249:                polyarcs[ilast++].pPts = (DDXPointPtr) NULL;
        !           250:                for(; ilast < narcs; ilast++)
        !           251:                {
        !           252:                    cpt = polyarcs[ilast].cpt;
        !           253:                    pAllPts = (DDXPointPtr) Xrealloc(pAllPts, 
        !           254:                         (cptAll+cpt-1) * sizeof(DDXPointRec));
        !           255:                    bcopy((char *) &polyarcs[ilast].pPts[1],
        !           256:                          (char *) &pAllPts[cptAll],
        !           257:                          (cpt - 1) * sizeof(DDXPointRec));
        !           258:                    cptAll += cpt - 1;
        !           259:                }
        !           260:                for( i = 0; i <= ifirst; i++)
        !           261:                {
        !           262:                    cpt = polyarcs[i].cpt;
        !           263:                    pAllPts =  (DDXPointPtr) Xrealloc(pAllPts, 
        !           264:                             (cptAll+cpt-1) * sizeof(DDXPointRec));
        !           265:                    bcopy((char *) &polyarcs[i].pPts[1],
        !           266:                          (char *) &pAllPts[cptAll],
        !           267:                          (cpt - 1) * sizeof(DDXPointRec));
        !           268:                    cptAll += cpt - 1;
        !           269:                }
        !           270:                (*pGCTo->Polylines)(pDrawTo, pGCTo, CoordModeOrigin,
        !           271:                                    cptAll, pAllPts);
        !           272:                /* Don't need to free pAllPts, because we're sure to
        !           273:                 * Xrealloc it again */
        !           274:                if(fTricky)
        !           275:                {
        !           276:                    (*pGC->PushPixels)(pGC, pDrawTo, pDraw, dx, dy,
        !           277:                                        xOrg, yOrg);
        !           278:                    miClearDrawable(pDrawTo, pGCTo);
        !           279:                }
        !           280:            }
        !           281:            ifirst++;
        !           282:        }
        !           283:        narcs -= count;
        !           284: 
        !           285:        /* Now draw all the (remaining) arcs */
        !           286:        cptAll = 0;
        !           287:        for(i = ifirst; i < narcs; i++)
        !           288:        {
        !           289:            cpt = polyarcs[i].cpt;
        !           290:            pPts = polyarcs[i].pPts;
        !           291: 
        !           292:            if((i > ifirst) && PtEqual(pPts[0], LastPt))
        !           293:            {
        !           294:                pAllPts = (DDXPointPtr)
        !           295:                   Xrealloc(pAllPts,
        !           296:                            (cptAll-1 + cpt) * sizeof(DDXPointRec));
        !           297:                bcopy((char *)&pPts[1],
        !           298:                      (char *)&pAllPts[cptAll], 
        !           299:                      (cpt - 1) * sizeof(DDXPointRec));
        !           300:                cptAll += cpt - 1;
        !           301:            }
        !           302:            else
        !           303:            {
        !           304:                /* Flush what we have so far and start collecting again */
        !           305:                if(cptAll > 0)
        !           306:                {
        !           307:                    (*pGC->Polylines)(pDrawTo, pGCTo, CoordModeOrigin,
        !           308:                                      cptAll, pAllPts);
        !           309:                    Xfree(pAllPts);
        !           310:                    if(fTricky)
        !           311:                    {
        !           312:                        (*pGC->PushPixels)(pGC, pDrawTo, pDraw, dx, dy,
        !           313:                                            xOrg, yOrg);
        !           314:                        miClearDrawable(pDrawTo, pGCTo);
        !           315:                    }
        !           316:                }
        !           317:                cptAll = cpt;
        !           318:                pAllPts = pPts;
        !           319:            }
        !           320:            LastPt = pPts[cpt-1];
        !           321:        }    /* end for each remaining arc */
        !           322: 
        !           323: 
        !           324:        if(cptAll > 0)
        !           325:        {
        !           326:            (*pGC->Polylines)(pDrawTo,pGCTo, CoordModeOrigin, cptAll, pAllPts);
        !           327:            Xfree(pAllPts);
        !           328:        }
        !           329:        if(fTricky)
        !           330:            (*pGC->PushPixels)(pGC, pDrawTo, pDraw, dx, dy, xOrg, yOrg);
        !           331:        for(i = 0; i < narcs; i++)
        !           332:        {
        !           333:            Xfree(polyarcs[i].pPts);
        !           334:        }
        !           335:        DEALLOCATE_LOCAL(polyarcs);
        !           336:        if(fTricky)
        !           337:        {
        !           338:            (*pGCTo->pScreen->DestroyPixmap)(pDrawTo);
        !           339:            FreeScratchGC(pGCTo);
        !           340:        }
        !           341:         else
        !           342:            if(arcmode != ArcChord)
        !           343:            {
        !           344:                DoChangeGC(pGCTo, GCArcMode, &arcmode, 0);
        !           345:                ValidateGC(pDrawTo, pGCTo);
        !           346:            }
        !           347:     }
        !           348: }
        !           349: 
        !           350: /* 360 degrees * 64 sub-degree positions */
        !           351: #define FULLCIRCLE 64 * 360
        !           352: 
        !           353: /* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
        !           354:  * Since we don't have to worry about overlapping segments, we can just
        !           355:  * fill each arc as it comes.  As above, we convert the arc into a set of
        !           356:  * line segments and then fill the resulting polygon.
        !           357:  */
        !           358: void
        !           359: miPolyFillArc(pDraw, pGC, narcs, parcs)
        !           360:     DrawablePtr        pDraw;
        !           361:     GCPtr      pGC;
        !           362:     int                narcs;
        !           363:     xArc       *parcs;
        !           364: {
        !           365:     int        i, cpt;
        !           366:     DDXPointPtr pPts;
        !           367: 
        !           368:     for(i = 0; i < narcs; i++)
        !           369:     {
        !           370:        /* We do this test every time because a full circle PieSlice isn't
        !           371:         * really a slice, but a full pie, and the Chord code (below) should
        !           372:         * handle it better */
        !           373:         if(pGC->arcMode == ArcPieSlice && parcs[i].angle2 < FULLCIRCLE)
        !           374:        {
        !           375:            cpt = 1;
        !           376:            pPts = (DDXPointPtr)Xalloc(sizeof(DDXPointRec));
        !           377:            if(cpt = miGetArcPts(&parcs[i], cpt, &pPts))
        !           378:            {
        !           379:                pPts[0].x = parcs[i].x + parcs[i].width/2;
        !           380:                pPts[0].y = parcs[i].y + parcs[i].height/2;
        !           381:                (*pGC->FillPolygon)(pDraw, pGC, Convex,
        !           382:                                    CoordModeOrigin, cpt + 1, pPts);
        !           383:                Xfree((char *) pPts);
        !           384:            }
        !           385:        }
        !           386:         else /* Chord */
        !           387:        {
        !           388:            pPts = (DDXPointPtr)NULL;
        !           389:            if(cpt = miGetArcPts(&parcs[i], 0, &pPts))
        !           390:            {
        !           391:                (*pGC->FillPolygon)(pDraw, pGC, Convex,
        !           392:                                    CoordModeOrigin, cpt, pPts);
        !           393:                Xfree((char *) pPts);
        !           394:            }
        !           395:        }
        !           396:     }
        !           397: }
        !           398: 
        !           399: /* MIGETARCPTS -- Converts an arc into a set of line segments -- a helper
        !           400:  * routine for arc and line (round cap) code.
        !           401:  * Returns the number of points in the arc.  Note that it takes a pointer
        !           402:  * to a pointer to where it should put the points and an index (cpt).
        !           403:  * This procedure allocates the space necessary to fit the arc points.
        !           404:  * Sometimes it's convenient for those points to be at the end of an existing
        !           405:  * array. (For example, if we want to leave a spare point to make sectors
        !           406:  * instead of segments.)  So we pass in the Xalloc()ed chunk that contains the
        !           407:  * array and an index saying where we should start stashing the points.
        !           408:  * If there isn't an array already, we just pass in a null pointer and 
        !           409:  * count on Xrealloc() to handle the null pointer correctly.
        !           410:  */
        !           411: int
        !           412: miGetArcPts(parc, cpt, ppPts)
        !           413:     xArc       *parc;  /* points to an arc */
        !           414:     int                cpt;    /* number of points already in arc list */
        !           415:     DDXPointPtr        *ppPts; /* pointer to pointer to arc-list -- modified */
        !           416: {
        !           417:     double     st,     /* Start Theta, start angle */
        !           418:                 et,    /* End Theta, offset from start theta */
        !           419:                dt,     /* Delta Theta, angle to sweep ellipse */
        !           420:                cdt,    /* Cos Delta Theta, actually 2 cos(dt) */
        !           421:                x0, y0, /* the recurrence formula needs two points to start */
        !           422:                x1, y1,
        !           423:                x2, y2, /* this will be the new point generated */
        !           424:                xc, yc; /* the center point */
        !           425:     int                count, i;
        !           426:     DDXPointPtr        poly;
        !           427: 
        !           428:     /* The spec says that positive angles indicate counterclockwise motion.
        !           429:      * Given our coordinate system (with 0,0 in the upper left corner), 
        !           430:      * the screen appears flipped in Y.  The easiest fix is to negate the
        !           431:      * angles given */
        !           432:     
        !           433:     /* Throw out multiples of 360 degrees. */
        !           434:     i = -parc->angle1;
        !           435:     if(i < 0)
        !           436:     {
        !           437:        while (i < -FULLCIRCLE)
        !           438:            i += FULLCIRCLE;
        !           439:     }
        !           440:     else
        !           441:     {
        !           442:        while(i > FULLCIRCLE)
        !           443:            i -= FULLCIRCLE;
        !           444:     }
        !           445:     st = (double ) i;
        !           446:     st *= ((double)M_PI) / (64 * 180);         /* convert to degrees, then to rads */
        !           447: 
        !           448:     i = -parc->angle2;
        !           449:     /* If it's more than one full rotation, make it exactly 1 rotation */
        !           450:     if(i > FULLCIRCLE || i < -FULLCIRCLE)
        !           451:     {
        !           452:        i = FULLCIRCLE;
        !           453:     }
        !           454:     et = (double) i;
        !           455:     et *= ((double)M_PI) / (64 * 180);         /* convert to degrees, then to rads */
        !           456: 
        !           457:     /* Try to get a delta theta that is within 1/2 pixel.  Then adjust it
        !           458:      * so that it divides evenly into the total.
        !           459:      * I'm just using cdt 'cause I'm lazy.
        !           460:      */
        !           461:     cdt = max(parc->width, parc->height)/2;
        !           462:     if(cdt <= 0)
        !           463:        return 0;
        !           464:     dt =  ( (double)2.0 / sqrt(cdt));
        !           465:     count = et/dt;
        !           466:     count = abs(count) + 1;
        !           467:     dt = et/count;     
        !           468:     count++;
        !           469: 
        !           470:     cdt = 2 * cos(dt);
        !           471: 
        !           472:     poly = (DDXPointPtr) Xrealloc(*ppPts, (count + cpt) * sizeof(DDXPointRec));
        !           473:     *ppPts = poly;
        !           474: 
        !           475:     xc = parc->width/2.0;              /* store half width and half height */
        !           476:     yc = parc->height/2.0;
        !           477:     
        !           478: 
        !           479:     x0 = xc * cos(st);
        !           480:     y0 = yc * sin(st);
        !           481:     x1 = xc * cos(st + dt);
        !           482:     y1 = yc * sin(st + dt);
        !           483:     xc += parc->x;             /* by adding initial point, these become */
        !           484:     yc += parc->y;             /* the center point */
        !           485:     poly[cpt].x = ROUNDTOINT(xc + x0);
        !           486:     poly[cpt].y = ROUNDTOINT(yc + y0);
        !           487:     poly[cpt + 1].x = ROUNDTOINT(xc + x1);
        !           488:     poly[cpt + 1].y = ROUNDTOINT(yc + y1);
        !           489: 
        !           490:     for(i = 2; i < count; i++)
        !           491:     {
        !           492:        x2 = cdt * x1 - x0;
        !           493:        y2 = cdt * y1 - y0;
        !           494:        poly[cpt + i].x = ROUNDTOINT(xc + x2);
        !           495:        poly[cpt + i].y = ROUNDTOINT(yc + y2);
        !           496: 
        !           497:        x0 = x1; y0 = y1;
        !           498:        x1 = x2; y1 = y2;
        !           499:     }
        !           500:     /* adjust the last point */
        !           501:     poly[cpt +i -1].x = ROUNDTOINT(cos(st + et) * parc->width/2.0 + xc);
        !           502:     poly[cpt +i -1].y = ROUNDTOINT(sin(st + et) * parc->height/2.0 + yc);
        !           503: 
        !           504:     return(count);
        !           505: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.