initial commit
[profile/ivi/xorg-x11-server.git] / hw / xfree86 / xaa / xaaTEText.c
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
39 static 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
53 int
54 XAAPolyText8TEColorExpansion(
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
77 int
78 XAAPolyText16TEColorExpansion(
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
102 void
103 XAAImageText8TEColorExpansion(
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
126 void
127 XAAImageText16TEColorExpansion(
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
161 void
162 XAAImageGlyphBltTEColorExpansion(
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
181 void
182 XAAPolyGlyphBltTEColorExpansion(
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
215 static void
216 XAAGlyphBltTEColorExpansion(
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