emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 3d6075e 20/20: Merge branch 'feature/extend_face_id


From: Jimmy Aguilar Mena
Subject: [Emacs-diffs] master 3d6075e 20/20: Merge branch 'feature/extend_face_id'
Date: Mon, 14 Oct 2019 08:32:35 -0400 (EDT)

branch: master
commit 3d6075e3ee8c447f8974b37007a1b1ae1af8917c
Merge: a122ca6 7a10082
Author: Jimmy Aguilar Mena <address@hidden>
Commit: Jimmy Aguilar Mena <address@hidden>

    Merge branch 'feature/extend_face_id'
    
    New face attribute :extend to control the face extension after
    EOL.
    
    necessary, # especially if it merges an updated upstream into a topic
    branch.  # # Lines starting with '#' will be ignored, and an empty
    message aborts # the commit.
---
 doc/emacs/mark.texi      |   5 +
 doc/lispref/display.texi |  22 ++
 etc/NEWS                 |   7 +
 lisp/cus-face.el         |   6 +-
 lisp/faces.el            |  47 +++-
 lisp/help-fns.el         |   1 +
 lisp/hl-line.el          |   2 +-
 src/dispextern.h         |  27 ++-
 src/font.c               |  10 +-
 src/nsterm.m             |  10 +-
 src/w32term.c            |  12 +-
 src/xdisp.c              | 567 +++++++++++++++++++++++------------------------
 src/xfaces.c             | 144 ++++++++----
 src/xterm.c              |  10 +-
 14 files changed, 492 insertions(+), 378 deletions(-)

diff --git a/doc/emacs/mark.texi b/doc/emacs/mark.texi
index bbeb4cb..f012d72 100644
--- a/doc/emacs/mark.texi
+++ b/doc/emacs/mark.texi
@@ -23,6 +23,11 @@ When the mark is active, we say also that the region is 
active; Emacs
 indicates its extent by highlighting the text within it, using the
 @code{region} face (@pxref{Face Customization}).
 
+This is one of the few faces that has the @code{:extend t} attribute
+by default, which implies that the same face is used to highlight the
+text and space between end of line and the window border.  To
+highlight only the text you could set this attribute to @code{nil}.
+
 @cindex deactivating the mark
   After certain non-motion commands, including any command that
 changes the text in the buffer, Emacs automatically @dfn{deactivates}
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 61bd4ce..1678d32 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -2482,6 +2482,17 @@ faces (@pxref{Displaying Faces}).  If the face to 
inherit from is
 never merges @code{:inherit} attributes.  If a list of faces is used,
 attributes from faces earlier in the list override those from later
 faces.
+
+@item :extend
+Whether or not this face will be extended until the end of the window.
+The value should be @code{t} to extend until end of the window using
+this face or @code{nil} fill the space between the end of the line and
+the end of the window with the default face.  When a face is conformed
+by merging multiple other faces; only those with @code{:extend t} will
+be merged to conform a new face to extend until end of window.  By
+default only @code{region} and @code{hl-line} have this attribute set
+to @code{t}.
+
 @end table
 
 @defun font-family-list &optional frame
@@ -2842,6 +2853,11 @@ This sets the @code{:inverse-video} attribute of 
@var{face} to
 This swaps the foreground and background colors of face @var{face}.
 @end deffn
 
+@deffn Command set-face-extend face extend &optional frame
+This sets the @code{:extend} attribute of @var{face} to
+@var{extend}.
+@end deffn
+
   The following functions examine the attributes of a face.  They
 mostly provide compatibility with old versions of Emacs.  If you don't
 specify @var{frame}, they refer to the selected frame; @code{t} refers
@@ -2900,6 +2916,12 @@ This function returns non-@code{nil} if face @var{face} 
specifies
 a non-@code{nil} @code{:inverse-video} attribute.
 @end defun
 
+@defun face-extend-p face &optional frame
+This function returns non-@code{nil} if face @var{face} specifies
+a non-@code{nil} @code{:extend} attribute.
+@end defun
+
+
 @node Displaying Faces
 @subsection Displaying Faces
 @cindex displaying faces
diff --git a/etc/NEWS b/etc/NEWS
index 34925c1..5923726 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -384,6 +384,13 @@ matches strings where the pattern appears as a 
subsequence.  Put
 simply, makes "foo" complete to both "barfoo" and "frodo".  Add 'flex'
 to 'completion-styles' or 'completion-category-overrides' to use it.
 
++++
+** New face attribute ':extend' to control face extension at EOL.
+There is a new face attribute :extend to use the face attributes to
+extend after the end of the line until the end of the window.  Such
+:extend is set to nil by default in all faces except for 'hl-line' and
+'region' because those extend until the end of the window by default.
+
 ** Connection-local variables
 
 +++
diff --git a/lisp/cus-face.el b/lisp/cus-face.el
index d73bce4..5a49a81 100644
--- a/lisp/cus-face.el
+++ b/lisp/cus-face.el
@@ -233,7 +233,11 @@
             (file :tag "File"
                   :help-echo "Name of bitmap file."
                   :must-match t)))
