Annotation of researchv9/X11/src/X.V11R1/lib/oldX/XDraw.c, revision 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.