From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Ergus via "Emacs development discussions." Newsgroups: gmane.emacs.devel Subject: Re: Question about display engine Date: Wed, 4 Sep 2019 22:19:01 +0200 Message-ID: <20190904201901.fj7uer4hsdmn2w3w@Ergus> References: <20190902110504.zniyfmd7bi53iyxe@Ergus> <83zhjm7juc.fsf@gnu.org> <4663e760-a611-6c29-e0e2-69bde9da87b1@gmx.at> <83tv9t77oq.fsf@gnu.org> <85658428-5253-6099-07b8-79831cf4e689@gmx.at> <83pnkh70d5.fsf@gnu.org> <81596d5c-427e-a95b-b66f-b571ac228ce1@gmx.at> <87pnkfsyhx.fsf@Ergus.i-did-not-set--mail-host-address--so-tickle-me> <2da98931-51d2-eb78-b79c-81323f95b4f6@gmx.at> Reply-To: Ergus Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="2aia2jixbc7ydizs" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="23860"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: NeoMutt/20180716 Cc: Eli Zaretskii , emacs-devel@gnu.org To: martin rudalics Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Sep 04 22:37:44 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1i5c2A-0005xZ-AM for ged-emacs-devel@m.gmane.org; Wed, 04 Sep 2019 22:37:42 +0200 Original-Received: from localhost ([::1]:39080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i5c28-0006iG-E7 for ged-emacs-devel@m.gmane.org; Wed, 04 Sep 2019 16:37:40 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48055) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i5bkN-0004hT-9s for emacs-devel@gnu.org; Wed, 04 Sep 2019 16:19:23 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i5bkI-0000zY-DU for emacs-devel@gnu.org; Wed, 04 Sep 2019 16:19:18 -0400 Original-Received: from sonic314-20.consmr.mail.ir2.yahoo.com ([77.238.177.146]:37059) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1i5bkH-0000yd-PU for emacs-devel@gnu.org; Wed, 04 Sep 2019 16:19:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aol.com; s=a2048; t=1567628352; bh=QzLpFgPI9QBiXcUUJP237lqGQqnO7VC2Q7xO+vd8daw=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From:Subject; b=cYykVbIheTJG0CCAAv1AexMCI0yllqnsORPCiAfHASOm7jllgSe1+ZugxAcp6cMjyr81n6YUDCtNipL2KDeCtqJPcsNTImBehnaFSfn75ESyYtBeCrLQJot3dUz4jKi7La7eD2l63CbYMb9Ni1NLTaNAf1jQ2Icak/69QhPcLbN1g5NTn4JQ+w8ldID5GH/WToKhOTc38VYGsabQp1Cl3n6zYaEMViKsmlQ2/RmoYTiTdZMJEHWoHOXQvtf7RV9rCh3FpZVTS/r2XifUqQGIC8HQDR4jK1seTEfxyblir57RSbOa/u+bJjdjcFM1cZ2bwe8qWdKpr9H3Opae1Jpn5Q== X-YMail-OSG: GmB9WToVM1nkZSfdwJlI63amL_dOW4LFpy8pdcyleUzhDTUnYj1AgyBhq3gpgwE QAiPNyva1TTelfE0hCvdb0QyhjDAL_tt1O4gdpGwYVGzAIZEg_3trZUkHAzX8lL_hm5hAX8aXbLY DFpGqlkgQ8UK7Y9hmPB_0nDbEcSrEIs_1mvtOjs9sx9qGKGeVFa8KHuyaMGlOOYlv_L06ksCU_Zm l11LxAwY67PZzUZi9Xbuktfh2vK5MEZLdCZh8.HY6zxbkTK8y2j_cJl3nazMb.AEeAZeEyHUpNxx YK.howF5fbaR9.C4HGCrb0hmsqvFFWrOS6imoJRgx8KXT1vm3MceqLqUhfQEkBt74zB695BS3vqs H.SFCUyxooJO8NbVhUCVj.5KadgIG_Lf.gZUekWmsRPkkssWJV7lS50I46AcE2l_ed9DO2ORTnUD kLTNoGOyg8KVOLyn7AgwP7cvv8wfLwNNPKHZIOKrgiMm_Ne3mnbpYQ0o70wC33rmCX4ADt0sigH_ sCLjlgZ4yMELPuOsrAvX385vuRGPeolQ5.nvCgHf5emvwqJ9fpvn2gI7wM7oyc.x7YlQFiJa4AWU Q_Xz9LHMSmk8jVO3NJC2FjqJUl1VQ3AVsPnYEggMW1BW.m8qjFf5nI4QVdq33aCxGNdjxryRDDJW eHSI8Mf91DTPxmZTjDYZg6ed3xsZFJGYp42s0rIpkgfk9yuXspqu3dsl54MjkLKnP_9xxzdaALqn g7kOh_DHnnMi_qVUfOMN4E_ZXNjc79zLUJxA_FU1qKv2bmcDpnJxL3T4d7UZg8mnOHEAyTFu7mCQ KSbTgPphViLvfbfNynxuUB_YXjaHq2j48ZDt0.CCcq Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ir2.yahoo.com with HTTP; Wed, 4 Sep 2019 20:19:12 +0000 Original-Received: by smtp402.mail.ir2.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 16a21ce5ac713a3a3b33ea9a2472420f; Wed, 04 Sep 2019 20:19:07 +0000 (UTC) Content-Disposition: inline In-Reply-To: <2da98931-51d2-eb78-b79c-81323f95b4f6@gmx.at> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 77.238.177.146 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:239850 Archived-At: --2aia2jixbc7ydizs Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline Here is the diff of the latest commit. (Patch attached anyway). https://github.com/Ergus/Emacs/commit/4943087027acd3f2c7a54a092b64bc839ef8850e On Wed, Sep 04, 2019 at 10:04:16PM +0200, martin rudalics wrote: >> I have just uploaded some changes but the functionality is still not >> working. >> >> I separated the changes in 3 commits and in the last one are only the >> ones I made in the xdisp.c (the ones that need to be checked, because >> the rest is only infrastructure.) >> >> see the master branch in: https://github.com/Ergus/Emacs > >Please send a patch for current master. Otherwise I have no idea how >to compare your changes. > >Thanks, martin --2aia2jixbc7ydizs Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.patch" diff --git a/lisp/cus-face.el b/lisp/cus-face.el index d73bce42c3..5a49a81043 100644 --- a/lisp/cus-face.el +++ b/lisp/cus-face.el @@ -233,7 +233,11 @@ custom-face-attributes (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 5193c216d0..6b6fcf0d2d 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -342,6 +342,7 @@ face-x-resources (: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 @@ face-italic-p (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 @@ set-face-attribute `: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 @@ set-face-italic (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 @@ face-valid-attribute-values (: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 @@ face-attribute-name-alist (:slant . "slant") (:underline . "underline") (:overline . "overline") + (:extend . "extend") (:strike-through . "strike-through") (:box . "box") (:inverse-video . "inverse-video display") @@ -2432,24 +2458,24 @@ highlight ;; 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/src/dispextern.h b/src/dispextern.h index 05f199ff35..c11a3a7b54 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1564,6 +1564,7 @@ #define FONT_TOO_HIGH(ft) \ LFACE_INHERIT_INDEX, LFACE_FONTSET_INDEX, LFACE_DISTANT_FOREGROUND_INDEX, + LFACE_EXTEND_INDEX, LFACE_VECTOR_SIZE }; @@ -1589,6 +1590,7 @@ #define FONT_TOO_HIGH(ft) \ enum face_underline_type { + FACE_NO_UNDERLINE = 0, FACE_UNDER_LINE, FACE_UNDER_WAVE }; @@ -1632,11 +1634,9 @@ #define FONT_TOO_HIGH(ft) \ /* 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; @@ -1663,7 +1663,7 @@ #define FONT_TOO_HIGH(ft) \ 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. */ @@ -1671,7 +1671,6 @@ #define FONT_TOO_HIGH(ft) \ /* 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; @@ -1681,14 +1680,10 @@ #define FONT_TOO_HIGH(ft) \ 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; @@ -1822,6 +1817,9 @@ #define FACE_FROM_ID_OR_NULL(F, ID) \ ? 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) @@ -2328,7 +2326,7 @@ #define IT_STACK_SIZE 5 /* Face id of the iterator saved in case a glyph from dpvec contains a face. The face is restored when all glyphs from dpvec have been delivered. */ - int saved_face_id; + int saved_face_id, saved_extend_face_id; /* Vector of glyphs for control character translation. The pointer dpvec is set to ctl_chars when a control character is translated. @@ -2390,7 +2388,7 @@ #define OVERLAY_STRING_CHUNK_SIZE 16 ptrdiff_t prev_stop; ptrdiff_t base_level_stop; struct composition_it cmp_it; - int face_id; + int face_id, extend_face_id; /* Save values specific to a given method. */ union { @@ -2448,6 +2446,9 @@ #define OVERLAY_STRING_CHUNK_SIZE 16 /* Face to use. */ int face_id; + /* Face to extend at EOL/ */ + int extend_face_id; + /* Setting of buffer-local variable selective-display-ellipses. */ bool_bf selective_display_ellipsis_p : 1; diff --git a/src/nsterm.m b/src/nsterm.m index 42ef4dd010..99b621533a 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3404,9 +3404,9 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. 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 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. 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 e5874f2d36..99a1db5784 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2479,9 +2479,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; @@ -2492,13 +2492,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; @@ -2512,7 +2512,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 94f969f37c..db7f1e8d34 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -3120,6 +3120,7 @@ init_iterator (struct it *it, struct window *w, struct face *face; it->face_id = remapped_base_face_id; + it->extend_face_id = remapped_base_face_id; /* If we have a boxed mode line, make the first character appear with a left box line. */ @@ -3141,6 +3142,8 @@ init_iterator (struct it *it, struct window *w, /* We will rely on `reseat' to set this up properly, via handle_face_prop. */ it->face_id = it->base_face_id; + it->extend_face_id = it->base_face_id; // ERGUS: FIX_THIS + it->start = it->current; /* Do we need to reorder bidirectional text? Not if this is a @@ -3536,7 +3539,10 @@ handle_stop (struct it *it) /* Use face of preceding text for ellipsis (if invisible) */ if (it->selective_display_ellipsis_p) - it->saved_face_id = it->face_id; + { + it->saved_face_id = it->face_id; + it->saved_extend_face_id = it->extend_face_id; + } /* Here's the description of the semantics of, and the logic behind, the various HANDLED_* statuses: @@ -4154,7 +4160,15 @@ handle_face_prop (struct it *it) 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; + + /* Update the faces id and extend. */ + it->face_id = new_face_id; + + if (FACE_EXTENSIBLE_P (new_face)) + it->extend_face_id = new_face_id; + } + } else { @@ -4253,10 +4267,16 @@ handle_face_prop (struct it *it) 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; + + /* Update the faces id and extend. */ + it->face_id = new_face_id; + + if (FACE_EXTENSIBLE_P (new_face)) + it->extend_face_id = new_face_id; + } } - it->face_id = new_face_id; return HANDLED_NORMALLY; } @@ -4854,6 +4874,9 @@ setup_for_ellipsis (struct it *it, int len) if (it->saved_face_id >= 0) it->face_id = it->saved_face_id; + if (it->saved_extend_face_id >= 0) + it->extend_face_id = it->saved_extend_face_id; + /* If the ellipsis represents buffer text, it means we advanced in the buffer, so we should no longer ignore overlay strings. */ if (it->method == GET_FROM_BUFFER) @@ -5063,7 +5086,8 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos) of buffer or string text. */ static int -handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, +handle_single_display_spec (struct it *it, Lisp_Object spec, + Lisp_Object object, Lisp_Object overlay, struct text_pos *position, ptrdiff_t bufpos, int display_replaced, bool frame_window_p, bool enable_eval_p) @@ -5137,7 +5161,11 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, int steps = XFIXNUM (XCAR (XCDR (it->font_height))); if (EQ (XCAR (it->font_height), Qplus)) steps = - steps; + it->face_id = smaller_face (it->f, it->face_id, steps); + it->extend_face_id + = smaller_face (it->f, it->extend_face_id, steps); + } else if (FUNCTIONP (it->font_height) && enable_eval_p) { @@ -5180,7 +5208,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, } if (new_height > 0) - it->face_id = face_with_height (it->f, it->face_id, new_height); + { + it->face_id + = face_with_height (it->f, it->face_id, new_height); + it->extend_face_id + = face_with_height (it->f, it->extend_face_id, new_height); + } } } @@ -5370,6 +5403,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, it->method = GET_FROM_IMAGE; it->from_overlay = Qnil; it->face_id = face_id; + it->extend_face_id = face_id; // ERGUS: FIX_THIS it->from_disp_prop_p = true; /* Say that we haven't consumed the characters with @@ -6263,6 +6297,7 @@ push_it (struct it *it, struct text_pos *position) p->cmp_it = it->cmp_it; eassert (it->face_id >= 0); p->face_id = it->face_id; + p->extend_face_id = it->extend_face_id; p->string = it->string; p->method = it->method; p->from_overlay = it->from_overlay; @@ -6366,6 +6401,7 @@ pop_it (struct it *it) it->base_level_stop = p->base_level_stop; it->cmp_it = p->cmp_it; it->face_id = p->face_id; + it->extend_face_id = p->extend_face_id; it->current = p->current; it->position = p->position; it->string = p->string; @@ -7142,17 +7178,32 @@ lookup_glyphless_char_display (int c, struct it *it) /* Merge escape glyph face and cache the result. */ +static int +merge_extend_glyph_face (struct it *it, int lface_id) +{ + + struct face *lface = FACE_FROM_ID (it->f, lface_id); + + if (lface && FACE_EXTENSIBLE_P (lface)) + return merge_faces (it->w, Qt, lface_id, it->extend_face_id); + + return it->extend_face_id; +} + +/* Merge escape glyph face and cache the result. */ static struct frame *last_escape_glyph_frame = NULL; static int last_escape_glyph_face_id = (1 << FACE_ID_BITS); static int last_escape_glyph_merged_face_id = 0; static int -merge_escape_glyph_face (struct it *it) +merge_escape_glyph_face (struct it *it, int lface_id) { int face_id; - if (it->f == last_escape_glyph_frame - && it->face_id == last_escape_glyph_face_id) + if (lface_id) + face_id = merge_faces (it->w, Qt, lface_id, it->face_id); + else if (it->f == last_escape_glyph_frame + && it->face_id == last_escape_glyph_face_id) face_id = last_escape_glyph_merged_face_id; else { @@ -7162,6 +7213,7 @@ merge_escape_glyph_face (struct it *it) last_escape_glyph_face_id = it->face_id; last_escape_glyph_merged_face_id = face_id; } + return face_id; } @@ -7187,9 +7239,11 @@ merge_glyphless_glyph_face (struct it *it) last_glyphless_glyph_face_id = it->face_id; last_glyphless_glyph_merged_face_id = face_id; } + return face_id; } + /* Forget the `escape-glyph' and `glyphless-char' faces. This should be called before redisplaying windows, and when the frame's face cache is freed. */ @@ -7275,6 +7329,7 @@ get_next_display_element (struct it *it) it->current.dpvec_index = 0; it->dpvec_face_id = -1; it->saved_face_id = it->face_id; + it->saved_extend_face_id = it->extend_face_id; it->method = GET_FROM_DISPLAY_VECTOR; it->ellipsis_p = false; } @@ -7355,9 +7410,7 @@ get_next_display_element (struct it *it) lface_id = GLYPH_CODE_FACE (gc); } - face_id = (lface_id - ? merge_faces (it->w, Qt, lface_id, it->face_id) - : merge_escape_glyph_face (it)); + face_id = merge_escape_glyph_face (it, lface_id); XSETINT (it->ctl_chars[0], g); XSETINT (it->ctl_chars[1], c ^ 0100); @@ -7373,6 +7426,7 @@ get_next_display_element (struct it *it) /* Merge `nobreak-space' into the current face. */ face_id = merge_faces (it->w, Qnobreak_space, 0, it->face_id); + XSETINT (it->ctl_chars[0], ' '); ctl_len = 1; goto display_control; @@ -7385,7 +7439,8 @@ get_next_display_element (struct it *it) { /* Merge `nobreak-space' into the current face. */ face_id = merge_faces (it->w, Qnobreak_hyphen, 0, - it->face_id); + it->face_id); + XSETINT (it->ctl_chars[0], '-'); ctl_len = 1; goto display_control; @@ -7403,12 +7458,9 @@ get_next_display_element (struct it *it) lface_id = GLYPH_CODE_FACE (gc); } - face_id = (lface_id - ? merge_faces (it->w, Qt, lface_id, it->face_id) - : merge_escape_glyph_face (it)); + face_id = merge_escape_glyph_face (it, lface_id); /* Draw non-ASCII space/hyphen with escape glyph: */ - if (nonascii_space_p || nonascii_hyphen_p) { XSETINT (it->ctl_chars[0], escape_glyph); @@ -7443,6 +7495,7 @@ get_next_display_element (struct it *it) it->current.dpvec_index = 0; it->dpvec_face_id = face_id; it->saved_face_id = it->face_id; + it->saved_extend_face_id = it->extend_face_id; it->method = GET_FROM_DISPLAY_VECTOR; it->ellipsis_p = false; goto get_next; @@ -7778,6 +7831,7 @@ set_iterator_to_next (struct it *it, bool reseat_p) /* Restore face of the iterator to what they were before the display vector entry (these entries may contain faces). */ it->face_id = it->saved_face_id; + it->extend_face_id = it->saved_extend_face_id; if (it->dpvec + it->current.dpvec_index >= it->dpend) { @@ -8012,6 +8066,7 @@ next_element_from_display_vector (struct it *it) eassert (it->dpvec && it->current.dpvec_index >= 0); it->face_id = it->saved_face_id; + it->extend_face_id = it->saved_extend_face_id; /* KFS: This code used to check ip->dpvec[0] instead of the current element. That seemed totally bogus - so I changed it... */ @@ -8027,13 +8082,24 @@ next_element_from_display_vector (struct it *it) the id of a Lisp face, not a realized face. A face id of zero means no face is specified. */ if (it->dpvec_face_id >= 0) - it->face_id = it->dpvec_face_id; + { + it->face_id = it->dpvec_face_id; + //it->extend_face_id = it->dpvec_face_id; // ERGUS: FIX_THIS + } else { int lface_id = GLYPH_CODE_FACE (gc); if (lface_id > 0) - it->face_id = merge_faces (it->w, Qt, lface_id, - it->saved_face_id); + { + it->face_id = merge_faces (it->w, Qt, lface_id, + it->saved_face_id); + + struct face *lface = FACE_FROM_ID (it->f, lface_id); + + if (FACE_EXTENSIBLE_P (lface)) + it->extend_face_id = merge_faces (it->w, Qt, lface_id, + it->saved_extend_face_id);; + } } /* Glyphs in the display vector could have the box face, so we @@ -8061,8 +8127,12 @@ next_element_from_display_vector (struct it *it) GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]); if (lface_id > 0) - next_face_id = merge_faces (it->w, Qt, lface_id, - it->saved_face_id); + { + next_face_id = merge_faces (it->w, Qt, lface_id, + it->saved_face_id); + it->extend_face_id = + merge_extend_glyph_face (it, lface_id); + } } } next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id); @@ -8411,6 +8481,7 @@ next_element_from_ellipsis (struct it *it) was in IT->saved_face_id, and signal that it's there by setting face_before_selective_p. */ it->saved_face_id = it->face_id; + it->saved_extend_face_id = it->extend_face_id; it->method = GET_FROM_BUFFER; it->object = it->w->contents; reseat_at_next_visible_line_start (it, true); @@ -12848,7 +12919,10 @@ display_tool_bar_line (struct it *it, int height) use the tool-bar face for the border too. */ if (!MATRIX_ROW_DISPLAYS_TEXT_P (row) && !EQ (Vauto_resize_tool_bars, Qgrow_only)) - it->face_id = DEFAULT_FACE_ID; + { + it->face_id = DEFAULT_FACE_ID; + it->extend_face_id = DEFAULT_FACE_ID; + } extend_face_to_end_of_line (it); last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1; @@ -20325,7 +20399,7 @@ append_space_for_newline (struct it *it, bool default_face_p) = XFIXNAT (Vdisplay_fill_column_indicator_character); it->face_id = merge_faces (it->w, Qfill_column_indicator, - 0, saved_face_id); + 0, it->extend_face_id); face = FACE_FROM_ID (it->f, it->face_id); goto produce_glyphs; } @@ -20472,33 +20546,33 @@ extend_face_to_end_of_line (struct it *it) 1-``pixel'' wide, so they hit the equality too early. This grace is needed only for R2L rows that are not continued, to produce one extra blank where we could display the cursor. */ - if ((it->current_x >= it->last_visible_x - + (!FRAME_WINDOW_P (f) - && it->glyph_row->reversed_p - && !it->glyph_row->continued_p)) - /* If the window has display margins, we will need to extend - their face even if the text area is filled. */ - && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0 - || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) - return; - - /* Face extension extends the background and box of IT->face_id - to the end of the line. If the background equals the background - of the frame, we don't have to do anything. */ +/* if ((it->current_x >= it->last_visible_x */ +/* + (!FRAME_WINDOW_P (f) */ +/* && it->glyph_row->reversed_p */ +/* && !it->glyph_row->continued_p)) */ +/* /\* If the window has display margins, we will need to extend */ +/* their face even if the text area is filled. *\/ */ +/* && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0 */ +/* || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) */ +/* return; */ + +/* /\* Face extension extends the background and box of IT->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)); - - if (FRAME_WINDOW_P (f) - && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) - && face->box == FACE_NO_BOX - && FACE_COLOR_TO_PIXEL (face->background, f) == FRAME_BACKGROUND_PIXEL (f) -#ifdef HAVE_WINDOW_SYSTEM - && !face->stipple -#endif - && !it->glyph_row->reversed_p - && !Vdisplay_fill_column_indicator) - return; + ? it->saved_extend_face_id + : it->extend_face_id)); + +/* if (FRAME_WINDOW_P (f) */ +/* && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) */ +/* && face->box == FACE_NO_BOX */ +/* && FACE_COLOR_TO_PIXEL (face->background, f) == FRAME_BACKGROUND_PIXEL (f) */ +/* #ifdef HAVE_WINDOW_SYSTEM */ +/* && !face->stipple */ +/* #endif */ +/* && !it->glyph_row->reversed_p */ +/* && !Vdisplay_fill_column_indicator) */ +/* return; */ /* Set the glyph row flag indicating that the face of the last glyph in the text area has to be drawn to the end of the text area. */ @@ -20561,79 +20635,88 @@ 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. */ + 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; + + it->avoid_cursor_p = true; + it->object = Qnil; + memset (&it->position, 0, sizeof it->position); + 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 + + 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); - } + const int char_width = (font->average_width + ? font->average_width + : font->space_width); + int column_x; + + if (indicator_column >= 0 + && !INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x) + && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x) + && column_x >= it->current_x + && column_x <= it->last_visible_x) + { + + /* The stretch width needs to considet the latter + added glyph. */ + const int stretch_width + = column_x - it->current_x - char_width; + + /* Only generate a stretch glyph if there is distance + between current_x and and the indicator position. */ + if (stretch_width > 0) + { + it->face_id = it->extend_face_id; - /* 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; - } - } + 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, it->extend_face_id); + PRODUCE_GLYPHS (it); + it->char_to_display = saved_char; + } + + } + + const int stretch_width = it->last_visible_x - it->current_x; + + if (stretch_width > 0) + { + it->face_id = it->extend_face_id; + + 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); + } + + it->char_to_display = saved_char; + it->position = saved_pos; + it->avoid_cursor_p = saved_avoid_cursor; + it->face_id = saved_face_id; + it->start_of_box_run_p = saved_box_start; + it->object = save_object; } if (it->glyph_row->reversed_p) { @@ -20679,10 +20762,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); @@ -20719,7 +20801,7 @@ extend_face_to_end_of_line (struct it *it) it->len = 1; if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0 - && (it->glyph_row->used[LEFT_MARGIN_AREA] + && (it->glyph_row->used[LEFT_MARGIN_AREA] < WINDOW_LEFT_MARGIN_WIDTH (it->w)) && !it->glyph_row->mode_line_p && FACE_COLOR_TO_PIXEL (face->background, f) != FRAME_BACKGROUND_PIXEL (f)) @@ -20750,10 +20832,8 @@ 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); @@ -20763,24 +20843,25 @@ extend_face_to_end_of_line (struct it *it) indicator_column = -1; do { - int saved_face_id; - bool indicate = it->current_x == indicator_column; - if (indicate) + if (it->current_x == indicator_column) { - 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, + it->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 = ' '; } + else + { + PRODUCE_GLYPHS (it); + } } while (it->current_x <= it->last_visible_x); @@ -25423,7 +25504,8 @@ display_count_lines (ptrdiff_t start_byte, Value is the number of columns displayed. */ static int -display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string, +display_string (const char *string, Lisp_Object lisp_string, + Lisp_Object face_string, ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it, int field_width, int precision, int max_x, int multibyte) { @@ -25446,12 +25528,13 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st if (STRINGP (face_string)) { ptrdiff_t endptr; - struct face *face; it->face_id = face_at_string_position (it->w, face_string, face_string_pos, 0, &endptr, it->base_face_id, false); - face = FACE_FROM_ID (it->f, it->face_id); + + struct face *face = FACE_FROM_ID (it->f, it->face_id); + it->face_box_p = face->box != FACE_NO_BOX; } @@ -27355,7 +27438,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; } diff --git a/src/xfaces.c b/src/xfaces.c index c3cae7e2a6..7987681ce9 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -1209,7 +1209,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 +1590,7 @@ #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX) #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) @@ -2512,6 +2513,13 @@ merge_face_ref (struct window *w, err_msgs, named_merge_points)) err = true; } + else if (EQ (keyword, QCextend)) + { + if (EQ (value, Qt) || NILP (value)) + to[LFACE_EXTEND_INDEX] = value; + else + err = true; + } else err = true; @@ -3030,6 +3038,17 @@ DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute, 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 inverse-video 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 +3522,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 +3748,8 @@ DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute, 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)) @@ -5694,16 +5717,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, @@ -5711,7 +5732,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; } @@ -5719,10 +5740,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. */ @@ -5755,9 +5775,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; } } } @@ -6292,9 +6312,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; @@ -6319,12 +6338,14 @@ merge_faces (struct window *w, Lisp_Object face_name, int 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); } @@ -6412,7 +6433,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); } @@ -6537,6 +6558,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 b761eaf4d1..b8f8db56a7 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3798,9 +3798,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); @@ -3814,13 +3814,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; --2aia2jixbc7ydizs--