-
+    (:extend
+     (choice :tag "Extend"
+            :help-echo "Control whether attributes should be extended after 
EOL."
+            (const :tag "Off" nil)
+            (const :tag "On" t)))
     (:inherit
      (repeat :tag "Inherit"
             :help-echo "List of faces to inherit attributes from."
diff --git a/lisp/faces.el b/lisp/faces.el
index c789d37..36fc698 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -342,6 +342,7 @@ is either `foreground-color', `background-color', or a 
keyword."
     (:box (".attributeBox" . "Face.AttributeBox"))
     (:underline (".attributeUnderline" . "Face.AttributeUnderline"))
     (:inverse-video (".attributeInverse" . "Face.AttributeInverse"))
+    (:extend (".attributeExtend" . "Face.AttributeExtend"))
     (:stipple
      (".attributeStipple" . "Face.AttributeStipple")
      (".attributeBackgroundPixmap" . "Face.AttributeBackgroundPixmap"))
@@ -594,6 +595,13 @@ Use `face-attribute' for finer control."
   (let ((italic (face-attribute face :slant frame inherit)))
     (memq italic '(italic oblique))))
 
+(defun face-extend-p (face &optional frame inherit)
+ "Return non-nil if FACE specifies a non-nil extend.
+If the optional argument FRAME is given, report on face FACE in that frame.
+If FRAME is t, report on the defaults for face FACE (for new frames).
+If FRAME is omitted or nil, use the selected frame.
+Optional argument INHERIT is passed to `face-attribute'."
+ (eq (face-attribute face :extend frame inherit) t))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -760,6 +768,11 @@ For convenience, attributes `:family', `:foundry', 
`:width',
 `:height', `:weight', and `:slant' may also be set in one step
 from an X font name:
 
+`:extend'
+
+VALUE specifies whether the FACE should be extended after EOL.
+VALUE must be one of t or nil.
+
 `:font'
 
 Set font-related face attributes from VALUE.
@@ -979,6 +992,18 @@ Use `set-face-attribute' or `modify-face' for finer 
control."
 
 (define-obsolete-function-alias 'set-face-italic-p 'set-face-italic "24.4")
 
+(defun set-face-extend (face extend-p &optional frame)
+  "Specify whether face FACE should be extended.
+EXTEND-P nil means FACE explicitly doesn't extend after EOL.
+EXTEND-P t means FACE extends after EOL.
+
+FRAME nil or not specified means change face on all frames.
+Use `set-face-attribute' to \"unspecify\" underlining."
+  (interactive
+   (let ((list (read-face-and-attribute :extend)))
+     (list (car list) (if (cadr list) t))))
+  (set-face-attribute face frame :extend extend-p))
+
 
 (defalias 'set-face-background-pixmap 'set-face-stipple)
 
@@ -1102,7 +1127,7 @@ an integer value."
           (:slant
            (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
                    font-slant-table))
-          (:inverse-video
+          ((or :inverse-video :extend)
            (mapcar #'(lambda (x) (cons (symbol-name x) x))
                    (internal-lisp-face-attribute-values attribute)))
            ((or :underline :overline :strike-through :box)
@@ -1147,6 +1172,7 @@ an integer value."
     (:slant . "slant")
     (:underline . "underline")
     (:overline . "overline")
+    (:extend . "extend")
     (:strike-through . "strike-through")
     (:box . "box")
     (:inverse-video . "inverse-video display")
@@ -1549,7 +1575,8 @@ is given, in which case return its value instead."
             ;; (see also realize_default_face in xfaces.c).
             (append
              '(:underline nil :overline nil :strike-through nil
-               :box nil :inverse-video nil :stipple nil :inherit nil)
+               :box nil :inverse-video nil :stipple nil :inherit nil
+                :extend nil)
              ;; `display-graphic-p' is unavailable when running
              ;; temacs, prior to loading frame.el.
              (when (fboundp 'display-graphic-p)
@@ -2314,24 +2341,24 @@ If you set `term-file-prefix' to nil, this function 
does nothing."
 ;; if background is light.
 (defface region
   '((((class color) (min-colors 88) (background dark))
-     :background "blue3")
+     :background "blue3" :extend t)
     (((class color) (min-colors 88) (background light) (type gtk))
      :distant-foreground "gtk_selection_fg_color"
-     :background "gtk_selection_bg_color")
+     :background "gtk_selection_bg_color" :extend t)
     (((class color) (min-colors 88) (background light) (type ns))
      :distant-foreground "ns_selection_fg_color"
-     :background "ns_selection_bg_color")
+     :background "ns_selection_bg_color" :extend t)
     (((class color) (min-colors 88) (background light))
-     :background "lightgoldenrod2")
+     :background "lightgoldenrod2" :extend t)
     (((class color) (min-colors 16) (background dark))
-     :background "blue3")
+     :background "blue3" :extend t)
     (((class color) (min-colors 16) (background light))
-     :background "lightgoldenrod2")
+     :background "lightgoldenrod2" :extend t)
     (((class color) (min-colors 8))
-     :background "blue" :foreground "white")
+     :background "blue" :foreground "white" :extend t)
     (((type tty) (class mono))
      :inverse-video t)
-    (t :background "gray"))
+    (t :background "gray" :extend t))
   "Basic face for highlighting the region."
   :version "21.1"
   :group 'basic-faces)
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 5e55240..235aa9a 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -1385,6 +1385,7 @@ If FRAME is omitted or nil, use the selected frame."
                  (:stipple . "Stipple")
                  (:font . "Font")
                  (:fontset . "Fontset")
+                  (:extend . "Extend")
                  (:inherit . "Inherit")))
         (max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x)))
                                         attrs))))
diff --git a/lisp/hl-line.el b/lisp/hl-line.el
index 8d929b8..8d92e36 100644
--- a/lisp/hl-line.el
+++ b/lisp/hl-line.el
@@ -78,7 +78,7 @@ when `global-hl-line-sticky-flag' is non-nil.")
   :group 'convenience)
 
 (defface hl-line
-  '((t :inherit highlight))
+  '((t :inherit highlight :extend t))
   "Default face for highlighting the current line in Hl-Line mode."
   :version "22.1"
   :group 'hl-line)
diff --git a/src/dispextern.h b/src/dispextern.h
index 7a15e27..0615b16 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1607,6 +1607,7 @@ enum lface_attribute_index
   LFACE_INHERIT_INDEX,
   LFACE_FONTSET_INDEX,
   LFACE_DISTANT_FOREGROUND_INDEX,
+  LFACE_EXTEND_INDEX,
   LFACE_VECTOR_SIZE
 };
 
@@ -1632,6 +1633,7 @@ enum face_box_type
 
 enum face_underline_type
 {
+  FACE_NO_UNDERLINE = 0,
   FACE_UNDER_LINE,
   FACE_UNDER_WAVE
 };
@@ -1675,11 +1677,9 @@ struct face
   /* Pixel value or color index of background color.  */
   unsigned long background;
 
-  /* Pixel value or color index of underline color.  */
+  /* Pixel value or color index of underline, overlined,
+     strike-through, or box color.  */
   unsigned long underline_color;
-
-  /* Pixel value or color index of overlined, strike-through, or box
-     color.  */
   unsigned long overline_color;
   unsigned long strike_through_color;
   unsigned long box_color;
@@ -1706,7 +1706,7 @@ struct face
   ENUM_BF (face_box_type) box : 2;
 
   /* Style of underlining. */
-  ENUM_BF (face_underline_type) underline_type : 1;
+  ENUM_BF (face_underline_type) underline : 2;
 
   /* If `box' above specifies a 3D type, true means use box_color for
      drawing shadows.  */
@@ -1714,7 +1714,6 @@ struct face
 
   /* Non-zero if text in this face should be underlined, overlined,
      strike-through or have a box drawn around it.  */
-  bool_bf underline_p : 1;
   bool_bf overline_p : 1;
   bool_bf strike_through_p : 1;
 
@@ -1724,14 +1723,10 @@ struct face
   bool_bf foreground_defaulted_p : 1;
   bool_bf background_defaulted_p : 1;
 
-  /* True means that either no color is specified for underlining or that
-     the specified color couldn't be loaded.  Use the foreground
-     color when drawing in that case. */
-  bool_bf underline_defaulted_p : 1;
-
   /* True means that either no color is specified for the corresponding
      attribute or that the specified color couldn't be loaded.
      Use the foreground color when drawing in that case. */
+  bool_bf underline_defaulted_p : 1;
   bool_bf overline_color_defaulted_p : 1;
   bool_bf strike_through_color_defaulted_p : 1;
   bool_bf box_color_defaulted_p : 1;
@@ -1867,6 +1862,9 @@ struct face_cache
    ? FRAME_FACE_CACHE (F)->faces_by_id[ID]             \
    : NULL)
 
+#define FACE_EXTENSIBLE_P(F)                   \
+  (!NILP (F->lface[LFACE_EXTEND_INDEX]))
+
 /* True if FACE is suitable for displaying ASCII characters.  */
 INLINE bool
 FACE_SUITABLE_FOR_ASCII_CHAR_P (struct face *face)
@@ -3553,12 +3551,13 @@ int lookup_derived_face (struct window *, struct frame 
*,
 void init_frame_faces (struct frame *);
 void free_frame_faces (struct frame *);
 void recompute_basic_faces (struct frame *);
-int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, 
ptrdiff_t,
-                             bool, int);
+int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *,
+                             ptrdiff_t, bool, int, enum lface_attribute_index);
 int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, 
ptrdiff_t,
                              bool, Lisp_Object);
 int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, 
ptrdiff_t,
-                             ptrdiff_t *, enum face_id, bool);
+                             ptrdiff_t *, enum face_id, bool,
+                             enum lface_attribute_index);
 int merge_faces (struct window *, Lisp_Object, int, int);
 int compute_char_face (struct frame *, int, Lisp_Object);
 void free_all_realized_faces (Lisp_Object);
diff --git a/src/font.c b/src/font.c
index 6bc977f..7fdadb1 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,
 
       if (STRINGP (string))
        face_id = face_at_string_position (w, string, pos, 0, &endptr,
-                                          DEFAULT_FACE_ID, false);
+                                          DEFAULT_FACE_ID, false, 0);
       else
        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);
     }
   if (multibyte)
