aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2008-06-13 02:18:59 +0000
committerKenichi Handa2008-06-13 02:18:59 +0000
commit4007dd1cf6dbd6f2cb5321aa4c7baa27291c5c41 (patch)
tree68e35151e18ddbaf10dce30c244b680cf900fd05 /src
parent53aaf1e22f415b058b27ebd2c0c3f97727d54bcd (diff)
downloademacs-4007dd1cf6dbd6f2cb5321aa4c7baa27291c5c41.tar.gz
emacs-4007dd1cf6dbd6f2cb5321aa4c7baa27291c5c41.zip
(font_score): Delete arg alternate_families. Check only
weight, slant, width, and size. (font_sort_entites): Adjusted for the above change. Reflect the order of font-driver to scores. (font_list_entities): Don't check alternate_familes here. (font_clear_prop): Handle foundry. (font_update_lface): Don't parse "foundry-family" form here. Handle FONT_FOUNDRY_INDEX. (font_find_for_lface): Likewise. Handle alternate families here. (font_open_for_lface): Pay attention to size in ENTITY. (font_open_by_name): Simplified by calling font_load_for_lface. (free_font_driver_list): Delete it. (font_update_drivers): Preserve the order of backends. (syms_of_font): Setting of sort_shift_bits adjusted for the change of font_score and font_sort_entites.
Diffstat (limited to 'src')
-rw-r--r--src/font.c452
1 files changed, 213 insertions, 239 deletions
diff --git a/src/font.c b/src/font.c
index 5fd2abe5641..cfe6e41ac28 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2074,7 +2074,7 @@ font_prepare_composition (cmp, f)
2074 2074
2075/* Font sorting */ 2075/* Font sorting */
2076 2076
2077static unsigned font_score P_ ((Lisp_Object, Lisp_Object *, Lisp_Object)); 2077static unsigned font_score P_ ((Lisp_Object, Lisp_Object *));
2078static int font_compare P_ ((const void *, const void *)); 2078static int font_compare P_ ((const void *, const void *));
2079static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, 2079static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object,
2080 Lisp_Object, Lisp_Object, 2080 Lisp_Object, Lisp_Object,
@@ -2084,14 +2084,10 @@ static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object,
2084 font-spec. The score value is 32 bit (`unsigned'), and the smaller 2084 font-spec. The score value is 32 bit (`unsigned'), and the smaller
2085 the value is, the closer the font is to the font-spec. 2085 the value is, the closer the font is to the font-spec.
2086 2086
2087 The highest 2 bits of the score is used for FAMILY. The exact 2087 The lowest 2 bits of the score is used for driver type. The font
2088 match is 0, match with one of face-font-family-alternatives is 2088 available by the most preferred font driver is 0.
2089 nonzero.
2090 2089
2091 The next 2 bits of the score is used for the atomic properties 2090 Each 7-bit in the higher 28 bits are used for numeric properties
2092 FOUNDRY and ADSTYLE respectively.
2093
2094 Each 7-bit in the lower 28 bits are used for numeric properties
2095 WEIGHT, SLANT, WIDTH, and SIZE. */ 2091 WEIGHT, SLANT, WIDTH, and SIZE. */
2096 2092
2097/* How many bits to shift to store the difference value of each font 2093/* How many bits to shift to store the difference value of each font
@@ -2107,43 +2103,12 @@ static int sort_shift_bits[FONT_SIZE_INDEX + 1];
2107 alternate family names for AREF (SPEC_PROP, FONT_FAMILY_INDEX). */ 2103 alternate family names for AREF (SPEC_PROP, FONT_FAMILY_INDEX). */
2108 2104
2109static unsigned 2105static unsigned
2110font_score (entity, spec_prop, alternate_families) 2106font_score (entity, spec_prop)
2111 Lisp_Object entity, *spec_prop; 2107 Lisp_Object entity, *spec_prop;
2112 Lisp_Object alternate_families;
2113{ 2108{
2114 unsigned score = 0; 2109 unsigned score = 0;
2115 int i; 2110 int i;
2116 2111
2117 /* Score three atomic fields. Maximum difference is 1 (family is 3). */
2118 for (i = FONT_FOUNDRY_INDEX; i <= FONT_ADSTYLE_INDEX; i++)
2119 if (i != FONT_REGISTRY_INDEX
2120 && ! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i]))
2121 {
2122 Lisp_Object entity_str = SYMBOL_NAME (AREF (entity, i));
2123 Lisp_Object spec_str = SYMBOL_NAME (spec_prop[i]);
2124
2125 if (xstrcasecmp (SDATA (spec_str), SDATA (entity_str)))
2126 {
2127 if (i == FONT_FAMILY_INDEX && CONSP (alternate_families))
2128 {
2129 int j;
2130
2131 for (j = 1; CONSP (alternate_families);
2132 j++, alternate_families = XCDR (alternate_families))
2133 {
2134 spec_str = XCAR (alternate_families);
2135 if (xstrcasecmp (SDATA (spec_str), SDATA (entity_str)) == 0)
2136 break;
2137 }
2138 if (j > 3)
2139 j = 3;
2140 score |= j << sort_shift_bits[i];
2141 }
2142 else
2143 score |= 1 << sort_shift_bits[i];
2144 }
2145 }
2146
2147 /* Score three style numeric fields. Maximum difference is 127. */ 2112 /* Score three style numeric fields. Maximum difference is 127. */
2148 for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++) 2113 for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++)
2149 if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i])) 2114 if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i]))
@@ -2214,16 +2179,18 @@ font_sort_entites (vec, prefer, frame, spec, best_only)
2214 Lisp_Object prefer_prop[FONT_SPEC_MAX]; 2179 Lisp_Object prefer_prop[FONT_SPEC_MAX];
2215 int len, i; 2180 int len, i;
2216 struct font_sort_data *data; 2181 struct font_sort_data *data;
2217 Lisp_Object alternate_families = Qnil;
2218 unsigned best_score; 2182 unsigned best_score;
2219 Lisp_Object best_entity; 2183 Lisp_Object best_entity, driver_type;
2184 int driver_order;
2185 struct frame *f = XFRAME (frame);
2186 struct font_driver_list *list;
2220 USE_SAFE_ALLOCA; 2187 USE_SAFE_ALLOCA;
2221 2188
2222 len = ASIZE (vec); 2189 len = ASIZE (vec);
2223 if (len <= 1) 2190 if (len <= 1)
2224 return best_only ? AREF (vec, 0) : vec; 2191 return best_only ? AREF (vec, 0) : vec;
2225 2192
2226 for (i = FONT_FOUNDRY_INDEX; i <= FONT_DPI_INDEX; i++) 2193 for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
2227 prefer_prop[i] = AREF (prefer, i); 2194 prefer_prop[i] = AREF (prefer, i);
2228 2195
2229 if (! NILP (spec)) 2196 if (! NILP (spec))
@@ -2234,7 +2201,7 @@ font_sort_entites (vec, prefer, frame, spec, best_only)
2234 generic family name as "serif" is specified. So, to ignore 2201 generic family name as "serif" is specified. So, to ignore
2235 such a difference, for all properties specified in SPEC, set 2202 such a difference, for all properties specified in SPEC, set
2236 the corresponding properties in PREFER_PROP to nil. */ 2203 the corresponding properties in PREFER_PROP to nil. */
2237 for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++) 2204 for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
2238 if (! NILP (AREF (spec, i))) 2205 if (! NILP (AREF (spec, i)))
2239 prefer_prop[i] = Qnil; 2206 prefer_prop[i] = Qnil;
2240 } 2207 }
@@ -2242,24 +2209,28 @@ font_sort_entites (vec, prefer, frame, spec, best_only)
2242 if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) 2209 if (FLOATP (prefer_prop[FONT_SIZE_INDEX]))
2243 prefer_prop[FONT_SIZE_INDEX] 2210 prefer_prop[FONT_SIZE_INDEX]
2244 = make_number (font_pixel_size (XFRAME (frame), prefer)); 2211 = make_number (font_pixel_size (XFRAME (frame), prefer));
2245 if (! NILP (prefer_prop[FONT_FAMILY_INDEX]))
2246 {
2247 alternate_families
2248 = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX],
2249 Vface_alternative_font_family_alist, Qt);
2250 if (CONSP (alternate_families))
2251 alternate_families = XCDR (alternate_families);
2252 }
2253 2212
2254 /* Scoring and sorting. */ 2213 /* Scoring and sorting. */
2255 SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len); 2214 SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len);
2256 best_score = 0xFFFFFFFF; 2215 best_score = 0xFFFFFFFF;
2257 best_entity = Qnil; 2216 /* We are sure that the length of VEC > 1. */
2217 driver_type = AREF (AREF (vec, 0), FONT_TYPE_INDEX);
2218 for (driver_order = 0, list = f->font_driver_list; list;
2219 driver_order++, list = list->next)
2220 if (EQ (driver_type, list->driver->type))
2221 break;
2222 best_entity = data[0].entity = AREF (vec, 0);
2223 best_score = data[0].score
2224 = font_score (data[0].entity, prefer_prop) | driver_order;
2258 for (i = 0; i < len; i++) 2225 for (i = 0; i < len; i++)
2259 { 2226 {
2227 if (!EQ (driver_type, AREF (AREF (vec, i), FONT_TYPE_INDEX)))
2228 for (driver_order = 0, list = f->font_driver_list; list;
2229 driver_order++, list = list->next)
2230 if (EQ (driver_type, list->driver->type))
2231 break;
2260 data[i].entity = AREF (vec, i); 2232 data[i].entity = AREF (vec, i);
2261 data[i].score = font_score (data[i].entity, prefer_prop, 2233 data[i].score = font_score (data[i].entity, prefer_prop) | driver_order;
2262 alternate_families);
2263 if (best_only && best_score > data[i].score) 2234 if (best_only && best_score > data[i].score)
2264 { 2235 {
2265 best_score = data[i].score; 2236 best_score = data[i].score;
@@ -2335,7 +2306,7 @@ font_match_p (spec, entity)
2335 alternate_families = XCDR (alternate_families); 2306 alternate_families = XCDR (alternate_families);
2336 } 2307 }
2337 2308
2338 return (font_score (entity, prefer_prop, alternate_families) == 0); 2309 return (font_score (entity, prefer_prop) == 0);
2339} 2310}
2340 2311
2341 2312
@@ -2531,28 +2502,14 @@ font_list_entities (frame, spec)
2531{ 2502{
2532 FRAME_PTR f = XFRAME (frame); 2503 FRAME_PTR f = XFRAME (frame);
2533 struct font_driver_list *driver_list = f->font_driver_list; 2504 struct font_driver_list *driver_list = f->font_driver_list;
2534 Lisp_Object ftype, family, alternate_familes, val; 2505 Lisp_Object ftype, val;
2535 Lisp_Object *vec; 2506 Lisp_Object *vec;
2536 int size; 2507 int size;
2537 int need_filtering = 0; 2508 int need_filtering = 0;
2538 int n_family = 1;
2539 int i; 2509 int i;
2540 2510
2541 font_assert (FONT_SPEC_P (spec)); 2511 font_assert (FONT_SPEC_P (spec));
2542 2512
2543 family = AREF (spec, FONT_FAMILY_INDEX);
2544 if (NILP (family))
2545 alternate_familes = Qnil;
2546 else
2547 {
2548 alternate_familes = Fassoc_string (family,
2549 Vface_alternative_font_family_alist,
2550 Qt);
2551 if (! NILP (alternate_familes))
2552 alternate_familes = XCDR (alternate_familes);
2553 n_family += XINT (Flength (alternate_familes));
2554 }
2555
2556 if (INTEGERP (AREF (spec, FONT_SIZE_INDEX))) 2513 if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
2557 size = XINT (AREF (spec, FONT_SIZE_INDEX)); 2514 size = XINT (AREF (spec, FONT_SIZE_INDEX));
2558 else if (FLOATP (AREF (spec, FONT_SIZE_INDEX))) 2515 else if (FLOATP (AREF (spec, FONT_SIZE_INDEX)))
@@ -2561,18 +2518,21 @@ font_list_entities (frame, spec)
2561 size = 0; 2518 size = 0;
2562 2519
2563 ftype = AREF (spec, FONT_TYPE_INDEX); 2520 ftype = AREF (spec, FONT_TYPE_INDEX);
2564 for (i = 1; i <= FONT_REGISTRY_INDEX; i++) 2521 for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++)
2565 ASET (scratch_font_spec, i, AREF (spec, i)); 2522 ASET (scratch_font_spec, i, AREF (spec, i));
2566 for (i = FONT_DPI_INDEX; i < FONT_EXTRA_INDEX; i += 2) 2523 for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++)
2567 { 2524 {
2568 ASET (scratch_font_spec, i, Qnil); 2525 ASET (scratch_font_spec, i, Qnil);
2569 if (! NILP (AREF (spec, i))) 2526 if (! NILP (AREF (spec, i)))
2570 need_filtering = 1; 2527 need_filtering = 1;
2528 if (i == FONT_DPI_INDEX)
2529 /* Skip FONT_SPACING_INDEX */
2530 i++;
2571 } 2531 }
2572 ASET (scratch_font_spec, FONT_SPACING_INDEX, AREF (spec, FONT_SPACING_INDEX)); 2532 ASET (scratch_font_spec, FONT_SPACING_INDEX, AREF (spec, FONT_SPACING_INDEX));
2573 ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX)); 2533 ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX));
2574 2534
2575 vec = alloca (sizeof (Lisp_Object) * num_font_drivers * n_family); 2535 vec = alloca (sizeof (Lisp_Object) * num_font_drivers);
2576 if (! vec) 2536 if (! vec)
2577 return null_vector; 2537 return null_vector;
2578 2538
@@ -2581,37 +2541,24 @@ font_list_entities (frame, spec)
2581 && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) 2541 && (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
2582 { 2542 {
2583 Lisp_Object cache = font_get_cache (f, driver_list->driver); 2543 Lisp_Object cache = font_get_cache (f, driver_list->driver);
2584 Lisp_Object tail = alternate_familes;
2585 2544
2586 ASET (scratch_font_spec, FONT_TYPE_INDEX, driver_list->driver->type); 2545 ASET (scratch_font_spec, FONT_TYPE_INDEX, driver_list->driver->type);
2587 ASET (scratch_font_spec, FONT_FAMILY_INDEX, family); 2546 val = assoc_no_quit (scratch_font_spec, XCDR (cache));
2588 while (1) 2547 if (CONSP (val))
2548 val = XCDR (val);
2549 else
2589 { 2550 {
2590 val = assoc_no_quit (scratch_font_spec, XCDR (cache)); 2551 Lisp_Object copy;
2591 if (CONSP (val))
2592 val = XCDR (val);
2593 else
2594 {
2595 Lisp_Object copy;
2596 2552
2597 val = driver_list->driver->list (frame, scratch_font_spec); 2553 val = driver_list->driver->list (frame, scratch_font_spec);
2598 copy = Fcopy_font_spec (scratch_font_spec); 2554 copy = Fcopy_font_spec (scratch_font_spec);
2599 ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); 2555 ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
2600 XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); 2556 XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache)));
2601 }
2602 if (! NILP (val) && need_filtering)
2603 val = font_delete_unmatched (val, spec, size);
2604 if (! NILP (val))
2605 {
2606 vec[i++] = val;
2607 break;
2608 }
2609 if (NILP (tail))
2610 break;
2611 ASET (scratch_font_spec, FONT_FAMILY_INDEX,
2612 Fintern (XCAR (tail), Qnil));
2613 tail = XCDR (tail);
2614 } 2557 }
2558 if (! NILP (val) && need_filtering)
2559 val = font_delete_unmatched (val, spec, size);
2560 if (! NILP (val))
2561 vec[i++] = val;
2615 } 2562 }
2616 2563
2617 val = (i > 0 ? Fvconcat (i, vec) : null_vector); 2564 val = (i > 0 ? Fvconcat (i, vec) : null_vector);
@@ -2869,14 +2816,17 @@ font_clear_prop (attrs, prop)
2869 if (! FONTP (font)) 2816 if (! FONTP (font))
2870 return; 2817 return;
2871 if (NILP (AREF (font, prop)) 2818 if (NILP (AREF (font, prop))
2872 && prop != FONT_FAMILY_INDEX && prop != FONT_FAMILY_INDEX) 2819 && prop != FONT_FAMILY_INDEX && prop != FONT_FOUNDRY_INDEX
2820 && prop != FONT_SIZE_INDEX)
2873 return; 2821 return;
2874 font = Fcopy_font_spec (font); 2822 font = Fcopy_font_spec (font);
2875 ASET (font, prop, Qnil); 2823 ASET (font, prop, Qnil);
2876 if (prop == FONT_FAMILY_INDEX) 2824 if (prop == FONT_FAMILY_INDEX || prop == FONT_FOUNDRY_INDEX)
2877 { 2825 {
2878 ASET (font, FONT_FOUNDRY_INDEX, Qnil); 2826 if (prop == FONT_FAMILY_INDEX)
2827 ASET (font, FONT_FOUNDRY_INDEX, Qnil);
2879 ASET (font, FONT_ADSTYLE_INDEX, Qnil); 2828 ASET (font, FONT_ADSTYLE_INDEX, Qnil);
2829 ASET (font, FONT_REGISTRY_INDEX, Qnil);
2880 ASET (font, FONT_SIZE_INDEX, Qnil); 2830 ASET (font, FONT_SIZE_INDEX, Qnil);
2881 ASET (font, FONT_DPI_INDEX, Qnil); 2831 ASET (font, FONT_DPI_INDEX, Qnil);
2882 ASET (font, FONT_SPACING_INDEX, Qnil); 2832 ASET (font, FONT_SPACING_INDEX, Qnil);
@@ -2902,22 +2852,10 @@ font_update_lface (f, attrs)
2902 if (! FONT_SPEC_P (spec)) 2852 if (! FONT_SPEC_P (spec))
2903 return; 2853 return;
2904 2854
2905 if (! NILP (AREF (spec, FONT_FOUNDRY_INDEX)) 2855 if (! NILP (AREF (spec, FONT_FOUNDRY_INDEX)))
2906 || ! NILP (AREF (spec, FONT_FAMILY_INDEX))) 2856 attrs[LFACE_FOUNDRY_INDEX] = SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX));
2907 { 2857 if (! NILP (AREF (spec, FONT_FAMILY_INDEX)))
2908 Lisp_Object family; 2858 attrs[LFACE_FAMILY_INDEX] = SYMBOL_NAME (AREF (spec, FONT_FAMILY_INDEX));
2909
2910 if (NILP (AREF (spec, FONT_FOUNDRY_INDEX)))
2911 family = AREF (spec, FONT_FAMILY_INDEX);
2912 else if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
2913 family = concat2 (SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX)),
2914 build_string ("-*"));
2915 else
2916 family = concat3 (SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX)),
2917 build_string ("-"),
2918 SYMBOL_NAME (AREF (spec, FONT_FAMILY_INDEX)));
2919 attrs[LFACE_FAMILY_INDEX] = family;
2920 }
2921 if (! NILP (AREF (spec, FONT_WEIGHT_INDEX))) 2859 if (! NILP (AREF (spec, FONT_WEIGHT_INDEX)))
2922 attrs[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (spec); 2860 attrs[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (spec);
2923 if (! NILP (AREF (spec, FONT_SLANT_INDEX))) 2861 if (! NILP (AREF (spec, FONT_SLANT_INDEX)))
@@ -2957,17 +2895,18 @@ font_find_for_lface (f, attrs, spec, c)
2957 Lisp_Object spec; 2895 Lisp_Object spec;
2958 int c; 2896 int c;
2959{ 2897{
2898 Lisp_Object work;
2960 Lisp_Object frame, entities, val, props[FONT_REGISTRY_INDEX + 1] ; 2899 Lisp_Object frame, entities, val, props[FONT_REGISTRY_INDEX + 1] ;
2961 Lisp_Object size; 2900 Lisp_Object size, foundry[3], *family;
2962 int pixel_size; 2901 int pixel_size;
2963 int i, result; 2902 int i, j, result;
2964 2903
2965 if (c >= 0) 2904 if (c >= 0 && ! NILP (AREF (spec, FONT_REGISTRY_INDEX)))
2966 { 2905 {
2967 Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX);
2968 struct charset *encoding, *repertory; 2906 struct charset *encoding, *repertory;
2969 2907
2970 if (font_registry_charsets (registry, &encoding, &repertory) < 0) 2908 if (font_registry_charsets (AREF (spec, FONT_REGISTRY_INDEX),
2909 &encoding, &repertory) < 0)
2971 return Qnil; 2910 return Qnil;
2972 if (repertory) 2911 if (repertory)
2973 { 2912 {
@@ -2981,6 +2920,7 @@ font_find_for_lface (f, attrs, spec, c)
2981 return Qnil; 2920 return Qnil;
2982 } 2921 }
2983 2922
2923 work = Fcopy_font_spec (spec);
2984 XSETFRAME (frame, f); 2924 XSETFRAME (frame, f);
2985 size = AREF (spec, FONT_SIZE_INDEX); 2925 size = AREF (spec, FONT_SIZE_INDEX);
2986 pixel_size = font_pixel_size (f, spec); 2926 pixel_size = font_pixel_size (f, spec);
@@ -2990,9 +2930,68 @@ font_find_for_lface (f, attrs, spec, c)
2990 2930
2991 pixel_size = POINT_TO_PIXEL (pt / 10, f->resy); 2931 pixel_size = POINT_TO_PIXEL (pt / 10, f->resy);
2992 } 2932 }
2993 ASET (spec, FONT_SIZE_INDEX, Qnil); 2933 ASET (work, FONT_SIZE_INDEX, Qnil);
2994 entities = font_list_entities (frame, spec); 2934 foundry[0] = AREF (work, FONT_FOUNDRY_INDEX);
2995 ASET (spec, FONT_SIZE_INDEX, size); 2935 if (! NILP (foundry[0]))
2936 foundry[1] = null_vector;
2937 else if (STRINGP (attrs[LFACE_FOUNDRY_INDEX]))
2938 {
2939 foundry[0] = font_intern_prop (SDATA (attrs[LFACE_FOUNDRY_INDEX]),
2940 SBYTES (attrs[LFACE_FOUNDRY_INDEX]), 1);
2941 foundry[1] = Qnil;
2942 foundry[2] = null_vector;
2943 }
2944 else
2945 foundry[0] = Qnil, foundry[1] = null_vector;
2946
2947 val = AREF (work, FONT_FAMILY_INDEX);
2948 if (NILP (val) && STRINGP (attrs[LFACE_FAMILY_INDEX]))
2949 val = font_intern_prop (SDATA (attrs[LFACE_FAMILY_INDEX]),
2950 SBYTES (attrs[LFACE_FAMILY_INDEX]), 1);
2951 if (NILP (val))
2952 {
2953 family = alloca ((sizeof family[0]) * 2);
2954 family[0] = Qnil;
2955 family[1] = null_vector; /* terminator. */
2956 }
2957 else
2958 {
2959 Lisp_Object alters
2960 = Fassoc_string (val, Vface_alternative_font_family_alist, Qt);
2961
2962 if (! NILP (alters))
2963 {
2964 family = alloca ((sizeof family[0]) * (XINT (Flength (alters)) + 2));
2965 for (i = 0; CONSP (alters); i++, alters = XCDR (alters))
2966 family[i] = XCAR (alters);
2967 if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
2968 family[i++] = Qnil;
2969 family[i] = null_vector;
2970 }
2971 else
2972 {
2973 family = alloca ((sizeof family[0]) * 3);
2974 i = 0;
2975 family[i++] = val;
2976 if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
2977 family[i++] = Qnil;
2978 family[i] = null_vector;
2979 }
2980 }
2981
2982 for (j = 0; SYMBOLP (family[j]); j++)
2983 {
2984 ASET (work, FONT_FAMILY_INDEX, family[j]);
2985 for (i = 0; SYMBOLP (foundry[i]); i++)
2986 {
2987 ASET (work, FONT_FOUNDRY_INDEX, foundry[i]);
2988 entities = font_list_entities (frame, work);
2989 if (ASIZE (entities) > 0)
2990 break;
2991 }
2992 if (ASIZE (entities) > 0)
2993 break;
2994 }
2996 if (ASIZE (entities) == 0) 2995 if (ASIZE (entities) == 0)
2997 return Qnil; 2996 return Qnil;
2998 if (ASIZE (entities) == 1) 2997 if (ASIZE (entities) == 1)
@@ -3006,7 +3005,7 @@ font_find_for_lface (f, attrs, spec, c)
3006 Lisp_Object prefer = scratch_font_prefer; 3005 Lisp_Object prefer = scratch_font_prefer;
3007 3006
3008 for (i = 0; i < FONT_EXTRA_INDEX; i++) 3007 for (i = 0; i < FONT_EXTRA_INDEX; i++)
3009 ASET (prefer, i, AREF (spec, i)); 3008 ASET (prefer, i, AREF (work, i));
3010 if (FONTP (attrs[LFACE_FONT_INDEX])) 3009 if (FONTP (attrs[LFACE_FONT_INDEX]))
3011 { 3010 {
3012 Lisp_Object face_font = attrs[LFACE_FONT_INDEX]; 3011 Lisp_Object face_font = attrs[LFACE_FONT_INDEX];
@@ -3015,8 +3014,6 @@ font_find_for_lface (f, attrs, spec, c)
3015 if (NILP (AREF (prefer, i))) 3014 if (NILP (AREF (prefer, i)))
3016 ASET (prefer, i, AREF (face_font, i)); 3015 ASET (prefer, i, AREF (face_font, i));
3017 } 3016 }
3018 if (NILP (AREF (prefer, FONT_FAMILY_INDEX)))
3019 font_parse_family_registry (attrs[LFACE_FAMILY_INDEX], Qnil, prefer);
3020 if (NILP (AREF (prefer, FONT_WEIGHT_INDEX))) 3017 if (NILP (AREF (prefer, FONT_WEIGHT_INDEX)))
3021 FONT_SET_STYLE (prefer, FONT_WEIGHT_INDEX, attrs[LFACE_WEIGHT_INDEX]); 3018 FONT_SET_STYLE (prefer, FONT_WEIGHT_INDEX, attrs[LFACE_WEIGHT_INDEX]);
3022 if (NILP (AREF (prefer, FONT_SLANT_INDEX))) 3019 if (NILP (AREF (prefer, FONT_SLANT_INDEX)))
@@ -3024,9 +3021,7 @@ font_find_for_lface (f, attrs, spec, c)
3024 if (NILP (AREF (prefer, FONT_WIDTH_INDEX))) 3021 if (NILP (AREF (prefer, FONT_WIDTH_INDEX)))
3025 FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]); 3022 FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]);
3026 ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size)); 3023 ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size));
3027 ASET (spec, FONT_SIZE_INDEX, Qnil); 3024 entities = font_sort_entites (entities, prefer, frame, work, c < 0);
3028 entities = font_sort_entites (entities, prefer, frame, spec, c < 0);
3029 ASET (spec, FONT_SIZE_INDEX, size);
3030 } 3025 }
3031 if (c < 0) 3026 if (c < 0)
3032 return entities; 3027 return entities;
@@ -3072,7 +3067,10 @@ font_open_for_lface (f, entity, attrs, spec)
3072{ 3067{
3073 int size; 3068 int size;
3074 3069
3075 if (FONT_SPEC_P (spec) && ! NILP (AREF (spec, FONT_SIZE_INDEX))) 3070 if (INTEGERP (AREF (entity, FONT_SIZE_INDEX))
3071 && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
3072 size = XINT (AREF (entity, FONT_SIZE_INDEX));
3073 else if (FONT_SPEC_P (spec) && ! NILP (AREF (spec, FONT_SIZE_INDEX)))
3076 size = font_pixel_size (f, spec); 3074 size = font_pixel_size (f, spec);
3077 else 3075 else
3078 { 3076 {
@@ -3144,63 +3142,20 @@ font_open_by_name (f, name)
3144 char *name; 3142 char *name;
3145{ 3143{
3146 Lisp_Object args[2]; 3144 Lisp_Object args[2];
3147 Lisp_Object spec, prefer, size, registry, entity, entity_list; 3145 Lisp_Object spec, attrs[LFACE_VECTOR_SIZE];
3148 Lisp_Object frame;
3149 int i;
3150 int pixel_size;
3151
3152 XSETFRAME (frame, f);
3153 3146
3154 args[0] = QCname; 3147 args[0] = QCname;
3155 args[1] = make_unibyte_string (name, strlen (name)); 3148 args[1] = make_unibyte_string (name, strlen (name));
3156 spec = Ffont_spec (2, args); 3149 spec = Ffont_spec (2, args);
3157 prefer = scratch_font_prefer; 3150 /* We set up the default font-related attributes of a face to prefer
3158 for (i = 0; i < FONT_SPEC_MAX; i++) 3151 a moderate font. */
3159 { 3152 attrs[LFACE_FAMILY_INDEX] = attrs[LFACE_FOUNDRY_INDEX] = Qnil;
3160 ASET (prefer, i, AREF (spec, i)); 3153 attrs[LFACE_SWIDTH_INDEX] = attrs[LFACE_WEIGHT_INDEX]
3161 if (NILP (AREF (prefer, i)) 3154 = attrs[LFACE_SLANT_INDEX] = Qnormal;
3162 && i >= FONT_WEIGHT_INDEX && i <= FONT_WIDTH_INDEX) 3155 attrs[LFACE_HEIGHT_INDEX] = make_number (120);
3163 FONT_SET_STYLE (prefer, i, make_number (100)); 3156 attrs[LFACE_FONT_INDEX] = Qnil;
3164 } 3157
3165 size = AREF (spec, FONT_SIZE_INDEX); 3158 return font_load_for_lface (f, attrs, spec);
3166 if (NILP (size))
3167 pixel_size = 0;
3168 else
3169 {
3170 if (INTEGERP (size))
3171 pixel_size = XINT (size);
3172 else /* FLOATP (size) */
3173 {
3174 double pt = XFLOAT_DATA (size);
3175
3176 pixel_size = POINT_TO_PIXEL (pt, f->resy);
3177 }
3178 if (pixel_size == 0)
3179 ASET (spec, FONT_SIZE_INDEX, Qnil);
3180 }
3181 if (pixel_size == 0)
3182 {
3183 pixel_size = POINT_TO_PIXEL (12.0, f->resy);
3184 size = make_number (pixel_size);
3185 ASET (prefer, FONT_SIZE_INDEX, size);
3186 }
3187 registry = AREF (spec, FONT_REGISTRY_INDEX);
3188 if (NILP (registry))
3189 ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1);
3190 entity_list = Flist_fonts (spec, frame, make_number (1), prefer);
3191 if (NILP (entity_list) && NILP (registry))
3192 {
3193 ASET (spec, FONT_REGISTRY_INDEX, Qascii_0);
3194 entity_list = Flist_fonts (spec, frame, make_number (1), prefer);
3195 }
3196 ASET (spec, FONT_REGISTRY_INDEX, registry);
3197 if (NILP (entity_list))
3198 entity = font_matching_entity (f, NULL, spec);
3199 else
3200 entity = XCAR (entity_list);
3201 return (NILP (entity)
3202 ? Qnil
3203 : font_open_entity (f, entity, pixel_size));
3204} 3159}
3205 3160
3206 3161
@@ -3247,23 +3202,6 @@ register_font_driver (driver, f)
3247} 3202}
3248 3203
3249 3204
3250/* Free font-driver list on frame F. It doesn't free font-drivers
3251 themselves. */
3252
3253void
3254free_font_driver_list (f)
3255 FRAME_PTR f;
3256{
3257 while (f->font_driver_list)
3258 {
3259 struct font_driver_list *next = f->font_driver_list->next;
3260
3261 free (f->font_driver_list);
3262 f->font_driver_list = next;
3263 }
3264}
3265
3266
3267/* Make the frame F use font backends listed in NEW_DRIVERS (list of 3205/* Make the frame F use font backends listed in NEW_DRIVERS (list of
3268 symbols, e.g. xft, x). If NEW_DRIVERS is t, make F use all 3206 symbols, e.g. xft, x). If NEW_DRIVERS is t, make F use all
3269 available font drivers. If NEW_DRIVERS is nil, finalize all drivers. 3207 available font drivers. If NEW_DRIVERS is nil, finalize all drivers.
@@ -3278,36 +3216,75 @@ font_update_drivers (f, new_drivers)
3278 Lisp_Object new_drivers; 3216 Lisp_Object new_drivers;
3279{ 3217{
3280 Lisp_Object active_drivers = Qnil; 3218 Lisp_Object active_drivers = Qnil;
3219 struct font_driver *driver;
3281 struct font_driver_list *list; 3220 struct font_driver_list *list;
3282 3221
3222 /* At first, turn off non-requested drivers, and turn on requested
3223 drivers. */
3283 for (list = f->font_driver_list; list; list = list->next) 3224 for (list = f->font_driver_list; list; list = list->next)
3284 if (list->on) 3225 {
3285 { 3226 driver = list->driver;
3286 if (! EQ (new_drivers, Qt) 3227 if ((EQ (new_drivers, Qt) || ! NILP (Fmemq (driver->type, new_drivers)))
3287 && NILP (Fmemq (list->driver->type, new_drivers))) 3228 != list->on)
3288 { 3229 {
3289 if (list->driver->end_for_frame) 3230 if (list->on)
3290 list->driver->end_for_frame (f); 3231 {
3291 font_finish_cache (f, list->driver); 3232 if (driver->end_for_frame)
3292 list->on = 0; 3233 driver->end_for_frame (f);
3293 } 3234 font_finish_cache (f, driver);
3294 } 3235 list->on = 0;
3295 else 3236 }
3296 { 3237 else
3297 if (EQ (new_drivers, Qt) 3238 {
3298 || ! NILP (Fmemq (list->driver->type, new_drivers))) 3239 if (! driver->start_for_frame
3299 { 3240 || driver->start_for_frame (f) == 0)
3300 if (! list->driver->start_for_frame 3241 {
3301 || list->driver->start_for_frame (f) == 0) 3242 font_prepare_cache (f, driver);
3302 { 3243 list->on = 1;
3303 font_prepare_cache (f, list->driver); 3244 }
3304 list->on = 1; 3245 }
3305 active_drivers = nconc2 (active_drivers, 3246 }
3306 Fcons (list->driver->type, Qnil)); 3247 }
3307 } 3248
3308 } 3249 if (NILP (new_drivers))
3309 } 3250 return Qnil;
3251
3252 if (! EQ (new_drivers, Qt))
3253 {
3254 /* Re-order the driver list according to new_drivers. */
3255 struct font_driver_list **list_table, *list;
3256 Lisp_Object tail;
3257 int i;
3258
3259 list_table = alloca (sizeof list_table[0] * (num_font_drivers + 1));
3260 for (i = 0, tail = new_drivers; ! NILP (tail); tail = XCDR (tail))
3261 {
3262 for (list = f->font_driver_list; list; list = list->next)
3263 if (list->on && EQ (list->driver->type, XCAR (tail)))
3264 break;
3265 if (list)
3266 list_table[i++] = list;
3267 }
3268 for (list = f->font_driver_list; list; list = list->next)
3269 if (! list->on)
3270 list_table[i] = list;
3271 list_table[i] = NULL;
3272
3273 f->font_driver_list = list = NULL;
3274 for (i = 0; list_table[i]; i++)
3275 {
3276 if (list)
3277 list->next = list_table[i], list = list->next;
3278 else
3279 f->font_driver_list = list = list_table[i];
3280 }
3281 list->next = NULL;
3282 }
3310 3283
3284 for (list = f->font_driver_list; list; list = list->next)
3285 if (list->on)
3286 active_drivers = nconc2 (active_drivers,
3287 Fcons (list->driver->type, Qnil));
3311 return active_drivers; 3288 return active_drivers;
3312} 3289}
3313 3290
@@ -4646,15 +4623,12 @@ extern void syms_of_atmfont P_ (());
4646void 4623void
4647syms_of_font () 4624syms_of_font ()
4648{ 4625{
4649 sort_shift_bits[FONT_SLANT_INDEX] = 0; 4626 sort_shift_bits[FONT_TYPE_INDEX] = 0;
4650 sort_shift_bits[FONT_WEIGHT_INDEX] = 7; 4627 sort_shift_bits[FONT_SLANT_INDEX] = 2;
4651 sort_shift_bits[FONT_SIZE_INDEX] = 14; 4628 sort_shift_bits[FONT_WEIGHT_INDEX] = 9;
4652 sort_shift_bits[FONT_WIDTH_INDEX] = 21; 4629 sort_shift_bits[FONT_SIZE_INDEX] = 16;
4653 sort_shift_bits[FONT_ADSTYLE_INDEX] = 28; 4630 sort_shift_bits[FONT_WIDTH_INDEX] = 23;
4654 sort_shift_bits[FONT_FOUNDRY_INDEX] = 29; 4631 /* Note that the other elements in sort_shift_bits are not used. */
4655 sort_shift_bits[FONT_FAMILY_INDEX] = 30;
4656 /* Note that sort_shift_bits[FONT_SORT_TYPE] and
4657 sort_shift_bits[FONT_SORT_REGISTRY] are never used. */
4658 4632
4659 staticpro (&font_charset_alist); 4633 staticpro (&font_charset_alist);
4660 font_charset_alist = Qnil; 4634 font_charset_alist = Qnil;