First import
[xorg_rtime.git] / xorg-server-1.4 / cfb / cfbglblt8.c
blobc4cba0e15d05fe47f8ce0b22d0a78ae699820349
1 /*
3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
27 * Poly glyph blt. Accepts an arbitrary font <= 32 bits wide, in Copy mode
28 * only.
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
33 #endif
35 #include <X11/X.h>
36 #include <X11/Xmd.h>
37 #include <X11/Xproto.h>
38 #include "cfb.h"
39 #include <X11/fonts/fontstruct.h>
40 #include "dixfontstr.h"
41 #include "gcstruct.h"
42 #include "windowstr.h"
43 #include "scrnintstr.h"
44 #include "pixmapstr.h"
45 #include "regionstr.h"
46 #include "cfbmskbits.h"
47 #include "cfb8bit.h"
49 #define BOX_OVERLAP(box1, box2, xoffset, yoffset) \
50 ((box1)->x1 <= ((int) (box2)->x2 + (xoffset)) && \
51 ((int) (box2)->x1 + (xoffset)) <= (box1)->x2 && \
52 (box1)->y1 <= ((int) (box2)->y2 + (yoffset)) && \
53 ((int) (box2)->y1 + (yoffset)) <= (box1)->y2)
55 #define BOX_CONTAINS(box1, box2, xoffset, yoffset) \
56 ((box1)->x1 <= ((int) (box2)->x1 + (xoffset)) && \
57 ((int) (box2)->x2 + (xoffset)) <= (box1)->x2 && \
58 (box1)->y1 <= ((int) (box2)->y1 + (yoffset)) && \
59 ((int) (box2)->y2 + (yoffset)) <= (box1)->y2)
61 #if defined(FOUR_BIT_CODE) || defined(WriteBitGroup) && !defined(GLYPHROP)
63 #if GLYPHPADBYTES != 4
64 #define USE_LEFTBITS
65 #endif
67 #ifdef USE_LEFTBITS
68 typedef unsigned char *glyphPointer;
70 #define GlyphBits(bits,width,dst) getleftbits(bits,width,dst); \
71 (dst) &= widthMask; \
72 (bits) += widthGlyph;
73 #define GlyphBitsS(bits,width,dst,off) GlyphBits(bits,width,dst); \
74 dst = BitRight (dst, off);
75 #else
76 typedef CARD32 *glyphPointer;
78 #define GlyphBits(bits,width,dst) dst = *bits++;
79 #define GlyphBitsS(bits,width,dst,off) dst = BitRight(*bits++, off);
80 #endif
82 #ifdef GLYPHROP
83 #define cfbPolyGlyphBlt8 cfbPolyGlyphRop8
84 #define cfbPolyGlyphBlt8Clipped cfbPolyGlyphRop8Clipped
86 #undef WriteBitGroup
87 #define WriteBitGroup(dst,pixel,bits) RRopBitGroup(dst,bits)
89 #endif
91 static void cfbPolyGlyphBlt8Clipped(
92 DrawablePtr pDrawable,
93 GCPtr pGC,
94 int x,
95 int y,
96 unsigned int nglyph,
97 CharInfoPtr *ppci, /* array of character info */
98 unsigned char *pglyphBase); /* start of array of glyphs */
100 #if defined(HAS_STIPPLE_CODE) && !defined(GLYPHROP) && !defined(USE_LEFTBITS)
101 #define USE_STIPPLE_CODE
102 #endif
104 #if defined(__GNUC__) && !defined(GLYPHROP) && (defined(mc68020) || defined(mc68000) || defined(__mc68000__)) && PSZ == 8 && !defined(USE_LEFTBITS)
105 #ifdef USE_STIPPLE_CODE
106 #undef USE_STIPPLE_CODE
107 #endif
108 #include "stip68kgnu.h"
109 #endif
111 #if PSZ == 24
112 #define DST_INC 3
113 #else
114 #define DST_INC (PGSZB >> PWSH)
115 #endif
117 /* cfbStippleStack/cfbStippleStackTE are coded in assembly language.
118 * They are only provided on some architecures.
120 #ifdef USE_STIPPLE_CODE
121 extern void cfbStippleStack (), cfbStippleStackTE ();
122 #endif
124 void
125 cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
126 DrawablePtr pDrawable;
127 GCPtr pGC;
128 int x, y;
129 unsigned int nglyph;
130 CharInfoPtr *ppci; /* array of character info */
131 pointer pglyphBase; /* start of array of glyphs */
133 #ifndef GLYPHROP
134 register CfbBits pixel;
135 #endif
136 #if !defined(STIPPLE) && !defined(USE_STIPPLE_CODE)
137 register CfbBits c;
138 register CfbBits *dst;
139 #endif
140 register glyphPointer glyphBits;
141 register int xoff;
143 FontPtr pfont = pGC->font;
144 CharInfoPtr pci;
145 CfbBits *dstLine;
146 CfbBits *pdstBase;
147 int hTmp;
148 int bwidthDst;
149 int widthDst;
150 int h;
151 BoxRec bbox; /* for clipping */
152 int w;
153 RegionPtr clip;
154 BoxPtr extents;
155 #ifdef USE_LEFTBITS
156 int widthGlyph;
157 CfbBits widthMask;
158 #endif
159 #ifndef STIPPLE
160 #ifdef USE_STIPPLE_CODE
161 void (*stipple)();
163 stipple = cfbStippleStack;
164 if (FONTCONSTMETRICS(pfont))
165 stipple = cfbStippleStackTE;
166 #endif
167 #endif
169 x += pDrawable->x;
170 y += pDrawable->y;
172 /* compute an approximate (but covering) bounding box */
173 bbox.x1 = 0;
174 if ((ppci[0]->metrics.leftSideBearing < 0))
175 bbox.x1 = ppci[0]->metrics.leftSideBearing;
176 h = nglyph - 1;
177 w = ppci[h]->metrics.rightSideBearing;
178 while (--h >= 0)
179 w += ppci[h]->metrics.characterWidth;
180 bbox.x2 = w;
181 bbox.y1 = -FONTMAXBOUNDS(pfont,ascent);
182 bbox.y2 = FONTMAXBOUNDS(pfont,descent);
184 clip = cfbGetCompositeClip(pGC);
185 extents = &clip->extents;
187 if (!clip->data)
189 if (!BOX_CONTAINS(extents, &bbox, x, y))
191 if (BOX_OVERLAP (extents, &bbox, x, y))
192 cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
193 nglyph, ppci, pglyphBase);
194 return;
197 else
199 /* check to make sure some of the text appears on the screen */
200 if (!BOX_OVERLAP (extents, &bbox, x, y))
201 return;
203 bbox.x1 += x;
204 bbox.x2 += x;
205 bbox.y1 += y;
206 bbox.y2 += y;
208 switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox))
210 case rgnPART:
211 cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
212 nglyph, ppci, pglyphBase);
213 case rgnOUT:
214 return;
218 #ifdef GLYPHROP
219 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
220 #else
221 pixel = cfbGetGCPrivate(pGC)->xor;
222 #endif
224 cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, CfbBits)
226 widthDst = bwidthDst / PGSZB;
227 while (nglyph--)
229 pci = *ppci++;
230 glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
231 xoff = x + pci->metrics.leftSideBearing;
232 #if PSZ == 24
233 dstLine = pdstBase + (y - pci->metrics.ascent) * widthDst +((xoff>> 2)*3);
234 #else
235 dstLine = pdstBase +
236 (y - pci->metrics.ascent) * widthDst + (xoff >> PWSH);
237 #endif
238 x += pci->metrics.characterWidth;
239 if ((hTmp = pci->metrics.descent + pci->metrics.ascent))
241 #if PSZ == 24
242 xoff &= 0x03;
243 #else
244 xoff &= PIM;
245 #endif /* PSZ == 24 */
246 #ifdef STIPPLE
247 STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
248 #else
249 #ifdef USE_STIPPLE_CODE
250 (*stipple)(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
251 #else
252 #ifdef USE_LEFTBITS
253 w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
254 widthGlyph = PADGLYPHWIDTHBYTES(w);
255 widthMask = mfbGetendtab(w);
256 #endif
257 do {
258 dst = dstLine;
259 dstLine = (CfbBits *) (((char *) dstLine) + bwidthDst);
260 GlyphBits(glyphBits, w, c)
261 WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
262 dst += DST_INC;
263 c = BitLeft(c,PGSZB - xoff);
264 while (c)
266 WriteBitGroup(dst, pixel, GetBitGroup(c));
267 NextBitGroup(c);
268 dst += DST_INC;
270 } while (--hTmp);
271 #endif /* USE_STIPPLE_CODE else */
272 #endif /* STIPPLE else */
277 static void
278 cfbPolyGlyphBlt8Clipped(
279 DrawablePtr pDrawable,
280 GCPtr pGC,
281 int x,
282 int y,
283 unsigned int nglyph,
284 CharInfoPtr *ppci, /* array of character info */
285 unsigned char *pglyphBase) /* start of array of glyphs */
287 #ifndef GLYPHROP
288 register CfbBits pixel;
289 #endif
290 #if !defined(STIPPLE) && !defined(USE_STIPPLE_CODE)
291 register CfbBits c;
292 #endif
293 register glyphPointer glyphBits;
294 register int xoff;
295 #if defined(USE_LEFTBITS) || (!defined(STIPPLE) && !defined(USE_STIPPLE_CODE))
296 register CfbBits *dst;
297 #endif
299 CharInfoPtr pci;
300 FontPtr pfont = pGC->font;
301 CfbBits *dstLine;
302 CfbBits *pdstBase;
303 #ifdef USE_LEFTBITS
304 CARD32 *cTmp;
305 #endif
306 CARD32 *clips;
307 int maxAscent, maxDescent;
308 int minLeftBearing;
309 int hTmp;
310 int widthDst;
311 int bwidthDst;
312 int xG, yG;
313 BoxPtr pBox;
314 int numRects;
315 int w;
316 RegionPtr pRegion;
317 int yBand;
318 #ifdef GLYPHROP
319 CfbBits bits;
320 #endif
321 #ifdef USE_LEFTBITS
322 int widthGlyph;
323 CfbBits widthMask;
324 #endif
326 #ifdef GLYPHROP
327 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
328 #else
329 pixel = cfbGetGCPrivate(pGC)->xor;
330 #endif
332 cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, CfbBits)
334 widthDst = bwidthDst / PGSZB;
335 maxAscent = FONTMAXBOUNDS(pfont,ascent);
336 maxDescent = FONTMAXBOUNDS(pfont,descent);
337 minLeftBearing = FONTMINBOUNDS(pfont,leftSideBearing);
339 pRegion = cfbGetCompositeClip(pGC);
341 pBox = REGION_RECTS(pRegion);
342 numRects = REGION_NUM_RECTS (pRegion);
343 while (numRects && pBox->y2 <= y - maxAscent)
345 ++pBox;
346 --numRects;
348 if (!numRects || pBox->y1 >= y + maxDescent)
349 return;
350 yBand = pBox->y1;
351 while (numRects && pBox->y1 == yBand && pBox->x2 <= x + minLeftBearing)
353 ++pBox;
354 --numRects;
356 if (!numRects)
357 return;
358 clips = (CARD32 *)ALLOCATE_LOCAL ((maxAscent + maxDescent) *
359 sizeof (CARD32));
360 while (nglyph--)
362 pci = *ppci++;
363 glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
364 w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
365 xG = x + pci->metrics.leftSideBearing;
366 yG = y - pci->metrics.ascent;
367 x += pci->metrics.characterWidth;
368 if ((hTmp = pci->metrics.descent + pci->metrics.ascent))
370 #if PSZ == 24
371 dstLine = pdstBase + yG * widthDst + ((xG>> 2)*3);
372 /* never use (xG*3)>>2 */
373 #else
374 dstLine = pdstBase + yG * widthDst + (xG >> PWSH);
375 #endif
376 #if PSZ == 24
377 xoff = xG & 3;
378 #else
379 xoff = xG & PIM;
380 #endif
381 #ifdef USE_LEFTBITS
382 w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
383 widthGlyph = PADGLYPHWIDTHBYTES(w);
384 widthMask = mfbGetendtab(w);
385 #endif
386 switch (cfb8ComputeClipMasks32 (pBox, numRects, xG, yG, w, hTmp, clips))
388 case rgnPART:
389 #ifdef USE_LEFTBITS
390 cTmp = clips;
391 do {
392 dst = dstLine;
393 dstLine = (CfbBits *) (((char *) dstLine) + bwidthDst);
394 GlyphBits(glyphBits, w, c)
395 c &= *cTmp++;
396 if (c)
398 WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
399 c = BitLeft(c,PGSZB - xoff);
400 dst += DST_INC;
401 while (c)
403 WriteBitGroup(dst, pixel, GetBitGroup(c));
404 NextBitGroup(c);
405 dst += DST_INC;
408 } while (--hTmp);
409 break;
410 #else /* !USE_LEFTBITS */
412 int h;
414 h = hTmp;
417 --h;
418 clips[h] = clips[h] & glyphBits[h];
419 } while (h);
421 glyphBits = clips;
422 /* fall through */
423 #endif /* USE_LEFTBITS */
424 case rgnIN:
425 #ifdef STIPPLE
426 STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
427 #else
428 #ifdef USE_STIPPLE_CODE
429 cfbStippleStackTE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
430 #else
431 do {
432 dst = dstLine;
433 dstLine = (CfbBits *) (((char *) dstLine) + bwidthDst);
434 GlyphBits(glyphBits, w, c)
435 if (c)
437 /* This code originally could read memory locations
438 * that were not mapped. Hence we have to check the
439 * trailing bits to see whether they are zero and if
440 * then skip them correctly. This is no problem for
441 * the GXcopy case, since there only the pixels that
442 * are non-zero are written ...
444 #ifndef GLYPHROP
445 WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
446 c = BitLeft(c,PGSZB - xoff);
447 dst += DST_INC;
448 #else /* GLYPHROP */
449 if ((bits = GetBitGroup(BitRight(c,xoff))))
450 WriteBitGroup(dst, pixel, bits);
451 c = BitLeft(c,PGSZB - xoff);
452 dst += DST_INC;
454 while (c && ((bits = GetBitGroup(c)) == 0))
456 NextBitGroup(c);
457 dst += DST_INC;
459 #endif /* GLYPHROP */
460 while (c)
462 WriteBitGroup(dst, pixel, GetBitGroup(c));
463 NextBitGroup(c);
464 dst += DST_INC;
467 } while (--hTmp);
468 #endif /* USE_STIPPLE_CODE else */
469 #endif /* STIPPLE else */
470 break;
474 DEALLOCATE_LOCAL (clips);
477 #endif /* FOUR_BIT_CODE */