@@ -3832,7 +3832,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t 
*limit,
 
       if (NILP (string))
          face_id = face_at_buffer_position (w, pos, &ignore, *limit,
-                                            false, -1);
+                                            false, -1, 0);
       else
        {
          face_id =
@@ -3841,7 +3841,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t 
*limit,
            : lookup_basic_face (w, f, DEFAULT_FACE_ID);
 
          face_id = face_at_string_position (w, string, pos, 0, &ignore,
-                                            face_id, false);
+                                            face_id, false, 0);
        }
       face = FACE_FROM_ID (f, face_id);
     }
@@ -4618,7 +4618,7 @@ DEFUN ("internal-char-font", Finternal_char_font, 
Sinternal_char_font, 1, 2, 0,
       w = XWINDOW (window);
       f = XFRAME (w->frame);
       face_id = face_at_buffer_position (w, pos, &dummy,
-                                        pos + 100, false, -1);
+                                         pos + 100, false, -1, 0);
     }
   if (! CHAR_VALID_P (c))
     return Qnil;
diff --git a/src/nsterm.m b/src/nsterm.m
index c8094d0..5583c61 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3404,9 +3404,9 @@ ns_draw_text_decoration (struct glyph_string *s, struct 
face *face,
     return;
 
   /* Do underline.  */
-  if (face->underline_p)
+  if (face->underline)
     {
-      if (s->face->underline_type == FACE_UNDER_WAVE)
+      if (s->face->underline == FACE_UNDER_WAVE)
         {
           if (face->underline_defaulted_p)
             [defaultCol set];
@@ -3415,15 +3415,15 @@ ns_draw_text_decoration (struct glyph_string *s, struct 
face *face,
 
           ns_draw_underwave (s, width, x);
         }
-      else if (s->face->underline_type == FACE_UNDER_LINE)
+      else if (s->face->underline == FACE_UNDER_LINE)
         {
 
           NSRect r;
           unsigned long thickness, position;
 
           /* If the prev was underlined, match its appearance.  */
-          if (s->prev && s->prev->face->underline_p
-             && s->prev->face->underline_type == FACE_UNDER_LINE
+          if (s->prev
+             && s->prev->face->underline == FACE_UNDER_LINE
               && s->prev->underline_thickness > 0)
             {
               thickness = s->prev->underline_thickness;
diff --git a/src/w32term.c b/src/w32term.c
index 82256db..9da0845 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2481,9 +2481,9 @@ w32_draw_glyph_string (struct glyph_string *s)
   if (!s->for_overlaps)
     {
       /* Draw underline.  */
-      if (s->face->underline_p)
+      if (s->face->underline)
         {
-          if (s->face->underline_type == FACE_UNDER_WAVE)
+          if (s->face->underline == FACE_UNDER_WAVE)
             {
               COLORREF color;
 
@@ -2494,13 +2494,13 @@ w32_draw_glyph_string (struct glyph_string *s)
 
               w32_draw_underwave (s, color);
             }
-          else if (s->face->underline_type == FACE_UNDER_LINE)
+          else if (s->face->underline == FACE_UNDER_LINE)
             {
               unsigned long thickness, position;
               int y;
 
-              if (s->prev && s->prev->face->underline_p
-                 && s->prev->face->underline_type == FACE_UNDER_LINE)
+              if (s->prev
+                 && s->prev->face->underline == FACE_UNDER_LINE)
                 {
                   /* We use the same underline style as the previous one.  */
                   thickness = s->prev->underline_thickness;
@@ -2514,7 +2514,7 @@ w32_draw_glyph_string (struct glyph_string *s)
                  BOOL use_underline_position_properties;
                  Lisp_Object val
                    = buffer_local_value (Qunderline_minimum_offset,
-                                       s->w->contents);
+                                         s->w->contents);
                  if (FIXNUMP (val))
                    minimum_offset = max (0, XFIXNUM (val));
                  else
diff --git a/src/xdisp.c b/src/xdisp.c
index 1cfd7ef..30be492 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -431,17 +431,26 @@ static Lisp_Object list_of_error;
    met, return the (nonnegative) column number, else return a negative
    value.  */
 static int
-fill_column_indicator_column (struct it *it)
+fill_column_indicator_column (struct it *it, int char_width)
 {
   if (Vdisplay_fill_column_indicator
+      && !it->w->pseudo_window_p
       && it->continuation_lines_width == 0
       && CHARACTERP (Vdisplay_fill_column_indicator_character))
     {
       Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt)
                         ? BVAR (current_buffer, fill_column)
                         : Vdisplay_fill_column_indicator_column);
+
+      /* The stretch width needs to consider the latter
+        added glyph in append_space_for_newline.  */
       if (RANGED_FIXNUMP (0, col, INT_MAX))
-       return XFIXNUM (col);
+       {
+          int icol = XFIXNUM (col);
+         if (!INT_MULTIPLY_WRAPV (char_width, icol, &icol)
+             && !INT_ADD_WRAPV (it->lnum_pixel_width, icol, &icol))
+           return icol;
+       }
     }
   return -1;
 }
@@ -984,7 +993,7 @@ static int handle_display_spec (struct it *, Lisp_Object, 
Lisp_Object,
 static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object,
                                       Lisp_Object, struct text_pos *,
                                       ptrdiff_t, int, bool, bool);
-static int underlying_face_id (struct it *);
+static int underlying_face_id (const struct it *);
 
 #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true)
 #define face_after_it_pos(IT)  face_before_or_after_it_pos (IT, false)
@@ -4148,56 +4157,20 @@ handle_fontified_prop (struct it *it)
                                Faces
  ***********************************************************************/
 
-/* 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)
+static int
+face_at_pos (const struct it *it, enum lface_attribute_index attr_filter)
 {
-  int new_face_id;
   ptrdiff_t next_stop;
 
   if (!STRINGP (it->string))
     {
-      new_face_id
-       = face_at_buffer_position (it->w,
-                                  IT_CHARPOS (*it),
-                                  &next_stop,
-                                  (IT_CHARPOS (*it)
-                                   + TEXT_PROP_DISTANCE_LIMIT),
-                                  false, it->base_face_id);
-
-      /* Is this a start of a run of characters with box face?
-        Caveat: this can be called for a freshly initialized
-        iterator; face_id is -1 in this case.  We know that the new
-        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
-        usual, we don't know whether limit is really the end.  */
-      if (new_face_id != it->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
-            the definition of FACE_FROM_ID_OR_NULL.  This will happen
-            if this is the initial call that gets the face.  */
-         struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
-
-         /* 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
-            face there that's different from new_face_id.  */
-         if (!old_face && IT_CHARPOS (*it) > BEG)
-           {
-             int prev_face_id = face_before_it_pos (it);
-
-             old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
-           }
-
-         /* If the new face has a box, but the old face does not,
-            this is the start of a run of characters with box face,
-            i.e. this character has a shadow on the left side.  */
-         it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
-                                   && (old_face == NULL || !old_face->box));
-         it->face_box_p = new_face->box != FACE_NO_BOX;
-       }
+      return face_at_buffer_position (it->w,
+                                      IT_CHARPOS (*it),
+                                      &next_stop,
+                                      (IT_CHARPOS (*it)
+                                      + TEXT_PROP_DISTANCE_LIMIT),
+                                      false, it->base_face_id,
+                                      attr_filter);
     }
   else
     {
@@ -4207,7 +4180,7 @@ handle_face_prop (struct it *it)
       Lisp_Object from_overlay
        = (it->current.overlay_string_index >= 0
           ? it->string_overlays[it->current.overlay_string_index
-                                % OVERLAY_STRING_CHUNK_SIZE]
+                                % OVERLAY_STRING_CHUNK_SIZE]
           : Qnil);
 
       /* See if we got to this string directly or indirectly from
@@ -4222,7 +4195,7 @@ handle_face_prop (struct it *it)
            if (it->stack[i].current.overlay_string_index >= 0)
              from_overlay
                = it->string_overlays[it->stack[i].current.overlay_string_index
-                                     % OVERLAY_STRING_CHUNK_SIZE];
+                                     % OVERLAY_STRING_CHUNK_SIZE];
            else if (! NILP (it->stack[i].from_overlay))
              from_overlay = it->stack[i].from_overlay;
 
@@ -4237,12 +4210,12 @@ handle_face_prop (struct it *it)
             only on text properties and ignores overlays.  */
          base_face_id
            = face_for_overlay_string (it->w,
-                                      IT_CHARPOS (*it),
-                                      &next_stop,
-                                      (IT_CHARPOS (*it)
-                                       + TEXT_PROP_DISTANCE_LIMIT),
-                                      false,
-                                      from_overlay);
+                                      IT_CHARPOS (*it),
+                                      &next_stop,
+                                      (IT_CHARPOS (*it)
+                                       + TEXT_PROP_DISTANCE_LIMIT),
+                                      false,
+                                      from_overlay);
        }
       else
        {
@@ -4271,35 +4244,60 @@ handle_face_prop (struct it *it)
            : underlying_face_id (it);
        }
 
-      new_face_id = face_at_string_position (it->w,
-                                            it->string,
-                                            IT_STRING_CHARPOS (*it),
-                                            bufpos,
-                                            &next_stop,
-                                            base_face_id, false);
+      return face_at_string_position (it->w,
+                                      it->string,
+                                      IT_STRING_CHARPOS (*it),
+                                      bufpos,
+                                      &next_stop,
+                                      base_face_id, false,
+                                      attr_filter);
+    } // !STRINGP (it->string))
+}
+
 
-      /* Is this a start of a run of characters with box?  Caveat:
-        this can be called for a freshly allocated iterator; face_id
-        is -1 is this case.  We know that the new face will not
-        change until the next check pos, i.e. if the new face has a
-        box, all characters up to that position will have a
-        box.  But, as usual, we don't know whether that position
-        is really the end.  */
-      if (new_face_id != it->face_id)
+/* 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)
+{
+  const int new_face_id = face_at_pos (it, 0);
+
+
+  /* Is this a start of a run of characters with box face?
+     Caveat: this can be called for a freshly initialized
+     iterator; face_id is -1 in this case.  We know that the new
+     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
+     usual, we don't know whether limit is really the end.  */
+  if (new_face_id != it->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
+        the definition of FACE_FROM_ID_OR_NULL.  This will happen
+        if this is the initial call that gets the face.  */
+      struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
+
+      /* 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
+        face there that's different from new_face_id.  */
+      if (!STRINGP (it->string)
+          && !old_face
+          && IT_CHARPOS (*it) > BEG)
        {
-         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);
+         const int prev_face_id = face_before_it_pos (it);
 
-         /* 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
-            shadow on the left side.  */
-         it->start_of_box_run_p
-           = new_face->box && (old_face == NULL || !old_face->box);
-         it->face_box_p = new_face->box != FACE_NO_BOX;
+         old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
        }
+
+      /* If the new face has a box, but the old face does not,
+        this is the start of a run of characters with box face,
+        i.e. this character has a shadow on the left side.  */
+      it->face_id = new_face_id;
+      it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
+                                && (old_face == NULL || !old_face->box));
+      it->face_box_p = new_face->box != FACE_NO_BOX;
     }
 
