Annotation of researchv9/X11/src/X.V11R1/server/ddx/mfb/mfbline.c, revision 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.