aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/xfaces.c244
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
2205static INLINE Lisp_Object
2206face_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
2234static INLINE Lisp_Object
2235face_symbolic_weight (weight)
2236 Lisp_Object weight;
2237{
2238 return face_symbolic_value (weight_table, DIM (weight_table), weight);
2239}
2240
2241static INLINE Lisp_Object
2242face_symbolic_slant (slant)
2243 Lisp_Object slant;
2244{
2245 return face_symbolic_value (slant_table, DIM (slant_table), slant);
2246}
2247
2248static INLINE Lisp_Object
2249face_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
2191Lisp_Object 2256Lisp_Object
2192split_font_name_into_vector (fontname) 2257split_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
6045int
6046face_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. */