-  it->face_id = new_face_id;
   return HANDLED_NORMALLY;
 }
 
@@ -4310,7 +4308,7 @@ handle_face_prop (struct it *it)
    Otherwise, use the iterator's base_face_id.  */
 
 static int
-underlying_face_id (struct it *it)
+underlying_face_id (const struct it *it)
 {
   int face_id = it->base_face_id, i;
 
@@ -4423,12 +4421,9 @@ face_before_or_after_it_pos (struct it *it, bool 
before_p)
       base_face_id = underlying_face_id (it);
 
       /* Get the face for ASCII, or unibyte.  */
-      face_id = face_at_string_position (it->w,
-                                        it->string,
-                                        charpos,
-                                        bufpos,
-                                        &next_check_charpos,
-                                        base_face_id, false);
+      face_id = face_at_string_position (it->w, it->string, charpos,
+                                         bufpos, &next_check_charpos,
+                                         base_face_id, false, 0);
 
       /* Correct the face for charsets different from ASCII.  Do it
         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)
       face_id = face_at_buffer_position (it->w,
                                         CHARPOS (pos),
                                         &next_check_charpos,
-                                        limit, false, -1);
+                                         limit, false, -1, 0);
 
       /* Correct the face for charsets different from ASCII.  Do it
         for the multibyte case only.  The face returned above is
@@ -7638,7 +7633,8 @@ get_next_display_element (struct it *it)
                          next_face_id
                            = face_at_string_position (it->w, base_string,
                                                       CHARPOS (pos), 0,
-                                                      &ignore, face_id, false);
+                                                      &ignore, face_id,
+                                                      false, 0);
                          it->end_of_box_run_p
                            = (FACE_FROM_ID (it->f, next_face_id)->box
                               == FACE_NO_BOX);
@@ -7649,10 +7645,11 @@ get_next_display_element (struct it *it)
                  else
                    {
                      next_face_id =
-                       face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
+                       face_at_buffer_position (it->w, CHARPOS (pos),
+                                                &ignore,
                                                 CHARPOS (pos)
                                                 + TEXT_PROP_DISTANCE_LIMIT,
-                                                false, -1);
+                                                false, -1, 0);
                      it->end_of_box_run_p
                        = (FACE_FROM_ID (it->f, next_face_id)->box
                           == FACE_NO_BOX);
@@ -21366,80 +21363,78 @@ compute_line_metrics (struct it *it)
 static bool
 append_space_for_newline (struct it *it, bool default_face_p)
 {
-#ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (it->f))
+  int n = it->glyph_row->used[TEXT_AREA];
+
+  if (it->glyph_row->glyphs[TEXT_AREA] + n
+      < it->glyph_row->glyphs[1 + TEXT_AREA])
     {
-      int n = it->glyph_row->used[TEXT_AREA];
-
-      if (it->glyph_row->glyphs[TEXT_AREA] + n
-         < it->glyph_row->glyphs[1 + TEXT_AREA])
-       {
-         /* Save some values that must not be changed.
-            Must save IT->c and IT->len because otherwise
-            ITERATOR_AT_END_P wouldn't work anymore after
-            append_space_for_newline has been called.  */
-         enum display_element_type saved_what = it->what;
-         int saved_c = it->c, saved_len = it->len;
-         int saved_char_to_display = it->char_to_display;
-         int saved_x = it->current_x;
-         int saved_face_id = it->face_id;
-         bool saved_box_end = it->end_of_box_run_p;
-         struct text_pos saved_pos;
-         Lisp_Object saved_object;
-         struct face *face;
+      /* Save some values that must not be changed.
+        Must save IT->c and IT->len because otherwise
+        ITERATOR_AT_END_P wouldn't work anymore after
+        append_space_for_newline has been called.  */
+      enum display_element_type saved_what = it->what;
+      int saved_c = it->c, saved_len = it->len;
+      int saved_char_to_display = it->char_to_display;
+      int saved_x = it->current_x;
+      const int saved_face_id = it->face_id;
+      bool saved_box_end = it->end_of_box_run_p;
+      struct text_pos saved_pos = it->position;
+      Lisp_Object saved_object = it->object;
+      struct face *face;
 
-         saved_object = it->object;
-         saved_pos = it->position;
+      it->what = IT_CHARACTER;
+      memset (&it->position, 0, sizeof it->position);
+      it->object = Qnil;
+      it->len = 1;
 
-         it->what = IT_CHARACTER;
-         memset (&it->position, 0, sizeof it->position);
-         it->object = Qnil;
-         it->len = 1;
+      int char_width = 1;
 
-         int local_default_face_id =
+      if (default_face_p
+#ifdef HAVE_WINDOW_SYSTEM
+          || FRAME_WINDOW_P (it->f)
+#endif
+         )
+       {
+         const int local_default_face_id =
            lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
          struct face* default_face =
            FACE_FROM_ID_OR_NULL (it->f, local_default_face_id);
 
-         /* Corner case for when display-fill-column-indicator-mode
-            is active and the extra character should be added in the
-            same place than the line.  */
-         int indicator_column = (it->w->pseudo_window_p == 0
-                                 ? fill_column_indicator_column (it)
-                                 : -1);
-         if (indicator_column >= 0)
-           {
-              struct font *font = (default_face->font
-                                   ? default_face->font
-                                   : FRAME_FONT (it->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)
-                  && it->current_x == column_x)
-                {
-                  it->c = it->char_to_display
-                    = XFIXNAT (Vdisplay_fill_column_indicator_character);
-                  it->face_id
-                    = merge_faces (it->w, Qfill_column_indicator,
-                                   0, saved_face_id);
-                  face = FACE_FROM_ID (it->f, it->face_id);
-                  goto produce_glyphs;
-                }
+#ifdef HAVE_WINDOW_SYSTEM
+         if (FRAME_WINDOW_P (it->f))
+           {
+             struct font *font = (default_face->font
+                                  ? default_face->font
+                                  : FRAME_FONT (it->f));
+             char_width = (font->average_width
+                           ? font->average_width
+                           : font->space_width);
            }
+#endif
+         if (default_face_p)
+           it->face_id = local_default_face_id;
+       }
+      /* Corner case for when display-fill-column-indicator-mode
+        is active and the extra character should be added in the
+        same place than the line.  */
+
+      const int indicator_column =
+       fill_column_indicator_column (it, char_width);
 
+      if (it->current_x == indicator_column)
+       {
+         it->c = it->char_to_display
+           = XFIXNAT (Vdisplay_fill_column_indicator_character);
+         it->face_id
+           = merge_faces (it->w, Qfill_column_indicator,
+                          0, saved_face_id);
+         face = FACE_FROM_ID (it->f, it->face_id);
+       }
+      else
+       {
          it->c = it->char_to_display = ' ';
          /* If the default face was remapped, be sure to use the
             remapped face for the appended newline.  */
-         if (default_face_p)
-           it->face_id = local_default_face_id;
-         else if (it->face_before_selective_p)
-           it->face_id = it->saved_face_id;
 
          face = FACE_FROM_ID (it->f, it->face_id);
          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)
                 so leave the box flag set.  */
              && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
            it->end_of_box_run_p = false;
-
-       produce_glyphs:
-         PRODUCE_GLYPHS (it);
-
+       }
+      PRODUCE_GLYPHS (it);
+#ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (it->f))
+       {
          /* Make sure this space glyph has the right ascent and
             descent values, or else cursor at end of line will look
             funny, and height of empty lines will be incorrect.  */
@@ -21477,8 +21473,8 @@ append_space_for_newline (struct it *it, bool 
default_face_p)
                 gui_produce_glyph for newline characters.  */
              height = get_it_property (it, Qline_height);
              if (CONSP (height)
-                 && CONSP (XCDR (height))
-                 && NILP (XCDR (XCDR (height))))
+                 && CONSP (XCDR (height))
+                 && NILP (XCDR (XCDR (height))))
                {
                  total_height = XCAR (XCDR (height));
                  height = XCAR (height);
@@ -21507,12 +21503,12 @@ append_space_for_newline (struct it *it, bool 
default_face_p)
 
                  if (!NILP (total_height))
                    spacing = calc_line_height_property (it, total_height, font,
-                                                        boff, false);
+                                                        boff, false);
                  else
                    {
                      spacing = get_it_property (it, Qline_spacing);
                      spacing = calc_line_height_property (it, spacing, font,
-                                                          boff, false);
+                                                          boff, false);
                    }
                  if (FIXNUMP (spacing))
                    {
@@ -21535,22 +21531,21 @@ append_space_for_newline (struct it *it, bool 
default_face_p)
 
          g->ascent = it->max_ascent;
          g->descent = it->max_descent;
-
-         it->override_ascent = -1;
-         it->constrain_row_ascent_descent_p = false;
-         it->current_x = saved_x;
-         it->object = saved_object;
-         it->position = saved_pos;
-         it->what = saved_what;
-         it->face_id = saved_face_id;
-         it->len = saved_len;
-         it->c = saved_c;
-         it->char_to_display = saved_char_to_display;
-         it->end_of_box_run_p = saved_box_end;
-         return true;
        }
