2
* $XFree86: xc/lib/Xft/xftcore.c,v 1.13 2003/02/15 22:30:51 dawes Exp $
4
* Copyright � 2000 Keith Packard, member of The XFree86 Project, Inc.
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.
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.
30
XftRectCore (XftDraw *draw,
31
_Xconst XftColor *color,
37
if (color->color.alpha >= 0x8000)
39
XSetForeground (draw->dpy, draw->core.gc, color->pixel);
40
XFillRectangle (draw->dpy, draw->drawable, draw->core.gc,
46
* Use the core protocol to draw the glyphs
50
_XftSharpGlyphMono (XftDraw *draw,
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;
63
x -= glyph->metrics.x;
64
y -= glyph->metrics.y;
71
bitsMask = 0x80; /* FreeType is always MSB first */
85
bitsMask = bitsMask >> 1;
91
} while (bits & bitsMask);
92
XFillRectangle (draw->dpy, draw->drawable,
93
draw->core.gc, xspan, y, lenspan, 1);
105
bitsMask = bitsMask >> 1;
111
} while (!(bits & bitsMask));
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
123
_XftSharpGlyphGray (XftDraw *draw,
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;
135
x -= glyph->metrics.x;
136
y -= glyph->metrics.y;
156
} while (bits >= 0x80);
157
XFillRectangle (draw->dpy, draw->drawable,
158
draw->core.gc, xspan, y, lenspan, 1);
171
} while (bits < 0x80);
179
_XftSharpGlyphRgba (XftDraw *draw,
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;
191
x -= glyph->metrics.x;
192
y -= glyph->metrics.y;
203
if (bits >= 0x80000000)
212
} while (bits >= 0x80000000);
213
XFillRectangle (draw->dpy, draw->drawable,
214
draw->core.gc, xspan, y, lenspan, 1);
227
} while (bits < 0x80000000);
234
typedef void (*XftSharpGlyph) (XftDraw *draw,
240
_XftSharpGlyphFind (XftDraw *draw, XftFont *public)
242
XftFontInt *font = (XftFontInt *) public;
244
if (!font->info.antialias)
245
return _XftSharpGlyphMono;
246
else switch (font->info.rgba) {
251
return _XftSharpGlyphRgba;
253
return _XftSharpGlyphGray;
258
* Draw glyphs to a target that supports anti-aliasing
262
* Primitives for converting between RGB values and TrueColor pixels
266
_XftExamineBitfield (unsigned long mask, int *shift, int *len)
271
while ((mask & 1) == 0)
277
while ((mask & 1) == 1)
287
_XftGetField (unsigned long l_pixel, int shift, int len)
289
CARD32 pixel = (CARD32) l_pixel;
291
pixel = pixel & (((1 << (len)) - 1) << shift);
292
pixel = pixel << (32 - (shift + len)) >> 24;
295
pixel |= (pixel >> len);
302
_XftPutField (CARD32 pixel, int shift, int len)
304
unsigned long l_pixel = (unsigned long) pixel;
306
shift = shift - (8 - len);
308
l_pixel &= (((1 << len) - 1) << (8 - len));
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
322
_XftSmoothGlyphMono (XImage *image,
323
_Xconst XftGlyph *xftg,
326
_Xconst XftColor *color)
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;
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;
354
bitsMask = 0x80; /* FreeType is always MSB first */
361
XPutPixel (image, xspan, y, pixel);
362
bitsMask = bitsMask >> 1;
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
380
#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
381
(((s) >> 5) & 0x07e0) | \
382
(((s) >> 8) & 0xf800))
384
#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
385
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
386
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
388
#define cvt8888to0555(s) ((((s) >> 3) & 0x001f) | \
389
(((s) >> 6) & 0x03e0) | \
390
(((s) >> 7) & 0x7c00))
392
#define cvt0555to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
393
((((s) << 6) & 0xf800) | (((s) >> 0) & 0x300)) | \
394
((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000)))
397
#define XftIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
398
#define XftIntDiv(a,b) (((CARD16) (a) * 255) / (b))
400
#define XftGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
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.
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))
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))
416
#define XftInU(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),(a),(t)) << (i))
418
#define XftInC(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),XftGet8(a,i),(t)) << (i))
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))
425
#define XftAdd(x,y,i,t) ((t) = XftGet8(x,i) + XftGet8(y,i), \
426
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
430
fbOver24 (CARD32 x, CARD32 y)
436
m = XftOverU(x,y,0,a,t);
437
n = XftOverU(x,y,8,a,t);
438
o = XftOverU(x,y,16,a,t);
443
fbIn (CARD32 x, CARD8 y)
451
o = XftInU(x,16,a,t);
452
p = XftInU(x,24,a,t);
457
_XftSmoothGlyphGray8888 (XImage *image,
458
_Xconst XftGlyph *xftg,
461
_Xconst XftColor *color)
465
CARD32 *dstLine, *dst, d;
466
CARD8 *maskLine, *mask, m;
467
int dstStride, maskStride;
471
srca = color->color.alpha >> 8;
473
/* This handles only RGB and BGR */
474
g = (color->color.green & 0xff00);
475
if (image->red_mask == 0xff0000)
477
r = (color->color.red & 0xff00) << 8;
478
b = color->color.blue >> 8;
482
r = color->color.red >> 8;
483
b = (color->color.blue & 0xff00) << 8;
485
src = (srca << 24) | r | g | b;
487
width = xftg->metrics.width;
488
height = xftg->metrics.height;
490
x -= xftg->metrics.x;
491
y -= xftg->metrics.y;
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;
501
dstLine += dstStride;
503
maskLine += maskStride;
514
*dst = fbOver24 (src, *dst);
519
*dst = fbOver24 (d, *dst);
527
_XftSmoothGlyphGray565 (XImage *image,
528
_Xconst XftGlyph *xftg,
531
_Xconst XftColor *color)
536
CARD16 *dstLine, *dst;
537
CARD8 *maskLine, *mask, m;
538
int dstStride, maskStride;
542
srca = color->color.alpha >> 8;
544
/* This handles only RGB and BGR */
545
g = (color->color.green & 0xff00);
546
if (image->red_mask == 0xf800)
548
r = (color->color.red & 0xff00) << 8;
549
b = color->color.blue >> 8;
553
r = color->color.red >> 8;
554
b = (color->color.blue & 0xff00) << 8;
556
src = (srca << 24) | r | g | b;
558
width = xftg->metrics.width;
559
height = xftg->metrics.height;
561
x -= xftg->metrics.x;
562
y -= xftg->metrics.y;
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;
572
dstLine += dstStride;
574
maskLine += maskStride;
587
d = fbOver24 (src, cvt0565to8888(d));
589
*dst = cvt8888to0565(d);
594
d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
595
*dst = cvt8888to0565(d);
603
_XftSmoothGlyphGray555 (XImage *image,
604
_Xconst XftGlyph *xftg,
607
_Xconst XftColor *color)
612
CARD16 *dstLine, *dst;
613
CARD8 *maskLine, *mask, m;
614
int dstStride, maskStride;
618
srca = color->color.alpha >> 8;
620
/* This handles only RGB and BGR */
621
g = (color->color.green & 0xff00);
622
if (image->red_mask == 0xf800)
624
r = (color->color.red & 0xff00) << 8;
625
b = color->color.blue >> 8;
629
r = color->color.red >> 8;
630
b = (color->color.blue & 0xff00) << 8;
632
src = (srca << 24) | r | g | b;
634
width = xftg->metrics.width;
635
height = xftg->metrics.height;
637
x -= xftg->metrics.x;
638
y -= xftg->metrics.y;
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;
648
dstLine += dstStride;
650
maskLine += maskStride;
663
d = fbOver24 (src, cvt0555to8888(d));
665
*dst = cvt8888to0555(d);
670
d = fbOver24 (fbIn(src,m), cvt0555to8888(d));
671
*dst = cvt8888to0555(d);
679
_XftSmoothGlyphGray (XImage *image,
680
_Xconst XftGlyph *xftg,
683
_Xconst XftColor *color)
689
CARD8 *maskLine, *mask, m;
696
srca = color->color.alpha >> 8;
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;
706
maskLine = (unsigned char *) xftg->bitmap;
707
maskStride = (width + 3) & ~3;
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);
715
maskLine += maskStride;
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);
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);
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);
758
_XftSmoothGlyphRgba (XImage *image,
759
_Xconst XftGlyph *xftg,
762
_Xconst XftColor *color)
774
srca = color->color.alpha >> 8;
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;
784
mask = (CARD32 *) xftg->bitmap;
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);
797
if (ma == 0xffffffff)
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);
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);
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); \
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); \
831
XftInOverC(src,srca,ma,d,0,m);
832
XftInOverC(src,srca,ma,d,8,n);
833
XftInOverC(src,srca,ma,d,16,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);
847
_XftSmoothGlyphPossible (XftDraw *draw)
851
if (draw->visual->class != TrueColor)
856
typedef void (*XftSmoothGlyph) (XImage *image,
857
_Xconst XftGlyph *xftg,
860
_Xconst XftColor *color);
862
static XftSmoothGlyph
863
_XftSmoothGlyphFind (XftDraw *draw, XftFont *public)
865
XftFontInt *font = (XftFontInt *) public;
867
if (!font->info.antialias)
868
return _XftSmoothGlyphMono;
869
else switch (font->info.rgba) {
874
return _XftSmoothGlyphRgba;
876
switch (XftDrawBitsPerPixel (draw)) {
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))
885
return _XftSmoothGlyphGray8888;
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))
896
return _XftSmoothGlyphGray565;
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))
905
return _XftSmoothGlyphGray555;
911
return _XftSmoothGlyphGray;
916
_XftGlyphDefault (Display *dpy, XftFont *public)
918
XftFontInt *font = (XftFontInt *) public;
919
FT_UInt missing[XFT_NMISSING];
921
FcBool glyphs_loaded = FcFalse;
923
if (XftFontCheckGlyph (dpy, public, FcTrue, 0, missing, &nmissing))
924
glyphs_loaded = FcTrue;
926
XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
927
return font->glyphs[0];
930
static int XftGetImageErrorHandler (Display *dpy, XErrorEvent *error_event)
936
XftGlyphCore (XftDraw *draw,
937
_Xconst XftColor *color,
941
_Xconst FT_UInt *glyphs,
944
Display *dpy = draw->dpy;
945
XftFontInt *font = (XftFontInt *) public;
949
FT_UInt missing[XFT_NMISSING];
950
FcBool glyphs_loaded;
953
XErrorHandler prev_error;
956
* Load missing glyphs
961
glyphs_loaded = FcFalse;
963
if (XftFontCheckGlyph (dpy, public, FcTrue, *g++, missing, &nmissing))
964
glyphs_loaded = FcTrue;
966
XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
970
if ((font->info.antialias || color->color.alpha != 0xffff) &&
971
_XftSmoothGlyphPossible (draw))
977
XftSmoothGlyph smooth = _XftSmoothGlyphFind (draw, public);
979
XftGlyphExtents (dpy, public, glyphs, nglyphs, &gi);
980
if (!gi.width || !gi.height)
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.
990
if (draw->core.use_pixmap == 0)
992
prev_error = XSetErrorHandler (XftGetImageErrorHandler);
993
image = XGetImage (dpy, draw->drawable,
995
gi.width, gi.height, AllPlanes,
997
XSetErrorHandler (prev_error);
999
draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
1003
draw->core.use_pixmap--;
1006
if (!image && (depth = XftDrawDepth (draw)))
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);
1019
image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes,
1021
XFreePixmap (dpy, pix);
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);
1033
if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
1034
xftg = _XftGlyphDefault (dpy, public);
1037
(*smooth) (image, xftg, x - ox, y - oy, color);
1038
x += xftg->metrics.xOff;
1039
y += xftg->metrics.yOff;
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);
1050
XftSharpGlyph sharp = _XftSharpGlyphFind (draw, public);
1054
if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
1055
xftg = _XftGlyphDefault (dpy, public);
1058
(*sharp) (draw, xftg, x, y);
1059
x += xftg->metrics.xOff;
1060
y += xftg->metrics.yOff;
1066
_XftFontManageMemory (dpy, public);
1069
#define NUM_LOCAL 1024
1072
XftGlyphSpecCore (XftDraw *draw,
1073
_Xconst XftColor *color,
1075
_Xconst XftGlyphSpec *glyphs,
1078
Display *dpy = draw->dpy;
1079
XftFontInt *font = (XftFontInt *) public;
1081
FT_UInt missing[XFT_NMISSING];
1082
FcBool glyphs_loaded;
1085
XErrorHandler prev_error;
1089
* Load missing glyphs
1091
glyphs_loaded = FcFalse;
1092
x1 = y1 = x2 = y2 = 0;
1093
for (i = 0; i < nglyphs; i++)
1096
int g_x1, g_x2, g_y1, g_y2;
1099
if (XftFontCheckGlyph (dpy, public, FcTrue, glyphs[i].glyph, missing, &nmissing))
1100
glyphs_loaded = FcTrue;
1102
XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
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;
1129
if (x1 == x2 || y1 == y2)
1132
if ((font->info.antialias || color->color.alpha != 0xffff) &&
1133
_XftSmoothGlyphPossible (draw))
1137
int width = x2 - x1, height = y2 - y1;
1138
XftSmoothGlyph smooth = _XftSmoothGlyphFind (draw, public);
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.
1146
if (draw->core.use_pixmap == 0)
1148
prev_error = XSetErrorHandler (XftGetImageErrorHandler);
1149
image = XGetImage (dpy, draw->drawable,
1151
width, height, AllPlanes,
1153
XSetErrorHandler (prev_error);
1155
draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
1159
draw->core.use_pixmap--;
1162
if (!image && (depth = XftDrawDepth (draw)))
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);
1175
image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes,
1177
XFreePixmap (dpy, pix);
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++)
1188
FT_UInt glyph = glyphs[i].glyph;
1189
if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
1190
xftg = _XftGlyphDefault (dpy, public);
1193
(*smooth) (image, xftg, glyphs[i].x - x1,
1194
glyphs[i].y - y1, color);
1197
if (image->byte_order != XftNativeByteOrder ())
1198
XftSwapImage (image);
1199
XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1,
1201
XDestroyImage (image);
1205
XftSharpGlyph sharp = _XftSharpGlyphFind (draw, public);
1206
for (i = 0; i < nglyphs; i++)
1208
FT_UInt glyph = glyphs[i].glyph;
1209
if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
1210
xftg = _XftGlyphDefault (dpy, public);
1212
(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
1217
_XftFontManageMemory (dpy, public);
1221
XftGlyphFontSpecCore (XftDraw *draw,
1222
_Xconst XftColor *color,
1223
_Xconst XftGlyphFontSpec *glyphs,
1226
Display *dpy = draw->dpy;
1228
FT_UInt missing[XFT_NMISSING];
1229
FcBool glyphs_loaded;
1232
XErrorHandler prev_error;
1236
* Load missing glyphs
1238
glyphs_loaded = FcFalse;
1239
x1 = y1 = x2 = y2 = 0;
1240
for (i = 0; i < nglyphs; i++)
1242
XftFont *public = glyphs[i].font;
1244
int g_x1, g_x2, g_y1, g_y2;
1247
if (XftFontCheckGlyph (dpy, public, FcTrue, glyphs[i].glyph, missing, &nmissing))
1248
glyphs_loaded = FcTrue;
1250
XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
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;
1277
if (x1 == x2 || y1 == y2)
1280
for (i = 0; i < nglyphs; i++)
1281
if (((XftFontInt *) glyphs[i].font)->info.antialias)
1284
if ((i != nglyphs || color->color.alpha != 0xffff) &&
1285
_XftSmoothGlyphPossible (draw))
1289
int width = x2 - x1, height = y2 - y1;
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.
1297
if (draw->core.use_pixmap == 0)
1299
prev_error = XSetErrorHandler (XftGetImageErrorHandler);
1300
image = XGetImage (dpy, draw->drawable,
1302
width, height, AllPlanes,
1304
XSetErrorHandler (prev_error);
1306
draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
1310
draw->core.use_pixmap--;
1313
if (!image && (depth = XftDrawDepth (draw)))
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);
1326
image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes,
1328
XFreePixmap (dpy, pix);
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++)
1339
XftFont *public = glyphs[i].font;
1340
XftFontInt *font = (XftFontInt *) public;
1341
XftSmoothGlyph smooth = _XftSmoothGlyphFind (draw, public);
1342
FT_UInt glyph = glyphs[i].glyph;
1344
if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
1345
xftg = _XftGlyphDefault (dpy, public);
1348
(*smooth) (image, xftg, glyphs[i].x - x1,
1349
glyphs[i].y - y1, color);
1352
if (image->byte_order != XftNativeByteOrder ())
1353
XftSwapImage (image);
1354
XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1,
1356
XDestroyImage (image);
1360
for (i = 0; i < nglyphs; i++)
1362
XftFont *public = glyphs[i].font;
1363
XftFontInt *font = (XftFontInt *) public;
1364
XftSharpGlyph sharp = _XftSharpGlyphFind (draw, public);
1365
FT_UInt glyph = glyphs[i].glyph;
1367
if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
1368
xftg = _XftGlyphDefault (dpy, public);
1370
(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
1375
for (i = 0; i < nglyphs; i++)
1376
_XftFontManageMemory (dpy, glyphs[i].font);