1706f2543Smrg
2706f2543Smrg/********************************************************************
3706f2543Smrg
4706f2543Smrg   In this file we have GC level replacements for PolyText8/16,
5706f2543Smrg   ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
6706f2543Smrg   The idea is that everything in this file is device independent.
7706f2543Smrg   The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
8706f2543Smrg   which calculates the boxes containing arbitrarily clipped text
9706f2543Smrg   and passes them to the TEGlyphRenderer which will usually be a lower
10706f2543Smrg   level XAA function which renders these clipped glyphs using
11706f2543Smrg   the basic color expansion functions exported by the chipset driver.
12706f2543Smrg   The TEGlyphRenderer itself may optionally be driver supplied to
13706f2543Smrg   facilitate work-arounds/optimizations at a higher level than usual.
14706f2543Smrg
15706f2543Smrg   v1.0 - Mark Vojkovich (mvojkovi@ucsd.edu)
16706f2543Smrg
17706f2543Smrg
18706f2543Smrg********************************************************************/
19706f2543Smrg
20706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
21706f2543Smrg#include <xorg-config.h>
22706f2543Smrg#endif
23706f2543Smrg
24706f2543Smrg#include "misc.h"
25706f2543Smrg#include "xf86.h"
26706f2543Smrg#include "xf86_OSproc.h"
27706f2543Smrg
28706f2543Smrg#include <X11/X.h>
29706f2543Smrg#include <X11/fonts/font.h>
30706f2543Smrg#include "scrnintstr.h"
31706f2543Smrg#include "dixfontstr.h"
32706f2543Smrg#include "xf86str.h"
33706f2543Smrg#include "xaa.h"
34706f2543Smrg#include "xaalocal.h"
35706f2543Smrg#include "gcstruct.h"
36706f2543Smrg#include "pixmapstr.h"
37706f2543Smrg
38706f2543Smrg
39706f2543Smrgstatic void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
40706f2543Smrg			int yInit, FontPtr font, int fg, int bg, int rop,
41706f2543Smrg			unsigned int planemask, RegionPtr cclip, int nglyph,
42706f2543Smrg			unsigned char* gBase, CharInfoPtr *ppci);
43706f2543Smrg
44706f2543Smrg
45706f2543Smrg/********************************************************************
46706f2543Smrg
47706f2543Smrg   GC level replacements for PolyText8/16 and ImageText8/16
48706f2543Smrg   for TE fonts when using color expansion.
49706f2543Smrg
50706f2543Smrg********************************************************************/
51706f2543Smrg
52706f2543Smrg
53706f2543Smrgint
54706f2543SmrgXAAPolyText8TEColorExpansion(
55706f2543Smrg    DrawablePtr pDraw,
56706f2543Smrg    GCPtr pGC,
57706f2543Smrg    int	x, int y,
58706f2543Smrg    int count,
59706f2543Smrg    char *chars )
60706f2543Smrg{
61706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
62706f2543Smrg    unsigned long n;
63706f2543Smrg
64706f2543Smrg    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
65706f2543Smrg		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
66706f2543Smrg
67706f2543Smrg    /* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
68706f2543Smrg    if(n) XAAGlyphBltTEColorExpansion(
69706f2543Smrg	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
70706f2543Smrg	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
71706f2543Smrg	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
72706f2543Smrg
73706f2543Smrg    return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
74706f2543Smrg}
75706f2543Smrg
76706f2543Smrg
77706f2543Smrgint
78706f2543SmrgXAAPolyText16TEColorExpansion(
79706f2543Smrg    DrawablePtr pDraw,
80706f2543Smrg    GCPtr pGC,
81706f2543Smrg    int	x, int y,
82706f2543Smrg    int count,
83706f2543Smrg    unsigned short *chars )
84706f2543Smrg{
85706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
86706f2543Smrg    unsigned long n;
87706f2543Smrg
88706f2543Smrg    (*pGC->font->get_glyphs)(
89706f2543Smrg		pGC->font, (unsigned long)count, (unsigned char *)chars,
90706f2543Smrg		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
91706f2543Smrg		&n, infoRec->CharInfo);
92706f2543Smrg
93706f2543Smrg    if(n) XAAGlyphBltTEColorExpansion(
94706f2543Smrg	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
95706f2543Smrg	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
96706f2543Smrg	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
97706f2543Smrg
98706f2543Smrg    return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
99706f2543Smrg}
100706f2543Smrg
101706f2543Smrg
102706f2543Smrgvoid
103706f2543SmrgXAAImageText8TEColorExpansion(
104706f2543Smrg    DrawablePtr pDraw,
105706f2543Smrg    GCPtr pGC,
106706f2543Smrg    int	x, int y,
107706f2543Smrg    int count,
108706f2543Smrg    char *chars )
109706f2543Smrg{
110706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
111706f2543Smrg    unsigned long n;
112706f2543Smrg
113706f2543Smrg    if(!RegionNumRects(pGC->pCompositeClip))
114706f2543Smrg	return;
115706f2543Smrg
116706f2543Smrg    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
117706f2543Smrg		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
118706f2543Smrg
119706f2543Smrg    if(n) XAAGlyphBltTEColorExpansion(
120706f2543Smrg	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
121706f2543Smrg	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
122706f2543Smrg	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
123706f2543Smrg}
124706f2543Smrg
125706f2543Smrg
126706f2543Smrgvoid
127706f2543SmrgXAAImageText16TEColorExpansion(
128706f2543Smrg    DrawablePtr pDraw,
129706f2543Smrg    GCPtr pGC,
130706f2543Smrg    int	x, int y,
131706f2543Smrg    int count,
132706f2543Smrg    unsigned short *chars )
133706f2543Smrg{
134706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
135706f2543Smrg    unsigned long n;
136706f2543Smrg
137706f2543Smrg    if(!RegionNumRects(pGC->pCompositeClip))
138706f2543Smrg	return;
139706f2543Smrg
140706f2543Smrg    (*pGC->font->get_glyphs)(
141706f2543Smrg	      pGC->font, (unsigned long)count, (unsigned char *)chars,
142706f2543Smrg	      (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
143706f2543Smrg	      &n, infoRec->CharInfo);
144706f2543Smrg
145706f2543Smrg    if(n) XAAGlyphBltTEColorExpansion(
146706f2543Smrg	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
147706f2543Smrg	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
148706f2543Smrg	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
149706f2543Smrg}
150706f2543Smrg
151706f2543Smrg
152706f2543Smrg
153706f2543Smrg/********************************************************************
154706f2543Smrg
155706f2543Smrg   GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
156706f2543Smrg   TE fonts when using color expansion.
157706f2543Smrg
158706f2543Smrg********************************************************************/
159706f2543Smrg
160706f2543Smrg
161706f2543Smrgvoid
162706f2543SmrgXAAImageGlyphBltTEColorExpansion(
163706f2543Smrg    DrawablePtr pDrawable,
164706f2543Smrg    GCPtr pGC,
165706f2543Smrg    int xInit, int yInit,
166706f2543Smrg    unsigned int nglyph,
167706f2543Smrg    CharInfoPtr *ppci,
168706f2543Smrg    pointer pglyphBase )
169706f2543Smrg{
170706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
171706f2543Smrg
172706f2543Smrg    if(!RegionNumRects(pGC->pCompositeClip))
173706f2543Smrg	return;
174706f2543Smrg
175706f2543Smrg    XAAGlyphBltTEColorExpansion(
176706f2543Smrg	infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
177706f2543Smrg	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
178706f2543Smrg	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
179706f2543Smrg}
180706f2543Smrg
181706f2543Smrgvoid
182706f2543SmrgXAAPolyGlyphBltTEColorExpansion(
183706f2543Smrg    DrawablePtr pDrawable,
184706f2543Smrg    GCPtr pGC,
185706f2543Smrg    int xInit, int yInit,
186706f2543Smrg    unsigned int nglyph,
187706f2543Smrg    CharInfoPtr *ppci,
188706f2543Smrg    pointer pglyphBase )
189706f2543Smrg{
190706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
191706f2543Smrg
192706f2543Smrg    if(!RegionNumRects(pGC->pCompositeClip))
193706f2543Smrg	return;
194706f2543Smrg
195706f2543Smrg    XAAGlyphBltTEColorExpansion(
196706f2543Smrg	infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
197706f2543Smrg	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
198706f2543Smrg	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
199706f2543Smrg}
200706f2543Smrg
201706f2543Smrg
202706f2543Smrg
203706f2543Smrg
204706f2543Smrg/********************************************************************
205706f2543Smrg
206706f2543Smrg   XAAGlyphBltTEColorExpansion -
207706f2543Smrg
208706f2543Smrg   This guy computes the clipped pieces of text and sends it to
209706f2543Smrg   the lower-level function which will handle acceleration of
210706f2543Smrg   arbitrarily clipped text.
211706f2543Smrg
212706f2543Smrg********************************************************************/
213706f2543Smrg
214706f2543Smrg
215706f2543Smrgstatic void
216706f2543SmrgXAAGlyphBltTEColorExpansion(
217706f2543Smrg   ScrnInfoPtr pScrn,
218706f2543Smrg   int xInit, int yInit,
219706f2543Smrg   FontPtr font,
220706f2543Smrg   int fg, int bg,
221706f2543Smrg   int rop,
222706f2543Smrg   unsigned int planemask,
223706f2543Smrg   RegionPtr cclip,
224706f2543Smrg   int nglyph,
225706f2543Smrg   unsigned char* gBase,
226706f2543Smrg   CharInfoPtr *ppci )
227706f2543Smrg{
228706f2543Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
229706f2543Smrg    int skippix, skipglyphs;
230706f2543Smrg    int Left, Right, Top, Bottom;
231706f2543Smrg    int LeftEdge, RightEdge, ytop, ybot;
232706f2543Smrg    int nbox = RegionNumRects(cclip);
233706f2543Smrg    BoxPtr pbox = RegionRects(cclip);
234706f2543Smrg    unsigned int **glyphs = NULL;
235706f2543Smrg    int glyphWidth = FONTMAXBOUNDS(font, characterWidth);
236706f2543Smrg
237706f2543Smrg    /* find the size of the box */
238706f2543Smrg    Left = xInit;
239706f2543Smrg    Right = Left + (glyphWidth * nglyph);
240706f2543Smrg    Top = yInit - FONTASCENT(font);
241706f2543Smrg    Bottom =  yInit + FONTDESCENT(font);
242706f2543Smrg
243706f2543Smrg    /* get into the first band that may contain part of our string */
244706f2543Smrg    while(nbox && (Top >= pbox->y2)) {
245706f2543Smrg	pbox++; nbox--;
246706f2543Smrg    }
247706f2543Smrg
248706f2543Smrg    /* stop when the lower edge of the box is beyond our string */
249706f2543Smrg    while(nbox && (Bottom > pbox->y1)) {
250706f2543Smrg	LeftEdge = max(Left, pbox->x1);
251706f2543Smrg	RightEdge = min(Right, pbox->x2);
252706f2543Smrg
253706f2543Smrg	if(RightEdge > LeftEdge) {	/* we have something to draw */
254706f2543Smrg	    unsigned int *fallbackBits = NULL;
255706f2543Smrg	    ytop = max(Top, pbox->y1);
256706f2543Smrg	    ybot = min(Bottom, pbox->y2);
257706f2543Smrg
258706f2543Smrg	    if((skippix = LeftEdge - Left)) {
259706f2543Smrg		skipglyphs = skippix/glyphWidth;
260706f2543Smrg		skippix %= glyphWidth;
261706f2543Smrg	    } else skipglyphs = 0;
262706f2543Smrg
263706f2543Smrg	    if(!glyphs) {
264706f2543Smrg		int count;
265706f2543Smrg		glyphs = (unsigned int**)(infoRec->PreAllocMem);
266706f2543Smrg
267706f2543Smrg		for(count = 0; count < nglyph; count++) {
268706f2543Smrg 			glyphs[count] = (unsigned int*)
269706f2543Smrg				FONTGLYPHBITS(gBase,*ppci++);
270706f2543Smrg			if (!glyphs[count]) {
271706f2543Smrg			    /* Glyphs with NULL bits do exist in the wild.
272706f2543Smrg			       Replace with blank bits in that case */
273706f2543Smrg
274706f2543Smrg			    if (!fallbackBits) {
275706f2543Smrg				int fontHeight = Bottom - Top + 1;
276706f2543Smrg				fallbackBits = calloc(glyphWidth * fontHeight, 1);
277706f2543Smrg				if (!fallbackBits)
278706f2543Smrg				    return;
279706f2543Smrg			    }
280706f2543Smrg			    glyphs[count] = fallbackBits;
281706f2543Smrg			}
282706f2543Smrg		}
283706f2543Smrg
284706f2543Smrg		/* our new unrolled TE code only writes DWORDS at a time
285706f2543Smrg		   so it can read up to 6 characters past the last one
286706f2543Smrg		   we're displaying */
287706f2543Smrg		glyphs[count + 0] = glyphs[0];
288706f2543Smrg		glyphs[count + 1] = glyphs[0];
289706f2543Smrg		glyphs[count + 2] = glyphs[0];
290706f2543Smrg		glyphs[count + 3] = glyphs[0];
291706f2543Smrg		glyphs[count + 4] = glyphs[0];
292706f2543Smrg		glyphs[count + 5] = glyphs[0];
293706f2543Smrg	    }
294706f2543Smrg
295706f2543Smrg    /* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */
296706f2543Smrg
297706f2543Smrg	    (*infoRec->TEGlyphRenderer)( pScrn,
298706f2543Smrg		LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop,
299706f2543Smrg		skippix, ytop - Top, glyphs + skipglyphs, glyphWidth,
300706f2543Smrg		fg, bg, rop, planemask);
301706f2543Smrg
302706f2543Smrg	    free(fallbackBits);
303706f2543Smrg	}
304706f2543Smrg
305706f2543Smrg	nbox--; pbox++;
306706f2543Smrg    }
307706f2543Smrg}
308706f2543Smrg
309706f2543Smrg
310706f2543Smrg
311706f2543Smrg
312