comparison src/font.c @ 103889:82ad563e96ed

(font_vconcat_entity_vectors): New function. (struct font_sort_data): New member font_driver_preference. (font_compare): Check font_driver_preference. (font_sort_entities): The format of the first argument changed. (font_delete_unmatched): Likewise. (font_list_entities): The return type changed. (font_select_entity): The format of the second argument changed. (font_find_for_lface): Adjusted for the above changes. Don't suppress the checking of C even if the repertory supports it. (Flist_fonts): Adjusted for the above changes.
author Kenichi Handa <handa@m17n.org>
date Tue, 14 Jul 2009 12:03:16 +0000
parents 1a45bb782f72
children 5ad8c9beecab
comparison
equal deleted inserted replaced
103888:0cebb3e8f85d 103889:82ad563e96ed
271 /* The following code is copied from the function intern (in 271 /* The following code is copied from the function intern (in
272 lread.c), and modified to suite our purpose. */ 272 lread.c), and modified to suite our purpose. */
273 obarray = Vobarray; 273 obarray = Vobarray;
274 if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0) 274 if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
275 obarray = check_obarray (obarray); 275 obarray = check_obarray (obarray);
276 parse_str_as_multibyte (str, len, &nchars, &nbytes); 276 parse_str_as_multibyte ((unsigned char *) str, len, &nchars, &nbytes);
277 if (len == nchars || len != nbytes) 277 if (len == nchars || len != nbytes)
278 /* CONTENTS contains no multibyte sequences or contains an invalid 278 /* CONTENTS contains no multibyte sequences or contains an invalid
279 multibyte sequence. We'll make a unibyte string. */ 279 multibyte sequence. We'll make a unibyte string. */
280 tem = oblookup (obarray, str, len, len); 280 tem = oblookup (obarray, str, len, len);
281 else 281 else
2278 2278
2279 return score; 2279 return score;
2280 } 2280 }
2281 2281
2282 2282
2283 /* Concatenate all elements of LIST into one vector. LIST is a list
2284 of font-entity vectors. */
2285
2286 static Lisp_Object
2287 font_vconcat_entity_vectors (Lisp_Object list)
2288 {
2289 int nargs = XINT (Flength (list));
2290 Lisp_Object *args = alloca (sizeof (Lisp_Object) * nargs);
2291 int i;
2292
2293 for (i = 0; i < nargs; i++, list = XCDR (list))
2294 args[i] = XCAR (list);
2295 return Fvconcat (nargs, args);
2296 }
2297
2298
2299 /* The structure for elements being sorted by qsort. */
2300 struct font_sort_data
2301 {
2302 unsigned score;
2303 int font_driver_preference;
2304 Lisp_Object entity;
2305 };
2306
2307
2283 /* The comparison function for qsort. */ 2308 /* The comparison function for qsort. */
2284 2309
2285 static int 2310 static int
2286 font_compare (d1, d2) 2311 font_compare (d1, d2)
2287 const void *d1, *d2; 2312 const void *d1, *d2;
2288 { 2313 {
2289 return (*(unsigned *) d1 - *(unsigned *) d2); 2314 const struct font_sort_data *data1 = d1;
2290 } 2315 const struct font_sort_data *data2 = d2;
2291 2316
2292 2317 if (data1->score < data2->score)
2293 /* The structure for elements being sorted by qsort. */ 2318 return -1;
2294 struct font_sort_data 2319 else if (data1->score > data2->score)
2295 { 2320 return 1;
2296 unsigned score; 2321 return (data1->font_driver_preference - data2->font_driver_preference);
2297 Lisp_Object entity; 2322 }
2298 }; 2323
2299 2324
2300 2325 /* Sort each font-entity vector in LIST by closeness to font-spec PREFER.
2301 /* Sort font-entities in vector VEC by closeness to font-spec PREFER.
2302 If PREFER specifies a point-size, calculate the corresponding 2326 If PREFER specifies a point-size, calculate the corresponding
2303 pixel-size from QCdpi property of PREFER or from the Y-resolution 2327 pixel-size from QCdpi property of PREFER or from the Y-resolution
2304 of FRAME before sorting. 2328 of FRAME before sorting.
2305 2329
2306 If BEST-ONLY is nonzero, return the best matching entity (that 2330 If BEST-ONLY is nonzero, return the best matching entity (that
2307 supports the character BEST-ONLY if BEST-ONLY is positive, or any 2331 supports the character BEST-ONLY if BEST-ONLY is positive, or any
2308 if BEST-ONLY is negative). Otherwise, return the sorted VEC. 2332 if BEST-ONLY is negative). Otherwise, return the sorted result as
2309 2333 a single vector of font-entities.
2310 This function does no optimization for the case that the length of 2334
2311 VEC is 1. The caller should avoid calling this in such a case. */ 2335 This function does no optimization for the case that the total
2336 number of elements is 1. The caller should avoid calling this in
2337 such a case. */
2312 2338
2313 static Lisp_Object 2339 static Lisp_Object
2314 font_sort_entities (vec, prefer, frame, best_only) 2340 font_sort_entities (list, prefer, frame, best_only)
2315 Lisp_Object vec, prefer, frame; 2341 Lisp_Object list, prefer, frame;
2316 int best_only; 2342 int best_only;
2317 { 2343 {
2318 Lisp_Object prefer_prop[FONT_SPEC_MAX]; 2344 Lisp_Object prefer_prop[FONT_SPEC_MAX];
2319 int len, i; 2345 int len, maxlen, i;
2320 struct font_sort_data *data; 2346 struct font_sort_data *data;
2321 unsigned best_score; 2347 unsigned best_score;
2322 Lisp_Object best_entity, driver_type; 2348 Lisp_Object best_entity;
2323 int driver_order;
2324 struct frame *f = XFRAME (frame); 2349 struct frame *f = XFRAME (frame);
2325 struct font_driver_list *list; 2350 Lisp_Object tail, vec;
2326 USE_SAFE_ALLOCA; 2351 USE_SAFE_ALLOCA;
2327 2352
2328 len = ASIZE (vec);
2329 for (i = FONT_WEIGHT_INDEX; i <= FONT_AVGWIDTH_INDEX; i++) 2353 for (i = FONT_WEIGHT_INDEX; i <= FONT_AVGWIDTH_INDEX; i++)
2330 prefer_prop[i] = AREF (prefer, i); 2354 prefer_prop[i] = AREF (prefer, i);
2331 if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) 2355 if (FLOATP (prefer_prop[FONT_SIZE_INDEX]))
2332 prefer_prop[FONT_SIZE_INDEX] 2356 prefer_prop[FONT_SIZE_INDEX]
2333 = make_number (font_pixel_size (XFRAME (frame), prefer)); 2357 = make_number (font_pixel_size (XFRAME (frame), prefer));
2334 2358
2335 /* Scoring and sorting. */ 2359 if (NILP (XCDR (list)))
2336 SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len); 2360 {
2337 /* We are sure that the length of VEC > 1. */ 2361 /* What we have to take care of is this single vector. */
2338 driver_type = AREF (AREF (vec, 0), FONT_TYPE_INDEX); 2362 vec = XCAR (list);
2339 for (driver_order = 0, list = f->font_driver_list; list; 2363 maxlen = ASIZE (vec);
2340 driver_order++, list = list->next) 2364 }
2341 if (EQ (driver_type, list->driver->type)) 2365 else if (best_only)
2342 break; 2366 {
2367 /* We don't have to perform sort, so there's no need of creating
2368 a single vector. But, we must find the length of the longest
2369 vector. */
2370 maxlen = 0;
2371 for (tail = list; CONSP (tail); tail = XCDR (tail))
2372 if (maxlen < ASIZE (XCAR (tail)))
2373 maxlen = ASIZE (XCAR (tail));
2374 }
2375 else
2376 {
2377 /* We have to create a single vector to sort it. */
2378 vec = font_vconcat_entity_vectors (list);
2379 maxlen = ASIZE (vec);
2380 }
2381
2382 SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * maxlen);
2343 best_score = 0xFFFFFFFF; 2383 best_score = 0xFFFFFFFF;
2344 best_entity = Qnil; 2384 best_entity = Qnil;
2345 for (i = 0; i < len; i++) 2385
2346 { 2386 for (tail = list; CONSP (tail); tail = XCDR (tail))
2347 if (!EQ (driver_type, AREF (AREF (vec, i), FONT_TYPE_INDEX))) 2387 {
2348 for (driver_order = 0, list = f->font_driver_list; list; 2388 int font_driver_preference = 0;
2349 driver_order++, list = list->next) 2389 Lisp_Object current_font_driver;
2350 if (EQ (driver_type, list->driver->type)) 2390
2351 break; 2391 if (best_only)
2352 data[i].entity = AREF (vec, i); 2392 vec = XCAR (tail);
2353 data[i].score 2393 len = ASIZE (vec);
2354 = (best_only <= 0 || font_has_char (f, data[i].entity, best_only) > 0 2394
2355 ? font_score (data[i].entity, prefer_prop) | driver_order 2395 /* We are sure that the length of VEC > 0. */
2356 : 0xFFFFFFFF); 2396 current_font_driver = AREF (AREF (vec, 0), FONT_TYPE_INDEX);
2357 if (best_only && best_score > data[i].score) 2397 /* Score the elements. */
2358 {
2359 best_score = data[i].score;
2360 best_entity = data[i].entity;
2361 if (best_score == 0)
2362 break;
2363 }
2364 }
2365 if (! best_only)
2366 {
2367 qsort (data, len, sizeof *data, font_compare);
2368 for (i = 0; i < len; i++) 2398 for (i = 0; i < len; i++)
2369 ASET (vec, i, data[i].entity); 2399 {
2370 } 2400 data[i].entity = AREF (vec, i);
2371 else 2401 data[i].score
2372 vec = best_entity; 2402 = ((best_only <= 0 || font_has_char (f, data[i].entity, best_only)
2403 > 0)
2404 ? font_score (data[i].entity, prefer_prop)
2405 : 0xFFFFFFFF);
2406 if (best_only && best_score > data[i].score)
2407 {
2408 best_score = data[i].score;
2409 best_entity = data[i].entity;
2410 if (best_score == 0)
2411 break;
2412 }
2413 if (! EQ (current_font_driver, AREF (AREF (vec, i), FONT_TYPE_INDEX)))
2414 {
2415 current_font_driver = AREF (AREF (vec, i), FONT_TYPE_INDEX);
2416 font_driver_preference++;
2417 }
2418 data[i].font_driver_preference = font_driver_preference;
2419 }
2420
2421 /* Sort if necessary. */
2422 if (! best_only)
2423 {
2424 qsort (data, len, sizeof *data, font_compare);
2425 for (i = 0; i < len; i++)
2426 ASET (vec, i, data[i].entity);
2427 break;
2428 }
2429 else
2430 vec = best_entity;
2431 }
2432
2373 SAFE_FREE (); 2433 SAFE_FREE ();
2374 2434
2375 FONT_ADD_LOG ("sort-by", prefer, vec); 2435 FONT_ADD_LOG ("sort-by", prefer, vec);
2376 return vec; 2436 return vec;
2377 } 2437 }
2716 2776
2717 2777
2718 static Lisp_Object scratch_font_spec, scratch_font_prefer; 2778 static Lisp_Object scratch_font_spec, scratch_font_prefer;
2719 2779
2720 Lisp_Object 2780 Lisp_Object
2721 font_delete_unmatched (list, spec, size) 2781 font_delete_unmatched (vec, spec, size)
2722 Lisp_Object list, spec; 2782 Lisp_Object vec, spec;
2723 int size; 2783 int size;
2724 { 2784 {
2725 Lisp_Object entity, val; 2785 Lisp_Object entity, val;
2726 enum font_property_index prop; 2786 enum font_property_index prop;
2727 2787 int i;
2728 for (val = Qnil; CONSP (list); list = XCDR (list)) 2788
2729 { 2789 for (val = Qnil, i = ASIZE (vec) - 1; i >= 0; i--)
2730 entity = XCAR (list); 2790 {
2791 entity = AREF (vec, i);
2731 for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++) 2792 for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++)
2732 if (INTEGERP (AREF (spec, prop)) 2793 if (INTEGERP (AREF (spec, prop))
2733 && ((XINT (AREF (spec, prop)) >> 8) 2794 && ((XINT (AREF (spec, prop)) >> 8)
2734 != (XINT (AREF (entity, prop)) >> 8))) 2795 != (XINT (AREF (entity, prop)) >> 8)))
2735 prop = FONT_SPEC_MAX; 2796 prop = FONT_SPEC_MAX;
2758 AREF (entity, FONT_AVGWIDTH_INDEX))) 2819 AREF (entity, FONT_AVGWIDTH_INDEX)))
2759 prop = FONT_SPEC_MAX; 2820 prop = FONT_SPEC_MAX;
2760 if (prop < FONT_SPEC_MAX) 2821 if (prop < FONT_SPEC_MAX)
2761 val = Fcons (entity, val); 2822 val = Fcons (entity, val);
2762 } 2823 }
2763 return Fnreverse (val); 2824 return (Fvconcat (1, &val));
2764 } 2825 }
2765 2826
2766 2827
2767 /* Return a vector of font-entities matching with SPEC on FRAME. */ 2828 /* Return a list of vectors of font-entities matching with SPEC on
2829 FRAME. The elements of the list are in the same of order of
2830 font-drivers. */
2768 2831
2769 Lisp_Object 2832 Lisp_Object
2770 font_list_entities (frame, spec) 2833 font_list_entities (frame, spec)
2771 Lisp_Object frame, spec; 2834 Lisp_Object frame, spec;
2772 { 2835 {
2773 FRAME_PTR f = XFRAME (frame); 2836 FRAME_PTR f = XFRAME (frame);
2774 struct font_driver_list *driver_list = f->font_driver_list; 2837 struct font_driver_list *driver_list = f->font_driver_list;
2775 Lisp_Object ftype, val; 2838 Lisp_Object ftype, val;
2776 Lisp_Object *vec; 2839 Lisp_Object list = Qnil;
2777 int size; 2840 int size;
2778 int need_filtering = 0; 2841 int need_filtering = 0;
2779 int i; 2842 int i;
2780 2843
2781 font_assert (FONT_SPEC_P (spec)); 2844 font_assert (FONT_SPEC_P (spec));
2799 /* Skip FONT_SPACING_INDEX */ 2862 /* Skip FONT_SPACING_INDEX */
2800 i++; 2863 i++;
2801 } 2864 }
2802 ASET (scratch_font_spec, FONT_SPACING_INDEX, AREF (spec, FONT_SPACING_INDEX)); 2865 ASET (scratch_font_spec, FONT_SPACING_INDEX, AREF (spec, FONT_SPACING_INDEX));
2803 ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX)); 2866 ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX));
2804
2805 vec = alloca (sizeof (Lisp_Object) * num_font_drivers);
2806 if (! vec)
2807 return null_vector;
2808 2867
2809 for (i = 0; driver_list; driver_list = driver_list->next) 2868 for (i = 0; driver_list; driver_list = driver_list->next)
2810 if (driver_list->on 2869 if (driver_list->on
2811 && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) 2870 && (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
2812 { 2871 {
2819 else 2878 else
2820 { 2879 {
2821 Lisp_Object copy; 2880 Lisp_Object copy;
2822 2881
2823 val = driver_list->driver->list (frame, scratch_font_spec); 2882 val = driver_list->driver->list (frame, scratch_font_spec);
2883 if (NILP (val))
2884 val = null_vector;
2885 else
2886 val = Fvconcat (1, &val);
2824 copy = Fcopy_font_spec (scratch_font_spec); 2887 copy = Fcopy_font_spec (scratch_font_spec);
2825 ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); 2888 ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
2826 XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); 2889 XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache)));
2827 } 2890 }
2828 if (! NILP (val) && need_filtering) 2891 if (ASIZE (val) > 0 && need_filtering)
2829 val = font_delete_unmatched (val, spec, size); 2892 val = font_delete_unmatched (val, spec, size);
2830 if (! NILP (val)) 2893 if (ASIZE (val) > 0)
2831 vec[i++] = val; 2894 list = Fcons (val, list);
2832 } 2895 }
2833 2896
2834 val = (i > 0 ? Fvconcat (i, vec) : null_vector); 2897 list = Fnreverse (list);
2835 FONT_ADD_LOG ("list", spec, val); 2898 FONT_ADD_LOG ("list", spec, list);
2836 return (val); 2899 return list;
2837 } 2900 }
2838 2901
2839 2902
2840 /* Return a font entity matching with SPEC on FRAME. ATTRS, if non 2903 /* Return a font entity matching with SPEC on FRAME. ATTRS, if non
2841 nil, is an array of face's attributes, which specifies preferred 2904 nil, is an array of face's attributes, which specifies preferred
3177 } 3240 }
3178 } 3241 }
3179 } 3242 }
3180 3243
3181 3244
3182 /* Selecte a font from ENTITIES that supports C and matches best with 3245 /* Selecte a font from ENTITIES (list of font-entity vectors) that
3183 ATTRS and PIXEL_SIZE. */ 3246 supports C and matches best with ATTRS and PIXEL_SIZE. */
3184 3247
3185 static Lisp_Object 3248 static Lisp_Object
3186 font_select_entity (frame, entities, attrs, pixel_size, c) 3249 font_select_entity (frame, entities, attrs, pixel_size, c)
3187 Lisp_Object frame, entities, *attrs; 3250 Lisp_Object frame, entities, *attrs;
3188 int pixel_size, c; 3251 int pixel_size, c;
3189 { 3252 {
3190 Lisp_Object font_entity; 3253 Lisp_Object font_entity;
3191 Lisp_Object prefer; 3254 Lisp_Object prefer;
3192 Lisp_Object props[FONT_REGISTRY_INDEX + 1] ;
3193 int result, i; 3255 int result, i;
3194 FRAME_PTR f = XFRAME (frame); 3256 FRAME_PTR f = XFRAME (frame);
3195 3257
3196 if (ASIZE (entities) == 1) 3258 if (NILP (XCDR (entities))
3197 { 3259 && ASIZE (XCAR (entities)) == 1)
3198 font_entity = AREF (entities, 0); 3260 {
3261 font_entity = AREF (XCAR (entities), 0);
3199 if (c < 0 3262 if (c < 0
3200 || (result = font_has_char (f, font_entity, c)) > 0) 3263 || (result = font_has_char (f, font_entity, c)) > 0)
3201 return font_entity; 3264 return font_entity;
3202 return Qnil; 3265 return Qnil;
3203 } 3266 }
3235 Lisp_Object *attrs; 3298 Lisp_Object *attrs;
3236 Lisp_Object spec; 3299 Lisp_Object spec;
3237 int c; 3300 int c;
3238 { 3301 {
3239 Lisp_Object work; 3302 Lisp_Object work;
3240 Lisp_Object frame, entities, val, props[FONT_REGISTRY_INDEX + 1] ; 3303 Lisp_Object frame, entities, val;
3241 Lisp_Object size, foundry[3], *family, registry[3], adstyle[3]; 3304 Lisp_Object size, foundry[3], *family, registry[3], adstyle[3];
3242 int pixel_size; 3305 int pixel_size;
3243 int i, j, k, l, result; 3306 int i, j, k, l;
3244 3307
3245 registry[0] = AREF (spec, FONT_REGISTRY_INDEX); 3308 registry[0] = AREF (spec, FONT_REGISTRY_INDEX);
3246 if (NILP (registry[0])) 3309 if (NILP (registry[0]))
3247 { 3310 {
3248 registry[0] = DEFAULT_ENCODING; 3311 registry[0] = DEFAULT_ENCODING;
3257 struct charset *encoding, *repertory; 3320 struct charset *encoding, *repertory;
3258 3321
3259 if (font_registry_charsets (AREF (spec, FONT_REGISTRY_INDEX), 3322 if (font_registry_charsets (AREF (spec, FONT_REGISTRY_INDEX),
3260 &encoding, &repertory) < 0) 3323 &encoding, &repertory) < 0)
3261 return Qnil; 3324 return Qnil;
3262 if (repertory) 3325 if (repertory
3263 { 3326 && ENCODE_CHAR (repertory, c) == CHARSET_INVALID_CODE (repertory))
3264 if (ENCODE_CHAR (repertory, c) == CHARSET_INVALID_CODE (repertory)) 3327 return Qnil;
3265 return Qnil;
3266 /* Any font of this registry support C. So, let's
3267 suppress the further checking. */
3268 c = -1;
3269 }
3270 else if (c > encoding->max_char) 3328 else if (c > encoding->max_char)
3271 return Qnil; 3329 return Qnil;
3272 } 3330 }
3273 3331
3274 work = Fcopy_font_spec (spec); 3332 work = Fcopy_font_spec (spec);
3370 ASET (work, FONT_REGISTRY_INDEX, registry[k]); 3428 ASET (work, FONT_REGISTRY_INDEX, registry[k]);
3371 for (l = 0; SYMBOLP (adstyle[l]); l++) 3429 for (l = 0; SYMBOLP (adstyle[l]); l++)
3372 { 3430 {
3373 ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]); 3431 ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]);
3374 entities = font_list_entities (frame, work); 3432 entities = font_list_entities (frame, work);
3375 if (ASIZE (entities) > 0) 3433 if (! NILP (entities))
3376 { 3434 {
3377 val = font_select_entity (frame, entities, 3435 val = font_select_entity (frame, entities,
3378 attrs, pixel_size, c); 3436 attrs, pixel_size, c);
3379 if (! NILP (val)) 3437 if (! NILP (val))
3380 return val; 3438 return val;
4234 control the order of the returned list. Fonts are sorted by 4292 control the order of the returned list. Fonts are sorted by
4235 how close they are to PREFER. */) 4293 how close they are to PREFER. */)
4236 (font_spec, frame, num, prefer) 4294 (font_spec, frame, num, prefer)
4237 Lisp_Object font_spec, frame, num, prefer; 4295 Lisp_Object font_spec, frame, num, prefer;
4238 { 4296 {
4239 Lisp_Object vec, list, tail; 4297 Lisp_Object vec, list;
4240 int n = 0, i, len; 4298 int n = 0;
4241 4299
4242 if (NILP (frame)) 4300 if (NILP (frame))
4243 frame = selected_frame; 4301 frame = selected_frame;
4244 CHECK_LIVE_FRAME (frame); 4302 CHECK_LIVE_FRAME (frame);
4245 CHECK_FONT_SPEC (font_spec); 4303 CHECK_FONT_SPEC (font_spec);
4251 return Qnil; 4309 return Qnil;
4252 } 4310 }
4253 if (! NILP (prefer)) 4311 if (! NILP (prefer))
4254 CHECK_FONT_SPEC (prefer); 4312 CHECK_FONT_SPEC (prefer);
4255 4313
4256 vec = font_list_entities (frame, font_spec); 4314 list = font_list_entities (frame, font_spec);
4257 len = ASIZE (vec); 4315 if (NILP (list))
4258 if (len == 0)
4259 return Qnil; 4316 return Qnil;
4260 if (len == 1) 4317 if (NILP (XCDR (list))
4261 return Fcons (AREF (vec, 0), Qnil); 4318 && ASIZE (XCAR (list)) == 1)
4319 return Fcons (AREF (XCAR (list), 0), Qnil);
4262 4320
4263 if (! NILP (prefer)) 4321 if (! NILP (prefer))
4264 vec = font_sort_entities (vec, prefer, frame, 0); 4322 vec = font_sort_entities (list, prefer, frame, 0);
4265 4323 else
4266 list = tail = Fcons (AREF (vec, 0), Qnil); 4324 vec = font_vconcat_entity_vectors (list);
4267 if (n == 0 || n > len) 4325 if (n == 0 || n >= ASIZE (vec))
4268 n = len; 4326 {
4269 for (i = 1; i < n; i++) 4327 Lisp_Object args[2];
4270 { 4328
4271 Lisp_Object val = Fcons (AREF (vec, i), Qnil); 4329 args[0] = vec;
4272 4330 args[1] = Qnil;
4273 XSETCDR (tail, val); 4331 list = Fappend (2, args);
4274 tail = val; 4332 }
4333 else
4334 {
4335 for (list = Qnil, n--; n >= 0; n--)
4336 list = Fcons (AREF (vec, n), list);
4275 } 4337 }
4276 return list; 4338 return list;
4277 } 4339 }
4278 4340
4279 DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0, 4341 DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0,
5057 concat2 (equalstr, 5119 concat2 (equalstr,
5058 SYMBOL_NAME (XCAR (XCDR (elt))))); 5120 SYMBOL_NAME (XCAR (XCDR (elt)))));
5059 } 5121 }
5060 arg = val; 5122 arg = val;
5061 } 5123 }
5124
5125 if (CONSP (result)
5126 && VECTORP (XCAR (result))
5127 && ASIZE (XCAR (result)) > 0
5128 && FONTP (AREF (XCAR (result), 0)))
5129 result = font_vconcat_entity_vectors (result);
5062 if (FONTP (result)) 5130 if (FONTP (result))
5063 { 5131 {
5064 val = Ffont_xlfd_name (result, Qt); 5132 val = Ffont_xlfd_name (result, Qt);
5065 if (! FONT_SPEC_P (result)) 5133 if (! FONT_SPEC_P (result))
5066 val = concat3 (SYMBOL_NAME (AREF (result, FONT_TYPE_INDEX)), 5134 val = concat3 (SYMBOL_NAME (AREF (result, FONT_TYPE_INDEX)),