aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Moellmann2001-02-05 20:01:01 +0000
committerGerd Moellmann2001-02-05 20:01:01 +0000
commita08332c0e5ff2467cd3919f1930e0244b40a3126 (patch)
treeea7ae9559ea61849a0d153568357ac96aa06b05c
parent670019ba28ec089c7578a774a3612f5d6406a489 (diff)
downloademacs-a08332c0e5ff2467cd3919f1930e0244b40a3126.tar.gz
emacs-a08332c0e5ff2467cd3919f1930e0244b40a3126.zip
(split_font_name): Compute numeric value of
XLFD_AVGWIDTH. (LFACE_AVGWIDTH): New macro. (LFACEP): Use AREF. (check_lface_attrs): Check LFACE_AVGWIDTH. (lface_fully_specified_p): Don't check LFACE_AVGWIDTH. (set_lface_from_font_name): Set LFACE_AVGWIDTH. (merge_face_vectors): Check LFACE_AVGWIDTH. (Finternal_make_lisp_face): Use AREF. (xm_set_menu_resources_from_menu_face) (xl_set_menu_resources_from_menu_face): Check LFACE_AVGWIDTH. (Finternal_lisp_face_empty_p): Use AREF. (lface_same_font_attributes_p): Compare LFACE_AVGWIDTH. (better_font_p, exact_face_match_p): Add parameter AVGWIDTH. Compare average widths.. (best_matching_font): Arrange for comparing average widths.
-rw-r--r--src/ChangeLog22
-rw-r--r--src/xfaces.c152
2 files changed, 110 insertions, 64 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index ac307862aa4..df8e58ac4bc 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,25 @@
12001-02-05 Gerd Moellmann <gerd@gnu.org>
2
3 * xfaces.c (split_font_name): Compute numeric value of
4 XLFD_AVGWIDTH.
5 (LFACE_AVGWIDTH): New macro.
6 (LFACEP): Use AREF.
7 (check_lface_attrs): Check LFACE_AVGWIDTH.
8 (lface_fully_specified_p): Don't check LFACE_AVGWIDTH.
9 (set_lface_from_font_name): Set LFACE_AVGWIDTH.
10 (merge_face_vectors): Check LFACE_AVGWIDTH.
11 (Finternal_make_lisp_face): Use AREF.
12 (xm_set_menu_resources_from_menu_face)
13 (xl_set_menu_resources_from_menu_face): Check LFACE_AVGWIDTH.
14 (Finternal_lisp_face_empty_p): Use AREF.
15 (lface_same_font_attributes_p): Compare LFACE_AVGWIDTH.
16 (better_font_p, exact_face_match_p): Add parameter AVGWIDTH.
17 Compare average widths..
18 (best_matching_font): Arrange for comparing average widths.
19
20 * dispextern.h (enum lface_attribute_index): Add
21 LFACE_AVGWIDTH_INDEX (invisible from Lisp).
22
12001-02-05 Dave Love <fx@gnu.org> 232001-02-05 Dave Love <fx@gnu.org>
2 24
3 * puresize.h: Revert last change following loadup.el change. 25 * puresize.h: Revert last change following loadup.el change.
diff --git a/src/xfaces.c b/src/xfaces.c
index fc8a224b5bd..64e53fc12d6 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -68,6 +68,10 @@ Boston, MA 02111-1307, USA. */
68 68
69 15. A face name or list of face names from which to inherit attributes. 69 15. A face name or list of face names from which to inherit attributes.
70 70
71 16. A specified average font width, which is invisible from Lisp,
72 and is used to ensure that a font specified on the command line,
73 for example, can be matched exactly.
74
71 Faces are frame-local by nature because Emacs allows to define the 75 Faces are frame-local by nature because Emacs allows to define the
72 same named face (face names are symbols) differently for different 76 same named face (face names are symbols) differently for different
73 frames. Each frame has an alist of face definitions for all named 77 frames. Each frame has an alist of face definitions for all named
@@ -504,7 +508,7 @@ static Lisp_Object resolve_face_name P_ ((Lisp_Object));
504static int may_use_scalable_font_p P_ ((struct font_name *, char *)); 508static int may_use_scalable_font_p P_ ((struct font_name *, char *));
505static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); 509static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
506static int better_font_p P_ ((int *, struct font_name *, struct font_name *, 510static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
507 int)); 511 int, int));
508static int first_font_matching P_ ((struct frame *f, char *, 512static int first_font_matching P_ ((struct frame *f, char *,
509 struct font_name *)); 513 struct font_name *));
510static int x_face_list_fonts P_ ((struct frame *, char *, 514static int x_face_list_fonts P_ ((struct frame *, char *,
@@ -1859,7 +1863,9 @@ static struct frame *font_frame;
1859 set via set-face-font-sort-order. */ 1863 set via set-face-font-sort-order. */
1860 1864
1861#ifdef macintosh 1865#ifdef macintosh
1862static int font_sort_order[4] = { XLFD_SWIDTH, XLFD_POINT_SIZE, XLFD_WEIGHT, XLFD_SLANT }; 1866static int font_sort_order[4] = {
1867 XLFD_SWIDTH, XLFD_POINT_SIZE, XLFD_WEIGHT, XLFD_SLANT
1868};
1863#else 1869#else
1864static int font_sort_order[4]; 1870static int font_sort_order[4];
1865#endif 1871#endif
@@ -2193,6 +2199,7 @@ split_font_name (f, font, numeric_p)
2193 font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font); 2199 font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font);
2194 font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font); 2200 font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font);
2195 font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font); 2201 font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font);
2202 font->numeric[XLFD_AVGWIDTH] = atoi (font->fields[XLFD_AVGWIDTH]);
2196 } 2203 }
2197 2204
2198 /* Initialize it to zero. It will be overridden by font_list while 2205 /* Initialize it to zero. It will be overridden by font_list while
@@ -2835,38 +2842,24 @@ the WIDTH times as wide as FACE on FRAME.")
2835 Lisp Faces 2842 Lisp Faces
2836 ***********************************************************************/ 2843 ***********************************************************************/
2837 2844
2838/* Access face attributes of face FACE, a Lisp vector. */ 2845/* Access face attributes of face LFACE, a Lisp vector. */
2839 2846
2840#define LFACE_FAMILY(LFACE) \ 2847#define LFACE_FAMILY(LFACE) AREF ((LFACE), LFACE_FAMILY_INDEX)
2841 XVECTOR (LFACE)->contents[LFACE_FAMILY_INDEX] 2848#define LFACE_HEIGHT(LFACE) AREF ((LFACE), LFACE_HEIGHT_INDEX)
2842#define LFACE_HEIGHT(LFACE) \ 2849#define LFACE_WEIGHT(LFACE) AREF ((LFACE), LFACE_WEIGHT_INDEX)
2843 XVECTOR (LFACE)->contents[LFACE_HEIGHT_INDEX] 2850#define LFACE_SLANT(LFACE) AREF ((LFACE), LFACE_SLANT_INDEX)
2844#define LFACE_WEIGHT(LFACE) \ 2851#define LFACE_UNDERLINE(LFACE) AREF ((LFACE), LFACE_UNDERLINE_INDEX)
2845 XVECTOR (LFACE)->contents[LFACE_WEIGHT_INDEX] 2852#define LFACE_INVERSE(LFACE) AREF ((LFACE), LFACE_INVERSE_INDEX)
2846#define LFACE_SLANT(LFACE) \ 2853#define LFACE_FOREGROUND(LFACE) AREF ((LFACE), LFACE_FOREGROUND_INDEX)
2847 XVECTOR (LFACE)->contents[LFACE_SLANT_INDEX] 2854#define LFACE_BACKGROUND(LFACE) AREF ((LFACE), LFACE_BACKGROUND_INDEX)
2848#define LFACE_UNDERLINE(LFACE) \ 2855#define LFACE_STIPPLE(LFACE) AREF ((LFACE), LFACE_STIPPLE_INDEX)
2849 XVECTOR (LFACE)->contents[LFACE_UNDERLINE_INDEX] 2856#define LFACE_SWIDTH(LFACE) AREF ((LFACE), LFACE_SWIDTH_INDEX)
2850#define LFACE_INVERSE(LFACE) \ 2857#define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX)
2851 XVECTOR (LFACE)->contents[LFACE_INVERSE_INDEX] 2858#define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX)
2852#define LFACE_FOREGROUND(LFACE) \ 2859#define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX)
2853 XVECTOR (LFACE)->contents[LFACE_FOREGROUND_INDEX] 2860#define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
2854#define LFACE_BACKGROUND(LFACE) \ 2861#define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
2855 XVECTOR (LFACE)->contents[LFACE_BACKGROUND_INDEX] 2862#define LFACE_AVGWIDTH(LFACE) AREF ((LFACE), LFACE_AVGWIDTH_INDEX)
2856#define LFACE_STIPPLE(LFACE) \
2857 XVECTOR (LFACE)->contents[LFACE_STIPPLE_INDEX]
2858#define LFACE_SWIDTH(LFACE) \
2859 XVECTOR (LFACE)->contents[LFACE_SWIDTH_INDEX]
2860#define LFACE_OVERLINE(LFACE) \
2861 XVECTOR (LFACE)->contents[LFACE_OVERLINE_INDEX]
2862#define LFACE_STRIKE_THROUGH(LFACE) \
2863 XVECTOR (LFACE)->contents[LFACE_STRIKE_THROUGH_INDEX]
2864#define LFACE_BOX(LFACE) \
2865 XVECTOR (LFACE)->contents[LFACE_BOX_INDEX]
2866#define LFACE_FONT(LFACE) \
2867 XVECTOR (LFACE)->contents[LFACE_FONT_INDEX]
2868#define LFACE_INHERIT(LFACE) \
2869 XVECTOR (LFACE)->contents[LFACE_INHERIT_INDEX]
2870 2863
2871/* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size 2864/* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
2872 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */ 2865 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
@@ -2874,7 +2867,7 @@ the WIDTH times as wide as FACE on FRAME.")
2874#define LFACEP(LFACE) \ 2867#define LFACEP(LFACE) \
2875 (VECTORP (LFACE) \ 2868 (VECTORP (LFACE) \
2876 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \ 2869 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
2877 && EQ (XVECTOR (LFACE)->contents[0], Qface)) 2870 && EQ (AREF (LFACE, 0), Qface))
2878 2871
2879 2872
2880#if GLYPH_DEBUG 2873#if GLYPH_DEBUG
@@ -2889,6 +2882,8 @@ check_lface_attrs (attrs)
2889 || STRINGP (attrs[LFACE_FAMILY_INDEX])); 2882 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
2890 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) 2883 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
2891 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX])); 2884 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
2885 xassert (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
2886 || INTEGERP (attrs[LFACE_AVGWIDTH_INDEX]));
2892 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) 2887 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
2893 || INTEGERP (attrs[LFACE_HEIGHT_INDEX]) 2888 || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
2894 || FLOATP (attrs[LFACE_HEIGHT_INDEX]) 2889 || FLOATP (attrs[LFACE_HEIGHT_INDEX])
@@ -3053,7 +3048,8 @@ lface_fully_specified_p (attrs)
3053 int i; 3048 int i;
3054 3049
3055 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) 3050 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3056 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX) 3051 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
3052 && i != LFACE_AVGWIDTH_INDEX)
3057 if (UNSPECIFIEDP (attrs[i])) 3053 if (UNSPECIFIEDP (attrs[i]))
3058 break; 3054 break;
3059 3055
@@ -3148,6 +3144,12 @@ set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p)
3148 LFACE_SWIDTH (lface) 3144 LFACE_SWIDTH (lface)
3149 = have_xlfd_p ? xlfd_symbolic_swidth (&font) : Qnormal; 3145 = have_xlfd_p ? xlfd_symbolic_swidth (&font) : Qnormal;
3150 3146
3147 if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
3148 LFACE_AVGWIDTH (lface)
3149 = (have_xlfd_p
3150 ? make_number (font.numeric[XLFD_AVGWIDTH])
3151 : Qunspecified);
3152
3151 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface))) 3153 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
3152 LFACE_WEIGHT (lface) 3154 LFACE_WEIGHT (lface)
3153 = have_xlfd_p ? xlfd_symbolic_weight (&font) : Qnormal; 3155 = have_xlfd_p ? xlfd_symbolic_weight (&font) : Qnormal;
@@ -3263,7 +3265,8 @@ merge_face_vectors (f, from, to, cycle_check)
3263 || !UNSPECIFIEDP (from[LFACE_HEIGHT_INDEX]) 3265 || !UNSPECIFIEDP (from[LFACE_HEIGHT_INDEX])
3264 || !UNSPECIFIEDP (from[LFACE_WEIGHT_INDEX]) 3266 || !UNSPECIFIEDP (from[LFACE_WEIGHT_INDEX])
3265 || !UNSPECIFIEDP (from[LFACE_SLANT_INDEX]) 3267 || !UNSPECIFIEDP (from[LFACE_SLANT_INDEX])
3266 || !UNSPECIFIEDP (from[LFACE_SWIDTH_INDEX]))) 3268 || !UNSPECIFIEDP (from[LFACE_SWIDTH_INDEX])
3269 || !UNSPECIFIEDP (from[LFACE_AVGWIDTH_INDEX])))
3267 to[LFACE_FONT_INDEX] = Qnil; 3270 to[LFACE_FONT_INDEX] = Qnil;
3268 3271
3269 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) 3272 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
@@ -3601,7 +3604,7 @@ Value is a vector of face attributes.")
3601 { 3604 {
3602 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE), 3605 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3603 Qunspecified); 3606 Qunspecified);
3604 XVECTOR (global_lface)->contents[0] = Qface; 3607 AREF (global_lface, 0) = Qface;
3605 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface), 3608 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
3606 Vface_new_frame_defaults); 3609 Vface_new_frame_defaults);
3607 3610
@@ -3623,7 +3626,7 @@ Value is a vector of face attributes.")
3623 } 3626 }
3624 else if (f == NULL) 3627 else if (f == NULL)
3625 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) 3628 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3626 XVECTOR (global_lface)->contents[i] = Qunspecified; 3629 AREF (global_lface, i) = Qunspecified;
3627 3630
3628 /* Add a frame-local definition. */ 3631 /* Add a frame-local definition. */
3629 if (f) 3632 if (f)
@@ -3632,12 +3635,12 @@ Value is a vector of face attributes.")
3632 { 3635 {
3633 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE), 3636 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3634 Qunspecified); 3637 Qunspecified);
3635 XVECTOR (lface)->contents[0] = Qface; 3638 AREF (lface, 0) = Qface;
3636 f->face_alist = Fcons (Fcons (face, lface), f->face_alist); 3639 f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
3637 } 3640 }
3638 else 3641 else
3639 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) 3642 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3640 XVECTOR (lface)->contents[i] = Qunspecified; 3643 AREF (lface, i) = Qunspecified;
3641 } 3644 }
3642 else 3645 else
3643 lface = global_lface; 3646 lface = global_lface;
@@ -4420,6 +4423,7 @@ xm_set_menu_resources_from_menu_face (f, widget)
4420 if (face->font 4423 if (face->font
4421 && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) 4424 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
4422 || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) 4425 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
4426 || !UNSPECIFIEDP (LFACE_AVGWIDTH (lface))
4423 || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) 4427 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
4424 || !UNSPECIFIEDP (LFACE_SLANT (lface)) 4428 || !UNSPECIFIEDP (LFACE_SLANT (lface))
4425 || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) 4429 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
@@ -4500,6 +4504,7 @@ xl_set_menu_resources_from_menu_face (f, widget)
4500 if (face->font 4504 if (face->font
4501 && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) 4505 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
4502 || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) 4506 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
4507 || !UNSPECIFIEDP (LFACE_AVGWIDTH (lface))
4503 || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) 4508 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
4504 || !UNSPECIFIEDP (LFACE_SLANT (lface)) 4509 || !UNSPECIFIEDP (LFACE_SLANT (lface))
4505 || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) 4510 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
@@ -4845,7 +4850,7 @@ If FRAME is omitted or nil, use the selected frame.")
4845 lface = lface_from_face_name (f, face, 1); 4850 lface = lface_from_face_name (f, face, 1);
4846 4851
4847 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) 4852 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4848 if (!UNSPECIFIEDP (XVECTOR (lface)->contents[i])) 4853 if (!UNSPECIFIEDP (AREF (lface, i)))
4849 break; 4854 break;
4850 4855
4851 return i == LFACE_VECTOR_SIZE ? Qt : Qnil; 4856 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
@@ -4911,6 +4916,7 @@ lface_same_font_attributes_p (lface1, lface2)
4911 XSTRING (lface2[LFACE_FAMILY_INDEX])->data) == 0 4916 XSTRING (lface2[LFACE_FAMILY_INDEX])->data) == 0
4912 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX]) 4917 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
4913 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX]) 4918 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
4919 && EQ (lface1[LFACE_AVGWIDTH_INDEX], lface2[LFACE_AVGWIDTH_INDEX])
4914 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX]) 4920 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
4915 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX]) 4921 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
4916 && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX]) 4922 && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
@@ -5543,7 +5549,7 @@ Value is ORDER.")
5543{ 5549{
5544 Lisp_Object list; 5550 Lisp_Object list;
5545 int i; 5551 int i;
5546 int indices[4]; 5552 int indices[DIM (font_sort_order)];
5547 5553
5548 CHECK_LIST (order, 0); 5554 CHECK_LIST (order, 0);
5549 bzero (indices, sizeof indices); 5555 bzero (indices, sizeof indices);
@@ -5572,13 +5578,11 @@ Value is ORDER.")
5572 indices[i] = xlfd; 5578 indices[i] = xlfd;
5573 } 5579 }
5574 5580
5575 if (!NILP (list) 5581 if (!NILP (list) || i != DIM (indices))
5576 || i != DIM (indices)
5577 || indices[0] == 0
5578 || indices[1] == 0
5579 || indices[2] == 0
5580 || indices[3] == 0)
5581 signal_error ("Invalid font sort order", order); 5582 signal_error ("Invalid font sort order", order);
5583 for (i = 0; i < DIM (font_sort_order); ++i)
5584 if (indices[i] == 0)
5585 signal_error ("Invalid font sort order", order);
5582 5586
5583 if (bcmp (indices, font_sort_order, sizeof indices) != 0) 5587 if (bcmp (indices, font_sort_order, sizeof indices) != 0)
5584 { 5588 {
@@ -5655,17 +5659,18 @@ font_scalable_p (font)
5655/* Value is non-zero if FONT1 is a better match for font attributes 5659/* Value is non-zero if FONT1 is a better match for font attributes
5656 VALUES than FONT2. VALUES is an array of face attribute values in 5660 VALUES than FONT2. VALUES is an array of face attribute values in
5657 font sort order. COMPARE_PT_P zero means don't compare point 5661 font sort order. COMPARE_PT_P zero means don't compare point
5658 sizes. */ 5662 sizes. AVGWIDTH, if not zero, is a specified font average width
5663 to compare with. */
5659 5664
5660static int 5665static int
5661better_font_p (values, font1, font2, compare_pt_p) 5666better_font_p (values, font1, font2, compare_pt_p, avgwidth)
5662 int *values; 5667 int *values;
5663 struct font_name *font1, *font2; 5668 struct font_name *font1, *font2;
5664 int compare_pt_p; 5669 int compare_pt_p, avgwidth;
5665{ 5670{
5666 int i; 5671 int i;
5667 5672
5668 for (i = 0; i < 4; ++i) 5673 for (i = 0; i < DIM (font_sort_order); ++i)
5669 { 5674 {
5670 int xlfd_idx = font_sort_order[i]; 5675 int xlfd_idx = font_sort_order[i];
5671 5676
@@ -5694,26 +5699,40 @@ better_font_p (values, font1, font2, compare_pt_p)
5694 } 5699 }
5695 } 5700 }
5696 5701
5697 return (font1->registry_priority < font2->registry_priority); 5702 if (avgwidth)
5703 {
5704 int delta1 = abs (avgwidth - font1->numeric[XLFD_AVGWIDTH]);
5705 int delta2 = abs (avgwidth - font2->numeric[XLFD_AVGWIDTH]);
5706 if (delta1 > delta2)
5707 return 0;
5708 else if (delta1 < delta2)
5709 return 1;
5710 }
5711
5712 return font1->registry_priority < font2->registry_priority;
5698} 5713}
5699 5714
5700 5715
5701/* Value is non-zero if FONT is an exact match for face attributes in 5716/* Value is non-zero if FONT is an exact match for face attributes in
5702 SPECIFIED. SPECIFIED is an array of face attribute values in font 5717 SPECIFIED. SPECIFIED is an array of face attribute values in font
5703 sort order. */ 5718 sort order. AVGWIDTH, if non-zero, is an average width to compare
5719 with. */
5704 5720
5705static int 5721static int
5706exact_face_match_p (specified, font) 5722exact_face_match_p (specified, font, avgwidth)
5707 int *specified; 5723 int *specified;
5708 struct font_name *font; 5724 struct font_name *font;
5725 int avgwidth;
5709{ 5726{
5710 int i; 5727 int i;
5711 5728
5712 for (i = 0; i < 4; ++i) 5729 for (i = 0; i < DIM (font_sort_order); ++i)
5713 if (specified[i] != font->numeric[font_sort_order[i]]) 5730 if (specified[i] != font->numeric[font_sort_order[i]])
5714 break; 5731 break;
5715 5732
5716 return i == 4; 5733 return (i == DIM (font_sort_order)
5734 && (avgwidth <= 0
5735 || avgwidth == font->numeric[XLFD_AVGWIDTH]));
5717} 5736}
5718 5737
5719 5738
@@ -5823,8 +5842,8 @@ best_matching_font (f, attrs, fonts, nfonts)
5823 char *font_name; 5842 char *font_name;
5824 struct font_name *best; 5843 struct font_name *best;
5825 int i, pt = 0; 5844 int i, pt = 0;
5826 int specified[4]; 5845 int specified[5];
5827 int exact_p; 5846 int exact_p, avgwidth;
5828 5847
5829 if (nfonts == 0) 5848 if (nfonts == 0)
5830 return NULL; 5849 return NULL;
@@ -5847,6 +5866,10 @@ best_matching_font (f, attrs, fonts, nfonts)
5847 abort (); 5866 abort ();
5848 } 5867 }
5849 5868
5869 avgwidth = (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
5870 ? 0
5871 : XFASTINT (attrs[LFACE_AVGWIDTH_INDEX]));
5872
5850 exact_p = 0; 5873 exact_p = 0;
5851 5874
5852 /* Start with the first non-scalable font in the list. */ 5875 /* Start with the first non-scalable font in the list. */
@@ -5861,11 +5884,11 @@ best_matching_font (f, attrs, fonts, nfonts)
5861 5884
5862 for (i = 1; i < nfonts; ++i) 5885 for (i = 1; i < nfonts; ++i)
5863 if (!font_scalable_p (fonts + i) 5886 if (!font_scalable_p (fonts + i)
5864 && better_font_p (specified, fonts + i, best, 1)) 5887 && better_font_p (specified, fonts + i, best, 1, avgwidth))
5865 { 5888 {
5866 best = fonts + i; 5889 best = fonts + i;
5867 5890
5868 exact_p = exact_face_match_p (specified, best); 5891 exact_p = exact_face_match_p (specified, best, avgwidth);
5869 if (exact_p) 5892 if (exact_p)
5870 break; 5893 break;
5871 } 5894 }
@@ -5897,9 +5920,9 @@ best_matching_font (f, attrs, fonts, nfonts)
5897 if (font_scalable_p (fonts + i)) 5920 if (font_scalable_p (fonts + i))
5898 { 5921 {
5899 if (best == NULL 5922 if (best == NULL
5900 || better_font_p (specified, fonts + i, best, 0) 5923 || better_font_p (specified, fonts + i, best, 0, 0)
5901 || (!non_scalable_has_exact_height_p 5924 || (!non_scalable_has_exact_height_p
5902 && !better_font_p (specified, best, fonts + i, 0))) 5925 && !better_font_p (specified, best, fonts + i, 0, 0)))
5903 best = fonts + i; 5926 best = fonts + i;
5904 } 5927 }
5905 } 5928 }
@@ -6131,6 +6154,7 @@ realize_default_face (f)
6131 LFACE_HEIGHT (lface) = make_number (1); 6154 LFACE_HEIGHT (lface) = make_number (1);
6132 LFACE_WEIGHT (lface) = Qnormal; 6155 LFACE_WEIGHT (lface) = Qnormal;
6133 LFACE_SLANT (lface) = Qnormal; 6156 LFACE_SLANT (lface) = Qnormal;
6157 LFACE_AVGWIDTH (lface) = Qunspecified;
6134 } 6158 }
6135 6159
6136 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface))) 6160 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))