Annotation of researchv9/X11/src/X.V11R1/server/ddx/mfb/mfbplygblt.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: 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.