Annotation of 43BSDTahoe/new/X/libibm/libsrc/pathlist.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *rcsid_pathlist_c = "$Header: pathlist.c,v 10.1 86/11/19 10:43:18 jg Exp $";
        !             3: #endif lint
        !             4: /* pathlist.c - Coverter for vertex list
        !             5:  *
        !             6:  *     PathListConverter       Convert a list of vertices 
        !             7:  *                             into absolute striaght lines
        !             8:  *     Spline                  Generates a series of line segments
        !             9:  *                             that make up a smooth curve
        !            10:  *     Matrix                  Utility rtn used by Spline to interpolate
        !            11:  *                             points along the curve
        !            12:  *
        !            13:  *     Author:
        !            14:  *         Scott Bates
        !            15:  *         Brown University
        !            16:  *         IRIS, Box 1946
        !            17:  *         Providence, RI 02912
        !            18:  *
        !            19:  *
        !            20:  *             Copyright (c) 1986 Brown University
        !            21:  *
        !            22:  * Permission to use, copy, modify and distribute this software and its
        !            23:  * documentation for any purpose and without fee is hereby granted, provided
        !            24:  * that the above copyright notice appear in all copies, and that both
        !            25:  * that copyright notice and this permission notice appear in supporting
        !            26:  * documentation, and that the name of Brown University not be used in
        !            27:  * advertising or publicity pertaining to distribution of the software
        !            28:  * without specific, written prior permission. Brown University makes no
        !            29:  * representations about the suitability of this software for any purpose.
        !            30:  * It is provided "as-is" without express or implied warranty.
        !            31:  */
        !            32: 
        !            33: #include "private.h"
        !            34: #include "pathlist.h"
        !            35: 
        !            36: /*
        !            37:  * Convert vertex list
        !            38:  */
        !            39: 
        !            40: PathListConverter(verts, vertcount, xbase, ybase, newverts, newvertcount, type)
        !            41:     register Vertex *verts;
        !            42:     int vertcount;
        !            43:     short xbase, ybase;
        !            44:     Vertex **newverts;
        !            45:     int *newvertcount;
        !            46:     int type;
        !            47: {
        !            48:     register Vertex *ThisVertex = verts;
        !            49:     register Vertex *LastVertex;
        !            50:     register Vertex *NewVerts;
        !            51:     register Segment *CurrentSegment;
        !            52:     register i, j;
        !            53:     int VertexCount;
        !            54:     int VertexIndex = 0;
        !            55:     int SegmentIndex = 0;
        !            56:     int CurvedSegments = 0;
        !            57:     int MaxSegments = INITIAL_SEGMENTS;
        !            58:     int TotalVertexCount = vertcount;
        !            59: 
        !            60: #ifdef TRACE_X
        !            61:     fprintf (stderr, "In PathListConverter\n");
        !            62:     fflush (stderr);
        !            63: #endif TRACE_X
        !            64: 
        !            65:     /*
        !            66:      * Perform initial allocation of segment table
        !            67:      */
        !            68: 
        !            69:     CurrentSegment = SegmentTable =
        !            70:        (Segment *)malloc(MaxSegments * sizeof(Segment));
        !            71:     if(SegmentTable == NULL) {
        !            72:        return(NULL);
        !            73:     }
        !            74: 
        !            75:     /*
        !            76:      * Prime first segment table entry
        !            77:      */
        !            78: 
        !            79:     ThisVertex->x += xbase;
        !            80:     ThisVertex->y += ybase;
        !            81: 
        !            82:     CurrentSegment->Index = 0;
        !            83:     CurrentSegment->Count = 1;
        !            84: 
        !            85:     switch(ThisVertex->flags & VERTEX_TYPE_MASK) {
        !            86:     case(LINE):                        /* First segment is a line */
        !            87: 
        !            88:        CurrentSegment->Type = LINE_SEGMENT;
        !            89:        break;
        !            90: 
        !            91:     case(START_CLOSED_CURVE):  /* First segment is a closed curve */
        !            92: 
        !            93:        CurrentSegment->Type = CLOSED_CURVE_SEGMENT;
        !            94:        CurvedSegments++;
        !            95:        break;
        !            96: 
        !            97:     default:                   /* First segment is a line */
        !            98: 
        !            99:        /*
        !           100:         * turn off bogus flags and make this first segment a line
        !           101:         */
        !           102: 
        !           103:        ThisVertex->flags &= ~(START_CLOSED_CURVE | END_CLOSED_CURVE);
        !           104:        CurrentSegment->Type = LINE_SEGMENT;
        !           105:     }
        !           106: 
        !           107:     /*
        !           108:      * Convert remaining vertices to absolute coordinates and
        !           109:      * divide them up into there appropriate segemnts.
        !           110:      */
        !           111: 
        !           112:     do {
        !           113:        if(++VertexIndex < vertcount) {
        !           114:            /*
        !           115:             * Move on to next vertex and save current vertex
        !           116:             */
        !           117: 
        !           118:            LastVertex = ThisVertex++;
        !           119:        } else {
        !           120:            /*
        !           121:             * Conversion has completed. If the last segment was a
        !           122:             * curved segment verify it before exiting loop.
        !           123:             */
        !           124: 
        !           125:            if(CurrentSegment->Type == CLOSED_CURVE_SEGMENT &&
        !           126:              ((ThisVertex->flags & VERTEX_TYPE_MASK) != END_CLOSED_CURVE ||
        !           127:              CurrentSegment->Count < 3)) {
        !           128:                    return(NULL);
        !           129:            } else if(CurrentSegment->Type == OPEN_CURVE_SEGMENT &&
        !           130:              CurrentSegment->Count < 3) {
        !           131:                    return(NULL);
        !           132:            }
        !           133:            break;
        !           134:        }
        !           135: 
        !           136:        /*
        !           137:         * Make Vertex an absolute coordinate
        !           138:         */
        !           139: 
        !           140:        if(ThisVertex->flags & VertexRelative) {
        !           141:            ThisVertex->x += LastVertex->x;
        !           142:            ThisVertex->y += LastVertex->y;
        !           143:        } else  {
        !           144:            ThisVertex->x += xbase;
        !           145:            ThisVertex->y += ybase;
        !           146:        }
        !           147: 
        !           148:        /*
        !           149:         * If this is the last vertex turn off any bogus flags
        !           150:         * before processing it
        !           151:         */
        !           152: 
        !           153:        if((VertexIndex + 1) == vertcount &&
        !           154:          CurrentSegment->Type != CLOSED_CURVE_SEGMENT) {
        !           155:             ThisVertex->flags &= ~(END_CLOSED_CURVE);
        !           156:        }
        !           157: 
        !           158:        /*
        !           159:         * add this vertex to the current segement or start a new one.
        !           160:         */
        !           161: 
        !           162:        switch(ThisVertex->flags & VERTEX_TYPE_MASK) {
        !           163: 
        !           164:        case(LINE):                     /* This vertex is a LINE */
        !           165:            switch(LastVertex->flags & VERTEX_TYPE_MASK) {
        !           166: 
        !           167:            case(LINE):                 /* Last vertex was a LINE */
        !           168:                /*
        !           169:                 * Add this vertex to the current segment
        !           170:                 */
        !           171: 
        !           172:                CurrentSegment->Count++;
        !           173:                break;
        !           174: 
        !           175:            case(CURVE):                /* Last vertex was a CURVE */
        !           176:                /*
        !           177:                 * If the current segment type is a closed curve
        !           178:                 * convert it to an open curve segment.
        !           179:                 */
        !           180: 
        !           181:                if(CurrentSegment->Type == CLOSED_CURVE_SEGMENT) {
        !           182:                    CurrentSegment->Type = OPEN_CURVE_SEGMENT;
        !           183:                    if(CurrentSegment->Index > 0) {
        !           184:                        CurrentSegment->Index--;
        !           185:                        CurrentSegment->Count++;
        !           186:                    }
        !           187:                }
        !           188:                if(++CurrentSegment->Count < 3) {
        !           189:                    return(NULL);
        !           190:                }
        !           191: 
        !           192:            case(END_CLOSED_CURVE):     /* Last vertex was a END_CLOSED_CURVE */
        !           193:                /*
        !           194:                 * Start a line segment
        !           195:                 */
        !           196: 
        !           197:                StartNewSegment(LINE_SEGMENT, VertexIndex, 1);
        !           198:                break;
        !           199: 
        !           200:            case(START_CLOSED_CURVE):   /* Last vertex was start closed curve */
        !           201:                /*
        !           202:                 * Convert the current segment to a line segment
        !           203:                 */
        !           204: 
        !           205:                CurrentSegment->Type = LINE_SEGMENT;
        !           206:                CurrentSegment->Count++;
        !           207:                CurvedSegments--;
        !           208:            }
        !           209:            break;
        !           210: 
        !           211:        case(CURVE):                    /* This vertex was a curve */
        !           212: 
        !           213:            switch(LastVertex->flags & VERTEX_TYPE_MASK) {
        !           214: 
        !           215:            case(LINE):                 /* Last vertex was a line or */
        !           216:            case(END_CLOSED_CURVE):     /* end closed curve          */
        !           217:                /*
        !           218:                 * Start an open curve segment
        !           219:                 */
        !           220: 
        !           221:                StartNewSegment(OPEN_CURVE_SEGMENT, VertexIndex - 1, 2);
        !           222:                CurvedSegments++;
        !           223:                break;
        !           224: 
        !           225:            case(CURVE):                /* Last vertex was a curve or start */
        !           226:            case(START_CLOSED_CURVE):   /* closed curve                     */
        !           227:                /*
        !           228:                 * Add this vertex to current segment
        !           229:                 */
        !           230: 
        !           231:                CurrentSegment->Count++;
        !           232: 
        !           233:            }
        !           234:            break;
        !           235: 
        !           236:        case(START_CLOSED_CURVE):       /* This vertex is start closed curve */
        !           237: 
        !           238:            switch(LastVertex->flags & VERTEX_TYPE_MASK) {
        !           239: 
        !           240:            case(CURVE):                /* Last vertex was a curve */
        !           241:                /* If the current segment type is a closed curve
        !           242:                 * convert it to a open curve segment. Then start 
        !           243:                 * a closed curve segment using this vertex.
        !           244:                 */
        !           245: 
        !           246:                if(CurrentSegment->Type == CLOSED_CURVE_SEGMENT) {
        !           247:                    CurrentSegment->Type = OPEN_CURVE_SEGMENT;
        !           248:                    if(CurrentSegment->Index > 0) {
        !           249:                        CurrentSegment->Index--;
        !           250:                        CurrentSegment->Count++;
        !           251:                    }
        !           252:                }
        !           253:                if(++CurrentSegment->Count < 3) {
        !           254:                    return(NULL);
        !           255:                }
        !           256: 
        !           257:            case(LINE):                 /* Last vertex was a line or */
        !           258:            case(END_CLOSED_CURVE):     /* end closed curve          */
        !           259:                /*
        !           260:                 * Start closed curve segemnt
        !           261:                 */
        !           262: 
        !           263:                StartNewSegment(CLOSED_CURVE_SEGMENT, VertexIndex, 1);
        !           264:                CurvedSegments++;
        !           265:                break;
        !           266: 
        !           267:            case(START_CLOSED_CURVE):   /* Last vertex was start closed curve */
        !           268:                /*
        !           269:                 * Indicate to caller that there was a
        !           270:                 * path list error.
        !           271:                 */
        !           272: 
        !           273:                return(NULL);
        !           274:            }
        !           275:            break;
        !           276: 
        !           277:        case(END_CLOSED_CURVE):         /* This vertex is end closed curve */
        !           278:            /*
        !           279:             * Add this vertex to the current segment
        !           280:             */
        !           281: 
        !           282:            ++CurrentSegment->Count;
        !           283: 
        !           284:            /*
        !           285:             * Last vertex was a curve
        !           286:             */
        !           287: 
        !           288:            if((LastVertex->flags & VERTEX_TYPE_MASK) == CURVE) {
        !           289:                /*
        !           290:                 * Vaild vertex count of curved segment
        !           291:                 */
        !           292: 
        !           293:                if(CurrentSegment->Count < 3) {
        !           294:                      return(NULL);
        !           295:                } 
        !           296: 
        !           297:                /*
        !           298:                 * If the current segment is a closed segment
        !           299:                 * validate that the last vertex of the segment
        !           300:                 * equals the first.
        !           301:                 */
        !           302: 
        !           303:                if(CurrentSegment->Type == CLOSED_CURVE_SEGMENT) {
        !           304:                    if(verts[CurrentSegment->Index].x != verts[VertexIndex].x ||
        !           305:                      verts[CurrentSegment->Index].y != verts[VertexIndex].y) {
        !           306:                        return(NULL);
        !           307:                    }
        !           308:                } else {
        !           309:                    /*
        !           310:                     * Start a line segment using this vertex
        !           311:                     */
        !           312: 
        !           313:                    StartNewSegment(LINE_SEGMENT, VertexIndex, 1);
        !           314:                }
        !           315:            }
        !           316:            break;
        !           317: 
        !           318:        default:
        !           319:            /*
        !           320:             * Indicate to caller that there was a
        !           321:             * path list error.
        !           322:             */
        !           323: 
        !           324:            return(NULL);
        !           325:        }
        !           326:     } while(1);
        !           327: 
        !           328:     /*
        !           329:      * If there are curved segments in this path list
        !           330:      * then perform the required setup and call the spline 
        !           331:      * rtn . 
        !           332:      */
        !           333: 
        !           334:     SplineUsed = 0;
        !           335:     if(CurvedSegments) {
        !           336:        Vertex *Vertex_A;
        !           337:        Vertex *Vertex_B;
        !           338:        Vertex *Vertex_C;
        !           339:        Vertex *Vertex_D;
        !           340:        int Count;
        !           341: 
        !           342:        /*
        !           343:        * Initial allocating of the spline vertex buffer
        !           344:        */
        !           345: 
        !           346:        SplineVertexIndex = 0;
        !           347:        MaxSplineVerts = INITIAL_SPLINE_VERTS;
        !           348:        SplineVertexBuffer = (Vertex *)malloc(MaxSplineVerts * sizeof(Vertex));
        !           349:        if(SplineVertexBuffer == NULL) {
        !           350:            return(NULL);
        !           351:        }
        !           352:        SplineUsed++;
        !           353: 
        !           354:        /*
        !           355:        * Loop thru all the path list segments looking 
        !           356:        * for all open and closed curve segments.
        !           357:        */
        !           358: 
        !           359:        for(i = 0; i <= SegmentIndex; i++) {
        !           360: 
        !           361:        switch((CurrentSegment = &SegmentTable[i])->Type) {
        !           362: 
        !           363:        case(LINE_SEGMENT):
        !           364:            /*
        !           365:            * Ignore line segments
        !           366:            */
        !           367:     
        !           368:            continue;
        !           369:     
        !           370:        case(OPEN_CURVE_SEGMENT):
        !           371:            /*
        !           372:             * Generate a series of line segments
        !           373:             * that represent the open curve defined
        !           374:             * by this segment.
        !           375:             */
        !           376: 
        !           377:            Count = 0;
        !           378:            Vertex_A = &verts[CurrentSegment->Index +
        !           379:                    CurrentSegment->Count - 1];
        !           380:            Vertex_B = &verts[CurrentSegment->Index];
        !           381:            Vertex_C = Vertex_B + 1;
        !           382:            Vertex_D = Vertex_C + 1;
        !           383:            CurrentSegment->Index = SplineVertexIndex;
        !           384:            j = CurrentSegment->Count - 2;
        !           385: 
        !           386:            while(1) {
        !           387:                Count += Spline(Vertex_A, Vertex_B, Vertex_C, Vertex_D);
        !           388:                if(--j == 0) {
        !           389:                break;
        !           390:                }
        !           391:                Vertex_A = Vertex_B;
        !           392:                Vertex_B = Vertex_C;
        !           393:                Vertex_C = Vertex_D++;
        !           394:            }
        !           395:            break;
        !           396: 
        !           397:        case(CLOSED_CURVE_SEGMENT):
        !           398:            /*
        !           399:             * Generate a series of line segments
        !           400:             * that represent the closed curve defined
        !           401:             * by this segment.
        !           402:             */
        !           403: 
        !           404:            Count = 0;
        !           405:            LastVertex = &verts[CurrentSegment->Index + 1];
        !           406:            Vertex_A = &verts[CurrentSegment->Index +
        !           407:                    CurrentSegment->Count - 2];
        !           408:            Vertex_B = &verts[CurrentSegment->Index];
        !           409:            CurrentSegment->Index = SplineVertexIndex;
        !           410:            Vertex_C = Vertex_B + 1;
        !           411:            Vertex_D = Vertex_C;
        !           412:            j = CurrentSegment->Count - 2;
        !           413: 
        !           414:            while(j--) {
        !           415:                Vertex_D++;
        !           416:                Count += Spline(Vertex_A, Vertex_B, Vertex_C, Vertex_D);
        !           417:                Vertex_A = Vertex_B;
        !           418:                Vertex_B = Vertex_C;
        !           419:                Vertex_C = Vertex_D;
        !           420:            }
        !           421:            Vertex_D = LastVertex;
        !           422:            Count += Spline(Vertex_A, Vertex_B, Vertex_C, Vertex_D);
        !           423: 
        !           424:            }
        !           425: 
        !           426:            /*
        !           427:             * Adjust the current segment count and
        !           428:             * increase the total vertex to reflect 
        !           429:             * the new points generated by the spline rtn.
        !           430:             */
        !           431: 
        !           432:            CurrentSegment->Count = Count;
        !           433:            TotalVertexCount += Count;
        !           434: 
        !           435:            /*
        !           436:             * If there are no more curved segments exit early
        !           437:             */
        !           438: 
        !           439:            if(--CurvedSegments == 0) {
        !           440:                break;
        !           441:            }
        !           442:        }
        !           443:     }
        !           444: 
        !           445:     /*
        !           446:      * Allocate space for new vertex list
        !           447:      */
        !           448: 
        !           449:     NewVerts = *newverts = (Vertex *)malloc((TotalVertexCount << 1) *
        !           450:                sizeof(Vertex));
        !           451:     if(NewVerts == NULL) {
        !           452:        return(NULL);
        !           453:     }
        !           454: 
        !           455:     /*
        !           456:      * Loop thru coordinate list
        !           457:      */
        !           458: 
        !           459:     for(VertexCount = 0, i = 0; i <= SegmentIndex; i++) {
        !           460:        /* 
        !           461:         * If this segment is a line segment get verts from original
        !           462:         * vertex list else use the spline vertex list.
        !           463:         */
        !           464: 
        !           465:        if((CurrentSegment = &SegmentTable[i])->Type == LINE_SEGMENT) {
        !           466:            ThisVertex = &verts[CurrentSegment->Index];
        !           467:        } else {
        !           468:            ThisVertex = &SplineVertexBuffer[CurrentSegment->Index];
        !           469:        }
        !           470: 
        !           471:        /*
        !           472:         * Get segment vertex count
        !           473:         */
        !           474: 
        !           475:        j = CurrentSegment->Count;
        !           476: 
        !           477:        /*
        !           478:         * Convert path list to fill format
        !           479:         */
        !           480: 
        !           481:        if(type == FILL_PATH_LIST) {
        !           482:            do { 
        !           483:                /*
        !           484:                 * Something to draw ?
        !           485:                 */
        !           486: 
        !           487:                if(ThisVertex->flags & VertexDontDraw) {
        !           488:                    /*
        !           489:                     * Indicate start of closed polygon
        !           490:                     */
        !           491: 
        !           492:                    ThisVertex->flags |= START_OF_CLOSED_POLY;
        !           493: 
        !           494:                    /*
        !           495:                     * Increment vertex pointers
        !           496:                     */
        !           497: 
        !           498:                    LastVertex = ThisVertex++;
        !           499: 
        !           500:                    /*
        !           501:                     * Continue processing of current segment
        !           502:                     */
        !           503: 
        !           504:                    continue;
        !           505:                }
        !           506: 
        !           507:                /*
        !           508:                 * If this vertex is not a dup save the 
        !           509:                 * line segment represented by the last 
        !           510:                 * vertex and this one in NewVerts.
        !           511:                 * If it is a dup ignore this vertex.
        !           512:                 */
        !           513: 
        !           514:                if(ThisVertex->x != LastVertex->x ||
        !           515:                   ThisVertex->y != LastVertex->y) {
        !           516: 
        !           517:                    /*
        !           518:                     * Save start and end points of
        !           519:                     * visible line
        !           520:                     */
        !           521: 
        !           522:                    *NewVerts++ = *LastVertex;
        !           523:                    *NewVerts++ = *ThisVertex;
        !           524:        
        !           525:                    /*
        !           526:                     * Increment vertex count
        !           527:                     */
        !           528: 
        !           529:                    VertexCount += 2;
        !           530: 
        !           531:                    /*
        !           532:                     * Increment vertex pointers
        !           533:                     */
        !           534: 
        !           535:                    LastVertex = ThisVertex++;
        !           536:                } else {
        !           537:                    /*
        !           538:                     * Ignore this vertex
        !           539:                     */
        !           540: 
        !           541:                    ThisVertex++;
        !           542:                }
        !           543:            }while(--j);
        !           544:        } else {
        !           545:            do {
        !           546:                /*
        !           547:                 * Something to draw ?
        !           548:                 */
        !           549: 
        !           550:                if(ThisVertex->flags & VertexDontDraw) {
        !           551:                    /*
        !           552:                     * Increment vertex pointers
        !           553:                     */
        !           554: 
        !           555:                    LastVertex = ThisVertex++;
        !           556: 
        !           557:                    /*
        !           558:                     * Continue processing current segment
        !           559:                     */
        !           560: 
        !           561:                    continue;
        !           562:                }
        !           563: 
        !           564:                if(ThisVertex->x != LastVertex->x ||
        !           565:                   ThisVertex->y != LastVertex->y) {
        !           566:                    /*
        !           567:                     * Save start and end points of
        !           568:                     * visible line
        !           569:                     */
        !           570: 
        !           571:                    *NewVerts++ = *LastVertex;
        !           572:                    *NewVerts = *ThisVertex;
        !           573: 
        !           574:                    /*
        !           575:                     * Shorten line by one point if
        !           576:                     * "VertexDrawLastPoint" flag is off
        !           577:                     */
        !           578: 
        !           579:                    if(!(ThisVertex->flags & VertexDrawLastPoint)) {
        !           580:                        int DeltaX, DeltaY;
        !           581:                        int SignX = 0, SignY = 0;
        !           582:        
        !           583:                        if((DeltaX = ThisVertex->x - LastVertex->x) < 0) {
        !           584:                            SignX = -1;
        !           585:                            DeltaX = -DeltaX;
        !           586:                        }
        !           587: 
        !           588:                        if((DeltaY = ThisVertex->y - LastVertex->y) < 0) {
        !           589:                            SignY = -1;
        !           590:                            DeltaY = -DeltaY;
        !           591:                        }
        !           592:        
        !           593:                        if (DeltaX > DeltaY) {
        !           594:                            SignX < 0 ? NewVerts->x++ : NewVerts->x--;
        !           595:                            if ((DeltaX >> 1) <= DeltaY) {
        !           596:                                SignY < 0 ? NewVerts->y++ : NewVerts->y--;
        !           597:                            }
        !           598:                        } else if (DeltaX < DeltaY ) {
        !           599:                            SignY < 0 ? NewVerts->y++ : NewVerts->y--;
        !           600:                            if ((DeltaY >> 1) <= DeltaX) {
        !           601:                                SignX < 0 ? NewVerts->x++ : NewVerts->x--;
        !           602:                            }
        !           603:                        } else {
        !           604:                            if (DeltaX > 0) {
        !           605:                                SignX < 0 ? NewVerts->x++ : NewVerts->x--;
        !           606:                                SignY < 0 ? NewVerts->y++ : NewVerts->y--;
        !           607:                            } else {
        !           608:                                /*
        !           609:                                 * Line now has a length of zero
        !           610:                                 * so we skip this one. Back up the
        !           611:                                 * buffer pointer and move on to the
        !           612:                                 * next vertex
        !           613:                                 */
        !           614: 
        !           615:                                NewVerts--;
        !           616: 
        !           617:                                /*
        !           618:                                 * Increment vertex pointers
        !           619:                                 */
        !           620:            
        !           621:                                LastVertex = ThisVertex++;
        !           622:                                continue;
        !           623:                            }
        !           624:                        }
        !           625:                    }
        !           626:        
        !           627:                    /*
        !           628:                     * Advance buffer pointer
        !           629:                     */
        !           630:        
        !           631:                    NewVerts++;
        !           632:        
        !           633:                    /*
        !           634:                     * Increment vertex count
        !           635:                     */
        !           636: 
        !           637:                    VertexCount += 2;
        !           638: 
        !           639:                    /*
        !           640:                     * Increment vertex pointers
        !           641:                     */
        !           642: 
        !           643:                    LastVertex = ThisVertex++;
        !           644:                } else {
        !           645:                    /*
        !           646:                     * Ignore this vertex
        !           647:                     */
        !           648: 
        !           649:                    ThisVertex++;
        !           650:                }
        !           651:            } while(--j);
        !           652:        }
        !           653:     }
        !           654: 
        !           655:     /*
        !           656:      * Save final vertex count and free any resources used
        !           657:      * during path list conversion.
        !           658:      */
        !           659: 
        !           660:     *newvertcount = VertexCount;
        !           661:     free((caddr_t)SegmentTable);
        !           662:     if(SplineUsed) {
        !           663:        free((caddr_t)SplineVertexBuffer);
        !           664:     }
        !           665:     return(1);
        !           666: }
        !           667: 
        !           668: /*
        !           669:  * Generate a series of points that will form
        !           670:  * a curve between Vertex_B and Vertex_C.
        !           671:  */
        !           672: 
        !           673: static
        !           674: Spline(Vertex_A, Vertex_B, Vertex_C, Vertex_D)
        !           675:     register Vertex *Vertex_A;
        !           676:     register Vertex *Vertex_B;
        !           677:     register Vertex *Vertex_C;
        !           678:     register Vertex *Vertex_D;
        !           679: {
        !           680:     register Vertex *Verts = &SplineVertexBuffer[SplineVertexIndex];
        !           681:     register i;
        !           682:     int nls = 1;
        !           683:     int Delta_X, Delta_Y;
        !           684:     long Matrix();
        !           685: 
        !           686: #ifdef TRACE_X
        !           687:     fprintf (stderr, "In Spline\n");
        !           688:     fflush (stderr);
        !           689: #endif TRACE_X
        !           690: 
        !           691:     GrowSplineVertexBuffer(Verts, 2);
        !           692:     *Verts++ = *Vertex_B;
        !           693:     SplineVertexIndex++;
        !           694:     if((Vertex_C->flags & VertexDontDraw) == 0) {
        !           695:        /* 
        !           696:         * Compute how many points to generate
        !           697:         * based on the largest delta change in either 
        !           698:         * the X or Y direction. This number represents
        !           699:         * the maximum number of points to be generated
        !           700:         * and may be reduced by an increasing amount
        !           701:         * as the change (delta) gets larger. This allows
        !           702:         * us to generate fewer points and therefore 
        !           703:         * improve performace and still generate
        !           704:         * quality smooth curve.
        !           705:         */
        !           706: 
        !           707:        if((Delta_X = Vertex_C->x - Vertex_B->x) < 0) {
        !           708:            Delta_X = -Delta_X;
        !           709:        }
        !           710: 
        !           711:        if((Delta_Y = Vertex_C->y - Vertex_B->y) < 0) {
        !           712:            Delta_Y = -Delta_Y;
        !           713:        }
        !           714: 
        !           715:        if(Delta_X > Delta_Y) {
        !           716:            if(Delta_X > 64) {
        !           717:                nls = Delta_X >> 3;
        !           718:            } else if(Delta_X > 32) {
        !           719:                nls = Delta_X >> 2;
        !           720:            } else if(Delta_X > 16) {
        !           721:                nls = Delta_X >> 1;
        !           722:            } else {
        !           723:                nls = Delta_X;
        !           724:            }
        !           725:        } else  {
        !           726:            if(Delta_Y > 64) {
        !           727:                nls = Delta_Y >> 3;
        !           728:            } else if(Delta_Y > 32) {
        !           729:                nls = Delta_Y >> 2;
        !           730:            } else if(Delta_Y > 16) {
        !           731:                nls = Delta_Y >> 1;
        !           732:            } else {
        !           733:                nls = Delta_Y;
        !           734:            }
        !           735:        }
        !           736: 
        !           737:        /*
        !           738:         * Generate the actual points
        !           739:         */
        !           740: 
        !           741:        if(nls) {
        !           742:            GrowSplineVertexBuffer(Verts, nls);
        !           743:            for(i = 1; i < nls; i++, Verts++) {
        !           744:                Verts->x = Matrix((long)Vertex_A->x, (long)Vertex_B->x,
        !           745:                    (long)Vertex_C->x, (long)Vertex_D->x, nls, i);
        !           746:                Verts->y = Matrix((long)Vertex_A->y, (long)Vertex_B->y,
        !           747:                    (long)Vertex_C->y, (long)Vertex_D->y, nls, i);
        !           748:                Verts->flags = Vertex_C->flags & VertexDrawLastPoint;
        !           749:            }
        !           750:            SplineVertexIndex += nls;
        !           751:        } else {
        !           752:            nls = 1;
        !           753:            SplineVertexIndex++;
        !           754:        }
        !           755:     } else {
        !           756:        SplineVertexIndex++;
        !           757:     }
        !           758:     *Verts = *Vertex_C;
        !           759: 
        !           760:     /*
        !           761:      * Return the number of points generated 
        !           762:      */
        !           763: 
        !           764:     return(nls + 1);
        !           765: }
        !           766: 
        !           767: /* 
        !           768:  * This rtn performs the matrix math require to interpolate a
        !           769:  * point on the curve represented by a, b, c, and d. The generated 
        !           770:  * point will be between points b and c.
        !           771:  */
        !           772: 
        !           773: static long
        !           774: Matrix(a, b, c, d, nls, i)
        !           775:     register long a, b, c, d;
        !           776:     register nls;
        !           777:     int i;
        !           778: {
        !           779:     register long p = SHIFT_LEFT_16(-a + b - c + d);
        !           780: 
        !           781: #ifdef TRACE_X
        !           782:         fprintf (stderr, "In Matrix\n");
        !           783:         fflush (stderr);
        !           784: #endif TRACE_X
        !           785: 
        !           786:     p = PERCENT_16(p, i, nls) + SHIFT_LEFT_16((a << 1) - (b << 1) + c - d);
        !           787:     p = PERCENT_16(p, i, nls) + SHIFT_LEFT_16(-a + c);
        !           788:     return(ROUND_16(PERCENT_16(p, i, nls) + SHIFT_LEFT_16(b)));
        !           789: }

unix.superglobalmegacorp.com

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