aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h27
-rw-r--r--src/font.c10
-rw-r--r--src/nsterm.m10
-rw-r--r--src/w32term.c12
-rw-r--r--src/xdisp.c567
-rw-r--r--src/xfaces.c144
-rw-r--r--src/xterm.c10
7 files changed, 414 insertions, 366 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 7a15e2745b5..0615b16d712 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1607,6 +1607,7 @@ enum lface_attribute_index
1607 LFACE_INHERIT_INDEX, 1607 LFACE_INHERIT_INDEX,
1608 LFACE_FONTSET_INDEX, 1608 LFACE_FONTSET_INDEX,
1609 LFACE_DISTANT_FOREGROUND_INDEX, 1609 LFACE_DISTANT_FOREGROUND_INDEX,
1610 LFACE_EXTEND_INDEX,
1610 LFACE_VECTOR_SIZE 1611 LFACE_VECTOR_SIZE
1611}; 1612};
1612 1613
@@ -1632,6 +1633,7 @@ enum face_box_type
1632 1633
1633enum face_underline_type 1634enum face_underline_type
1634{ 1635{
1636 FACE_NO_UNDERLINE = 0,
1635 FACE_UNDER_LINE, 1637 FACE_UNDER_LINE,
1636 FACE_UNDER_WAVE 1638 FACE_UNDER_WAVE
1637}; 1639};
@@ -1675,11 +1677,9 @@ struct face
1675 /* Pixel value or color index of background color. */ 1677 /* Pixel value or color index of background color. */
1676 unsigned long background; 1678 unsigned long background;
1677 1679
1678 /* Pixel value or color index of underline color. */ 1680 /* Pixel value or color index of underline, overlined,
1681 strike-through, or box color. */
1679 unsigned long underline_color; 1682 unsigned long underline_color;
1680
1681 /* Pixel value or color index of overlined, strike-through, or box
1682 color. */
1683 unsigned long overline_color; 1683 unsigned long overline_color;
1684 unsigned long strike_through_color; 1684 unsigned long strike_through_color;
1685 unsigned long box_color; 1685 unsigned long box_color;
@@ -1706,7 +1706,7 @@ struct face
1706 ENUM_BF (face_box_type) box : 2; 1706 ENUM_BF (face_box_type) box : 2;
1707 1707
1708 /* Style of underlining. */ 1708 /* Style of underlining. */
1709 ENUM_BF (face_underline_type) underline_type : 1; 1709 ENUM_BF (face_underline_type) underline : 2;
1710 1710
1711 /* If `box' above specifies a 3D type, true means use box_color for 1711 /* If `box' above specifies a 3D type, true means use box_color for
1712 drawing shadows. */ 1712 drawing shadows. */
@@ -1714,7 +1714,6 @@ struct face
1714 1714
1715 /* Non-zero if text in this face should be underlined, overlined, 1715 /* Non-zero if text in this face should be underlined, overlined,
1716 strike-through or have a box drawn around it. */ 1716 strike-through or have a box drawn around it. */
1717 bool_bf underline_p : 1;
1718 bool_bf overline_p : 1; 1717 bool_bf overline_p : 1;
1719 bool_bf strike_through_p : 1; 1718 bool_bf strike_through_p : 1;
1720 1719
@@ -1724,14 +1723,10 @@ struct face
1724 bool_bf foreground_defaulted_p : 1; 1723 bool_bf foreground_defaulted_p : 1;
1725 bool_bf background_defaulted_p : 1; 1724 bool_bf background_defaulted_p : 1;
1726 1725
1727 /* True means that either no color is specified for underlining or that
1728 the specified color couldn't be loaded. Use the foreground
1729 color when drawing in that case. */
1730 bool_bf underline_defaulted_p : 1;
1731
1732 /* True means that either no color is specified for the corresponding 1726 /* True means that either no color is specified for the corresponding
1733 attribute or that the specified color couldn't be loaded. 1727 attribute or that the specified color couldn't be loaded.
1734 Use the foreground color when drawing in that case. */ 1728 Use the foreground color when drawing in that case. */
1729 bool_bf underline_defaulted_p : 1;
1735 bool_bf overline_color_defaulted_p : 1; 1730 bool_bf overline_color_defaulted_p : 1;
1736 bool_bf strike_through_color_defaulted_p : 1; 1731 bool_bf strike_through_color_defaulted_p : 1;
1737 bool_bf box_color_defaulted_p : 1; 1732 bool_bf box_color_defaulted_p : 1;
@@ -1867,6 +1862,9 @@ struct face_cache
1867 ? FRAME_FACE_CACHE (F)->faces_by_id[ID] \ 1862 ? FRAME_FACE_CACHE (F)->faces_by_id[ID] \
1868 : NULL) 1863 : NULL)
1869 1864
1865#define FACE_EXTENSIBLE_P(F) \
1866 (!NILP (F->lface[LFACE_EXTEND_INDEX]))
1867
1870/* True if FACE is suitable for displaying ASCII characters. */ 1868/* True if FACE is suitable for displaying ASCII characters. */
1871INLINE bool 1869INLINE bool
1872FACE_SUITABLE_FOR_ASCII_CHAR_P (struct face *face) 1870FACE_SUITABLE_FOR_ASCII_CHAR_P (struct face *face)
@@ -3553,12 +3551,13 @@ int lookup_derived_face (struct window *, struct frame *,
3553void init_frame_faces (struct frame *); 3551void init_frame_faces (struct frame *);
3554void free_frame_faces (struct frame *); 3552void free_frame_faces (struct frame *);
3555void recompute_basic_faces (struct frame *); 3553void recompute_basic_faces (struct frame *);
3556int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, 3554int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *,
3557 bool, int); 3555 ptrdiff_t, bool, int, enum lface_attribute_index);
3558int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, 3556int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t,
3559 bool, Lisp_Object); 3557 bool, Lisp_Object);
3560int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, 3558int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t,
3561 ptrdiff_t *, enum face_id, bool); 3559 ptrdiff_t *, enum face_id, bool,
3560 enum lface_attribute_index);
3562int merge_faces (struct window *, Lisp_Object, int, int); 3561int merge_faces (struct window *, Lisp_Object, int, int);
3563int compute_char_face (struct frame *, int, Lisp_Object); 3562int compute_char_face (struct frame *, int, Lisp_Object);
3564void free_all_realized_faces (Lisp_Object); 3563void free_all_realized_faces (Lisp_Object);
diff --git a/src/font.c b/src/font.c
index 6bc977fd68e..7fdadb17c14 100644
--- a/src/font.c
+++ b/src/font.c
@@ -3785,10 +3785,10 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
3785 3785
3786 if (STRINGP (string)) 3786 if (STRINGP (string))
3787 face_id = face_at_string_position (w, string, pos, 0, &endptr, 3787 face_id = face_at_string_position (w, string, pos, 0, &endptr,
3788 DEFAULT_FACE_ID, false); 3788 DEFAULT_FACE_ID, false, 0);
3789 else 3789 else
3790 face_id = face_at_buffer_position (w, pos, &endptr, 3790 face_id = face_at_buffer_position (w, pos, &endptr,
3791 pos + 100, false, -1); 3791 pos + 100, false, -1, 0);
3792 face = FACE_FROM_ID (f, face_id); 3792 face = FACE_FROM_ID (f, face_id);
3793 } 3793 }
3794 if (multibyte) 3794 if (multibyte)
@@ -3832,7 +3832,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
3832 3832
3833 if (NILP (string)) 3833 if (NILP (string))
3834 face_id = face_at_buffer_position (w, pos, &ignore, *limit, 3834 face_id = face_at_buffer_position (w, pos, &ignore, *limit,
3835 false, -1); 3835 false, -1, 0);
3836 else 3836 else
3837 { 3837 {
3838 face_id = 3838 face_id =
@@ -3841,7 +3841,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
3841 : lookup_basic_face (w, f, DEFAULT_FACE_ID); 3841 : lookup_basic_face (w, f, DEFAULT_FACE_ID);
3842 3842
3843 face_id = face_at_string_position (w, string, pos, 0, &ignore, 3843 face_id = face_at_string_position (w, string, pos, 0, &ignore,
3844 face_id, false); 3844 face_id, false, 0);
3845 } 3845 }
3846 face = FACE_FROM_ID (f, face_id); 3846 face = FACE_FROM_ID (f, face_id);
3847 } 3847 }
@@ -4618,7 +4618,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
4618 w = XWINDOW (window); 4618 w = XWINDOW (window);
4619 f = XFRAME (w->frame); 4619 f = XFRAME (w->frame);
4620 face_id = face_at_buffer_position (w, pos, &dummy, 4620 face_id = face_at_buffer_position (w, pos, &dummy,
4621 pos + 100, false, -1); 4621 pos + 100, false, -1, 0);
4622 } 4622 }
4623 if (! CHAR_VALID_P (c)) 4623 if (! CHAR_VALID_P (c))
4624 return Qnil; 4624 return Qnil;
diff --git a/src/nsterm.m b/src/nsterm.m
index c8094d0ee37..5583c6105cb 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3404,9 +3404,9 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
3404 return; 3404 return;
3405 3405
3406 /* Do underline. */ 3406 /* Do underline. */
3407 if (face->underline_p) 3407 if (face->underline)
3408 { 3408 {
3409 if (s->face->underline_type == FACE_UNDER_WAVE) 3409 if (s->face->underline == FACE_UNDER_WAVE)
3410 { 3410 {
3411 if (face->underline_defaulted_p) 3411 if (face->underline_defaulted_p)
3412 [defaultCol set]; 3412 [defaultCol set];
@@ -3415,15 +3415,15 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
3415 3415
3416 ns_draw_underwave (s, width, x); 3416 ns_draw_underwave (s, width, x);
3417 } 3417 }
3418 else if (s->face->underline_type == FACE_UNDER_LINE) 3418 else if (s->face->underline == FACE_UNDER_LINE)
3419 { 3419 {
3420 3420
3421 NSRect r; 3421 NSRect r;
3422 unsigned long thickness, position; 3422 unsigned long thickness, position;
3423 3423
3424 /* If the prev was underlined, match its appearance. */ 3424 /* If the prev was underlined, match its appearance. */
3425 if (s->prev && s->prev->face->underline_p 3425 if (s->prev
3426 && s->prev->face->underline_type == FACE_UNDER_LINE 3426 && s->prev->face->underline == FACE_UNDER_LINE
3427 && s->prev->underline_thickness > 0) 3427 && s->prev->underline_thickness > 0)
3428 { 3428 {
3429 thickness = s->prev->underline_thickness; 3429 thickness = s->prev->underline_thickness;
diff --git a/src/w32term.c b/src/w32term.c
index 82256db1721..9da0845836a 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2481,9 +2481,9 @@ w32_draw_glyph_string (struct glyph_string *s)
2481 if (!s->for_overlaps) 2481 if (!s->for_overlaps)
2482 { 2482 {
2483 /* Draw underline. */ 2483 /* Draw underline. */
2484 if (s->face->underline_p) 2484 if (s->face->underline)
2485 { 2485 {
2486 if (s->face->underline_type == FACE_UNDER_WAVE) 2486 if (s->face->underline == FACE_UNDER_WAVE)
2487 { 2487 {
2488 COLORREF color; 2488 COLORREF color;
2489 2489
@@ -2494,13 +2494,13 @@ w32_draw_glyph_string (struct glyph_string *s)
2494 2494
2495 w32_draw_underwave (s, color); 2495 w32_draw_underwave (s, color);
2496 } 2496 }
2497 else if (s->face->underline_type == FACE_UNDER_LINE) 2497 else if (s->face->underline == FACE_UNDER_LINE)
2498 { 2498 {
2499 unsigned long thickness, position; 2499 unsigned long thickness, position;
2500 int y; 2500 int y;
2501 2501
2502 if (s->prev && s->prev->face->underline_p 2502 if (s->prev
2503 && s->prev->face->underline_type == FACE_UNDER_LINE) 2503 && s->prev->face->underline == FACE_UNDER_LINE)
2504 { 2504 {
2505 /* We use the same underline style as the previous one. */ 2505 /* We use the same underline style as the previous one. */
2506 thickness = s->prev->underline_thickness; 2506 thickness = s->prev->underline_thickness;
@@ -2514,7 +2514,7 @@ w32_draw_glyph_string (struct glyph_string *s)
2514 BOOL use_underline_position_properties; 2514 BOOL use_underline_position_properties;
2515 Lisp_Object val 2515 Lisp_Object val
2516 = buffer_local_value (Qunderline_minimum_offset, 2516 = buffer_local_value (Qunderline_minimum_offset,
2517 s->w->contents); 2517 s->w->contents);
2518 if (FIXNUMP (val)) 2518 if (FIXNUMP (val))
2519 minimum_offset = max (0, XFIXNUM (val)); 2519 minimum_offset = max (0, XFIXNUM (val));
2520 else 2520 else
diff --git a/src/xdisp.c b/src/xdisp.c
index 1cfd7ef7601..30be492d9b4 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -431,17 +431,26 @@ static Lisp_Object list_of_error;
431 met, return the (nonnegative) column number, else return a negative 431 met, return the (nonnegative) column number, else return a negative
432 value. */ 432 value. */
433static int 433static int
434fill_column_indicator_column (struct it *it) 434fill_column_indicator_column (struct it *it, int char_width)
435{ 435{
436 if (Vdisplay_fill_column_indicator 436 if (Vdisplay_fill_column_indicator
437 && !it->w->pseudo_window_p
437 && it->continuation_lines_width == 0 438 && it->continuation_lines_width == 0
438 && CHARACTERP (Vdisplay_fill_column_indicator_character)) 439 && CHARACTERP (Vdisplay_fill_column_indicator_character))
439 { 440 {
440 Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt) 441 Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt)
441 ? BVAR (current_buffer, fill_column) 442 ? BVAR (current_buffer, fill_column)
442 : Vdisplay_fill_column_indicator_column); 443 : Vdisplay_fill_column_indicator_column);
444
445 /* The stretch width needs to consider the latter
446 added glyph in append_space_for_newline. */
443 if (RANGED_FIXNUMP (0, col, INT_MAX)) 447 if (RANGED_FIXNUMP (0, col, INT_MAX))
444 return XFIXNUM (col); 448 {
449 int icol = XFIXNUM (col);
450 if (!INT_MULTIPLY_WRAPV (char_width, icol, &icol)
451 && !INT_ADD_WRAPV (it->lnum_pixel_width, icol, &icol))
452 return icol;
453 }
445 } 454 }
446 return -1; 455 return -1;
447} 456}
@@ -984,7 +993,7 @@ static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
984static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object, 993static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object,
985 Lisp_Object, struct text_pos *, 994 Lisp_Object, struct text_pos *,
986 ptrdiff_t, int, bool, bool); 995 ptrdiff_t, int, bool, bool);
987static int underlying_face_id (struct it *); 996static int underlying_face_id (const struct it *);
988 997
989#define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true) 998#define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true)
990#define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false) 999#define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false)
@@ -4148,56 +4157,20 @@ handle_fontified_prop (struct it *it)
4148 Faces 4157 Faces
4149 ***********************************************************************/ 4158 ***********************************************************************/
4150 4159
4151/* Set up iterator IT from face properties at its current position. 4160static int
4152 Called from handle_stop. */ 4161face_at_pos (const struct it *it, enum lface_attribute_index attr_filter)
4153
4154static enum prop_handled
4155handle_face_prop (struct it *it)
4156{ 4162{
4157 int new_face_id;
4158 ptrdiff_t next_stop; 4163 ptrdiff_t next_stop;
4159 4164
4160 if (!STRINGP (it->string)) 4165 if (!STRINGP (it->string))
4161 { 4166 {
4162 new_face_id 4167 return face_at_buffer_position (it->w,
4163 = face_at_buffer_position (it->w, 4168 IT_CHARPOS (*it),
4164 IT_CHARPOS (*it), 4169 &next_stop,
4165 &next_stop, 4170 (IT_CHARPOS (*it)
4166 (IT_CHARPOS (*it) 4171 + TEXT_PROP_DISTANCE_LIMIT),
4167 + TEXT_PROP_DISTANCE_LIMIT), 4172 false, it->base_face_id,
4168 false, it->base_face_id); 4173 attr_filter);
4169
4170 /* Is this a start of a run of characters with box face?
4171 Caveat: this can be called for a freshly initialized
4172 iterator; face_id is -1 in this case. We know that the new
4173 face will not change until limit, i.e. if the new face has a
4174 box, all characters up to limit will have one. But, as
4175 usual, we don't know whether limit is really the end. */
4176 if (new_face_id != it->face_id)
4177 {
4178 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4179 /* If it->face_id is -1, old_face below will be NULL, see
4180 the definition of FACE_FROM_ID_OR_NULL. This will happen
4181 if this is the initial call that gets the face. */
4182 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
4183
4184 /* If the value of face_id of the iterator is -1, we have to
4185 look in front of IT's position and see whether there is a
4186 face there that's different from new_face_id. */
4187 if (!old_face && IT_CHARPOS (*it) > BEG)
4188 {
4189 int prev_face_id = face_before_it_pos (it);
4190
4191 old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
4192 }
4193
4194 /* If the new face has a box, but the old face does not,
4195 this is the start of a run of characters with box face,
4196 i.e. this character has a shadow on the left side. */
4197 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
4198 && (old_face == NULL || !old_face->box));
4199 it->face_box_p = new_face->box != FACE_NO_BOX;
4200 }
4201 } 4174 }
4202 else 4175 else
4203 { 4176 {
@@ -4207,7 +4180,7 @@ handle_face_prop (struct it *it)
4207 Lisp_Object from_overlay 4180 Lisp_Object from_overlay
4208 = (it->current.overlay_string_index >= 0 4181 = (it->current.overlay_string_index >= 0
4209 ? it->string_overlays[it->current.overlay_string_index 4182 ? it->string_overlays[it->current.overlay_string_index
4210 % OVERLAY_STRING_CHUNK_SIZE] 4183 % OVERLAY_STRING_CHUNK_SIZE]
4211 : Qnil); 4184 : Qnil);
4212 4185
4213 /* See if we got to this string directly or indirectly from 4186 /* See if we got to this string directly or indirectly from
@@ -4222,7 +4195,7 @@ handle_face_prop (struct it *it)
4222 if (it->stack[i].current.overlay_string_index >= 0) 4195 if (it->stack[i].current.overlay_string_index >= 0)
4223 from_overlay 4196 from_overlay
4224 = it->string_overlays[it->stack[i].current.overlay_string_index 4197 = it->string_overlays[it->stack[i].current.overlay_string_index
4225 % OVERLAY_STRING_CHUNK_SIZE]; 4198 % OVERLAY_STRING_CHUNK_SIZE];
4226 else if (! NILP (it->stack[i].from_overlay)) 4199 else if (! NILP (it->stack[i].from_overlay))
4227 from_overlay = it->stack[i].from_overlay; 4200 from_overlay = it->stack[i].from_overlay;
4228 4201
@@ -4237,12 +4210,12 @@ handle_face_prop (struct it *it)
4237 only on text properties and ignores overlays. */ 4210 only on text properties and ignores overlays. */
4238 base_face_id 4211 base_face_id
4239 = face_for_overlay_string (it->w, 4212 = face_for_overlay_string (it->w,
4240 IT_CHARPOS (*it), 4213 IT_CHARPOS (*it),
4241 &next_stop, 4214 &next_stop,
4242 (IT_CHARPOS (*it) 4215 (IT_CHARPOS (*it)
4243 + TEXT_PROP_DISTANCE_LIMIT), 4216 + TEXT_PROP_DISTANCE_LIMIT),
4244 false, 4217 false,
4245 from_overlay); 4218 from_overlay);
4246 } 4219 }
4247 else 4220 else
4248 { 4221 {
@@ -4271,35 +4244,60 @@ handle_face_prop (struct it *it)
4271 : underlying_face_id (it); 4244 : underlying_face_id (it);
4272 } 4245 }
4273 4246
4274 new_face_id = face_at_string_position (it->w, 4247 return face_at_string_position (it->w,
4275 it->string, 4248 it->string,
4276 IT_STRING_CHARPOS (*it), 4249 IT_STRING_CHARPOS (*it),
4277 bufpos, 4250 bufpos,
4278 &next_stop, 4251 &next_stop,
4279 base_face_id, false); 4252 base_face_id, false,
4253 attr_filter);
4254 } // !STRINGP (it->string))
4255}
4256
4280 4257
4281 /* Is this a start of a run of characters with box? Caveat: 4258/* Set up iterator IT from face properties at its current position.
4282 this can be called for a freshly allocated iterator; face_id 4259 Called from handle_stop. */
4283 is -1 is this case. We know that the new face will not 4260static enum prop_handled
4284 change until the next check pos, i.e. if the new face has a 4261handle_face_prop (struct it *it)
4285 box, all characters up to that position will have a 4262{
4286 box. But, as usual, we don't know whether that position 4263 const int new_face_id = face_at_pos (it, 0);
4287 is really the end. */ 4264
4288 if (new_face_id != it->face_id) 4265
4266 /* Is this a start of a run of characters with box face?
4267 Caveat: this can be called for a freshly initialized
4268 iterator; face_id is -1 in this case. We know that the new
4269 face will not change until limit, i.e. if the new face has a
4270 box, all characters up to limit will have one. But, as
4271 usual, we don't know whether limit is really the end. */
4272 if (new_face_id != it->face_id)
4273 {
4274 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4275 /* If it->face_id is -1, old_face below will be NULL, see
4276 the definition of FACE_FROM_ID_OR_NULL. This will happen
4277 if this is the initial call that gets the face. */
4278 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
4279
4280 /* If the value of face_id of the iterator is -1, we have to
4281 look in front of IT's position and see whether there is a
4282 face there that's different from new_face_id. */
4283 if (!STRINGP (it->string)
4284 && !old_face
4285 && IT_CHARPOS (*it) > BEG)
4289 { 4286 {
4290 struct face *new_face = FACE_FROM_ID (it->f, new_face_id); 4287 const int prev_face_id = face_before_it_pos (it);
4291 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
4292 4288
4293 /* If new face has a box but old face hasn't, this is the 4289 old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
4294 start of a run of characters with box, i.e. it has a
4295 shadow on the left side. */
4296 it->start_of_box_run_p
4297 = new_face->box && (old_face == NULL || !old_face->box);
4298 it->face_box_p = new_face->box != FACE_NO_BOX;
4299 } 4290 }
4291
4292 /* If the new face has a box, but the old face does not,
4293 this is the start of a run of characters with box face,
4294 i.e. this character has a shadow on the left side. */
4295 it->face_id = new_face_id;
4296 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
4297 && (old_face == NULL || !old_face->box));
4298 it->face_box_p = new_face->box != FACE_NO_BOX;
4300 } 4299 }
4301 4300
4302 it->face_id = new_face_id;
4303 return HANDLED_NORMALLY; 4301 return HANDLED_NORMALLY;
4304} 4302}
4305 4303
@@ -4310,7 +4308,7 @@ handle_face_prop (struct it *it)
4310 Otherwise, use the iterator's base_face_id. */ 4308 Otherwise, use the iterator's base_face_id. */
4311 4309
4312static int 4310static int
4313underlying_face_id (struct it *it) 4311underlying_face_id (const struct it *it)
4314{ 4312{
4315 int face_id = it->base_face_id, i; 4313 int face_id = it->base_face_id, i;
4316 4314
@@ -4423,12 +4421,9 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
4423 base_face_id = underlying_face_id (it); 4421 base_face_id = underlying_face_id (it);
4424 4422
4425 /* Get the face for ASCII, or unibyte. */ 4423 /* Get the face for ASCII, or unibyte. */
4426 face_id = face_at_string_position (it->w, 4424 face_id = face_at_string_position (it->w, it->string, charpos,
4427 it->string, 4425 bufpos, &next_check_charpos,
4428 charpos, 4426 base_face_id, false, 0);
4429 bufpos,
4430 &next_check_charpos,
4431 base_face_id, false);
4432 4427
4433 /* Correct the face for charsets different from ASCII. Do it 4428 /* Correct the face for charsets different from ASCII. Do it
4434 for the multibyte case only. The face returned above is 4429 for the multibyte case only. The face returned above is
@@ -4527,7 +4522,7 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
4527 face_id = face_at_buffer_position (it->w, 4522 face_id = face_at_buffer_position (it->w,
4528 CHARPOS (pos), 4523 CHARPOS (pos),
4529 &next_check_charpos, 4524 &next_check_charpos,
4530 limit, false, -1); 4525 limit, false, -1, 0);
4531 4526
4532 /* Correct the face for charsets different from ASCII. Do it 4527 /* Correct the face for charsets different from ASCII. Do it
4533 for the multibyte case only. The face returned above is 4528 for the multibyte case only. The face returned above is
@@ -7638,7 +7633,8 @@ get_next_display_element (struct it *it)
7638 next_face_id 7633 next_face_id
7639 = face_at_string_position (it->w, base_string, 7634 = face_at_string_position (it->w, base_string,
7640 CHARPOS (pos), 0, 7635 CHARPOS (pos), 0,
7641 &ignore, face_id, false); 7636 &ignore, face_id,
7637 false, 0);
7642 it->end_of_box_run_p 7638 it->end_of_box_run_p
7643 = (FACE_FROM_ID (it->f, next_face_id)->box 7639 = (FACE_FROM_ID (it->f, next_face_id)->box
7644 == FACE_NO_BOX); 7640 == FACE_NO_BOX);
@@ -7649,10 +7645,11 @@ get_next_display_element (struct it *it)
7649 else 7645 else
7650 { 7646 {
7651 next_face_id = 7647 next_face_id =
7652 face_at_buffer_position (it->w, CHARPOS (pos), &ignore, 7648 face_at_buffer_position (it->w, CHARPOS (pos),
7649 &ignore,
7653 CHARPOS (pos) 7650 CHARPOS (pos)
7654 + TEXT_PROP_DISTANCE_LIMIT, 7651 + TEXT_PROP_DISTANCE_LIMIT,
7655 false, -1); 7652 false, -1, 0);
7656 it->end_of_box_run_p 7653 it->end_of_box_run_p
7657 = (FACE_FROM_ID (it->f, next_face_id)->box 7654 = (FACE_FROM_ID (it->f, next_face_id)->box
7658 == FACE_NO_BOX); 7655 == FACE_NO_BOX);
@@ -21366,80 +21363,78 @@ compute_line_metrics (struct it *it)
21366static bool 21363static bool
21367append_space_for_newline (struct it *it, bool default_face_p) 21364append_space_for_newline (struct it *it, bool default_face_p)
21368{ 21365{
21369#ifdef HAVE_WINDOW_SYSTEM 21366 int n = it->glyph_row->used[TEXT_AREA];
21370 if (FRAME_WINDOW_P (it->f)) 21367
21368 if (it->glyph_row->glyphs[TEXT_AREA] + n
21369 < it->glyph_row->glyphs[1 + TEXT_AREA])
21371 { 21370 {
21372 int n = it->glyph_row->used[TEXT_AREA]; 21371 /* Save some values that must not be changed.
21373 21372 Must save IT->c and IT->len because otherwise
21374 if (it->glyph_row->glyphs[TEXT_AREA] + n 21373 ITERATOR_AT_END_P wouldn't work anymore after
21375 < it->glyph_row->glyphs[1 + TEXT_AREA]) 21374 append_space_for_newline has been called. */
21376 { 21375 enum display_element_type saved_what = it->what;
21377 /* Save some values that must not be changed. 21376 int saved_c = it->c, saved_len = it->len;
21378 Must save IT->c and IT->len because otherwise 21377 int saved_char_to_display = it->char_to_display;
21379 ITERATOR_AT_END_P wouldn't work anymore after 21378 int saved_x = it->current_x;
21380 append_space_for_newline has been called. */ 21379 const int saved_face_id = it->face_id;
21381 enum display_element_type saved_what = it->what; 21380 bool saved_box_end = it->end_of_box_run_p;
21382 int saved_c = it->c, saved_len = it->len; 21381 struct text_pos saved_pos = it->position;
21383 int saved_char_to_display = it->char_to_display; 21382 Lisp_Object saved_object = it->object;
21384 int saved_x = it->current_x; 21383 struct face *face;
21385 int saved_face_id = it->face_id;
21386 bool saved_box_end = it->end_of_box_run_p;
21387 struct text_pos saved_pos;
21388 Lisp_Object saved_object;
21389 struct face *face;
21390 21384
21391 saved_object = it->object; 21385 it->what = IT_CHARACTER;
21392 saved_pos = it->position; 21386 memset (&it->position, 0, sizeof it->position);
21387 it->object = Qnil;
21388 it->len = 1;
21393 21389
21394 it->what = IT_CHARACTER; 21390 int char_width = 1;
21395 memset (&it->position, 0, sizeof it->position);
21396 it->object = Qnil;
21397 it->len = 1;
21398 21391
21399 int local_default_face_id = 21392 if (default_face_p
21393#ifdef HAVE_WINDOW_SYSTEM
21394 || FRAME_WINDOW_P (it->f)
21395#endif
21396 )
21397 {
21398 const int local_default_face_id =
21400 lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); 21399 lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
21401 struct face* default_face = 21400 struct face* default_face =
21402 FACE_FROM_ID_OR_NULL (it->f, local_default_face_id); 21401 FACE_FROM_ID_OR_NULL (it->f, local_default_face_id);
21403 21402
21404 /* Corner case for when display-fill-column-indicator-mode 21403#ifdef HAVE_WINDOW_SYSTEM
21405 is active and the extra character should be added in the 21404 if (FRAME_WINDOW_P (it->f))
21406 same place than the line. */ 21405 {
21407 int indicator_column = (it->w->pseudo_window_p == 0 21406 struct font *font = (default_face->font
21408 ? fill_column_indicator_column (it) 21407 ? default_face->font
21409 : -1); 21408 : FRAME_FONT (it->f));
21410 if (indicator_column >= 0) 21409 char_width = (font->average_width
21411 { 21410 ? font->average_width
21412 struct font *font = (default_face->font 21411 : font->space_width);
21413 ? default_face->font
21414 : FRAME_FONT (it->f));
21415 const int char_width = (font->average_width
21416 ? font->average_width
21417 : font->space_width);
21418 int column_x;
21419
21420 if (!INT_MULTIPLY_WRAPV (indicator_column, char_width,
21421 &column_x)
21422 && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x,
21423 &column_x)
21424 && it->current_x == column_x)
21425 {
21426 it->c = it->char_to_display
21427 = XFIXNAT (Vdisplay_fill_column_indicator_character);
21428 it->face_id
21429 = merge_faces (it->w, Qfill_column_indicator,
21430 0, saved_face_id);
21431 face = FACE_FROM_ID (it->f, it->face_id);
21432 goto produce_glyphs;
21433 }
21434 } 21412 }
21413#endif
21414 if (default_face_p)
21415 it->face_id = local_default_face_id;
21416 }
21417 /* Corner case for when display-fill-column-indicator-mode
21418 is active and the extra character should be added in the
21419 same place than the line. */
21420
21421 const int indicator_column =
21422 fill_column_indicator_column (it, char_width);
21435 21423
21424 if (it->current_x == indicator_column)
21425 {
21426 it->c = it->char_to_display
21427 = XFIXNAT (Vdisplay_fill_column_indicator_character);
21428 it->face_id
21429 = merge_faces (it->w, Qfill_column_indicator,
21430 0, saved_face_id);
21431 face = FACE_FROM_ID (it->f, it->face_id);
21432 }
21433 else
21434 {
21436 it->c = it->char_to_display = ' '; 21435 it->c = it->char_to_display = ' ';
21437 /* If the default face was remapped, be sure to use the 21436 /* If the default face was remapped, be sure to use the
21438 remapped face for the appended newline. */ 21437 remapped face for the appended newline. */
21439 if (default_face_p)
21440 it->face_id = local_default_face_id;
21441 else if (it->face_before_selective_p)
21442 it->face_id = it->saved_face_id;
21443 21438
21444 face = FACE_FROM_ID (it->f, it->face_id); 21439 face = FACE_FROM_ID (it->f, it->face_id);
21445 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); 21440 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
@@ -21453,10 +21448,11 @@ append_space_for_newline (struct it *it, bool default_face_p)
21453 so leave the box flag set. */ 21448 so leave the box flag set. */
21454 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) 21449 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
21455 it->end_of_box_run_p = false; 21450 it->end_of_box_run_p = false;
21456 21451 }
21457 produce_glyphs: 21452 PRODUCE_GLYPHS (it);
21458 PRODUCE_GLYPHS (it); 21453#ifdef HAVE_WINDOW_SYSTEM
21459 21454 if (FRAME_WINDOW_P (it->f))
21455 {
21460 /* Make sure this space glyph has the right ascent and 21456 /* Make sure this space glyph has the right ascent and
21461 descent values, or else cursor at end of line will look 21457 descent values, or else cursor at end of line will look
21462 funny, and height of empty lines will be incorrect. */ 21458 funny, and height of empty lines will be incorrect. */
@@ -21477,8 +21473,8 @@ append_space_for_newline (struct it *it, bool default_face_p)
21477 gui_produce_glyph for newline characters. */ 21473 gui_produce_glyph for newline characters. */
21478 height = get_it_property (it, Qline_height); 21474 height = get_it_property (it, Qline_height);
21479 if (CONSP (height) 21475 if (CONSP (height)
21480 && CONSP (XCDR (height)) 21476 && CONSP (XCDR (height))
21481 && NILP (XCDR (XCDR (height)))) 21477 && NILP (XCDR (XCDR (height))))
21482 { 21478 {
21483 total_height = XCAR (XCDR (height)); 21479 total_height = XCAR (XCDR (height));
21484 height = XCAR (height); 21480 height = XCAR (height);
@@ -21507,12 +21503,12 @@ append_space_for_newline (struct it *it, bool default_face_p)
21507 21503
21508 if (!NILP (total_height)) 21504 if (!NILP (total_height))
21509 spacing = calc_line_height_property (it, total_height, font, 21505 spacing = calc_line_height_property (it, total_height, font,
21510 boff, false); 21506 boff, false);
21511 else 21507 else
21512 { 21508 {
21513 spacing = get_it_property (it, Qline_spacing); 21509 spacing = get_it_property (it, Qline_spacing);
21514 spacing = calc_line_height_property (it, spacing, font, 21510 spacing = calc_line_height_property (it, spacing, font,
21515 boff, false); 21511 boff, false);
21516 } 21512 }
21517 if (FIXNUMP (spacing)) 21513 if (FIXNUMP (spacing))
21518 { 21514 {
@@ -21535,22 +21531,21 @@ append_space_for_newline (struct it *it, bool default_face_p)
21535 21531
21536 g->ascent = it->max_ascent; 21532 g->ascent = it->max_ascent;
21537 g->descent = it->max_descent; 21533 g->descent = it->max_descent;
21538
21539 it->override_ascent = -1;
21540 it->constrain_row_ascent_descent_p = false;
21541 it->current_x = saved_x;
21542 it->object = saved_object;
21543 it->position = saved_pos;
21544 it->what = saved_what;
21545 it->face_id = saved_face_id;
21546 it->len = saved_len;
21547 it->c = saved_c;
21548 it->char_to_display = saved_char_to_display;
21549 it->end_of_box_run_p = saved_box_end;
21550 return true;
21551 } 21534 }
21535#endif /* HAVE_WINDOW_SYSTEM */
21536 it->override_ascent = -1;
21537 it->constrain_row_ascent_descent_p = false;
21538 it->current_x = saved_x;
21539 it->object = saved_object;
21540 it->position = saved_pos;
21541 it->what = saved_what;
21542 it->face_id = saved_face_id;
21543 it->len = saved_len;
21544 it->c = saved_c;
21545 it->char_to_display = saved_char_to_display;
21546 it->end_of_box_run_p = saved_box_end;
21547 return true;
21552 } 21548 }
21553#endif
21554 21549
21555 return false; 21550 return false;
21556} 21551}
@@ -21566,7 +21561,6 @@ append_space_for_newline (struct it *it, bool default_face_p)
21566static void 21561static void
21567extend_face_to_end_of_line (struct it *it) 21562extend_face_to_end_of_line (struct it *it)
21568{ 21563{
21569 struct face *face;
21570 struct frame *f = it->f; 21564 struct frame *f = it->f;
21571 21565
21572 /* If line is already filled, do nothing. Non window-system frames 21566 /* If line is already filled, do nothing. Non window-system frames
@@ -21584,12 +21578,17 @@ extend_face_to_end_of_line (struct it *it)
21584 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) 21578 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
21585 return; 21579 return;
21586 21580
21587 /* Face extension extends the background and box of IT->face_id 21581 const int extend_face_id = (it->face_id == DEFAULT_FACE_ID
21582 || it->s != NULL)
21583 ? DEFAULT_FACE_ID
21584 : face_at_pos (it, LFACE_EXTEND_INDEX);
21585
21586 /* Face extension extends the background and box of IT->extend_face_id
21588 to the end of the line. If the background equals the background 21587 to the end of the line. If the background equals the background
21589 of the frame, we don't have to do anything. */ 21588 of the frame, we don't have to do anything. */
21590 face = FACE_FROM_ID (f, (it->face_before_selective_p 21589 struct face *face = FACE_FROM_ID (f, (it->face_before_selective_p
21591 ? it->saved_face_id 21590 ? it->saved_face_id
21592 : it->face_id)); 21591 : extend_face_id));
21593 21592
21594 if (FRAME_WINDOW_P (f) 21593 if (FRAME_WINDOW_P (f)
21595 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) 21594 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
@@ -21612,9 +21611,7 @@ extend_face_to_end_of_line (struct it *it)
21612 that the character will always be single byte in unibyte 21611 that the character will always be single byte in unibyte
21613 text. */ 21612 text. */
21614 if (!ASCII_CHAR_P (it->c)) 21613 if (!ASCII_CHAR_P (it->c))
21615 {
21616 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil); 21614 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
21617 }
21618 21615
21619 /* The default face, possibly remapped. */ 21616 /* The default face, possibly remapped. */
21620 struct face *default_face = 21617 struct face *default_face =
@@ -21665,79 +21662,81 @@ extend_face_to_end_of_line (struct it *it)
21665 /* Display fill column indicator if not in modeline or 21662 /* Display fill column indicator if not in modeline or
21666 toolbar and display fill column indicator mode is 21663 toolbar and display fill column indicator mode is
21667 active. */ 21664 active. */
21668 int indicator_column = (it->w->pseudo_window_p == 0 21665
21669 ? fill_column_indicator_column (it) 21666 struct font *font = (default_face->font
21670 : -1); 21667 ? default_face->font
21671 if (indicator_column >= 0) 21668 : FRAME_FONT (f));
21669
21670 const int char_width = (font->average_width
21671 ? font->average_width
21672 : font->space_width);
21673
21674 const int indicator_column =
21675 fill_column_indicator_column (it, char_width);
21676
21677 const char saved_char = it->char_to_display;
21678 const struct text_pos saved_pos = it->position;
21679 const bool saved_avoid_cursor = it->avoid_cursor_p;
21680 const bool saved_box_start = it->start_of_box_run_p;
21681 Lisp_Object save_object = it->object;
21682 const int saved_face_id = it->face_id;
21683
21684 it->face_id = extend_face_id;
21685 it->avoid_cursor_p = true;
21686 it->object = Qnil;
21687
21688 if (indicator_column >= 0
21689 && indicator_column > it->current_x
21690 && indicator_column < it->last_visible_x)
21672 { 21691 {
21673 struct font *font = (default_face->font
21674 ? default_face->font
21675 : FRAME_FONT (f));
21676 const int char_width = (font->average_width
21677 ? font->average_width
21678 : font->space_width);
21679 int column_x;
21680
21681 if (!INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x)
21682 && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x)
21683 && column_x >= it->current_x
21684 && column_x <= it->last_visible_x)
21685 {
21686 const char saved_char = it->char_to_display;
21687 const struct text_pos saved_pos = it->position;
21688 const bool saved_avoid_cursor = it->avoid_cursor_p;
21689 const int saved_face_id = it->face_id;
21690 const bool saved_box_start = it->start_of_box_run_p;
21691 Lisp_Object save_object = it->object;
21692
21693 /* The stretch width needs to considet the latter
21694 added glyph. */
21695 const int stretch_width
21696 = column_x - it->current_x - char_width;
21697
21698 memset (&it->position, 0, sizeof it->position);
21699 it->avoid_cursor_p = true;
21700 it->object = Qnil;
21701
21702 /* Only generate a stretch glyph if there is distance
21703 between current_x and and the indicator position. */
21704 if (stretch_width > 0)
21705 {
21706 int stretch_ascent = (((it->ascent + it->descent)
21707 * FONT_BASE (font)) / FONT_HEIGHT (font));
21708 append_stretch_glyph (it, Qnil, stretch_width,
21709 it->ascent + it->descent,
21710 stretch_ascent);
21711 }
21712 21692
21713 /* Generate the glyph indicator only if 21693 /* Here we substract char_width because we want the
21714 append_space_for_newline didn't already. */ 21694 column indicator in the column INDICATOR_COLUMN, not
21715 if (it->current_x < column_x) 21695 after it. */
21716 { 21696 const int stretch_width =
21717 it->char_to_display 21697 indicator_column - it->current_x - char_width;
21718 = XFIXNAT (Vdisplay_fill_column_indicator_character); 21698
21719 it->face_id 21699 memset (&it->position, 0, sizeof it->position);
21720 = merge_faces (it->w, Qfill_column_indicator, 21700
21721 0, saved_face_id); 21701 /* Only generate a stretch glyph if there is distance
21722 PRODUCE_GLYPHS (it); 21702 between current_x and and the indicator position. */
21723 } 21703 if (stretch_width > 0)
21724 21704 {
21725 /* Restore the face after the indicator was generated. */ 21705 int stretch_ascent = (((it->ascent + it->descent)
21726 it->face_id = saved_face_id; 21706 * FONT_BASE (font)) / FONT_HEIGHT (font));
21727 21707 append_stretch_glyph (it, Qnil, stretch_width,
21728 /* If there is space after the indicator generate an 21708 it->ascent + it->descent,
21729 extra empty glyph to restore the face. Issue was 21709 stretch_ascent);
21730 observed in X systems. */ 21710 }
21731 it->char_to_display = ' '; 21711
21732 PRODUCE_GLYPHS (it); 21712 /* Generate the glyph indicator only if
21733 21713 append_space_for_newline didn't already. */
21734 it->char_to_display = saved_char; 21714 if (it->current_x < indicator_column)
21735 it->position = saved_pos; 21715 {
21736 it->avoid_cursor_p = saved_avoid_cursor; 21716 const int save_face_id = it->face_id;
21737 it->start_of_box_run_p = saved_box_start; 21717 it->char_to_display
21738 it->object = save_object; 21718 = XFIXNAT (Vdisplay_fill_column_indicator_character);
21739 } 21719 it->face_id
21720 = merge_faces (it->w, Qfill_column_indicator,
21721 0, extend_face_id);
21722 PRODUCE_GLYPHS (it);
21723 it->face_id = save_face_id;
21724 }
21740 } 21725 }
21726
21727 /* If there is space after the indicator generate an
21728 extra empty glyph to restore the face. Issue was
21729 observed in X systems. */
21730 it->char_to_display = ' ';
21731 PRODUCE_GLYPHS (it);
21732
21733 it->char_to_display = saved_char;
21734 it->position = saved_pos;
21735 it->avoid_cursor_p = saved_avoid_cursor;
21736 it->start_of_box_run_p = saved_box_start;
21737 it->object = save_object;
21738 it->face_id = saved_face_id;
21739
21741 } 21740 }
21742 if (it->glyph_row->reversed_p) 21741 if (it->glyph_row->reversed_p)
21743 { 21742 {
@@ -21783,10 +21782,9 @@ extend_face_to_end_of_line (struct it *it)
21783 /* The last row's stretch glyph should get the default 21782 /* The last row's stretch glyph should get the default
21784 face, to avoid painting the rest of the window with 21783 face, to avoid painting the rest of the window with
21785 the region face, if the region ends at ZV. */ 21784 the region face, if the region ends at ZV. */
21786 if (it->glyph_row->ends_at_zv_p) 21785 it->face_id = (it->glyph_row->ends_at_zv_p ?
21787 it->face_id = default_face->id; 21786 default_face->id : face->id);
21788 else 21787
21789 it->face_id = face->id;
21790 it->start_of_box_run_p = false; 21788 it->start_of_box_run_p = false;
21791 append_stretch_glyph (it, Qnil, stretch_width, 21789 append_stretch_glyph (it, Qnil, stretch_width,
21792 it->ascent + it->descent, stretch_ascent); 21790 it->ascent + it->descent, stretch_ascent);
@@ -21808,14 +21806,11 @@ extend_face_to_end_of_line (struct it *it)
21808 { 21806 {
21809 /* Save some values that must not be changed. */ 21807 /* Save some values that must not be changed. */
21810 int saved_x = it->current_x; 21808 int saved_x = it->current_x;
21811 struct text_pos saved_pos; 21809 struct text_pos saved_pos = it->position;
21812 Lisp_Object saved_object; 21810 Lisp_Object saved_object = it->object;;
21813 enum display_element_type saved_what = it->what; 21811 enum display_element_type saved_what = it->what;
21814 int saved_face_id = it->face_id; 21812 int saved_face_id = it->face_id;
21815 21813
21816 saved_object = it->object;
21817 saved_pos = it->position;
21818
21819 it->what = IT_CHARACTER; 21814 it->what = IT_CHARACTER;
21820 memset (&it->position, 0, sizeof it->position); 21815 memset (&it->position, 0, sizeof it->position);
21821 it->object = Qnil; 21816 it->object = Qnil;
@@ -21854,34 +21849,31 @@ extend_face_to_end_of_line (struct it *it)
21854 /* The last row's blank glyphs should get the default face, to 21849 /* The last row's blank glyphs should get the default face, to
21855 avoid painting the rest of the window with the region face, 21850 avoid painting the rest of the window with the region face,
21856 if the region ends at ZV. */ 21851 if the region ends at ZV. */
21857 if (it->glyph_row->ends_at_zv_p) 21852 it->face_id = (it->glyph_row->ends_at_zv_p ?
21858 it->face_id = default_face->id; 21853 default_face->id : face->id);
21859 else
21860 it->face_id = face->id;
21861 21854
21862 /* Display fill-column indicator if needed. */ 21855 /* Display fill-column indicator if needed. */
21863 int indicator_column = fill_column_indicator_column (it); 21856 /* We need to subtract 1 to the indicator_column here because we
21864 if (indicator_column >= 0 21857 will add the indicator IN the column indicator number, not
21865 && INT_ADD_WRAPV (it->lnum_pixel_width, indicator_column, 21858 after it. We compare the variable it->current_x before
21866 &indicator_column)) 21859 producing the glyph. When FRAME_WINDOW_P we substract
21867 indicator_column = -1; 21860 CHAR_WIDTH calculating STRETCH_WIDTH for the same reason. */
21861 const int indicator_column =
21862 fill_column_indicator_column (it, 1) - 1;
21868 do 21863 do
21869 { 21864 {
21870 int saved_face_id; 21865 if (it->current_x != indicator_column)
21871 bool indicate = it->current_x == indicator_column; 21866 PRODUCE_GLYPHS (it);
21872 if (indicate) 21867 else
21873 { 21868 {
21874 saved_face_id = it->face_id; 21869 int saved_face_id = it->face_id;
21875 it->face_id 21870 it->face_id
21876 = merge_faces (it->w, Qfill_column_indicator, 0, saved_face_id); 21871 = merge_faces (it->w, Qfill_column_indicator, 0, extend_face_id);
21877 it->c = it->char_to_display 21872 it->c = it->char_to_display
21878 = XFIXNAT (Vdisplay_fill_column_indicator_character); 21873 = XFIXNAT (Vdisplay_fill_column_indicator_character);
21879 }
21880 21874
21881 PRODUCE_GLYPHS (it); 21875 PRODUCE_GLYPHS (it);
21882 21876
21883 if (indicate)
21884 {
21885 it->face_id = saved_face_id; 21877 it->face_id = saved_face_id;
21886 it->c = it->char_to_display = ' '; 21878 it->c = it->char_to_display = ' ';
21887 } 21879 }
@@ -26581,8 +26573,8 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
26581 26573
26582 /* Initialize the iterator IT for iteration over STRING beginning 26574 /* Initialize the iterator IT for iteration over STRING beginning
26583 with index START. */ 26575 with index START. */
26584 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start, 26576 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string,
26585 precision, field_width, multibyte); 26577 start, precision, field_width, multibyte);
26586 if (string && STRINGP (lisp_string)) 26578 if (string && STRINGP (lisp_string))
26587 /* LISP_STRING is the one returned by decode_mode_spec. We should 26579 /* LISP_STRING is the one returned by decode_mode_spec. We should
26588 ignore its text properties. */ 26580 ignore its text properties. */
@@ -26597,7 +26589,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
26597 26589
26598 it->face_id 26590 it->face_id
26599 = face_at_string_position (it->w, face_string, face_string_pos, 26591 = face_at_string_position (it->w, face_string, face_string_pos,
26600 0, &endptr, it->base_face_id, false); 26592 0, &endptr, it->base_face_id, false, 0);
26601 face = FACE_FROM_ID (it->f, it->face_id); 26593 face = FACE_FROM_ID (it->f, it->face_id);
26602 it->face_box_p = face->box != FACE_NO_BOX; 26594 it->face_box_p = face->box != FACE_NO_BOX;
26603 } 26595 }
@@ -28502,7 +28494,7 @@ font_for_underline_metrics (struct glyph_string *s)
28502 for (g = s->first_glyph - 1; g >= g0; g--) 28494 for (g = s->first_glyph - 1; g >= g0; g--)
28503 { 28495 {
28504 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); 28496 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
28505 if (!(prev_face && prev_face->underline_p)) 28497 if (!(prev_face && prev_face->underline != FACE_NO_UNDERLINE))
28506 break; 28498 break;
28507 } 28499 }
28508 28500
@@ -32068,7 +32060,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
32068 hlinfo->mouse_face_face_id 32060 hlinfo->mouse_face_face_id
32069 = face_at_buffer_position (w, mouse_charpos, &ignore, 32061 = face_at_buffer_position (w, mouse_charpos, &ignore,
32070 mouse_charpos + 1, 32062 mouse_charpos + 1,
32071 !hlinfo->mouse_face_hidden, -1); 32063 !hlinfo->mouse_face_hidden, -1, 0);
32072 show_mouse_face (hlinfo, DRAW_MOUSE_FACE); 32064 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
32073} 32065}
32074 32066
@@ -32757,11 +32749,10 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
32757 hlinfo->mouse_face_past_end = false; 32749 hlinfo->mouse_face_past_end = false;
32758 hlinfo->mouse_face_window = window; 32750 hlinfo->mouse_face_window = window;
32759 32751
32760 hlinfo->mouse_face_face_id = face_at_string_position (w, string, 32752 hlinfo->mouse_face_face_id =
32761 charpos, 32753 face_at_string_position (w, string, charpos, 0, &ignore,
32762 0, &ignore, 32754 glyph->face_id, true, 0);
32763 glyph->face_id, 32755
32764 true);
32765 show_mouse_face (hlinfo, DRAW_MOUSE_FACE); 32756 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
32766 mouse_face_shown = true; 32757 mouse_face_shown = true;
32767 32758
@@ -33187,7 +33178,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
33187 hlinfo->mouse_face_window = window; 33178 hlinfo->mouse_face_window = window;
33188 hlinfo->mouse_face_face_id 33179 hlinfo->mouse_face_face_id
33189 = face_at_string_position (w, object, pos, 0, &ignore, 33180 = face_at_string_position (w, object, pos, 0, &ignore,
33190 glyph->face_id, true); 33181 glyph->face_id, true, 0);
33191 show_mouse_face (hlinfo, DRAW_MOUSE_FACE); 33182 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
33192 cursor = No_Cursor; 33183 cursor = No_Cursor;
33193 } 33184 }
diff --git a/src/xfaces.c b/src/xfaces.c
index 0c99eea1567..5a741ae8cc6 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *);
347static void free_face_cache (struct face_cache *); 347static void free_face_cache (struct face_cache *);
348static bool merge_face_ref (struct window *w, 348static bool merge_face_ref (struct window *w,
349 struct frame *, Lisp_Object, Lisp_Object *, 349 struct frame *, Lisp_Object, Lisp_Object *,
350 bool, struct named_merge_point *); 350 bool, struct named_merge_point *,
351 enum lface_attribute_index);
351static int color_distance (Emacs_Color *x, Emacs_Color *y); 352static int color_distance (Emacs_Color *x, Emacs_Color *y);
352 353
353#ifdef HAVE_WINDOW_SYSTEM 354#ifdef HAVE_WINDOW_SYSTEM
@@ -1209,7 +1210,7 @@ free_face_colors (struct frame *f, struct face *face)
1209 IF_DEBUG (--ncolors_allocated); 1210 IF_DEBUG (--ncolors_allocated);
1210 } 1211 }
1211 1212
1212 if (face->underline_p 1213 if (face->underline
1213 && !face->underline_defaulted_p) 1214 && !face->underline_defaulted_p)
1214 { 1215 {
1215 x_free_colors (f, &face->underline_color, 1); 1216 x_free_colors (f, &face->underline_color, 1);
@@ -1590,6 +1591,7 @@ the WIDTH times as wide as FACE on FRAME. */)
1590#define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX) 1591#define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
1591#define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX) 1592#define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
1592#define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX) 1593#define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX)
1594#define LFACE_EXTEND(LFACE) AREF ((LFACE), LFACE_EXTEND_INDEX)
1593#define LFACE_DISTANT_FOREGROUND(LFACE) \ 1595#define LFACE_DISTANT_FOREGROUND(LFACE) \
1594 AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX) 1596 AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX)
1595 1597
@@ -1633,6 +1635,10 @@ check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE])
1633 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX]) 1635 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
1634 || STRINGP (attrs[LFACE_UNDERLINE_INDEX]) 1636 || STRINGP (attrs[LFACE_UNDERLINE_INDEX])
1635 || CONSP (attrs[LFACE_UNDERLINE_INDEX])); 1637 || CONSP (attrs[LFACE_UNDERLINE_INDEX]));
1638 eassert (UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX])
1639 || IGNORE_DEFFACE_P (attrs[LFACE_EXTEND_INDEX])
1640 || SYMBOLP (attrs[LFACE_EXTEND_INDEX])
1641 || STRINGP (attrs[LFACE_EXTEND_INDEX]));
1636 eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) 1642 eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
1637 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX]) 1643 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
1638 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX]) 1644 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
@@ -1905,7 +1911,8 @@ get_lface_attributes (struct window *w,
1905 attrs[i] = Qunspecified; 1911 attrs[i] = Qunspecified;
1906 1912
1907 return merge_face_ref (w, f, XCDR (face_remapping), attrs, 1913 return merge_face_ref (w, f, XCDR (face_remapping), attrs,
1908 signal_p, named_merge_points); 1914 signal_p, named_merge_points,
1915 0);
1909 } 1916 }
1910 } 1917 }
1911 1918
@@ -2060,7 +2067,8 @@ merge_face_vectors (struct window *w,
2060 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) 2067 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
2061 && !NILP (from[LFACE_INHERIT_INDEX])) 2068 && !NILP (from[LFACE_INHERIT_INDEX]))
2062 merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], 2069 merge_face_ref (w, f, from[LFACE_INHERIT_INDEX],
2063 to, false, named_merge_points); 2070 to, false, named_merge_points,
2071 0);
2064 2072
2065 if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) 2073 if (FONT_SPEC_P (from[LFACE_FONT_INDEX]))
2066 { 2074 {
@@ -2126,7 +2134,8 @@ merge_face_vectors (struct window *w,
2126static bool 2134static bool
2127merge_named_face (struct window *w, 2135merge_named_face (struct window *w,
2128 struct frame *f, Lisp_Object face_name, Lisp_Object *to, 2136 struct frame *f, Lisp_Object face_name, Lisp_Object *to,
2129 struct named_merge_point *named_merge_points) 2137 struct named_merge_point *named_merge_points,
2138 enum lface_attribute_index attr_filter)
2130{ 2139{
2131 struct named_merge_point named_merge_point; 2140 struct named_merge_point named_merge_point;
2132 2141
@@ -2136,9 +2145,13 @@ merge_named_face (struct window *w,
2136 { 2145 {
2137 Lisp_Object from[LFACE_VECTOR_SIZE]; 2146 Lisp_Object from[LFACE_VECTOR_SIZE];
2138 bool ok = get_lface_attributes (w, f, face_name, from, false, 2147 bool ok = get_lface_attributes (w, f, face_name, from, false,
2139 named_merge_points); 2148 named_merge_points);
2140 2149
2141 if (ok) 2150 eassert (attr_filter < LFACE_VECTOR_SIZE);
2151
2152 if (ok && (attr_filter == 0
2153 || (!NILP (from[attr_filter])
2154 && !UNSPECIFIEDP (from[attr_filter]))))
2142 merge_face_vectors (w, f, from, to, named_merge_points); 2155 merge_face_vectors (w, f, from, to, named_merge_points);
2143 2156
2144 return ok; 2157 return ok;
@@ -2269,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref,
2269 of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face 2282 of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face
2270 inheritance or list structure; it may be 0 for most callers. 2283 inheritance or list structure; it may be 0 for most callers.
2271 2284
2285 ATTR_FILTER is the index of a parameter that conditions the merging
2286 for named faces (case 1) to only the face_ref where
2287 lface[merge_face_ref] is non-nil. To merge unconditionally set this
2288 value to 0.
2289
2272 FACE_REF may be a single face specification or a list of such 2290 FACE_REF may be a single face specification or a list of such
2273 specifications. Each face specification can be: 2291 specifications. Each face specification can be:
2274 2292
@@ -2297,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref,
2297static bool 2315static bool
2298merge_face_ref (struct window *w, 2316merge_face_ref (struct window *w,
2299 struct frame *f, Lisp_Object face_ref, Lisp_Object *to, 2317 struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
2300 bool err_msgs, struct named_merge_point *named_merge_points) 2318 bool err_msgs, struct named_merge_point *named_merge_points,
2319 enum lface_attribute_index attr_filter)
2301{ 2320{
2302 bool ok = true; /* Succeed without an error? */ 2321 bool ok = true; /* Succeed without an error? */
2303 Lisp_Object filtered_face_ref; 2322 Lisp_Object filtered_face_ref;
@@ -2509,7 +2528,15 @@ merge_face_ref (struct window *w,
2509 /* This is not really very useful; it's just like a 2528 /* This is not really very useful; it's just like a
2510 normal face reference. */ 2529 normal face reference. */
2511 if (! merge_face_ref (w, f, value, to, 2530 if (! merge_face_ref (w, f, value, to,
2512 err_msgs, named_merge_points)) 2531 err_msgs, named_merge_points,
2532 attr_filter))
2533 err = true;
2534 }
2535 else if (EQ (keyword, QCextend))
2536 {
2537 if (EQ (value, Qt) || NILP (value))
2538 to[LFACE_EXTEND_INDEX] = value;
2539 else
2513 err = true; 2540 err = true;
2514 } 2541 }
2515 else 2542 else
@@ -2532,16 +2559,19 @@ merge_face_ref (struct window *w,
2532 Lisp_Object next = XCDR (face_ref); 2559 Lisp_Object next = XCDR (face_ref);
2533 2560
2534 if (! NILP (next)) 2561 if (! NILP (next))
2535 ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points); 2562 ok = merge_face_ref (w, f, next, to, err_msgs,
2563 named_merge_points, attr_filter);
2536 2564
2537 if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points)) 2565 if (! merge_face_ref (w, f, first, to, err_msgs,
2566 named_merge_points, attr_filter))
2538 ok = false; 2567 ok = false;
2539 } 2568 }
2540 } 2569 }
2541 else 2570 else
2542 { 2571 {
2543 /* FACE_REF ought to be a face name. */ 2572 /* FACE_REF ought to be a face name. */
2544 ok = merge_named_face (w, f, face_ref, to, named_merge_points); 2573 ok = merge_named_face (w, f, face_ref, to, named_merge_points,
2574 attr_filter);
2545 if (!ok && err_msgs) 2575 if (!ok && err_msgs)
2546 add_to_log ("Invalid face reference: %s", face_ref); 2576 add_to_log ("Invalid face reference: %s", face_ref);
2547 } 2577 }
@@ -3030,6 +3060,17 @@ FRAME 0 means change the face on all frames, and change the default
3030 old_value = LFACE_INVERSE (lface); 3060 old_value = LFACE_INVERSE (lface);
3031 ASET (lface, LFACE_INVERSE_INDEX, value); 3061 ASET (lface, LFACE_INVERSE_INDEX, value);
3032 } 3062 }
3063 else if (EQ (attr, QCextend))
3064 {
3065 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3066 {
3067 CHECK_SYMBOL (value);
3068 if (!EQ (value, Qt) && !NILP (value))
3069 signal_error ("Invalid extend face attribute value", value);
3070 }
3071 old_value = LFACE_EXTEND (lface);
3072 ASET (lface, LFACE_EXTEND_INDEX, value);
3073 }
3033 else if (EQ (attr, QCforeground)) 3074 else if (EQ (attr, QCforeground))
3034 { 3075 {
3035 /* Compatibility with 20.x. */ 3076 /* Compatibility with 20.x. */
@@ -3503,7 +3544,9 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
3503 value = face_boolean_x_resource_value (value, true); 3544 value = face_boolean_x_resource_value (value, true);
3504 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth)) 3545 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
3505 value = intern (SSDATA (value)); 3546 value = intern (SSDATA (value));
3506 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video)) 3547 else if (EQ (attr, QCreverse_video)
3548 || EQ (attr, QCinverse_video)
3549 || EQ (attr, QCextend))
3507 value = face_boolean_x_resource_value (value, true); 3550 value = face_boolean_x_resource_value (value, true);
3508 else if (EQ (attr, QCunderline) 3551 else if (EQ (attr, QCunderline)
3509 || EQ (attr, QCoverline) 3552 || EQ (attr, QCoverline)
@@ -3727,6 +3770,8 @@ frames). If FRAME is omitted or nil, use the selected frame. */)
3727 value = LFACE_SWIDTH (lface); 3770 value = LFACE_SWIDTH (lface);
3728 else if (EQ (keyword, QCinherit)) 3771 else if (EQ (keyword, QCinherit))
3729 value = LFACE_INHERIT (lface); 3772 value = LFACE_INHERIT (lface);
3773 else if (EQ (keyword, QCextend))
3774 value = LFACE_EXTEND (lface);
3730 else if (EQ (keyword, QCfont)) 3775 else if (EQ (keyword, QCfont))
3731 value = LFACE_FONT (lface); 3776 value = LFACE_FONT (lface);
3732 else if (EQ (keyword, QCfontset)) 3777 else if (EQ (keyword, QCfontset))
@@ -3754,7 +3799,9 @@ Value is nil if ATTR doesn't have a discrete set of valid values. */)
3754 3799
3755 if (EQ (attr, QCunderline) || EQ (attr, QCoverline) 3800 if (EQ (attr, QCunderline) || EQ (attr, QCoverline)
3756 || EQ (attr, QCstrike_through) 3801 || EQ (attr, QCstrike_through)
3757 || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video)) 3802 || EQ (attr, QCinverse_video)
3803 || EQ (attr, QCreverse_video)
3804 || EQ (attr, QCextend))
3758 result = list2 (Qt, Qnil); 3805 result = list2 (Qt, Qnil);
3759 3806
3760 return result; 3807 return result;
@@ -4505,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr)
4505 suitable face is found, realize a new one. */ 4552 suitable face is found, realize a new one. */
4506 4553
4507int 4554int
4508face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) 4555face_for_font (struct frame *f, Lisp_Object font_object,
4556 struct face *base_face)
4509{ 4557{
4510 struct face_cache *cache = FRAME_FACE_CACHE (f); 4558 struct face_cache *cache = FRAME_FACE_CACHE (f);
4511 unsigned hash; 4559 unsigned hash;
@@ -4740,7 +4788,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
4740 Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); 4788 Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified);
4741 merge_face_ref (NULL, XFRAME (selected_frame), 4789 merge_face_ref (NULL, XFRAME (selected_frame),
4742 plist, XVECTOR (lface)->contents, 4790 plist, XVECTOR (lface)->contents,
4743 true, 0); 4791 true, NULL, 0);
4744 return lface; 4792 return lface;
4745} 4793}
4746 4794
@@ -4784,6 +4832,9 @@ gui_supports_face_attributes_p (struct frame *f,
4784 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX]) 4832 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
4785 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX], 4833 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
4786 def_attrs[LFACE_INVERSE_INDEX])) 4834 def_attrs[LFACE_INVERSE_INDEX]))
4835 || (!UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX])
4836 && face_attr_equal_p (attrs[LFACE_EXTEND_INDEX],
4837 def_attrs[LFACE_EXTEND_INDEX]))
4787 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX]) 4838 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
4788 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX], 4839 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
4789 def_attrs[LFACE_FOREGROUND_INDEX])) 4840 def_attrs[LFACE_FOREGROUND_INDEX]))
@@ -5094,7 +5145,7 @@ face for italic. */)
5094 5145
5095 for (i = 0; i < LFACE_VECTOR_SIZE; i++) 5146 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
5096 attrs[i] = Qunspecified; 5147 attrs[i] = Qunspecified;
5097 merge_face_ref (NULL, f, attributes, attrs, true, 0); 5148 merge_face_ref (NULL, f, attributes, attrs, true, NULL, 0);
5098 5149
5099 def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); 5150 def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
5100 if (def_face == NULL) 5151 if (def_face == NULL)
@@ -5362,6 +5413,9 @@ realize_default_face (struct frame *f)
5362 ASET (lface, LFACE_FONTSET_INDEX, Qnil); 5413 ASET (lface, LFACE_FONTSET_INDEX, Qnil);
5363 } 5414 }
5364 5415
5416 if (UNSPECIFIEDP (LFACE_EXTEND (lface)))
5417 ASET (lface, LFACE_EXTEND_INDEX, Qnil);
5418
5365 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface))) 5419 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
5366 ASET (lface, LFACE_UNDERLINE_INDEX, Qnil); 5420 ASET (lface, LFACE_UNDERLINE_INDEX, Qnil);
5367 5421
@@ -5698,16 +5752,14 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5698 if (EQ (underline, Qt)) 5752 if (EQ (underline, Qt))
5699 { 5753 {
5700 /* Use default color (same as foreground color). */ 5754 /* Use default color (same as foreground color). */
5701 face->underline_p = true; 5755 face->underline = FACE_UNDER_LINE;
5702 face->underline_type = FACE_UNDER_LINE;
5703 face->underline_defaulted_p = true; 5756 face->underline_defaulted_p = true;
5704 face->underline_color = 0; 5757 face->underline_color = 0;
5705 } 5758 }
5706 else if (STRINGP (underline)) 5759 else if (STRINGP (underline))
5707 { 5760 {
5708 /* Use specified color. */ 5761 /* Use specified color. */
5709 face->underline_p = true; 5762 face->underline = FACE_UNDER_LINE;
5710 face->underline_type = FACE_UNDER_LINE;
5711 face->underline_defaulted_p = false; 5763 face->underline_defaulted_p = false;
5712 face->underline_color 5764 face->underline_color
5713 = load_color (f, face, underline, 5765 = load_color (f, face, underline,
@@ -5715,7 +5767,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5715 } 5767 }
5716 else if (NILP (underline)) 5768 else if (NILP (underline))
5717 { 5769 {
5718 face->underline_p = false; 5770 face->underline = FACE_NO_UNDERLINE;
5719 face->underline_defaulted_p = false; 5771 face->underline_defaulted_p = false;
5720 face->underline_color = 0; 5772 face->underline_color = 0;
5721 } 5773 }
@@ -5723,10 +5775,9 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5723 { 5775 {
5724 /* `(:color COLOR :style STYLE)'. 5776 /* `(:color COLOR :style STYLE)'.
5725 STYLE being one of `line' or `wave'. */ 5777 STYLE being one of `line' or `wave'. */
5726 face->underline_p = true; 5778 face->underline = FACE_UNDER_LINE;
5727 face->underline_color = 0; 5779 face->underline_color = 0;
5728 face->underline_defaulted_p = true; 5780 face->underline_defaulted_p = true;
5729 face->underline_type = FACE_UNDER_LINE;
5730 5781
5731 /* FIXME? This is also not robust about checking the precise form. 5782 /* FIXME? This is also not robust about checking the precise form.
5732 See comments in Finternal_set_lisp_face_attribute. */ 5783 See comments in Finternal_set_lisp_face_attribute. */
@@ -5759,9 +5810,9 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5759 else if (EQ (keyword, QCstyle)) 5810 else if (EQ (keyword, QCstyle))
5760 { 5811 {
5761 if (EQ (value, Qline)) 5812 if (EQ (value, Qline))
5762 face->underline_type = FACE_UNDER_LINE; 5813 face->underline = FACE_UNDER_LINE;
5763 else if (EQ (value, Qwave)) 5814 else if (EQ (value, Qwave))
5764 face->underline_type = FACE_UNDER_WAVE; 5815 face->underline = FACE_UNDER_WAVE;
5765 } 5816 }
5766 } 5817 }
5767 } 5818 }
@@ -5980,7 +6031,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
5980 Lisp_Object attrs[LFACE_VECTOR_SIZE]; 6031 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5981 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); 6032 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5982 memcpy (attrs, default_face->lface, sizeof attrs); 6033 memcpy (attrs, default_face->lface, sizeof attrs);
5983 merge_face_ref (NULL, f, prop, attrs, true, 0); 6034 merge_face_ref (NULL, f, prop, attrs, true, NULL, 0);
5984 face_id = lookup_face (f, attrs); 6035 face_id = lookup_face (f, attrs);
5985 } 6036 }
5986 6037
@@ -5992,6 +6043,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
5992 which a different face is needed, as far as text properties and 6043 which a different face is needed, as far as text properties and
5993 overlays are concerned. W is a window displaying current_buffer. 6044 overlays are concerned. W is a window displaying current_buffer.
5994 6045
6046 ATTR_FILTER is passed merge_face_ref.
6047
5995 REGION_BEG, REGION_END delimit the region, so it can be 6048 REGION_BEG, REGION_END delimit the region, so it can be
5996 highlighted. 6049 highlighted.
5997 6050
@@ -6011,7 +6064,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
6011int 6064int
6012face_at_buffer_position (struct window *w, ptrdiff_t pos, 6065face_at_buffer_position (struct window *w, ptrdiff_t pos,
6013 ptrdiff_t *endptr, ptrdiff_t limit, 6066 ptrdiff_t *endptr, ptrdiff_t limit,
6014 bool mouse, int base_face_id) 6067 bool mouse, int base_face_id,
6068 enum lface_attribute_index attr_filter)
6015{ 6069{
6016 struct frame *f = XFRAME (w->frame); 6070 struct frame *f = XFRAME (w->frame);
6017 Lisp_Object attrs[LFACE_VECTOR_SIZE]; 6071 Lisp_Object attrs[LFACE_VECTOR_SIZE];
@@ -6080,11 +6134,11 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
6080 } 6134 }
6081 6135
6082 /* Begin with attributes from the default face. */ 6136 /* Begin with attributes from the default face. */
6083 memcpy (attrs, default_face->lface, sizeof attrs); 6137 memcpy (attrs, default_face->lface, sizeof(attrs));
6084 6138
6085 /* Merge in attributes specified via text properties. */ 6139 /* Merge in attributes specified via text properties. */
6086 if (!NILP (prop)) 6140 if (!NILP (prop))
6087 merge_face_ref (w, f, prop, attrs, true, 0); 6141 merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
6088 6142
6089 /* Now merge the overlay data. */ 6143 /* Now merge the overlay data. */
6090 noverlays = sort_overlays (overlay_vec, noverlays, w); 6144 noverlays = sort_overlays (overlay_vec, noverlays, w);
@@ -6104,7 +6158,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
6104 so discard the mouse-face text property, if any, and 6158 so discard the mouse-face text property, if any, and
6105 use the overlay property instead. */ 6159 use the overlay property instead. */
6106 memcpy (attrs, default_face->lface, sizeof attrs); 6160 memcpy (attrs, default_face->lface, sizeof attrs);
6107 merge_face_ref (w, f, prop, attrs, true, 0); 6161 merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
6108 } 6162 }
6109 6163
6110 oend = OVERLAY_END (overlay_vec[i]); 6164 oend = OVERLAY_END (overlay_vec[i]);
@@ -6121,8 +6175,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
6121 ptrdiff_t oendpos; 6175 ptrdiff_t oendpos;
6122 6176
6123 prop = Foverlay_get (overlay_vec[i], propname); 6177 prop = Foverlay_get (overlay_vec[i], propname);
6178
6124 if (!NILP (prop)) 6179 if (!NILP (prop))
6125 merge_face_ref (w, f, prop, attrs, true, 0); 6180 merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
6126 6181
6127 oend = OVERLAY_END (overlay_vec[i]); 6182 oend = OVERLAY_END (overlay_vec[i]);
6128 oendpos = OVERLAY_POSITION (oend); 6183 oendpos = OVERLAY_POSITION (oend);
@@ -6188,7 +6243,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
6188 6243
6189 /* Merge in attributes specified via text properties. */ 6244 /* Merge in attributes specified via text properties. */
6190 if (!NILP (prop)) 6245 if (!NILP (prop))
6191 merge_face_ref (w, f, prop, attrs, true, 0); 6246 merge_face_ref (w, f, prop, attrs, true, NULL, 0);
6192 6247
6193 *endptr = endpos; 6248 *endptr = endpos;
6194 6249
@@ -6221,9 +6276,10 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
6221 6276
6222int 6277int
6223face_at_string_position (struct window *w, Lisp_Object string, 6278face_at_string_position (struct window *w, Lisp_Object string,
6224 ptrdiff_t pos, ptrdiff_t bufpos, 6279 ptrdiff_t pos, ptrdiff_t bufpos,
6225 ptrdiff_t *endptr, enum face_id base_face_id, 6280 ptrdiff_t *endptr, enum face_id base_face_id,
6226 bool mouse_p) 6281 bool mouse_p,
6282 enum lface_attribute_index attr_filter)
6227{ 6283{
6228 Lisp_Object prop, position, end, limit; 6284 Lisp_Object prop, position, end, limit;
6229 struct frame *f = XFRAME (WINDOW_FRAME (w)); 6285 struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -6267,7 +6323,7 @@ face_at_string_position (struct window *w, Lisp_Object string,
6267 6323
6268 /* Merge in attributes specified via text properties. */ 6324 /* Merge in attributes specified via text properties. */
6269 if (!NILP (prop)) 6325 if (!NILP (prop))
6270 merge_face_ref (w, f, prop, attrs, true, 0); 6326 merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
6271 6327
6272 /* Look up a realized face with the given face attributes, 6328 /* Look up a realized face with the given face attributes,
6273 or realize a new one for ASCII characters. */ 6329 or realize a new one for ASCII characters. */
@@ -6296,9 +6352,8 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id,
6296{ 6352{
6297 struct frame *f = WINDOW_XFRAME (w); 6353 struct frame *f = WINDOW_XFRAME (w);
6298 Lisp_Object attrs[LFACE_VECTOR_SIZE]; 6354 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6299 struct face *base_face; 6355 struct face *base_face = FACE_FROM_ID_OR_NULL (f, base_face_id);
6300 6356
6301 base_face = FACE_FROM_ID_OR_NULL (f, base_face_id);
6302 if (!base_face) 6357 if (!base_face)
6303 return base_face_id; 6358 return base_face_id;
6304 6359
@@ -6318,17 +6373,19 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id,
6318 6373
6319 if (!NILP (face_name)) 6374 if (!NILP (face_name))
6320 { 6375 {
6321 if (!merge_named_face (w, f, face_name, attrs, 0)) 6376 if (!merge_named_face (w, f, face_name, attrs, NULL, 0))
6322 return base_face_id; 6377 return base_face_id;
6323 } 6378 }
6324 else 6379 else
6325 { 6380 {
6326 struct face *face;
6327 if (face_id < 0) 6381 if (face_id < 0)
6328 return base_face_id; 6382 return base_face_id;
6329 face = FACE_FROM_ID_OR_NULL (f, face_id); 6383
6384 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
6385
6330 if (!face) 6386 if (!face)
6331 return base_face_id; 6387 return base_face_id;
6388
6332 merge_face_vectors (w, f, face->lface, attrs, 0); 6389 merge_face_vectors (w, f, face->lface, attrs, 0);
6333 } 6390 }
6334 6391
@@ -6416,7 +6473,7 @@ dump_realized_face (struct face *face)
6416#endif 6473#endif
6417 fprintf (stderr, "fontset: %d\n", face->fontset); 6474 fprintf (stderr, "fontset: %d\n", face->fontset);
6418 fprintf (stderr, "underline: %d (%s)\n", 6475 fprintf (stderr, "underline: %d (%s)\n",
6419 face->underline_p, 6476 face->underline,
6420 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); 6477 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
6421 fprintf (stderr, "hash: %" PRIuPTR "\n", face->hash); 6478 fprintf (stderr, "hash: %" PRIuPTR "\n", face->hash);
6422} 6479}
@@ -6541,6 +6598,7 @@ syms_of_xfaces (void)
6541 DEFSYM (QCstrike_through, ":strike-through"); 6598 DEFSYM (QCstrike_through, ":strike-through");
6542 DEFSYM (QCbox, ":box"); 6599 DEFSYM (QCbox, ":box");
6543 DEFSYM (QCinherit, ":inherit"); 6600 DEFSYM (QCinherit, ":inherit");
6601 DEFSYM (QCextend, ":extend");
6544 6602
6545 /* Symbols used for Lisp face attribute values. */ 6603 /* Symbols used for Lisp face attribute values. */
6546 DEFSYM (QCcolor, ":color"); 6604 DEFSYM (QCcolor, ":color");
diff --git a/src/xterm.c b/src/xterm.c
index b49c9d6893a..5d8b1482a6d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3813,9 +3813,9 @@ x_draw_glyph_string (struct glyph_string *s)
3813 if (!s->for_overlaps) 3813 if (!s->for_overlaps)
3814 { 3814 {
3815 /* Draw underline. */ 3815 /* Draw underline. */
3816 if (s->face->underline_p) 3816 if (s->face->underline)
3817 { 3817 {
3818 if (s->face->underline_type == FACE_UNDER_WAVE) 3818 if (s->face->underline == FACE_UNDER_WAVE)
3819 { 3819 {
3820 if (s->face->underline_defaulted_p) 3820 if (s->face->underline_defaulted_p)
3821 x_draw_underwave (s); 3821 x_draw_underwave (s);
@@ -3829,13 +3829,13 @@ x_draw_glyph_string (struct glyph_string *s)
3829 XSetForeground (display, s->gc, xgcv.foreground); 3829 XSetForeground (display, s->gc, xgcv.foreground);
3830 } 3830 }
3831 } 3831 }
3832 else if (s->face->underline_type == FACE_UNDER_LINE) 3832 else if (s->face->underline == FACE_UNDER_LINE)
3833 { 3833 {
3834 unsigned long thickness, position; 3834 unsigned long thickness, position;
3835 int y; 3835 int y;
3836 3836
3837 if (s->prev && s->prev->face->underline_p 3837 if (s->prev &&
3838 && s->prev->face->underline_type == FACE_UNDER_LINE) 3838 s->prev->face->underline == FACE_UNDER_LINE)
3839 { 3839 {
3840 /* We use the same underline style as the previous one. */ 3840 /* We use the same underline style as the previous one. */
3841 thickness = s->prev->underline_thickness; 3841 thickness = s->prev->underline_thickness;