File: | xftcore.c |
Location: | line 288, column 19 |
Description: | The result of the '<<' expression is undefined |
1 | /* | |||
2 | * Copyright © 2000 Keith Packard | |||
3 | * | |||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |||
5 | * documentation for any purpose is hereby granted without fee, provided that | |||
6 | * the above copyright notice appear in all copies and that both that | |||
7 | * copyright notice and this permission notice appear in supporting | |||
8 | * documentation, and that the name of Keith Packard not be used in | |||
9 | * advertising or publicity pertaining to distribution of the software without | |||
10 | * specific, written prior permission. Keith Packard makes no | |||
11 | * representations about the suitability of this software for any purpose. It | |||
12 | * is provided "as is" without express or implied warranty. | |||
13 | * | |||
14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |||
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |||
16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |||
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |||
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |||
20 | * PERFORMANCE OF THIS SOFTWARE. | |||
21 | */ | |||
22 | ||||
23 | #include "xftint.h" | |||
24 | ||||
25 | _X_HIDDEN__attribute__((visibility("hidden"))) void | |||
26 | XftRectCore (XftDraw *draw, | |||
27 | _Xconstconst XftColor *color, | |||
28 | int x, | |||
29 | int y, | |||
30 | unsigned int width, | |||
31 | unsigned int height) | |||
32 | { | |||
33 | if (color->color.alpha >= 0x8000) | |||
34 | { | |||
35 | XSetForeground (draw->dpy, draw->core.gc, color->pixel); | |||
36 | XFillRectangle (draw->dpy, draw->drawable, draw->core.gc, | |||
37 | x, y, width, height); | |||
38 | } | |||
39 | } | |||
40 | ||||
41 | /* | |||
42 | * Use the core protocol to draw the glyphs | |||
43 | */ | |||
44 | ||||
45 | static void | |||
46 | _XftSharpGlyphMono (XftDraw *draw, | |||
47 | XftGlyph *glyph, | |||
48 | int x, | |||
49 | int y) | |||
50 | { | |||
51 | unsigned char *srcLine = glyph->bitmap, *src; | |||
52 | unsigned char bits, bitsMask; | |||
53 | int width = glyph->metrics.width; | |||
54 | int stride = ((width + 31) & ~31) >> 3; | |||
55 | int height = glyph->metrics.height; | |||
56 | int w; | |||
57 | int xspan, lenspan; | |||
58 | ||||
59 | x -= glyph->metrics.x; | |||
60 | y -= glyph->metrics.y; | |||
61 | while (height--) | |||
62 | { | |||
63 | src = srcLine; | |||
64 | srcLine += stride; | |||
65 | w = width; | |||
66 | ||||
67 | bitsMask = 0x80; /* FreeType is always MSB first */ | |||
68 | bits = *src++; | |||
69 | ||||
70 | xspan = x; | |||
71 | while (w) | |||
72 | { | |||
73 | if (bits & bitsMask) | |||
74 | { | |||
75 | lenspan = 0; | |||
76 | do | |||
77 | { | |||
78 | lenspan++; | |||
79 | if (lenspan == w) | |||
80 | break; | |||
81 | bitsMask = bitsMask >> 1; | |||
82 | if (!bitsMask) | |||
83 | { | |||
84 | bits = *src++; | |||
85 | bitsMask = 0x80; | |||
86 | } | |||
87 | } while (bits & bitsMask); | |||
88 | XFillRectangle (draw->dpy, draw->drawable, | |||
89 | draw->core.gc, xspan, y, lenspan, 1); | |||
90 | xspan += lenspan; | |||
91 | w -= lenspan; | |||
92 | } | |||
93 | else | |||
94 | { | |||
95 | do | |||
96 | { | |||
97 | w--; | |||
98 | xspan++; | |||
99 | if (!w) | |||
100 | break; | |||
101 | bitsMask = bitsMask >> 1; | |||
102 | if (!bitsMask) | |||
103 | { | |||
104 | bits = *src++; | |||
105 | bitsMask = 0x80; | |||
106 | } | |||
107 | } while (!(bits & bitsMask)); | |||
108 | } | |||
109 | } | |||
110 | y++; | |||
111 | } | |||
112 | } | |||
113 | ||||
114 | /* | |||
115 | * Draw solid color text from an anti-aliased bitmap. This is a | |||
116 | * fallback for cases where a particular drawable has no AA code | |||
117 | */ | |||
118 | static void | |||
119 | _XftSharpGlyphGray (XftDraw *draw, | |||
120 | XftGlyph *glyph, | |||
121 | int x, | |||
122 | int y) | |||
123 | { | |||
124 | unsigned char *srcLine = glyph->bitmap, *src, bits; | |||
125 | int width = glyph->metrics.width; | |||
126 | int stride = ((width + 3) & ~3); | |||
127 | int height = glyph->metrics.height; | |||
128 | int w; | |||
129 | int xspan, lenspan; | |||
130 | ||||
131 | x -= glyph->metrics.x; | |||
132 | y -= glyph->metrics.y; | |||
133 | while (height--) | |||
134 | { | |||
135 | src = srcLine; | |||
136 | srcLine += stride; | |||
137 | w = width; | |||
138 | ||||
139 | bits = *src++; | |||
140 | xspan = x; | |||
141 | while (w) | |||
142 | { | |||
143 | if (bits >= 0x80) | |||
144 | { | |||
145 | lenspan = 0; | |||
146 | do | |||
147 | { | |||
148 | lenspan++; | |||
149 | if (lenspan == w) | |||
150 | break; | |||
151 | bits = *src++; | |||
152 | } while (bits >= 0x80); | |||
153 | XFillRectangle (draw->dpy, draw->drawable, | |||
154 | draw->core.gc, xspan, y, lenspan, 1); | |||
155 | xspan += lenspan; | |||
156 | w -= lenspan; | |||
157 | } | |||
158 | else | |||
159 | { | |||
160 | do | |||
161 | { | |||
162 | w--; | |||
163 | xspan++; | |||
164 | if (!w) | |||
165 | break; | |||
166 | bits = *src++; | |||
167 | } while (bits < 0x80); | |||
168 | } | |||
169 | } | |||
170 | y++; | |||
171 | } | |||
172 | } | |||
173 | ||||
174 | static void | |||
175 | _XftSharpGlyphRgba (XftDraw *draw, | |||
176 | XftGlyph *glyph, | |||
177 | int x, | |||
178 | int y) | |||
179 | { | |||
180 | CARD32 *srcLine = glyph->bitmap, *src, bits; | |||
181 | int width = glyph->metrics.width; | |||
182 | int stride = ((width + 3) & ~3); | |||
183 | int height = glyph->metrics.height; | |||
184 | int w; | |||
185 | int xspan, lenspan; | |||
186 | ||||
187 | x -= glyph->metrics.x; | |||
188 | y -= glyph->metrics.y; | |||
189 | while (height--) | |||
190 | { | |||
191 | src = srcLine; | |||
192 | srcLine += stride; | |||
193 | w = width; | |||
194 | ||||
195 | bits = *src++; | |||
196 | xspan = x; | |||
197 | while (w) | |||
198 | { | |||
199 | if (bits >= 0x80000000) | |||
200 | { | |||
201 | lenspan = 0; | |||
202 | do | |||
203 | { | |||
204 | lenspan++; | |||
205 | if (lenspan == w) | |||
206 | break; | |||
207 | bits = *src++; | |||
208 | } while (bits >= 0x80000000); | |||
209 | XFillRectangle (draw->dpy, draw->drawable, | |||
210 | draw->core.gc, xspan, y, lenspan, 1); | |||
211 | xspan += lenspan; | |||
212 | w -= lenspan; | |||
213 | } | |||
214 | else | |||
215 | { | |||
216 | do | |||
217 | { | |||
218 | w--; | |||
219 | xspan++; | |||
220 | if (!w) | |||
221 | break; | |||
222 | bits = *src++; | |||
223 | } while (bits < 0x80000000); | |||
224 | } | |||
225 | } | |||
226 | y++; | |||
227 | } | |||
228 | } | |||
229 | ||||
230 | typedef void (*XftSharpGlyph) (XftDraw *draw, | |||
231 | XftGlyph *glyph, | |||
232 | int x, | |||
233 | int y); | |||
234 | ||||
235 | static XftSharpGlyph | |||
236 | _XftSharpGlyphFind (XftDraw *draw, XftFont *public) | |||
237 | { | |||
238 | XftFontInt *font = (XftFontInt *) public; | |||
239 | ||||
240 | if (!font->info.antialias) | |||
241 | return _XftSharpGlyphMono; | |||
242 | else switch (font->info.rgba) { | |||
243 | case FC_RGBA_RGB1: | |||
244 | case FC_RGBA_BGR2: | |||
245 | case FC_RGBA_VRGB3: | |||
246 | case FC_RGBA_VBGR4: | |||
247 | return _XftSharpGlyphRgba; | |||
248 | default: | |||
249 | return _XftSharpGlyphGray; | |||
250 | } | |||
251 | } | |||
252 | ||||
253 | /* | |||
254 | * Draw glyphs to a target that supports anti-aliasing | |||
255 | */ | |||
256 | ||||
257 | /* | |||
258 | * Primitives for converting between RGB values and TrueColor pixels | |||
259 | */ | |||
260 | ||||
261 | static void | |||
262 | _XftExamineBitfield (unsigned long mask, int *shift, int *len) | |||
263 | { | |||
264 | int s, l; | |||
265 | ||||
266 | s = 0; | |||
267 | while ((mask & 1) == 0) | |||
268 | { | |||
269 | mask >>= 1; | |||
270 | s++; | |||
271 | } | |||
272 | l = 0; | |||
273 | while ((mask & 1) == 1) | |||
274 | { | |||
275 | mask >>= 1; | |||
276 | l++; | |||
277 | } | |||
278 | *shift = s; | |||
279 | *len = l; | |||
280 | } | |||
281 | ||||
282 | static CARD32 | |||
283 | _XftGetField (unsigned long l_pixel, int shift, int len) | |||
284 | { | |||
285 | CARD32 pixel = (CARD32) l_pixel; | |||
286 | ||||
287 | pixel = pixel & (((1 << (len)) - 1) << shift); | |||
288 | pixel = pixel << (32 - (shift + len)) >> 24; | |||
| ||||
289 | while (len < 8) | |||
290 | { | |||
291 | pixel |= (pixel >> len); | |||
292 | len <<= 1; | |||
293 | } | |||
294 | return pixel; | |||
295 | } | |||
296 | ||||
297 | static unsigned long | |||
298 | _XftPutField (CARD32 pixel, int shift, int len) | |||
299 | { | |||
300 | unsigned long l_pixel = (unsigned long) pixel; | |||
301 | ||||
302 | shift = shift - (8 - len); | |||
303 | if (len <= 8) | |||
304 | l_pixel &= (((1 << len) - 1) << (8 - len)); | |||
305 | if (shift < 0) | |||
306 | l_pixel >>= -shift; | |||
307 | else | |||
308 | l_pixel <<= shift; | |||
309 | return l_pixel; | |||
310 | } | |||
311 | ||||
312 | /* | |||
313 | * This is used when doing XftCharFontSpec/XftGlyphFontSpec where | |||
314 | * some of the fonts are bitmaps and some are anti-aliased to handle | |||
315 | * the bitmap portions | |||
316 | */ | |||
317 | static void | |||
318 | _XftSmoothGlyphMono (XImage *image, | |||
319 | _Xconstconst XftGlyph *xftg, | |||
320 | int x, | |||
321 | int y, | |||
322 | _Xconstconst XftColor *color) | |||
323 | { | |||
324 | unsigned char *srcLine = xftg->bitmap, *src; | |||
325 | unsigned char bits, bitsMask; | |||
326 | int width = xftg->metrics.width; | |||
327 | int stride = ((width + 31) & ~31) >> 3; | |||
328 | int height = xftg->metrics.height; | |||
329 | int w; | |||
330 | int xspan; | |||
331 | int r_shift, r_len; | |||
332 | int g_shift, g_len; | |||
333 | int b_shift, b_len; | |||
334 | unsigned long pixel; | |||
335 | ||||
336 | _XftExamineBitfield (image->red_mask, &r_shift, &r_len); | |||
337 | _XftExamineBitfield (image->green_mask, &g_shift, &g_len); | |||
338 | _XftExamineBitfield (image->blue_mask, &b_shift, &b_len); | |||
339 | pixel = (_XftPutField (color->color.red >> 8, r_shift, r_len) | | |||
340 | _XftPutField (color->color.green >> 8, g_shift, g_len) | | |||
341 | _XftPutField (color->color.blue >> 8, b_shift, b_len)); | |||
342 | x -= xftg->metrics.x; | |||
343 | y -= xftg->metrics.y; | |||
344 | while (height--) | |||
345 | { | |||
346 | src = srcLine; | |||
347 | srcLine += stride; | |||
348 | w = width; | |||
349 | ||||
350 | bitsMask = 0x80; /* FreeType is always MSB first */ | |||
351 | bits = *src++; | |||
352 | ||||
353 | xspan = x; | |||
354 | while (w--) | |||
355 | { | |||
356 | if (bits & bitsMask) | |||
357 | XPutPixel (image, xspan, y, pixel)((*((image)->f.put_pixel))((image), (xspan), (y), (pixel)) ); | |||
358 | bitsMask = bitsMask >> 1; | |||
359 | if (!bitsMask) | |||
360 | { | |||
361 | bits = *src++; | |||
362 | bitsMask = 0x80; | |||
363 | } | |||
364 | xspan++; | |||
365 | } | |||
366 | y++; | |||
367 | } | |||
368 | } | |||
369 | ||||
370 | /* | |||
371 | * As simple anti-aliasing is likely to be common, there are three | |||
372 | * optimized versions for the usual true color pixel formats (888, 565, 555). | |||
373 | * Other formats are handled by the general case | |||
374 | */ | |||
375 | ||||
376 | #define cvt8888to0565(s)((((s) >> 3) & 0x001f) | (((s) >> 5) & 0x07e0 ) | (((s) >> 8) & 0xf800)) ((((s) >> 3) & 0x001f) | \ | |||
377 | (((s) >> 5) & 0x07e0) | \ | |||
378 | (((s) >> 8) & 0xf800)) | |||
379 | ||||
380 | #define cvt0565to8888(s)(((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7 )) | ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ | |||
381 | ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ | |||
382 | ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) | |||
383 | ||||
384 | #define cvt8888to0555(s)((((s) >> 3) & 0x001f) | (((s) >> 6) & 0x03e0 ) | (((s) >> 7) & 0x7c00)) ((((s) >> 3) & 0x001f) | \ | |||
385 | (((s) >> 6) & 0x03e0) | \ | |||
386 | (((s) >> 7) & 0x7c00)) | |||
387 | ||||
388 | #define cvt0555to8888(s)(((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7 )) | ((((s) << 6) & 0xf800) | (((s) >> 0) & 0x300)) | ((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000))) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ | |||
389 | ((((s) << 6) & 0xf800) | (((s) >> 0) & 0x300)) | \ | |||
390 | ((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000))) | |||
391 | ||||
392 | ||||
393 | #define XftIntMult(a,b,t)( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>> 8 ) ) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) ) | |||
394 | #define XftIntDiv(a,b)(((CARD16) (a) * 255) / (b)) (((CARD16) (a) * 255) / (b)) | |||
395 | ||||
396 | #define XftGet8(v,i)((CARD16) (CARD8) ((v) >> i)) ((CARD16) (CARD8) ((v) >> i)) | |||
397 | ||||
398 | /* | |||
399 | * There are two ways of handling alpha -- either as a single unified value or | |||
400 | * a separate value for each component, hence each macro must have two | |||
401 | * versions. The unified alpha version has a 'U' at the end of the name, | |||
402 | * the component version has a 'C'. Similarly, functions which deal with | |||
403 | * this difference will have two versions using the same convention. | |||
404 | */ | |||
405 | ||||
406 | #define XftOverU(x,y,i,a,t)((t) = ( ((t)) = (((CARD16) (CARD8) ((y) >> i))) * ((a) ) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) + ((CARD16 ) (CARD8) ((x) >> i)), (CARD32) ((CARD8) ((t) | (0 - (( t) >> 8)))) << (i)) ((t) = XftIntMult(XftGet8(y,i),(a),(t))( ((t)) = (((CARD16) (CARD8) ((y) >> i))) * ((a)) + 0x80 , ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) + XftGet8(x,i)((CARD16) (CARD8) ((x) >> i)),\ | |||
407 | (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i)) | |||
408 | ||||
409 | #define XftOverC(x,y,i,a,t)((t) = ( ((t)) = (((CARD16) (CARD8) ((y) >> i))) * (((CARD16 ) (CARD8) ((a) >> i))) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) + ((CARD16) (CARD8) ((x) >> i)), ( CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i) ) ((t) = XftIntMult(XftGet8(y,i),XftGet8(a,i),(t))( ((t)) = (((CARD16) (CARD8) ((y) >> i))) * (((CARD16) ( CARD8) ((a) >> i))) + 0x80, ( ( ( ((t))>>8 ) + (( t)) )>>8 ) ) + XftGet8(x,i)((CARD16) (CARD8) ((x) >> i)),\ | |||
410 | (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i)) | |||
411 | ||||
412 | #define XftInU(x,i,a,t)((CARD32) ( ((t)) = (((CARD16) (CARD8) ((x) >> i))) * ( (a)) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) << (i)) ((CARD32) XftIntMult(XftGet8(x,i),(a),(t))( ((t)) = (((CARD16) (CARD8) ((x) >> i))) * ((a)) + 0x80 , ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) << (i)) | |||
413 | ||||
414 | #define XftInC(x,i,a,t)((CARD32) ( ((t)) = (((CARD16) (CARD8) ((x) >> i))) * ( ((CARD16) (CARD8) ((a) >> i))) + 0x80, ( ( ( ((t))>> 8 ) + ((t)) )>>8 ) ) << (i)) ((CARD32) XftIntMult(XftGet8(x,i),XftGet8(a,i),(t))( ((t)) = (((CARD16) (CARD8) ((x) >> i))) * (((CARD16) ( CARD8) ((a) >> i))) + 0x80, ( ( ( ((t))>>8 ) + (( t)) )>>8 ) ) << (i)) | |||
415 | ||||
416 | #define XftGen(x,y,i,ax,ay,t,u,v)((t) = (( ((u)) = (((CARD16) (CARD8) ((y) >> i))) * (ay ) + 0x80, ( ( ( ((u))>>8 ) + ((u)) )>>8 ) ) + ( ( (v)) = (((CARD16) (CARD8) ((x) >> i))) * (ax) + 0x80, ( ( ( ((v))>>8 ) + ((v)) )>>8 ) )), (CARD32) ((CARD8 ) ((t) | (0 - ((t) >> 8)))) << (i)) ((t) = (XftIntMult(XftGet8(y,i),ay,(u))( ((u)) = (((CARD16) (CARD8) ((y) >> i))) * (ay) + 0x80 , ( ( ( ((u))>>8 ) + ((u)) )>>8 ) ) + \ | |||
417 | XftIntMult(XftGet8(x,i),ax,(v))( ((v)) = (((CARD16) (CARD8) ((x) >> i))) * (ax) + 0x80 , ( ( ( ((v))>>8 ) + ((v)) )>>8 ) )),\ | |||
418 | (CARD32) ((CARD8) ((t) | \ | |||
419 | (0 - ((t) >> 8)))) << (i)) | |||
420 | ||||
421 | #define XftAdd(x,y,i,t)((t) = ((CARD16) (CARD8) ((x) >> i)) + ((CARD16) (CARD8 ) ((y) >> i)), (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i)) ((t) = XftGet8(x,i)((CARD16) (CARD8) ((x) >> i)) + XftGet8(y,i)((CARD16) (CARD8) ((y) >> i)), \ | |||
422 | (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i)) | |||
423 | ||||
424 | ||||
425 | static CARD32 | |||
426 | fbOver24 (CARD32 x, CARD32 y) | |||
427 | { | |||
428 | CARD16 a = ~x >> 24; | |||
429 | CARD16 t; | |||
430 | CARD32 m,n,o; | |||
431 | ||||
432 | m = XftOverU(x,y,0,a,t)((t) = ( ((t)) = (((CARD16) (CARD8) ((y) >> 0))) * ((a) ) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) + ((CARD16 ) (CARD8) ((x) >> 0)), (CARD32) ((CARD8) ((t) | (0 - (( t) >> 8)))) << (0)); | |||
433 | n = XftOverU(x,y,8,a,t)((t) = ( ((t)) = (((CARD16) (CARD8) ((y) >> 8))) * ((a) ) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) + ((CARD16 ) (CARD8) ((x) >> 8)), (CARD32) ((CARD8) ((t) | (0 - (( t) >> 8)))) << (8)); | |||
434 | o = XftOverU(x,y,16,a,t)((t) = ( ((t)) = (((CARD16) (CARD8) ((y) >> 16))) * ((a )) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) + (( CARD16) (CARD8) ((x) >> 16)), (CARD32) ((CARD8) ((t) | ( 0 - ((t) >> 8)))) << (16)); | |||
435 | return m|n|o; | |||
436 | } | |||
437 | ||||
438 | static CARD32 | |||
439 | fbIn (CARD32 x, CARD8 y) | |||
440 | { | |||
441 | CARD16 a = y; | |||
442 | CARD16 t; | |||
443 | CARD32 m,n,o,p; | |||
444 | ||||
445 | m = XftInU(x,0,a,t)((CARD32) ( ((t)) = (((CARD16) (CARD8) ((x) >> 0))) * ( (a)) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) << (0)); | |||
446 | n = XftInU(x,8,a,t)((CARD32) ( ((t)) = (((CARD16) (CARD8) ((x) >> 8))) * ( (a)) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) << (8)); | |||
447 | o = XftInU(x,16,a,t)((CARD32) ( ((t)) = (((CARD16) (CARD8) ((x) >> 16))) * ( (a)) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) << (16)); | |||
448 | p = XftInU(x,24,a,t)((CARD32) ( ((t)) = (((CARD16) (CARD8) ((x) >> 24))) * ( (a)) + 0x80, ( ( ( ((t))>>8 ) + ((t)) )>>8 ) ) << (24)); | |||
449 | return m|n|o|p; | |||
450 | } | |||
451 | ||||
452 | static void | |||
453 | _XftSmoothGlyphGray8888 (XImage *image, | |||
454 | _Xconstconst XftGlyph *xftg, | |||
455 | int x, | |||
456 | int y, | |||
457 | _Xconstconst XftColor *color) | |||
458 | { | |||
459 | CARD32 src, srca; | |||
460 | CARD32 r, g, b; | |||
461 | CARD32 *dstLine, *dst, d; | |||
462 | CARD8 *maskLine, *mask, m; | |||
463 | int dstStride, maskStride; | |||
464 | int width, height; | |||
465 | int w; | |||
466 | ||||
467 | srca = color->color.alpha >> 8; | |||
468 | ||||
469 | /* This handles only RGB and BGR */ | |||
470 | g = (color->color.green & 0xff00); | |||
471 | if (image->red_mask == 0xff0000) | |||
472 | { | |||
473 | r = (color->color.red & 0xff00) << 8; | |||
474 | b = color->color.blue >> 8; | |||
475 | } | |||
476 | else | |||
477 | { | |||
478 | r = color->color.red >> 8; | |||
479 | b = (color->color.blue & 0xff00) << 8; | |||
480 | } | |||
481 | src = (srca << 24) | r | g | b; | |||
482 | ||||
483 | width = xftg->metrics.width; | |||
484 | height = xftg->metrics.height; | |||
485 | ||||
486 | x -= xftg->metrics.x; | |||
487 | y -= xftg->metrics.y; | |||
488 | ||||
489 | dstLine = (CARD32 *) (image->data + image->bytes_per_line * y + (x << 2)); | |||
490 | dstStride = image->bytes_per_line >> 2; | |||
491 | maskLine = (unsigned char *) xftg->bitmap; | |||
492 | maskStride = (width + 3) & ~3; | |||
493 | ||||
494 | while (height--) | |||
495 | { | |||
496 | dst = dstLine; | |||
497 | dstLine += dstStride; | |||
498 | mask = maskLine; | |||
499 | maskLine += maskStride; | |||
500 | w = width; | |||
501 | ||||
502 | while (w--) | |||
503 | { | |||
504 | m = *mask++; | |||
505 | if (m == 0xff) | |||
506 | { | |||
507 | if (srca == 0xff) | |||
508 | *dst = src; | |||
509 | else | |||
510 | *dst = fbOver24 (src, *dst); | |||
511 | } | |||
512 | else if (m) | |||
513 | { | |||
514 | d = fbIn (src, m); | |||
515 | *dst = fbOver24 (d, *dst); | |||
516 | } | |||
517 | dst++; | |||
518 | } | |||
519 | } | |||
520 | } | |||
521 | ||||
522 | static void | |||
523 | _XftSmoothGlyphGray565 (XImage *image, | |||
524 | _Xconstconst XftGlyph *xftg, | |||
525 | int x, | |||
526 | int y, | |||
527 | _Xconstconst XftColor *color) | |||
528 | { | |||
529 | CARD32 src, srca; | |||
530 | CARD32 r, g, b; | |||
531 | CARD32 d; | |||
532 | CARD16 *dstLine, *dst; | |||
533 | CARD8 *maskLine, *mask, m; | |||
534 | int dstStride, maskStride; | |||
535 | int width, height; | |||
536 | int w; | |||
537 | ||||
538 | srca = color->color.alpha >> 8; | |||
539 | ||||
540 | /* This handles only RGB and BGR */ | |||
541 | g = (color->color.green & 0xff00); | |||
542 | if (image->red_mask == 0xf800) | |||
543 | { | |||
544 | r = (color->color.red & 0xff00) << 8; | |||
545 | b = color->color.blue >> 8; | |||
546 | } | |||
547 | else | |||
548 | { | |||
549 | r = color->color.red >> 8; | |||
550 | b = (color->color.blue & 0xff00) << 8; | |||
551 | } | |||
552 | src = (srca << 24) | r | g | b; | |||
553 | ||||
554 | width = xftg->metrics.width; | |||
555 | height = xftg->metrics.height; | |||
556 | ||||
557 | x -= xftg->metrics.x; | |||
558 | y -= xftg->metrics.y; | |||
559 | ||||
560 | dstLine = (CARD16 *) (image->data + image->bytes_per_line * y + (x << 1)); | |||
561 | dstStride = image->bytes_per_line >> 1; | |||
562 | maskLine = (unsigned char *) xftg->bitmap; | |||
563 | maskStride = (width + 3) & ~3; | |||
564 | ||||
565 | while (height--) | |||
566 | { | |||
567 | dst = dstLine; | |||
568 | dstLine += dstStride; | |||
569 | mask = maskLine; | |||
570 | maskLine += maskStride; | |||
571 | w = width; | |||
572 | ||||
573 | while (w--) | |||
574 | { | |||
575 | m = *mask++; | |||
576 | if (m == 0xff) | |||
577 | { | |||
578 | if (srca == 0xff) | |||
579 | d = src; | |||
580 | else | |||
581 | { | |||
582 | d = *dst; | |||
583 | d = fbOver24 (src, cvt0565to8888(d)(((((d) << 3) & 0xf8) | (((d) >> 2) & 0x7 )) | ((((d) << 5) & 0xfc00) | (((d) >> 1) & 0x300)) | ((((d) << 8) & 0xf80000) | (((d) << 3) & 0x70000)))); | |||
584 | } | |||
585 | *dst = cvt8888to0565(d)((((d) >> 3) & 0x001f) | (((d) >> 5) & 0x07e0 ) | (((d) >> 8) & 0xf800)); | |||
586 | } | |||
587 | else if (m) | |||
588 | { | |||
589 | d = *dst; | |||
590 | d = fbOver24 (fbIn(src,m), cvt0565to8888(d)(((((d) << 3) & 0xf8) | (((d) >> 2) & 0x7 )) | ((((d) << 5) & 0xfc00) | (((d) >> 1) & 0x300)) | ((((d) << 8) & 0xf80000) | (((d) << 3) & 0x70000)))); | |||
591 | *dst = cvt8888to0565(d)((((d) >> 3) & 0x001f) | (((d) >> 5) & 0x07e0 ) | (((d) >> 8) & 0xf800)); | |||
592 | } | |||
593 | dst++; | |||
594 | } | |||
595 | } | |||
596 | } | |||
597 | ||||
598 | static void | |||
599 | _XftSmoothGlyphGray555 (XImage *image, | |||
600 | _Xconstconst XftGlyph *xftg, | |||
601 | int x, | |||
602 | int y, | |||
603 | _Xconstconst XftColor *color) | |||
604 | { | |||
605 | CARD32 src, srca; | |||
606 | CARD32 r, g, b; | |||
607 | CARD32 d; | |||
608 | CARD16 *dstLine, *dst; | |||
609 | CARD8 *maskLine, *mask, m; | |||
610 | int dstStride, maskStride; | |||
611 | int width, height; | |||
612 | int w; | |||
613 | ||||
614 | srca = color->color.alpha >> 8; | |||
615 | ||||
616 | /* This handles only RGB and BGR */ | |||
617 | g = (color->color.green & 0xff00); | |||
618 | if (image->red_mask == 0xf800) | |||
619 | { | |||
620 | r = (color->color.red & 0xff00) << 8; | |||
621 | b = color->color.blue >> 8; | |||
622 | } | |||
623 | else | |||
624 | { | |||
625 | r = color->color.red >> 8; | |||
626 | b = (color->color.blue & 0xff00) << 8; | |||
627 | } | |||
628 | src = (srca << 24) | r | g | b; | |||
629 | ||||
630 | width = xftg->metrics.width; | |||
631 | height = xftg->metrics.height; | |||
632 | ||||
633 | x -= xftg->metrics.x; | |||
634 | y -= xftg->metrics.y; | |||
635 | ||||
636 | dstLine = (CARD16 *) (image->data + image->bytes_per_line * y + (x << 1)); | |||
637 | dstStride = image->bytes_per_line >> 1; | |||
638 | maskLine = (unsigned char *) xftg->bitmap; | |||
639 | maskStride = (width + 3) & ~3; | |||
640 | ||||
641 | while (height--) | |||
642 | { | |||
643 | dst = dstLine; | |||
644 | dstLine += dstStride; | |||
645 | mask = maskLine; | |||
646 | maskLine += maskStride; | |||
647 | w = width; | |||
648 | ||||
649 | while (w--) | |||
650 | { | |||
651 | m = *mask++; | |||
652 | if (m == 0xff) | |||
653 | { | |||
654 | if (srca == 0xff) | |||
655 | d = src; | |||
656 | else | |||
657 | { | |||
658 | d = *dst; | |||
659 | d = fbOver24 (src, cvt0555to8888(d)(((((d) << 3) & 0xf8) | (((d) >> 2) & 0x7 )) | ((((d) << 6) & 0xf800) | (((d) >> 0) & 0x300)) | ((((d) << 9) & 0xf80000) | (((d) << 4) & 0x70000)))); | |||
660 | } | |||
661 | *dst = cvt8888to0555(d)((((d) >> 3) & 0x001f) | (((d) >> 6) & 0x03e0 ) | (((d) >> 7) & 0x7c00)); | |||
662 | } | |||
663 | else if (m) | |||
664 | { | |||
665 | d = *dst; | |||
666 | d = fbOver24 (fbIn(src,m), cvt0555to8888(d)(((((d) << 3) & 0xf8) | (((d) >> 2) & 0x7 )) | ((((d) << 6) & 0xf800) | (((d) >> 0) & 0x300)) | ((((d) << 9) & 0xf80000) | (((d) << 4) & 0x70000)))); | |||
667 | *dst = cvt8888to0555(d)((((d) >> 3) & 0x001f) | (((d) >> 6) & 0x03e0 ) | (((d) >> 7) & 0x7c00)); | |||
668 | } | |||
669 | dst++; | |||
670 | } | |||
671 | } | |||
672 | } | |||
673 | ||||
674 | static void | |||
675 | _XftSmoothGlyphGray (XImage *image, | |||
676 | _Xconstconst XftGlyph *xftg, | |||
677 | int x, | |||
678 | int y, | |||
679 | _Xconstconst XftColor *color) | |||
680 | { | |||
681 | CARD32 src, srca; | |||
682 | int r_shift, r_len; | |||
683 | int g_shift, g_len; | |||
684 | int b_shift, b_len; | |||
685 | CARD8 *maskLine, *mask, m; | |||
686 | int maskStride; | |||
687 | CARD32 d; | |||
688 | unsigned long pixel; | |||
689 | int width, height; | |||
690 | int w, tx; | |||
691 | ||||
692 | srca = color->color.alpha >> 8; | |||
693 | src = (srca << 24 | | |||
694 | (color->color.red & 0xff00) << 8 | | |||
695 | (color->color.green & 0xff00) | | |||
696 | (color->color.blue) >> 8); | |||
697 | x -= xftg->metrics.x; | |||
698 | y -= xftg->metrics.y; | |||
699 | width = xftg->metrics.width; | |||
700 | height = xftg->metrics.height; | |||
701 | ||||
702 | maskLine = (unsigned char *) xftg->bitmap; | |||
703 | maskStride = (width + 3) & ~3; | |||
704 | ||||
705 | _XftExamineBitfield (image->red_mask, &r_shift, &r_len); | |||
706 | _XftExamineBitfield (image->green_mask, &g_shift, &g_len); | |||
707 | _XftExamineBitfield (image->blue_mask, &b_shift, &b_len); | |||
708 | while (height--) | |||
709 | { | |||
710 | mask = maskLine; | |||
711 | maskLine += maskStride; | |||
712 | w = width; | |||
713 | tx = x; | |||
714 | ||||
715 | while (w--) | |||
716 | { | |||
717 | m = *mask++; | |||
718 | if (m == 0xff) | |||
719 | { | |||
720 | if (srca == 0xff) | |||
721 | d = src; | |||
722 | else | |||
723 | { | |||
724 | pixel = XGetPixel (image, tx, y)((*((image)->f.get_pixel))((image), (tx), (y))); | |||
725 | d = (_XftGetField (pixel, r_shift, r_len) << 16 | | |||
726 | _XftGetField (pixel, g_shift, g_len) << 8 | | |||
727 | _XftGetField (pixel, b_shift, b_len)); | |||
728 | d = fbOver24 (src, d); | |||
729 | } | |||
730 | pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) | | |||
731 | _XftPutField ((d >> 8) & 0xff, g_shift, g_len) | | |||
732 | _XftPutField ((d ) & 0xff, b_shift, b_len)); | |||
733 | XPutPixel (image, tx, y, pixel)((*((image)->f.put_pixel))((image), (tx), (y), (pixel))); | |||
734 | } | |||
735 | else if (m) | |||
736 | { | |||
737 | pixel = XGetPixel (image, tx, y)((*((image)->f.get_pixel))((image), (tx), (y))); | |||
738 | d = (_XftGetField (pixel, r_shift, r_len) << 16 | | |||
739 | _XftGetField (pixel, g_shift, g_len) << 8 | | |||
740 | _XftGetField (pixel, b_shift, b_len)); | |||
741 | d = fbOver24 (fbIn(src,m), d); | |||
742 | pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) | | |||
743 | _XftPutField ((d >> 8) & 0xff, g_shift, g_len) | | |||
744 | _XftPutField ((d ) & 0xff, b_shift, b_len)); | |||
745 | XPutPixel (image, tx, y, pixel)((*((image)->f.put_pixel))((image), (tx), (y), (pixel))); | |||
746 | } | |||
747 | tx++; | |||
748 | } | |||
749 | y++; | |||
750 | } | |||
751 | } | |||
752 | ||||
753 | static void | |||
754 | _XftSmoothGlyphRgba (XImage *image, | |||
755 | _Xconstconst XftGlyph *xftg, | |||
756 | int x, | |||
757 | int y, | |||
758 | _Xconstconst XftColor *color) | |||
759 | { | |||
760 | CARD32 src, srca; | |||
761 | int r_shift, r_len; | |||
762 | int g_shift, g_len; | |||
763 | int b_shift, b_len; | |||
764 | CARD32 *mask, ma; | |||
765 | CARD32 d; | |||
766 | unsigned long pixel; | |||
767 | int width, height; | |||
768 | int w, tx; | |||
769 | ||||
770 | srca = color->color.alpha >> 8; | |||
771 | src = (srca << 24 | | |||
772 | (color->color.red & 0xff00) << 8 | | |||
773 | (color->color.green & 0xff00) | | |||
774 | (color->color.blue) >> 8); | |||
775 | x -= xftg->metrics.x; | |||
776 | y -= xftg->metrics.y; | |||
777 | width = xftg->metrics.width; | |||
778 | height = xftg->metrics.height; | |||
779 | ||||
780 | mask = (CARD32 *) xftg->bitmap; | |||
781 | ||||
782 | _XftExamineBitfield (image->red_mask, &r_shift, &r_len); | |||
783 | _XftExamineBitfield (image->green_mask, &g_shift, &g_len); | |||
784 | _XftExamineBitfield (image->blue_mask, &b_shift, &b_len); | |||
785 | while (height--) | |||
| ||||
786 | { | |||
787 | w = width; | |||
788 | tx = x; | |||
789 | ||||
790 | while (w--) | |||
791 | { | |||
792 | ma = *mask++; | |||
793 | if (ma == 0xffffffff) | |||
794 | { | |||
795 | if (srca == 0xff) | |||
796 | d = src; | |||
797 | else | |||
798 | { | |||
799 | pixel = XGetPixel (image, tx, y)((*((image)->f.get_pixel))((image), (tx), (y))); | |||
800 | d = (_XftGetField (pixel, r_shift, r_len) << 16 | | |||
801 | _XftGetField (pixel, g_shift, g_len) << 8 | | |||
802 | _XftGetField (pixel, b_shift, b_len)); | |||
803 | d = fbOver24 (src, d); | |||
804 | } | |||
805 | pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) | | |||
806 | _XftPutField ((d >> 8) & 0xff, g_shift, g_len) | | |||
807 | _XftPutField ((d ) & 0xff, b_shift, b_len)); | |||
808 | XPutPixel (image, tx, y, pixel)((*((image)->f.put_pixel))((image), (tx), (y), (pixel))); | |||
809 | } | |||
810 | else if (ma) | |||
811 | { | |||
812 | CARD32 m,n,o; | |||
813 | pixel = XGetPixel (image, tx, y)((*((image)->f.get_pixel))((image), (tx), (y))); | |||
814 | d = (_XftGetField (pixel, r_shift, r_len) << 16 | | |||
815 | _XftGetField (pixel, g_shift, g_len) << 8 | | |||
816 | _XftGetField (pixel, b_shift, b_len)); | |||
817 | #define XftInOverC(src,srca,msk,dst,i,result){ CARD16 __a = ((CARD16) (CARD8) ((msk) >> i)); CARD32 __t , __ta; CARD32 __i; __t = ( (__i) = (((CARD16) (CARD8) ((src) >> i))) * (__a) + 0x80, ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __ta = (CARD8) ~( (__i) = (srca) * (__a) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = __t + ( (__i) = (((CARD16) (CARD8) ((dst) >> i))) * (__ta) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = (CARD32 ) (CARD8) (__t | (-(__t >> 8))); result = __t << ( i); } { \ | |||
818 | CARD16 __a = XftGet8(msk,i)((CARD16) (CARD8) ((msk) >> i)); \ | |||
819 | CARD32 __t, __ta; \ | |||
820 | CARD32 __i; \ | |||
821 | __t = XftIntMult (XftGet8(src,i), __a,__i)( (__i) = (((CARD16) (CARD8) ((src) >> i))) * (__a) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); \ | |||
822 | __ta = (CARD8) ~XftIntMult (srca, __a,__i)( (__i) = (srca) * (__a) + 0x80, ( ( ( (__i)>>8 ) + (__i ) )>>8 ) ); \ | |||
823 | __t = __t + XftIntMult(XftGet8(dst,i),__ta,__i)( (__i) = (((CARD16) (CARD8) ((dst) >> i))) * (__ta) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); \ | |||
824 | __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \ | |||
825 | result = __t << (i); \ | |||
826 | } | |||
827 | XftInOverC(src,srca,ma,d,0,m){ CARD16 __a = ((CARD16) (CARD8) ((ma) >> 0)); CARD32 __t , __ta; CARD32 __i; __t = ( (__i) = (((CARD16) (CARD8) ((src) >> 0))) * (__a) + 0x80, ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __ta = (CARD8) ~( (__i) = (srca) * (__a) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = __t + ( (__i) = (((CARD16) (CARD8) ((d) >> 0))) * (__ta) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = (CARD32 ) (CARD8) (__t | (-(__t >> 8))); m = __t << (0); }; | |||
828 | XftInOverC(src,srca,ma,d,8,n){ CARD16 __a = ((CARD16) (CARD8) ((ma) >> 8)); CARD32 __t , __ta; CARD32 __i; __t = ( (__i) = (((CARD16) (CARD8) ((src) >> 8))) * (__a) + 0x80, ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __ta = (CARD8) ~( (__i) = (srca) * (__a) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = __t + ( (__i) = (((CARD16) (CARD8) ((d) >> 8))) * (__ta) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = (CARD32 ) (CARD8) (__t | (-(__t >> 8))); n = __t << (8); }; | |||
829 | XftInOverC(src,srca,ma,d,16,o){ CARD16 __a = ((CARD16) (CARD8) ((ma) >> 16)); CARD32 __t , __ta; CARD32 __i; __t = ( (__i) = (((CARD16) (CARD8) ((src) >> 16))) * (__a) + 0x80, ( ( ( (__i)>>8 ) + (__i ) )>>8 ) ); __ta = (CARD8) ~( (__i) = (srca) * (__a) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = __t + ( (__i) = (((CARD16) (CARD8) ((d) >> 16))) * (__ta) + 0x80 , ( ( ( (__i)>>8 ) + (__i) )>>8 ) ); __t = (CARD32 ) (CARD8) (__t | (-(__t >> 8))); o = __t << (16); }; | |||
830 | d = m | n | o; | |||
831 | pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) | | |||
832 | _XftPutField ((d >> 8) & 0xff, g_shift, g_len) | | |||
833 | _XftPutField ((d ) & 0xff, b_shift, b_len)); | |||
834 | XPutPixel (image, tx, y, pixel)((*((image)->f.put_pixel))((image), (tx), (y), (pixel))); | |||
835 | } | |||
836 | tx++; | |||
837 | } | |||
838 | y++; | |||
839 | } | |||
840 | } | |||
841 | ||||
842 | static FcBool | |||
843 | _XftSmoothGlyphPossible (XftDraw *draw) | |||
844 | { | |||
845 | if (!draw->visual) | |||
846 | return FcFalse0; | |||
847 | if (draw->visual->class != TrueColor4) | |||
848 | return FcFalse0; | |||
849 | return FcTrue1; | |||
850 | } | |||
851 | ||||
852 | typedef void (*XftSmoothGlyph) (XImage *image, | |||
853 | _Xconstconst XftGlyph *xftg, | |||
854 | int x, | |||
855 | int y, | |||
856 | _Xconstconst XftColor *color); | |||
857 | ||||
858 | static XftSmoothGlyph | |||
859 | _XftSmoothGlyphFind (XftDraw *draw, XftFont *public) | |||
860 | { | |||
861 | XftFontInt *font = (XftFontInt *) public; | |||
862 | ||||
863 | if (!font->info.antialias) | |||
864 | return _XftSmoothGlyphMono; | |||
865 | else switch (font->info.rgba) { | |||
866 | case FC_RGBA_RGB1: | |||
867 | case FC_RGBA_BGR2: | |||
868 | case FC_RGBA_VRGB3: | |||
869 | case FC_RGBA_VBGR4: | |||
870 | return _XftSmoothGlyphRgba; | |||
871 | default: | |||
872 | switch (XftDrawBitsPerPixel (draw)) { | |||
873 | case 32: | |||
874 | if ((draw->visual->red_mask == 0xff0000 && | |||
875 | draw->visual->green_mask == 0x00ff00 && | |||
876 | draw->visual->blue_mask == 0x0000ff) || | |||
877 | (draw->visual->red_mask == 0x0000ff && | |||
878 | draw->visual->green_mask == 0x00ff00 && | |||
879 | draw->visual->blue_mask == 0xff0000)) | |||
880 | { | |||
881 | return _XftSmoothGlyphGray8888; | |||
882 | } | |||
883 | break; | |||
884 | case 16: | |||
885 | if ((draw->visual->red_mask == 0xf800 && | |||
886 | draw->visual->green_mask == 0x07e0 && | |||
887 | draw->visual->blue_mask == 0x001f) || | |||
888 | (draw->visual->red_mask == 0x001f && | |||
889 | draw->visual->green_mask == 0x07e0 && | |||
890 | draw->visual->blue_mask == 0xf800)) | |||
891 | { | |||
892 | return _XftSmoothGlyphGray565; | |||
893 | } | |||
894 | if ((draw->visual->red_mask == 0x7c00 && | |||
895 | draw->visual->green_mask == 0x03e0 && | |||
896 | draw->visual->blue_mask == 0x001f) || | |||
897 | (draw->visual->red_mask == 0x001f && | |||
898 | draw->visual->green_mask == 0x03e0 && | |||
899 | draw->visual->blue_mask == 0x7c00)) | |||
900 | { | |||
901 | return _XftSmoothGlyphGray555; | |||
902 | } | |||
903 | break; | |||
904 | default: | |||
905 | break; | |||
906 | } | |||
907 | return _XftSmoothGlyphGray; | |||
908 | } | |||
909 | } | |||
910 | ||||
911 | static XftGlyph * | |||
912 | _XftGlyphDefault (Display *dpy, XftFont *public) | |||
913 | { | |||
914 | XftFontInt *font = (XftFontInt *) public; | |||
915 | FT_UInt missing[XFT_NMISSING256]; | |||
916 | int nmissing; | |||
917 | FcBool glyphs_loaded = FcFalse0; | |||
918 | ||||
919 | if (XftFontCheckGlyph (dpy, public, FcTrue1, 0, missing, &nmissing)) | |||
920 | glyphs_loaded = FcTrue1; | |||
921 | if (nmissing) | |||
922 | XftFontLoadGlyphs (dpy, public, glyphs_loaded, missing, nmissing); | |||
923 | return font->glyphs[0]; | |||
924 | } | |||
925 | ||||
926 | static int XftGetImageErrorHandler (Display *dpy, XErrorEvent *error_event) | |||
927 | { | |||
928 | return 0; | |||
929 | } | |||
930 | ||||
931 | _X_HIDDEN__attribute__((visibility("hidden"))) void | |||
932 | XftGlyphCore (XftDraw *draw, | |||
933 | _Xconstconst XftColor *color, | |||
934 | XftFont *public, | |||
935 | int x, | |||
936 | int y, | |||
937 | _Xconstconst FT_UInt *glyphs, | |||
938 | int nglyphs) | |||
939 | { | |||
940 | Display *dpy = draw->dpy; | |||
941 | XftFontInt *font = (XftFontInt *) public; | |||
942 | XftGlyph *xftg; | |||
943 | FT_UInt glyph; | |||
944 | _Xconstconst FT_UInt *g; | |||
945 | FT_UInt missing[XFT_NMISSING256]; | |||
946 | FcBool glyphs_loaded; | |||
947 | int nmissing; | |||
948 | int n; | |||
949 | XErrorHandler prev_error; | |||
950 | ||||
951 | /* | |||
952 | * Load missing glyphs | |||
953 | */ | |||
954 | g = glyphs; | |||
955 | n = nglyphs; | |||
956 | nmissing = 0; | |||
957 | glyphs_loaded = FcFalse0; | |||
958 | while (n--) | |||
959 | if (XftFontCheckGlyph (dpy, public, FcTrue1, *g++, missing, &nmissing)) | |||
960 | glyphs_loaded = FcTrue1; | |||
961 | if (nmissing) | |||
962 | XftFontLoadGlyphs (dpy, public, FcTrue1, missing, nmissing); | |||
963 | ||||
964 | g = glyphs; | |||
965 | n = nglyphs; | |||
966 | if ((font->info.antialias || color->color.alpha != 0xffff) && | |||
967 | _XftSmoothGlyphPossible (draw)) | |||
968 | { | |||
969 | XGlyphInfo gi; | |||
970 | XImage *image; | |||
971 | unsigned int depth; | |||
972 | int ox, oy; | |||
973 | XftSmoothGlyph smooth = _XftSmoothGlyphFind (draw, public); | |||
974 | ||||
975 | XftGlyphExtents (dpy, public, glyphs, nglyphs, &gi); | |||
976 | if (!gi.width || !gi.height) | |||
977 | goto bail1; | |||
978 | ox = x - gi.x; | |||
979 | oy = y - gi.y; | |||
980 | /* | |||
981 | * Try to get bits directly from the drawable; if that fails, | |||
982 | * use a temporary pixmap. When it does fail, assume it | |||
983 | * will probably fail for a while and keep using temporary | |||
984 | * pixmaps for a while to avoid double round trips. | |||
985 | */ | |||
986 | if (draw->core.use_pixmap == 0) | |||
987 | { | |||
988 | prev_error = XSetErrorHandler (XftGetImageErrorHandler); | |||
989 | image = XGetImage (dpy, draw->drawable, | |||
990 | ox, oy, | |||
991 | gi.width, gi.height, AllPlanes((unsigned long)~0L), | |||
992 | ZPixmap2); | |||
993 | XSetErrorHandler (prev_error); | |||
994 | if (!image) | |||
995 | draw->core.use_pixmap = XFT_ASSUME_PIXMAP20; | |||
996 | } | |||
997 | else | |||
998 | { | |||
999 | draw->core.use_pixmap--; | |||
1000 | image = NULL((void*)0); | |||
1001 | } | |||
1002 | if (!image && (depth = XftDrawDepth (draw))) | |||
1003 | { | |||
1004 | Pixmap pix; | |||
1005 | GC gc; | |||
1006 | XGCValues gcv; | |||
1007 | ||||
1008 | pix = XCreatePixmap (dpy, draw->drawable, | |||
1009 | gi.width, gi.height, depth); | |||
1010 | gcv.graphics_exposures = False0; | |||
1011 | gc = XCreateGC (dpy, pix, GCGraphicsExposures(1L<<16), &gcv); | |||
1012 | XCopyArea (dpy, draw->drawable, pix, gc, ox, oy, | |||
1013 | gi.width, gi.height, 0, 0); | |||
1014 | XFreeGC (dpy, gc); | |||
1015 | image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes((unsigned long)~0L), | |||
1016 | ZPixmap2); | |||
1017 | XFreePixmap (dpy, pix); | |||
1018 | } | |||
1019 | if (!image) | |||
1020 | goto bail1; | |||
1021 | image->red_mask = draw->visual->red_mask; | |||
1022 | image->green_mask = draw->visual->green_mask; | |||
1023 | image->blue_mask = draw->visual->blue_mask; | |||
1024 | if (image->byte_order != XftNativeByteOrder ()) | |||
1025 | XftSwapImage (image); | |||
1026 | while (n--) | |||
1027 | { | |||
1028 | glyph = *g++; | |||
1029 | if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph])) | |||
1030 | xftg = _XftGlyphDefault (dpy, public); | |||
1031 | if (xftg) | |||
1032 | { | |||
1033 | (*smooth) (image, xftg, x - ox, y - oy, color); | |||
1034 | x += xftg->metrics.xOff; | |||
1035 | y += xftg->metrics.yOff; | |||
1036 | } | |||
1037 | } | |||
1038 | if (image->byte_order != XftNativeByteOrder ()) | |||
1039 | XftSwapImage (image); | |||
1040 | XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, ox, oy, | |||
1041 | gi.width, gi.height); | |||
1042 | XDestroyImage (image)((*((image)->f.destroy_image))((image))); | |||
1043 | } | |||
1044 | else | |||
1045 | { | |||
1046 | XftSharpGlyph sharp = _XftSharpGlyphFind (draw, public); | |||
1047 | while (n--) | |||
1048 | { | |||
1049 | glyph = *g++; | |||
1050 | if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph])) | |||
1051 | xftg = _XftGlyphDefault (dpy, public); | |||
1052 | if (xftg) | |||
1053 | { | |||
1054 | (*sharp) (draw, xftg, x, y); | |||
1055 | x += xftg->metrics.xOff; | |||
1056 | y += xftg->metrics.yOff; | |||
1057 | } | |||
1058 | } | |||
1059 | } | |||
1060 | bail1: | |||
1061 | if (glyphs_loaded) | |||
1062 | _XftFontManageMemory (dpy, public); | |||
1063 | } | |||
1064 | ||||
1065 | #define NUM_LOCAL1024 1024 | |||
1066 | ||||
1067 | _X_HIDDEN__attribute__((visibility("hidden"))) void | |||
1068 | XftGlyphSpecCore (XftDraw *draw, | |||
1069 | _Xconstconst XftColor *color, | |||
1070 | XftFont *public, | |||
1071 | _Xconstconst XftGlyphSpec *glyphs, | |||
1072 | int nglyphs) | |||
1073 | { | |||
1074 | Display *dpy = draw->dpy; | |||
1075 | XftFontInt *font = (XftFontInt *) public; | |||
1076 | XftGlyph *xftg; | |||
1077 | FT_UInt missing[XFT_NMISSING256]; | |||
1078 | FcBool glyphs_loaded; | |||
1079 | int nmissing; | |||
1080 | int i; | |||
1081 | XErrorHandler prev_error; | |||
1082 | int x1, y1, x2, y2; | |||
1083 | ||||
1084 | /* | |||
1085 | * Load missing glyphs | |||
1086 | */ | |||
1087 | glyphs_loaded = FcFalse0; | |||
1088 | x1 = y1 = x2 = y2 = 0; | |||
1089 | for (i = 0; i < nglyphs; i++) | |||
1090 | { | |||
1091 | XGlyphInfo gi; | |||
1092 | int g_x1, g_x2, g_y1, g_y2; | |||
1093 | ||||
1094 | nmissing = 0; | |||
1095 | if (XftFontCheckGlyph (dpy, public, FcTrue1, glyphs[i].glyph, missing, &nmissing)) | |||
1096 | glyphs_loaded = FcTrue1; | |||
1097 | if (nmissing) | |||
1098 | XftFontLoadGlyphs (dpy, public, FcTrue1, missing, nmissing); | |||
1099 | ||||
1100 | XftGlyphExtents (dpy, public, &glyphs[i].glyph, 1, &gi); | |||
1101 | g_x1 = glyphs[i].x - gi.x; | |||
1102 | g_y1 = glyphs[i].y - gi.y; | |||
1103 | g_x2 = g_x1 + gi.width; | |||
1104 | g_y2 = g_y1 + gi.height; | |||
1105 | if (i) | |||
1106 | { | |||
1107 | if (g_x1 < x1) | |||
1108 | x1 = g_x1; | |||
1109 | if (g_y1 < y1) | |||
1110 | y1 = g_y1; | |||
1111 | if (g_x2 > x2) | |||
1112 | x2 = g_x2; | |||
1113 | if (g_y2 > y2) | |||
1114 | y2 = g_y2; | |||
1115 | } | |||
1116 | else | |||
1117 | { | |||
1118 | x1 = g_x1; | |||
1119 | y1 = g_y1; | |||
1120 | x2 = g_x2; | |||
1121 | y2 = g_y2; | |||
1122 | } | |||
1123 | } | |||
1124 | ||||
1125 | if (x1 == x2 || y1 == y2) | |||
1126 | goto bail1; | |||
1127 | ||||
1128 | if ((font->info.antialias || color->color.alpha != 0xffff) && | |||
1129 | _XftSmoothGlyphPossible (draw)) | |||
1130 | { | |||
1131 | XImage *image; | |||
1132 | unsigned int depth; | |||
1133 | int width = x2 - x1, height = y2 - y1; | |||
1134 | XftSmoothGlyph smooth = _XftSmoothGlyphFind (draw, public); | |||
1135 | ||||
1136 | /* | |||
1137 | * Try to get bits directly from the drawable; if that fails, | |||
1138 | * use a temporary pixmap. When it does fail, assume it | |||
1139 | * will probably fail for a while and keep using temporary | |||
1140 | * pixmaps for a while to avoid double round trips. | |||
1141 | */ | |||
1142 | if (draw->core.use_pixmap == 0) | |||
1143 | { | |||
1144 | prev_error = XSetErrorHandler (XftGetImageErrorHandler); | |||
1145 | image = XGetImage (dpy, draw->drawable, | |||
1146 | x1, y1, | |||
1147 | width, height, AllPlanes((unsigned long)~0L), | |||
1148 | ZPixmap2); | |||
1149 | XSetErrorHandler (prev_error); | |||
1150 | if (!image) | |||
1151 | draw->core.use_pixmap = XFT_ASSUME_PIXMAP20; | |||
1152 | } | |||
1153 | else | |||
1154 | { | |||
1155 | draw->core.use_pixmap--; | |||
1156 | image = NULL((void*)0); | |||
1157 | } | |||
1158 | if (!image && (depth = XftDrawDepth (draw))) | |||
1159 | { | |||
1160 | Pixmap pix; | |||
1161 | GC gc; | |||
1162 | XGCValues gcv; | |||
1163 | ||||
1164 | pix = XCreatePixmap (dpy, draw->drawable, | |||
1165 | width, height, depth); | |||
1166 | gcv.graphics_exposures = False0; | |||
1167 | gc = XCreateGC (dpy, pix, GCGraphicsExposures(1L<<16), &gcv); | |||
1168 | XCopyArea (dpy, draw->drawable, pix, gc, x1, y1, | |||
1169 | width, height, 0, 0); | |||
1170 | XFreeGC (dpy, gc); | |||
1171 | image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes((unsigned long)~0L), | |||
1172 | ZPixmap2); | |||
1173 | XFreePixmap (dpy, pix); | |||
1174 | } | |||
1175 | if (!image) | |||
1176 | goto bail1; | |||
1177 | image->red_mask = draw->visual->red_mask; | |||
1178 | image->green_mask = draw->visual->green_mask; | |||
1179 | image->blue_mask = draw->visual->blue_mask; | |||
1180 | if (image->byte_order != XftNativeByteOrder ()) | |||
1181 | XftSwapImage (image); | |||
1182 | for (i = 0; i < nglyphs; i++) | |||
1183 | { | |||
1184 | FT_UInt glyph = glyphs[i].glyph; | |||
1185 | if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph])) | |||
1186 | xftg = _XftGlyphDefault (dpy, public); | |||
1187 | if (xftg) | |||
1188 | { | |||
1189 | (*smooth) (image, xftg, glyphs[i].x - x1, | |||
1190 | glyphs[i].y - y1, color); | |||
1191 | } | |||
1192 | } | |||
1193 | if (image->byte_order != XftNativeByteOrder ()) | |||
1194 | XftSwapImage (image); | |||
1195 | XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1, | |||
1196 | width, height); | |||
1197 | XDestroyImage (image)((*((image)->f.destroy_image))((image))); | |||
1198 | } | |||
1199 | else | |||
1200 | { | |||
1201 | XftSharpGlyph sharp = _XftSharpGlyphFind (draw, public); | |||
1202 | for (i = 0; i < nglyphs; i++) | |||
1203 | { | |||
1204 | FT_UInt glyph = glyphs[i].glyph; | |||
1205 | if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph])) | |||
1206 | xftg = _XftGlyphDefault (dpy, public); | |||
1207 | if (xftg) | |||
1208 | (*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y); | |||
1209 | } | |||
1210 | } | |||
1211 | bail1: | |||
1212 | if (glyphs_loaded) | |||
1213 | _XftFontManageMemory (dpy, public); | |||
1214 | } | |||
1215 | ||||
1216 | _X_HIDDEN__attribute__((visibility("hidden"))) void | |||
1217 | XftGlyphFontSpecCore (XftDraw *draw, | |||
1218 | _Xconstconst XftColor *color, | |||
1219 | _Xconstconst XftGlyphFontSpec *glyphs, | |||
1220 | int nglyphs) | |||
1221 | { | |||
1222 | Display *dpy = draw->dpy; | |||
1223 | XftGlyph *xftg; | |||
1224 | FT_UInt missing[XFT_NMISSING256]; | |||
1225 | FcBool glyphs_loaded; | |||
1226 | int nmissing; | |||
1227 | int i; | |||
1228 | XErrorHandler prev_error; | |||
1229 | int x1, y1, x2, y2; | |||
1230 | ||||
1231 | /* | |||
1232 | * Load missing glyphs | |||
1233 | */ | |||
1234 | glyphs_loaded = FcFalse0; | |||
1235 | x1 = y1 = x2 = y2 = 0; | |||
1236 | for (i = 0; i < nglyphs; i++) | |||
1237 | { | |||
1238 | XftFont *public = glyphs[i].font; | |||
1239 | XGlyphInfo gi; | |||
1240 | int g_x1, g_x2, g_y1, g_y2; | |||
1241 | ||||
1242 | nmissing = 0; | |||
1243 | if (XftFontCheckGlyph (dpy, public, FcTrue1, glyphs[i].glyph, missing, &nmissing)) | |||
1244 | glyphs_loaded = FcTrue1; | |||
1245 | if (nmissing) | |||
1246 | XftFontLoadGlyphs (dpy, public, FcTrue1, missing, nmissing); | |||
1247 | ||||
1248 | XftGlyphExtents (dpy, public, &glyphs[i].glyph, 1, &gi); | |||
1249 | g_x1 = glyphs[i].x - gi.x; | |||
1250 | g_y1 = glyphs[i].y - gi.y; | |||
1251 | g_x2 = g_x1 + gi.width; | |||
1252 | g_y2 = g_y1 + gi.height; | |||
1253 | if (i) | |||
1254 | { | |||
1255 | if (g_x1 < x1) | |||
1256 | { | |||
1257 | if (g_x1 < 0) | |||
1258 | { | |||
1259 | /* do nothing if the given glyphs are out of range */ | |||
1260 | short t = glyphs[i-1].font->max_advance_width | |||
1261 | + glyphs[i-1].x; | |||
1262 | if (t < 0 && glyphs[i-1].x > 0) | |||
1263 | goto bail1; | |||
1264 | } | |||
1265 | x1 = g_x1; | |||
1266 | } | |||
1267 | if (g_y1 < y1) | |||
1268 | y1 = g_y1; | |||
1269 | if (g_x2 > x2) | |||
1270 | x2 = g_x2; | |||
1271 | if (g_y2 > y2) | |||
1272 | y2 = g_y2; | |||
1273 | } | |||
1274 | else | |||
1275 | { | |||
1276 | x1 = g_x1; | |||
1277 | y1 = g_y1; | |||
1278 | x2 = g_x2; | |||
1279 | y2 = g_y2; | |||
1280 | } | |||
1281 | } | |||
1282 | ||||
1283 | if (x1 == x2 || y1 == y2) | |||
1284 | goto bail1; | |||
1285 | ||||
1286 | for (i = 0; i < nglyphs; i++) | |||
1287 | if (((XftFontInt *) glyphs[i].font)->info.antialias) | |||
1288 | break; | |||
1289 | ||||
1290 | if ((i != nglyphs || color->color.alpha != 0xffff) && | |||
1291 | _XftSmoothGlyphPossible (draw)) | |||
1292 | { | |||
1293 | XImage *image; | |||
1294 | unsigned int depth; | |||
1295 | int width = x2 - x1, height = y2 - y1; | |||
1296 | ||||
1297 | /* | |||
1298 | * Try to get bits directly from the drawable; if that fails, | |||
1299 | * use a temporary pixmap. When it does fail, assume it | |||
1300 | * will probably fail for a while and keep using temporary | |||
1301 | * pixmaps for a while to avoid double round trips. | |||
1302 | */ | |||
1303 | if (draw->core.use_pixmap == 0) | |||
1304 | { | |||
1305 | prev_error = XSetErrorHandler (XftGetImageErrorHandler); | |||
1306 | image = XGetImage (dpy, draw->drawable, | |||
1307 | x1, y1, | |||
1308 | width, height, AllPlanes((unsigned long)~0L), | |||
1309 | ZPixmap2); | |||
1310 | XSetErrorHandler (prev_error); | |||
1311 | if (!image) | |||
1312 | draw->core.use_pixmap = XFT_ASSUME_PIXMAP20; | |||
1313 | } | |||
1314 | else | |||
1315 | { | |||
1316 | draw->core.use_pixmap--; | |||
1317 | image = NULL((void*)0); | |||
1318 | } | |||
1319 | if (!image && (depth = XftDrawDepth (draw))) | |||
1320 | { | |||
1321 | Pixmap pix; | |||
1322 | GC gc; | |||
1323 | XGCValues gcv; | |||
1324 | ||||
1325 | pix = XCreatePixmap (dpy, draw->drawable, | |||
1326 | width, height, depth); | |||
1327 | gcv.graphics_exposures = False0; | |||
1328 | gc = XCreateGC (dpy, pix, GCGraphicsExposures(1L<<16), &gcv); | |||
1329 | XCopyArea (dpy, draw->drawable, pix, gc, x1, y1, | |||
1330 | width, height, 0, 0); | |||
1331 | XFreeGC (dpy, gc); | |||
1332 | image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes((unsigned long)~0L), | |||
1333 | ZPixmap2); | |||
1334 | XFreePixmap (dpy, pix); | |||
1335 | } | |||
1336 | if (!image) | |||
1337 | goto bail1; | |||
1338 | image->red_mask = draw->visual->red_mask; | |||
1339 | image->green_mask = draw->visual->green_mask; | |||
1340 | image->blue_mask = draw->visual->blue_mask; | |||
1341 | if (image->byte_order != XftNativeByteOrder ()) | |||
1342 | XftSwapImage (image); | |||
1343 | for (i = 0; i < nglyphs; i++) | |||
1344 | { | |||
1345 | XftFont *public = glyphs[i].font; | |||
1346 | XftFontInt *font = (XftFontInt *) public; | |||
1347 | XftSmoothGlyph smooth = _XftSmoothGlyphFind (draw, public); | |||
1348 | FT_UInt glyph = glyphs[i].glyph; | |||
1349 | ||||
1350 | if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph])) | |||
1351 | xftg = _XftGlyphDefault (dpy, public); | |||
1352 | if (xftg) | |||
1353 | { | |||
1354 | (*smooth) (image, xftg, glyphs[i].x - x1, | |||
1355 | glyphs[i].y - y1, color); | |||
1356 | } | |||
1357 | } | |||
1358 | if (image->byte_order != XftNativeByteOrder ()) | |||
1359 | XftSwapImage (image); | |||
1360 | XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1, | |||
1361 | width, height); | |||
1362 | XDestroyImage (image)((*((image)->f.destroy_image))((image))); | |||
1363 | } | |||
1364 | else | |||
1365 | { | |||
1366 | for (i = 0; i < nglyphs; i++) | |||
1367 | { | |||
1368 | XftFont *public = glyphs[i].font; | |||
1369 | XftFontInt *font = (XftFontInt *) public; | |||
1370 | XftSharpGlyph sharp = _XftSharpGlyphFind (draw, public); | |||
1371 | FT_UInt glyph = glyphs[i].glyph; | |||
1372 | ||||
1373 | if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph])) | |||
1374 | xftg = _XftGlyphDefault (dpy, public); | |||
1375 | if (xftg) | |||
1376 | (*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y); | |||
1377 | } | |||
1378 | } | |||
1379 | bail1: | |||
1380 | if (glyphs_loaded) | |||
1381 | for (i = 0; i < nglyphs; i++) | |||
1382 | _XftFontManageMemory (dpy, glyphs[i].font); | |||
1383 | } |