Bug Summary

File:xftcore.c
Location:line 288, column 19
Description:The result of the '<<' expression is undefined

Annotated Source Code

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
26XftRectCore (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
45static 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 */
118static 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
174static 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
230typedef void (*XftSharpGlyph) (XftDraw *draw,
231 XftGlyph *glyph,
232 int x,
233 int y);
234
235static 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
261static 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
282static 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;
8
The result of the '<<' expression is undefined
289 while (len < 8)
290 {
291 pixel |= (pixel >> len);
292 len <<= 1;
293 }
294 return pixel;
295}
296
297static 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 */
317static 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
425static CARD32
426fbOver24 (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
438static CARD32
439fbIn (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
452static 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
522static 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
598static 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
674static 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
753static 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--)
1
Loop condition is true. Entering loop body
786 {
787 w = width;
788 tx = x;
789
790 while (w--)
2
Loop condition is true. Entering loop body
791 {
792 ma = *mask++;
793 if (ma == 0xffffffff)
3
Assuming 'ma' is equal to -1
4
Taking true branch
794 {
795 if (srca == 0xff)
5
Assuming 'srca' is not equal to 255
6
Taking false branch
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 |
7
Calling '_XftGetField'
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
842static 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
852typedef void (*XftSmoothGlyph) (XImage *image,
853 _Xconstconst XftGlyph *xftg,
854 int x,
855 int y,
856 _Xconstconst XftColor *color);
857
858static 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
911static 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
926static int XftGetImageErrorHandler (Display *dpy, XErrorEvent *error_event)
927{
928 return 0;
929}
930
931_X_HIDDEN__attribute__((visibility("hidden"))) void
932XftGlyphCore (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 }
1060bail1:
1061 if (glyphs_loaded)
1062 _XftFontManageMemory (dpy, public);
1063}
1064
1065#define NUM_LOCAL1024 1024
1066
1067_X_HIDDEN__attribute__((visibility("hidden"))) void
1068XftGlyphSpecCore (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 }
1211bail1:
1212 if (glyphs_loaded)
1213 _XftFontManageMemory (dpy, public);
1214}
1215
1216_X_HIDDEN__attribute__((visibility("hidden"))) void
1217XftGlyphFontSpecCore (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 }
1379bail1:
1380 if (glyphs_loaded)
1381 for (i = 0; i < nglyphs; i++)
1382 _XftFontManageMemory (dpy, glyphs[i].font);
1383}