X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a4eec62604216f6d4efc86221466a5e883a0113b..5dcde606e32d1794f8268ea51cd2d1746e45a311:/src/xfaces.c
diff --git a/src/xfaces.c b/src/xfaces.c
index 3afa17a1c2..6bde1c121d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -1,6 +1,6 @@
/* xfaces.c -- "Face" primitives.
Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -27,34 +27,36 @@ along with GNU Emacs. If not, see . */
1. Font family name.
- 2. Relative proportionate width, aka character set width or set
+ 2. Font foundary name.
+
+ 3. Relative proportionate width, aka character set width or set
width (swidth), e.g. `semi-compressed'.
- 3. Font height in 1/10pt.
+ 4. Font height in 1/10pt.
- 4. Font weight, e.g. `bold'.
+ 5. Font weight, e.g. `bold'.
- 5. Font slant, e.g. `italic'.
+ 6. Font slant, e.g. `italic'.
- 6. Foreground color.
+ 7. Foreground color.
- 7. Background color.
+ 8. Background color.
- 8. Whether or not characters should be underlined, and in what color.
+ 9. Whether or not characters should be underlined, and in what color.
- 9. Whether or not characters should be displayed in inverse video.
+ 10. Whether or not characters should be displayed in inverse video.
- 10. A background stipple, a bitmap.
+ 11. A background stipple, a bitmap.
- 11. Whether or not characters should be overlined, and in what color.
+ 12. Whether or not characters should be overlined, and in what color.
- 12. Whether or not characters should be strike-through, and in what
+ 13. Whether or not characters should be strike-through, and in what
color.
- 13. Whether or not a box should be drawn around characters, the box
+ 14. Whether or not a box should be drawn around characters, the box
type, and, for simple boxes, in what color.
- 14. Font-spec, or nil. This is a special attribute.
+ 15. Font-spec, or nil. This is a special attribute.
A font-spec is a collection of font attributes (specs).
@@ -202,6 +204,7 @@ along with GNU Emacs. If not, see . */
#include
#include
#include /* This needs to be before termchar.h */
+#include
#include "lisp.h"
#include "character.h"
@@ -232,15 +235,18 @@ along with GNU Emacs. If not, see . */
#define x_display_info w32_display_info
#define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
#define check_x check_w32
-#define x_list_fonts w32_list_fonts
#define GCGraphicsExposures 0
#endif /* WINDOWSNT */
-#ifdef MAC_OS
-#include "macterm.h"
-#define x_display_info mac_display_info
-#define check_x check_mac
-#endif /* MAC_OS */
+#ifdef HAVE_NS
+#include "nsterm.h"
+#undef FRAME_X_DISPLAY_INFO
+#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
+#define x_display_info ns_display_info
+#define FRAME_X_FONT_TABLE FRAME_NS_FONT_TABLE
+#define check_x check_ns
+#define GCGraphicsExposures 0
+#endif /* HAVE_NS */
#include "buffer.h"
#include "dispextern.h"
@@ -422,6 +428,23 @@ Lisp_Object Qbitmap_spec_p;
Lisp_Object Vface_new_frame_defaults;
+/* Alist of face remappings. Each element is of the form:
+ (FACE REPLACEMENT...) which causes display of the face FACE to use
+ REPLACEMENT... instead. REPLACEMENT... is interpreted the same way
+ the value of a `face' text property is: it may be (1) A face name,
+ (2) A list of face names, (3) A property-list of face attribute/value
+ pairs, or (4) A list of face names intermixed with lists containing
+ face attribute/value pairs.
+
+ Multiple entries in REPLACEMENT... are merged together to form the final
+ result, with faces or attributes earlier in the list taking precedence
+ over those that are later.
+
+ Face-name remapping cycles are suppressed; recursive references use
+ the underlying face instead of the remapped face. */
+
+Lisp_Object Vface_remapping_alist;
+
/* The next ID to assign to Lisp faces. */
static int next_lface_id;
@@ -484,7 +507,6 @@ int menu_face_changed_default;
/* Function prototypes. */
-struct font_name;
struct table_entry;
struct named_merge_point;
@@ -493,9 +515,9 @@ static void map_tty_color P_ ((struct frame *, struct face *,
static Lisp_Object resolve_face_name P_ ((Lisp_Object, int));
static int may_use_scalable_font_p P_ ((const char *));
static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
-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, struct named_merge_point *));
static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
-static unsigned char *xstrlwr P_ ((unsigned char *));
static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
static void free_face_colors P_ ((struct frame *, struct face *));
@@ -534,10 +556,6 @@ static void uncache_face P_ ((struct face_cache *, struct face *));
static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
static void x_free_gc P_ ((struct frame *, GC));
-#ifdef WINDOWSNT
-extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
-#endif /* WINDOWSNT */
-
#ifdef USE_X_TOOLKIT
static void x_update_menu_appearance P_ ((struct frame *));
@@ -748,8 +766,8 @@ x_free_gc (f, gc)
#endif /* WINDOWSNT */
-#ifdef MAC_OS
-/* Mac OS emulation of GCs */
+#ifdef HAVE_NS
+/* NS emulation of GCs */
static INLINE GC
x_create_gc (f, mask, xgcv)
@@ -757,11 +775,9 @@ x_create_gc (f, mask, xgcv)
unsigned long mask;
XGCValues *xgcv;
{
- GC gc;
- BLOCK_INPUT;
- gc = XCreateGC (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), mask, xgcv);
- UNBLOCK_INPUT;
- IF_DEBUG (++ngcs);
+ GC gc = xmalloc (sizeof (*gc));
+ if (gc)
+ bcopy(xgcv, gc, sizeof(XGCValues));
return gc;
}
@@ -770,12 +786,9 @@ x_free_gc (f, gc)
struct frame *f;
GC gc;
{
- eassert (interrupt_input_blocked);
- IF_DEBUG (xassert (--ngcs >= 0));
- XFreeGC (FRAME_MAC_DISPLAY (f), gc);
+ xfree (gc);
}
-
-#endif /* MAC_OS */
+#endif /* HAVE_NS */
/* Like strcasecmp/stricmp. Used to compare parts of font names which
are in ISO8859-1. */
@@ -836,8 +849,10 @@ init_frame_faces (f)
/* Make the image cache. */
if (FRAME_WINDOW_P (f))
{
+ /* We initialize the image cache when creating the first frame
+ on a terminal, and not during terminal creation. This way,
+ `x-open-connection' on a tty won't create an image cache. */
if (FRAME_IMAGE_CACHE (f) == NULL)
- /* Is that ever possible?? --Stef */
FRAME_IMAGE_CACHE (f) = make_image_cache ();
++FRAME_IMAGE_CACHE (f)->refcount;
}
@@ -851,15 +866,15 @@ init_frame_faces (f)
#ifdef WINDOWSNT
if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
#endif
-#ifdef MAC_OS
- if (!FRAME_MAC_P (f) || FRAME_MAC_WINDOW (f))
+#ifdef HAVE_NS
+ if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
#endif
if (!realize_basic_faces (f))
- abort ();
+ abort ();
}
-/* Free face cache of frame F. Called from Fdelete_frame. */
+/* Free face cache of frame F. Called from delete_frame. */
void
free_frame_faces (f)
@@ -1247,9 +1262,9 @@ defined_color (f, color_name, color_def, alloc)
else if (FRAME_W32_P (f))
return w32_defined_color (f, color_name, color_def, alloc);
#endif
-#ifdef MAC_OS
- else if (FRAME_MAC_P (f))
- return mac_defined_color (f, color_name, color_def, alloc);
+#ifdef HAVE_NS
+ else if (FRAME_NS_P (f))
+ return ns_defined_color (f, color_name, color_def, alloc, 1);
#endif
else
abort ();
@@ -1540,6 +1555,7 @@ free_face_colors (f, face)
struct frame *f;
struct face *face;
{
+/* PENDING(NS): need to do something here? */
#ifdef HAVE_X_WINDOWS
if (face->colors_copied_bitwise_p)
return;
@@ -1670,35 +1686,10 @@ enum xlfd_swidth
font height, then for weight, then for slant.' This variable can be
set via set-face-font-sort-order. */
-#ifdef MAC_OS
-static int font_sort_order[4] = {
- XLFD_SWIDTH, XLFD_POINT_SIZE, XLFD_WEIGHT, XLFD_SLANT
-};
-#else
static int font_sort_order[4];
-#endif
-
#ifdef HAVE_WINDOW_SYSTEM
-/* Return a rescaling ratio of a font of NAME. */
-
-static double
-font_rescale_ratio (name)
- char *name;
-{
- Lisp_Object tail, elt;
-
- for (tail = Vface_font_rescale_alist; CONSP (tail); tail = XCDR (tail))
- {
- elt = XCAR (tail);
- if (STRINGP (XCAR (elt)) && FLOATP (XCDR (elt))
- && fast_c_string_match_ignore_case (XCAR (elt), name) >= 0)
- return XFLOAT_DATA (XCDR (elt));
- }
- return 1.0;
-}
-
static enum font_property_index font_props_for_sorting[FONT_SIZE_INDEX];
static int
@@ -1708,7 +1699,7 @@ compare_fonts_by_sort_order (v1, v2)
Lisp_Object font1 = *(Lisp_Object *) v1;
Lisp_Object font2 = *(Lisp_Object *) v2;
int i;
-
+
for (i = 0; i < FONT_SIZE_INDEX; i++)
{
enum font_property_index idx = font_props_for_sorting[i];
@@ -1754,43 +1745,52 @@ the face font sort order. */)
(family, frame)
Lisp_Object family, frame;
{
- struct frame *f = check_x_frame (frame);
- Lisp_Object font_spec = Qnil, vec;
- int i, nfonts;
+ Lisp_Object font_spec, list, *drivers, vec;
+ int i, nfonts, ndrivers;
Lisp_Object result;
+ if (NILP (frame))
+ frame = selected_frame;
+ CHECK_LIVE_FRAME (frame);
+
+ font_spec = Ffont_spec (0, NULL);
if (!NILP (family))
{
CHECK_STRING (family);
- font_spec = Ffont_spec (0, NULL);
- Ffont_put (font_spec, QCfamily, family);
+ font_parse_family_registry (family, Qnil, font_spec);
}
- vec = font_list_entities (frame, font_spec);
- nfonts = ASIZE (vec);
- if (nfonts == 0)
+
+ list = font_list_entities (frame, font_spec);
+ if (NILP (list))
return Qnil;
- if (nfonts > 1)
- {
- for (i = 0; i < 4; i++)
- switch (font_sort_order[i])
- {
- case XLFD_SWIDTH:
- font_props_for_sorting[i] = FONT_WIDTH_INDEX; break;
- case XLFD_POINT_SIZE:
- font_props_for_sorting[i] = FONT_SIZE_INDEX; break;
- case XLFD_WEIGHT:
- font_props_for_sorting[i] = FONT_WEIGHT_INDEX; break;
- default:
- font_props_for_sorting[i] = FONT_SLANT_INDEX; break;
- }
- font_props_for_sorting[i++] = FONT_FAMILY_INDEX;
- font_props_for_sorting[i++] = FONT_FOUNDRY_INDEX;
- font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX;
- font_props_for_sorting[i++] = FONT_REGISTRY_INDEX;
- qsort (XVECTOR (vec)->contents, nfonts, sizeof (Lisp_Object),
- compare_fonts_by_sort_order);
- }
+ /* Sort the font entities. */
+ for (i = 0; i < 4; i++)
+ switch (font_sort_order[i])
+ {
+ case XLFD_SWIDTH:
+ font_props_for_sorting[i] = FONT_WIDTH_INDEX; break;
+ case XLFD_POINT_SIZE:
+ font_props_for_sorting[i] = FONT_SIZE_INDEX; break;
+ case XLFD_WEIGHT:
+ font_props_for_sorting[i] = FONT_WEIGHT_INDEX; break;
+ default:
+ font_props_for_sorting[i] = FONT_SLANT_INDEX; break;
+ }
+ font_props_for_sorting[i++] = FONT_FAMILY_INDEX;
+ font_props_for_sorting[i++] = FONT_FOUNDRY_INDEX;
+ font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX;
+ font_props_for_sorting[i++] = FONT_REGISTRY_INDEX;
+
+ ndrivers = XINT (Flength (list));
+ drivers = alloca (sizeof (Lisp_Object) * ndrivers);
+ for (i = 0; i < ndrivers; i++, list = XCDR (list))
+ drivers[i] = XCAR (list);
+ vec = Fvconcat (ndrivers, drivers);
+ nfonts = ASIZE (vec);
+
+ qsort (XVECTOR (vec)->contents, nfonts, sizeof (Lisp_Object),
+ compare_fonts_by_sort_order);
result = Qnil;
for (i = nfonts - 1; i >= 0; --i)
@@ -1803,13 +1803,13 @@ the face font sort order. */)
ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
- f->resy);
+ XFRAME (frame)->resy);
ASET (v, 2, make_number (point));
ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
spacing = Ffont_get (font, QCspacing);
ASET (v, 5, (NILP (spacing) || EQ (spacing, Qp)) ? Qnil : Qt);
- ASET (v, 6, AREF (font, FONT_NAME_INDEX));
+ ASET (v, 6, Ffont_xlfd_name (font, Qnil));
ASET (v, 7, AREF (font, FONT_REGISTRY_INDEX));
result = Fcons (v, result);
@@ -1818,33 +1818,20 @@ the face font sort order. */)
return result;
}
-
-DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
- 0, 1, 0,
- doc: /* Return a list of available font families on FRAME.
-If FRAME is omitted or nil, use the selected frame.
-Value is a list of conses (FAMILY . FIXED-P) where FAMILY
-is a font family, and FIXED-P is non-nil if fonts of that family
-are fixed-pitch. */)
- (frame)
- Lisp_Object frame;
-{
- return Ffont_family_list (frame);
-}
-
-
DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
doc: /* Return a list of the names of available fonts matching PATTERN.
If optional arguments FACE and FRAME are specified, return only fonts
the same size as FACE on FRAME.
-PATTERN is a string, perhaps with wildcard characters;
+
+PATTERN should be a string containing a font name in the XLFD,
+Fontconfig, or GTK format. A font name given in the XLFD format may
+contain wildcard characters:
the * character matches any substring, and
the ? character matches any single character.
PATTERN is case-insensitive.
-FACE is a face name--a symbol.
The return value is a list of strings, suitable as arguments to
-set-face-font.
+`set-face-font'.
Fonts Emacs can't use may or may not be excluded
even if they match PATTERN and FACE.
@@ -1913,14 +1900,32 @@ the WIDTH times as wide as FACE on FRAME. */)
Lisp_Object args[2], tail;
font_spec = font_spec_from_name (pattern);
+ if (!FONTP (font_spec))
+ signal_error ("Invalid font name", pattern);
+
if (size)
{
Ffont_put (font_spec, QCsize, make_number (size));
Ffont_put (font_spec, QCavgwidth, make_number (avgwidth));
}
- args[0] = Flist_fonts (font_spec, frame, maximum, Qnil);
+ args[0] = Flist_fonts (font_spec, frame, maximum, font_spec);
for (tail = args[0]; CONSP (tail); tail = XCDR (tail))
- XSETCAR (tail, Ffont_xlfd_name (XCAR (tail), Qnil));
+ {
+ Lisp_Object font_entity;
+
+ font_entity = XCAR (tail);
+ if ((NILP (AREF (font_entity, FONT_SIZE_INDEX))
+ || XINT (AREF (font_entity, FONT_SIZE_INDEX)) == 0)
+ && ! NILP (AREF (font_spec, FONT_SIZE_INDEX)))
+ {
+ /* This is a scalable font. For backward compatibility,
+ we set the specified size. */
+ font_entity = Fcopy_font_spec (font_entity);
+ ASET (font_entity, FONT_SIZE_INDEX,
+ AREF (font_spec, FONT_SIZE_INDEX));
+ }
+ XSETCAR (tail, Ffont_xlfd_name (font_entity, Qnil));
+ }
if (NILP (frame))
/* We don't have to check fontsets. */
return args[0];
@@ -1931,7 +1936,6 @@ the WIDTH times as wide as FACE on FRAME. */)
#endif /* HAVE_WINDOW_SYSTEM */
-
/***********************************************************************
Lisp Faces
@@ -1940,6 +1944,7 @@ the WIDTH times as wide as FACE on FRAME. */)
/* Access face attributes of face LFACE, a Lisp vector. */
#define LFACE_FAMILY(LFACE) AREF ((LFACE), LFACE_FAMILY_INDEX)
+#define LFACE_FOUNDRY(LFACE) AREF ((LFACE), LFACE_FOUNDRY_INDEX)
#define LFACE_HEIGHT(LFACE) AREF ((LFACE), LFACE_HEIGHT_INDEX)
#define LFACE_WEIGHT(LFACE) AREF ((LFACE), LFACE_WEIGHT_INDEX)
#define LFACE_SLANT(LFACE) AREF ((LFACE), LFACE_SLANT_INDEX)
@@ -1976,6 +1981,9 @@ check_lface_attrs (attrs)
xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
|| STRINGP (attrs[LFACE_FAMILY_INDEX]));
+ xassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
+ || IGNORE_DEFFACE_P (attrs[LFACE_FOUNDRY_INDEX])
+ || STRINGP (attrs[LFACE_FOUNDRY_INDEX]));
xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
|| IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
|| SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
@@ -2060,6 +2068,12 @@ check_lface (lface)
/* Face-merge cycle checking. */
+enum named_merge_point_kind
+{
+ NAMED_MERGE_POINT_NORMAL,
+ NAMED_MERGE_POINT_REMAP
+};
+
/* A `named merge point' is simply a point during face-merging where we
look up a face by name. We keep a stack of which named lookups we're
currently processing so that we can easily detect cycles, using a
@@ -2069,27 +2083,40 @@ check_lface (lface)
struct named_merge_point
{
Lisp_Object face_name;
+ enum named_merge_point_kind named_merge_point_kind;
struct named_merge_point *prev;
};
/* If a face merging cycle is detected for FACE_NAME, return 0,
otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
- FACE_NAME, as the head of the linked list pointed to by
- NAMED_MERGE_POINTS, and return 1. */
+ FACE_NAME and NAMED_MERGE_POINT_KIND, as the head of the linked list
+ pointed to by NAMED_MERGE_POINTS, and return 1. */
static INLINE int
push_named_merge_point (struct named_merge_point *new_named_merge_point,
Lisp_Object face_name,
+ enum named_merge_point_kind named_merge_point_kind,
struct named_merge_point **named_merge_points)
{
struct named_merge_point *prev;
for (prev = *named_merge_points; prev; prev = prev->prev)
if (EQ (face_name, prev->face_name))
- return 0;
+ {
+ if (prev->named_merge_point_kind == named_merge_point_kind)
+ /* A cycle, so fail. */
+ return 0;
+ else if (prev->named_merge_point_kind == NAMED_MERGE_POINT_REMAP)
+ /* A remap `hides ' any previous normal merge points
+ (because the remap means that it's actually different face),
+ so as we know the current merge point must be normal, we
+ can just assume it's OK. */
+ break;
+ }
new_named_merge_point->face_name = face_name;
+ new_named_merge_point->named_merge_point_kind = named_merge_point_kind;
new_named_merge_point->prev = *named_merge_points;
*named_merge_points = new_named_merge_point;
@@ -2167,22 +2194,17 @@ resolve_face_name (face_name, signal_p)
/* Return the face definition of FACE_NAME on frame F. F null means
return the definition for new frames. FACE_NAME may be a string or
a symbol (apparently Emacs 20.2 allowed strings as face names in
- face text properties; Ediff uses that). If FACE_NAME is an alias
- for another face, return that face's definition. If SIGNAL_P is
- non-zero, signal an error if FACE_NAME is not a valid face name.
- If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
- name. */
-
+ face text properties; Ediff uses that). If SIGNAL_P is non-zero,
+ signal an error if FACE_NAME is not a valid face name. If SIGNAL_P
+ is zero, value is nil if FACE_NAME is not a valid face name. */
static INLINE Lisp_Object
-lface_from_face_name (f, face_name, signal_p)
+lface_from_face_name_no_resolve (f, face_name, signal_p)
struct frame *f;
Lisp_Object face_name;
int signal_p;
{
Lisp_Object lface;
- face_name = resolve_face_name (face_name, signal_p);
-
if (f)
lface = assq_no_quit (face_name, f->face_alist);
else
@@ -2194,9 +2216,28 @@ lface_from_face_name (f, face_name, signal_p)
signal_error ("Invalid face", face_name);
check_lface (lface);
+
return lface;
}
+/* Return the face definition of FACE_NAME on frame F. F null means
+ return the definition for new frames. FACE_NAME may be a string or
+ a symbol (apparently Emacs 20.2 allowed strings as face names in
+ face text properties; Ediff uses that). If FACE_NAME is an alias
+ for another face, return that face's definition. If SIGNAL_P is
+ non-zero, signal an error if FACE_NAME is not a valid face name.
+ If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
+ name. */
+static INLINE Lisp_Object
+lface_from_face_name (f, face_name, signal_p)
+ struct frame *f;
+ Lisp_Object face_name;
+ int signal_p;
+{
+ face_name = resolve_face_name (face_name, signal_p);
+ return lface_from_face_name_no_resolve (f, face_name, signal_p);
+}
+
/* Get face attributes of face FACE_NAME from frame-local faces on
frame F. Store the resulting attributes in ATTRS which must point
@@ -2205,26 +2246,65 @@ lface_from_face_name (f, face_name, signal_p)
Otherwise, value is zero if FACE_NAME is not a face. */
static INLINE int
-get_lface_attributes (f, face_name, attrs, signal_p)
+get_lface_attributes_no_remap (f, face_name, attrs, signal_p)
struct frame *f;
Lisp_Object face_name;
Lisp_Object *attrs;
int signal_p;
{
Lisp_Object lface;
- int success_p;
- lface = lface_from_face_name (f, face_name, signal_p);
- if (!NILP (lface))
+ lface = lface_from_face_name_no_resolve (f, face_name, signal_p);
+
+ if (! NILP (lface))
+ bcopy (XVECTOR (lface)->contents, attrs,
+ LFACE_VECTOR_SIZE * sizeof *attrs);
+
+ return !NILP (lface);
+}
+
+/* Get face attributes of face FACE_NAME from frame-local faces on frame
+ F. Store the resulting attributes in ATTRS which must point to a
+ vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If FACE_NAME is an
+ alias for another face, use that face's definition. If SIGNAL_P is
+ non-zero, signal an error if FACE_NAME does not name a face.
+ Otherwise, value is zero if FACE_NAME is not a face. */
+
+static INLINE int
+get_lface_attributes (f, face_name, attrs, signal_p, named_merge_points)
+ struct frame *f;
+ Lisp_Object face_name;
+ Lisp_Object *attrs;
+ int signal_p;
+ struct named_merge_point *named_merge_points;
+{
+ Lisp_Object face_remapping;
+
+ face_name = resolve_face_name (face_name, signal_p);
+
+ /* See if SYMBOL has been remapped to some other face (usually this
+ is done buffer-locally). */
+ face_remapping = assq_no_quit (face_name, Vface_remapping_alist);
+ if (CONSP (face_remapping))
{
- bcopy (XVECTOR (lface)->contents, attrs,
- LFACE_VECTOR_SIZE * sizeof *attrs);
- success_p = 1;
+ struct named_merge_point named_merge_point;
+
+ if (push_named_merge_point (&named_merge_point,
+ face_name, NAMED_MERGE_POINT_REMAP,
+ &named_merge_points))
+ {
+ int i;
+
+ for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
+ attrs[i] = Qunspecified;
+
+ return merge_face_ref (f, XCDR (face_remapping), attrs,
+ signal_p, named_merge_points);
+ }
}
- else
- success_p = 0;
- return success_p;
+ /* Default case, no remapping. */
+ return get_lface_attributes_no_remap (f, face_name, attrs, signal_p);
}
@@ -2239,13 +2319,7 @@ lface_fully_specified_p (attrs)
for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
- if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i]))
-#ifdef MAC_OS
- /* MAC_TODO: No stipple support on Mac OS yet, this index is
- always unspecified. */
- && i != LFACE_STIPPLE_INDEX
-#endif
- )
+ if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
break;
return i == LFACE_VECTOR_SIZE;
@@ -2273,25 +2347,16 @@ set_lface_from_font (f, lface, font_object, force_p)
if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
{
- Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX);
Lisp_Object family = AREF (font_object, FONT_FAMILY_INDEX);
- if (! NILP (foundry))
- {
- if (! NILP (family))
- val = concat3 (SYMBOL_NAME (foundry), build_string ("-"),
- SYMBOL_NAME (family));
- else
- val = concat2 (SYMBOL_NAME (foundry), build_string ("-*"));
- }
- else
- {
- if (! NILP (family))
- val = SYMBOL_NAME (family);
- else
- val = build_string ("*");
- }
- LFACE_FAMILY (lface) = val;
+ LFACE_FAMILY (lface) = SYMBOL_NAME (family);
+ }
+
+ if (force_p || UNSPECIFIEDP (LFACE_FOUNDRY (lface)))
+ {
+ Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX);
+
+ LFACE_FOUNDRY (lface) = SYMBOL_NAME (foundry);
}
if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
@@ -2329,9 +2394,7 @@ set_lface_from_font (f, lface, font_object, force_p)
merged height. If FROM is an invalid height, then INVALID is
returned instead. FROM and TO may be either absolute face heights or
`relative' heights; the returned value is always an absolute height
- unless both FROM and TO are relative. GCPRO is a lisp value that
- will be protected from garbage-collection if this function makes a
- call into lisp. */
+ unless both FROM and TO are relative. */
Lisp_Object
merge_face_heights (from, to, invalid)
@@ -2380,8 +2443,8 @@ merge_face_heights (from, to, invalid)
specified attribute of FROM overrides the corresponding attribute of
TO; relative attributes in FROM are merged with the absolute value in
TO and replace it. NAMED_MERGE_POINTS is used internally to detect
- loops in face inheritance; it should be 0 when called from other
- places. */
+ loops in face inheritance/remapping; it should be 0 when called from
+ other places. */
static INLINE void
merge_face_vectors (f, from, to, named_merge_points)
@@ -2407,6 +2470,16 @@ merge_face_vectors (f, from, to, named_merge_points)
to[i] = Fmerge_font_spec (from[i], to[i]);
else
to[i] = Fcopy_font_spec (from[i]);
+ if (! NILP (AREF (to[i], FONT_FOUNDRY_INDEX)))
+ to[LFACE_FOUNDRY_INDEX] = SYMBOL_NAME (AREF (to[i], FONT_FOUNDRY_INDEX));
+ if (! NILP (AREF (to[i], FONT_FAMILY_INDEX)))
+ to[LFACE_FAMILY_INDEX] = SYMBOL_NAME (AREF (to[i], FONT_FAMILY_INDEX));
+ if (! NILP (AREF (to[i], FONT_WEIGHT_INDEX)))
+ to[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (to[i]);
+ if (! NILP (AREF (to[i], FONT_SLANT_INDEX)))
+ to[LFACE_SLANT_INDEX] = FONT_SLANT_FOR_FACE (to[i]);
+ if (! NILP (AREF (to[i], FONT_WIDTH_INDEX)))
+ to[LFACE_SWIDTH_INDEX] = FONT_WIDTH_FOR_FACE (to[i]);
ASET (to[i], FONT_SIZE_INDEX, Qnil);
}
@@ -2418,12 +2491,14 @@ merge_face_vectors (f, from, to, named_merge_points)
to[i] = merge_face_heights (from[i], to[i], to[i]);
font_clear_prop (to, FONT_SIZE_INDEX);
}
- else if (i != LFACE_FONT_INDEX)
+ else if (i != LFACE_FONT_INDEX
+ && ! EQ (to[i], from[i]))
{
to[i] = from[i];
if (i >= LFACE_FAMILY_INDEX && i <=LFACE_SLANT_INDEX)
font_clear_prop (to,
(i == LFACE_FAMILY_INDEX ? FONT_FAMILY_INDEX
+ : i == LFACE_FOUNDRY_INDEX ? FONT_FOUNDRY_INDEX
: i == LFACE_SWIDTH_INDEX ? FONT_WIDTH_INDEX
: i == LFACE_HEIGHT_INDEX ? FONT_SIZE_INDEX
: i == LFACE_WEIGHT_INDEX ? FONT_WEIGHT_INDEX
@@ -2431,11 +2506,6 @@ merge_face_vectors (f, from, to, named_merge_points)
}
}
- /* If `font' attribute is specified, reflect the font properties in
- it to the other attributes. */
- if (0 && !UNSPECIFIEDP (to[LFACE_FONT_INDEX]))
- font_update_lface (f, to);
-
/* TO is always an absolute face, which should inherit from nothing.
We blindly copy the :inherit attribute above and fix it up here. */
to[LFACE_INHERIT_INDEX] = Qnil;
@@ -2456,11 +2526,12 @@ merge_named_face (f, face_name, to, named_merge_points)
struct named_merge_point named_merge_point;
if (push_named_merge_point (&named_merge_point,
- face_name, &named_merge_points))
+ face_name, NAMED_MERGE_POINT_NORMAL,
+ &named_merge_points))
{
struct gcpro gcpro1;
Lisp_Object from[LFACE_VECTOR_SIZE];
- int ok = get_lface_attributes (f, face_name, from, 0);
+ int ok = get_lface_attributes (f, face_name, from, 0, named_merge_points);
if (ok)
{
@@ -2558,6 +2629,16 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
else
err = 1;
}
+ else if (EQ (keyword, QCfoundry))
+ {
+ if (STRINGP (value))
+ {
+ to[LFACE_FOUNDRY_INDEX] = value;
+ font_clear_prop (to, FONT_FOUNDRY_INDEX);
+ }
+ else
+ err = 1;
+ }
else if (EQ (keyword, QCheight))
{
Lisp_Object new_height =
@@ -2654,7 +2735,7 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
}
else if (EQ (keyword, QCstipple))
{
-#ifdef HAVE_X_WINDOWS
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
Lisp_Object pixmap_p = Fbitmap_spec_p (value);
if (!NILP (pixmap_p))
to[LFACE_STIPPLE_INDEX] = value;
@@ -2810,6 +2891,7 @@ Value is a vector of face attributes. */)
DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
Sinternal_lisp_face_p, 1, 2, 0,
doc: /* Return non-nil if FACE names a face.
+FACE should be a symbol or string.
If optional second argument FRAME is non-nil, check for the
existence of a frame-local face with name FACE on that frame.
Otherwise check for the existence of a global face. */)
@@ -2838,7 +2920,7 @@ DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
If FRAME is t, copy the global face definition of FROM.
Otherwise, copy the frame-local definition of FROM on FRAME.
If NEW-FRAME is a frame, copy that data into the frame-local
-definition of TO on NEW-FRAME. If NEW-FRAME is nil.
+definition of TO on NEW-FRAME. If NEW-FRAME is nil,
FRAME controls where the data is copied to.
The value is TO. */)
@@ -2958,21 +3040,38 @@ FRAME 0 means change the face on all frames, and change the default
LFACE_FAMILY (lface) = value;
prop_index = FONT_FAMILY_INDEX;
}
+ else if (EQ (attr, QCfoundry))
+ {
+ if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+ {
+ CHECK_STRING (value);
+ if (SCHARS (value) == 0)
+ signal_error ("Invalid face foundry", value);
+ }
+ old_value = LFACE_FOUNDRY (lface);
+ LFACE_FOUNDRY (lface) = value;
+ prop_index = FONT_FOUNDRY_INDEX;
+ }
else if (EQ (attr, QCheight))
{
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
{
- Lisp_Object test;
-
- test = (EQ (face, Qdefault)
- ? value
- /* The default face must have an absolute size,
- otherwise, we do a test merge with a random
- height to see if VALUE's ok. */
- : merge_face_heights (value, make_number (10), Qnil));
-
- if (!INTEGERP (test) || XINT (test) <= 0)
- signal_error ("Invalid face height", value);
+ if (EQ (face, Qdefault))
+ {
+ /* The default face must have an absolute size. */
+ if (!INTEGERP (value) || XINT (value) <= 0)
+ signal_error ("Invalid default face height", value);
+ }
+ else
+ {
+ /* For non-default faces, do a test merge with a random
+ height to see if VALUE's ok. */
+ Lisp_Object test = merge_face_heights (value,
+ make_number (10),
+ Qnil);
+ if (!INTEGERP (test) || XINT (test) <= 0)
+ signal_error ("Invalid face height", value);
+ }
}
old_value = LFACE_HEIGHT (lface);
@@ -3122,6 +3221,9 @@ FRAME 0 means change the face on all frames, and change the default
}
else if (EQ (attr, QCforeground))
{
+ /* Compatibility with 20.x. */
+ if (NILP (value))
+ value = Qunspecified;
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
{
/* Don't check for valid color names here because it depends
@@ -3136,6 +3238,9 @@ FRAME 0 means change the face on all frames, and change the default
}
else if (EQ (attr, QCbackground))
{
+ /* Compatibility with 20.x. */
+ if (NILP (value))
+ value = Qunspecified;
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
{
/* Don't check for valid color names here because it depends
@@ -3150,14 +3255,14 @@ FRAME 0 means change the face on all frames, and change the default
}
else if (EQ (attr, QCstipple))
{
-#ifdef HAVE_X_WINDOWS
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
&& !NILP (value)
&& NILP (Fbitmap_spec_p (value)))
signal_error ("Invalid stipple attribute", value);
old_value = LFACE_STIPPLE (lface);
LFACE_STIPPLE (lface) = value;
-#endif /* HAVE_X_WINDOWS */
+#endif /* HAVE_X_WINDOWS || HAVE_NS */
}
else if (EQ (attr, QCwidth))
{
@@ -3185,11 +3290,14 @@ FRAME 0 means change the face on all frames, and change the default
{
if (STRINGP (value))
{
- int fontset = fs_query_fontset (value, 0);
+ Lisp_Object name = value;
+ int fontset = fs_query_fontset (name, 0);
if (fontset >= 0)
- value = fontset_ascii (fontset);
- value = font_spec_from_name (value);
+ name = fontset_ascii (fontset);
+ value = font_spec_from_name (name);
+ if (!FONTP (value))
+ signal_error ("Invalid font name", name);
}
else
signal_error ("Invalid font or font-spec", value);
@@ -3261,12 +3369,15 @@ FRAME 0 means change the face on all frames, and change the default
signal_error ("Invalid face attribute name", attr);
if (prop_index)
- /* If a font-related attribute other than QCfont and QCfontset is
- specified, and if the original QCfont attribute has a font
- (font-spec or font-object), set the corresponding property in
- the font to nil so that the font selector doesn't think that
- the attribute is mandatory. */
- font_clear_prop (XVECTOR (lface)->contents, prop_index);
+ {
+ /* If a font-related attribute other than QCfont and QCfontset
+ is specified, and if the original QCfont attribute has a font
+ (font-spec or font-object), set the corresponding property in
+ the font to nil so that the font selector doesn't think that
+ the attribute is mandatory. Also, clear the average
+ width. */
+ font_clear_prop (XVECTOR (lface)->contents, prop_index);
+ }
/* Changing a named face means that all realized faces depending on
that face are invalid. Since we cannot tell which realized faces
@@ -3389,11 +3500,14 @@ set_font_frame_param (frame, lface)
Lisp_Object frame, lface;
{
struct frame *f = XFRAME (frame);
+ Lisp_Object font;
- if (FRAME_WINDOW_P (f))
+ if (FRAME_WINDOW_P (f)
+ /* Don't do anything if the font is `unspecified'. This can
+ happen during frame creation. */
+ && (font = LFACE_FONT (lface),
+ ! UNSPECIFIEDP (font)))
{
- Lisp_Object font = LFACE_FONT (lface);
-
if (FONT_SPEC_P (font))
{
font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
@@ -3438,7 +3552,7 @@ update_face_from_frame_parameter (f, param, new_value)
/* Changing the background color might change the background
mode, so that we have to load new defface specs.
- Call frame-set-background-mode to do that. */
+ Call frame-update-face-colors to do that. */
XSETFRAME (frame, f);
call1 (Qframe_set_background_mode, frame);
@@ -3635,7 +3749,12 @@ x_update_menu_appearance (f)
}
if (face->font
+ /* On Solaris 5.8, it's been reported that the `menu' face
+ can be unspecified here, during startup. Why this
+ happens remains unknown. -- cyd */
+ && FONTP (LFACE_FONT (lface))
&& (!UNSPECIFIEDP (LFACE_FAMILY (lface))
+ || !UNSPECIFIEDP (LFACE_FOUNDRY (lface))
|| !UNSPECIFIEDP (LFACE_SWIDTH (lface))
|| !UNSPECIFIEDP (LFACE_WEIGHT (lface))
|| !UNSPECIFIEDP (LFACE_SLANT (lface))
@@ -3752,6 +3871,8 @@ frames). If FRAME is omitted or nil, use the selected frame. */)
if (EQ (keyword, QCfamily))
value = LFACE_FAMILY (lface);
+ else if (EQ (keyword, QCfoundry))
+ value = LFACE_FOUNDRY (lface);
else if (EQ (keyword, QCheight))
value = LFACE_HEIGHT (lface);
else if (EQ (keyword, QCweight))
@@ -3827,10 +3948,11 @@ Default face attributes override any local face attributes. */)
{
int i;
Lisp_Object global_lface, local_lface, *gvec, *lvec;
+ struct frame *f = XFRAME (frame);
CHECK_LIVE_FRAME (frame);
global_lface = lface_from_face_name (NULL, face, 1);
- local_lface = lface_from_face_name (XFRAME (frame), face, 0);
+ local_lface = lface_from_face_name (f, face, 0);
if (NILP (local_lface))
local_lface = Finternal_make_lisp_face (face, frame);
@@ -3842,13 +3964,44 @@ Default face attributes override any local face attributes. */)
lvec = XVECTOR (local_lface)->contents;
gvec = XVECTOR (global_lface)->contents;
for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
- if (! UNSPECIFIEDP (gvec[i]))
- {
- if (IGNORE_DEFFACE_P (gvec[i]))
- lvec[i] = Qunspecified;
- else
- lvec[i] = gvec[i];
- }
+ if (IGNORE_DEFFACE_P (gvec[i]))
+ lvec[i] = Qunspecified;
+ else if (! UNSPECIFIEDP (gvec[i]))
+ lvec[i] = gvec[i];
+
+ /* If the default face was changed, update the face cache and the
+ `font' frame parameter. */
+ if (EQ (face, Qdefault))
+ {
+ struct face_cache *c = FRAME_FACE_CACHE (f);
+ struct face *newface, *oldface = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+ Lisp_Object attrs[LFACE_VECTOR_SIZE];
+
+ /* This can be NULL (e.g., in batch mode). */
+ if (oldface)
+ {
+ /* Ensure that the face vector is fully specified by merging
+ the previously-cached vector. */
+ bcopy (oldface->lface, attrs, sizeof attrs);
+ merge_face_vectors (f, lvec, attrs, 0);
+ bcopy (attrs, lvec, sizeof attrs);
+ newface = realize_face (c, lvec, DEFAULT_FACE_ID);
+
+ if ((! UNSPECIFIEDP (gvec[LFACE_FAMILY_INDEX])
+ || ! UNSPECIFIEDP (gvec[LFACE_FOUNDRY_INDEX])
+ || ! UNSPECIFIEDP (gvec[LFACE_HEIGHT_INDEX])
+ || ! UNSPECIFIEDP (gvec[LFACE_WEIGHT_INDEX])
+ || ! UNSPECIFIEDP (gvec[LFACE_SLANT_INDEX])
+ || ! UNSPECIFIEDP (gvec[LFACE_SWIDTH_INDEX])
+ || ! UNSPECIFIEDP (gvec[LFACE_FONT_INDEX]))
+ && newface->font)
+ {
+ Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
+ Qnil));
+ }
+ }
+ }
return Qnil;
}
@@ -3939,7 +4092,7 @@ face_attr_equal_p (v1, v2)
return bcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
- case Lisp_Int:
+ case_Lisp_Int:
case Lisp_Symbol:
return 0;
@@ -4062,6 +4215,7 @@ lface_hash (v)
Lisp_Object *v;
{
return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
+ ^ hash_string_case_insensitive (v[LFACE_FOUNDRY_INDEX])
^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
^ XHASH (v[LFACE_WEIGHT_INDEX])
@@ -4084,6 +4238,8 @@ lface_same_font_attributes_p (lface1, lface2)
&& lface_fully_specified_p (lface2));
return (xstrcasecmp (SDATA (lface1[LFACE_FAMILY_INDEX]),
SDATA (lface2[LFACE_FAMILY_INDEX])) == 0
+ && xstrcasecmp (SDATA (lface1[LFACE_FOUNDRY_INDEX]),
+ SDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
&& EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
&& EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
&& EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
@@ -4644,7 +4800,7 @@ lookup_named_face (f, symbol, signal_p)
abort (); /* realize_basic_faces must have set it up */
}
- if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p))
+ if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
return -1;
bcopy (default_face->lface, attrs, sizeof attrs);
@@ -4654,6 +4810,58 @@ lookup_named_face (f, symbol, signal_p)
}
+/* Return the display face-id of the basic face who's canonical face-id
+ is FACE_ID. The return value will usually simply be FACE_ID, unless that
+ basic face has bee remapped via Vface_remapping_alist. This function is
+ conservative: if something goes wrong, it will simply return FACE_ID
+ rather than signal an error. */
+
+int
+lookup_basic_face (f, face_id)
+ struct frame *f;
+ int face_id;
+{
+ Lisp_Object name, mapping;
+ int remapped_face_id;
+
+ if (NILP (Vface_remapping_alist))
+ return face_id; /* Nothing to do. */
+
+ switch (face_id)
+ {
+ case DEFAULT_FACE_ID: name = Qdefault; break;
+ case MODE_LINE_FACE_ID: name = Qmode_line; break;
+ case MODE_LINE_INACTIVE_FACE_ID: name = Qmode_line_inactive; break;
+ case HEADER_LINE_FACE_ID: name = Qheader_line; break;
+ case TOOL_BAR_FACE_ID: name = Qtool_bar; break;
+ case FRINGE_FACE_ID: name = Qfringe; break;
+ case SCROLL_BAR_FACE_ID: name = Qscroll_bar; break;
+ case BORDER_FACE_ID: name = Qborder; break;
+ case CURSOR_FACE_ID: name = Qcursor; break;
+ case MOUSE_FACE_ID: name = Qmouse; break;
+ case MENU_FACE_ID: name = Qmenu; break;
+
+ default:
+ abort (); /* the caller is supposed to pass us a basic face id */
+ }
+
+ /* Do a quick scan through Vface_remapping_alist, and return immediately
+ if there is no remapping for face NAME. This is just an optimization
+ for the very common no-remapping case. */
+ mapping = assq_no_quit (name, Vface_remapping_alist);
+ if (NILP (mapping))
+ return face_id; /* Give up. */
+
+ /* If there is a remapping entry, lookup the face using NAME, which will
+ handle the remapping too. */
+ remapped_face_id = lookup_named_face (f, name, 0);
+ if (remapped_face_id < 0)
+ return face_id; /* Give up. */
+
+ return remapped_face_id;
+}
+
+
/* Return the ID of the realized ASCII face of Lisp face with ID
LFACE_ID on frame F. Value is -1 if LFACE_ID isn't valid. */
@@ -4758,6 +4966,7 @@ face_with_height (f, face_id, height)
face = FACE_FROM_ID (f, face_id);
bcopy (face->lface, attrs, sizeof attrs);
attrs[LFACE_HEIGHT_INDEX] = make_number (height);
+ font_clear_prop (attrs, FONT_SIZE_INDEX);
face_id = lookup_face (f, attrs);
#endif /* HAVE_WINDOW_SYSTEM */
@@ -4786,7 +4995,9 @@ lookup_derived_face (f, symbol, face_id, signal_p)
if (!default_face)
abort ();
- get_lface_attributes (f, symbol, symbol_attrs, signal_p);
+ if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
+ return -1;
+
bcopy (default_face->lface, attrs, sizeof attrs);
merge_face_vectors (f, symbol_attrs, attrs, 0);
return lookup_face (f, attrs);
@@ -4870,6 +5081,7 @@ x_supports_face_attributes_p (f, attrs, def_face)
/* Check font-related attributes, as those are the most commonly
"unsupported" on a window-system (because of missing fonts). */
if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
+ || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
|| !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
|| !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
|| !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
@@ -4890,8 +5102,10 @@ x_supports_face_attributes_p (f, attrs, def_face)
if (! face)
error ("Cannot make face");
- /* If the font is the same, then not supported. */
- if (face->font == def_face->font)
+ /* If the font is the same, or no font is found, then not
+ supported. */
+ if (face->font == def_face->font
+ || ! face->font)
return 0;
for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++)
if (! EQ (face->font->props[i], def_face->font->props[i]))
@@ -4955,6 +5169,7 @@ tty_supports_face_attributes_p (f, attrs, def_face)
because the faked result is too different from what the face
specifies. */
if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
+ || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
|| !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
|| !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
|| !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
@@ -4968,8 +5183,9 @@ tty_supports_face_attributes_p (f, attrs, def_face)
/* Test for terminal `capabilities' (non-color character attributes). */
/* font weight (bold/dim) */
- weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
- if (weight >= 0)
+ val = attrs[LFACE_WEIGHT_INDEX];
+ if (!UNSPECIFIEDP (val)
+ && (weight = FONT_WEIGHT_NAME_NUMERIC (val), weight >= 0))
{
int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]);
@@ -5182,7 +5398,7 @@ face for italic. */)
Font selection
***********************************************************************/
- DEFUN ("internal-set-font-selection-order",
+DEFUN ("internal-set-font-selection-order",
Finternal_set_font_selection_order,
Sinternal_set_font_selection_order, 1, 1, 0,
doc: /* Set font selection order for face font selection to ORDER.
@@ -5254,7 +5470,20 @@ be found. Value is ALIST. */)
(alist)
Lisp_Object alist;
{
+ Lisp_Object entry, tail, tail2;
+
CHECK_LIST (alist);
+ alist = Fcopy_sequence (alist);
+ for (tail = alist; CONSP (tail); tail = XCDR (tail))
+ {
+ entry = XCAR (tail);
+ CHECK_LIST (entry);
+ entry = Fcopy_sequence (entry);
+ XSETCAR (tail, entry);
+ for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
+ XSETCAR (tail2, Fintern (XCAR (tail2), Qnil));
+ }
+
Vface_alternative_font_family_alist = alist;
free_all_realized_faces (Qnil);
return alist;
@@ -5271,7 +5500,19 @@ be found. Value is ALIST. */)
(alist)
Lisp_Object alist;
{
+ Lisp_Object entry, tail, tail2;
+
CHECK_LIST (alist);
+ alist = Fcopy_sequence (alist);
+ for (tail = alist; CONSP (tail); tail = XCDR (tail))
+ {
+ entry = XCAR (tail);
+ CHECK_LIST (entry);
+ entry = Fcopy_sequence (entry);
+ XSETCAR (tail, entry);
+ for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
+ XSETCAR (tail2, Fdowncase (XCAR (tail2)));
+ }
Vface_alternative_font_registry_alist = alist;
free_all_realized_faces (Qnil);
return alist;
@@ -5394,12 +5635,15 @@ realize_default_face (f)
if (!FRAME_WINDOW_P (f))
{
LFACE_FAMILY (lface) = build_string ("default");
+ LFACE_FOUNDRY (lface) = LFACE_FAMILY (lface);
LFACE_SWIDTH (lface) = Qnormal;
LFACE_HEIGHT (lface) = make_number (1);
if (UNSPECIFIEDP (LFACE_WEIGHT (lface)))
LFACE_WEIGHT (lface) = Qnormal;
if (UNSPECIFIEDP (LFACE_SLANT (lface)))
LFACE_SLANT (lface) = Qnormal;
+ if (UNSPECIFIEDP (LFACE_FONTSET (lface)))
+ LFACE_FONTSET (lface) = Qnil;
}
if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
@@ -5465,7 +5709,7 @@ realize_default_face (f)
not support the default font. */
if (!face->font)
return 0;
-
+
/* Otherwise, the font specified for the frame was not
acceptable as a font for the default face (perhaps because
auto-scaled fonts are rejected), so we must adjust the frame
@@ -5495,7 +5739,7 @@ realize_named_face (f, symbol, id)
struct face *new_face;
/* The default face must exist and be fully specified. */
- get_lface_attributes (f, Qdefault, attrs, 1);
+ get_lface_attributes_no_remap (f, Qdefault, attrs, 1);
check_lface_attrs (attrs);
xassert (lface_fully_specified_p (attrs));
@@ -5508,7 +5752,7 @@ realize_named_face (f, symbol, id)
}
/* Merge SYMBOL's face with the default face. */
- get_lface_attributes (f, symbol, symbol_attrs, 1);
+ get_lface_attributes_no_remap (f, symbol, symbol_attrs, 1);
merge_face_vectors (f, symbol_attrs, attrs, 0);
/* Realize the face. */
@@ -5628,7 +5872,8 @@ realize_x_face (cache, attrs)
&& lface_same_font_attributes_p (default_face->lface, attrs))
{
face->font = default_face->font;
- face->fontset = make_fontset_for_ascii_face (f, -1, face);
+ face->fontset
+ = make_fontset_for_ascii_face (f, default_face->fontset, face);
}
else
{
@@ -5645,9 +5890,12 @@ realize_x_face (cache, attrs)
realizing the default face, thus the default face should have
already been realized. */
if (fontset == -1)
- fontset = default_face->fontset;
- if (fontset == -1)
- abort ();
+ {
+ if (default_face)
+ fontset = default_face->fontset;
+ if (fontset == -1)
+ abort ();
+ }
if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
attrs[LFACE_FONT_INDEX]
= font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]);
@@ -6012,17 +6260,21 @@ compute_char_face (f, ch, prop)
If MOUSE is non-zero, use the character's mouse-face, not its face.
+ BASE_FACE_ID, if non-negative, specifies a base face id to use
+ instead of DEFAULT_FACE_ID.
+
The face returned is suitable for displaying ASCII characters. */
int
face_at_buffer_position (w, pos, region_beg, region_end,
- endptr, limit, mouse)
+ endptr, limit, mouse, base_face_id)
struct window *w;
EMACS_INT pos;
EMACS_INT region_beg, region_end;
EMACS_INT *endptr;
EMACS_INT limit;
int mouse;
+ int base_face_id;
{
struct frame *f = XFRAME (w->frame);
Lisp_Object attrs[LFACE_VECTOR_SIZE];
@@ -6065,13 +6317,15 @@ face_at_buffer_position (w, pos, region_beg, region_end,
*endptr = endpos;
- default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+ default_face = FACE_FROM_ID (f, base_face_id >= 0 ? base_face_id
+ : NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
+ : lookup_basic_face (f, DEFAULT_FACE_ID));
/* Optimize common cases where we can use the default face. */
if (noverlays == 0
&& NILP (prop)
&& !(pos >= region_beg && pos < region_end))
- return DEFAULT_FACE_ID;
+ return default_face->id;
/* Begin with attributes from the default face. */
bcopy (default_face->lface, attrs, sizeof attrs);
@@ -6320,10 +6574,10 @@ merge_faces (f, face_name, face_id, base_face_id)
if (face_id < 0 || face_id >= lface_id_to_name_size)
return base_face_id;
face_name = lface_id_to_name[face_id];
- face_id = lookup_derived_face (f, face_name, base_face_id, 1);
- if (face_id >= 0)
- return face_id;
- return base_face_id;
+ /* When called during make-frame, lookup_derived_face may fail
+ if the faces are uninitialized. Don't signal an error. */
+ face_id = lookup_derived_face (f, face_name, base_face_id, 0);
+ return (face_id >= 0 ? face_id : base_face_id);
}
/* Begin with attributes from the base face. */
@@ -6350,6 +6604,60 @@ merge_faces (f, face_name, face_id, base_face_id)
return lookup_face (f, attrs);
}
+
+
+#ifndef HAVE_X_WINDOWS
+DEFUN ("x-load-color-file", Fx_load_color_file,
+ Sx_load_color_file, 1, 1, 0,
+ doc: /* Create an alist of color entries from an external file.
+
+The file should define one named RGB color per line like so:
+ R G B name
+where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
+ (filename)
+ Lisp_Object filename;
+{
+ FILE *fp;
+ Lisp_Object cmap = Qnil;
+ Lisp_Object abspath;
+
+ CHECK_STRING (filename);
+ abspath = Fexpand_file_name (filename, Qnil);
+
+ fp = fopen (SDATA (filename), "rt");
+ if (fp)
+ {
+ char buf[512];
+ int red, green, blue;
+ int num;
+
+ BLOCK_INPUT;
+
+ while (fgets (buf, sizeof (buf), fp) != NULL) {
+ if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
+ {
+ char *name = buf + num;
+ num = strlen (name) - 1;
+ if (num >= 0 && name[num] == '\n')
+ name[num] = 0;
+ cmap = Fcons (Fcons (build_string (name),
+#ifdef WINDOWSNT
+ make_number (RGB (red, green, blue))),
+#else
+ make_number ((red << 16) | (green << 8) | blue)),
+#endif
+ cmap);
+ }
+ }
+ fclose (fp);
+
+ UNBLOCK_INPUT;
+ }
+
+ return cmap;
+}
+#endif
+
/***********************************************************************
Tests
@@ -6443,152 +6751,152 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
void
syms_of_xfaces ()
{
- Qface = intern ("face");
+ Qface = intern_c_string ("face");
staticpro (&Qface);
- Qface_no_inherit = intern ("face-no-inherit");
+ Qface_no_inherit = intern_c_string ("face-no-inherit");
staticpro (&Qface_no_inherit);
- Qbitmap_spec_p = intern ("bitmap-spec-p");
+ Qbitmap_spec_p = intern_c_string ("bitmap-spec-p");
staticpro (&Qbitmap_spec_p);
- Qframe_set_background_mode = intern ("frame-set-background-mode");
+ Qframe_set_background_mode = intern_c_string ("frame-set-background-mode");
staticpro (&Qframe_set_background_mode);
/* Lisp face attribute keywords. */
- QCfamily = intern (":family");
+ QCfamily = intern_c_string (":family");
staticpro (&QCfamily);
- QCheight = intern (":height");
+ QCheight = intern_c_string (":height");
staticpro (&QCheight);
- QCweight = intern (":weight");
+ QCweight = intern_c_string (":weight");
staticpro (&QCweight);
- QCslant = intern (":slant");
+ QCslant = intern_c_string (":slant");
staticpro (&QCslant);
- QCunderline = intern (":underline");
+ QCunderline = intern_c_string (":underline");
staticpro (&QCunderline);
- QCinverse_video = intern (":inverse-video");
+ QCinverse_video = intern_c_string (":inverse-video");
staticpro (&QCinverse_video);
- QCreverse_video = intern (":reverse-video");
+ QCreverse_video = intern_c_string (":reverse-video");
staticpro (&QCreverse_video);
- QCforeground = intern (":foreground");
+ QCforeground = intern_c_string (":foreground");
staticpro (&QCforeground);
- QCbackground = intern (":background");
+ QCbackground = intern_c_string (":background");
staticpro (&QCbackground);
- QCstipple = intern (":stipple");
+ QCstipple = intern_c_string (":stipple");
staticpro (&QCstipple);
- QCwidth = intern (":width");
+ QCwidth = intern_c_string (":width");
staticpro (&QCwidth);
- QCfont = intern (":font");
+ QCfont = intern_c_string (":font");
staticpro (&QCfont);
- QCfontset = intern (":fontset");
+ QCfontset = intern_c_string (":fontset");
staticpro (&QCfontset);
- QCbold = intern (":bold");
+ QCbold = intern_c_string (":bold");
staticpro (&QCbold);
- QCitalic = intern (":italic");
+ QCitalic = intern_c_string (":italic");
staticpro (&QCitalic);
- QCoverline = intern (":overline");
+ QCoverline = intern_c_string (":overline");
staticpro (&QCoverline);
- QCstrike_through = intern (":strike-through");
+ QCstrike_through = intern_c_string (":strike-through");
staticpro (&QCstrike_through);
- QCbox = intern (":box");
+ QCbox = intern_c_string (":box");
staticpro (&QCbox);
- QCinherit = intern (":inherit");
+ QCinherit = intern_c_string (":inherit");
staticpro (&QCinherit);
/* Symbols used for Lisp face attribute values. */
- QCcolor = intern (":color");
+ QCcolor = intern_c_string (":color");
staticpro (&QCcolor);
- QCline_width = intern (":line-width");
+ QCline_width = intern_c_string (":line-width");
staticpro (&QCline_width);
- QCstyle = intern (":style");
+ QCstyle = intern_c_string (":style");
staticpro (&QCstyle);
- Qreleased_button = intern ("released-button");
+ Qreleased_button = intern_c_string ("released-button");
staticpro (&Qreleased_button);
- Qpressed_button = intern ("pressed-button");
+ Qpressed_button = intern_c_string ("pressed-button");
staticpro (&Qpressed_button);
- Qnormal = intern ("normal");
+ Qnormal = intern_c_string ("normal");
staticpro (&Qnormal);
- Qultra_light = intern ("ultra-light");
+ Qultra_light = intern_c_string ("ultra-light");
staticpro (&Qultra_light);
- Qextra_light = intern ("extra-light");
+ Qextra_light = intern_c_string ("extra-light");
staticpro (&Qextra_light);
- Qlight = intern ("light");
+ Qlight = intern_c_string ("light");
staticpro (&Qlight);
- Qsemi_light = intern ("semi-light");
+ Qsemi_light = intern_c_string ("semi-light");
staticpro (&Qsemi_light);
- Qsemi_bold = intern ("semi-bold");
+ Qsemi_bold = intern_c_string ("semi-bold");
staticpro (&Qsemi_bold);
- Qbold = intern ("bold");
+ Qbold = intern_c_string ("bold");
staticpro (&Qbold);
- Qextra_bold = intern ("extra-bold");
+ Qextra_bold = intern_c_string ("extra-bold");
staticpro (&Qextra_bold);
- Qultra_bold = intern ("ultra-bold");
+ Qultra_bold = intern_c_string ("ultra-bold");
staticpro (&Qultra_bold);
- Qoblique = intern ("oblique");
+ Qoblique = intern_c_string ("oblique");
staticpro (&Qoblique);
- Qitalic = intern ("italic");
+ Qitalic = intern_c_string ("italic");
staticpro (&Qitalic);
- Qreverse_oblique = intern ("reverse-oblique");
+ Qreverse_oblique = intern_c_string ("reverse-oblique");
staticpro (&Qreverse_oblique);
- Qreverse_italic = intern ("reverse-italic");
+ Qreverse_italic = intern_c_string ("reverse-italic");
staticpro (&Qreverse_italic);
- Qultra_condensed = intern ("ultra-condensed");
+ Qultra_condensed = intern_c_string ("ultra-condensed");
staticpro (&Qultra_condensed);
- Qextra_condensed = intern ("extra-condensed");
+ Qextra_condensed = intern_c_string ("extra-condensed");
staticpro (&Qextra_condensed);
- Qcondensed = intern ("condensed");
+ Qcondensed = intern_c_string ("condensed");
staticpro (&Qcondensed);
- Qsemi_condensed = intern ("semi-condensed");
+ Qsemi_condensed = intern_c_string ("semi-condensed");
staticpro (&Qsemi_condensed);
- Qsemi_expanded = intern ("semi-expanded");
+ Qsemi_expanded = intern_c_string ("semi-expanded");
staticpro (&Qsemi_expanded);
- Qexpanded = intern ("expanded");
+ Qexpanded = intern_c_string ("expanded");
staticpro (&Qexpanded);
- Qextra_expanded = intern ("extra-expanded");
+ Qextra_expanded = intern_c_string ("extra-expanded");
staticpro (&Qextra_expanded);
- Qultra_expanded = intern ("ultra-expanded");
+ Qultra_expanded = intern_c_string ("ultra-expanded");
staticpro (&Qultra_expanded);
- Qbackground_color = intern ("background-color");
+ Qbackground_color = intern_c_string ("background-color");
staticpro (&Qbackground_color);
- Qforeground_color = intern ("foreground-color");
+ Qforeground_color = intern_c_string ("foreground-color");
staticpro (&Qforeground_color);
- Qunspecified = intern ("unspecified");
+ Qunspecified = intern_c_string ("unspecified");
staticpro (&Qunspecified);
- Qignore_defface = intern (":ignore-defface");
+ Qignore_defface = intern_c_string (":ignore-defface");
staticpro (&Qignore_defface);
- Qface_alias = intern ("face-alias");
+ Qface_alias = intern_c_string ("face-alias");
staticpro (&Qface_alias);
- Qdefault = intern ("default");
+ Qdefault = intern_c_string ("default");
staticpro (&Qdefault);
- Qtool_bar = intern ("tool-bar");
+ Qtool_bar = intern_c_string ("tool-bar");
staticpro (&Qtool_bar);
- Qregion = intern ("region");
+ Qregion = intern_c_string ("region");
staticpro (&Qregion);
- Qfringe = intern ("fringe");
+ Qfringe = intern_c_string ("fringe");
staticpro (&Qfringe);
- Qheader_line = intern ("header-line");
+ Qheader_line = intern_c_string ("header-line");
staticpro (&Qheader_line);
- Qscroll_bar = intern ("scroll-bar");
+ Qscroll_bar = intern_c_string ("scroll-bar");
staticpro (&Qscroll_bar);
- Qmenu = intern ("menu");
+ Qmenu = intern_c_string ("menu");
staticpro (&Qmenu);
- Qcursor = intern ("cursor");
+ Qcursor = intern_c_string ("cursor");
staticpro (&Qcursor);
- Qborder = intern ("border");
+ Qborder = intern_c_string ("border");
staticpro (&Qborder);
- Qmouse = intern ("mouse");
+ Qmouse = intern_c_string ("mouse");
staticpro (&Qmouse);
- Qmode_line_inactive = intern ("mode-line-inactive");
+ Qmode_line_inactive = intern_c_string ("mode-line-inactive");
staticpro (&Qmode_line_inactive);
- Qvertical_border = intern ("vertical-border");
+ Qvertical_border = intern_c_string ("vertical-border");
staticpro (&Qvertical_border);
- Qtty_color_desc = intern ("tty-color-desc");
+ Qtty_color_desc = intern_c_string ("tty-color-desc");
staticpro (&Qtty_color_desc);
- Qtty_color_standard_values = intern ("tty-color-standard-values");
+ Qtty_color_standard_values = intern_c_string ("tty-color-standard-values");
staticpro (&Qtty_color_standard_values);
- Qtty_color_by_index = intern ("tty-color-by-index");
+ Qtty_color_by_index = intern_c_string ("tty-color-by-index");
staticpro (&Qtty_color_by_index);
- Qtty_color_alist = intern ("tty-color-alist");
+ Qtty_color_alist = intern_c_string ("tty-color-alist");
staticpro (&Qtty_color_alist);
- Qscalable_fonts_allowed = intern ("scalable-fonts-allowed");
+ Qscalable_fonts_allowed = intern_c_string ("scalable-fonts-allowed");
staticpro (&Qscalable_fonts_allowed);
Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
@@ -6606,6 +6914,9 @@ syms_of_xfaces ()
#endif
defsubr (&Scolor_gray_p);
defsubr (&Scolor_supported_p);
+#ifndef HAVE_X_WINDOWS
+ defsubr (&Sx_load_color_file);
+#endif
defsubr (&Sface_attribute_relative_p);
defsubr (&Smerge_face_attribute);
defsubr (&Sinternal_get_lisp_face_attribute);
@@ -6648,7 +6959,7 @@ that number of fonts when searching for a matching font. */);
This stipple pattern is used on monochrome displays
instead of shades of gray for a face background color.
See `set-face-stipple' for possible values for this variable. */);
- Vface_default_stipple = build_string ("gray3");
+ Vface_default_stipple = make_pure_c_string ("gray3");
DEFVAR_LISP ("tty-defined-color-alist", &Vtty_defined_color_alist,
doc: /* An alist of defined terminal colors and their RGB values. */);
@@ -6670,10 +6981,47 @@ Each element is a regular expression that matches names of fonts to
ignore. */);
Vface_ignored_fonts = Qnil;
+ DEFVAR_LISP ("face-remapping-alist", &Vface_remapping_alist,
+ doc: /* Alist of face remappings.
+Each element is of the form:
+
+ (FACE REPLACEMENT...),
+
+which causes display of the face FACE to use REPLACEMENT... instead.
+REPLACEMENT... is interpreted the same way the value of a `face' text
+property is: it may be (1) A face name, (2) A list of face names, (3) A
+property-list of face attribute/value pairs, or (4) A list of face names
+intermixed with lists containing face attribute/value pairs.
+
+Multiple entries in REPLACEMENT... are merged together to form the final
+result, with faces or attributes earlier in the list taking precedence
+over those that are later.
+
+Face-name remapping cycles are suppressed; recursive references use the
+underlying face instead of the remapped face. So a remapping of the form:
+
+ (FACE EXTRA-FACE... FACE)
+
+or:
+
+ (FACE (FACE-ATTR VAL ...) FACE)
+
+will cause EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the
+existing definition of FACE. Note that for the default face, this isn't
+necessary, as every face inherits from the default face.
+
+Making this variable buffer-local is a good way to allow buffer-specific
+face definitions. For instance, the mode my-mode could define a face
+`my-mode-default', and then in the mode setup function, do:
+
+ (set (make-local-variable 'face-remapping-alist)
+ '((default my-mode-default)))). */);
+ Vface_remapping_alist = Qnil;
+
DEFVAR_LISP ("face-font-rescale-alist", &Vface_font_rescale_alist,
doc: /* Alist of fonts vs the rescaling factors.
-Each element is a cons (FONT-NAME-PATTERN . RESCALE-RATIO), where
-FONT-NAME-PATTERN is a regular expression matching a font name, and
+Each element is a cons (FONT-PATTERN . RESCALE-RATIO), where
+FONT-PATTERN is a font-spec or a regular expression matching a font name, and
RESCALE-RATIO is a floating point number to specify how much larger
\(or smaller) font we should use. For instance, if a face requests
a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point. */);
@@ -6684,8 +7032,7 @@ a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point. */);
defsubr (&Sx_list_fonts);
defsubr (&Sinternal_face_x_get_resource);
defsubr (&Sx_family_fonts);
- defsubr (&Sx_font_family_list);
-#endif /* HAVE_WINDOW_SYSTEM */
+#endif
}
/* arch-tag: 8a0f7598-5517-408d-9ab3-1da6fcd4c749