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
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
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
37 #include <X11/Xproto.h>
39 #include <X11/fonts/fontstruct.h>
40 #include "dixfontstr.h"
42 #include "windowstr.h"
43 #include "scrnintstr.h"
44 #include "pixmapstr.h"
45 #include "regionstr.h"
46 #include "cfbmskbits.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
68 typedef unsigned char *glyphPointer
;
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(
92 DrawablePtr pDrawable
,
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
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
108 #include "stip68kgnu.h"
114 #define DST_INC (PGSZB >> PWSH)
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 ();
125 cfbPolyGlyphBlt8 (pDrawable
, pGC
, x
, y
, nglyph
, ppci
, pglyphBase
)
126 DrawablePtr pDrawable
;
130 CharInfoPtr
*ppci
; /* array of character info */
131 pointer pglyphBase
; /* start of array of glyphs */
134 register CfbBits pixel
;
136 #if !defined(STIPPLE) && !defined(USE_STIPPLE_CODE)
138 register CfbBits
*dst
;
140 register glyphPointer glyphBits
;
143 FontPtr pfont
= pGC
->font
;
151 BoxRec bbox
; /* for clipping */
160 #ifdef USE_STIPPLE_CODE
163 stipple
= cfbStippleStack
;
164 if (FONTCONSTMETRICS(pfont
))
165 stipple
= cfbStippleStackTE
;
172 /* compute an approximate (but covering) bounding box */
174 if ((ppci
[0]->metrics
.leftSideBearing
< 0))
175 bbox
.x1
= ppci
[0]->metrics
.leftSideBearing
;
177 w
= ppci
[h
]->metrics
.rightSideBearing
;
179 w
+= ppci
[h
]->metrics
.characterWidth
;
181 bbox
.y1
= -FONTMAXBOUNDS(pfont
,ascent
);
182 bbox
.y2
= FONTMAXBOUNDS(pfont
,descent
);
184 clip
= cfbGetCompositeClip(pGC
);
185 extents
= &clip
->extents
;
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
);
199 /* check to make sure some of the text appears on the screen */
200 if (!BOX_OVERLAP (extents
, &bbox
, x
, y
))
208 switch (RECT_IN_REGION(pGC
->pScreen
, clip
, &bbox
))
211 cfbPolyGlyphBlt8Clipped(pDrawable
, pGC
, x
, y
,
212 nglyph
, ppci
, pglyphBase
);
219 cfb8CheckStipple (pGC
->alu
, pGC
->fgPixel
, pGC
->planemask
);
221 pixel
= cfbGetGCPrivate(pGC
)->xor;
224 cfbGetTypedWidthAndPointer (pDrawable
, bwidthDst
, pdstBase
, char, CfbBits
)
226 widthDst
= bwidthDst
/ PGSZB
;
230 glyphBits
= (glyphPointer
) FONTGLYPHBITS(pglyphBase
,pci
);
231 xoff
= x
+ pci
->metrics
.leftSideBearing
;
233 dstLine
= pdstBase
+ (y
- pci
->metrics
.ascent
) * widthDst
+((xoff
>> 2)*3);
236 (y
- pci
->metrics
.ascent
) * widthDst
+ (xoff
>> PWSH
);
238 x
+= pci
->metrics
.characterWidth
;
239 if ((hTmp
= pci
->metrics
.descent
+ pci
->metrics
.ascent
))
245 #endif /* PSZ == 24 */
247 STIPPLE(dstLine
,glyphBits
,pixel
,bwidthDst
,hTmp
,xoff
);
249 #ifdef USE_STIPPLE_CODE
250 (*stipple
)(dstLine
,glyphBits
,pixel
,bwidthDst
,hTmp
,xoff
);
253 w
= pci
->metrics
.rightSideBearing
- pci
->metrics
.leftSideBearing
;
254 widthGlyph
= PADGLYPHWIDTHBYTES(w
);
255 widthMask
= mfbGetendtab(w
);
259 dstLine
= (CfbBits
*) (((char *) dstLine
) + bwidthDst
);
260 GlyphBits(glyphBits
, w
, c
)
261 WriteBitGroup(dst
, pixel
, GetBitGroup(BitRight(c
,xoff
)));
263 c
= BitLeft(c
,PGSZB
- xoff
);
266 WriteBitGroup(dst
, pixel
, GetBitGroup(c
));
271 #endif /* USE_STIPPLE_CODE else */
272 #endif /* STIPPLE else */
278 cfbPolyGlyphBlt8Clipped(
279 DrawablePtr pDrawable
,
284 CharInfoPtr
*ppci
, /* array of character info */
285 unsigned char *pglyphBase
) /* start of array of glyphs */
288 register CfbBits pixel
;
290 #if !defined(STIPPLE) && !defined(USE_STIPPLE_CODE)
293 register glyphPointer glyphBits
;
295 #if defined(USE_LEFTBITS) || (!defined(STIPPLE) && !defined(USE_STIPPLE_CODE))
296 register CfbBits
*dst
;
300 FontPtr pfont
= pGC
->font
;
307 int maxAscent
, maxDescent
;
327 cfb8CheckStipple (pGC
->alu
, pGC
->fgPixel
, pGC
->planemask
);
329 pixel
= cfbGetGCPrivate(pGC
)->xor;
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
)
348 if (!numRects
|| pBox
->y1
>= y
+ maxDescent
)
351 while (numRects
&& pBox
->y1
== yBand
&& pBox
->x2
<= x
+ minLeftBearing
)
358 clips
= (CARD32
*)ALLOCATE_LOCAL ((maxAscent
+ maxDescent
) *
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
))
371 dstLine
= pdstBase
+ yG
* widthDst
+ ((xG
>> 2)*3);
372 /* never use (xG*3)>>2 */
374 dstLine
= pdstBase
+ yG
* widthDst
+ (xG
>> PWSH
);
382 w
= pci
->metrics
.rightSideBearing
- pci
->metrics
.leftSideBearing
;
383 widthGlyph
= PADGLYPHWIDTHBYTES(w
);
384 widthMask
= mfbGetendtab(w
);
386 switch (cfb8ComputeClipMasks32 (pBox
, numRects
, xG
, yG
, w
, hTmp
, clips
))
393 dstLine
= (CfbBits
*) (((char *) dstLine
) + bwidthDst
);
394 GlyphBits(glyphBits
, w
, c
)
398 WriteBitGroup(dst
, pixel
, GetBitGroup(BitRight(c
,xoff
)));
399 c
= BitLeft(c
,PGSZB
- xoff
);
403 WriteBitGroup(dst
, pixel
, GetBitGroup(c
));
410 #else /* !USE_LEFTBITS */
418 clips
[h
] = clips
[h
] & glyphBits
[h
];
423 #endif /* USE_LEFTBITS */
426 STIPPLE(dstLine
,glyphBits
,pixel
,bwidthDst
,hTmp
,xoff
);
428 #ifdef USE_STIPPLE_CODE
429 cfbStippleStackTE(dstLine
,glyphBits
,pixel
,bwidthDst
,hTmp
,xoff
);
433 dstLine
= (CfbBits
*) (((char *) dstLine
) + bwidthDst
);
434 GlyphBits(glyphBits
, w
, 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 ...
445 WriteBitGroup(dst
, pixel
, GetBitGroup(BitRight(c
,xoff
)));
446 c
= BitLeft(c
,PGSZB
- xoff
);
449 if ((bits
= GetBitGroup(BitRight(c
,xoff
))))
450 WriteBitGroup(dst
, pixel
, bits
);
451 c
= BitLeft(c
,PGSZB
- xoff
);
454 while (c
&& ((bits
= GetBitGroup(c
)) == 0))
459 #endif /* GLYPHROP */
462 WriteBitGroup(dst
, pixel
, GetBitGroup(c
));
468 #endif /* USE_STIPPLE_CODE else */
469 #endif /* STIPPLE else */
474 DEALLOCATE_LOCAL (clips
);
477 #endif /* FOUR_BIT_CODE */