1
2/********************************************************************
3
4   In this file we have GC level replacements for PolyText8/16,
5   ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
6   The idea is that everything in this file is device independent.
7   The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
8   which calculates the boxes containing arbitrarily clipped text
9   and passes them to the TEGlyphRenderer which will usually be a lower
10   level XAA function which renders these clipped glyphs using
11   the basic color expansion functions exported by the chipset driver.
12   The TEGlyphRenderer itself may optionally be driver supplied to
13   facilitate work-arounds/optimizations at a higher level than usual.
14
15   v1.0 - Mark Vojkovich (mvojkovi@ucsd.edu)
16
17
18********************************************************************/
19
20#ifdef HAVE_XORG_CONFIG_H
21#include <xorg-config.h>
22#endif
23
24#include "misc.h"
25#include "xf86.h"
26#include "xf86_OSproc.h"
27
28#include <X11/X.h>
29#include <X11/fonts/font.h>
30#include "scrnintstr.h"
31#include "dixfontstr.h"
32#include "xf86str.h"
33#include "xaa.h"
34#include "xaalocal.h"
35#include "gcstruct.h"
36#include "pixmapstr.h"
37
38
39static void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
40			int yInit, FontPtr font, int fg, int bg, int rop,
41			unsigned int planemask, RegionPtr cclip, int nglyph,
42			unsigned char* gBase, CharInfoPtr *ppci);
43
44
45/********************************************************************
46
47   GC level replacements for PolyText8/16 and ImageText8/16
48   for TE fonts when using color expansion.
49
50********************************************************************/
51
52
53int
54XAAPolyText8TEColorExpansion(
55    DrawablePtr pDraw,
56    GCPtr pGC,
57    int	x, int y,
58    int count,
59    char *chars )
60{
61    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
62    unsigned long n;
63
64    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
65		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
66
67    /* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
68    if(n) XAAGlyphBltTEColorExpansion(
69	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
70	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
71	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
72
73    return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
74}
75
76
77int
78XAAPolyText16TEColorExpansion(
79    DrawablePtr pDraw,
80    GCPtr pGC,
81    int	x, int y,
82    int count,
83    unsigned short *chars )
84{
85    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
86    unsigned long n;
87
88    (*pGC->font->get_glyphs)(
89		pGC->font, (unsigned long)count, (unsigned char *)chars,
90		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
91		&n, infoRec->CharInfo);
92
93    if(n) XAAGlyphBltTEColorExpansion(
94	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
95	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
96	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
97
98    return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
99}
100
101
102void
103XAAImageText8TEColorExpansion(
104    DrawablePtr pDraw,
105    GCPtr pGC,
106    int	x, int y,
107    int count,
108    char *chars )
109{
110    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
111    unsigned long n;
112
113    if(!RegionNumRects(pGC->pCompositeClip))
114	return;
115
116    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
117		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
118
119    if(n) XAAGlyphBltTEColorExpansion(
120	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
121	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
122	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
123}
124
125
126void
127XAAImageText16TEColorExpansion(
128    DrawablePtr pDraw,
129    GCPtr pGC,
130    int	x, int y,
131    int count,
132    unsigned short *chars )
133{
134    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
135    unsigned long n;
136
137    if(!RegionNumRects(pGC->pCompositeClip))
138	return;
139
140    (*pGC->font->get_glyphs)(
141	      pGC->font, (unsigned long)count, (unsigned char *)chars,
142	      (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
143	      &n, infoRec->CharInfo);
144
145    if(n) XAAGlyphBltTEColorExpansion(
146	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
147	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
148	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
149}
150
151
152
153/********************************************************************
154
155   GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
156   TE fonts when using color expansion.
157
158********************************************************************/
159
160
161void
162XAAImageGlyphBltTEColorExpansion(
163    DrawablePtr pDrawable,
164    GCPtr pGC,
165    int xInit, int yInit,
166    unsigned int nglyph,
167    CharInfoPtr *ppci,
168    pointer pglyphBase )
169{
170    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
171
172    if(!RegionNumRects(pGC->pCompositeClip))
173	return;
174
175    XAAGlyphBltTEColorExpansion(
176	infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
177	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
178	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
179}
180
181void
182XAAPolyGlyphBltTEColorExpansion(
183    DrawablePtr pDrawable,
184    GCPtr pGC,
185    int xInit, int yInit,
186    unsigned int nglyph,
187    CharInfoPtr *ppci,
188    pointer pglyphBase )
189{
190    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
191
192    if(!RegionNumRects(pGC->pCompositeClip))
193	return;
194
195    XAAGlyphBltTEColorExpansion(
196	infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
197	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
198	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
199}
200
201
202
203
204/********************************************************************
205
206   XAAGlyphBltTEColorExpansion -
207
208   This guy computes the clipped pieces of text and sends it to
209   the lower-level function which will handle acceleration of
210   arbitrarily clipped text.
211
212********************************************************************/
213
214
215static void
216XAAGlyphBltTEColorExpansion(
217   ScrnInfoPtr pScrn,
218   int xInit, int yInit,
219   FontPtr font,
220   int fg, int bg,
221   int rop,
222   unsigned int planemask,
223   RegionPtr cclip,
224   int nglyph,
225   unsigned char* gBase,
226   CharInfoPtr *ppci )
227{
228    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
229    int skippix, skipglyphs;
230    int Left, Right, Top, Bottom;
231    int LeftEdge, RightEdge, ytop, ybot;
232    int nbox = RegionNumRects(cclip);
233    BoxPtr pbox = RegionRects(cclip);
234    unsigned int **glyphs = NULL;
235    int glyphWidth = FONTMAXBOUNDS(font, characterWidth);
236
237    /* find the size of the box */
238    Left = xInit;
239    Right = Left + (glyphWidth * nglyph);
240    Top = yInit - FONTASCENT(font);
241    Bottom =  yInit + FONTDESCENT(font);
242
243    /* get into the first band that may contain part of our string */
244    while(nbox && (Top >= pbox->y2)) {
245	pbox++; nbox--;
246    }
247
248    /* stop when the lower edge of the box is beyond our string */
249    while(nbox && (Bottom > pbox->y1)) {
250	LeftEdge = max(Left, pbox->x1);
251	RightEdge = min(Right, pbox->x2);
252
253	if(RightEdge > LeftEdge) {	/* we have something to draw */
254	    unsigned int *fallbackBits = NULL;
255	    ytop = max(Top, pbox->y1);
256	    ybot = min(Bottom, pbox->y2);
257
258	    if((skippix = LeftEdge - Left)) {
259		skipglyphs = skippix/glyphWidth;
260		skippix %= glyphWidth;
261	    } else skipglyphs = 0;
262
263	    if(!glyphs) {
264		int count;
265		glyphs = (unsigned int**)(infoRec->PreAllocMem);
266
267		for(count = 0; count < nglyph; count++) {
268 			glyphs[count] = (unsigned int*)
269				FONTGLYPHBITS(gBase,*ppci++);
270			if (!glyphs[count]) {
271			    /* Glyphs with NULL bits do exist in the wild.
272			       Replace with blank bits in that case */
273
274			    if (!fallbackBits) {
275				int fontHeight = Bottom - Top + 1;
276				fallbackBits = calloc(glyphWidth * fontHeight, 1);
277				if (!fallbackBits)
278				    return;
279			    }
280			    glyphs[count] = fallbackBits;
281			}
282		}
283
284		/* our new unrolled TE code only writes DWORDS at a time
285		   so it can read up to 6 characters past the last one
286		   we're displaying */
287		glyphs[count + 0] = glyphs[0];
288		glyphs[count + 1] = glyphs[0];
289		glyphs[count + 2] = glyphs[0];
290		glyphs[count + 3] = glyphs[0];
291		glyphs[count + 4] = glyphs[0];
292		glyphs[count + 5] = glyphs[0];
293	    }
294
295    /* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */
296
297	    (*infoRec->TEGlyphRenderer)( pScrn,
298		LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop,
299		skippix, ytop - Top, glyphs + skipglyphs, glyphWidth,
300		fg, bg, rop, planemask);
301
302	    free(fallbackBits);
303	}
304
305	nbox--; pbox++;
306    }
307}
308
309
310
311
312