+#endif /* HAVE_WINDOW_SYSTEM  */
+      it->override_ascent = -1;
+      it->constrain_row_ascent_descent_p = false;
+      it->current_x = saved_x;
+      it->object = saved_object;
+      it->position = saved_pos;
+      it->what = saved_what;
+      it->face_id = saved_face_id;
+      it->len = saved_len;
+      it->c = saved_c;
+      it->char_to_display = saved_char_to_display;
+      it->end_of_box_run_p = saved_box_end;
+      return true;
     }
-#endif
 
   return false;
 }
@@ -21566,7 +21561,6 @@ append_space_for_newline (struct it *it, bool 
default_face_p)
 static void
 extend_face_to_end_of_line (struct it *it)
 {
-  struct face *face;
   struct frame *f = it->f;
 
   /* If line is already filled, do nothing.  Non window-system frames
@@ -21584,12 +21578,17 @@ extend_face_to_end_of_line (struct it *it)
           || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
     return;
 
-  /* Face extension extends the background and box of IT->face_id
+  const int extend_face_id = (it->face_id == DEFAULT_FACE_ID
+                              || it->s != NULL)
+    ? DEFAULT_FACE_ID
+    : face_at_pos (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
      of the frame, we don't have to do anything.  */
-  face = FACE_FROM_ID (f, (it->face_before_selective_p
-                          ? it->saved_face_id
-                          : it->face_id));
+  struct face *face = FACE_FROM_ID (f, (it->face_before_selective_p
+                                        ? it->saved_face_id
+                                        : extend_face_id));
 
   if (FRAME_WINDOW_P (f)
       && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
@@ -21612,9 +21611,7 @@ extend_face_to_end_of_line (struct it *it)
      that the character will always be single byte in unibyte
      text.  */
   if (!ASCII_CHAR_P (it->c))
-    {
       it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
-    }
 
   /* The default face, possibly remapped. */
   struct face *default_face =
@@ -21665,79 +21662,81 @@ extend_face_to_end_of_line (struct it *it)
          /* Display fill column indicator if not in modeline or
             toolbar and display fill column indicator mode is
             active.  */
-         int indicator_column = (it->w->pseudo_window_p == 0
-                                 ? fill_column_indicator_column (it)
-                                 : -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);
+
+         const int indicator_column =
+           fill_column_indicator_column (it, char_width);
+
+         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 = extend_face_id;
+         it->avoid_cursor_p = true;
+         it->object = Qnil;
+
+         if (indicator_column >= 0
+             && indicator_column > it->current_x
+             && indicator_column < 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
-                    append_space_for_newline didn't already.  */
-                 if (it->current_x < column_x)
-                   {
-                     it->char_to_display
-                       = XFIXNAT (Vdisplay_fill_column_indicator_character);
-                     it->face_id
-                       = merge_faces (it->w, Qfill_column_indicator,
-                                      0, saved_face_id);
-                     PRODUCE_GLYPHS (it);
-                   }
-
-                 /* Restore the face after the indicator was generated.  */
-                 it->face_id = saved_face_id;
-
-                 /* 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;
-               }
+             /* Here we substract char_width because we want the
+                column indicator in the column INDICATOR_COLUMN, not
+                after it.  */
+             const int stretch_width =
+               indicator_column - it->current_x - char_width;
+
+             memset (&it->position, 0, sizeof it->position);
+
+             /* 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
+                append_space_for_newline didn't already.  */
+             if (it->current_x < indicator_column)
+               {
+                 const int save_face_id = it->face_id;
+                 it->char_to_display
+                   = XFIXNAT (Vdisplay_fill_column_indicator_character);
+                 it->face_id
+                   = merge_faces (it->w, Qfill_column_indicator,
+                                  0, extend_face_id);
+                 PRODUCE_GLYPHS (it);
+                 it->face_id = save_face_id;
+               }
             }
+
+         /* 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)
        {
@@ -21783,10 +21782,9 @@ extend_face_to_end_of_line (struct it *it)
              /* The last row's stretch glyph should get the default
                 face, to avoid painting the rest of the window with
                 the region face, if the region ends at ZV.  */
-             if (it->glyph_row->ends_at_zv_p)
-               it->face_id = default_face->id;
-             else
-               it->face_id = face->id;
+             it->face_id = (it->glyph_row->ends_at_zv_p ?
+                            default_face->id : face->id);
+
              it->start_of_box_run_p = false;
              append_stretch_glyph (it, Qnil, stretch_width,
                                    it->ascent + it->descent, stretch_ascent);
@@ -21808,14 +21806,11 @@ extend_face_to_end_of_line (struct it *it)
     {
       /* Save some values that must not be changed.  */
       int saved_x = it->current_x;
-      struct text_pos saved_pos;
-      Lisp_Object saved_object;
+      struct text_pos saved_pos = it->position;
+      Lisp_Object saved_object = it->object;;
       enum display_element_type saved_what = it->what;
       int saved_face_id = it->face_id;
 
-      saved_object = it->object;
-      saved_pos = it->position;
-
       it->what = IT_CHARACTER;
       memset (&it->position, 0, sizeof it->position);
       it->object = Qnil;
@@ -21854,34 +21849,31 @@ extend_face_to_end_of_line (struct it *it)
       /* The last row's blank glyphs should get the default face, to
         avoid painting the rest of the window with the region face,
         if the region ends at ZV.  */
-      if (it->glyph_row->ends_at_zv_p)
-       it->face_id = default_face->id;
-      else
-       it->face_id = face->id;
+      it->face_id = (it->glyph_row->ends_at_zv_p ?
+                     default_face->id : face->id);
 
       /* Display fill-column indicator if needed.  */
-      int indicator_column = fill_column_indicator_column (it);
-      if (indicator_column >= 0
-         && INT_ADD_WRAPV (it->lnum_pixel_width, indicator_column,
-                           &indicator_column))
-       indicator_column = -1;
+      /* We need to subtract 1 to the indicator_column here because we
+        will add the indicator IN the column indicator number, not
+        after it.  We compare the variable it->current_x before
+        producing the glyph.  When FRAME_WINDOW_P we substract
+        CHAR_WIDTH calculating STRETCH_WIDTH for the same reason.  */
+      const int indicator_column =
+       fill_column_indicator_column (it, 1) - 1;
       do
        {
-         int saved_face_id;
-         bool indicate = it->current_x == indicator_column;
-         if (indicate)
+         if (it->current_x != indicator_column)
+           PRODUCE_GLYPHS (it);
+         else
            {
-             saved_face_id = it->face_id;
+             int saved_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, 
extend_face_id);
              it->c = it->char_to_display
                = XFIXNAT (Vdisplay_fill_column_indicator_character);
-           }
 
-         PRODUCE_GLYPHS (it);
+             PRODUCE_GLYPHS (it);
 
-         if (indicate)
-           {
              it->face_id = saved_face_id;
              it->c = it->char_to_display = ' ';
            }
@@ -26581,8 +26573,8 @@ display_string (const char *string, Lisp_Object 
lisp_string, Lisp_Object face_st
 
   /* Initialize the iterator IT for iteration over STRING beginning
      with index START.  */
-  reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
-                   precision, field_width, multibyte);
+  reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string,
+                    start, precision, field_width, multibyte);
   if (string && STRINGP (lisp_string))
     /* LISP_STRING is the one returned by decode_mode_spec.  We should
        ignore its text properties.  */
@@ -26597,7 +26589,7 @@ display_string (const char *string, Lisp_Object 
lisp_string, Lisp_Object face_st
 
       it->face_id
        = face_at_string_position (it->w, face_string, face_string_pos,
-                                  0, &endptr, it->base_face_id, false);
+                                  0, &endptr, it->base_face_id, false, 0);
       face = FACE_FROM_ID (it->f, it->face_id);
       it->face_box_p = face->box != FACE_NO_BOX;
     }
@@ -28502,7 +28494,7 @@ font_for_underline_metrics (struct glyph_string *s)
   for (g = s->first_glyph - 1; g >= g0; g--)
     {
       struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
-      if (!(prev_face && prev_face->underline_p))
+      if (!(prev_face && prev_face->underline != FACE_NO_UNDERLINE))
        break;
     }
 
@@ -32068,7 +32060,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
   hlinfo->mouse_face_face_id
     = face_at_buffer_position (w, mouse_charpos, &ignore,
                               mouse_charpos + 1,
-                              !hlinfo->mouse_face_hidden, -1);
+                               !hlinfo->mouse_face_hidden, -1, 0);
   show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
 }
 
