Annotation of 43BSDTahoe/new/X/libibm/libsrc/pathlist.c, revision 1.1.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.