Annotation of researchv9/X11/src/X.V11R1/server/ddx/mfb/mfbplygblt.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: mfbplygblt.c,v 1.15 87/09/01 16:53:00 toddb Exp $ */
        !            25: 
        !            26: #include "X.h"
        !            27: #include "Xmd.h"
        !            28: #include "Xproto.h"
        !            29: #include "fontstruct.h"
        !            30: #include "dixfontstr.h"
        !            31: #include "gcstruct.h"
        !            32: #include "windowstr.h"
        !            33: #include "pixmapstr.h"
        !            34: #include "scrnintstr.h"
        !            35: #include "regionstr.h"
        !            36: #include "mfb.h"
        !            37: #include "maskbits.h"
        !            38: #include "miscstruct.h"
        !            39: 
        !            40: 
        !            41: /*
        !            42:     we should eventually special-case fixed-width fonts, although
        !            43: its more important for ImageText, which is meant for terminal
        !            44: emulators.
        !            45: 
        !            46:     this works for fonts with glyphs <= 32 bits wide.
        !            47: 
        !            48:     the clipping calculations are done for worst-case fonts.
        !            49: we make no assumptions about the heights, widths, or bearings
        !            50: of the glyphs.  if we knew that the glyphs are all the same height,
        !            51: we could clip the tops and bottoms per clipping box, rather
        !            52: than per character per clipping box.  if we knew that the glyphs'
        !            53: left and right bearings were well-behaved, we could clip a single
        !            54: character at the start, output until the last unclipped
        !            55: character, and then clip the last one.  this is all straightforward
        !            56: to determine based on max-bounds and min-bounds from the font.
        !            57:     there is some inefficiency introduced in the per-character
        !            58: clipping to make what's going on clearer.
        !            59: 
        !            60:     (it is possible, for example, for a font to be defined in which the
        !            61: next-to-last character in a font would be clipped out, but the last
        !            62: one wouldn't.  the code below deals with this.)
        !            63: 
        !            64:     PolyText looks at the fg color and the rasterop; mfbValidateGC
        !            65: swaps in the right routine after looking at the reduced ratserop
        !            66: in the private field of the GC.  
        !            67: 
        !            68:    the register allocations are provisional; in particualr startmask and
        !            69: endmask might not be the right things.  pglyph, xoff, pdst, and tmpSrc
        !            70: are fairly obvious, though.
        !            71: 
        !            72:    to avoid source proliferation, this file is compiled
        !            73: three times:
        !            74:        MFBPOLYGLYPHBLT         OPEQ
        !            75:        mfbPolyGlyphBltWhite    |=
        !            76:        mfbPolyGlyphBltBlack    &=~
        !            77:        mfbPolyGlyphBltInvert   ^=
        !            78: */
        !            79: 
        !            80: void
        !            81: MFBPOLYGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
        !            82:     DrawablePtr pDrawable;
        !            83:     GCPtr      pGC;
        !            84:     int        x, y;
        !            85:     unsigned int nglyph;
        !            86:     CharInfoPtr *ppci;         /* array of character info */
        !            87:     unsigned char *pglyphBase; /* start of array of glyphs */
        !            88: {
        !            89:     ExtentInfoRec info;        /* used by QueryGlyphExtents() */
        !            90:     BoxRec bbox;               /* string's bounding box */
        !            91: 
        !            92:     CharInfoPtr pci;
        !            93:     int xorg, yorg;    /* origin of drawable in bitmap */
        !            94:     int widthDst;      /* width of dst in longwords */
        !            95: 
        !            96:                        /* these keep track of the character origin */
        !            97:     unsigned int *pdstBase;
        !            98:                        /* points to longword with character origin */
        !            99:     int xchar;         /* xorigin of char (mod 32) */
        !           100: 
        !           101:                        /* these are used for placing the glyph */
        !           102:     register int xoff; /* x offset of left edge of glyph (mod 32) */
        !           103:     register unsigned int *pdst;
        !           104:                        /* pointer to current longword in dst */
        !           105: 
        !           106:     int w;             /* width of glyph in bits */
        !           107:     int h;             /* height of glyph */
        !           108:     int widthGlyph;    /* width of glyph, in bytes */
        !           109:     register unsigned char *pglyph;
        !           110:                        /* pointer to current row of glyph */
        !           111: 
        !           112:                        /* used for putting down glyph */
        !           113:     register int startmask;
        !           114:     register int endmask;
        !           115:     int nFirst;                /* bits of glyph in current longword */
        !           116:     register unsigned int tmpSrc;
        !           117:                        /* for getting bits from glyph */
        !           118: 
        !           119:     if (!(pGC->planemask & 1))
        !           120:        return;
        !           121: 
        !           122:     if (pDrawable->type == DRAWABLE_WINDOW)
        !           123:     {
        !           124:        xorg = ((WindowPtr)pDrawable)->absCorner.x;
        !           125:        yorg = ((WindowPtr)pDrawable)->absCorner.y;
        !           126:        pdstBase = (unsigned int *)
        !           127:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
        !           128:        widthDst = (int)
        !           129:                 (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
        !           130:     }
        !           131:     else
        !           132:     {
        !           133:        xorg = 0;
        !           134:        yorg = 0;
        !           135:        pdstBase = (unsigned int *)(((PixmapPtr)pDrawable)->devPrivate);
        !           136:        widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
        !           137:     }
        !           138: 
        !           139:     x += xorg;
        !           140:     y += yorg;
        !           141: 
        !           142:     QueryGlyphExtents(pGC->font, ppci, nglyph, &info);
        !           143:     bbox.x1 = x + info.overallLeft;
        !           144:     bbox.x2 = x + info.overallRight;
        !           145:     bbox.y1 = y - info.overallAscent;
        !           146:     bbox.y2 = y + info.overallDescent;
        !           147: 
        !           148:     switch ((*pGC->pScreen->RectIn)(
        !           149:                 ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip, &bbox))
        !           150:     {
        !           151:       case rgnOUT:
        !           152:        break;
        !           153:       case rgnIN:
        !           154:         pdstBase = pdstBase + (widthDst * y) + (x >> 5);
        !           155:         xchar = x & 0x1f;
        !           156: 
        !           157:         while(nglyph--)
        !           158:         {
        !           159:            pci = *ppci;
        !           160:            pglyph = pglyphBase + pci->byteOffset;
        !           161:            w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
        !           162:            h = pci->metrics.ascent + pci->metrics.descent;
        !           163:            widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
        !           164: 
        !           165:            /* start at top scanline of glyph */
        !           166:            pdst = pdstBase - (pci->metrics.ascent * widthDst);
        !           167: 
        !           168:            /* find correct word in scanline and x offset within it
        !           169:               for left edge of glyph
        !           170:            */
        !           171:            xoff = xchar + pci->metrics.leftSideBearing;
        !           172:            if (xoff > 31)
        !           173:            {
        !           174:                pdst++;
        !           175:                xoff &= 0x1f;
        !           176:            }
        !           177:            else if (xoff < 0)
        !           178:            {
        !           179:                xoff += 32;
        !           180:                pdst--;
        !           181:            }
        !           182: 
        !           183:            if ((xoff + w) <= 32)
        !           184:            {
        !           185:                /* glyph all in one longword */
        !           186:                maskpartialbits(xoff, w, startmask);
        !           187:                while (h--)
        !           188:                {
        !           189:                    getleftbits(pglyph, w, tmpSrc);
        !           190:                    *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           191:                    pglyph += widthGlyph;
        !           192:                    pdst += widthDst;
        !           193:                }
        !           194:            }
        !           195:            else
        !           196:            {
        !           197:                /* glyph crosses longword boundary */
        !           198:                mask32bits(xoff, w, startmask, endmask);
        !           199:                nFirst = 32 - xoff;
        !           200:                while (h--)
        !           201:                {
        !           202:                    getleftbits(pglyph, w, tmpSrc);
        !           203:                    *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           204:                    *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
        !           205:                    pglyph += widthGlyph;
        !           206:                    pdst += widthDst;
        !           207:                }
        !           208:            } /* glyph crosses longwords boundary */
        !           209: 
        !           210:            /* update character origin */
        !           211:            x += pci->metrics.characterWidth;
        !           212:            xchar += pci->metrics.characterWidth;
        !           213:            if (xchar > 31)
        !           214:            {
        !           215:                xchar -= 32;
        !           216:                pdstBase++;
        !           217:            }
        !           218:            else if (xchar < 0)
        !           219:            {
        !           220:                xchar += 32;
        !           221:                pdstBase--;
        !           222:            }
        !           223:            ppci++;
        !           224:         } /* while nglyph-- */
        !           225:        break;
        !           226:       case rgnPART:
        !           227:       {
        !           228:        TEXTPOS *ppos;
        !           229:        int nbox;
        !           230:        BoxPtr pbox;
        !           231:        int xpos;               /* x position of char origin */
        !           232:        int i;
        !           233:        BoxRec clip;
        !           234:        int leftEdge, rightEdge;
        !           235:        int topEdge, bottomEdge;
        !           236:        int glyphRow;           /* first row of glyph not wholly
        !           237:                                   clipped out */
        !           238:        int glyphCol;           /* leftmost visible column of glyph */
        !           239: 
        !           240:        if(!(ppos = (TEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(TEXTPOS))))
        !           241:            return;
        !           242: 
        !           243:         pdstBase = pdstBase + (widthDst * y) + (x >> 5);
        !           244:         xpos = x;
        !           245:        xchar = xpos & 0x1f;
        !           246: 
        !           247:        for (i=0; i<nglyph; i++)
        !           248:        {
        !           249:            pci = ppci[i];
        !           250: 
        !           251:            ppos[i].xpos = xpos;
        !           252:            ppos[i].xchar = xchar;
        !           253:            ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
        !           254:            ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
        !           255:            ppos[i].topEdge = y - pci->metrics.ascent;
        !           256:            ppos[i].bottomEdge = y + pci->metrics.descent;
        !           257:            ppos[i].pdstBase = pdstBase;
        !           258:            ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
        !           259: 
        !           260:            xpos += pci->metrics.characterWidth;
        !           261:            xchar += pci->metrics.characterWidth;
        !           262:            if (xchar > 31)
        !           263:            {
        !           264:                xchar &= 0x1f;
        !           265:                pdstBase++;
        !           266:            }
        !           267:            else if (xchar < 0)
        !           268:            {
        !           269:                xchar += 32;
        !           270:                pdstBase--;
        !           271:            }
        !           272:        }
        !           273: 
        !           274:        pbox = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->rects;
        !           275:        nbox = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->numRects;
        !           276: 
        !           277:        /* HACK ALERT
        !           278:           since we continue out of the loop below so often, it
        !           279:           is easier to increment pbox at the  top than at the end.
        !           280:           don't try this at home.
        !           281:        */
        !           282:        pbox--;
        !           283:        while(nbox--)
        !           284:        {
        !           285:            pbox++;
        !           286:            clip.x1 = max(bbox.x1, pbox->x1);
        !           287:            clip.y1 = max(bbox.y1, pbox->y1);
        !           288:            clip.x2 = min(bbox.x2, pbox->x2);
        !           289:            clip.y2 = min(bbox.y2, pbox->y2);
        !           290:            if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
        !           291:                continue;
        !           292: 
        !           293:            for(i=0; i<nglyph; i++)
        !           294:            {
        !           295:                pci = ppci[i];
        !           296:                xchar = ppos[i].xchar;
        !           297: 
        !           298:                /* clip the left and right edges */
        !           299:                if (ppos[i].leftEdge < clip.x1)
        !           300:                    leftEdge = clip.x1;
        !           301:                else
        !           302:                    leftEdge = ppos[i].leftEdge;
        !           303: 
        !           304:                if (ppos[i].rightEdge > clip.x2)
        !           305:                    rightEdge = clip.x2;
        !           306:                else
        !           307:                    rightEdge = ppos[i].rightEdge;
        !           308: 
        !           309:                w = rightEdge - leftEdge;
        !           310:                if (w <= 0)
        !           311:                    continue;
        !           312: 
        !           313:                /* clip the top and bottom edges */
        !           314:                if (ppos[i].topEdge < clip.y1)
        !           315:                    topEdge = clip.y1;
        !           316:                else
        !           317:                    topEdge = ppos[i].topEdge;
        !           318: 
        !           319:                if (ppos[i].bottomEdge > clip.y2)
        !           320:                    bottomEdge = clip.y2;
        !           321:                else
        !           322:                    bottomEdge = ppos[i].bottomEdge;
        !           323: 
        !           324:                h = bottomEdge - topEdge;
        !           325:                if (h <= 0)
        !           326:                    continue;
        !           327: 
        !           328:                glyphRow = (topEdge - y) + pci->metrics.ascent;
        !           329:                widthGlyph = ppos[i].widthGlyph;
        !           330:                pglyph = pglyphBase + pci->byteOffset;
        !           331:                pglyph += (glyphRow * widthGlyph);
        !           332: 
        !           333:                pdst = ppos[i].pdstBase - ((y-topEdge) * widthDst);
        !           334: 
        !           335:                glyphCol = (leftEdge - ppos[i].xpos) -
        !           336:                           (pci->metrics.leftSideBearing);
        !           337:                xoff = xchar + (leftEdge - ppos[i].xpos);
        !           338:                if (xoff > 31)
        !           339:                {
        !           340:                    xoff &= 0x1f;
        !           341:                    pdst++;
        !           342:                }
        !           343:                else if (xoff < 0)
        !           344:                {
        !           345:                    xoff += 32;
        !           346:                    pdst--;
        !           347:                }
        !           348: 
        !           349:                if ((xoff + w) <= 32)
        !           350:                {
        !           351:                    maskpartialbits(xoff, w, startmask);
        !           352:                    while (h--)
        !           353:                    {
        !           354:                        getshiftedleftbits(pglyph, glyphCol, w, tmpSrc);
        !           355:                        *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           356:                        pglyph += widthGlyph;
        !           357:                        pdst += widthDst;
        !           358:                    }
        !           359:                }
        !           360:                else
        !           361:                {
        !           362:                    mask32bits(xoff, w, startmask, endmask);
        !           363:                    nFirst = 32 - xoff;
        !           364:                    while (h--)
        !           365:                    {
        !           366:                        getshiftedleftbits(pglyph, glyphCol, w, tmpSrc);
        !           367:                        *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           368:                        *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
        !           369:                        pglyph += widthGlyph;
        !           370:                        pdst += widthDst;
        !           371:                    }
        !           372:                }
        !           373:            } /* for each glyph */
        !           374:        } /* while nbox-- */
        !           375:        DEALLOCATE_LOCAL(ppos);
        !           376:        break;
        !           377:       }
        !           378:       default:
        !           379:        break;
        !           380:     }
        !           381: }
        !           382: 
        !           383: 

unix.superglobalmegacorp.com

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