Annotation of researchv9/X11/src/X.V11R1/server/ddx/mfb/mfbimggblt.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: mfbimggblt.c,v 1.4 87/09/08 10:03:47 toddb Exp $ */
        !            25: #include       "X.h"
        !            26: #include       "Xmd.h"
        !            27: #include       "Xproto.h"
        !            28: #include       "fontstruct.h"
        !            29: #include       "dixfontstr.h"
        !            30: #include       "gcstruct.h"
        !            31: #include       "windowstr.h"
        !            32: #include       "scrnintstr.h"
        !            33: #include       "pixmapstr.h"
        !            34: #include       "regionstr.h"
        !            35: #include       "mfb.h"
        !            36: #include       "maskbits.h"
        !            37: 
        !            38: 
        !            39: /*
        !            40:     we should eventually special-case fixed-width fonts for ImageText.
        !            41: 
        !            42:     this works for fonts with glyphs <= 32 bits wide.
        !            43: 
        !            44:     the clipping calculations are done for worst-case fonts.
        !            45: we make no assumptions about the heights, widths, or bearings
        !            46: of the glyphs.  if we knew that the glyphs are all the same height,
        !            47: we could clip the tops and bottoms per clipping box, rather
        !            48: than per character per clipping box.  if we knew that the glyphs'
        !            49: left and right bearings were wlle-behaved, we could clip a single
        !            50: character at the start, output until the last unclipped
        !            51: character, and then clip the last one.  this is all straightforward
        !            52: to determine based on max-bounds and min-bounds from the font.
        !            53:     there is some inefficiency introduced in the per-character
        !            54: clipping to make what's going on clearer.
        !            55: 
        !            56:     (it is possible, for example, for a font to be defined in which the
        !            57: next-to-last character in a font would be clipped out, but the last
        !            58: one wouldn't.  the code below deals with this.)
        !            59: 
        !            60:     Image text looks at the bits in the glyph and the fg and bg in the
        !            61: GC.  it paints a rectangle, as defined in the protocol dcoument,
        !            62: and the paints the characters.
        !            63: 
        !            64:    to avoid source proliferation, this file is compiled
        !            65: three times:
        !            66:        MFBIMAGEGLYPHBLT        OPEQ
        !            67:        mfbImageGlyphBltWhite   |=
        !            68:        mfbImageGlyphBltBlack   &=~
        !            69: 
        !            70:     the register allocations for startmask and endmask may not
        !            71: be the right thing.  are there two other deserving candidates?
        !            72: xoff, pdst, pglyph, and tmpSrc seem like the right things, though.
        !            73: */
        !            74: 
        !            75: void
        !            76: MFBIMAGEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
        !            77:     DrawablePtr pDrawable;
        !            78:     GC                 *pGC;
        !            79:     int        x, y;
        !            80:     unsigned int nglyph;
        !            81:     CharInfoPtr *ppci;         /* array of character info */
        !            82:     unsigned char *pglyphBase; /* start of array of glyphs */
        !            83: {
        !            84:     ExtentInfoRec info;        /* used by QueryGlyphExtents() */
        !            85:     BoxRec bbox;       /* string's bounding box */
        !            86:     xRectangle backrect;/* backing rectangle to paint.
        !            87:                           in the general case, NOT necessarily
        !            88:                           the same as the string's bounding box
        !            89:                        */
        !            90: 
        !            91:     CharInfoPtr pci;
        !            92:     int xorg, yorg;    /* origin of drawable in bitmap */
        !            93:     int widthDst;      /* width of dst in longwords */
        !            94: 
        !            95:                        /* these keep track of the character origin */
        !            96:     unsigned int *pdstBase;
        !            97:                        /* points to longword with character origin */
        !            98:     int xchar;         /* xorigin of char (mod 32) */
        !            99: 
        !           100:                        /* these are used for placing the glyph */
        !           101:     register int xoff; /* x offset of left edge of glyph (mod 32) */
        !           102:     register unsigned int *pdst;
        !           103:                        /* pointer to current longword in dst */
        !           104: 
        !           105:     int w;             /* width of glyph in bits */
        !           106:     int h;             /* height of glyph */
        !           107:     int widthGlyph;    /* width of glyph, in bytes */
        !           108:     register unsigned char *pglyph;
        !           109:                        /* pointer to current row of glyph */
        !           110: 
        !           111:                        /* used for putting down glyph */    
        !           112:     register int startmask;
        !           113:     register int endmask;
        !           114: 
        !           115:     int nFirst;                /* bits of glyph in current longword */
        !           116:     register unsigned int tmpSrc;
        !           117:                        /* for getting bits from glyph */
        !           118:     void (* oldFillArea)();
        !           119:                        /* we might temporarily usurp this
        !           120:                           field in devPriv */
        !           121: 
        !           122:     if (!(pGC->planemask & 1))
        !           123:        return;
        !           124: 
        !           125:     if (pDrawable->type == DRAWABLE_WINDOW)
        !           126:     {
        !           127:        xorg = ((WindowPtr)pDrawable)->absCorner.x;
        !           128:        yorg = ((WindowPtr)pDrawable)->absCorner.y;
        !           129:        pdstBase = (unsigned int *)
        !           130:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
        !           131:        widthDst = (int)
        !           132:                 (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
        !           133:     }
        !           134:     else
        !           135:     {
        !           136:        xorg = 0;
        !           137:        yorg = 0;
        !           138:        pdstBase = (unsigned int *)(((PixmapPtr)pDrawable)->devPrivate);
        !           139:        widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
        !           140:     }
        !           141: 
        !           142:     QueryGlyphExtents(pGC->font, ppci, nglyph, &info);
        !           143: 
        !           144:     backrect.x = x;
        !           145:     backrect.y = y - pGC->font->pFI->fontAscent;
        !           146:     backrect.width = info.overallWidth;
        !           147:     backrect.height = pGC->font->pFI->fontAscent + 
        !           148:                      pGC->font->pFI->fontDescent;
        !           149: 
        !           150:     x += xorg;
        !           151:     y += yorg;
        !           152: 
        !           153:     bbox.x1 = x + info.overallLeft;
        !           154:     bbox.x2 = x + info.overallRight;
        !           155:     bbox.y1 = y - info.overallAscent;
        !           156:     bbox.y2 = y + info.overallDescent;
        !           157: 
        !           158:     /* UNCLEAN CODE
        !           159:        we know the mfbPolyFillRect uses only three fields in
        !           160:        devPriv, two of which (ppPixmap and ropFillArea) are 
        !           161:        irrelevant for solid filling, so we just poke the FillArea
        !           162:        field.  the GC is now in an inconsistent state, but we'll fix
        !           163:        it as soon as PolyFillRect returns.  fortunately, the server
        !           164:        is single threaded.
        !           165: 
        !           166:     NOTE:
        !           167:        if you are not using the standard mfbFillRectangle code, you
        !           168:        need to poke any fields in the GC the rectangle stuff need
        !           169:        (probably alu, fgPixel, and fillStyle) and in devPriv
        !           170:        (probably rop or ropFillArea.)  You could just call ValidateGC,
        !           171:        but that is usually not a cheap thing to do.
        !           172:     */
        !           173: 
        !           174:     oldFillArea = ((mfbPrivGC *)(pGC->devPriv))->FillArea;
        !           175: 
        !           176: /* pcc doesn't like this.  why?
        !           177:     ((mfbPrivGC *)(pGC->devPriv))->FillArea = 
        !           178:                        (pGC->bgPixel ? mfbSolidWhiteArea : mfbSolidBlackArea);
        !           179: */
        !           180:     if (pGC->bgPixel)
        !           181:         ((mfbPrivGC *)(pGC->devPriv))->FillArea = mfbSolidWhiteArea;
        !           182:     else
        !           183:         ((mfbPrivGC *)(pGC->devPriv))->FillArea = mfbSolidBlackArea;
        !           184: 
        !           185:     mfbPolyFillRect(pDrawable, pGC, 1, &backrect);
        !           186:     ((mfbPrivGC *)(pGC->devPriv))->FillArea = oldFillArea;
        !           187: 
        !           188:     /* the faint-hearted can open their eyes now */
        !           189:     switch ((*pGC->pScreen->RectIn)(
        !           190:                  ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip, &bbox))
        !           191:     {
        !           192:       case rgnOUT:
        !           193:        break;
        !           194:       case rgnIN:
        !           195:         pdstBase = pdstBase + (widthDst * y) + (x >> 5);
        !           196:         xchar = x & 0x1f;
        !           197: 
        !           198:         while(nglyph--)
        !           199:         {
        !           200:            pci = *ppci;
        !           201:            pglyph = pglyphBase + pci->byteOffset;
        !           202:            w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
        !           203:            h = pci->metrics.ascent + pci->metrics.descent;
        !           204:            widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
        !           205: 
        !           206:            /* start at top scanline of glyph */
        !           207:            pdst = pdstBase - (pci->metrics.ascent * widthDst);
        !           208: 
        !           209:            /* find correct word in scanline and x offset within it
        !           210:               for left edge of glyph
        !           211:            */
        !           212:            xoff = xchar + pci->metrics.leftSideBearing;
        !           213:            if (xoff > 31)
        !           214:            {
        !           215:                pdst++;
        !           216:                xoff &= 0x1f;
        !           217:            }
        !           218:            else if (xoff < 0)
        !           219:            {
        !           220:                xoff += 32;
        !           221:                pdst--;
        !           222:            }
        !           223: 
        !           224:            if ((xoff + w) <= 32)
        !           225:            {
        !           226:                /* glyph all in one longword */
        !           227:                maskpartialbits(xoff, w, startmask);
        !           228:                while (h--)
        !           229:                {
        !           230:                    getleftbits(pglyph, w, tmpSrc);
        !           231:                    *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           232:                    pglyph += widthGlyph;
        !           233:                    pdst += widthDst;
        !           234:                }
        !           235:            }
        !           236:            else
        !           237:            {
        !           238:                /* glyph crosses longword boundary */
        !           239:                mask32bits(xoff, w, startmask, endmask);
        !           240:                nFirst = 32 - xoff;
        !           241:                while (h--)
        !           242:                {
        !           243:                    getleftbits(pglyph, w, tmpSrc);
        !           244:                    *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           245:                    *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
        !           246:                    pglyph += widthGlyph;
        !           247:                    pdst += widthDst;
        !           248:                }
        !           249:            } /* glyph crosses longwords boundary */
        !           250: 
        !           251:            /* update character origin */
        !           252:            x += pci->metrics.characterWidth;
        !           253:            xchar += pci->metrics.characterWidth;
        !           254:            if (xchar > 31)
        !           255:            {
        !           256:                xchar -= 32;
        !           257:                pdstBase++;
        !           258:            }
        !           259:            else if (xchar < 0)
        !           260:            {
        !           261:                xchar += 32;
        !           262:                pdstBase--;
        !           263:            }
        !           264:            ppci++;
        !           265:         } /* while nglyph-- */
        !           266:        break;
        !           267:       case rgnPART:
        !           268:       {
        !           269:        TEXTPOS *ppos;
        !           270:        int nbox;
        !           271:        BoxPtr pbox;
        !           272:        int xpos;               /* x position of char origin */
        !           273:        int i;
        !           274:        BoxRec clip;
        !           275:        int leftEdge, rightEdge;
        !           276:        int topEdge, bottomEdge;
        !           277:        int glyphRow;           /* first row of glyph not wholly
        !           278:                                   clipped out */
        !           279:        int glyphCol;           /* leftmost visible column of glyph */
        !           280: 
        !           281:        if(!(ppos = (TEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(TEXTPOS))))
        !           282:            return;
        !           283: 
        !           284:         pdstBase = pdstBase + (widthDst * y) + (x >> 5);
        !           285:         xpos = x;
        !           286:        xchar = xpos & 0x1f;
        !           287: 
        !           288:        for (i=0; i<nglyph; i++)
        !           289:        {
        !           290:            pci = ppci[i];
        !           291: 
        !           292:            ppos[i].xpos = xpos;
        !           293:            ppos[i].xchar = xchar;
        !           294:            ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
        !           295:            ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
        !           296:            ppos[i].topEdge = y - pci->metrics.ascent;
        !           297:            ppos[i].bottomEdge = y + pci->metrics.descent;
        !           298:            ppos[i].pdstBase = pdstBase;
        !           299:            ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
        !           300: 
        !           301:            xpos += pci->metrics.characterWidth;
        !           302:            xchar += pci->metrics.characterWidth;
        !           303:            if (xchar > 31)
        !           304:            {
        !           305:                xchar &= 0x1f;
        !           306:                pdstBase++;
        !           307:            }
        !           308:            else if (xchar < 0)
        !           309:            {
        !           310:                xchar += 32;
        !           311:                pdstBase--;
        !           312:            }
        !           313:        }
        !           314: 
        !           315:        pbox = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->rects;
        !           316:        nbox = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->numRects;
        !           317: 
        !           318:        /* HACK ALERT
        !           319:           since we continue out of the loop below so often, it
        !           320:           is easier to increment pbox at the  top than at the end.
        !           321:           don't try this at home.
        !           322:        */
        !           323:        pbox--;
        !           324:        while(nbox--)
        !           325:        {
        !           326:            pbox++;
        !           327:            clip.x1 = max(bbox.x1, pbox->x1);
        !           328:            clip.y1 = max(bbox.y1, pbox->y1);
        !           329:            clip.x2 = min(bbox.x2, pbox->x2);
        !           330:            clip.y2 = min(bbox.y2, pbox->y2);
        !           331:            if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
        !           332:                continue;
        !           333: 
        !           334:            for(i=0; i<nglyph; i++)
        !           335:            {
        !           336:                pci = ppci[i];
        !           337:                xchar = ppos[i].xchar;
        !           338: 
        !           339:                /* clip the left and right edges */
        !           340:                if (ppos[i].leftEdge < clip.x1)
        !           341:                    leftEdge = clip.x1;
        !           342:                else
        !           343:                    leftEdge = ppos[i].leftEdge;
        !           344: 
        !           345:                if (ppos[i].rightEdge > clip.x2)
        !           346:                    rightEdge = clip.x2;
        !           347:                else
        !           348:                    rightEdge = ppos[i].rightEdge;
        !           349: 
        !           350:                w = rightEdge - leftEdge;
        !           351:                if (w <= 0)
        !           352:                    continue;
        !           353: 
        !           354:                /* clip the top and bottom edges */
        !           355:                if (ppos[i].topEdge < clip.y1)
        !           356:                    topEdge = clip.y1;
        !           357:                else
        !           358:                    topEdge = ppos[i].topEdge;
        !           359: 
        !           360:                if (ppos[i].bottomEdge > clip.y2)
        !           361:                    bottomEdge = clip.y2;
        !           362:                else
        !           363:                    bottomEdge = ppos[i].bottomEdge;
        !           364: 
        !           365:                h = bottomEdge - topEdge;
        !           366:                if (h <= 0)
        !           367:                    continue;
        !           368: 
        !           369:                glyphRow = (topEdge - y) + pci->metrics.ascent;
        !           370:                widthGlyph = ppos[i].widthGlyph;
        !           371:                pglyph = pglyphBase + pci->byteOffset;
        !           372:                pglyph += (glyphRow * widthGlyph);
        !           373: 
        !           374:                pdst = ppos[i].pdstBase - ((y-topEdge) * widthDst);
        !           375: 
        !           376:                glyphCol = (leftEdge - ppos[i].xpos) -
        !           377:                           (pci->metrics.leftSideBearing);
        !           378:                xoff = xchar + (leftEdge - ppos[i].xpos);
        !           379:                if (xoff > 31)
        !           380:                {
        !           381:                    xoff &= 0x1f;
        !           382:                    pdst++;
        !           383:                }
        !           384:                else if (xoff < 0)
        !           385:                {
        !           386:                    xoff += 32;
        !           387:                    pdst--;
        !           388:                }
        !           389: 
        !           390:                if ((xoff + w) <= 32)
        !           391:                {
        !           392:                    maskpartialbits(xoff, w, startmask);
        !           393:                    while (h--)
        !           394:                    {
        !           395:                        getshiftedleftbits(pglyph, glyphCol, w, tmpSrc);
        !           396:                        *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           397:                        pglyph += widthGlyph;
        !           398:                        pdst += widthDst;
        !           399:                    }
        !           400:                }
        !           401:                else
        !           402:                {
        !           403:                    mask32bits(xoff, w, startmask, endmask);
        !           404:                    nFirst = 32 - xoff;
        !           405:                    while (h--)
        !           406:                    {
        !           407:                        getshiftedleftbits(pglyph, glyphCol, w, tmpSrc);
        !           408:                        *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
        !           409:                        *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
        !           410:                        pglyph += widthGlyph;
        !           411:                        pdst += widthDst;
        !           412:                    }
        !           413:                }
        !           414:            } /* for each glyph */
        !           415:        } /* while nbox-- */
        !           416:        DEALLOCATE_LOCAL(ppos);
        !           417:        break;
        !           418:       }
        !           419:       default:
        !           420:        break;
        !           421:     }
        !           422: }
        !           423: 

unix.superglobalmegacorp.com

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