diff options
| -rw-r--r-- | src/xfaces.c | 244 |
1 files changed, 243 insertions, 1 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 5596d5dc613..2b2f1620133 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -246,6 +246,12 @@ Boston, MA 02110-1301, USA. */ | |||
| 246 | #include "window.h" | 246 | #include "window.h" |
| 247 | #include "intervals.h" | 247 | #include "intervals.h" |
| 248 | 248 | ||
| 249 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 250 | #ifdef USE_FONT_BACKEND | ||
| 251 | #include "font.h" | ||
| 252 | #endif /* USE_FONT_BACKEND */ | ||
| 253 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 254 | |||
| 249 | #ifdef HAVE_X_WINDOWS | 255 | #ifdef HAVE_X_WINDOWS |
| 250 | 256 | ||
| 251 | /* Compensate for a bug in Xos.h on some systems, on which it requires | 257 | /* Compensate for a bug in Xos.h on some systems, on which it requires |
| @@ -988,6 +994,9 @@ clear_face_cache (clear_fonts_p) | |||
| 988 | { | 994 | { |
| 989 | struct x_display_info *dpyinfo; | 995 | struct x_display_info *dpyinfo; |
| 990 | 996 | ||
| 997 | #ifdef USE_FONT_BACKEND | ||
| 998 | if (! enable_font_backend) | ||
| 999 | #endif /* USE_FONT_BACKEND */ | ||
| 991 | /* Fonts are common for frames on one display, i.e. on | 1000 | /* Fonts are common for frames on one display, i.e. on |
| 992 | one X screen. */ | 1001 | one X screen. */ |
| 993 | for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) | 1002 | for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) |
| @@ -1249,6 +1258,10 @@ load_face_font (f, face) | |||
| 1249 | char *font_name; | 1258 | char *font_name; |
| 1250 | int needs_overstrike; | 1259 | int needs_overstrike; |
| 1251 | 1260 | ||
| 1261 | #ifdef USE_FONT_BACKEND | ||
| 1262 | if (enable_font_backend) | ||
| 1263 | abort (); | ||
| 1264 | #endif /* USE_FONT_BACKEND */ | ||
| 1252 | face->font_info_id = -1; | 1265 | face->font_info_id = -1; |
| 1253 | face->font = NULL; | 1266 | face->font = NULL; |
| 1254 | face->font_name = NULL; | 1267 | face->font_name = NULL; |
| @@ -2188,6 +2201,58 @@ face_numeric_swidth (width) | |||
| 2188 | 2201 | ||
| 2189 | #ifdef HAVE_WINDOW_SYSTEM | 2202 | #ifdef HAVE_WINDOW_SYSTEM |
| 2190 | 2203 | ||
| 2204 | #ifdef USE_FONT_BACKEND | ||
| 2205 | static INLINE Lisp_Object | ||
| 2206 | face_symbolic_value (table, dim, font_prop) | ||
| 2207 | struct table_entry *table; | ||
| 2208 | int dim; | ||
| 2209 | Lisp_Object font_prop; | ||
| 2210 | { | ||
| 2211 | struct table_entry *p; | ||
| 2212 | char *s = SDATA (SYMBOL_NAME (font_prop)); | ||
| 2213 | int low, mid, high, cmp; | ||
| 2214 | |||
| 2215 | low = 0; | ||
| 2216 | high = dim - 1; | ||
| 2217 | |||
| 2218 | while (low <= high) | ||
| 2219 | { | ||
| 2220 | mid = (low + high) / 2; | ||
| 2221 | cmp = strcmp (table[mid].name, s); | ||
| 2222 | |||
| 2223 | if (cmp < 0) | ||
| 2224 | low = mid + 1; | ||
| 2225 | else if (cmp > 0) | ||
| 2226 | high = mid - 1; | ||
| 2227 | else | ||
| 2228 | return *table[mid].symbol; | ||
| 2229 | } | ||
| 2230 | |||
| 2231 | return Qnil; | ||
| 2232 | } | ||
| 2233 | |||
| 2234 | static INLINE Lisp_Object | ||
| 2235 | face_symbolic_weight (weight) | ||
| 2236 | Lisp_Object weight; | ||
| 2237 | { | ||
| 2238 | return face_symbolic_value (weight_table, DIM (weight_table), weight); | ||
| 2239 | } | ||
| 2240 | |||
| 2241 | static INLINE Lisp_Object | ||
| 2242 | face_symbolic_slant (slant) | ||
| 2243 | Lisp_Object slant; | ||
| 2244 | { | ||
| 2245 | return face_symbolic_value (slant_table, DIM (slant_table), slant); | ||
| 2246 | } | ||
| 2247 | |||
| 2248 | static INLINE Lisp_Object | ||
| 2249 | face_symbolic_swidth (width) | ||
| 2250 | Lisp_Object width; | ||
| 2251 | { | ||
| 2252 | return face_symbolic_value (swidth_table, DIM (swidth_table), width); | ||
| 2253 | } | ||
| 2254 | #endif /* USE_FONT_BACKEND */ | ||
| 2255 | |||
| 2191 | Lisp_Object | 2256 | Lisp_Object |
| 2192 | split_font_name_into_vector (fontname) | 2257 | split_font_name_into_vector (fontname) |
| 2193 | Lisp_Object fontname; | 2258 | Lisp_Object fontname; |
| @@ -3467,6 +3532,107 @@ set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p) | |||
| 3467 | 3532 | ||
| 3468 | /* If FONTNAME is actually a fontset name, get ASCII font name of it. */ | 3533 | /* If FONTNAME is actually a fontset name, get ASCII font name of it. */ |
| 3469 | fontset = fs_query_fontset (fontname, 0); | 3534 | fontset = fs_query_fontset (fontname, 0); |
| 3535 | |||
| 3536 | #ifdef USE_FONT_BACKEND | ||
| 3537 | if (enable_font_backend) | ||
| 3538 | { | ||
| 3539 | Lisp_Object entity; | ||
| 3540 | struct font *font = NULL; | ||
| 3541 | |||
| 3542 | if (fontset > 0) | ||
| 3543 | font = fontset_ascii_font (f, fontset); | ||
| 3544 | else if (fontset == 0) | ||
| 3545 | { | ||
| 3546 | if (may_fail_p) | ||
| 3547 | return 0; | ||
| 3548 | abort (); | ||
| 3549 | } | ||
| 3550 | else | ||
| 3551 | { | ||
| 3552 | Lisp_Object font_object = font_open_by_name (f, SDATA (fontname)); | ||
| 3553 | |||
| 3554 | if (! NILP (font_object)) | ||
| 3555 | { | ||
| 3556 | font = XSAVE_VALUE (font_object)->pointer; | ||
| 3557 | fontset = new_fontset_from_font (f, font_object); | ||
| 3558 | } | ||
| 3559 | } | ||
| 3560 | |||
| 3561 | if (! font) | ||
| 3562 | { | ||
| 3563 | if (may_fail_p) | ||
| 3564 | return 0; | ||
| 3565 | abort (); | ||
| 3566 | } | ||
| 3567 | |||
| 3568 | entity = font->entity; | ||
| 3569 | |||
| 3570 | /* Set attributes only if unspecified, otherwise face defaults for | ||
| 3571 | new frames would never take effect. If we couldn't get a font | ||
| 3572 | name conforming to XLFD, set normal values. */ | ||
| 3573 | |||
| 3574 | if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface))) | ||
| 3575 | { | ||
| 3576 | Lisp_Object foundry = AREF (entity, FONT_FOUNDRY_INDEX); | ||
| 3577 | Lisp_Object family = AREF (entity, FONT_FAMILY_INDEX); | ||
| 3578 | Lisp_Object val; | ||
| 3579 | |||
| 3580 | if (! NILP (foundry)) | ||
| 3581 | { | ||
| 3582 | if (! NILP (family)) | ||
| 3583 | val = concat3 (SYMBOL_NAME (foundry), build_string ("-"), | ||
| 3584 | SYMBOL_NAME (family)); | ||
| 3585 | else | ||
| 3586 | val = concat2 (SYMBOL_NAME (foundry), build_string ("-*")); | ||
| 3587 | } | ||
| 3588 | else | ||
| 3589 | { | ||
| 3590 | if (! NILP (family)) | ||
| 3591 | val = SYMBOL_NAME (family); | ||
| 3592 | else | ||
| 3593 | val = build_string ("*"); | ||
| 3594 | } | ||
| 3595 | LFACE_FAMILY (lface) = val; | ||
| 3596 | } | ||
| 3597 | |||
| 3598 | if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface))) | ||
| 3599 | { | ||
| 3600 | int pt = pixel_point_size (f, font->pixel_size * 10); | ||
| 3601 | |||
| 3602 | xassert (pt > 0); | ||
| 3603 | LFACE_HEIGHT (lface) = make_number (pt); | ||
| 3604 | } | ||
| 3605 | |||
| 3606 | if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface))) | ||
| 3607 | LFACE_AVGWIDTH (lface) = make_number (0); | ||
| 3608 | |||
| 3609 | if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface))) | ||
| 3610 | { | ||
| 3611 | Lisp_Object weight = font_symbolic_weight (entity); | ||
| 3612 | Lisp_Object symbol = face_symbolic_weight (weight); | ||
| 3613 | |||
| 3614 | LFACE_WEIGHT (lface) = NILP (symbol) ? weight : symbol; | ||
| 3615 | } | ||
| 3616 | if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface))) | ||
| 3617 | { | ||
| 3618 | Lisp_Object slant = font_symbolic_slant (entity); | ||
| 3619 | Lisp_Object symbol = face_symbolic_slant (slant); | ||
| 3620 | |||
| 3621 | LFACE_SLANT (lface) = NILP (symbol) ? slant : symbol; | ||
| 3622 | } | ||
| 3623 | if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface))) | ||
| 3624 | { | ||
| 3625 | Lisp_Object width = font_symbolic_width (entity); | ||
| 3626 | Lisp_Object symbol = face_symbolic_swidth (width); | ||
| 3627 | |||
| 3628 | LFACE_SWIDTH (lface) = NILP (symbol) ? width : symbol; | ||
| 3629 | } | ||
| 3630 | |||
| 3631 | ASET (lface, LFACE_FONT_INDEX, Ffont_xlfd_name (font->entity)); | ||
| 3632 | ASET (lface, LFACE_FONTSET_INDEX, fontset_name (fontset)); | ||
| 3633 | return 1; | ||
| 3634 | } | ||
| 3635 | #endif /* USE_FONT_BACKEND */ | ||
| 3470 | if (fontset > 0) | 3636 | if (fontset > 0) |
| 3471 | font_name = SDATA (fontset_ascii (fontset)); | 3637 | font_name = SDATA (fontset_ascii (fontset)); |
| 3472 | else if (fontset == 0) | 3638 | else if (fontset == 0) |
| @@ -4592,6 +4758,18 @@ set_font_frame_param (frame, lface) | |||
| 4592 | 4758 | ||
| 4593 | if (STRINGP (LFACE_FONT (lface))) | 4759 | if (STRINGP (LFACE_FONT (lface))) |
| 4594 | font_name = LFACE_FONT (lface); | 4760 | font_name = LFACE_FONT (lface); |
| 4761 | #ifdef USE_FONT_BACKEND | ||
| 4762 | else if (enable_font_backend) | ||
| 4763 | { | ||
| 4764 | Lisp_Object entity = font_find_for_lface (f, &AREF (lface, 0), Qnil); | ||
| 4765 | |||
| 4766 | if (NILP (entity)) | ||
| 4767 | error ("No font matches the specified attribute"); | ||
| 4768 | font_name = font_open_for_lface (f, &AREF (lface, 0), entity); | ||
| 4769 | if (NILP (font_name)) | ||
| 4770 | error ("No font matches the specified attribute"); | ||
| 4771 | } | ||
| 4772 | #endif | ||
| 4595 | else | 4773 | else |
| 4596 | { | 4774 | { |
| 4597 | /* Choose a font name that reflects LFACE's attributes and has | 4775 | /* Choose a font name that reflects LFACE's attributes and has |
| @@ -5357,6 +5535,10 @@ free_realized_face (f, face) | |||
| 5357 | free_face_fontset (f, face); | 5535 | free_face_fontset (f, face); |
| 5358 | if (face->gc) | 5536 | if (face->gc) |
| 5359 | { | 5537 | { |
| 5538 | #ifdef USE_FONT_BACKEND | ||
| 5539 | if (enable_font_backend && face->font_info) | ||
| 5540 | font_done_for_face (f, face); | ||
| 5541 | #endif /* USE_FONT_BACKEND */ | ||
| 5360 | x_free_gc (f, face->gc); | 5542 | x_free_gc (f, face->gc); |
| 5361 | face->gc = 0; | 5543 | face->gc = 0; |
| 5362 | } | 5544 | } |
| @@ -5418,6 +5600,10 @@ prepare_face_for_display (f, face) | |||
| 5418 | } | 5600 | } |
| 5419 | #endif | 5601 | #endif |
| 5420 | face->gc = x_create_gc (f, mask, &xgcv); | 5602 | face->gc = x_create_gc (f, mask, &xgcv); |
| 5603 | #ifdef USE_FONT_BACKEND | ||
| 5604 | if (enable_font_backend && face->font) | ||
| 5605 | font_prepare_for_face (f, face); | ||
| 5606 | #endif /* USE_FONT_BACKEND */ | ||
| 5421 | UNBLOCK_INPUT; | 5607 | UNBLOCK_INPUT; |
| 5422 | } | 5608 | } |
| 5423 | #endif /* HAVE_WINDOW_SYSTEM */ | 5609 | #endif /* HAVE_WINDOW_SYSTEM */ |
| @@ -5524,6 +5710,10 @@ clear_face_gcs (c) | |||
| 5524 | struct face *face = c->faces_by_id[i]; | 5710 | struct face *face = c->faces_by_id[i]; |
| 5525 | if (face && face->gc) | 5711 | if (face && face->gc) |
| 5526 | { | 5712 | { |
| 5713 | #ifdef USE_FONT_BACKEND | ||
| 5714 | if (enable_font_backend && face->font_info) | ||
| 5715 | font_done_for_face (c->f, face); | ||
| 5716 | #endif /* USE_FONT_BACKEND */ | ||
| 5527 | x_free_gc (c->f, face->gc); | 5717 | x_free_gc (c->f, face->gc); |
| 5528 | face->gc = 0; | 5718 | face->gc = 0; |
| 5529 | } | 5719 | } |
| @@ -5850,6 +6040,43 @@ lookup_non_ascii_face (f, font_id, base_face) | |||
| 5850 | 6040 | ||
| 5851 | return face->id; | 6041 | return face->id; |
| 5852 | } | 6042 | } |
| 6043 | |||
| 6044 | #ifdef USE_FONT_BACKEND | ||
| 6045 | int | ||
| 6046 | face_for_font (f, font, base_face) | ||
| 6047 | struct frame *f; | ||
| 6048 | struct font *font; | ||
| 6049 | struct face *base_face; | ||
| 6050 | { | ||
| 6051 | struct face_cache *cache = FRAME_FACE_CACHE (f); | ||
| 6052 | unsigned hash; | ||
| 6053 | int i; | ||
| 6054 | struct face *face; | ||
| 6055 | |||
| 6056 | xassert (cache != NULL); | ||
| 6057 | base_face = base_face->ascii_face; | ||
| 6058 | hash = lface_hash (base_face->lface); | ||
| 6059 | i = hash % FACE_CACHE_BUCKETS_SIZE; | ||
| 6060 | |||
| 6061 | for (face = cache->buckets[i]; face; face = face->next) | ||
| 6062 | { | ||
| 6063 | if (face->ascii_face == face) | ||
| 6064 | continue; | ||
| 6065 | if (face->ascii_face == base_face | ||
| 6066 | && face->font_info == (struct font_info *) font) | ||
| 6067 | return face->id; | ||
| 6068 | } | ||
| 6069 | |||
| 6070 | /* If not found, realize a new face. */ | ||
| 6071 | face = realize_non_ascii_face (f, -1, base_face); | ||
| 6072 | face->font = font->font.font; | ||
| 6073 | face->font_info = (struct font_info *) font; | ||
| 6074 | face->font_info_id = 0; | ||
| 6075 | face->font_name = font->font.full_name; | ||
| 6076 | return face->id; | ||
| 6077 | } | ||
| 6078 | #endif /* USE_FONT_BACKEND */ | ||
| 6079 | |||
| 5853 | #endif /* HAVE_WINDOW_SYSTEM */ | 6080 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 5854 | 6081 | ||
| 5855 | /* Return the face id of the realized face for named face SYMBOL on | 6082 | /* Return the face id of the realized face for named face SYMBOL on |
| @@ -6451,6 +6678,10 @@ Value is ORDER. */) | |||
| 6451 | free_all_realized_faces (Qnil); | 6678 | free_all_realized_faces (Qnil); |
| 6452 | } | 6679 | } |
| 6453 | 6680 | ||
| 6681 | #ifdef USE_FONT_BACKEND | ||
| 6682 | font_update_sort_order (font_sort_order); | ||
| 6683 | #endif /* USE_FONT_BACKEND */ | ||
| 6684 | |||
| 6454 | return Qnil; | 6685 | return Qnil; |
| 6455 | } | 6686 | } |
| 6456 | 6687 | ||
| @@ -7425,6 +7656,9 @@ realize_x_face (cache, attrs) | |||
| 7425 | { | 7656 | { |
| 7426 | face->font = default_face->font; | 7657 | face->font = default_face->font; |
| 7427 | face->font_info_id = default_face->font_info_id; | 7658 | face->font_info_id = default_face->font_info_id; |
| 7659 | #ifdef USE_FONT_BACKEND | ||
| 7660 | face->font_info = default_face->font_info; | ||
| 7661 | #endif /* USE_FONT_BACKEND */ | ||
| 7428 | face->font_name = default_face->font_name; | 7662 | face->font_name = default_face->font_name; |
| 7429 | face->fontset | 7663 | face->fontset |
| 7430 | = make_fontset_for_ascii_face (f, default_face->fontset, face); | 7664 | = make_fontset_for_ascii_face (f, default_face->fontset, face); |
| @@ -7447,8 +7681,16 @@ realize_x_face (cache, attrs) | |||
| 7447 | fontset = default_face->fontset; | 7681 | fontset = default_face->fontset; |
| 7448 | if (fontset == -1) | 7682 | if (fontset == -1) |
| 7449 | abort (); | 7683 | abort (); |
| 7684 | #ifdef USE_FONT_BACKEND | ||
| 7685 | if (enable_font_backend) | ||
| 7686 | font_load_for_face (f, face); | ||
| 7687 | else | ||
| 7688 | #endif /* USE_FONT_BACKEND */ | ||
| 7450 | load_face_font (f, face); | 7689 | load_face_font (f, face); |
| 7451 | face->fontset = make_fontset_for_ascii_face (f, fontset, face); | 7690 | if (face->font) |
| 7691 | face->fontset = make_fontset_for_ascii_face (f, fontset, face); | ||
| 7692 | else | ||
| 7693 | face->fontset = -1; | ||
| 7452 | } | 7694 | } |
| 7453 | 7695 | ||
| 7454 | /* Load colors, and set remaining attributes. */ | 7696 | /* Load colors, and set remaining attributes. */ |