1 /* $XConsortium: cfbglblt8.c,v 5.31 94/04/17 20:28:51 dpw Exp $ */
2 /* $XFree86: xc/programs/Xserver/cfb/cfbglblt8.c,v 3.1 1996/08/13 11:27:34 dawes Exp $ */
5 Copyright (c) 1989 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
30 * Poly glyph blt. Accepts an arbitrary font <= 32 bits wide, in Copy mode
38 #include "fontstruct.h"
39 #include "dixfontstr.h"
41 #include "windowstr.h"
42 #include "scrnintstr.h"
43 #include "pixmapstr.h"
44 #include "regionstr.h"
45 #include "cfbmskbits.h"
48 #define BOX_OVERLAP(box1, box2, xoffset, yoffset) \
49 ((box1)->x1 <= ((int) (box2)->x2 + (xoffset)) && \
50 ((int) (box2)->x1 + (xoffset)) <= (box1)->x2 && \
51 (box1)->y1 <= ((int) (box2)->y2 + (yoffset)) && \
52 ((int) (box2)->y1 + (yoffset)) <= (box1)->y2)
54 #define BOX_CONTAINS(box1, box2, xoffset, yoffset) \
55 ((box1)->x1 <= ((int) (box2)->x1 + (xoffset)) && \
56 ((int) (box2)->x2 + (xoffset)) <= (box1)->x2 && \
57 (box1)->y1 <= ((int) (box2)->y1 + (yoffset)) && \
58 ((int) (box2)->y2 + (yoffset)) <= (box1)->y2)
60 #if defined(FOUR_BIT_CODE) || defined(WriteBitGroup) && !defined(GLYPHROP)
62 #if GLYPHPADBYTES != 4
67 typedef unsigned char *glyphPointer;
68 extern unsigned long endtab[];
70 #define GlyphBits(bits,width,dst) getleftbits(bits,width,dst); \
73 #define GlyphBitsS(bits,width,dst,off) GlyphBits(bits,width,dst); \
74 dst = BitRight (dst, off);
76 typedef CARD32 *glyphPointer;
78 #define GlyphBits(bits,width,dst) dst = *bits++;
79 #define GlyphBitsS(bits,width,dst,off) dst = BitRight(*bits++, off);
83 #define cfbPolyGlyphBlt8 cfbPolyGlyphRop8
84 #define cfbPolyGlyphBlt8Clipped cfbPolyGlyphRop8Clipped
87 #define WriteBitGroup(dst,pixel,bits) RRopBitGroup(dst,bits)
91 static void cfbPolyGlyphBlt8Clipped();
93 #if defined(HAS_STIPPLE_CODE) && !defined(GLYPHROP) && !defined(USE_LEFTBITS)
94 #define USE_STIPPLE_CODE
97 #if defined(__GNUC__) && !defined(GLYPHROP) && (defined(mc68020) || defined(mc68000) || defined(__mc68000__)) && PSZ == 8 && !defined(USE_LEFTBITS)
98 #ifdef USE_STIPPLE_CODE
99 #undef USE_STIPPLE_CODE
101 #include "stip68kgnu.h"
107 #define DST_INC (PGSZB >> PWSH)
110 /* cfbStippleStack/cfbStippleStackTE are coded in assembly language.
111 * They are only provided on some architecures.
113 #ifdef USE_STIPPLE_CODE
114 extern void cfbStippleStack (), cfbStippleStackTE ();
118 cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
119 DrawablePtr pDrawable;
123 CharInfoPtr *ppci; /* array of character info */
124 pointer pglyphBase; /* start of array of glyphs */
126 register unsigned long c;
128 register unsigned long pixel;
130 register unsigned long *dst;
131 register glyphPointer glyphBits;
134 FontPtr pfont = pGC->font;
136 unsigned long *dstLine;
137 unsigned long *pdstBase;
143 BoxRec bbox; /* for clipping */
150 unsigned long widthMask;
153 #ifdef USE_STIPPLE_CODE
156 stipple = cfbStippleStack;
157 if (FONTCONSTMETRICS(pfont))
158 stipple = cfbStippleStackTE;
165 /* compute an approximate (but covering) bounding box */
167 if ((ppci[0]->metrics.leftSideBearing < 0))
168 bbox.x1 = ppci[0]->metrics.leftSideBearing;
170 w = ppci[h]->metrics.rightSideBearing;
172 w += ppci[h]->metrics.characterWidth;
174 bbox.y1 = -FONTMAXBOUNDS(pfont,ascent);
175 bbox.y2 = FONTMAXBOUNDS(pfont,descent);
177 clip = cfbGetCompositeClip(pGC);
178 extents = &clip->extents;
182 if (!BOX_CONTAINS(extents, &bbox, x, y))
184 if (BOX_OVERLAP (extents, &bbox, x, y))
185 cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
186 nglyph, ppci, pglyphBase);
192 /* check to make sure some of the text appears on the screen */
193 if (!BOX_OVERLAP (extents, &bbox, x, y))
201 switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox))
204 cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
205 nglyph, ppci, pglyphBase);
212 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
214 pixel = cfbGetGCPrivate(pGC)->xor;
217 cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long)
219 widthDst = bwidthDst / PGSZB;
223 glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
224 xoff = x + pci->metrics.leftSideBearing;
226 dstLine = pdstBase + (y - pci->metrics.ascent) * widthDst +((xoff>> 2)*3);
229 (y - pci->metrics.ascent) * widthDst + (xoff >> PWSH);
231 x += pci->metrics.characterWidth;
232 if (hTmp = pci->metrics.descent + pci->metrics.ascent)
238 #endif /* PSZ == 24 */
240 STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
242 #ifdef USE_STIPPLE_CODE
243 (*stipple)(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
246 w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
247 widthGlyph = PADGLYPHWIDTHBYTES(w);
248 widthMask = endtab[w];
252 dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
253 GlyphBits(glyphBits, w, c)
254 WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
256 c = BitLeft(c,PGSZB - xoff);
259 WriteBitGroup(dst, pixel, GetBitGroup(c));
264 #endif /* USE_STIPPLE_CODE else */
265 #endif /* STIPPLE else */
271 cfbPolyGlyphBlt8Clipped (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
272 DrawablePtr pDrawable;
276 CharInfoPtr *ppci; /* array of character info */
277 unsigned char *pglyphBase; /* start of array of glyphs */
279 register unsigned long c;
281 register unsigned long pixel;
283 register unsigned long *dst;
284 register glyphPointer glyphBits;
289 FontPtr pfont = pGC->font;
290 unsigned long *dstLine;
291 unsigned long *pdstBase;
292 CARD32 *cTmp, *clips;
293 int maxAscent, maxDescent;
311 unsigned long widthMask;
315 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
317 pixel = cfbGetGCPrivate(pGC)->xor;
320 cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long)
322 widthDst = bwidthDst / PGSZB;
323 maxAscent = FONTMAXBOUNDS(pfont,ascent);
324 maxDescent = FONTMAXBOUNDS(pfont,descent);
325 minLeftBearing = FONTMINBOUNDS(pfont,leftSideBearing);
327 pRegion = cfbGetCompositeClip(pGC);
329 pBox = REGION_RECTS(pRegion);
330 numRects = REGION_NUM_RECTS (pRegion);
331 while (numRects && pBox->y2 <= y - maxAscent)
336 if (!numRects || pBox->y1 >= y + maxDescent)
339 while (numRects && pBox->y1 == yBand && pBox->x2 <= x + minLeftBearing)
346 clips = (CARD32 *)ALLOCATE_LOCAL ((maxAscent + maxDescent) *
351 glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
352 w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
353 xG = x + pci->metrics.leftSideBearing;
354 yG = y - pci->metrics.ascent;
355 x += pci->metrics.characterWidth;
356 if (hTmp = pci->metrics.descent + pci->metrics.ascent)
359 dstLine = pdstBase + yG * widthDst + ((xG>> 2)*3);
360 /* never use (xG*3)>>2 */
362 dstLine = pdstBase + yG * widthDst + (xG >> PWSH);
370 w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
371 widthGlyph = PADGLYPHWIDTHBYTES(w);
372 widthMask = endtab[w];
374 switch (cfb8ComputeClipMasks32 (pBox, numRects, xG, yG, w, hTmp, clips))
381 dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
382 GlyphBits(glyphBits, w, c)
386 WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
387 c = BitLeft(c,PGSZB - xoff);
391 WriteBitGroup(dst, pixel, GetBitGroup(c));
398 #else /* !USE_LEFT_BITS */
406 clips[h] = clips[h] & glyphBits[h];
411 #endif /* USE_LEFT_BITS */
414 STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
416 #ifdef USE_STIPPLE_CODE
417 cfbStippleStackTE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
421 dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
422 GlyphBits(glyphBits, w, c)
425 /* This code originally could read memory locations
426 * that were not mapped. Hence we have to check the
427 * trailing bits to see whether they are zero and if
428 * then skip them correctly. This is no problem for
429 * the GXcopy case, since there only the pixels that
430 * are non-zero are written ...
433 WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
434 c = BitLeft(c,PGSZB - xoff);
437 if (bits = GetBitGroup(BitRight(c,xoff)))
438 WriteBitGroup(dst, pixel, bits);
439 c = BitLeft(c,PGSZB - xoff);
442 while (c && ((bits = GetBitGroup(c)) == 0))
447 #endif /* GLYPHROP */
450 WriteBitGroup(dst, pixel, GetBitGroup(c));
456 #endif /* USE_STIPPLE_CODE else */
457 #endif /* STIPPLE else */
462 DEALLOCATE_LOCAL (clips);
465 #endif /* FOUR_BIT_CODE */