[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;
- [Emacs-diffs] master 0cf11eb 16/20: *etc/NEWS: Added comment about :extend face attribute in NEWS., (continued)
- [Emacs-diffs] master 0cf11eb 16/20: *etc/NEWS: Added comment about :extend face attribute in NEWS., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master faa9b06 05/20: Call handle_face_prop_general to extend face., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master e1b5e80 10/20: Extend face hl-line after end-of-line, Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master 7a10082 19/20: Fix issue calling face_at_pos., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master bc8db39 02/20: Added face parameter :extend., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master cc47cd4 17/20: ; extend_face_id and fill_column_indicator corrections, Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master 95d1c3b 08/20: Add space for cursor to work also in terminal., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master 501846c 18/20: Modify face_at_pos to not modify change IT., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master 38ee12d 14/20: Fixed merge_face_ref recursive calls., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master ab22720 09/20: Fix last change in append_space_for_newline., Jimmy Aguilar Mena, 2019/10/14
- [Emacs-diffs] master 3d6075e 20/20: Merge branch 'feature/extend_face_id',
Jimmy Aguilar Mena <=