aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xftfont.c121
1 files changed, 36 insertions, 85 deletions
diff --git a/src/xftfont.c b/src/xftfont.c
index 8ccdb946eca..5da5ac499da 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -46,13 +46,16 @@ static Lisp_Object QChinting , QCautohint, QChintstyle, QCrgba, QCembolden;
46struct xftfont_info 46struct xftfont_info
47{ 47{
48 struct font font; 48 struct font font;
49 Display *display; 49 /* The following three members must be here in this order to be
50 int screen; 50 compatible with struct ftfont_info (in ftfont.c). */
51 XftFont *xftfont;
52#ifdef HAVE_LIBOTF 51#ifdef HAVE_LIBOTF
53 int maybe_otf; /* Flag to tell if this may be OTF or not. */ 52 int maybe_otf; /* Flag to tell if this may be OTF or not. */
54 OTF *otf; 53 OTF *otf;
55#endif /* HAVE_LIBOTF */ 54#endif /* HAVE_LIBOTF */
55 FT_Size ft_size;
56 Display *display;
57 int screen;
58 XftFont *xftfont;
56}; 59};
57 60
58/* Structure pointed by (struct face *)->extra */ 61/* Structure pointed by (struct face *)->extra */
@@ -144,9 +147,6 @@ static unsigned xftfont_encode_char P_ ((struct font *, int));
144static int xftfont_text_extents P_ ((struct font *, unsigned *, int, 147static int xftfont_text_extents P_ ((struct font *, unsigned *, int,
145 struct font_metrics *)); 148 struct font_metrics *));
146static int xftfont_draw P_ ((struct glyph_string *, int, int, int, int, int)); 149static int xftfont_draw P_ ((struct glyph_string *, int, int, int, int, int));
147
148static int xftfont_anchor_point P_ ((struct font *, unsigned, int,
149 int *, int *));
150static int xftfont_end_for_frame P_ ((FRAME_PTR f)); 150static int xftfont_end_for_frame P_ ((FRAME_PTR f));
151 151
152struct font_driver xftfont_driver; 152struct font_driver xftfont_driver;
@@ -176,6 +176,7 @@ xftfont_match (frame, spec)
176} 176}
177 177
178extern Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object)); 178extern Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object));
179extern FcCharSet *ftfont_get_fc_charset P_ ((Lisp_Object));
179extern Lisp_Object QCantialias; 180extern Lisp_Object QCantialias;
180 181
181static FcChar8 ascii_printable[95]; 182static FcChar8 ascii_printable[95];
@@ -188,7 +189,7 @@ xftfont_open (f, entity, pixel_size)
188{ 189{
189 FcResult result; 190 FcResult result;
190 Display *display = FRAME_X_DISPLAY (f); 191 Display *display = FRAME_X_DISPLAY (f);
191 Lisp_Object val, filename, tail, font_object; 192 Lisp_Object val, filename, index, tail, font_object;
192 FcPattern *pat = NULL, *match; 193 FcPattern *pat = NULL, *match;
193 struct xftfont_info *xftfont_info = NULL; 194 struct xftfont_info *xftfont_info = NULL;
194 struct font *font; 195 struct font *font;
@@ -205,6 +206,7 @@ xftfont_open (f, entity, pixel_size)
205 return Qnil; 206 return Qnil;
206 val = XCDR (val); 207 val = XCDR (val);
207 filename = XCAR (val); 208 filename = XCAR (val);
209 index = XCDR (val);
208 size = XINT (AREF (entity, FONT_SIZE_INDEX)); 210 size = XINT (AREF (entity, FONT_SIZE_INDEX));
209 if (size == 0) 211 if (size == 0)
210 size = pixel_size; 212 size = pixel_size;
@@ -234,6 +236,9 @@ xftfont_open (f, entity, pixel_size)
234 val = AREF (entity, FONT_AVGWIDTH_INDEX); 236 val = AREF (entity, FONT_AVGWIDTH_INDEX);
235 if (INTEGERP (val) && XINT (val) == 0) 237 if (INTEGERP (val) && XINT (val) == 0)
236 FcPatternAddBool (pat, FC_SCALABLE, FcTrue); 238 FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
239 /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
240 over 10x20-ISO8859-1.pcf.gz). */
241 FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));
237 242
238 for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) 243 for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
239 { 244 {
@@ -262,23 +267,23 @@ xftfont_open (f, entity, pixel_size)
262#endif 267#endif
263 } 268 }
264 269
270 FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
271 FcPatternAddInteger (pat, FC_INDEX, XINT (index));
272
273
265 BLOCK_INPUT; 274 BLOCK_INPUT;
266 match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result); 275 match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result);
267 FcPatternDestroy (pat); 276 FcPatternDestroy (pat);
268 FcPatternDel (match, FC_FILE);
269 FcPatternAddString (match, FC_FILE, (FcChar8 *) SDATA (filename));
270 xftfont = XftFontOpenPattern (display, match); 277 xftfont = XftFontOpenPattern (display, match);
278 ft_face = XftLockFace (xftfont);
271 UNBLOCK_INPUT; 279 UNBLOCK_INPUT;
272 280
273 if (! xftfont) 281 if (! xftfont)
274 return Qnil; 282 return Qnil;
275 /* We should not destroy PAT here because it is kept in XFTFONT and 283 /* We should not destroy PAT here because it is kept in XFTFONT and
276 destroyed automatically when XFTFONT is closed. */ 284 destroyed automatically when XFTFONT is closed. */
277 font_object = font_make_object (VECSIZE (struct xftfont_info)); 285 font_object = font_make_object (VECSIZE (struct xftfont_info), entity, size);
278 ASET (font_object, FONT_TYPE_INDEX, Qxft); 286 ASET (font_object, FONT_TYPE_INDEX, Qxft);
279 for (i = 1; i < FONT_ENTITY_MAX; i++)
280 ASET (font_object, i, AREF (entity, i));
281 ASET (font_object, FONT_SIZE_INDEX, make_number (size));
282 len = font_unparse_xlfd (entity, size, name, 256); 287 len = font_unparse_xlfd (entity, size, name, 256);
283 if (len > 0) 288 if (len > 0)
284 ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len)); 289 ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len));
@@ -345,7 +350,6 @@ xftfont_open (f, entity, pixel_size)
345 } 350 }
346 font->height = font->ascent + font->descent; 351 font->height = font->ascent + font->descent;
347 352
348 ft_face = XftLockFace (xftfont);
349 if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0) 353 if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0)
350 { 354 {
351 int upEM = ft_face->units_per_EM; 355 int upEM = ft_face->units_per_EM;
@@ -364,7 +368,7 @@ xftfont_open (f, entity, pixel_size)
364 xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; 368 xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
365 xftfont_info->otf = NULL; 369 xftfont_info->otf = NULL;
366#endif /* HAVE_LIBOTF */ 370#endif /* HAVE_LIBOTF */
367 XftUnlockFace (xftfont); 371 xftfont_info->ft_size = ft_face->size;
368 372
369 /* Unfortunately Xft doesn't provide a way to get minimum char 373 /* Unfortunately Xft doesn't provide a way to get minimum char
370 width. So, we use space_width instead. */ 374 width. So, we use space_width instead. */
@@ -374,6 +378,22 @@ xftfont_open (f, entity, pixel_size)
374 font->relative_compose = 0; 378 font->relative_compose = 0;
375 font->default_ascent = 0; 379 font->default_ascent = 0;
376 font->vertical_centering = 0; 380 font->vertical_centering = 0;
381#ifdef FT_BDF_H
382 if (! (ft_face->face_flags & FT_FACE_FLAG_SFNT))
383 {
384 BDF_PropertyRec rec;
385
386 if (FT_Get_BDF_Property (ft_face, "_MULE_BASELINE_OFFSET", &rec) == 0
387 && rec.type == BDF_PROPERTY_TYPE_INTEGER)
388 font->baseline_offset = rec.u.integer;
389 if (FT_Get_BDF_Property (ft_face, "_MULE_RELATIVE_COMPOSE", &rec) == 0
390 && rec.type == BDF_PROPERTY_TYPE_INTEGER)
391 font->relative_compose = rec.u.integer;
392 if (FT_Get_BDF_Property (ft_face, "_MULE_DEFAULT_ASCENT", &rec) == 0
393 && rec.type == BDF_PROPERTY_TYPE_INTEGER)
394 font->default_ascent = rec.u.integer;
395 }
396#endif
377 397
378 return font_object; 398 return font_object;
379} 399}
@@ -390,6 +410,7 @@ xftfont_close (f, font)
390 OTF_close (xftfont_info->otf); 410 OTF_close (xftfont_info->otf);
391#endif 411#endif
392 BLOCK_INPUT; 412 BLOCK_INPUT;
413 XftUnlockFace (xftfont_info->xftfont);
393 XftFontClose (xftfont_info->display, xftfont_info->xftfont); 414 XftFontClose (xftfont_info->display, xftfont_info->xftfont);
394 UNBLOCK_INPUT; 415 UNBLOCK_INPUT;
395} 416}
@@ -545,32 +566,6 @@ xftfont_draw (s, from, to, x, y, with_background)
545} 566}
546 567
547static int 568static int
548xftfont_anchor_point (font, code, index, x, y)
549 struct font *font;
550 unsigned code;
551 int index;
552 int *x, *y;
553{
554 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
555 FT_Face ft_face = XftLockFace (xftfont_info->xftfont);
556 int result;
557
558 if (FT_Load_Glyph (ft_face, code, FT_LOAD_DEFAULT) != 0)
559 result = -1;
560 else if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
561 result = -1;
562 else if (index >= ft_face->glyph->outline.n_points)
563 result = -1;
564 else
565 {
566 *x = ft_face->glyph->outline.points[index].x;
567 *y = ft_face->glyph->outline.points[index].y;
568 }
569 XftUnlockFace (xftfont_info->xftfont);
570 return result;
571}
572
573static int
574xftfont_end_for_frame (f) 569xftfont_end_for_frame (f)
575 FRAME_PTR f; 570 FRAME_PTR f;
576{ 571{
@@ -586,44 +581,6 @@ xftfont_end_for_frame (f)
586 return 0; 581 return 0;
587} 582}
588 583
589#ifdef HAVE_LIBOTF
590#ifdef HAVE_M17N_FLT
591static Lisp_Object
592xftfont_shape (lgstring)
593 Lisp_Object lgstring;
594{
595 struct font *font;
596 struct xftfont_info *xftfont_info;
597 Lisp_Object result;
598 FT_Face ft_face;
599
600 CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font);
601 xftfont_info = (struct xftfont_info *) font;
602 if (! xftfont_info->maybe_otf)
603 return Qnil;
604 ft_face = XftLockFace (xftfont_info->xftfont);
605 if (! xftfont_info->otf)
606 {
607 OTF *otf = OTF_open_ft_face (ft_face);
608
609 if (! otf || OTF_get_table (otf, "head") < 0)
610 {
611 if (otf)
612 OTF_close (otf);
613 xftfont_info->maybe_otf = 0;
614 XftUnlockFace (xftfont_info->xftfont);
615 return Qnil;
616 }
617 xftfont_info->otf = otf;
618 }
619
620 result = ftfont_shape_by_flt (lgstring, font, ft_face, xftfont_info->otf);
621 XftUnlockFace (xftfont_info->xftfont);
622 return result;
623}
624#endif /* HAVE_M17N_FLT */
625#endif /* HAVE_LIBOTF */
626
627void 584void
628syms_of_xftfont () 585syms_of_xftfont ()
629{ 586{
@@ -646,13 +603,7 @@ syms_of_xftfont ()
646 xftfont_driver.encode_char = xftfont_encode_char; 603 xftfont_driver.encode_char = xftfont_encode_char;
647 xftfont_driver.text_extents = xftfont_text_extents; 604 xftfont_driver.text_extents = xftfont_text_extents;
648 xftfont_driver.draw = xftfont_draw; 605 xftfont_driver.draw = xftfont_draw;
649 xftfont_driver.anchor_point = xftfont_anchor_point;
650 xftfont_driver.end_for_frame = xftfont_end_for_frame; 606 xftfont_driver.end_for_frame = xftfont_end_for_frame;
651#ifdef HAVE_LIBOTF
652#ifdef HAVE_M17N_FLT
653 xftfont_driver.shape = xftfont_shape;
654#endif /* HAVE_M17N_FLT */
655#endif /* HAVE_LIBOTF */
656 607
657 register_font_driver (&xftfont_driver, NULL); 608 register_font_driver (&xftfont_driver, NULL);
658} 609}