@@ -32757,11 +32749,10 @@ note_mode_line_or_margin_highlight (Lisp_Object 
window, int x, int y,
          hlinfo->mouse_face_past_end = false;
          hlinfo->mouse_face_window   = window;
 
-         hlinfo->mouse_face_face_id = face_at_string_position (w, string,
-                                                               charpos,
-                                                               0, &ignore,
-                                                               glyph->face_id,
-                                                               true);
+         hlinfo->mouse_face_face_id =
+           face_at_string_position (w, string, charpos, 0, &ignore,
+                                    glyph->face_id, true, 0);
+
          show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
          mouse_face_shown = true;
 
@@ -33187,7 +33178,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
              hlinfo->mouse_face_window = window;
              hlinfo->mouse_face_face_id
                = face_at_string_position (w, object, pos, 0, &ignore,
-                                          glyph->face_id, true);
+                                          glyph->face_id, true, 0);
              show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
              cursor = No_Cursor;
            }
diff --git a/src/xfaces.c b/src/xfaces.c
index 0c99eea..5a741ae 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *);
 static void free_face_cache (struct face_cache *);
 static bool merge_face_ref (struct window *w,
                             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);
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1209,7 +1210,7 @@ free_face_colors (struct frame *f, struct face *face)
       IF_DEBUG (--ncolors_allocated);
     }
 
