Annotation of researchv9/X11/src/X.V11R1/lib/oldX/XDraw.c, revision 1.1.1.1

1.1       root        1: /* $Header: XDraw.c,v 1.2 87/08/28 13:34:18 toddb Exp $ */
                      2: #include "copyright.h"
                      3: 
                      4: /* Copyright    Massachusetts Institute of Technology    1987  */
                      5: 
                      6: #include "Xlibint.h"
                      7: #include "Xlib.h"
                      8: #include "X10.h"
                      9: 
                     10: #define OK_RETURN 1
                     11: #define ERR_RETURN 0
                     12: #define NULL 0
                     13: 
                     14: /*
                     15: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                     16: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                     17: 
                     18:                         All Rights Reserved
                     19: 
                     20: Permission to use, copy, modify, and distribute this software and its 
                     21: documentation for any purpose and without fee is hereby granted, 
                     22: provided that the above copyright notice appear in all copies and that
                     23: both that copyright notice and this permission notice appear in 
                     24: supporting documentation, and that the names of Digital or MIT not be
                     25: used in advertising or publicity pertaining to distribution of the
                     26: software without specific, written prior permission.  
                     27: 
                     28: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     29: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     30: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     31: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     32: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     33: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     34: SOFTWARE.
                     35: 
                     36: */
                     37: 
                     38: /*
                     39:  *
                     40:  * Vertices_converter: This internal routine takes a list of Vertices and
                     41:  *                     returns another list of Vertices such that the
                     42:  *                     following is true:
                     43:  *
                     44:  *         (1) No Vertex has the VertexRelative flag on
                     45:  *         (2) No Vertex has the VertexCurved flag on
                     46:  *         (3) The first Vertex has the VertexDontDraw flag on
                     47:  *         (4) The path that the return Vertex list specifies should
                     48:  *             be drawn on the screen is very close to the path that the
                     49:  *             Vertex list passed to vertices_converter specified should be
                     50:  *             drawn.  The difference is due solely to the approximation
                     51:  *             of curved segments in the original Vertex list by many
                     52:  *             small straight line segments that approximate the curve.
                     53:  *
                     54:  *    Notes:
                     55:  *
                     56:  *         (1) The first Vertex must have the VertexRelative flag
                     57:  *             turned off.  (This is not checked, just assumed)
                     58:  *         (2) VertexDontDraw is automatically turned on for the first
                     59:  *             Vertex because drawing to the first Vertex makes no sense.
                     60:  *         (3) This routine is used only by XDraw & XDrawFilled.
                     61:  *         (4) A 0 is returned iff no error occurs.
                     62:  *         (5) The passed Vertex list not changed in any way.
                     63:  *
                     64:  *    Implementation:
                     65:  *
                     66:  *         A routine from the qvss device dependent code library from the
                     67:  *         X version 10 sources written by DEC was used, abet slightly
                     68:  *         modified as it provided 99% of the desired functionality.
                     69:  *
                     70:  */
                     71: 
                     72: /*****************************************************************************/
                     73: /*                                                                          */
                     74: /*                  WRITTEN BY DARYL F. HAZEL      8509.06                  */
                     75: /*                                                                          */
                     76: /*  Modification history:                                                  */
                     77: /*                                                                         */
                     78: /*  Carver 8510.23  Fixed first time allocation of the coord buffer        */
                     79: /*                 to allocate max(200, pathcount) amount insted of just   */
                     80: /*                 200.  Potential Xserver crash problem.                  */
                     81: /*                                                                         */
                     82: /*  Carver 8510.21  Replaced old module by module worked on by Ram Rao and  */
                     83: /*                 Bob Scheifler to get better performace.                 */
                     84: /*                                                                         */
                     85: /*  Carver 8510.03  Changed the curve line converter to return the coord    */
                     86: /*                 path if a successor point does not exist for curve gen. */
                     87: /*                                                                          */
                     88: /*  Carver 8510.03  Fixed memory loss problem.  A coord path is only       */
                     89: /*                 allocated if the current path will not fit in it and    */
                     90: /*                 before the new coord path is allocated the old one is   */
                     91: /*                  freed.                                                 */
                     92: /*                                                                          */
                     93: /*  Carver 8509.24  Fixed pointer/integer mismatch {*ppathaddr_new = ...}   */
                     94: /*                                                                          */
                     95: /*  Corkum 8509.18  Modify code to intergrate into the draw curve command   */
                     96: /*                                                                          */
                     97: /*                  Modified by Mark Lillibridge 5/20/87 to make into       */
                     98: /*                 X11 Xlib XDraw() support.                               */
                     99: /****************************************************************************/
                    100:                                                         
                    101: /*
                    102:  * Definitions:
                    103:  *
                    104:  */
                    105: 
                    106: typedef short   WORD;
                    107: typedef        short   *WORD_POINTER;
                    108: 
                    109: /*
                    110:  * Lookup tables, buffers used in the conversion:
                    111:  *
                    112:  */
                    113: 
                    114: 
                    115: /*
                    116:  * modified path list storage information:
                    117:  */
                    118: static Vertex *pathaddr_new = NULL;  /*pointer to current modified path list*/
                    119: static int pathlist_bytes = 0; /* size of modified path list in bytes       */
                    120: static int pathlist_segs = 0;/* size of modified path list in segments    */
                    121: static Vertex *pathaddr_coords = NULL; /*ptr to path list with coordinates */
                    122: static int path_coord_list_bytes = 0;  /* size of path list (w/coords) buff */
                    123: static int path_coord_list_segs = 0;   /* size of path list (w/coords) buff */
                    124: 
                    125: /*
                    126:  * THE TABLE OF PSEUDO FLOATING-POINT NUMBERS WHICH MAKE UP THE
                    127:  * MULTIPLICATIVE COEFFICIENTS FOR THE CUBIC SPLINE ALGORITHM.
                    128:  */
                    129: static short bntable[] = {  0xfc18, 0x7f97, 0x0476, 0xffde,
                    130:                            0xf8be, 0x7e5d, 0x0972, 0xff76,
                    131:                            0xf5f4, 0x7c56, 0x0eec, 0xfecc,
                    132:                            0xf3ba, 0x7988, 0x14da, 0xfde6,
                    133:                            0xf20b, 0x75fe, 0x1b2f, 0xfcca,
                    134:                            0xf0e2, 0x71c1, 0x21dd, 0xfb81,
                    135:                            0xf038, 0x6ce1, 0x28d3, 0xfa16,
                    136:                            0xf001, 0x676d, 0x3000, 0xf894,
                    137:                            0xf034, 0x6176, 0x3750, 0xf709,
                    138:                            0xf0c3, 0x5b0f, 0x3eae, 0xf583,
                    139:                            0xf1a1, 0x544b, 0x4605, 0xf410,
                    140:                            0xf2c0, 0x4d41, 0x4d41, 0xf2c0,
                    141:                            0xf410, 0x4605, 0x544b, 0xf1a1,
                    142:                            0xf583, 0x3eae, 0x5b0f, 0xf0c3,
                    143:                            0xf709, 0x3750, 0x6176, 0xf034,
                    144:                            0xf894, 0x3000, 0x676d, 0xf001,
                    145:                            0xfa16, 0x28d3, 0x6ce1, 0xf038,
                    146:                            0xfb81, 0x21dd, 0x71c1, 0xf0e2,
                    147:                            0xfcca, 0x1b2f, 0x75fe, 0xf20b,
                    148:                            0xfde6, 0x14da, 0x7988, 0xf3ba,
                    149:                            0xfecc, 0x0eec, 0x7c56, 0xf5f4,
                    150:                            0xff76, 0x0972, 0x7e5d, 0xf8be,
                    151:                            0xffde, 0x0476, 0x7f97, 0xfc18
                    152:                            };
                    153:                            
                    154: /*
                    155:  * this is the table which determines how many straight-line segments to draw
                    156:  * for a given curved segment.
                    157:  */
                    158: static short segtable[] = {  10,  3, 56,       /* pl <= 10, 3 segments     */
                    159:                             32,  4, 40,        /* pl <= 32, 4 segments     */
                    160:                             80,  6, 24,        /* pl <= 80, 6 segments     */
                    161:                             96,  8, 16,        /* pl <= 96, 8 segments     */
                    162:                             192, 12, 8,        /* pl <= 192, 12 segments   */
                    163:                             32767, 24, 00      /* pl <= 32767, 24 segments */
                    164:                           };
                    165:                             
                    166: /*
                    167:  *
                    168:  * The Real routine:
                    169:  *
                    170:  */
                    171:                                                         
                    172: static vertices_converter(pathaddr, pathcount, ppathaddr_new, newpathcnt)
                    173:   Vertex  *pathaddr;       /* address of original path list             */
                    174:   int    pathcount;        /* number of points in original path list    */
                    175:   Vertex  **ppathaddr_new;  /* ptr to addr of new path list      */
                    176:   int     *newpathcnt;     /* ptr to new number of pts in path list */
                    177: {
                    178:   int p0x, p0y;            /* coordinates of curve's predecessor point  */
                    179:   int p1x, p1y;            /* coordinates of curve's starting point     */
                    180:   int p2x, p2y;            /* coordinates of curve's ending point       */
                    181:   int p3x, p3y;            /* coordinates of curve's successor point    */
                    182:   int  flag;               /* flag word of current end-point in p.list  */
                    183:   int successor_x = 0;     /* X coordinate of curve's successor point   */
                    184:   int successor_y = 0;     /* Y coordinate of curve's successor point   */
                    185:   WORD increment;          /* bntable-ptr-increment value       */
                    186:   WORD diffx, diffy;       /* absolute values of x, y end-point diffs   */
                    187:   WORD lmajoraxis;         /* "length" of seg projected onto major axis */
                    188:   union                /* accumulator variables for computing end-points... */
                    189:     {          /* ...using the bntable.                             */
                    190:       struct
                    191:        {
                    192:          WORD low;
                    193:          WORD high;
                    194:        } sword;
                    195:       int lword;
                    196:     } xxe, yye;
                    197:   register Vertex *pnewpath;/* pointer for traversing modified path list */
                    198:   int      newpathcount;   /* number of end-points in modified path list*/
                    199:   register Vertex *pflag;   /* pointer used for looking for fig's last pt*/
                    200:   int      i;              /* general-purpose loop variable             */
                    201:   int      ecf_flag_set;   /* flag indicating existence of set ECF flag */
                    202:   int       count;
                    203:   int      curve_flag;     /* 0 = no curves in path; 1 = curves in path */
                    204:   
                    205:   {
                    206:     register Vertex *poldpath;/* pointer for traversing original path list */
                    207:     register Vertex *p_coord_path; /* ptr to path list with coordinates    */
                    208: 
                    209:     /* Init the return path count to 0 in case of error */
                    210:     *newpathcnt = 0;
                    211:     newpathcount = 0;
                    212:     
                    213:     /* Use path buffers from last time */
                    214:     pnewpath = pathaddr_new;
                    215:     p_coord_path = pathaddr_coords;
                    216:     
                    217:     /*    
                    218:      * if size of coordinate path list buffer is not at least large enough to
                    219:      * accommodate the specified path list, allocate enough memory to do so
                    220:      */
                    221:     if (path_coord_list_segs == 0)             /* first time through*/
                    222:       {
                    223:        path_coord_list_segs = max (200, pathcount);
                    224:        path_coord_list_bytes = path_coord_list_segs * sizeof(Vertex);
                    225:        if ((pathaddr_coords = (Vertex *)Xmalloc(path_coord_list_bytes)) != 0)
                    226:          p_coord_path = pathaddr_coords;
                    227:        else
                    228:          return(ERR_RETURN);
                    229:       }
                    230:     else                               /* all but first time through       */
                    231:       {
                    232:        /* If coord buffer is large enough for this path then reuse it, other
                    233:           wise free the old one and get a new one (Carver) 8510.03 */
                    234:        if (path_coord_list_segs < pathcount)
                    235:          {
                    236:            Xfree( pathaddr_coords);
                    237:            path_coord_list_segs = pathcount;
                    238:            path_coord_list_bytes = path_coord_list_segs * sizeof(Vertex);
                    239:            if ((pathaddr_coords =(Vertex *)Xmalloc(path_coord_list_bytes)) !=0)
                    240:              p_coord_path = pathaddr_coords;
                    241:            else
                    242:              return(ERR_RETURN);
                    243:          };
                    244:       }
                    245: 
                    246:     /*
                    247:      * Copy given Vertex list (pathaddr) to coordinate buffer converting
                    248:      * relative coordinates to absolute coordinates.
                    249:      *
                    250:      * Sets curve_flag iff at least one Vertex has the VertexCurved flag set.
                    251:      * 
                    252:      */
                    253:     
                    254:     poldpath = pathaddr;
                    255:     curve_flag = 0;
                    256:     
                    257:     *p_coord_path = *poldpath++;       /* First Vertex is a special case */
                    258:     p_coord_path->flags = (p_coord_path->flags | VertexDontDraw)
                    259:                           & ~VertexRelative;
                    260:     if ((p_coord_path++)->flags & VertexCurved)
                    261:       curve_flag = 1;
                    262:     for (i = pathcount - 1; i > 0; i--)
                    263:       {
                    264:        if (poldpath->flags & VertexRelative) 
                    265:          {                           /* compute coordinates using last pt */
                    266:            p_coord_path->x = poldpath->x + p_coord_path[-1].x;
                    267:            p_coord_path->y = poldpath->y + p_coord_path[-1].y;
                    268:            p_coord_path->flags = poldpath->flags & ~VertexRelative;
                    269:          }
                    270:        else *p_coord_path++ = *poldpath;
                    271:        if ((poldpath++)->flags & VertexCurved)
                    272:          curve_flag = 1;
                    273:       }            
                    274:   }        /* End of scope for poldaddr, p_coord_path */
                    275: 
                    276:   /*
                    277:    * if it has been determined that there are no curved segment end points in
                    278:    * the specified path list, return the path list containing the coordinates
                    279:    * to the calling routine.
                    280:    */
                    281:   if (!curve_flag)
                    282:     {
                    283:       *newpathcnt    = pathcount;
                    284:       *ppathaddr_new = pathaddr_coords;
                    285:       return(OK_RETURN);
                    286:     }
                    287:   
                    288:   /*
                    289:    * if size of modified path list buffer is not at least large enough to
                    290:    * accommodate the specified path list allocate enough memory to do so
                    291:    */
                    292:   pathaddr = pathaddr_coords;
                    293:   if (pathlist_segs < pathcount)
                    294:     {
                    295:       if (pathlist_segs == 0)           /* Fix storage leak -- MDL 5/20/87 */
                    296:        Xfree( pathaddr_new );
                    297:       pathlist_segs = pathcount;
                    298:       pathlist_bytes = pathcount * sizeof(Vertex);
                    299:       if ((pathaddr_new = (Vertex *)Xmalloc(pathlist_bytes)) != 0)
                    300:        pnewpath = pathaddr_new;
                    301:       else
                    302:        return(ERR_RETURN);
                    303:     }
                    304: 
                    305:   /*
                    306:    * initialize the beginning and ending coordinates of the first segment
                    307:    */
                    308:   p1x = 0;
                    309:   p1y = 0;
                    310:   p2x = 0;
                    311:   p2y = 0;
                    312:   
                    313:   {
                    314:     register WORD *pbntable;   /* table of multiplicative coeffics.*/
                    315:     register WORD *psegtable;  /* table used to detrmn num.sub-segs*/
                    316:     register WORD m;           /* num segments into which curve is divided */
                    317: 
                    318:     /*
                    319:      * MAIN LOOP OF THE PATH_LIST_CONVERTER ROUTINE
                    320:      */
                    321:     for ( count=pathcount ; count > 0; count--)
                    322:       {
                    323:        p0x = p1x;    /* save previous values of path-list coordinate pairs*/
                    324:        p0y = p1y;
                    325:        p1x = p2x;
                    326:        p1y = p2y;
                    327:        
                    328:        /*
                    329:         * read next end-point's coordinates from the path list
                    330:         */
                    331:        p2x = pathaddr->x;
                    332:        p2y = pathaddr->y;
                    333:        flag = (pathaddr++)->flags;
                    334:        
                    335:        /*
                    336:         * CURVED-segment considerations
                    337:         */
                    338:        if (flag & VertexCurved)
                    339:          {
                    340:            /*
                    341:             * determine which point to use as the successor point:  the next
                    342:             * point in the list (if there is one), or a previously-saved point
                    343:             * (when drawing closed figures)
                    344:             */
                    345:            if (flag & VertexEndClosed) /* last segment of closed fig*/
                    346:              {
                    347:                p3x = successor_x;
                    348:                p3y = successor_y;
                    349:              }
                    350:            else                        /* stand-alone curved segment*/
                    351:              {
                    352:                if (count <= 1)         /* no points to use as successor pt */
                    353:                  {
                    354:                    
                    355:                    /* in this case draw the coord path */
                    356:                    *newpathcnt    = pathcount;
                    357:                    *ppathaddr_new = pathaddr_coords;
                    358:                    return(OK_RETURN);
                    359:                  }
                    360:                else
                    361:                  {
                    362:                    /*
                    363:                     * read next end-point's coordinates from the path list...
                    364:                     */
                    365:                    p3x = pathaddr->x;
                    366:                    p3y = pathaddr->y;
                    367:                    
                    368:                    if (flag & VertexStartClosed)
                    369:                      {      /* first segment of closed figure */
                    370:                        /*
                    371:                         * save P3 as successor pt for closed-fig-ending curve
                    372:                         */
                    373:                        successor_x = p3x;
                    374:                        successor_y = p3y;
                    375:                        
                    376:                        /*
                    377:                         * Traverse the original path list looking for ECF flag
                    378:                         * After finding it, back pointer up to previous point
                    379:                         * and save the information for use as curve's pred. pt
                    380:                         */
                    381:                        ecf_flag_set = 0;
                    382:                        pflag = pathaddr;
                    383:                        for (i = count; i > 0; i--)
                    384:                          {
                    385:                            if (pflag->flags & VertexEndClosed)
                    386:                              {
                    387:                                pflag--;
                    388:                                p1x = pflag->x;
                    389:                                p1y = pflag->y;
                    390:                                ecf_flag_set = 1;
                    391:                                break;
                    392:                              }
                    393:                            pflag++;
                    394:                          }
                    395:                        if (!ecf_flag_set)
                    396:                          return(ERR_RETURN);
                    397:                      }     /* end code pertaining to starting figure*/
                    398:                  }         /* end code pertaining to successor points   */
                    399:              }             /* end code pertaining to stand-alone curved segs*/
                    400:            
                    401:            if ((flag & VertexDontDraw) == 0)
                    402:              {
                    403:                /*
                    404:                 * determine the "length" of the segment along the major axis
                    405:                 */
                    406:                if ((diffx = p2x - p1x) < 0)
                    407:                  diffx = ~diffx + 1;
                    408:                if ((diffy = p2y - p1y) < 0)
                    409:                  diffy = ~diffy + 1;
                    410:                lmajoraxis = (diffx >= diffy) ? diffx : diffy;
                    411:                if (lmajoraxis == 0)    /* for vector to have length of...  */
                    412:                  lmajoraxis = 1;       /* ...at least one                  */
                    413:                
                    414:                /*
                    415:                 * compute M, the number of sub-segments into which a curved 
                    416:                 * segment is divided
                    417:                 */
                    418:                psegtable = segtable;
                    419:                while (lmajoraxis > *psegtable++)/* search for appropriate..*/
                    420:                  psegtable += 2;                /* ...table entry          */
                    421:                m = *psegtable++;                /* read number of segments */
                    422:                increment = *psegtable >> 1;
                    423:                
                    424:                /*
                    425:                 * determine if there is enough room remaining in the modified
                    426:                 * path-list buffer to hold ALL of the curve's sub-segment in-
                    427:                 * formation; if not, double the buffer size (if possible).
                    428:                 */
                    429:                while ((newpathcount + m) > pathlist_segs)
                    430:                  {
                    431:                    pathlist_segs *= 2;
                    432:                    pathlist_bytes *= 2;
                    433:                    if ((pathaddr_new = (Vertex *)Xrealloc(pathaddr_new, 
                    434:                                                         pathlist_bytes)) != 0)
                    435:                      pnewpath = pathaddr_new + newpathcount;
                    436:                    else
                    437:                      return(ERR_RETURN);
                    438:                  }
                    439:                
                    440:                /*
                    441:                 * generate end-points of sub-segs into which curve is divided
                    442:                 */
                    443:                pbntable = bntable; /* initialize the pointer to the Bn table*/
                    444:                for ( ; m > 1; m--)
                    445:                  {
                    446:                    pbntable += increment;
                    447:                    xxe.lword = *pbntable * p0x;
                    448:                    yye.lword = *pbntable++ * p0y;
                    449:                    xxe.lword += *pbntable * p1x;
                    450:                    yye.lword += *pbntable++ * p1y;
                    451:                    xxe.lword += *pbntable * p2x;
                    452:                    yye.lword += *pbntable++ * p2y;
                    453:                    xxe.lword += *pbntable * p3x;
                    454:                    yye.lword += *pbntable++ * p3y;
                    455:                    xxe.lword = xxe.lword << 1; /* double values...  */
                    456:                    yye.lword = yye.lword << 1; /* ...bn accts for it*/
                    457:                    xxe.lword += 0x8000; /* round off the accum value */
                    458:                    yye.lword += 0x8000;
                    459:                    pnewpath->x = xxe.sword.high;/* the X coordinate  */
                    460:                    pnewpath->y = yye.sword.high;/* the Y coordinate  */
                    461:                    (pnewpath++)->flags = 0;    /* the flag word     */
                    462:                    newpathcount++;/* increment segment end-point countr*/
                    463:                  }                /* end sub-segment end-point compute loop*/
                    464:              }            /* end DRAW-segment considerations code      */
                    465:          }                /* end CURVED-segment considerations code        */
                    466:        
                    467:        /*
                    468:         * put end-point from original path list into modified list
                    469:         */
                    470:        pnewpath->x = p2x;
                    471:        pnewpath->y = p2y;
                    472:        (pnewpath++)->flags = flag & ~VertexCurved;
                    473:        newpathcount++;
                    474:        
                    475:        /*
                    476:         * determine whether or not the modified path list is full, and if so,
                    477:         * double its size
                    478:         */
                    479:        if (newpathcount == pathlist_segs)
                    480:          {
                    481:            pathlist_bytes *= 2;
                    482:            pathlist_segs *= 2;
                    483:            if ((pathaddr_new = (Vertex *)Xrealloc(pathaddr_new, 
                    484:                                                 pathlist_bytes)) != 0)
                    485:              pnewpath = pathaddr_new + newpathcount;
                    486:            else
                    487:              return(ERR_RETURN);
                    488:          }
                    489:       }                    /* END of PATH_LIST_CONVERTER's main loop        */
                    490:     
                    491:     /*
                    492:      * return the address of the modified path list and the number of segment
                    493:      * end-points it contains
                    494:      */
                    495:     *newpathcnt    = newpathcount;
                    496:     *ppathaddr_new = pathaddr_new;
                    497:   }    
                    498: 
                    499:   return(OK_RETURN);
                    500: }
                    501: 
                    502: /* Written by Mark Lillibridge */
                    503: 
                    504: static XPoint *XDraw_points = NULL;    /* Buffer to hold list of points for */
                    505: static int    point_count = 0;         /* use in calling XDrawLines         */
                    506: 
                    507: Status XDraw (dpy, d, gc, vlist, vcount)
                    508:     register Display *dpy;
                    509:     Drawable d;
                    510:     GC gc;
                    511:     Vertex *vlist;
                    512:     int vcount;
                    513: {
                    514:   Vertex *newvlist;
                    515:   int newvcount;
                    516:   XPoint *p;
                    517:   int pcount;
                    518: 
                    519:   /* If less than 2 vertices, we don't have to do anything (no lines) */
                    520:   if (vcount<2)
                    521:     return(OK_RETURN);
                    522: 
                    523:   /* Convert curved lines to straight lines & change relative references to */
                    524:   /* absolute references. */
                    525:   if (!vertices_converter( vlist, vcount, &newvlist, &newvcount))
                    526:     return(ERR_RETURN);
                    527: 
                    528:   /* Insure we have enough buffer space */
                    529:   if (point_count < newvcount) {
                    530:     if (point_count != 0)
                    531:       Xfree( XDraw_points );
                    532:     if (!(XDraw_points = (XPoint *) Xmalloc( newvcount * sizeof(XPoint) )))
                    533:       return(ERR_RETURN);
                    534:     point_count = newvcount;
                    535:   }
                    536: 
                    537:   /*
                    538:    * Draw the lines defined by newvlist using seperate XDrawLines calls
                    539:    * to insure that all the lines that should be joined are and that closed
                    540:    * figures are joined correctly.
                    541:    */
                    542:   while (newvcount>0) {
                    543:     p = XDraw_points;               /* Put points in buffer */
                    544:     pcount = 0;
                    545:     p->x = newvlist->x;             /* Copy first point */
                    546:     (p++)->y = (newvlist++)->y;
                    547:     newvcount--; pcount++;
                    548: 
                    549:     /*
                    550:      * Copy more points until out of points or need to stop XDrawLine
                    551:      * because either we don't want to join to the next point
                    552:      * (VertexDontDraw) or we want to stop after the next point so that
                    553:      * a closed figure will be joined correctly.  (We have to stop before
                    554:      * a VertexStartClosed because the vertex marked VertexStartClosed
                    555:      * must be the first vertex in its XDrawLines call to get joining
                    556:      * to work correctly.
                    557:      */
                    558:     while (newvcount > 0 && !(newvlist->flags & (VertexDontDraw |
                    559:                                                 VertexStartClosed |
                    560:                                                 VertexEndClosed))) {
                    561:       p->x = newvlist->x;
                    562:       (p++)->y = (newvlist++)->y;
                    563:       newvcount--; pcount++;
                    564:     }
                    565: 
                    566:     /*
                    567:      * If stopped only because of need to start a new XDrawLines, copy
                    568:      * next point but don't advance pointer so two XdrawLines act like one.
                    569:      */
                    570:     if ( newvcount > 0 && !(newvlist->flags & VertexDontDraw) ) {
                    571:       p->x = newvlist->x;
                    572:       (p++)->y = newvlist->y;
                    573:       pcount++;
                    574:     }
                    575: 
                    576:     /* Do the XDrawLines if there are any lines to draw */
                    577:     if (pcount>1)
                    578:       XDrawLines(dpy, d, gc, XDraw_points, pcount, CoordModeOrigin);
                    579:   }
                    580: 
                    581:   return(OK_RETURN);
                    582: }
                    583: 
                    584: Status XDrawFilled (dpy, d, gc, vlist, vcount)
                    585:     register Display *dpy;
                    586:     Drawable d;
                    587:     GC gc;
                    588:     Vertex *vlist;
                    589:     int vcount;
                    590: {
                    591:   Vertex *newvlist;
                    592:   int newvcount;
                    593:   XPoint *p;
                    594:   int pcount;
                    595:   int closed;
                    596: 
                    597:   /* If less than 2 vertices, we don't have to do anything (no lines) */
                    598:   if (vcount<2)
                    599:     return(OK_RETURN);
                    600: 
                    601:   /* Convert curved lines to straight lines & change relative references to */
                    602:   /* absolute references. */
                    603:   if (!vertices_converter( vlist, vcount, &newvlist, &newvcount))
                    604:     return(ERR_RETURN);
                    605: 
                    606:   /* Insure we have enough buffer space */
                    607:   if (point_count < newvcount) {
                    608:     if (point_count != 0)
                    609:       Xfree( XDraw_points );
                    610:     if (!(XDraw_points = (XPoint *) Xmalloc( newvcount * sizeof(XPoint) )))
                    611:       return(ERR_RETURN);
                    612:     point_count = newvcount;
                    613:   }
                    614: 
                    615:   /*
                    616:    * Draw the lines defined by newvlist using seperate XDrawLines calls
                    617:    * to insure that all the lines that should be joined are and that closed
                    618:    * figures are joined correctly.
                    619:    */
                    620:   while (newvcount>0) {
                    621:     p = XDraw_points;               /* Put points in buffer */
                    622:     pcount = 0;
                    623:     closed = newvlist->flags & VertexStartClosed;
                    624:     p->x = newvlist->x;             /* Copy first point */
                    625:     (p++)->y = (newvlist++)->y;
                    626:     newvcount--; pcount++;
                    627: 
                    628:     /*
                    629:      * Copy more points until out of points or need to stop XDrawLine
                    630:      * because either we don't want to join to the next point
                    631:      * (VertexDontDraw) or we want to stop after the next point so that
                    632:      * a closed figure will be joined correctly.  (We have to stop before
                    633:      * a VertexStartClosed because the vertex marked VertexStartClosed
                    634:      * must be the first vertex in its XDrawLines call to get joining
                    635:      * to work correctly.
                    636:      */
                    637:     while (newvcount > 0 && !(newvlist->flags & (VertexDontDraw |
                    638:                                                 VertexStartClosed |
                    639:                                                 VertexEndClosed))) {
                    640:       p->x = newvlist->x;
                    641:       (p++)->y = (newvlist++)->y;
                    642:       newvcount--; pcount++;
                    643:     }
                    644: 
                    645:     /*
                    646:      * If stopped only because of need to start a new XDrawLines, copy
                    647:      * next point but don't advance pointer so two XdrawLines act like one.
                    648:      */
                    649:     if ( newvcount > 0 && !(newvlist->flags & VertexDontDraw) ) {
                    650:       p->x = newvlist->x;
                    651:       (p++)->y = newvlist->y;
                    652:       pcount++;
                    653:     }
                    654: 
                    655:     /* Do the XDrawLines if there are any lines to draw */
                    656:     if (pcount>1) {
                    657:        if (closed)
                    658:          XFillPolygon(dpy, d, gc, XDraw_points, pcount, Complex,
                    659:                       CoordModeOrigin);
                    660:        else
                    661:          XDrawLines(dpy, d, gc, XDraw_points, pcount, CoordModeOrigin);
                    662:     }
                    663:   }
                    664: 
                    665:   return(OK_RETURN);
                    666: }

unix.superglobalmegacorp.com

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