diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xftfont.c | 121 |
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; | |||
| 46 | struct xftfont_info | 46 | struct 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)); | |||
| 144 | static int xftfont_text_extents P_ ((struct font *, unsigned *, int, | 147 | static int xftfont_text_extents P_ ((struct font *, unsigned *, int, |
| 145 | struct font_metrics *)); | 148 | struct font_metrics *)); |
| 146 | static int xftfont_draw P_ ((struct glyph_string *, int, int, int, int, int)); | 149 | static int xftfont_draw P_ ((struct glyph_string *, int, int, int, int, int)); |
| 147 | |||
| 148 | static int xftfont_anchor_point P_ ((struct font *, unsigned, int, | ||
| 149 | int *, int *)); | ||
| 150 | static int xftfont_end_for_frame P_ ((FRAME_PTR f)); | 150 | static int xftfont_end_for_frame P_ ((FRAME_PTR f)); |
| 151 | 151 | ||
| 152 | struct font_driver xftfont_driver; | 152 | struct font_driver xftfont_driver; |
| @@ -176,6 +176,7 @@ xftfont_match (frame, spec) | |||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | extern Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object)); | 178 | extern Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object)); |
| 179 | extern FcCharSet *ftfont_get_fc_charset P_ ((Lisp_Object)); | ||
| 179 | extern Lisp_Object QCantialias; | 180 | extern Lisp_Object QCantialias; |
| 180 | 181 | ||
| 181 | static FcChar8 ascii_printable[95]; | 182 | static 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 | ||
| 547 | static int | 568 | static int |
| 548 | xftfont_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 | |||
| 573 | static int | ||
| 574 | xftfont_end_for_frame (f) | 569 | xftfont_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 | ||
| 591 | static Lisp_Object | ||
| 592 | xftfont_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 | |||
| 627 | void | 584 | void |
| 628 | syms_of_xftfont () | 585 | syms_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 | } |