Annotation of researchv9/X11/src/X.V11R1/server/ddx/mfb/mfbline.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: /* $Header: mfbline.c,v 1.34 87/09/11 07:21:06 toddb Exp $ */
                     25: #include "X.h"
                     26: 
                     27: #include "gcstruct.h"
                     28: #include "windowstr.h"
                     29: #include "pixmapstr.h"
                     30: #include "regionstr.h"
                     31: #include "scrnintstr.h"
                     32: #include "mistruct.h"
                     33: 
                     34: #include "mfb.h"
                     35: #include "maskbits.h"
                     36: 
                     37: /* single-pixel lines on a monochrome frame buffer
                     38: 
                     39:    NON-SLOPED LINES
                     40:    horizontal lines are always drawn left to right; we have to
                     41: move the endpoints right by one after they're swapped.
                     42:    horizontal lines will be confined to a single band of a
                     43: region.  the code finds that band (giving up if the lower
                     44: bound of the band is above the line we're drawing); then it
                     45: finds the first box in that band that contains part of the
                     46: line.  we clip the line to subsequent boxes in that band.
                     47:    vertical lines are always drawn top to bottom (y-increasing.)
                     48: this requires adding one to the y-coordinate of each endpoint
                     49: after swapping.
                     50: 
                     51:    SLOPED LINES
                     52:    when clipping a sloped line, we bring the second point inside
                     53: the clipping box, rather than one beyond it, and then add 1 to
                     54: the length of the line before drawing it.  this lets us use
                     55: the same box for finding the outcodes for both endpoints.  since
                     56: the equation for clipping the second endpoint to an edge gives us
                     57: 1 beyond the edge, we then have to move the point towards the
                     58: first point by one step on the major axis.
                     59:    eventually, there will be a diagram here to explain what's going
                     60: on.  the method uses Cohen-Sutherland outcodes to determine
                     61: outsideness, and a method similar to Pike's layers for doing the
                     62: actual clipping.
                     63: 
                     64:    DIVISION
                     65:    When clipping the lines, we want to round the answer, rather
                     66: than truncating.  We want to avoid floating point; we also
                     67: want to avoid the special code required when the dividend
                     68: and divisor have different signs.
                     69: 
                     70:     we work a little to make all the numbers in the division
                     71: positive.  we then use the signs of the major and minor axes
                     72: decide whether to add or subtract.  this takes the special-case 
                     73: code out of the rounding division (making it easier for a 
                     74: compiler or inline to do something clever).
                     75: 
                     76:    CEILING
                     77:    someties, we want the ceiling.  ceil(m/n) == floor((m+n-1)/n),
                     78: for n > 0.  in C, integer division results in floor.]
                     79: 
                     80:    MULTIPLICATION
                     81:    when multiplying by signdx or signdy, we KNOW that it will
                     82: be a multiplication by 1 or -1, but most compilers can't
                     83: figure this out.  if your compiler/hardware combination
                     84: does better at the ?: operator and 'move negated' instructions
                     85: that it does at multiplication, you should consider using
                     86: the alternate macros.
                     87: 
                     88:    OPTIMIZATION
                     89:    there has been no attempt to optimize this code.  there
                     90: are obviously many special cases, at the cost of increased
                     91: code space.  a few inline procedures (e.g. round, SignTimes,
                     92: ceiling, abs) would be very useful, since the macro expansions
                     93: are not very intelligent.
                     94: */
                     95: 
                     96: /* NOTE
                     97:    maybe OUTCODES should take box (the one that includes all
                     98: edges) instead of pbox (the standard no-right-or-lower-edge one)?
                     99: */
                    100: #define OUTCODES(result, x, y, pbox) \
                    101:     if (x < pbox->x1) \
                    102:        result |= OUT_LEFT; \
                    103:     if (y < pbox->y1) \
                    104:        result |= OUT_ABOVE; \
                    105:     if (x >= pbox->x2) \
                    106:        result |= OUT_RIGHT; \
                    107:     if (y >= pbox->y2) \
                    108:        result |= OUT_BELOW;
                    109: 
                    110: #define round(dividend, divisor) \
                    111: ( (((dividend)<<1) + (divisor)) / ((divisor)<<1) )
                    112: 
                    113: #define ceiling(m,n) ( ((m) + (n) -1)/(n) )
                    114: 
                    115: #define SignTimes(sign, n) ((sign) * (n))
                    116: 
                    117: /*
                    118: #define SignTimes(sign, n) \
                    119:     ( ((sign)<0) ? -(n) : (n) )
                    120: */
                    121: 
                    122: #define SWAPPT(p1, p2, pttmp) \
                    123: pttmp = p1; \
                    124: p1 = p2; \
                    125: p2 = pttmp;
                    126: 
                    127: #define SWAPINT(i, j, t) \
                    128: t = i; \
                    129: i = j; \
                    130: j = t;
                    131: 
                    132: void
                    133: mfbLineSS(pDrawable, pGC, mode, npt, pptInit)
                    134:     DrawablePtr pDrawable;
                    135:     GCPtr pGC;
                    136:     int mode;          /* Origin or Previous */
                    137:     int npt;           /* number of points */
                    138:     DDXPointPtr pptInit;
                    139: {
                    140:     int nboxInit;
                    141:     register int nbox;
                    142:     BoxPtr pboxInit;
                    143:     register BoxPtr pbox;
                    144:     int nptTmp;
                    145:     DDXPointPtr ppt;           /* pointer to list of translated points */
                    146: 
                    147:     DDXPointRec pt1;
                    148:     DDXPointRec pt2;
                    149: 
                    150:     unsigned int oc1;          /* outcode of point 1 */
                    151:     unsigned int oc2;          /* outcode of point 2 */
                    152: 
                    153:     int *addrl;                        /* address of longword with first point */
                    154:     int nlwidth;               /* width in longwords of destination bitmap */
                    155:     int xorg, yorg;            /* origin of window */
                    156: 
                    157:     int adx;           /* abs values of dx and dy */
                    158:     int ady;
                    159:     int signdx;                /* sign of dx and dy */
                    160:     int signdy;
                    161:     int e, e1, e2;             /* bresenham error and increments */
                    162:     int len;                   /* length of segment */
                    163:     int axis;                  /* major axis */
                    164: 
                    165:     int clipDone;              /* flag for clipping loop */
                    166:     DDXPointRec pt1Orig;       /* unclipped start point */
                    167:     DDXPointRec pt2Orig;       /* unclipped end point */
                    168:     int err;                   /* modified bresenham error term */
                    169:     int clip1, clip2;          /* clippedness of the endpoints */
                    170: 
                    171:     int clipdx, clipdy;                /* difference between clipped and
                    172:                                   unclipped start point */
                    173: 
                    174:                                /* a bunch of temporaries */
                    175:     int tmp;
                    176:     int x1, x2, y1, y2;
                    177: 
                    178:     pboxInit = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->rects;
                    179:     nboxInit = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->numRects;
                    180: 
                    181:     if (pDrawable->type == DRAWABLE_WINDOW)
                    182:     {
                    183:        xorg = ((WindowPtr)pDrawable)->absCorner.x;
                    184:        yorg = ((WindowPtr)pDrawable)->absCorner.y;
                    185:        addrl = (int *)
                    186:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    187:        nlwidth = (int)
                    188:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    189:     }
                    190:     else
                    191:     {
                    192:        xorg = 0;
                    193:        yorg = 0;
                    194:        addrl = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    195:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    196:     }
                    197: 
                    198:     /* translate the point list */
                    199:     ppt = pptInit;
                    200:     nptTmp = npt;
                    201:     if (mode == CoordModeOrigin)
                    202:     {
                    203:        while(nptTmp--)
                    204:        {
                    205:            ppt->x += xorg;
                    206:            ppt++->y += yorg;
                    207:        }
                    208:     }
                    209:     else
                    210:     {
                    211:        ppt->x += xorg;
                    212:        ppt->y += yorg;
                    213:        nptTmp--;
                    214:        while(nptTmp--)
                    215:        {
                    216:            ppt++;
                    217:            ppt->x += (ppt-1)->x;
                    218:            ppt->y += (ppt-1)->y;
                    219:        }
                    220:     }
                    221: 
                    222:     ppt = pptInit;
                    223:     while(--npt)
                    224:     {
                    225:        nbox = nboxInit;
                    226:        pbox = pboxInit;
                    227: 
                    228:        pt1 = *ppt++;
                    229:        pt2 = *ppt;
                    230: 
                    231:        if (pt1.x == pt2.x)
                    232:        {
                    233:            /* make the line go top to bottom of screen, keeping
                    234:               endpoint semantics
                    235:            */
                    236:            if (pt1.y > pt2.y)
                    237:            {
                    238:                tmp = pt2.y;
                    239:                pt2.y = pt1.y + 1;
                    240:                pt1.y = tmp + 1;
                    241:            }
                    242: 
                    243:            /* get to first band that might contain part of line */
                    244:            while ((nbox) && (pbox->y2 <= pt1.y))
                    245:            {
                    246:                pbox++;
                    247:                nbox--;
                    248:            }
                    249: 
                    250:            if (nbox)
                    251:            {
                    252:                /* stop when lower edge of box is beyond end of line */
                    253:                while((nbox) && (pt2.y >= pbox->y1))
                    254:                {
                    255:                    if ((pt1.x >= pbox->x1) && (pt1.x < pbox->x2))
                    256:                    {
                    257:                        /* this box has part of the line in it */
                    258:                        y1 = max(pt1.y, pbox->y1);
                    259:                        y2 = min(pt2.y, pbox->y2);
                    260:                        if (y1 != y2)
                    261:                        {
                    262:                            mfbVertS( ((mfbPrivGC *)(pGC->devPriv))->rop,
                    263:                                      addrl, nlwidth, 
                    264:                                      pt1.x, y1, y2-y1);
                    265:                        }
                    266:                    }
                    267:                    nbox--;
                    268:                    pbox++;
                    269:                }
                    270:            }
                    271: 
                    272:        }
                    273:        else if (pt1.y == pt2.y)
                    274:        {
                    275:            /* force line from left to right, keeping
                    276:               endpoint semantics
                    277:            */
                    278:            if (pt1.x > pt2.x)
                    279:            {
                    280:                tmp = pt2.x;
                    281:                pt2.x = pt1.x + 1;
                    282:                pt1.x = tmp + 1;
                    283:            }
                    284: 
                    285:            /* find the correct band */
                    286:            while( (nbox) && (pbox->y2 <= pt1.y))
                    287:            {
                    288:                pbox++;
                    289:                nbox--;
                    290:            }
                    291: 
                    292:            /* try to draw the line, if we haven't gone beyond it */
                    293:            if ((nbox) && (pbox->y1 <= pt1.y))
                    294:            {
                    295:                /* when we leave this band, we're done */
                    296:                tmp = pbox->y1;
                    297:                while((nbox) && (pbox->y1 == tmp))
                    298:                {
                    299:                    if (pbox->x2 <= pt1.x)
                    300:                    {
                    301:                        /* skip boxes until one might contain start point */
                    302:                        nbox--;
                    303:                        pbox++;
                    304:                        continue;
                    305:                    }
                    306: 
                    307:                    /* stop if left of box is beyond right of line */
                    308:                    if (pbox->x1 >= pt2.x)
                    309:                    {
                    310:                        nbox = 0;
                    311:                        continue;
                    312:                    }
                    313: 
                    314:                    x1 = max(pt1.x, pbox->x1);
                    315:                    x2 = min(pt2.x, pbox->x2);
                    316:                    if (x1 != x2)
                    317:                    {
                    318:                        mfbHorzS( ((mfbPrivGC *)(pGC->devPriv))->rop,
                    319:                                  addrl, nlwidth, 
                    320:                                  x1, pt1.y, x2-x1);
                    321:                    }
                    322:                    nbox--;
                    323:                    pbox++;
                    324:                }
                    325:            }
                    326:        }
                    327:        else    /* sloped line */
                    328:        {
                    329: 
                    330:            adx = pt2.x - pt1.x;
                    331:            ady = pt2.y - pt1.y;
                    332:            signdx = sign(adx);
                    333:            signdy = sign(ady);
                    334:            adx = abs(adx);
                    335:            ady = abs(ady);
                    336: 
                    337:            if (adx > ady)
                    338:            {
                    339:                axis = X_AXIS;
                    340:                e1 = ady*2;
                    341:                e2 = e1 - 2*adx;
                    342:                e = e1 - adx;
                    343: 
                    344:            }
                    345:            else
                    346:            {
                    347:                axis = Y_AXIS;
                    348:                e1 = adx*2;
                    349:                e2 = e1 - 2*ady;
                    350:                e = e1 - ady;
                    351:            }
                    352: 
                    353:            /* we have bresenham parameters and two points.
                    354:               all we have to do now is clip and draw.
                    355:            */
                    356: 
                    357:            pt1Orig = pt1;
                    358:            pt2Orig = pt2;
                    359: 
                    360:            while(nbox--)
                    361:            {
                    362: 
                    363:                BoxRec box;
                    364: 
                    365:                pt1 = pt1Orig;
                    366:                pt2 = pt2Orig;
                    367:                clipDone = 0;
                    368:                box.x1 = pbox->x1;
                    369:                box.y1 = pbox->y1;
                    370:                box.x2 = pbox->x2-1;
                    371:                box.y2 = pbox->y2-1;
                    372:                clip1 = 0;
                    373:                clip2 = 0;
                    374: 
                    375:                oc1 = 0;
                    376:                oc2 = 0;
                    377:                OUTCODES(oc1, pt1.x, pt1.y, pbox);
                    378:                OUTCODES(oc2, pt2.x, pt2.y, pbox);
                    379: 
                    380:                if (oc1 & oc2)
                    381:                    clipDone = -1;
                    382:                else if ((oc1 | oc2) == 0)
                    383:                    clipDone = 1;
                    384:                else /* have to clip */
                    385:                    clipDone = mfbClipLine(pbox, box,
                    386:                                           &pt1Orig, &pt1, &pt2, 
                    387:                                           adx, ady, signdx, signdy, axis,
                    388:                                           &clip1, &clip2);
                    389: 
                    390:                if (clipDone == -1)
                    391:                {
                    392:                    pbox++;
                    393:                }
                    394:                else
                    395:                {
                    396: 
                    397:                    if (axis == X_AXIS)
                    398:                        len = abs(pt2.x - pt1.x);
                    399:                    else
                    400:                        len = abs(pt2.y - pt1.y);
                    401: 
                    402:                    len += (clip2 != 0);
                    403:                    if (len)
                    404:                    {
                    405:                        /* unwind bresenham error term to first point */
                    406:                        if (clip1)
                    407:                        {
                    408:                            clipdx = abs(pt1.x - pt1Orig.x);
                    409:                            clipdy = abs(pt1.y - pt1Orig.y);
                    410:                            if (axis == X_AXIS)
                    411:                                err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
                    412:                            else
                    413:                                err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
                    414:                        }
                    415:                        else
                    416:                            err = e;
                    417:                        mfbBresS( ((mfbPrivGC *)(pGC->devPriv))->rop,
                    418:                                  addrl, nlwidth,
                    419:                                  signdx, signdy, axis, pt1.x, pt1.y,
                    420:                                  err, e1, e2, len);
                    421:                    }
                    422: 
                    423:                    /* if segment is unclipped, skip remaining rectangles */
                    424:                    if (!(clip1 || clip2))
                    425:                        break;
                    426:                    else
                    427:                        pbox++;
                    428:                }
                    429:            } /* while (nbox--) */
                    430:        } /* sloped line */
                    431:     } /* while (nline--) */
                    432: 
                    433:     /* paint the last point if the end style isn't CapNotLast.
                    434:        (Assume that a projecting, butt, or round cap that is one
                    435:         pixel wide is the same as the single pixel of the endpoint.)
                    436:     */
                    437: 
                    438:     if ((pGC->capStyle != CapNotLast) &&
                    439:        ((ppt->x != pptInit->x) ||
                    440:         (ppt->y != pptInit->y)))
                    441:     {
                    442:        pt1 = *ppt;
                    443: 
                    444:        nbox = nboxInit;
                    445:        pbox = pboxInit;
                    446:        while (nbox--)
                    447:        {
                    448:            if ((pt1.x >= pbox->x1) &&
                    449:                (pt1.y >= pbox->y1) &&
                    450:                (pt1.x <  pbox->x2) &&
                    451:                (pt1.y <  pbox->y2))
                    452:            {
                    453:                addrl += (pt1.y * nlwidth) + (pt1.x >> 5);
                    454:                switch( ((mfbPrivGC *)(pGC->devPriv))->rop)
                    455:                {
                    456:                    case RROP_BLACK:
                    457:                        *addrl &= rmask[pt1.x & 0x1f];
                    458:                        break;
                    459:                    case RROP_WHITE:
                    460:                        *addrl |= mask[pt1.x & 0x1f];
                    461:                        break;
                    462:                    case RROP_INVERT:
                    463:                        *addrl ^= mask[pt1.x & 0x1f];
                    464:                        break;
                    465:                }
                    466:                break;
                    467:            }
                    468:            else
                    469:                pbox++;
                    470:        }
                    471:     }
                    472: }
                    473: 
                    474: 
                    475: /*
                    476:     this code does not pretend to be efficient, but it does recycle a
                    477: lot of the line code and use the miDashLine() code too.  a better
                    478: implementation is to use the solid line code to clip and
                    479: translate, and then call mfbBresD(), to do the dashes as the
                    480: line is drawn.  a Bres() procedure entry in the devPrivate
                    481: part of the GC would make this easy to do, as well as possibly speeding
                    482: up solid lines to (by avoiding the test of rrop for each segment.)
                    483: 
                    484:     to do double dashes we concoct a rop for the (alu, bg) pair.
                    485: 
                    486:     the error term at the start of each dash is computed for us by
                    487: miDashLine.  if the segment we draw is not clipped, we can use this
                    488: error term; if the first point of the dash is clipped, we have to
                    489: calculate a new error term based on e at the first point of the line.
                    490: */
                    491: 
                    492: void
                    493: mfbDashLine( pDrawable, pGC, mode, npt, pptInit)
                    494:     DrawablePtr pDrawable;
                    495:     GCPtr pGC;
                    496:     int mode;          /* Origin or Previous */
                    497:     int npt;           /* number of points */
                    498:     DDXPointPtr pptInit;
                    499: {
                    500:     int nseg;                  /* number of dashed segments */
                    501:     miDashPtr pdash;           /* list of dashes */
                    502:     miDashPtr pdashInit;
                    503:     int fgRop;                 /* reduced rasterop for even dash */
                    504:     int bgRop;                 /* reduced rasterop for odd dash */
                    505:     int rop;
                    506: 
                    507:     int nboxInit;
                    508:     int nbox;
                    509:     BoxPtr pboxInit;
                    510:     BoxPtr pbox;
                    511:     int nptTmp;
                    512:     DDXPointPtr ppt;           /* pointer to list of translated points */
                    513: 
                    514:     DDXPointRec pt1;
                    515:     DDXPointRec pt2;
                    516: 
                    517:     unsigned int oc1;          /* outcode of point 1 */
                    518:     unsigned int oc2;          /* outcode of point 2 */
                    519: 
                    520:     int *addrl;                        /* address of longword with first point */
                    521:     int nlwidth;               /* width in longwords of destination bitmap */
                    522:     int xorg, yorg;            /* origin of window */
                    523: 
                    524:                                /* these are all per original line */
                    525:     int adx;                   /* abs values of dx and dy */
                    526:     int ady;
                    527:     int signdx;                        /* sign of dx and dy */
                    528:     int signdy;
                    529:     int e;                     /* error term for first point of
                    530:                                   original line */
                    531:     int e1, e2;                        /* i wonder what these are? */
                    532: 
                    533: 
                    534:                                /* these are all per dash */
                    535:     int err;                   /* bres error term for first drawn point */
                    536:     int len;                   /* length of segment */
                    537:     int axis;                  /* major axis */
                    538: 
                    539:     int clipDone;              /* flag for clipping loop */
                    540:     DDXPointRec pt1Orig;       /* unclipped start point */
                    541:     int clip1, clip2;          /* clippedness of the endpoints */
                    542: 
                    543:     int clipdx, clipdy;                /* difference between clipped and
                    544:                                   unclipped start point */
                    545: 
                    546: 
                    547:     pboxInit = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->rects;
                    548:     nboxInit = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->numRects;
                    549: 
                    550:     if (pDrawable->type == DRAWABLE_WINDOW)
                    551:     {
                    552:        xorg = ((WindowPtr)pDrawable)->absCorner.x;
                    553:        yorg = ((WindowPtr)pDrawable)->absCorner.y;
                    554:        addrl = (int *)
                    555:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    556:        nlwidth = (int)
                    557:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    558:     }
                    559:     else
                    560:     {
                    561:        xorg = 0;
                    562:        yorg = 0;
                    563:        addrl = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    564:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    565:     }
                    566: 
                    567:     /* translate the point list */
                    568:     ppt = pptInit;
                    569:     nptTmp = npt;
                    570:     if (mode == CoordModeOrigin)
                    571:     {
                    572:        while(nptTmp--)
                    573:        {
                    574:            ppt->x += xorg;
                    575:            ppt++->y += yorg;
                    576:        }
                    577:     }
                    578:     else
                    579:     {
                    580:        ppt->x += xorg;
                    581:        ppt->y += yorg;
                    582:        nptTmp--;
                    583:        while(nptTmp--)
                    584:        {
                    585:            ppt++;
                    586:            ppt->x += (ppt-1)->x;
                    587:            ppt->y += (ppt-1)->y;
                    588:        }
                    589:     }
                    590: 
                    591: 
                    592:     pdash = miDashLine(npt, pptInit, 
                    593:                       pGC->numInDashList, pGC->dash, pGC->dashOffset,
                    594:                       &nseg);
                    595:     pdashInit = pdash;
                    596: 
                    597:     if (pGC->lineStyle == LineOnOffDash)
                    598:     {
                    599:        rop = ((mfbPrivGC *)(pGC->devPriv))->rop;
                    600:     }
                    601:     else
                    602:     {
                    603:        fgRop = ((mfbPrivGC *)(pGC->devPriv))->rop;
                    604:        bgRop = ReduceRop(pGC->alu, pGC->bgPixel);
                    605:     }
                    606: 
                    607:     while(nseg--)
                    608:     {
                    609:        if (pGC->lineStyle == LineOnOffDash)
                    610:        {
                    611:            while ((nseg) && (pdash->which == ODD_DASH))
                    612:            {
                    613:                if (pdash->newLine)
                    614:                {
                    615:                    pt1Orig = pt1 = *pptInit++;
                    616:                    pt2 = *pptInit;
                    617:                    adx = pt2.x - pt1.x;
                    618:                    ady = pt2.y - pt1.y;
                    619:                    signdx = sign(adx);
                    620:                    signdy = sign(ady);
                    621:                    adx = abs(adx);
                    622:                    ady = abs(ady);
                    623:                    e = pdash->e;
                    624:                    e1 = pdash->e1;
                    625:                    e2 = pdash->e2;
                    626:                    if (adx > ady)
                    627:                        axis = X_AXIS;
                    628:                    else
                    629:                        axis = Y_AXIS;
                    630:                }
                    631:                nseg--;
                    632:                pdash++;
                    633:            }
                    634:            /* ??? is this right ??? */
                    635:            if (!nseg)
                    636:                break;
                    637:        }
                    638:        else if (pGC->lineStyle == LineDoubleDash)
                    639:        {
                    640:            /* use a different color for odd dashes */
                    641:            if (pdash->which == EVEN_DASH)
                    642:                rop = fgRop;
                    643:            else
                    644:                rop = bgRop;
                    645: 
                    646:        }
                    647: 
                    648:        if (pdash->newLine)
                    649:        {
                    650:            pt1Orig = pt1 = *pptInit++;
                    651:            pt2 = *pptInit;
                    652:            adx = pt2.x - pt1.x;
                    653:            ady = pt2.y - pt1.y;
                    654:            signdx = sign(adx);
                    655:            signdy = sign(ady);
                    656:            adx = abs(adx);
                    657:            ady = abs(ady);
                    658:            e = pdash->e;
                    659:            e1 = pdash->e1;
                    660:            e2 = pdash->e2;
                    661:            if (adx > ady)
                    662:                axis = X_AXIS;
                    663:            else
                    664:                axis = Y_AXIS;
                    665:        }
                    666: 
                    667:        nbox = nboxInit;
                    668:        pbox = pboxInit;
                    669:        while(nbox--)
                    670:        {
                    671:            BoxRec box;
                    672: 
                    673:            clipDone = 0;
                    674:            pt1 = pdash->pt;
                    675:            pt2 = (pdash+1)->pt;
                    676:            box.x1 = pbox->x1;
                    677:            box.y1 = pbox->y1;
                    678:            box.x2 = pbox->x2-1;
                    679:            box.y2 = pbox->y2-1;
                    680:            clip1 = 0;
                    681:            clip2 = 0;
                    682: 
                    683:            oc1 = 0;
                    684:            oc2 = 0;
                    685:            OUTCODES(oc1, pt1.x, pt1.y, pbox);
                    686:            OUTCODES(oc2, pt2.x, pt2.y, pbox);
                    687: 
                    688:            if (oc1 & oc2)
                    689:                clipDone = -1;
                    690:            else if ((oc1 | oc2) == 0)
                    691:                clipDone = 1;
                    692:            else /* have to clip */
                    693:                clipDone = mfbClipLine(pbox, box,
                    694:                                       &pt1Orig, &pt1, &pt2, 
                    695:                                       adx, ady, signdx, signdy, axis,
                    696:                                       &clip1, &clip2);
                    697: 
                    698:            if (clipDone == -1)
                    699:            {
                    700:                    pbox++;
                    701:            }
                    702:            else
                    703:            {
                    704:                if (axis == X_AXIS)
                    705:                    len = abs(pt2.x - pt1.x);
                    706:                else
                    707:                    len = abs(pt2.y - pt1.y);
                    708: 
                    709:                len += (clip2 != 0);
                    710:                if (len)
                    711:                {
                    712:                    if (clip1)
                    713:                    {
                    714:                        /* unwind bres error term to first visible point */
                    715:                        clipdx = abs(pt1.x - pt1Orig.x);
                    716:                        clipdy = abs(pt1.y - pt1Orig.y);
                    717:                        if (axis == X_AXIS)
                    718:                            err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
                    719:                        else
                    720:                            err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
                    721:                    }
                    722:                    else
                    723:                    {
                    724:                        /* use error term calculated with the dash */
                    725:                        err = pdash->e;
                    726:                    }
                    727: 
                    728:                    mfbBresS( rop,
                    729:                              addrl, nlwidth,
                    730:                              signdx, signdy, axis, pt1.x, pt1.y,
                    731:                              err, e1, e2, len);
                    732:                }
                    733: 
                    734:                /* if segment is unclipped, skip remaining rectangles */
                    735:                if (!(clip1 || clip2))
                    736:                        break;
                    737:                else
                    738:                        pbox++;
                    739:            }
                    740:        } /* while (nbox--) */
                    741:        pdash++;
                    742:     } /* while --nseg */
                    743: 
                    744:     Xfree(pdashInit);
                    745: }
                    746: 
                    747: 
                    748: /*
                    749:     the clipping code could be cleaned up some; most of its
                    750: mess derives from originally being inline in the line code,
                    751: then pulled out to make clipping dashes easier.
                    752: */
                    753: 
                    754: int
                    755: mfbClipLine(pbox, box,
                    756:            ppt1Orig, ppt1, ppt2, 
                    757:            adx, ady, signdx, signdy, axis,
                    758:            pclip1, pclip2)
                    759: BoxPtr pbox;                   /* box to clip to */
                    760: BoxRec box;                    /* box to do calculations with */
                    761: DDXPointPtr ppt1Orig, ppt1, ppt2;
                    762: register int adx, ady;
                    763: register int signdx, signdy;
                    764: int axis;
                    765: int *pclip1, *pclip2;
                    766: {
                    767:     DDXPointRec pt1Orig, pt1, pt2, ptTmp;
                    768:     int swapped = 0;
                    769:     int clipDone = 0;
                    770:     register int tmp;
                    771:     int oc1, oc2;
                    772:     int clip1, clip2;
                    773: 
                    774:     pt1Orig = *ppt1Orig;
                    775:     pt1 = *ppt1;
                    776:     pt2 = *ppt2;
                    777:     clip1 = 0;
                    778:     clip2 = 0;
                    779: 
                    780:     do
                    781:     {
                    782:         oc1 = 0;
                    783:         oc2 = 0;
                    784:         OUTCODES(oc1, pt1.x, pt1.y, pbox);
                    785:         OUTCODES(oc2, pt2.x, pt2.y, pbox);
                    786: 
                    787:         if (oc1 & oc2)
                    788:            clipDone = -1;
                    789:         else if ((oc1 | oc2) == 0)
                    790:         {
                    791:            clipDone = 1;
                    792:            if (swapped)
                    793:            {
                    794:                SWAPPT(pt1, pt2, ptTmp);
                    795:                SWAPINT(oc1, oc2, tmp);
                    796:                SWAPINT(clip1, clip2, tmp);
                    797:            }
                    798:         }
                    799:         else /* have to clip */
                    800:         {
                    801:            /* only clip one point at a time */
                    802:            if (!oc1)
                    803:            {
                    804:                SWAPPT(pt1, pt2, ptTmp);
                    805:                SWAPINT(oc1, oc2, tmp);
                    806:                SWAPINT(clip1, clip2, tmp);
                    807:                swapped = !swapped;
                    808:            }
                    809:     
                    810:            clip1 |= oc1;
                    811:            if (oc1 & OUT_LEFT)
                    812:            {
                    813:              pt1.x = box.x1;
                    814:              if(axis==X_AXIS)
                    815:              {
                    816:                pt1.y = pt1Orig.y +
                    817:                        SignTimes(signdy,
                    818:                                  round(abs(box.x1-pt1Orig.x)*ady,
                    819:                                        adx));
                    820:              }
                    821:              else
                    822:              {
                    823:                tmp = abs(pt1Orig.x - box.x1);
                    824:                tmp = 2 * tmp * ady;
                    825:                if (swapped)
                    826:                    tmp += ady;
                    827:                else
                    828:                    tmp -= ady;
                    829:                tmp = abs(tmp);
                    830:                pt1.y = pt1Orig.y +
                    831:                        SignTimes(signdy,
                    832:                                  ceiling(tmp, 2*adx));
                    833:                if (swapped)
                    834:                    pt1.y -= signdy;
                    835:              }
                    836:            }
                    837:            else if (oc1 & OUT_ABOVE)
                    838:            {
                    839:              pt1.y = box.y1;
                    840:              if (axis == Y_AXIS)
                    841:              {
                    842:                pt1.x = pt1Orig.x +
                    843:                        SignTimes(signdx,
                    844:                                  round(abs(box.y1-pt1Orig.y)*adx,
                    845:                                        ady));
                    846:              }
                    847:              else
                    848:              {
                    849:                tmp = abs(pt1Orig.y - box.y1);
                    850:                tmp = 2 * tmp * adx;
                    851:                if (swapped)
                    852:                    tmp += adx;
                    853:                else
                    854:                    tmp -= adx;
                    855:                tmp = abs(tmp);
                    856:                pt1.x = pt1Orig.x +
                    857:                        SignTimes(signdx,
                    858:                                  ceiling(tmp, 2*ady));
                    859:                if (swapped)
                    860:                    pt1.x -= signdx;
                    861:              }
                    862:            }
                    863:            else if (oc1 & OUT_RIGHT)
                    864:            {
                    865:              pt1.x = box.x2;
                    866:              if (axis == X_AXIS)
                    867:              {
                    868:                pt1.y = pt1Orig.y +
                    869:                        SignTimes(signdy,
                    870:                                  round(abs(box.x2-pt1Orig.x)*ady,
                    871:                                        adx));
                    872:              }
                    873:              else
                    874:              {
                    875:                tmp = abs(pt1Orig.x - box.x2);
                    876:                tmp = 2 * tmp * ady;
                    877:                if (swapped)
                    878:                    tmp += ady;
                    879:                else
                    880:                    tmp -= ady;
                    881:                tmp = abs(tmp);
                    882:                pt1.y = pt1Orig.y +
                    883:                        SignTimes(signdy,
                    884:                                  ceiling(tmp, 2*adx));
                    885:                if (swapped)
                    886:                    pt1.y -= signdy;
                    887:              }
                    888:            }
                    889:            else if (oc1 & OUT_BELOW)
                    890:            {
                    891:              pt1.y = box.y2;
                    892:              if (axis == Y_AXIS)
                    893:              {
                    894:                pt1.x = pt1Orig.x +
                    895:                        SignTimes(signdx,
                    896:                                  round(abs(box.y2-pt1Orig.y)*adx,
                    897:                                        ady));
                    898:              }
                    899:              else
                    900:              {
                    901:                tmp = abs(pt1Orig.y - box.y2);
                    902:                tmp = 2 * tmp * adx;
                    903:                if (swapped)
                    904:                    tmp += adx;
                    905:                else
                    906:                    tmp -= adx;
                    907:                tmp = abs(tmp);
                    908:                pt1.x = pt1Orig.x +
                    909:                        SignTimes(signdx,
                    910:                                  ceiling(tmp, 2*ady));
                    911:                if (swapped)
                    912:                    pt1.x -= signdx;
                    913:              }
                    914:            }
                    915:         } /* else have to clip */
                    916:     } while(!clipDone);
                    917:     *ppt1 = pt1;
                    918:     *ppt2 = pt2;
                    919:     *pclip1 = clip1;
                    920:     *pclip2 = clip2;
                    921: 
                    922:     return clipDone;
                    923: }
                    924: 

unix.superglobalmegacorp.com

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