-  if (face->underline_p
+  if (face->underline
       && !face->underline_defaulted_p)
     {
       x_free_colors (f, &face->underline_color, 1);
@@ -1590,6 +1591,7 @@ the WIDTH times as wide as FACE on FRAME.  */)
 #define LFACE_FONT(LFACE)          AREF ((LFACE), LFACE_FONT_INDEX)
 #define LFACE_INHERIT(LFACE)       AREF ((LFACE), LFACE_INHERIT_INDEX)
 #define LFACE_FONTSET(LFACE)       AREF ((LFACE), LFACE_FONTSET_INDEX)
+#define LFACE_EXTEND(LFACE)        AREF ((LFACE), LFACE_EXTEND_INDEX)
 #define LFACE_DISTANT_FOREGROUND(LFACE) \
   AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX)
 
@@ -1633,6 +1635,10 @@ check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE])
           || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
           || STRINGP (attrs[LFACE_UNDERLINE_INDEX])
           || CONSP (attrs[LFACE_UNDERLINE_INDEX]));
+  eassert (UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_EXTEND_INDEX])
+          || SYMBOLP (attrs[LFACE_EXTEND_INDEX])
+          || STRINGP (attrs[LFACE_EXTEND_INDEX]));
   eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
           || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
           || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
@@ -1905,7 +1911,8 @@ get_lface_attributes (struct window *w,
            attrs[i] = Qunspecified;
 
          return merge_face_ref (w, f, XCDR (face_remapping), attrs,
-                                signal_p, named_merge_points);
+                                signal_p, named_merge_points,
+                                0);
        }
     }
 
@@ -2060,7 +2067,8 @@ merge_face_vectors (struct window *w,
   if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
       && !NILP (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]))
     {
@@ -2126,7 +2134,8 @@ merge_face_vectors (struct window *w,
 static bool
 merge_named_face (struct window *w,
                   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;
 
@@ -2136,9 +2145,13 @@ merge_named_face (struct window *w,
     {
       Lisp_Object from[LFACE_VECTOR_SIZE];
       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);
 
       return ok;
@@ -2269,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref,
    of ERR_MSGS).  Use NAMED_MERGE_POINTS to detect loops in face
    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
    specifications.  Each face specification can be:
 
@@ -2297,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref,
 static bool
 merge_face_ref (struct window *w,
                 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? */
   Lisp_Object filtered_face_ref;
@@ -2509,7 +2528,15 @@ merge_face_ref (struct window *w,
                  /* This is not really very useful; it's just like a
                     normal face reference.  */
                  if (! merge_face_ref (w, f, value, to,
-                                       err_msgs, named_merge_points))
+                                       err_msgs, named_merge_points,
+                                       attr_filter))
+                   err = true;
+               }
+             else if (EQ (keyword, QCextend))
+               {
+                 if (EQ (value, Qt) || NILP (value))
+                   to[LFACE_EXTEND_INDEX] = value;
+                 else
                    err = true;
                }
              else
@@ -2532,16 +2559,19 @@ merge_face_ref (struct window *w,
          Lisp_Object next = XCDR (face_ref);
 
          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, attr_filter);
 
-         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, attr_filter))
            ok = false;
        }
     }
   else
     {
       /* 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)
        add_to_log ("Invalid face reference: %s", face_ref);
     }
@@ -3030,6 +3060,17 @@ FRAME 0 means change the face on all frames, and change 
the default
       old_value = LFACE_INVERSE (lface);
       ASET (lface, LFACE_INVERSE_INDEX, value);
     }
+  else if (EQ (attr, QCextend))
+    {
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+       {
+         CHECK_SYMBOL (value);
+         if (!EQ (value, Qt) && !NILP (value))
+           signal_error ("Invalid extend face attribute value", value);
+       }
+      old_value = LFACE_EXTEND (lface);
+      ASET (lface, LFACE_EXTEND_INDEX, value);
+    }
   else if (EQ (attr, QCforeground))
     {
       /* Compatibility with 20.x.  */
@@ -3503,7 +3544,9 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
     value = face_boolean_x_resource_value (value, true);
   else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
     value = intern (SSDATA (value));
-  else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
+  else if (EQ (attr, QCreverse_video)
+           || EQ (attr, QCinverse_video)
+           || EQ (attr, QCextend))
     value = face_boolean_x_resource_value (value, true);
   else if (EQ (attr, QCunderline)
           || EQ (attr, QCoverline)
@@ -3727,6 +3770,8 @@ frames).  If FRAME is omitted or nil, use the selected 
frame.  */)
     value = LFACE_SWIDTH (lface);
   else if (EQ (keyword, QCinherit))
     value = LFACE_INHERIT (lface);
+  else if (EQ (keyword, QCextend))
+    value = LFACE_EXTEND (lface);
   else if (EQ (keyword, QCfont))
     value = LFACE_FONT (lface);
   else if (EQ (keyword, QCfontset))
@@ -3754,7 +3799,9 @@ Value is nil if ATTR doesn't have a discrete set of valid 
values.  */)
 
   if (EQ (attr, QCunderline) || EQ (attr, QCoverline)
       || EQ (attr, QCstrike_through)
-      || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
+      || EQ (attr, QCinverse_video)
+      || EQ (attr, QCreverse_video)
+      || EQ (attr, QCextend))
     result = list2 (Qt, Qnil);
 
   return result;
@@ -4505,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr)
    suitable face is found, realize a new one.  */
 
 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);
   unsigned hash;
@@ -4740,7 +4788,7 @@ DEFUN ("face-attributes-as-vector", 
Fface_attributes_as_vector,
   Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified);
   merge_face_ref (NULL, XFRAME (selected_frame),
                   plist, XVECTOR (lface)->contents,
-                 true, 0);
+                  true, NULL, 0);
   return lface;
 }
 
@@ -4784,6 +4832,9 @@ gui_supports_face_attributes_p (struct frame *f,
       || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
          && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
                                def_attrs[LFACE_INVERSE_INDEX]))
+      || (!UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX])
+         && face_attr_equal_p (attrs[LFACE_EXTEND_INDEX],
+                               def_attrs[LFACE_EXTEND_INDEX]))
       || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
          && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
                                def_attrs[LFACE_FOREGROUND_INDEX]))
@@ -5094,7 +5145,7 @@ face for italic.  */)
 
   for (i = 0; i < LFACE_VECTOR_SIZE; i++)
     attrs[i] = Qunspecified;
-  merge_face_ref (NULL, f, attributes, attrs, true, 0);
+  merge_face_ref (NULL, f, attributes, attrs, true, NULL, 0);
 
   def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
   if (def_face == NULL)
@@ -5362,6 +5413,9 @@ realize_default_face (struct frame *f)
        ASET (lface, LFACE_FONTSET_INDEX, Qnil);
     }
 
+  if (UNSPECIFIEDP (LFACE_EXTEND (lface)))
+    ASET (lface, LFACE_EXTEND_INDEX, Qnil);
+
   if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
     ASET (lface, LFACE_UNDERLINE_INDEX, Qnil);
 
