|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.