1 |
/* xfaces.c -- "Face" primitives. |
/* xfaces.c -- "Face" primitives. |
2 |
Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002 |
Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003 |
3 |
Free Software Foundation. |
Free Software Foundation. |
4 |
|
|
5 |
This file is part of GNU Emacs. |
This file is part of GNU Emacs. |
290 |
/* Make a copy of the contents of Lisp string S on the stack using |
/* Make a copy of the contents of Lisp string S on the stack using |
291 |
alloca. Value is a pointer to the copy. */ |
alloca. Value is a pointer to the copy. */ |
292 |
|
|
293 |
#define LSTRDUPA(S) STRDUPA (XSTRING ((S))->data) |
#define LSTRDUPA(S) STRDUPA (SDATA ((S))) |
294 |
|
|
295 |
/* Size of hash table of realized faces in face caches (should be a |
/* Size of hash table of realized faces in face caches (should be a |
296 |
prime number). */ |
prime number). */ |
297 |
|
|
298 |
#define FACE_CACHE_BUCKETS_SIZE 1001 |
#define FACE_CACHE_BUCKETS_SIZE 1001 |
299 |
|
|
|
/* A definition of XColor for non-X frames. */ |
|
|
|
|
|
#ifndef HAVE_X_WINDOWS |
|
|
|
|
|
typedef struct |
|
|
{ |
|
|
unsigned long pixel; |
|
|
unsigned short red, green, blue; |
|
|
char flags; |
|
|
char pad; |
|
|
} |
|
|
XColor; |
|
|
|
|
|
#endif /* not HAVE_X_WINDOWS */ |
|
|
|
|
300 |
/* Keyword symbols used for face attribute names. */ |
/* Keyword symbols used for face attribute names. */ |
301 |
|
|
302 |
Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline; |
Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline; |
337 |
|
|
338 |
Lisp_Object Qface_alias; |
Lisp_Object Qface_alias; |
339 |
|
|
|
/* Names of frame parameters related to faces. */ |
|
|
|
|
|
extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; |
|
|
extern Lisp_Object Qborder_color, Qcursor_color, Qmouse_color; |
|
|
|
|
340 |
/* Default stipple pattern used on monochrome displays. This stipple |
/* Default stipple pattern used on monochrome displays. This stipple |
341 |
pattern is used on monochrome displays instead of shades of gray |
pattern is used on monochrome displays instead of shades of gray |
342 |
for a face background color. See `set-face-stipple' for possible |
for a face background color. See `set-face-stipple' for possible |
464 |
static void map_tty_color P_ ((struct frame *, struct face *, |
static void map_tty_color P_ ((struct frame *, struct face *, |
465 |
enum lface_attribute_index, int *)); |
enum lface_attribute_index, int *)); |
466 |
static Lisp_Object resolve_face_name P_ ((Lisp_Object)); |
static Lisp_Object resolve_face_name P_ ((Lisp_Object)); |
467 |
static int may_use_scalable_font_p P_ ((char *)); |
static int may_use_scalable_font_p P_ ((const char *)); |
468 |
static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); |
static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); |
469 |
static int better_font_p P_ ((int *, struct font_name *, struct font_name *, |
static int better_font_p P_ ((int *, struct font_name *, struct font_name *, |
470 |
int, int)); |
int, int)); |
471 |
static int x_face_list_fonts P_ ((struct frame *, char *, |
static int x_face_list_fonts P_ ((struct frame *, char *, |
472 |
struct font_name *, int, int)); |
struct font_name **, int, int)); |
473 |
static int font_scalable_p P_ ((struct font_name *)); |
static int font_scalable_p P_ ((struct font_name *)); |
474 |
static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int)); |
static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int)); |
475 |
static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *)); |
static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *)); |
489 |
Lisp_Object, struct font_name **)); |
Lisp_Object, struct font_name **)); |
490 |
static int font_list P_ ((struct frame *, Lisp_Object, Lisp_Object, |
static int font_list P_ ((struct frame *, Lisp_Object, Lisp_Object, |
491 |
Lisp_Object, struct font_name **)); |
Lisp_Object, struct font_name **)); |
492 |
static int try_font_list P_ ((struct frame *, Lisp_Object *, |
static int try_font_list P_ ((struct frame *, Lisp_Object *, |
493 |
Lisp_Object, Lisp_Object, struct font_name **)); |
Lisp_Object, Lisp_Object, struct font_name **, |
494 |
|
int)); |
495 |
static int try_alternative_families P_ ((struct frame *f, Lisp_Object, |
static int try_alternative_families P_ ((struct frame *f, Lisp_Object, |
496 |
Lisp_Object, struct font_name **)); |
Lisp_Object, struct font_name **)); |
497 |
static int cmp_font_names P_ ((const void *, const void *)); |
static int cmp_font_names P_ ((const void *, const void *)); |
517 |
static int face_numeric_slant P_ ((Lisp_Object)); |
static int face_numeric_slant P_ ((Lisp_Object)); |
518 |
static int face_numeric_swidth P_ ((Lisp_Object)); |
static int face_numeric_swidth P_ ((Lisp_Object)); |
519 |
static int face_fontset P_ ((Lisp_Object *)); |
static int face_fontset P_ ((Lisp_Object *)); |
520 |
static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int)); |
static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int, int*)); |
521 |
static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, Lisp_Object)); |
static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, Lisp_Object)); |
522 |
static void merge_face_inheritance P_ ((struct frame *f, Lisp_Object, |
static void merge_face_inheritance P_ ((struct frame *f, Lisp_Object, |
523 |
Lisp_Object *, Lisp_Object)); |
Lisp_Object *, Lisp_Object)); |
529 |
static struct face *make_realized_face P_ ((Lisp_Object *)); |
static struct face *make_realized_face P_ ((Lisp_Object *)); |
530 |
static void free_realized_faces P_ ((struct face_cache *)); |
static void free_realized_faces P_ ((struct face_cache *)); |
531 |
static char *best_matching_font P_ ((struct frame *, Lisp_Object *, |
static char *best_matching_font P_ ((struct frame *, Lisp_Object *, |
532 |
struct font_name *, int, int)); |
struct font_name *, int, int, int *)); |
533 |
static void cache_face P_ ((struct face_cache *, struct face *, unsigned)); |
static void cache_face P_ ((struct face_cache *, struct face *, unsigned)); |
534 |
static void uncache_face P_ ((struct face_cache *, struct face *)); |
static void uncache_face P_ ((struct face_cache *, struct face *)); |
535 |
static int xlfd_numeric_slant P_ ((struct font_name *)); |
static int xlfd_numeric_slant P_ ((struct font_name *)); |
805 |
|
|
806 |
int |
int |
807 |
xstricmp (s1, s2) |
xstricmp (s1, s2) |
808 |
unsigned char *s1, *s2; |
const unsigned char *s1, *s2; |
809 |
{ |
{ |
810 |
while (*s1 && *s2) |
while (*s1 && *s2) |
811 |
{ |
{ |
899 |
#ifdef WINDOWSNT |
#ifdef WINDOWSNT |
900 |
if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f)) |
if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f)) |
901 |
#endif |
#endif |
902 |
|
#ifdef MAC_OS |
903 |
|
if (!FRAME_MAC_P (f) || FRAME_MAC_WINDOW (f)) |
904 |
|
#endif |
905 |
if (!realize_basic_faces (f)) |
if (!realize_basic_faces (f)) |
906 |
abort (); |
abort (); |
907 |
} |
} |
969 |
|| ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) |
|| ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) |
970 |
{ |
{ |
971 |
struct x_display_info *dpyinfo; |
struct x_display_info *dpyinfo; |
972 |
|
|
973 |
/* Fonts are common for frames on one display, i.e. on |
/* Fonts are common for frames on one display, i.e. on |
974 |
one X screen. */ |
one X screen. */ |
975 |
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) |
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) |
976 |
if (dpyinfo->n_fonts > CLEAR_FONT_TABLE_NFONTS) |
if (dpyinfo->n_fonts > CLEAR_FONT_TABLE_NFONTS) |
977 |
clear_font_table (dpyinfo); |
clear_font_table (dpyinfo); |
978 |
|
|
979 |
/* From time to time see if we can unload some fonts. This also |
/* From time to time see if we can unload some fonts. This also |
980 |
frees all realized faces on all frames. Fonts needed by |
frees all realized faces on all frames. Fonts needed by |
981 |
faces will be loaded again when faces are realized again. */ |
faces will be loaded again when faces are realized again. */ |
1127 |
{ |
{ |
1128 |
int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1) |
int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1) |
1129 |
/ BITS_PER_CHAR); |
/ BITS_PER_CHAR); |
1130 |
if (STRING_BYTES (XSTRING (data)) >= bytes_per_row * XINT (height)) |
if (SBYTES (data) >= bytes_per_row * XINT (height)) |
1131 |
pixmap_p = 1; |
pixmap_p = 1; |
1132 |
} |
} |
1133 |
} |
} |
1171 |
h = XINT (Fcar (Fcdr (name))); |
h = XINT (Fcar (Fcdr (name))); |
1172 |
bits = Fcar (Fcdr (Fcdr (name))); |
bits = Fcar (Fcdr (Fcdr (name))); |
1173 |
|
|
1174 |
bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data, |
bitmap_id = x_create_bitmap_from_data (f, SDATA (bits), |
1175 |
w, h); |
w, h); |
1176 |
} |
} |
1177 |
else |
else |
1252 |
{ |
{ |
1253 |
struct font_info *font_info = NULL; |
struct font_info *font_info = NULL; |
1254 |
char *font_name; |
char *font_name; |
1255 |
|
int needs_overstrike; |
1256 |
|
|
1257 |
face->font_info_id = -1; |
face->font_info_id = -1; |
1258 |
face->font = NULL; |
face->font = NULL; |
1259 |
|
|
1260 |
font_name = choose_face_font (f, face->lface, face->fontset, c); |
font_name = choose_face_font (f, face->lface, face->fontset, c, |
1261 |
|
&needs_overstrike); |
1262 |
if (!font_name) |
if (!font_name) |
1263 |
return; |
return; |
1264 |
|
|
1271 |
face->font_info_id = font_info->font_idx; |
face->font_info_id = font_info->font_idx; |
1272 |
face->font = font_info->font; |
face->font = font_info->font; |
1273 |
face->font_name = font_info->full_name; |
face->font_name = font_info->full_name; |
1274 |
|
face->overstrike = needs_overstrike; |
1275 |
if (face->gc) |
if (face->gc) |
1276 |
{ |
{ |
1277 |
x_free_gc (f, face->gc); |
x_free_gc (f, face->gc); |
1396 |
int status = 1; |
int status = 1; |
1397 |
|
|
1398 |
/* Defaults. */ |
/* Defaults. */ |
1399 |
color_def->pixel = FACE_TTY_DEFAULT_COLOR; |
color_def->pixel = FACE_TTY_DEFAULT_COLOR; |
1400 |
color_def->red = 0; |
color_def->red = 0; |
1401 |
color_def->blue = 0; |
color_def->blue = 0; |
1402 |
color_def->green = 0; |
color_def->green = 0; |
1553 |
CHECK_FRAME (frame); |
CHECK_FRAME (frame); |
1554 |
CHECK_STRING (color); |
CHECK_STRING (color); |
1555 |
f = XFRAME (frame); |
f = XFRAME (frame); |
1556 |
return face_color_gray_p (f, XSTRING (color)->data) ? Qt : Qnil; |
return face_color_gray_p (f, SDATA (color)) ? Qt : Qnil; |
1557 |
} |
} |
1558 |
|
|
1559 |
|
|
1560 |
DEFUN ("color-supported-p", Fcolor_supported_p, |
DEFUN ("color-supported-p", Fcolor_supported_p, |
1561 |
Scolor_supported_p, 2, 3, 0, |
Scolor_supported_p, 1, 3, 0, |
1562 |
doc: /* Return non-nil if COLOR can be displayed on FRAME. |
doc: /* Return non-nil if COLOR can be displayed on FRAME. |
1563 |
BACKGROUND-P non-nil means COLOR is used as a background. |
BACKGROUND-P non-nil means COLOR is used as a background. |
1564 |
If FRAME is nil or omitted, use the selected frame. |
If FRAME is nil or omitted, use the selected frame. |
1571 |
CHECK_FRAME (frame); |
CHECK_FRAME (frame); |
1572 |
CHECK_STRING (color); |
CHECK_STRING (color); |
1573 |
f = XFRAME (frame); |
f = XFRAME (frame); |
1574 |
if (face_color_supported_p (f, XSTRING (color)->data, !NILP (background_p))) |
if (face_color_supported_p (f, SDATA (color), !NILP (background_p))) |
1575 |
return Qt; |
return Qt; |
1576 |
return Qnil; |
return Qnil; |
1577 |
} |
} |
1605 |
|
|
1606 |
/* if the color map is full, defined_color will return a best match |
/* if the color map is full, defined_color will return a best match |
1607 |
to the values in an existing cell. */ |
to the values in an existing cell. */ |
1608 |
if (!defined_color (f, XSTRING (name)->data, &color, 1)) |
if (!defined_color (f, SDATA (name), &color, 1)) |
1609 |
{ |
{ |
1610 |
add_to_log ("Unable to load color \"%s\"", name, Qnil); |
add_to_log ("Unable to load color \"%s\"", name, Qnil); |
1611 |
|
|
1685 |
face_color_supported_p is smart enough to know that grays are |
face_color_supported_p is smart enough to know that grays are |
1686 |
"supported" as background because we are supposed to use stipple |
"supported" as background because we are supposed to use stipple |
1687 |
for them. */ |
for them. */ |
1688 |
if (!face_color_supported_p (f, XSTRING (bg)->data, 0) |
if (!face_color_supported_p (f, SDATA (bg), 0) |
1689 |
&& !NILP (Fbitmap_spec_p (Vface_default_stipple))) |
&& !NILP (Fbitmap_spec_p (Vface_default_stipple))) |
1690 |
{ |
{ |
1691 |
x_destroy_bitmap (f, face->stipple); |
x_destroy_bitmap (f, face->stipple); |
2233 |
} |
} |
2234 |
else |
else |
2235 |
pixel = atoi (pixel_field); |
pixel = atoi (pixel_field); |
2236 |
|
|
2237 |
if (pixel == 0) |
if (pixel == 0) |
2238 |
real_pt = 0; |
real_pt = 0; |
2239 |
else |
else |
2301 |
{ |
{ |
2302 |
char *start, *end; |
char *start, *end; |
2303 |
int j; |
int j; |
2304 |
|
|
2305 |
for (++p; *p && *p != ']'; ++p) |
for (++p; *p && *p != ']'; ++p) |
2306 |
if (*p == '~') |
if (*p == '~') |
2307 |
*p = '-'; |
*p = '-'; |
2430 |
fonts that we can't parse. Value is the number of fonts found. */ |
fonts that we can't parse. Value is the number of fonts found. */ |
2431 |
|
|
2432 |
static int |
static int |
2433 |
x_face_list_fonts (f, pattern, fonts, nfonts, try_alternatives_p) |
x_face_list_fonts (f, pattern, pfonts, nfonts, try_alternatives_p) |
2434 |
struct frame *f; |
struct frame *f; |
2435 |
char *pattern; |
char *pattern; |
2436 |
struct font_name *fonts; |
struct font_name **pfonts; |
2437 |
int nfonts, try_alternatives_p; |
int nfonts, try_alternatives_p; |
2438 |
{ |
{ |
2439 |
int n, nignored; |
int n, nignored; |
2442 |
better to do it the other way around. */ |
better to do it the other way around. */ |
2443 |
Lisp_Object lfonts; |
Lisp_Object lfonts; |
2444 |
Lisp_Object lpattern, tem; |
Lisp_Object lpattern, tem; |
2445 |
|
struct font_name *fonts = 0; |
2446 |
|
int num_fonts = nfonts; |
2447 |
|
|
2448 |
|
*pfonts = 0; |
2449 |
lpattern = build_string (pattern); |
lpattern = build_string (pattern); |
2450 |
|
|
2451 |
/* Get the list of fonts matching PATTERN. */ |
/* Get the list of fonts matching PATTERN. */ |
2457 |
lfonts = x_list_fonts (f, lpattern, -1, nfonts); |
lfonts = x_list_fonts (f, lpattern, -1, nfonts); |
2458 |
#endif |
#endif |
2459 |
|
|
2460 |
|
if (nfonts < 0 && CONSP (lfonts)) |
2461 |
|
num_fonts = XFASTINT (Flength (lfonts)); |
2462 |
|
|
2463 |
/* Make a copy of the font names we got from X, and |
/* Make a copy of the font names we got from X, and |
2464 |
split them into fields. */ |
split them into fields. */ |
2465 |
n = nignored = 0; |
n = nignored = 0; |
2466 |
for (tem = lfonts; CONSP (tem) && n < nfonts; tem = XCDR (tem)) |
for (tem = lfonts; CONSP (tem) && n < num_fonts; tem = XCDR (tem)) |
2467 |
{ |
{ |
2468 |
Lisp_Object elt, tail; |
Lisp_Object elt, tail; |
2469 |
char *name = XSTRING (XCAR (tem))->data; |
const char *name = SDATA (XCAR (tem)); |
2470 |
|
|
2471 |
/* Ignore fonts matching a pattern from face-ignored-fonts. */ |
/* Ignore fonts matching a pattern from face-ignored-fonts. */ |
2472 |
for (tail = Vface_ignored_fonts; CONSP (tail); tail = XCDR (tail)) |
for (tail = Vface_ignored_fonts; CONSP (tail); tail = XCDR (tail)) |
2482 |
continue; |
continue; |
2483 |
} |
} |
2484 |
|
|
2485 |
|
if (! fonts) |
2486 |
|
{ |
2487 |
|
*pfonts = (struct font_name *) xmalloc (num_fonts * sizeof **pfonts); |
2488 |
|
fonts = *pfonts; |
2489 |
|
} |
2490 |
|
|
2491 |
/* Make a copy of the font name. */ |
/* Make a copy of the font name. */ |
2492 |
fonts[n].name = xstrdup (name); |
fonts[n].name = xstrdup (name); |
2493 |
|
|
2511 |
{ |
{ |
2512 |
Lisp_Object list = Valternate_fontname_alist; |
Lisp_Object list = Valternate_fontname_alist; |
2513 |
|
|
2514 |
|
if (*pfonts) |
2515 |
|
{ |
2516 |
|
xfree (*pfonts); |
2517 |
|
*pfonts = 0; |
2518 |
|
} |
2519 |
|
|
2520 |
while (CONSP (list)) |
while (CONSP (list)) |
2521 |
{ |
{ |
2522 |
Lisp_Object entry = XCAR (list); |
Lisp_Object entry = XCAR (list); |
2523 |
if (CONSP (entry) |
if (CONSP (entry) |
2524 |
&& STRINGP (XCAR (entry)) |
&& STRINGP (XCAR (entry)) |
2525 |
&& strcmp (XSTRING (XCAR (entry))->data, pattern) == 0) |
&& strcmp (SDATA (XCAR (entry)), pattern) == 0) |
2526 |
break; |
break; |
2527 |
list = XCDR (list); |
list = XCDR (list); |
2528 |
} |
} |
2538 |
STRINGP (name)) |
STRINGP (name)) |
2539 |
/* Ignore patterns equal to PATTERN because we tried that |
/* Ignore patterns equal to PATTERN because we tried that |
2540 |
already with no success. */ |
already with no success. */ |
2541 |
&& (strcmp (XSTRING (name)->data, pattern) == 0 |
&& (strcmp (SDATA (name), pattern) == 0 |
2542 |
|| (n = x_face_list_fonts (f, XSTRING (name)->data, |
|| (n = x_face_list_fonts (f, SDATA (name), |
2543 |
fonts, nfonts, 0), |
pfonts, nfonts, 0), |
2544 |
n == 0))) |
n == 0))) |
2545 |
patterns = XCDR (patterns); |
patterns = XCDR (patterns); |
2546 |
} |
} |
2569 |
|
|
2570 |
/* Get the list of fonts matching pattern. 100 should suffice. */ |
/* Get the list of fonts matching pattern. 100 should suffice. */ |
2571 |
nfonts = DEFAULT_FONT_LIST_LIMIT; |
nfonts = DEFAULT_FONT_LIST_LIMIT; |
2572 |
if (INTEGERP (Vfont_list_limit) && XINT (Vfont_list_limit) > 0) |
if (INTEGERP (Vfont_list_limit)) |
2573 |
nfonts = XFASTINT (Vfont_list_limit); |
nfonts = XINT (Vfont_list_limit); |
2574 |
|
|
2575 |
*fonts = (struct font_name *) xmalloc (nfonts * sizeof **fonts); |
*fonts = NULL; |
2576 |
nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1); |
nfonts = x_face_list_fonts (f, pattern, fonts, nfonts, 1); |
2577 |
|
|
2578 |
/* Sort the resulting array and return it in *FONTS. If no |
/* Sort the resulting array and return it in *FONTS. If no |
2579 |
fonts were found, make sure to set *FONTS to null. */ |
fonts were found, make sure to set *FONTS to null. */ |
2580 |
if (nfonts) |
if (nfonts) |
2581 |
sort_fonts (f, *fonts, nfonts, cmpfn); |
sort_fonts (f, *fonts, nfonts, cmpfn); |
2582 |
else |
else if (*fonts) |
2583 |
{ |
{ |
2584 |
xfree (*fonts); |
xfree (*fonts); |
2585 |
*fonts = NULL; |
*fonts = NULL; |
2649 |
|
|
2650 |
if (NILP (pattern)) |
if (NILP (pattern)) |
2651 |
{ |
{ |
2652 |
family_str = (NILP (family) ? "*" : (char *) XSTRING (family)->data); |
family_str = (NILP (family) ? "*" : (char *) SDATA (family)); |
2653 |
registry_str = (NILP (registry) ? "*" : (char *) XSTRING (registry)->data); |
registry_str = (NILP (registry) ? "*" : (char *) SDATA (registry)); |
2654 |
|
|
2655 |
pattern_str = (char *) alloca (strlen (family_str) |
pattern_str = (char *) alloca (strlen (family_str) |
2656 |
+ strlen (registry_str) |
+ strlen (registry_str) |
2668 |
} |
} |
2669 |
} |
} |
2670 |
else |
else |
2671 |
pattern_str = (char *) XSTRING (pattern)->data; |
pattern_str = (char *) SDATA (pattern); |
2672 |
|
|
2673 |
return sorted_font_list (f, pattern_str, cmp_font_names, fonts); |
return sorted_font_list (f, pattern_str, cmp_font_names, fonts); |
2674 |
} |
} |
2702 |
|
|
2703 |
If REGISTRY is non-nil, return fonts with that registry and the |
If REGISTRY is non-nil, return fonts with that registry and the |
2704 |
alternative registries from Vface_alternative_font_registry_alist. |
alternative registries from Vface_alternative_font_registry_alist. |
2705 |
|
|
2706 |
If REGISTRY is nil return fonts of any registry. |
If REGISTRY is nil return fonts of any registry. |
2707 |
|
|
2708 |
Set *FONTS to a vector of font_name structures allocated from the |
Set *FONTS to a vector of font_name structures allocated from the |
2716 |
struct font_name **fonts; |
struct font_name **fonts; |
2717 |
{ |
{ |
2718 |
int nfonts = font_list_1 (f, pattern, family, registry, fonts); |
int nfonts = font_list_1 (f, pattern, family, registry, fonts); |
2719 |
|
|
2720 |
if (!NILP (registry) |
if (!NILP (registry) |
2721 |
&& CONSP (Vface_alternative_font_registry_alist)) |
&& CONSP (Vface_alternative_font_registry_alist)) |
2722 |
{ |
{ |
2846 |
struct font_name *fonts; |
struct font_name *fonts; |
2847 |
Lisp_Object result; |
Lisp_Object result; |
2848 |
struct gcpro gcpro1; |
struct gcpro gcpro1; |
2849 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
|
int limit; |
|
2850 |
|
|
2851 |
/* Let's consider all fonts. Increase the limit for matching |
/* Let's consider all fonts. */ |
2852 |
fonts until we have them all. */ |
specbind (intern ("font-list-limit"), make_number (-1)); |
2853 |
for (limit = 500;;) |
nfonts = font_list (f, Qnil, Qnil, Qnil, &fonts); |
|
{ |
|
|
specbind (intern ("font-list-limit"), make_number (limit)); |
|
|
nfonts = font_list (f, Qnil, Qnil, Qnil, &fonts); |
|
|
|
|
|
if (nfonts == limit) |
|
|
{ |
|
|
free_font_names (fonts, nfonts); |
|
|
limit *= 2; |
|
|
} |
|
|
else |
|
|
break; |
|
|
} |
|
2854 |
|
|
2855 |
result = Qnil; |
result = Qnil; |
2856 |
GCPRO1 (result); |
GCPRO1 (result); |
2897 |
CHECK_STRING (pattern); |
CHECK_STRING (pattern); |
2898 |
|
|
2899 |
if (NILP (maximum)) |
if (NILP (maximum)) |
2900 |
maxnames = 2000; |
maxnames = -1; |
2901 |
else |
else |
2902 |
{ |
{ |
2903 |
CHECK_NATNUM (maximum); |
CHECK_NATNUM (maximum); |
3076 |
Lisp_Object aliased; |
Lisp_Object aliased; |
3077 |
|
|
3078 |
if (STRINGP (face_name)) |
if (STRINGP (face_name)) |
3079 |
face_name = intern (XSTRING (face_name)->data); |
face_name = intern (SDATA (face_name)); |
3080 |
|
|
3081 |
while (SYMBOLP (face_name)) |
while (SYMBOLP (face_name)) |
3082 |
{ |
{ |
3167 |
for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
3168 |
if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX |
if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX |
3169 |
&& i != LFACE_AVGWIDTH_INDEX) |
&& i != LFACE_AVGWIDTH_INDEX) |
3170 |
if (UNSPECIFIEDP (attrs[i])) |
if (UNSPECIFIEDP (attrs[i])) |
3171 |
break; |
break; |
3172 |
|
|
3173 |
return i == LFACE_VECTOR_SIZE; |
return i == LFACE_VECTOR_SIZE; |
3199 |
int pt; |
int pt; |
3200 |
int have_xlfd_p; |
int have_xlfd_p; |
3201 |
int fontset; |
int fontset; |
3202 |
char *font_name = XSTRING (fontname)->data; |
char *font_name = SDATA (fontname); |
3203 |
struct font_info *font_info; |
struct font_info *font_info; |
3204 |
|
|
3205 |
/* If FONTNAME is actually a fontset name, get ASCII font name of it. */ |
/* If FONTNAME is actually a fontset name, get ASCII font name of it. */ |
3206 |
fontset = fs_query_fontset (fontname, 0); |
fontset = fs_query_fontset (fontname, 0); |
3207 |
if (fontset >= 0) |
if (fontset >= 0) |
3208 |
font_name = XSTRING (fontset_ascii (fontset))->data; |
font_name = SDATA (fontset_ascii (fontset)); |
3209 |
|
|
3210 |
/* Check if FONT_NAME is surely available on the system. Usually |
/* Check if FONT_NAME is surely available on the system. Usually |
3211 |
FONT_NAME is already cached for the frame F and FS_LOAD_FONT |
FONT_NAME is already cached for the frame F and FS_LOAD_FONT |
3511 |
add_to_log ("Invalid face color", color_name, Qnil); |
add_to_log ("Invalid face color", color_name, Qnil); |
3512 |
} |
} |
3513 |
else if (SYMBOLP (first) |
else if (SYMBOLP (first) |
3514 |
&& *XSTRING (SYMBOL_NAME (first))->data == ':') |
&& *SDATA (SYMBOL_NAME (first)) == ':') |
3515 |
{ |
{ |
3516 |
/* Assume this is the property list form. */ |
/* Assume this is the property list form. */ |
3517 |
while (CONSP (prop) && CONSP (XCDR (prop))) |
while (CONSP (prop) && CONSP (XCDR (prop))) |
3893 |
if (!UNSPECIFIEDP (value)) |
if (!UNSPECIFIEDP (value)) |
3894 |
{ |
{ |
3895 |
CHECK_STRING (value); |
CHECK_STRING (value); |
3896 |
if (XSTRING (value)->size == 0) |
if (SCHARS (value) == 0) |
3897 |
signal_error ("Invalid face family", value); |
signal_error ("Invalid face family", value); |
3898 |
} |
} |
3899 |
old_value = LFACE_FAMILY (lface); |
old_value = LFACE_FAMILY (lface); |
3953 |
&& !EQ (value, Qnil)) |
&& !EQ (value, Qnil)) |
3954 |
/* Underline color. */ |
/* Underline color. */ |
3955 |
|| (STRINGP (value) |
|| (STRINGP (value) |
3956 |
&& XSTRING (value)->size == 0)) |
&& SCHARS (value) == 0)) |
3957 |
signal_error ("Invalid face underline", value); |
signal_error ("Invalid face underline", value); |
3958 |
|
|
3959 |
old_value = LFACE_UNDERLINE (lface); |
old_value = LFACE_UNDERLINE (lface); |
3967 |
&& !EQ (value, Qnil)) |
&& !EQ (value, Qnil)) |
3968 |
/* Overline color. */ |
/* Overline color. */ |
3969 |
|| (STRINGP (value) |
|| (STRINGP (value) |
3970 |
&& XSTRING (value)->size == 0)) |
&& SCHARS (value) == 0)) |
3971 |
signal_error ("Invalid face overline", value); |
signal_error ("Invalid face overline", value); |
3972 |
|
|
3973 |
old_value = LFACE_OVERLINE (lface); |
old_value = LFACE_OVERLINE (lface); |
3981 |
&& !EQ (value, Qnil)) |
&& !EQ (value, Qnil)) |
3982 |
/* Strike-through color. */ |
/* Strike-through color. */ |
3983 |
|| (STRINGP (value) |
|| (STRINGP (value) |
3984 |
&& XSTRING (value)->size == 0)) |
&& SCHARS (value) == 0)) |
3985 |
signal_error ("Invalid face strike-through", value); |
signal_error ("Invalid face strike-through", value); |
3986 |
|
|
3987 |
old_value = LFACE_STRIKE_THROUGH (lface); |
old_value = LFACE_STRIKE_THROUGH (lface); |
4003 |
else if (INTEGERP (value)) |
else if (INTEGERP (value)) |
4004 |
valid_p = XINT (value) != 0; |
valid_p = XINT (value) != 0; |
4005 |
else if (STRINGP (value)) |
else if (STRINGP (value)) |
4006 |
valid_p = XSTRING (value)->size > 0; |
valid_p = SCHARS (value) > 0; |
4007 |
else if (CONSP (value)) |
else if (CONSP (value)) |
4008 |
{ |
{ |
4009 |
Lisp_Object tem; |
Lisp_Object tem; |
4027 |
} |
} |
4028 |
else if (EQ (k, QCcolor)) |
else if (EQ (k, QCcolor)) |
4029 |
{ |
{ |
4030 |
if (!STRINGP (v) || XSTRING (v)->size == 0) |
if (!STRINGP (v) || SCHARS (v) == 0) |
4031 |
break; |
break; |
4032 |
} |
} |
4033 |
else if (EQ (k, QCstyle)) |
else if (EQ (k, QCstyle)) |
4070 |
on the frame (display) whether the color will be valid |
on the frame (display) whether the color will be valid |
4071 |
when the face is realized. */ |
when the face is realized. */ |
4072 |
CHECK_STRING (value); |
CHECK_STRING (value); |
4073 |
if (XSTRING (value)->size == 0) |
if (SCHARS (value) == 0) |
4074 |
signal_error ("Empty foreground color value", value); |
signal_error ("Empty foreground color value", value); |
4075 |
} |
} |
4076 |
old_value = LFACE_FOREGROUND (lface); |
old_value = LFACE_FOREGROUND (lface); |
4084 |
on the frame (display) whether the color will be valid |
on the frame (display) whether the color will be valid |
4085 |
when the face is realized. */ |
when the face is realized. */ |
4086 |
CHECK_STRING (value); |
CHECK_STRING (value); |
4087 |
if (XSTRING (value)->size == 0) |
if (SCHARS (value) == 0) |
4088 |
signal_error ("Empty background color value", value); |
signal_error ("Empty background color value", value); |
4089 |
} |
} |
4090 |
old_value = LFACE_BACKGROUND (lface); |
old_value = LFACE_BACKGROUND (lface); |
4308 |
{ |
{ |
4309 |
Lisp_Object font_name; |
Lisp_Object font_name; |
4310 |
char *font; |
char *font; |
4311 |
|
|
4312 |
if (STRINGP (LFACE_FONT (lface))) |
if (STRINGP (LFACE_FONT (lface))) |
4313 |
font_name = LFACE_FONT (lface); |
font_name = LFACE_FONT (lface); |
4314 |
else |
else |
4316 |
/* Choose a font name that reflects LFACE's attributes and has |
/* Choose a font name that reflects LFACE's attributes and has |
4317 |
the registry and encoding pattern specified in the default |
the registry and encoding pattern specified in the default |
4318 |
fontset (3rd arg: -1) for ASCII characters (4th arg: 0). */ |
fontset (3rd arg: -1) for ASCII characters (4th arg: 0). */ |
4319 |
font = choose_face_font (f, XVECTOR (lface)->contents, -1, 0); |
font = choose_face_font (f, XVECTOR (lface)->contents, -1, 0, 0); |
4320 |
if (!font) |
if (!font) |
4321 |
error ("No font matches the specified attribute"); |
error ("No font matches the specified attribute"); |
4322 |
font_name = build_string (font); |
font_name = build_string (font); |
4323 |
xfree (font); |
xfree (font); |
4324 |
} |
} |
4325 |
|
|
4326 |
Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font_name), Qnil)); |
Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font_name), Qnil)); |
4327 |
} |
} |
4328 |
} |
} |
4434 |
|
|
4435 |
xassert (STRINGP (value)); |
xassert (STRINGP (value)); |
4436 |
|
|
4437 |
if (xstricmp (XSTRING (value)->data, "on") == 0 |
if (xstricmp (SDATA (value), "on") == 0 |
4438 |
|| xstricmp (XSTRING (value)->data, "true") == 0) |
|| xstricmp (SDATA (value), "true") == 0) |
4439 |
result = Qt; |
result = Qt; |
4440 |
else if (xstricmp (XSTRING (value)->data, "off") == 0 |
else if (xstricmp (SDATA (value), "off") == 0 |
4441 |
|| xstricmp (XSTRING (value)->data, "false") == 0) |
|| xstricmp (SDATA (value), "false") == 0) |
4442 |
result = Qnil; |
result = Qnil; |
4443 |
else if (xstricmp (XSTRING (value)->data, "unspecified") == 0) |
else if (xstricmp (SDATA (value), "unspecified") == 0) |
4444 |
result = Qunspecified; |
result = Qunspecified; |
4445 |
else if (signal_p) |
else if (signal_p) |
4446 |
signal_error ("Invalid face attribute value from X resource", value); |
signal_error ("Invalid face attribute value from X resource", value); |
4460 |
CHECK_SYMBOL (attr); |
CHECK_SYMBOL (attr); |
4461 |
CHECK_STRING (value); |
CHECK_STRING (value); |
4462 |
|
|
4463 |
if (xstricmp (XSTRING (value)->data, "unspecified") == 0) |
if (xstricmp (SDATA (value), "unspecified") == 0) |
4464 |
value = Qunspecified; |
value = Qunspecified; |
4465 |
else if (EQ (attr, QCheight)) |
else if (EQ (attr, QCheight)) |
4466 |
{ |
{ |
4471 |
else if (EQ (attr, QCbold) || EQ (attr, QCitalic)) |
else if (EQ (attr, QCbold) || EQ (attr, QCitalic)) |
4472 |
value = face_boolean_x_resource_value (value, 1); |
value = face_boolean_x_resource_value (value, 1); |
4473 |
else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth)) |
else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth)) |
4474 |
value = intern (XSTRING (value)->data); |
value = intern (SDATA (value)); |
4475 |
else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video)) |
else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video)) |
4476 |
value = face_boolean_x_resource_value (value, 1); |
value = face_boolean_x_resource_value (value, 1); |
4477 |
else if (EQ (attr, QCunderline) |
else if (EQ (attr, QCunderline) |
4517 |
char line[512]; |
char line[512]; |
4518 |
Lisp_Object lface = lface_from_face_name (f, Qmenu, 1); |
Lisp_Object lface = lface_from_face_name (f, Qmenu, 1); |
4519 |
struct face *face = FACE_FROM_ID (f, MENU_FACE_ID); |
struct face *face = FACE_FROM_ID (f, MENU_FACE_ID); |
4520 |
char *myname = XSTRING (Vx_resource_name)->data; |
const char *myname = SDATA (Vx_resource_name); |
4521 |
int changed_p = 0; |
int changed_p = 0; |
4522 |
#ifdef USE_MOTIF |
#ifdef USE_MOTIF |
4523 |
const char *popup_path = "popup_menu"; |
const char *popup_path = "popup_menu"; |
4524 |
#else |
#else |
4525 |
const char *popup_path = "menu.popup"; |
const char *popup_path = "menu.popup"; |
4526 |
#endif |
#endif |
4527 |
|
|
4528 |
if (STRINGP (LFACE_FOREGROUND (lface))) |
if (STRINGP (LFACE_FOREGROUND (lface))) |
4529 |
{ |
{ |
4530 |
sprintf (line, "%s.%s*foreground: %s", |
sprintf (line, "%s.%s*foreground: %s", |
4531 |
myname, popup_path, |
myname, popup_path, |
4532 |
XSTRING (LFACE_FOREGROUND (lface))->data); |
SDATA (LFACE_FOREGROUND (lface))); |
4533 |
XrmPutLineResource (&rdb, line); |
XrmPutLineResource (&rdb, line); |
4534 |
sprintf (line, "%s.pane.menubar*foreground: %s", |
sprintf (line, "%s.pane.menubar*foreground: %s", |
4535 |
myname, XSTRING (LFACE_FOREGROUND (lface))->data); |
myname, SDATA (LFACE_FOREGROUND (lface))); |
4536 |
XrmPutLineResource (&rdb, line); |
XrmPutLineResource (&rdb, line); |
4537 |
changed_p = 1; |
changed_p = 1; |
4538 |
} |
} |
4541 |
{ |
{ |
4542 |
sprintf (line, "%s.%s*background: %s", |
sprintf (line, "%s.%s*background: %s", |
4543 |
myname, popup_path, |
myname, popup_path, |
4544 |
XSTRING (LFACE_BACKGROUND (lface))->data); |
SDATA (LFACE_BACKGROUND (lface))); |
4545 |
XrmPutLineResource (&rdb, line); |
XrmPutLineResource (&rdb, line); |
4546 |
sprintf (line, "%s.pane.menubar*background: %s", |
sprintf (line, "%s.pane.menubar*background: %s", |
4547 |
myname, XSTRING (LFACE_BACKGROUND (lface))->data); |
myname, SDATA (LFACE_BACKGROUND (lface))); |
4548 |
XrmPutLineResource (&rdb, line); |
XrmPutLineResource (&rdb, line); |
4549 |
changed_p = 1; |
changed_p = 1; |
4550 |
} |
} |
4551 |
|
|
4552 |
if (face->font_name |
if (face->font_name |
4553 |
&& (!UNSPECIFIEDP (LFACE_FAMILY (lface)) |
&& (!UNSPECIFIEDP (LFACE_FAMILY (lface)) |
4554 |
|| !UNSPECIFIEDP (LFACE_SWIDTH (lface)) |
|| !UNSPECIFIEDP (LFACE_SWIDTH (lface)) |
4579 |
#endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */ |
#endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */ |
4580 |
|
|
4581 |
|
|
4582 |
DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p, |
DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p, |
4583 |
Sface_attribute_relative_p, |
Sface_attribute_relative_p, |
4584 |
2, 2, 0, |
2, 2, 0, |
4585 |
doc: /* Return non-nil if face ATTRIBUTE VALUE is relative. */) |
doc: /* Return non-nil if face ATTRIBUTE VALUE is relative. */) |
4826 |
switch (XTYPE (a)) |
switch (XTYPE (a)) |
4827 |
{ |
{ |
4828 |
case Lisp_String: |
case Lisp_String: |
4829 |
equal_p = ((STRING_BYTES (XSTRING (a)) |
equal_p = ((SBYTES (a) |
4830 |
== STRING_BYTES (XSTRING (b))) |
== SBYTES (b)) |
4831 |
&& bcmp (XSTRING (a)->data, XSTRING (b)->data, |
&& bcmp (SDATA (a), SDATA (b), |
4832 |
STRING_BYTES (XSTRING (a))) == 0); |
SBYTES (a)) == 0); |
4833 |
break; |
break; |
4834 |
|
|
4835 |
case Lisp_Int: |
case Lisp_Int: |
4928 |
hash_string_case_insensitive (string) |
hash_string_case_insensitive (string) |
4929 |
Lisp_Object string; |
Lisp_Object string; |
4930 |
{ |
{ |
4931 |
unsigned char *s; |
const unsigned char *s; |
4932 |
unsigned hash = 0; |
unsigned hash = 0; |
4933 |
xassert (STRINGP (string)); |
xassert (STRINGP (string)); |
4934 |
for (s = XSTRING (string)->data; *s; ++s) |
for (s = SDATA (string); *s; ++s) |
4935 |
hash = (hash << 1) ^ tolower (*s); |
hash = (hash << 1) ^ tolower (*s); |
4936 |
return hash; |
return hash; |
4937 |
} |
} |
4964 |
{ |
{ |
4965 |
xassert (lface_fully_specified_p (lface1) |
xassert (lface_fully_specified_p (lface1) |
4966 |
&& lface_fully_specified_p (lface2)); |
&& lface_fully_specified_p (lface2)); |
4967 |
return (xstricmp (XSTRING (lface1[LFACE_FAMILY_INDEX])->data, |
return (xstricmp (SDATA (lface1[LFACE_FAMILY_INDEX]), |
4968 |
XSTRING (lface2[LFACE_FAMILY_INDEX])->data) == 0 |
SDATA (lface2[LFACE_FAMILY_INDEX])) == 0 |
4969 |
&& EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX]) |
&& EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX]) |
4970 |
&& EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX]) |
&& EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX]) |
4971 |
&& EQ (lface1[LFACE_AVGWIDTH_INDEX], lface2[LFACE_AVGWIDTH_INDEX]) |
&& EQ (lface1[LFACE_AVGWIDTH_INDEX], lface2[LFACE_AVGWIDTH_INDEX]) |
4974 |
&& (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX]) |
&& (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX]) |
4975 |
|| (STRINGP (lface1[LFACE_FONT_INDEX]) |
|| (STRINGP (lface1[LFACE_FONT_INDEX]) |
4976 |
&& STRINGP (lface2[LFACE_FONT_INDEX]) |
&& STRINGP (lface2[LFACE_FONT_INDEX]) |
4977 |
&& xstricmp (XSTRING (lface1[LFACE_FONT_INDEX])->data, |
&& xstricmp (SDATA (lface1[LFACE_FONT_INDEX]), |
4978 |
XSTRING (lface2[LFACE_FONT_INDEX])->data)))); |
SDATA (lface2[LFACE_FONT_INDEX]))))); |
4979 |
} |
} |
4980 |
|
|
4981 |
|
|
5130 |
|
|
5131 |
if ((CONSP (color1) && !parse_rgb_list (color1, &cdef1)) |
if ((CONSP (color1) && !parse_rgb_list (color1, &cdef1)) |
5132 |
|| !STRINGP (color1) |
|| !STRINGP (color1) |
5133 |
|| !defined_color (f, XSTRING (color1)->data, &cdef1, 0)) |
|| !defined_color (f, SDATA (color1), &cdef1, 0)) |
5134 |
signal_error ("Invalid color", color1); |
signal_error ("Invalid color", color1); |
5135 |
if ((CONSP (color2) && !parse_rgb_list (color2, &cdef2)) |
if ((CONSP (color2) && !parse_rgb_list (color2, &cdef2)) |
5136 |
|| !STRINGP (color2) |
|| !STRINGP (color2) |
5137 |
|| !defined_color (f, XSTRING (color2)->data, &cdef2, 0)) |
|| !defined_color (f, SDATA (color2), &cdef2, 0)) |
5138 |
signal_error ("Invalid color", color2); |
signal_error ("Invalid color", color2); |
5139 |
|
|
5140 |
return make_number (color_distance (&cdef1, &cdef2)); |
return make_number (color_distance (&cdef1, &cdef2)); |
5252 |
else if (weight < XLFD_WEIGHT_MEDIUM) |
else if (weight < XLFD_WEIGHT_MEDIUM) |
5253 |
test_caps = TTY_CAP_DIM; |
test_caps = TTY_CAP_DIM; |
5254 |
} |
} |
5255 |
|
|
5256 |
/* underlining */ |
/* underlining */ |
5257 |
val = attrs[LFACE_UNDERLINE_INDEX]; |
val = attrs[LFACE_UNDERLINE_INDEX]; |
5258 |
if (!UNSPECIFIEDP (val) && !NILP (val)) |
if (!UNSPECIFIEDP (val) && !NILP (val)) |
6115 |
|
|
6116 |
static int |
static int |
6117 |
may_use_scalable_font_p (font) |
may_use_scalable_font_p (font) |
6118 |
char *font; |
const char *font; |
6119 |
{ |
{ |
6120 |
if (EQ (Vscalable_fonts_allowed, Qt)) |
if (EQ (Vscalable_fonts_allowed, Qt)) |
6121 |
return 1; |
return 1; |
6143 |
widths if ATTRS specifies such a width. |
widths if ATTRS specifies such a width. |
6144 |
|
|
6145 |
Value is a font name which is allocated from the heap. FONTS is |
Value is a font name which is allocated from the heap. FONTS is |
6146 |
freed by this function. */ |
freed by this function. |
6147 |
|
|
6148 |
|
If NEEDS_OVERSTRIKE is non-zero, a boolean is returned in it to |
6149 |
|
indicate whether the resulting font should be drawn using overstrike |
6150 |
|
to simulate bold-face. */ |
6151 |
|
|
6152 |
static char * |
static char * |
6153 |
best_matching_font (f, attrs, fonts, nfonts, width_ratio) |
best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike) |
6154 |
struct frame *f; |
struct frame *f; |
6155 |
Lisp_Object *attrs; |
Lisp_Object *attrs; |
6156 |
struct font_name *fonts; |
struct font_name *fonts; |
6157 |
int nfonts; |
int nfonts; |
6158 |
int width_ratio; |
int width_ratio; |
6159 |
|
int *needs_overstrike; |
6160 |
{ |
{ |
6161 |
char *font_name; |
char *font_name; |
6162 |
struct font_name *best; |
struct font_name *best; |
6191 |
|
|
6192 |
exact_p = 0; |
exact_p = 0; |
6193 |
|
|
6194 |
|
if (needs_overstrike) |
6195 |
|
*needs_overstrike = 0; |
6196 |
|
|
6197 |
/* Start with the first non-scalable font in the list. */ |
/* Start with the first non-scalable font in the list. */ |
6198 |
for (i = 0; i < nfonts; ++i) |
for (i = 0; i < nfonts; ++i) |
6199 |
if (!font_scalable_p (fonts + i)) |
if (!font_scalable_p (fonts + i)) |
6214 |
if (exact_p) |
if (exact_p) |
6215 |
break; |
break; |
6216 |
} |
} |
|
|
|
6217 |
} |
} |
6218 |
else |
else |
6219 |
best = NULL; |
best = NULL; |
6246 |
&& !better_font_p (specified, best, fonts + i, 0, 0))) |
&& !better_font_p (specified, best, fonts + i, 0, 0))) |
6247 |
best = fonts + i; |
best = fonts + i; |
6248 |
} |
} |
6249 |
|
|
6250 |
|
if (needs_overstrike) |
6251 |
|
{ |
6252 |
|
enum xlfd_weight want_weight = specified[XLFD_WEIGHT]; |
6253 |
|
enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT]; |
6254 |
|
|
6255 |
|
if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight) |
6256 |
|
{ |
6257 |
|
/* We want a bold font, but didn't get one; try to use |
6258 |
|
overstriking instead to simulate bold-face. However, |
6259 |
|
don't overstrike an already-bold fontn unless the |
6260 |
|
desired weight grossly exceeds the available weight. */ |
6261 |
|
if (got_weight > XLFD_WEIGHT_MEDIUM) |
6262 |
|
*needs_overstrike = (got_weight - want_weight) > 2; |
6263 |
|
else |
6264 |
|
*needs_overstrike = 1; |
6265 |
|
} |
6266 |
|
} |
6267 |
} |
} |
6268 |
|
|
6269 |
if (font_scalable_p (best)) |
if (font_scalable_p (best)) |
6286 |
REGISTRY, if a string, specifies a font registry and encoding to |
REGISTRY, if a string, specifies a font registry and encoding to |
6287 |
match. A value of nil means include fonts of any registry and |
match. A value of nil means include fonts of any registry and |
6288 |
encoding. |
encoding. |
6289 |
|
|
6290 |
Return in *FONTS a pointer to a vector of font_name structures for |
Return in *FONTS a pointer to a vector of font_name structures for |
6291 |
the fonts matched. Value is the number of fonts found. */ |
the fonts matched. Value is the number of fonts found. */ |
6292 |
|
|
6314 |
nfonts = font_list (f, Qnil, XCAR (alter), registry, fonts); |
nfonts = font_list (f, Qnil, XCAR (alter), registry, fonts); |
6315 |
} |
} |
6316 |
} |
} |
6317 |
|
|
6318 |
/* Try scalable fonts before giving up. */ |
/* Try all scalable fonts before giving up. */ |
6319 |
if (nfonts == 0 && NILP (Vscalable_fonts_allowed)) |
if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt)) |
6320 |
{ |
{ |
6321 |
int count = BINDING_STACK_SIZE (); |
int count = SPECPDL_INDEX (); |
6322 |
specbind (Qscalable_fonts_allowed, Qt); |
specbind (Qscalable_fonts_allowed, Qt); |
6323 |
nfonts = try_alternative_families (f, family, registry, fonts); |
nfonts = try_alternative_families (f, family, registry, fonts); |
6324 |
unbind_to (count, Qnil); |
unbind_to (count, Qnil); |
6337 |
REGISTRY, if a string, specifies a font registry and encoding to |
REGISTRY, if a string, specifies a font registry and encoding to |
6338 |
match. A value of nil means include fonts of any registry and |
match. A value of nil means include fonts of any registry and |
6339 |
encoding. |
encoding. |
6340 |
|
|
6341 |
|
If PREFER_FACE_FAMILY is nonzero, perfer face's family to FAMILY. |
6342 |
|
Otherwise, prefer FAMILY. |
6343 |
|
|
6344 |
Return in *FONTS a pointer to a vector of font_name structures for |
Return in *FONTS a pointer to a vector of font_name structures for |
6345 |
the fonts matched. Value is the number of fonts found. */ |
the fonts matched. Value is the number of fonts found. */ |
6346 |
|
|
6347 |
static int |
static int |
6348 |
try_font_list (f, attrs, family, registry, fonts) |
try_font_list (f, attrs, family, registry, fonts, prefer_face_family) |
6349 |
struct frame *f; |
struct frame *f; |
6350 |
Lisp_Object *attrs; |
Lisp_Object *attrs; |
6351 |
Lisp_Object family, registry; |
Lisp_Object family, registry; |
6352 |
struct font_name **fonts; |
struct font_name **fonts; |
6353 |
|
int prefer_face_family; |
6354 |
{ |
{ |
6355 |
int nfonts = 0; |
int nfonts = 0; |
6356 |
Lisp_Object face_family = attrs[LFACE_FAMILY_INDEX]; |
Lisp_Object face_family = attrs[LFACE_FAMILY_INDEX]; |
6357 |
|
Lisp_Object try_family; |
6358 |
|
|
6359 |
|
try_family = (prefer_face_family || NILP (family)) ? face_family : family; |
6360 |
|
|
6361 |
|
if (STRINGP (try_family)) |
6362 |
|
nfonts = try_alternative_families (f, try_family, registry, fonts); |
6363 |
|
|
6364 |
|
#ifdef MAC_OS |
6365 |
|
/* When realizing the default face and a font spec does not matched |
6366 |
|
exactly, Emacs looks for ones with the same registry as the |
6367 |
|
default font. On the Mac, this is mac-roman, which does not work |
6368 |
|
if the family is -etl-fixed, e.g. The following widens the |
6369 |
|
choices and fixes that problem. */ |
6370 |
|
if (nfonts == 0 && STRINGP (try_family) && STRINGP (registry) |
6371 |
|
&& xstricmp (SDATA (registry), "mac-roman") == 0) |
6372 |
|
nfonts = try_alternative_families (f, try_family, Qnil, fonts); |
6373 |
|
#endif |
6374 |
|
|
6375 |
if (STRINGP (face_family)) |
if (EQ (try_family, family)) |
6376 |
nfonts = try_alternative_families (f, face_family, registry, fonts); |
family = face_family; |
6377 |
|
|
6378 |
if (nfonts == 0 && !NILP (family)) |
if (nfonts == 0 && STRINGP (family)) |
6379 |
nfonts = try_alternative_families (f, family, registry, fonts); |
nfonts = try_alternative_families (f, family, registry, fonts); |
6380 |
|
|
6381 |
/* Try font family of the default face or "fixed". */ |
/* Try font family of the default face or "fixed". */ |
6388 |
family = build_string ("fixed"); |
family = build_string ("fixed"); |
6389 |
nfonts = font_list (f, Qnil, family, registry, fonts); |
nfonts = font_list (f, Qnil, family, registry, fonts); |
6390 |
} |
} |
6391 |
|
|
6392 |
/* Try any family with the given registry. */ |
/* Try any family with the given registry. */ |
6393 |
if (nfonts == 0) |
if (nfonts == 0) |
6394 |
nfonts = font_list (f, Qnil, Qnil, registry, fonts); |
nfonts = font_list (f, Qnil, Qnil, registry, fonts); |
6421 |
allocated from the heap and must be freed by the caller, or NULL if |
allocated from the heap and must be freed by the caller, or NULL if |
6422 |
we can get no information about the font name of C. It is assured |
we can get no information about the font name of C. It is assured |
6423 |
that we always get some information for a single byte |
that we always get some information for a single byte |
6424 |
character. */ |
character. |
6425 |
|
|
6426 |
|
If NEEDS_OVERSTRIKE is non-zero, a boolean is returned in it to |
6427 |
|
indicate whether the resulting font should be drawn using overstrike |
6428 |
|
to simulate bold-face. */ |
6429 |
|
|
6430 |
static char * |
static char * |
6431 |
choose_face_font (f, attrs, fontset, c) |
choose_face_font (f, attrs, fontset, c, needs_overstrike) |
6432 |
struct frame *f; |
struct frame *f; |
6433 |
Lisp_Object *attrs; |
Lisp_Object *attrs; |
6434 |
int fontset, c; |
int fontset, c; |
6435 |
|
int *needs_overstrike; |
6436 |
{ |
{ |
6437 |
Lisp_Object pattern; |
Lisp_Object pattern; |
6438 |
char *font_name = NULL; |
char *font_name = NULL; |
6439 |
struct font_name *fonts; |
struct font_name *fonts; |
6440 |
int nfonts, width_ratio; |
int nfonts, width_ratio; |
6441 |
|
|
6442 |
|
if (needs_overstrike) |
6443 |
|
*needs_overstrike = 0; |
6444 |
|
|
6445 |
/* Get (foundry and) family name and registry (and encoding) name of |
/* Get (foundry and) family name and registry (and encoding) name of |
6446 |
a font for C. */ |
a font for C. */ |
6447 |
pattern = fontset_font_pattern (f, fontset, c); |
pattern = fontset_font_pattern (f, fontset, c); |
6450 |
xassert (!SINGLE_BYTE_CHAR_P (c)); |
xassert (!SINGLE_BYTE_CHAR_P (c)); |
6451 |
return NULL; |
return NULL; |
6452 |
} |
} |
6453 |
|
|
6454 |
/* If what we got is a name pattern, return it. */ |
/* If what we got is a name pattern, return it. */ |
6455 |
if (STRINGP (pattern)) |
if (STRINGP (pattern)) |
6456 |
return xstrdup (XSTRING (pattern)->data); |
return xstrdup (SDATA (pattern)); |
6457 |
|
|
6458 |
/* Get a list of fonts matching that pattern and choose the |
/* Get a list of fonts matching that pattern and choose the |
6459 |
best match for the specified face attributes from it. */ |
best match for the specified face attributes from it. */ |
6460 |
nfonts = try_font_list (f, attrs, XCAR (pattern), XCDR (pattern), &fonts); |
nfonts = try_font_list (f, attrs, XCAR (pattern), XCDR (pattern), &fonts, |
6461 |
|
(SINGLE_BYTE_CHAR_P (c) |
6462 |
|
|| CHAR_CHARSET (c) == charset_latin_iso8859_1)); |
6463 |
width_ratio = (SINGLE_BYTE_CHAR_P (c) |
width_ratio = (SINGLE_BYTE_CHAR_P (c) |
6464 |
? 1 |
? 1 |
6465 |
: CHARSET_WIDTH (CHAR_CHARSET (c))); |
: CHARSET_WIDTH (CHAR_CHARSET (c))); |
6466 |
font_name = best_matching_font (f, attrs, fonts, nfonts, width_ratio); |
font_name = best_matching_font (f, attrs, fonts, nfonts, width_ratio, |
6467 |
|
needs_overstrike); |
6468 |
return font_name; |
return font_name; |
6469 |
} |
} |
6470 |
|
|
6485 |
struct frame *f; |
struct frame *f; |
6486 |
{ |
{ |
6487 |
int success_p = 0; |
int success_p = 0; |
6488 |
int count = BINDING_STACK_SIZE (); |
int count = SPECPDL_INDEX (); |
6489 |
|
|
6490 |
/* Block input here so that we won't be surprised by an X expose |
/* Block input here so that we won't be surprised by an X expose |
6491 |
event, for instance, without having the faces set up. */ |
event, for instance, without having the faces set up. */ |
6513 |
x_update_menu_appearance (f); |
x_update_menu_appearance (f); |
6514 |
#endif |
#endif |
6515 |
} |
} |
6516 |
|
|
6517 |
success_p = 1; |
success_p = 1; |
6518 |
} |
} |
6519 |
|
|
6792 |
fontset = default_face->fontset; |
fontset = default_face->fontset; |
6793 |
face->fontset = make_fontset_for_ascii_face (f, fontset); |
face->fontset = make_fontset_for_ascii_face (f, fontset); |
6794 |
face->font = NULL; /* to force realize_face to load font */ |
face->font = NULL; /* to force realize_face to load font */ |
|
|
|
|
#ifdef MAC_OS |
|
|
/* Load the font if it is specified in ATTRS. This fixes |
|
|
changing frame font on the Mac. */ |
|
|
if (STRINGP (attrs[LFACE_FONT_INDEX])) |
|
|
{ |
|
|
struct font_info *font_info = |
|
|
FS_LOAD_FONT (f, 0, XSTRING (attrs[LFACE_FONT_INDEX])->data, -1); |
|
|
if (font_info) |
|
|
face->font = font_info->font; |
|
|
} |
|
|
#endif |
|
6795 |
} |
} |
6796 |
|
|
6797 |
/* Load colors, and set remaining attributes. */ |
/* Load colors, and set remaining attributes. */ |
6957 |
pixel = default_pixel = FACE_TTY_DEFAULT_BG_COLOR; |
pixel = default_pixel = FACE_TTY_DEFAULT_BG_COLOR; |
6958 |
default_other_pixel = FACE_TTY_DEFAULT_FG_COLOR; |
default_other_pixel = FACE_TTY_DEFAULT_FG_COLOR; |
6959 |
} |
} |
6960 |
|
|
6961 |
XSETFRAME (frame, f); |
XSETFRAME (frame, f); |
6962 |
color = face->lface[idx]; |
color = face->lface[idx]; |
6963 |
|
|
6964 |
if (STRINGP (color) |
if (STRINGP (color) |
6965 |
&& XSTRING (color)->size |
&& SCHARS (color) |
6966 |
&& CONSP (Vtty_defined_color_alist) |
&& CONSP (Vtty_defined_color_alist) |
6967 |
&& (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)), |
&& (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)), |
6968 |
CONSP (def))) |
CONSP (def))) |
7055 |
/* Map color names to color indices. */ |
/* Map color names to color indices. */ |
7056 |
map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted); |
map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted); |
7057 |
map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted); |
map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted); |
7058 |
|
|
7059 |
/* Swap colors if face is inverse-video. If the colors are taken |
/* Swap colors if face is inverse-video. If the colors are taken |
7060 |
from the frame colors, they are already inverted, since the |
from the frame colors, they are already inverted, since the |
7061 |
frame-creation function calls x-handle-reverse-video. */ |
frame-creation function calls x-handle-reverse-video. */ |
7312 |
Limit is the maximum position up to which to check for property |
Limit is the maximum position up to which to check for property |
7313 |
changes in Fnext_single_property_change. Strings are usually |
changes in Fnext_single_property_change. Strings are usually |
7314 |
short, so set the limit to the end of the string. */ |
short, so set the limit to the end of the string. */ |
7315 |
XSETFASTINT (limit, XSTRING (string)->size); |
XSETFASTINT (limit, SCHARS (string)); |
7316 |
end = Fnext_single_property_change (position, prop_name, string, limit); |
end = Fnext_single_property_change (position, prop_name, string, limit); |
7317 |
if (INTEGERP (end)) |
if (INTEGERP (end)) |
7318 |
*endptr = XFASTINT (end); |
*endptr = XFASTINT (end); |
7380 |
#endif |
#endif |
7381 |
fprintf (stderr, "foreground: 0x%lx (%s)\n", |
fprintf (stderr, "foreground: 0x%lx (%s)\n", |
7382 |
face->foreground, |
face->foreground, |
7383 |
XSTRING (face->lface[LFACE_FOREGROUND_INDEX])->data); |
SDATA (face->lface[LFACE_FOREGROUND_INDEX])); |
7384 |
fprintf (stderr, "background: 0x%lx (%s)\n", |
fprintf (stderr, "background: 0x%lx (%s)\n", |
7385 |
face->background, |
face->background, |
7386 |
XSTRING (face->lface[LFACE_BACKGROUND_INDEX])->data); |
SDATA (face->lface[LFACE_BACKGROUND_INDEX])); |
7387 |
fprintf (stderr, "font_name: %s (%s)\n", |
fprintf (stderr, "font_name: %s (%s)\n", |
7388 |
face->font_name, |
face->font_name, |
7389 |
XSTRING (face->lface[LFACE_FAMILY_INDEX])->data); |
SDATA (face->lface[LFACE_FAMILY_INDEX])); |
7390 |
#ifdef HAVE_X_WINDOWS |
#ifdef HAVE_X_WINDOWS |
7391 |
fprintf (stderr, "font = %p\n", face->font); |
fprintf (stderr, "font = %p\n", face->font); |
7392 |
#endif |
#endif |
7394 |
fprintf (stderr, "fontset: %d\n", face->fontset); |
fprintf (stderr, "fontset: %d\n", face->fontset); |
7395 |
fprintf (stderr, "underline: %d (%s)\n", |
fprintf (stderr, "underline: %d (%s)\n", |
7396 |
face->underline_p, |
face->underline_p, |
7397 |
XSTRING (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))->data); |
SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); |
7398 |
fprintf (stderr, "hash: %d\n", face->hash); |
fprintf (stderr, "hash: %d\n", face->hash); |
7399 |
fprintf (stderr, "charset: %d\n", face->charset); |
fprintf (stderr, "charset: %d\n", face->charset); |
7400 |
} |
} |