@@ -5698,16 +5752,14 @@ realize_gui_face (struct face_cache *cache, Lisp_Object 
attrs[LFACE_VECTOR_SIZE]
   if (EQ (underline, Qt))
     {
       /* Use default color (same as foreground color).  */
-      face->underline_p = true;
-      face->underline_type = FACE_UNDER_LINE;
+      face->underline = FACE_UNDER_LINE;
       face->underline_defaulted_p = true;
       face->underline_color = 0;
     }
   else if (STRINGP (underline))
     {
       /* Use specified color.  */
-      face->underline_p = true;
-      face->underline_type = FACE_UNDER_LINE;
+      face->underline = FACE_UNDER_LINE;
       face->underline_defaulted_p = false;
       face->underline_color
        = load_color (f, face, underline,
@@ -5715,7 +5767,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object 
attrs[LFACE_VECTOR_SIZE]
     }
   else if (NILP (underline))
     {
-      face->underline_p = false;
+      face->underline = FACE_NO_UNDERLINE;
       face->underline_defaulted_p = false;
       face->underline_color = 0;
     }
@@ -5723,10 +5775,9 @@ realize_gui_face (struct face_cache *cache, Lisp_Object 
attrs[LFACE_VECTOR_SIZE]
     {
       /* `(:color COLOR :style STYLE)'.
          STYLE being one of `line' or `wave'. */
-      face->underline_p = true;
+      face->underline = FACE_UNDER_LINE;
       face->underline_color = 0;
       face->underline_defaulted_p = true;
-      face->underline_type = FACE_UNDER_LINE;
 
       /* FIXME?  This is also not robust about checking the precise form.
          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]
           else if (EQ (keyword, QCstyle))
             {
               if (EQ (value, Qline))
-                face->underline_type = FACE_UNDER_LINE;
+                face->underline = FACE_UNDER_LINE;
               else if (EQ (value, Qwave))
-                face->underline_type = FACE_UNDER_WAVE;
+                face->underline = FACE_UNDER_WAVE;
             }
         }
     }
@@ -5980,7 +6031,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object 
prop)
       Lisp_Object attrs[LFACE_VECTOR_SIZE];
       struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
       memcpy (attrs, default_face->lface, sizeof attrs);
-      merge_face_ref (NULL, f, prop, attrs, true, 0);
+      merge_face_ref (NULL, f, prop, attrs, true, NULL, 0);
       face_id = lookup_face (f, attrs);
     }
 
@@ -5992,6 +6043,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object 
prop)
    which a different face is needed, as far as text properties and
    overlays are concerned.  W is a window displaying current_buffer.
 
+   ATTR_FILTER is passed merge_face_ref.
+
    REGION_BEG, REGION_END delimit the region, so it can be
    highlighted.
 
@@ -6011,7 +6064,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object 
prop)
 int
 face_at_buffer_position (struct window *w, ptrdiff_t pos,
                         ptrdiff_t *endptr, ptrdiff_t limit,
-                        bool mouse, int base_face_id)
+                         bool mouse, int base_face_id,
+                         enum lface_attribute_index attr_filter)
 {
   struct frame *f = XFRAME (w->frame);
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
@@ -6080,11 +6134,11 @@ face_at_buffer_position (struct window *w, ptrdiff_t 
pos,
     }
 
   /* Begin with attributes from the default face.  */
-  memcpy (attrs, default_face->lface, sizeof attrs);
+  memcpy (attrs, default_face->lface, sizeof(attrs));
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_ref (w, f, prop, attrs, true, 0);
+    merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
 
   /* Now merge the overlay data.  */
   noverlays = sort_overlays (overlay_vec, noverlays, w);
@@ -6104,7 +6158,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
                 so discard the mouse-face text property, if any, and
                 use the overlay property instead.  */
              memcpy (attrs, default_face->lface, sizeof attrs);
-             merge_face_ref (w, f, prop, attrs, true, 0);
+             merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
            }
 
          oend = OVERLAY_END (overlay_vec[i]);
@@ -6121,8 +6175,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
          ptrdiff_t oendpos;
 
          prop = Foverlay_get (overlay_vec[i], propname);
+
          if (!NILP (prop))
-           merge_face_ref (w, f, prop, attrs, true, 0);
+           merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
 
          oend = OVERLAY_END (overlay_vec[i]);
          oendpos = OVERLAY_POSITION (oend);
@@ -6188,7 +6243,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_ref (w, f, prop, attrs, true, 0);
+    merge_face_ref (w, f, prop, attrs, true, NULL, 0);
 
   *endptr = endpos;
 
@@ -6221,9 +6276,10 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
 
 int
 face_at_string_position (struct window *w, Lisp_Object string,
-                        ptrdiff_t pos, ptrdiff_t bufpos,
-                        ptrdiff_t *endptr, enum face_id base_face_id,
-                        bool mouse_p)
+                         ptrdiff_t pos, ptrdiff_t bufpos,
+                         ptrdiff_t *endptr, enum face_id base_face_id,
+                         bool mouse_p,
+                         enum lface_attribute_index attr_filter)
 {
   Lisp_Object prop, position, end, limit;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -6267,7 +6323,7 @@ face_at_string_position (struct window *w, Lisp_Object 
string,
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_ref (w, f, prop, attrs, true, 0);
+    merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
 
   /* Look up a realized face with the given face attributes,
      or realize a new one for ASCII characters.  */
@@ -6296,9 +6352,8 @@ merge_faces (struct window *w, Lisp_Object face_name, int 
face_id,
 {
   struct frame *f = WINDOW_XFRAME (w);
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  struct face *base_face;
+  struct face *base_face = FACE_FROM_ID_OR_NULL (f, base_face_id);
 
-  base_face = FACE_FROM_ID_OR_NULL (f, base_face_id);
   if (!base_face)
     return base_face_id;
 
@@ -6318,17 +6373,19 @@ merge_faces (struct window *w, Lisp_Object face_name, 
int face_id,
 
   if (!NILP (face_name))
     {
-      if (!merge_named_face (w, f, face_name, attrs, 0))
+      if (!merge_named_face (w, f, face_name, attrs, NULL, 0))
        return base_face_id;
     }
   else
     {
-      struct face *face;
       if (face_id < 0)
        return base_face_id;
-      face = FACE_FROM_ID_OR_NULL (f, face_id);
+
+      struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
+
       if (!face)
        return base_face_id;
+
       merge_face_vectors (w, f, face->lface, attrs, 0);
     }
 
@@ -6416,7 +6473,7 @@ dump_realized_face (struct face *face)
 #endif
   fprintf (stderr, "fontset: %d\n", face->fontset);
   fprintf (stderr, "underline: %d (%s)\n",
-          face->underline_p,
+          face->underline,
           SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
   fprintf (stderr, "hash: %" PRIuPTR "\n", face->hash);
 }
@@ -6541,6 +6598,7 @@ syms_of_xfaces (void)
   DEFSYM (QCstrike_through, ":strike-through");
   DEFSYM (QCbox, ":box");
   DEFSYM (QCinherit, ":inherit");
+  DEFSYM (QCextend, ":extend");
 
   /* Symbols used for Lisp face attribute values.  */
   DEFSYM (QCcolor, ":color");
diff --git a/src/xterm.c b/src/xterm.c
index b49c9d6..5d8b148 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3813,9 +3813,9 @@ x_draw_glyph_string (struct glyph_string *s)
   if (!s->for_overlaps)
     {
       /* Draw underline.  */
-      if (s->face->underline_p)
+      if (s->face->underline)
         {
-          if (s->face->underline_type == FACE_UNDER_WAVE)
+          if (s->face->underline == FACE_UNDER_WAVE)
             {
               if (s->face->underline_defaulted_p)
                 x_draw_underwave (s);
@@ -3829,13 +3829,13 @@ x_draw_glyph_string (struct glyph_string *s)
                   XSetForeground (display, s->gc, xgcv.foreground);
                 }
             }
-          else if (s->face->underline_type == FACE_UNDER_LINE)
+          else if (s->face->underline == FACE_UNDER_LINE)
             {
               unsigned long thickness, position;
               int y;
 
-              if (s->prev && s->prev->face->underline_p
-                 && s->prev->face->underline_type == FACE_UNDER_LINE)
+              if (s->prev &&
+                 s->prev->face->underline == FACE_UNDER_LINE)
                 {
                   /* We use the same underline style as the previous one.  */
                   thickness = s->prev->underline_thickness;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]