~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/Xft/xftcore.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

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