X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/eceeb5fca618f3bc0743c2388148dd758229c7c9..e509cfa6065d20e0d8d2b3ce9ac544355521bc89:/src/xfaces.c diff --git a/src/xfaces.c b/src/xfaces.c index 972de23451..021d40559e 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -320,6 +320,7 @@ static Lisp_Object QCfontset; Lisp_Object Qnormal; Lisp_Object Qbold; +static Lisp_Object Qline, Qwave; static Lisp_Object Qultra_light, Qextra_light, Qlight; static Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold; static Lisp_Object Qoblique, Qreverse_oblique, Qreverse_italic; @@ -440,7 +441,7 @@ static Lisp_Object Vparam_value_alist; /* The total number of colors currently allocated. */ -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG static int ncolors_allocated; static int npixmaps_allocated; static int ngcs; @@ -538,7 +539,7 @@ int color_count[256]; void register_color (unsigned long pixel) { - xassert (pixel < 256); + eassert (pixel < 256); ++color_count[pixel]; } @@ -548,7 +549,7 @@ register_color (unsigned long pixel) void unregister_color (unsigned long pixel) { - xassert (pixel < 256); + eassert (pixel < 256); if (color_count[pixel] > 0) --color_count[pixel]; else @@ -662,7 +663,7 @@ static inline void x_free_gc (struct frame *f, GC gc) { eassert (interrupt_input_blocked); - IF_DEBUG (xassert (--ngcs >= 0)); + IF_DEBUG (eassert (--ngcs >= 0)); XFreeGC (FRAME_X_DISPLAY (f), gc); } @@ -688,7 +689,7 @@ x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv) static inline void x_free_gc (struct frame *f, GC gc) { - IF_DEBUG (xassert (--ngcs >= 0)); + IF_DEBUG (eassert (--ngcs >= 0)); xfree (gc); } @@ -715,6 +716,7 @@ x_free_gc (struct frame *f, GC gc) } #endif /* HAVE_NS */ +#ifndef HAVE_STRCASECMP /* Like strcasecmp/stricmp. Used to compare parts of font names which are in ISO8859-1. */ @@ -736,7 +738,7 @@ xstrcasecmp (const char *s1, const char *s2) return *s2 == 0 ? 0 : -1; return 1; } - +#endif /* HAVE_STRCASECMP */ /* If FRAME is nil, return a pointer to the selected frame. Otherwise, check that FRAME is a live frame, and return a pointer @@ -922,7 +924,7 @@ the pixmap. Bits are stored row by row, each row occupies else if (CONSP (object)) { /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and - HEIGHT must be integers > 0, and DATA must be string large + HEIGHT must be ints > 0, and DATA must be string large enough to hold a bitmap of the specified size. */ Lisp_Object width, height, data; @@ -942,11 +944,11 @@ the pixmap. Bits are stored row by row, each row occupies } if (STRINGP (data) - && INTEGERP (width) && 0 < XINT (width) - && INTEGERP (height) && 0 < XINT (height)) + && RANGED_INTEGERP (1, width, INT_MAX) + && RANGED_INTEGERP (1, height, INT_MAX)) { - EMACS_INT bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1) - / BITS_PER_CHAR); + int bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1) + / BITS_PER_CHAR); if (XINT (height) <= SBYTES (data) / bytes_per_row) pixmap_p = 1; } @@ -1008,7 +1010,7 @@ load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr, } else { -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG ++npixmaps_allocated; #endif if (w_ptr) @@ -1323,8 +1325,8 @@ load_color (struct frame *f, struct face *face, Lisp_Object name, { XColor color; - xassert (STRINGP (name)); - xassert (target_index == LFACE_FOREGROUND_INDEX + eassert (STRINGP (name)); + eassert (target_index == LFACE_FOREGROUND_INDEX || target_index == LFACE_BACKGROUND_INDEX || target_index == LFACE_UNDERLINE_INDEX || target_index == LFACE_OVERLINE_INDEX @@ -1373,7 +1375,7 @@ load_color (struct frame *f, struct face *face, Lisp_Object name, abort (); } } -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG else ++ncolors_allocated; #endif @@ -1604,7 +1606,9 @@ compare_fonts_by_sort_order (const void *v1, const void *v2) else { if (INTEGERP (val1)) - result = INTEGERP (val2) ? XINT (val1) - XINT (val2) : -1; + result = (INTEGERP (val2) && XINT (val1) >= XINT (val2) + ? XINT (val1) > XINT (val2) + : -1); else result = INTEGERP (val2) ? 1 : 0; } @@ -1633,8 +1637,10 @@ the face font sort order. */) (Lisp_Object family, Lisp_Object frame) { Lisp_Object font_spec, list, *drivers, vec; - int i, nfonts, ndrivers; + ptrdiff_t i, nfonts; + EMACS_INT ndrivers; Lisp_Object result; + USE_SAFE_ALLOCA; if (NILP (frame)) frame = selected_frame; @@ -1670,7 +1676,7 @@ the face font sort order. */) font_props_for_sorting[i++] = FONT_REGISTRY_INDEX; ndrivers = XINT (Flength (list)); - drivers = alloca (sizeof (Lisp_Object) * ndrivers); + SAFE_ALLOCA_LISP (drivers, ndrivers); for (i = 0; i < ndrivers; i++, list = XCDR (list)) drivers[i] = XCAR (list); vec = Fvconcat (ndrivers, drivers); @@ -1702,6 +1708,7 @@ the face font sort order. */) result = Fcons (v, result); } + SAFE_FREE (); return result; } @@ -1848,7 +1855,6 @@ the WIDTH times as wide as FACE on FRAME. */) #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX) #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX) -#if XASSERTS /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */ @@ -1856,77 +1862,77 @@ the WIDTH times as wide as FACE on FRAME. */) (VECTORP (LFACE) \ && ASIZE (LFACE) == LFACE_VECTOR_SIZE \ && EQ (AREF (LFACE, 0), Qface)) -#endif -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG /* Check consistency of Lisp face attribute vector ATTRS. */ static void check_lface_attrs (Lisp_Object *attrs) { - xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX]) || STRINGP (attrs[LFACE_FAMILY_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_FOUNDRY_INDEX]) || STRINGP (attrs[LFACE_FOUNDRY_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX]) || SYMBOLP (attrs[LFACE_SWIDTH_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX]) || INTEGERP (attrs[LFACE_HEIGHT_INDEX]) || FLOATP (attrs[LFACE_HEIGHT_INDEX]) || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX]) || SYMBOLP (attrs[LFACE_WEIGHT_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX]) || SYMBOLP (attrs[LFACE_SLANT_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX]) || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX]) - || STRINGP (attrs[LFACE_UNDERLINE_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) + || STRINGP (attrs[LFACE_UNDERLINE_INDEX]) + || CONSP (attrs[LFACE_UNDERLINE_INDEX])); + eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX]) || SYMBOLP (attrs[LFACE_OVERLINE_INDEX]) || STRINGP (attrs[LFACE_OVERLINE_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX]) || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX]) || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX]) || SYMBOLP (attrs[LFACE_BOX_INDEX]) || STRINGP (attrs[LFACE_BOX_INDEX]) || INTEGERP (attrs[LFACE_BOX_INDEX]) || CONSP (attrs[LFACE_BOX_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX]) || SYMBOLP (attrs[LFACE_INVERSE_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX]) || STRINGP (attrs[LFACE_FOREGROUND_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX]) || STRINGP (attrs[LFACE_BACKGROUND_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX]) || NILP (attrs[LFACE_INHERIT_INDEX]) || SYMBOLP (attrs[LFACE_INHERIT_INDEX]) || CONSP (attrs[LFACE_INHERIT_INDEX])); #ifdef HAVE_WINDOW_SYSTEM - xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX]) || SYMBOLP (attrs[LFACE_STIPPLE_INDEX]) || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX]))); - xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX]) || FONTP (attrs[LFACE_FONT_INDEX])); - xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX]) + eassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX]) || STRINGP (attrs[LFACE_FONTSET_INDEX]) || NILP (attrs[LFACE_FONTSET_INDEX])); #endif @@ -1940,17 +1946,17 @@ check_lface (Lisp_Object lface) { if (!NILP (lface)) { - xassert (LFACEP (lface)); + eassert (LFACEP (lface)); check_lface_attrs (XVECTOR (lface)->contents); } } -#else /* GLYPH_DEBUG == 0 */ +#else /* not GLYPH_DEBUG */ #define check_lface_attrs(attrs) (void) 0 #define check_lface(lface) (void) 0 -#endif /* GLYPH_DEBUG == 0 */ +#endif /* GLYPH_DEBUG */ @@ -2217,7 +2223,7 @@ set_lface_from_font (struct frame *f, Lisp_Object lface, { int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy); - xassert (pt > 0); + eassert (pt > 0); LFACE_HEIGHT (lface) = make_number (pt); } @@ -2263,7 +2269,7 @@ merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid) { if (INTEGERP (to)) /* relative X absolute => absolute */ - result = make_number ((EMACS_INT)(XFLOAT_DATA (from) * XINT (to))); + result = make_number (XFLOAT_DATA (from) * XINT (to)); else if (FLOATP (to)) /* relative X relative => relative */ result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to)); @@ -2520,7 +2526,8 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, { if (EQ (value, Qt) || NILP (value) - || STRINGP (value)) + || STRINGP (value) + || CONSP (value)) to[LFACE_UNDERLINE_INDEX] = value; else err = 1; @@ -2683,8 +2690,7 @@ Value is a vector of face attributes. */) property `face' of the Lisp face name. */ if (next_lface_id == lface_id_to_name_size) lface_id_to_name = - xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, - min (INT_MAX, MOST_POSITIVE_FIXNUM), + xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, MAX_FACE_ID, sizeof *lface_id_to_name); lface_id_to_name[next_lface_id] = face; @@ -2723,7 +2729,7 @@ Value is a vector of face attributes. */) ++windows_or_buffers_changed; } - xassert (LFACEP (lface)); + eassert (LFACEP (lface)); check_lface (lface); return lface; } @@ -2944,15 +2950,54 @@ FRAME 0 means change the face on all frames, and change the default } else if (EQ (attr, QCunderline)) { - if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) - if ((SYMBOLP (value) - && !EQ (value, Qt) - && !EQ (value, Qnil)) - /* Underline color. */ - || (STRINGP (value) - && SCHARS (value) == 0)) - signal_error ("Invalid face underline", value); - + int valid_p = 0; + + if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value)) + valid_p = 1; + else if (NILP (value) || EQ (value, Qt)) + valid_p = 1; + else if (STRINGP (value) && SCHARS (value) > 0) + valid_p = 1; + else if (CONSP (value)) + { + Lisp_Object key, val, list; + + list = value; + valid_p = 1; + + while (!NILP (CAR_SAFE(list))) + { + key = CAR_SAFE (list); + list = CDR_SAFE (list); + val = CAR_SAFE (list); + list = CDR_SAFE (list); + + if(NILP (key) || NILP (val)) + { + valid_p = 0; + break; + } + + else if (EQ (key, QCcolor) + && !(EQ (val, Qforeground_color) + || (STRINGP (val) && SCHARS (val) > 0))) + { + valid_p = 0; + break; + } + + else if (EQ (key, QCstyle) + && !(EQ (val, Qline) || EQ (val, Qwave))) + { + valid_p = 0; + break; + } + } + } + + if (!valid_p) + signal_error ("Invalid face underline", value); + old_value = LFACE_UNDERLINE (lface); LFACE_UNDERLINE (lface) = value; } @@ -3468,7 +3513,7 @@ face_boolean_x_resource_value (Lisp_Object value, int signal_p) { Lisp_Object result = make_number (0); - xassert (STRINGP (value)); + eassert (STRINGP (value)); if (xstrcasecmp (SSDATA (value), "on") == 0 || xstrcasecmp (SSDATA (value), "true") == 0) @@ -4041,7 +4086,7 @@ hash_string_case_insensitive (Lisp_Object string) { const unsigned char *s; unsigned hash = 0; - xassert (STRINGP (string)); + eassert (STRINGP (string)); for (s = SDATA (string); *s; ++s) hash = (hash << 1) ^ tolower (*s); return hash; @@ -4072,7 +4117,7 @@ lface_hash (Lisp_Object *v) static inline int lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2) { - xassert (lface_fully_specified_p (lface1) + eassert (lface_fully_specified_p (lface1) && lface_fully_specified_p (lface2)); return (xstrcasecmp (SSDATA (lface1[LFACE_FAMILY_INDEX]), SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0 @@ -4153,7 +4198,7 @@ void prepare_face_for_display (struct frame *f, struct face *face) { #ifdef HAVE_WINDOW_SYSTEM - xassert (FRAME_WINDOW_P (f)); + eassert (FRAME_WINDOW_P (f)); if (face->gc == 0) { @@ -4414,7 +4459,7 @@ cache_face (struct face_cache *c, struct face *face, unsigned int hash) break; face->id = i; -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG /* Check that FACE got a unique id. */ { int j, n; @@ -4425,7 +4470,7 @@ cache_face (struct face_cache *c, struct face *face, unsigned int hash) if (face1->id == i) ++n; - xassert (n == 1); + eassert (n == 1); } #endif /* GLYPH_DEBUG */ @@ -4476,7 +4521,7 @@ lookup_face (struct frame *f, Lisp_Object *attr) int i; struct face *face; - xassert (cache != NULL); + eassert (cache != NULL); check_lface_attrs (attr); /* Look up ATTR in the face cache. */ @@ -4500,8 +4545,8 @@ lookup_face (struct frame *f, Lisp_Object *attr) if (face == NULL) face = realize_face (cache, attr, -1); -#if GLYPH_DEBUG - xassert (face == FACE_FROM_ID (f, face->id)); +#ifdef GLYPH_DEBUG + eassert (face == FACE_FROM_ID (f, face->id)); #endif /* GLYPH_DEBUG */ return face->id; @@ -4522,7 +4567,7 @@ face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) int i; struct face *face; - xassert (cache != NULL); + eassert (cache != NULL); base_face = base_face->ascii_face; hash = lface_hash (base_face->lface); i = hash % FACE_CACHE_BUCKETS_SIZE; @@ -4575,7 +4620,7 @@ lookup_named_face (struct frame *f, Lisp_Object symbol, int signal_p) } -/* Return the display face-id of the basic face who's canonical face-id +/* Return the display face-id of the basic face whose 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 @@ -4880,14 +4925,13 @@ static int tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *def_face) { - int weight; + int weight, slant; Lisp_Object val, fg, bg; XColor fg_tty_color, fg_std_color; XColor bg_tty_color, bg_std_color; unsigned test_caps = 0; Lisp_Object *def_attrs = def_face->lface; - /* First check some easy-to-check stuff; ttys support none of the following attributes, so we can just return false if any are requested (even if `nominal' values are specified, we should still return false, @@ -4903,11 +4947,9 @@ tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX]) - || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX]) - || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])) + || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])) return 0; - /* Test for terminal `capabilities' (non-color character attributes). */ /* font weight (bold/dim) */ @@ -4933,6 +4975,18 @@ tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, return 0; /* same as default */ } + /* font slant */ + val = attrs[LFACE_SLANT_INDEX]; + if (!UNSPECIFIEDP (val) + && (slant = FONT_SLANT_NAME_NUMERIC (val), slant >= 0)) + { + int def_slant = FONT_SLANT_NAME_NUMERIC (def_attrs[LFACE_SLANT_INDEX]); + if (slant == 100 || slant == def_slant) + return 0; /* same as default */ + else + test_caps |= TTY_CAP_ITALIC; + } + /* underlining */ val = attrs[LFACE_UNDERLINE_INDEX]; if (!UNSPECIFIEDP (val)) @@ -5277,7 +5331,7 @@ static int realize_basic_faces (struct frame *f) { int success_p = 0; - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); /* Block input here so that we won't be surprised by an X expose event, for instance, without having the faces set up. */ @@ -5332,11 +5386,11 @@ realize_default_face (struct frame *f) /* If the `default' face is not yet known, create it. */ lface = lface_from_face_name (f, Qdefault, 0); if (NILP (lface)) - { + { Lisp_Object frame; XSETFRAME (frame, f); lface = Finternal_make_lisp_face (Qdefault, frame); - } + } #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) @@ -5414,7 +5468,7 @@ realize_default_face (struct frame *f) LFACE_STIPPLE (lface) = Qnil; /* Realize the face; it must be fully-specified now. */ - xassert (lface_fully_specified_p (XVECTOR (lface)->contents)); + eassert (lface_fully_specified_p (XVECTOR (lface)->contents)); check_lface (lface); memcpy (attrs, XVECTOR (lface)->contents, sizeof attrs); face = realize_face (c, attrs, DEFAULT_FACE_ID); @@ -5455,7 +5509,7 @@ realize_named_face (struct frame *f, Lisp_Object symbol, int id) /* The default face must exist and be fully specified. */ get_lface_attributes_no_remap (f, Qdefault, attrs, 1); check_lface_attrs (attrs); - xassert (lface_fully_specified_p (attrs)); + eassert (lface_fully_specified_p (attrs)); /* If SYMBOL isn't know as a face, create it. */ if (NILP (lface)) @@ -5485,7 +5539,7 @@ realize_face (struct face_cache *cache, Lisp_Object *attrs, int former_face_id) struct face *face; /* LFACE must be fully specified. */ - xassert (cache != NULL); + eassert (cache != NULL); check_lface_attrs (attrs); if (former_face_id >= 0 && cache->used > former_face_id) @@ -5563,9 +5617,9 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs) #ifdef HAVE_WINDOW_SYSTEM struct face *default_face; struct frame *f; - Lisp_Object stipple, overline, strike_through, box; + Lisp_Object stipple, underline, overline, strike_through, box; - xassert (FRAME_WINDOW_P (cache->f)); + eassert (FRAME_WINDOW_P (cache->f)); /* Allocate a new realized face. */ face = make_realized_face (attrs); @@ -5643,7 +5697,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs) { /* Simple box of specified line width in foreground color of the face. */ - xassert (XINT (box) != 0); + eassert (XINT (box) != 0); face->box = FACE_SIMPLE_BOX; face->box_line_width = XINT (box); face->box_color = face->foreground; @@ -5696,29 +5750,76 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs) /* Text underline, overline, strike-through. */ - if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt)) + underline = attrs[LFACE_UNDERLINE_INDEX]; + if (EQ (underline, Qt)) { /* Use default color (same as foreground color). */ face->underline_p = 1; + face->underline_type = FACE_UNDER_LINE; face->underline_defaulted_p = 1; face->underline_color = 0; } - else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX])) + else if (STRINGP (underline)) { /* Use specified color. */ face->underline_p = 1; + face->underline_type = FACE_UNDER_LINE; face->underline_defaulted_p = 0; face->underline_color - = load_color (f, face, attrs[LFACE_UNDERLINE_INDEX], + = load_color (f, face, underline, LFACE_UNDERLINE_INDEX); } - else if (NILP (attrs[LFACE_UNDERLINE_INDEX])) + else if (NILP (underline)) { face->underline_p = 0; face->underline_defaulted_p = 0; face->underline_color = 0; } - + else if (CONSP (underline)) + { + /* `(:color COLOR :style STYLE)'. + STYLE being one of `line' or `wave'. */ + face->underline_p = 1; + face->underline_color = 0; + face->underline_defaulted_p = 1; + face->underline_type = FACE_UNDER_LINE; + + while (CONSP (underline)) + { + Lisp_Object keyword, value; + + keyword = XCAR (underline); + underline = XCDR (underline); + + if (!CONSP (underline)) + break; + value = XCAR (underline); + underline = XCDR (underline); + + if (EQ (keyword, QCcolor)) + { + if (EQ (value, Qforeground_color)) + { + face->underline_defaulted_p = 1; + face->underline_color = 0; + } + else if (STRINGP (value)) + { + face->underline_defaulted_p = 0; + face->underline_color = load_color (f, face, value, + LFACE_UNDERLINE_INDEX); + } + } + else if (EQ (keyword, QCstyle)) + { + if (EQ (value, Qline)) + face->underline_type = FACE_UNDER_LINE; + else if (EQ (value, Qwave)) + face->underline_type = FACE_UNDER_WAVE; + } + } + } + overline = attrs[LFACE_OVERLINE_INDEX]; if (STRINGP (overline)) { @@ -5777,7 +5878,7 @@ map_tty_color (struct frame *f, struct face *face, foreground_p ? FACE_TTY_DEFAULT_BG_COLOR : FACE_TTY_DEFAULT_FG_COLOR; #endif - xassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX); + eassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX); XSETFRAME (frame, f); color = face->lface[idx]; @@ -5845,7 +5946,7 @@ realize_tty_face (struct face_cache *cache, Lisp_Object *attrs) struct frame *f = cache->f; /* Frame must be a termcap frame. */ - xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f)); + eassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f)); /* Allocate a new realized face. */ face = make_realized_face (attrs); @@ -5853,15 +5954,13 @@ realize_tty_face (struct face_cache *cache, Lisp_Object *attrs) face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty"; #endif - /* Map face attributes to TTY appearances. We map slant to - dimmed text because we want italic text to appear differently - and because dimmed text is probably used infrequently. */ + /* Map face attributes to TTY appearances. */ weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]); slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]); if (weight > 100) face->tty_bold_p = 1; - if (weight < 100 || slant != 100) - face->tty_dim_p = 1; + if (slant != 100) + face->tty_italic_p = 1; if (!NILP (attrs[LFACE_UNDERLINE_INDEX])) face->tty_underline_p = 1; if (!NILP (attrs[LFACE_INVERSE_INDEX])) @@ -5960,9 +6059,9 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) The face returned is suitable for displaying ASCII characters. */ int -face_at_buffer_position (struct window *w, EMACS_INT pos, - EMACS_INT region_beg, EMACS_INT region_end, - EMACS_INT *endptr, EMACS_INT limit, +face_at_buffer_position (struct window *w, ptrdiff_t pos, + ptrdiff_t region_beg, ptrdiff_t region_end, + ptrdiff_t *endptr, ptrdiff_t limit, int mouse, int base_face_id) { struct frame *f = XFRAME (w->frame); @@ -5971,14 +6070,14 @@ face_at_buffer_position (struct window *w, EMACS_INT pos, ptrdiff_t i, noverlays; Lisp_Object *overlay_vec; Lisp_Object frame; - EMACS_INT endpos; + ptrdiff_t endpos; Lisp_Object propname = mouse ? Qmouse_face : Qface; Lisp_Object limit1, end; struct face *default_face; /* W must display the current buffer. We could write this function to use the frame and buffer of W, but right now it doesn't. */ - /* xassert (XBUFFER (w->buffer) == current_buffer); */ + /* eassert (XBUFFER (w->buffer) == current_buffer); */ XSETFRAME (frame, f); XSETFASTINT (position, pos); @@ -5997,7 +6096,7 @@ face_at_buffer_position (struct window *w, EMACS_INT pos, /* Look at properties from overlays. */ { - EMACS_INT next_overlay; + ptrdiff_t next_overlay; GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0); if (next_overlay < endpos) @@ -6072,9 +6171,9 @@ face_at_buffer_position (struct window *w, EMACS_INT pos, simply disregards the `face' properties of all overlays. */ int -face_for_overlay_string (struct window *w, EMACS_INT pos, - EMACS_INT region_beg, EMACS_INT region_end, - EMACS_INT *endptr, EMACS_INT limit, +face_for_overlay_string (struct window *w, ptrdiff_t pos, + ptrdiff_t region_beg, ptrdiff_t region_end, + ptrdiff_t *endptr, ptrdiff_t limit, int mouse, Lisp_Object overlay) { struct frame *f = XFRAME (w->frame); @@ -6088,7 +6187,7 @@ face_for_overlay_string (struct window *w, EMACS_INT pos, /* W must display the current buffer. We could write this function to use the frame and buffer of W, but right now it doesn't. */ - /* xassert (XBUFFER (w->buffer) == current_buffer); */ + /* eassert (XBUFFER (w->buffer) == current_buffer); */ XSETFRAME (frame, f); XSETFASTINT (position, pos); @@ -6107,14 +6206,14 @@ face_for_overlay_string (struct window *w, EMACS_INT pos, *endptr = endpos; - default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); - - /* Optimize common cases where we can use the default face. */ + /* Optimize common case where we can use the default face. */ if (NILP (prop) - && !(pos >= region_beg && pos < region_end)) + && !(pos >= region_beg && pos < region_end) + && NILP (Vface_remapping_alist)) return DEFAULT_FACE_ID; /* Begin with attributes from the default face. */ + default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID)); memcpy (attrs, default_face->lface, sizeof attrs); /* Merge in attributes specified via text properties. */ @@ -6161,9 +6260,9 @@ face_for_overlay_string (struct window *w, EMACS_INT pos, int face_at_string_position (struct window *w, Lisp_Object string, - EMACS_INT pos, EMACS_INT bufpos, - EMACS_INT region_beg, EMACS_INT region_end, - EMACS_INT *endptr, enum face_id base_face_id, + ptrdiff_t pos, ptrdiff_t bufpos, + ptrdiff_t region_beg, ptrdiff_t region_end, + ptrdiff_t *endptr, enum face_id base_face_id, int mouse_p) { Lisp_Object prop, position, end, limit; @@ -6192,7 +6291,7 @@ face_at_string_position (struct window *w, Lisp_Object string, *endptr = -1; base_face = FACE_FROM_ID (f, base_face_id); - xassert (base_face); + eassert (base_face); /* Optimize the default case that there is no face property and we are not in the region. */ @@ -6246,7 +6345,7 @@ face_at_string_position (struct window *w, Lisp_Object string, */ int -merge_faces (struct frame *f, Lisp_Object face_name, EMACS_INT face_id, +merge_faces (struct frame *f, Lisp_Object face_name, int face_id, int base_face_id) { Lisp_Object attrs[LFACE_VECTOR_SIZE]; @@ -6349,7 +6448,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */) Tests ***********************************************************************/ -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG /* Print the contents of the realized face FACE to stderr. */ @@ -6424,7 +6523,7 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources, return Qnil; } -#endif /* GLYPH_DEBUG != 0 */ +#endif /* GLYPH_DEBUG */ @@ -6465,6 +6564,8 @@ syms_of_xfaces (void) DEFSYM (QCcolor, ":color"); DEFSYM (QCline_width, ":line-width"); DEFSYM (QCstyle, ":style"); + DEFSYM (Qline, "line"); + DEFSYM (Qwave, "wave"); DEFSYM (Qreleased_button, "released-button"); DEFSYM (Qpressed_button, "pressed-button"); DEFSYM (Qnormal, "normal"); @@ -6546,7 +6647,7 @@ syms_of_xfaces (void) defsubr (&Sinternal_set_alternative_font_family_alist); defsubr (&Sinternal_set_alternative_font_registry_alist); defsubr (&Sface_attributes_as_vector); -#if GLYPH_DEBUG +#ifdef GLYPH_DEBUG defsubr (&Sdump_face); defsubr (&Sshow_face_resources); #endif /* GLYPH_DEBUG */