| 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 | } |