Commit 28655de4 authored by Jimmy Aguilar Mena's avatar Jimmy Aguilar Mena

Conditional merged face to extend after eol.

The face used in extend_face_to_end_of_line is not the same than in
the text before anymore.
The display engine uses the :extend parameter in the faces to
conditionally merge and create a new id if needed.
parent 6a3808cc
...@@ -3459,8 +3459,8 @@ int lookup_derived_face (struct window *, struct frame *, ...@@ -3459,8 +3459,8 @@ int lookup_derived_face (struct window *, struct frame *,
void init_frame_faces (struct frame *); void init_frame_faces (struct frame *);
void free_frame_faces (struct frame *); void free_frame_faces (struct frame *);
void recompute_basic_faces (struct frame *); void recompute_basic_faces (struct frame *);
int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *,
bool, int); ptrdiff_t, bool, int, enum lface_attribute_index);
int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t,
bool, Lisp_Object); bool, Lisp_Object);
int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t,
......
...@@ -3781,10 +3781,10 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, ...@@ -3781,10 +3781,10 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
if (STRINGP (string)) if (STRINGP (string))
face_id = face_at_string_position (w, string, pos, 0, &endptr, face_id = face_at_string_position (w, string, pos, 0, &endptr,
DEFAULT_FACE_ID, false); DEFAULT_FACE_ID, 0);
else else
face_id = face_at_buffer_position (w, pos, &endptr, face_id = face_at_buffer_position (w, pos, &endptr,
pos + 100, false, -1); pos + 100, false, -1, 0);
face = FACE_FROM_ID (f, face_id); face = FACE_FROM_ID (f, face_id);
} }
if (multibyte) if (multibyte)
...@@ -3828,7 +3828,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, ...@@ -3828,7 +3828,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
if (NILP (string)) if (NILP (string))
face_id = face_at_buffer_position (w, pos, &ignore, *limit, face_id = face_at_buffer_position (w, pos, &ignore, *limit,
false, -1); false, -1, 0);
else else
{ {
face_id = face_id =
...@@ -4614,7 +4614,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, ...@@ -4614,7 +4614,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
w = XWINDOW (window); w = XWINDOW (window);
f = XFRAME (w->frame); f = XFRAME (w->frame);
face_id = face_at_buffer_position (w, pos, &dummy, face_id = face_at_buffer_position (w, pos, &dummy,
pos + 100, false, -1); pos + 100, false, -1, 0);
} }
if (! CHAR_VALID_P (c)) if (! CHAR_VALID_P (c))
return Qnil; return Qnil;
......
...@@ -4105,15 +4105,18 @@ handle_fontified_prop (struct it *it) ...@@ -4105,15 +4105,18 @@ handle_fontified_prop (struct it *it)
Faces Faces
***********************************************************************/ ***********************************************************************/
/* Set up iterator IT from face properties at its current position.
Called from handle_stop. */
static enum prop_handled static enum prop_handled
handle_face_prop (struct it *it) handle_face_prop_general (struct it *it,
enum lface_attribute_index attr_filter)
{ {
int new_face_id; int new_face_id, *face_id_ptr;
ptrdiff_t next_stop; ptrdiff_t next_stop;
if (attr_filter == LFACE_EXTEND_INDEX)
face_id_ptr = &(it->extend_face_id);
else
face_id_ptr = &(it->face_id);
if (!STRINGP (it->string)) if (!STRINGP (it->string))
{ {
new_face_id new_face_id
...@@ -4122,7 +4125,7 @@ handle_face_prop (struct it *it) ...@@ -4122,7 +4125,7 @@ handle_face_prop (struct it *it)
&next_stop, &next_stop,
(IT_CHARPOS (*it) (IT_CHARPOS (*it)
+ TEXT_PROP_DISTANCE_LIMIT), + TEXT_PROP_DISTANCE_LIMIT),
false, it->base_face_id); false, it->base_face_id, attr_filter);
/* Is this a start of a run of characters with box face? /* Is this a start of a run of characters with box face?
Caveat: this can be called for a freshly initialized Caveat: this can be called for a freshly initialized
...@@ -4130,13 +4133,13 @@ handle_face_prop (struct it *it) ...@@ -4130,13 +4133,13 @@ handle_face_prop (struct it *it)
face will not change until limit, i.e. if the new face has a face will not change until limit, i.e. if the new face has a
box, all characters up to limit will have one. But, as box, all characters up to limit will have one. But, as
usual, we don't know whether limit is really the end. */ usual, we don't know whether limit is really the end. */
if (new_face_id != it->face_id) if (new_face_id != *face_id_ptr)
{ {
struct face *new_face = FACE_FROM_ID (it->f, new_face_id); struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
/* If it->face_id is -1, old_face below will be NULL, see /* If it->face_id is -1, old_face below will be NULL, see
the definition of FACE_FROM_ID_OR_NULL. This will happen the definition of FACE_FROM_ID_OR_NULL. This will happen
if this is the initial call that gets the face. */ if this is the initial call that gets the face. */
struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr);
/* If the value of face_id of the iterator is -1, we have to /* If the value of face_id of the iterator is -1, we have to
look in front of IT's position and see whether there is a look in front of IT's position and see whether there is a
...@@ -4242,10 +4245,10 @@ handle_face_prop (struct it *it) ...@@ -4242,10 +4245,10 @@ handle_face_prop (struct it *it)
box, all characters up to that position will have a box, all characters up to that position will have a
box. But, as usual, we don't know whether that position box. But, as usual, we don't know whether that position
is really the end. */ is really the end. */
if (new_face_id != it->face_id) if (new_face_id != *face_id_ptr)
{ {
struct face *new_face = FACE_FROM_ID (it->f, new_face_id); struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr);
/* If new face has a box but old face hasn't, this is the /* If new face has a box but old face hasn't, this is the
start of a run of characters with box, i.e. it has a start of a run of characters with box, i.e. it has a
...@@ -4256,11 +4259,21 @@ handle_face_prop (struct it *it) ...@@ -4256,11 +4259,21 @@ handle_face_prop (struct it *it)
} }
} }
it->face_id = new_face_id; *face_id_ptr = new_face_id;
return HANDLED_NORMALLY; return HANDLED_NORMALLY;
} }
/* Set up iterator IT from face properties at its current position.
Called from handle_stop. */
static enum prop_handled
handle_face_prop (struct it *it)
{
return handle_face_prop_general (it, 0);
}
/* Return the ID of the face ``underlying'' IT's current position, /* Return the ID of the face ``underlying'' IT's current position,
which is in a string. If the iterator is associated with a which is in a string. If the iterator is associated with a
buffer, return the face at IT's current buffer position. buffer, return the face at IT's current buffer position.
...@@ -4484,7 +4497,7 @@ face_before_or_after_it_pos (struct it *it, bool before_p) ...@@ -4484,7 +4497,7 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
face_id = face_at_buffer_position (it->w, face_id = face_at_buffer_position (it->w,
CHARPOS (pos), CHARPOS (pos),
&next_check_charpos, &next_check_charpos,
limit, false, -1); limit, false, -1, 0);
/* Correct the face for charsets different from ASCII. Do it /* Correct the face for charsets different from ASCII. Do it
for the multibyte case only. The face returned above is for the multibyte case only. The face returned above is
...@@ -7606,10 +7619,11 @@ get_next_display_element (struct it *it) ...@@ -7606,10 +7619,11 @@ get_next_display_element (struct it *it)
else else
{ {
next_face_id = next_face_id =
face_at_buffer_position (it->w, CHARPOS (pos), &ignore, face_at_buffer_position (it->w, CHARPOS (pos),
&ignore,
CHARPOS (pos) CHARPOS (pos)
+ TEXT_PROP_DISTANCE_LIMIT, + TEXT_PROP_DISTANCE_LIMIT,
false, -1); false, -1, 0);
it->end_of_box_run_p it->end_of_box_run_p
= (FACE_FROM_ID (it->f, next_face_id)->box = (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX); == FACE_NO_BOX);
...@@ -20494,12 +20508,14 @@ extend_face_to_end_of_line (struct it *it) ...@@ -20494,12 +20508,14 @@ extend_face_to_end_of_line (struct it *it)
|| WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
return; return;
/* Face extension extends the background and box of IT->face_id handle_face_prop_general (it, LFACE_EXTEND_INDEX);
/* Face extension extends the background and box of IT->extend_face_id
to the end of the line. If the background equals the background to the end of the line. If the background equals the background
of the frame, we don't have to do anything. */ of the frame, we don't have to do anything. */
face = FACE_FROM_ID (f, (it->face_before_selective_p face = FACE_FROM_ID (f, (it->face_before_selective_p
? it->saved_face_id ? it->saved_face_id
: it->face_id)); : it->extend_face_id));
if (FRAME_WINDOW_P (f) if (FRAME_WINDOW_P (f)
&& MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
...@@ -20522,9 +20538,7 @@ extend_face_to_end_of_line (struct it *it) ...@@ -20522,9 +20538,7 @@ extend_face_to_end_of_line (struct it *it)
that the character will always be single byte in unibyte that the character will always be single byte in unibyte
text. */ text. */
if (!ASCII_CHAR_P (it->c)) if (!ASCII_CHAR_P (it->c))
{
it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil); it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
}
/* The default face, possibly remapped. */ /* The default face, possibly remapped. */
struct face *default_face = struct face *default_face =
...@@ -20573,79 +20587,86 @@ extend_face_to_end_of_line (struct it *it) ...@@ -20573,79 +20587,86 @@ extend_face_to_end_of_line (struct it *it)
/* Display fill column indicator if not in modeline or /* Display fill column indicator if not in modeline or
toolbar and display fill column indicator mode is toolbar and display fill column indicator mode is
active. */ active. */
int indicator_column = (it->w->pseudo_window_p == 0 const int indicator_column = (it->w->pseudo_window_p == 0
? fill_column_indicator_column (it) ? fill_column_indicator_column (it)
: -1); : -1);
if (indicator_column >= 0)
struct font *font = (default_face->font
? default_face->font
: FRAME_FONT (f));
const int char_width = (font->average_width
? font->average_width
: font->space_width);
int column_x;
const char saved_char = it->char_to_display;
const struct text_pos saved_pos = it->position;
const bool saved_avoid_cursor = it->avoid_cursor_p;
const bool saved_box_start = it->start_of_box_run_p;
Lisp_Object save_object = it->object;
const int saved_face_id = it->face_id;
it->face_id = it->extend_face_id;
if (indicator_column >= 0
&& !INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x)
&& !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x)
&& column_x >= it->current_x
&& column_x <= it->last_visible_x)
{ {
struct font *font = (default_face->font
? default_face->font
: FRAME_FONT (f));
const int char_width = (font->average_width
? font->average_width
: font->space_width);
int column_x;
if (!INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x)
&& !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x)
&& column_x >= it->current_x
&& column_x <= it->last_visible_x)
{
const char saved_char = it->char_to_display;
const struct text_pos saved_pos = it->position;
const bool saved_avoid_cursor = it->avoid_cursor_p;
const int saved_face_id = it->face_id;
const bool saved_box_start = it->start_of_box_run_p;
Lisp_Object save_object = it->object;
/* The stretch width needs to considet the latter
added glyph. */
const int stretch_width
= column_x - it->current_x - char_width;
memset (&it->position, 0, sizeof it->position);
it->avoid_cursor_p = true;
it->object = Qnil;
/* Only generate a stretch glyph if there is distance
between current_x and and the indicator position. */
if (stretch_width > 0)
{
int stretch_ascent = (((it->ascent + it->descent)
* FONT_BASE (font)) / FONT_HEIGHT (font));
append_stretch_glyph (it, Qnil, stretch_width,
it->ascent + it->descent,
stretch_ascent);
}
/* Generate the glyph indicator only if /* The stretch width needs to considet the latter
append_space_for_newline didn't already. */ added glyph. */
if (it->current_x < column_x) const int stretch_width
{ = column_x - it->current_x - char_width;
it->char_to_display
= XFIXNAT (Vdisplay_fill_column_indicator_character); memset (&it->position, 0, sizeof it->position);
it->face_id it->avoid_cursor_p = true;
= merge_faces (it->w, Qfill_column_indicator, it->object = Qnil;
0, saved_face_id);
PRODUCE_GLYPHS (it); /* Only generate a stretch glyph if there is distance
} between current_x and and the indicator position. */
if (stretch_width > 0)
/* Restore the face after the indicator was generated. */ {
it->face_id = saved_face_id; int stretch_ascent = (((it->ascent + it->descent)
* FONT_BASE (font)) / FONT_HEIGHT (font));
/* If there is space after the indicator generate an append_stretch_glyph (it, Qnil, stretch_width,
extra empty glyph to restore the face. Issue was it->ascent + it->descent,
observed in X systems. */ stretch_ascent);
it->char_to_display = ' '; }
PRODUCE_GLYPHS (it);
/* Generate the glyph indicator only if
it->char_to_display = saved_char; append_space_for_newline didn't already. */
it->position = saved_pos; if (it->current_x < column_x)
it->avoid_cursor_p = saved_avoid_cursor; {
it->start_of_box_run_p = saved_box_start; const int save_face_id = it->face_id;
it->object = save_object; it->char_to_display
} = XFIXNAT (Vdisplay_fill_column_indicator_character);
it->face_id
= merge_faces (it->w, Qfill_column_indicator,
0, it->extend_face_id);
PRODUCE_GLYPHS (it);
it->face_id = save_face_id;
}
} }
/* Restore the face after the indicator was generated. */
/* If there is space after the indicator generate an
extra empty glyph to restore the face. Issue was
observed in X systems. */
it->char_to_display = ' ';
PRODUCE_GLYPHS (it);
it->char_to_display = saved_char;
it->position = saved_pos;
it->avoid_cursor_p = saved_avoid_cursor;
it->start_of_box_run_p = saved_box_start;
it->object = save_object;
it->face_id = saved_face_id;
} }
if (it->glyph_row->reversed_p) if (it->glyph_row->reversed_p)
{ {
...@@ -20691,10 +20712,9 @@ extend_face_to_end_of_line (struct it *it) ...@@ -20691,10 +20712,9 @@ extend_face_to_end_of_line (struct it *it)
/* The last row's stretch glyph should get the default /* The last row's stretch glyph should get the default
face, to avoid painting the rest of the window with face, to avoid painting the rest of the window with
the region face, if the region ends at ZV. */ the region face, if the region ends at ZV. */
if (it->glyph_row->ends_at_zv_p) it->face_id = (it->glyph_row->ends_at_zv_p ?
it->face_id = default_face->id; default_face->id : face->id);
else
it->face_id = face->id;
it->start_of_box_run_p = false; it->start_of_box_run_p = false;
append_stretch_glyph (it, Qnil, stretch_width, append_stretch_glyph (it, Qnil, stretch_width,
it->ascent + it->descent, stretch_ascent); it->ascent + it->descent, stretch_ascent);
...@@ -20716,14 +20736,11 @@ extend_face_to_end_of_line (struct it *it) ...@@ -20716,14 +20736,11 @@ extend_face_to_end_of_line (struct it *it)
{ {
/* Save some values that must not be changed. */ /* Save some values that must not be changed. */
int saved_x = it->current_x; int saved_x = it->current_x;
struct text_pos saved_pos; struct text_pos saved_pos = it->position;
Lisp_Object saved_object; Lisp_Object saved_object = it->object;;
enum display_element_type saved_what = it->what; enum display_element_type saved_what = it->what;
int saved_face_id = it->face_id; int saved_face_id = it->face_id;
saved_object = it->object;
saved_pos = it->position;
it->what = IT_CHARACTER; it->what = IT_CHARACTER;
memset (&it->position, 0, sizeof it->position); memset (&it->position, 0, sizeof it->position);
it->object = Qnil; it->object = Qnil;
...@@ -20762,10 +20779,8 @@ extend_face_to_end_of_line (struct it *it) ...@@ -20762,10 +20779,8 @@ extend_face_to_end_of_line (struct it *it)
/* The last row's blank glyphs should get the default face, to /* The last row's blank glyphs should get the default face, to
avoid painting the rest of the window with the region face, avoid painting the rest of the window with the region face,
if the region ends at ZV. */ if the region ends at ZV. */
if (it->glyph_row->ends_at_zv_p) it->face_id = (it->glyph_row->ends_at_zv_p ?
it->face_id = default_face->id; default_face->id : face->id);
else
it->face_id = face->id;
/* Display fill-column indicator if needed. */ /* Display fill-column indicator if needed. */
int indicator_column = fill_column_indicator_column (it); int indicator_column = fill_column_indicator_column (it);
...@@ -20775,24 +20790,21 @@ extend_face_to_end_of_line (struct it *it) ...@@ -20775,24 +20790,21 @@ extend_face_to_end_of_line (struct it *it)
indicator_column = -1; indicator_column = -1;
do do
{ {
int saved_face_id; if (it->current_x == indicator_column)
bool indicate = it->current_x == indicator_column;
if (indicate)
{ {
saved_face_id = it->face_id; int saved_face_id = it->face_id;
it->face_id it->face_id
= merge_faces (it->w, Qfill_column_indicator, 0, saved_face_id); = merge_faces (it->w, Qfill_column_indicator, 0, it->extend_face_id);
it->c = it->char_to_display it->c = it->char_to_display
= XFIXNAT (Vdisplay_fill_column_indicator_character); = XFIXNAT (Vdisplay_fill_column_indicator_character);
}
PRODUCE_GLYPHS (it); PRODUCE_GLYPHS (it);
if (indicate)
{
it->face_id = saved_face_id; it->face_id = saved_face_id;
it->c = it->char_to_display = ' '; it->c = it->char_to_display = ' ';
} }
else
PRODUCE_GLYPHS (it);
} }
while (it->current_x <= it->last_visible_x); while (it->current_x <= it->last_visible_x);
...@@ -30931,7 +30943,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, ...@@ -30931,7 +30943,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
hlinfo->mouse_face_face_id hlinfo->mouse_face_face_id
= face_at_buffer_position (w, mouse_charpos, &ignore, = face_at_buffer_position (w, mouse_charpos, &ignore,
mouse_charpos + 1, mouse_charpos + 1,
!hlinfo->mouse_face_hidden, -1); !hlinfo->mouse_face_hidden, -1, 0);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE); show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
} }
...@@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *); ...@@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *);
static void free_face_cache (struct face_cache *); static void free_face_cache (struct face_cache *);
static bool merge_face_ref (struct window *w, static bool merge_face_ref (struct window *w,
struct frame *, Lisp_Object, Lisp_Object *, struct frame *, Lisp_Object, Lisp_Object *,
bool, struct named_merge_point *); bool, struct named_merge_point *,
enum lface_attribute_index);
static int color_distance (Emacs_Color *x, Emacs_Color *y); static int color_distance (Emacs_Color *x, Emacs_Color *y);
#ifdef HAVE_WINDOW_SYSTEM #ifdef HAVE_WINDOW_SYSTEM
...@@ -1910,7 +1911,8 @@ get_lface_attributes (struct window *w, ...@@ -1910,7 +1911,8 @@ get_lface_attributes (struct window *w,
attrs[i] = Qunspecified; attrs[i] = Qunspecified;
return merge_face_ref (w, f, XCDR (face_remapping), attrs, return merge_face_ref (w, f, XCDR (face_remapping), attrs,
signal_p, named_merge_points); signal_p, named_merge_points,
0);
} }
} }
...@@ -2065,7 +2067,8 @@ merge_face_vectors (struct window *w, ...@@ -2065,7 +2067,8 @@ merge_face_vectors (struct window *w,
if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
&& !NILP (from[LFACE_INHERIT_INDEX])) && !NILP (from[LFACE_INHERIT_INDEX]))
merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], merge_face_ref (w, f, from[LFACE_INHERIT_INDEX],
to, false, named_merge_points); to, false, named_merge_points,
0);
if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) if (FONT_SPEC_P (from[LFACE_FONT_INDEX]))
{ {
...@@ -2131,7 +2134,8 @@ merge_face_vectors (struct window *w, ...@@ -2131,7 +2134,8 @@ merge_face_vectors (struct window *w,
static bool static bool
merge_named_face (struct window *w, merge_named_face (struct window *w,
struct frame *f, Lisp_Object face_name, Lisp_Object *to, struct frame *f, Lisp_Object face_name, Lisp_Object *to,
struct named_merge_point *named_merge_points) struct named_merge_point *named_merge_points,
enum lface_attribute_index attr_filter)
{ {
struct named_merge_point named_merge_point; struct named_merge_point named_merge_point;
...@@ -2141,9 +2145,13 @@ merge_named_face (struct window *w, ...@@ -2141,9 +2145,13 @@ merge_named_face (struct window *w,
{ {
Lisp_Object from[LFACE_VECTOR_SIZE]; Lisp_Object from[LFACE_VECTOR_SIZE];
bool ok = get_lface_attributes (w, f, face_name, from, false, bool ok = get_lface_attributes (w, f, face_name, from, false,
named_merge_points); named_merge_points);
if (ok) eassert (attr_filter < LFACE_VECTOR_SIZE);
if (ok && (attr_filter == 0
|| (!NILP (from[attr_filter])
&& !UNSPECIFIEDP (from[attr_filter]))))
merge_face_vectors (w, f, from, to, named_merge_points); merge_face_vectors (w, f, from, to, named_merge_points);
return ok; return ok;
...@@ -2274,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref, ...@@ -2274,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref,
of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face
inheritance or list structure; it may be 0 for most callers. inheritance or list structure; it may be 0 for most callers.
attr_filter is the index of a parameter that conditions the merging
for named faces (case 1) to only the face_ref where
lface[merge_face_ref] is non-nil. To merge unconditionally set this
value to 0.
FACE_REF may be a single face specification or a list of such FACE_REF may be a single face specification or a list of such
specifications. Each face specification can be: specifications. Each face specification can be:
...@@ -2302,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref, ...@@ -2302,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref,
static bool static bool
merge_face_ref (struct window *w, merge_face_ref (struct window *w,
struct frame *f, Lisp_Object face_ref, Lisp_Object *to, struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
bool err_msgs, struct named_merge_point *named_merge_points) bool err_msgs, struct named_merge_point *named_merge_points,
enum lface_attribute_index attr_filter)
{ {
bool ok = true; /* Succeed without an error? */ bool ok = true; /* Succeed without an error? */
Lisp_Object filtered_face_ref; Lisp_Object filtered_face_ref;
...@@ -2514,7 +2528,8 @@ merge_face_ref (struct window *w, ...@@ -2514,7 +2528,8 @@ merge_face_ref (struct window *w,
/* This is not really very useful; it's just like a /* This is not really very useful; it's just like a
normal face reference. */ normal face reference. */
if (! merge_face_ref (w, f, value, to, if (! merge_face_ref (w, f, value, to,
err_msgs, named_merge_points)) err_msgs, named_merge_points,
0))
err = true; err = true;
} }
else if (EQ (keyword, QCextend)) else if (EQ (keyword, QCextend))
...@@ -2544,16 +2559,19 @@ merge_face_ref (struct window *w, ...@@ -2544,16 +2559,19 @@ merge_face_ref (struct window *w,
Lisp_Object next = XCDR (face_ref); Lisp_Object next = XCDR (face_ref);
if (! NILP (next)) if (! NILP (next))
ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points); ok = merge_face_ref (w, f, next, to, err_msgs,
named_merge_points, 0);
if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points)) if (! merge_face_ref (w, f, first, to, err_msgs,
named_merge_points, 0))
ok = false; ok = false;
} }
} }
else else
{ {
/* FACE_REF ought to be a face name. */ /* FACE_REF ought to be a face name. */
ok = merge_named_face (w, f, face_ref, to, named_merge_points); ok = merge_named_face (w, f, face_ref, to, named_merge_points,
attr_filter);
if (!ok && err_msgs) if (!ok && err_msgs)
add_to_log ("Invalid face reference: %s", face_ref); add_to_log ("Invalid face reference: %s", face_ref);
} }
...@@ -4534,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr) ...@@ -4534,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr)
suitable face is found, realize a new one. */ suitable face is found, realize a new one. */
int int
face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) face_for_font (struct frame *f, Lisp_Object font_object,
struct face *base_face)
{ {
struct face_cache *cache = FRAME_FACE_CACHE (f); struct face_cache *cache = FRAME_FACE_CACHE (f);
unsigned hash;