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

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: /* $Header: 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.