From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Ergus Newsgroups: gmane.emacs.devel Subject: Re: Question about display engine Date: Wed, 7 Aug 2019 17:57:38 +0200 Message-ID: <20190807155738.yviofsumjjhqueci@Ergus> References: <20190807005411.qfzzpz5cjrajbwn2@Ergus> <83o911aukn.fsf@gnu.org> <20190807153220.ssijgjxnf6dszz45@Ergus> <83k1bpasic.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="c6he4b3riwkrytbe" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="33351"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: NeoMutt/20180716 Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Aug 07 17:58:23 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 1hvOKU-0008Ym-TU for ged-emacs-devel@m.gmane.org; Wed, 07 Aug 2019 17:58:23 +0200 Original-Received: from localhost ([::1]:42942 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hvOKT-0005iX-Rk for ged-emacs-devel@m.gmane.org; Wed, 07 Aug 2019 11:58:21 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:35272) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hvOJx-0004vT-PJ for emacs-devel@gnu.org; Wed, 07 Aug 2019 11:57:51 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hvOJw-0007GC-1G for emacs-devel@gnu.org; Wed, 07 Aug 2019 11:57:49 -0400 Original-Received: from sonic301-21.consmr.mail.ir2.yahoo.com ([77.238.176.98]:40181) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hvOJv-0007B1-R8 for emacs-devel@gnu.org; Wed, 07 Aug 2019 11:57:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aol.com; s=a2048; t=1565193465; bh=4UGX+3NosHXU5azkXq8xXai0xWLydr+tPGUjUsEuoMM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From:Subject; b=HL6+19CUI8es00O0Z/OVwuJh7nfMvMlNccfwya7AKhXFUHibfBASSaDjW7tkJIyLjRodQu3V4IvkbT/MMPe8BSA1+ouZV9fC3k6u9veK8nb4f+3KPm0GDUUBIyfHT3yLMojZFm/WqjsFiChpCIgM3UkL7x8ygB3LVNoESoaa+n2jqWSqRQWTMEHTlvstalmAkapWAcS4mFNSGKRrUJjhrNCC3bhvIzXuPVb7En4Y60xuoQIVzxNHDGecct32qJdZVBPooJZ42Co6BS0rk1jiH9wALKatPp0cPOvrx8uAo/fc0SOBQEEBhFr/562fUZyc71Xo18/2qW24qVRcOUcA9g== X-YMail-OSG: 9wHnEQcVM1l.Y6A6BulpV6yOYED05xfbaAFGbAf.XaDrGCGVQ3Ok4k.pFilW0wS IhMog9qv7NTCR9o0f5F_FEPFAWsJLK.X6NmVQwC0HxyTLipN1T.scKegxPPn6zLcRuUv1U9xJVbr tgdedA8kBuF4sfdV3VWr5RsVVhu8Yvusg9Oy4UxdK0ol9bCjEx.O47ehZCopXKyUW.tq5n1F6tBk q_nvK3f5HT5N3banjZEYS0kL9lfmpinh8Zx3vTS_gvdgBTtXUnxsA8ZGaatQPVFfQL4vypmzp1HV 2P8o4yCp9.ktTkMqzsGm83Jzvvx.v2AlDhoXOyfK.njDX3bhi9vo0kaD9JSlw4Kz4Pyf3oulnHCc OO6d702mqXXmmWco3JP8v6itWZ4igo5bAUajpiWAS5TKOtkgjUYpqnLin6qmSwinx7h2SAb.eO.0 hJX49jAFCgQe2A1FR45t8A0Cu9DbmaTjgMR55BnaWRnmTisXvTRFoq0t08N8dmNIYrw.eHXXekyA y9kxDIu1tC6Ud9xc5jdktEE2IwSEOzNrU3MWOTI1xYIO7cFzX3mHMF4ZIAZ5qttI9oHU4xzmQJ1W xif3TewtI4R0VRRM5N4uLxwN_.yGn5OSb2i8Uhkyevmr5Cp.ThZepi9xJ1ljHzbLC.aeSwvlQKE1 .1O0.6f2ZDgXDJrKJunL5QtnYQsYZwEAXF50wS2KIHn861CdSYQj7Pel0iofQFPb6GGHYintQvN4 lE7MBQhmcDOaOSSjFF1UdTdxRb8NxN7fH8z7EoFEYZeQFl_Gxvd3JRY_ejCCyXCVBm_6ZNki1mQb 5VA1uFJ_rQyjWfK.mxpYgC3Zv3gEq9LNEntxBO2V7. Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ir2.yahoo.com with HTTP; Wed, 7 Aug 2019 15:57:45 +0000 Original-Received: by smtp410.mail.ir2.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID a4b6fb7f7dafbe7fbf471eb182a6e5b3; Wed, 07 Aug 2019 15:57:41 +0000 (UTC) Content-Disposition: inline In-Reply-To: <83k1bpasic.fsf@gnu.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 77.238.176.98 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:239229 Archived-At: --c6he4b3riwkrytbe Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline On Wed, Aug 07, 2019 at 06:45:47PM +0300, Eli Zaretskii wrote: >> Date: Wed, 7 Aug 2019 17:32:20 +0200 >> From: Ergus >> Cc: emacs-devel@gnu.org >> >> After thinking on that a little bit more since yesterday; maybe it is >> possible to add another basic face for the rest of the line. That face >> will be merged with the previous face as in the example code, so if it >> specifies :underline then merging should work as specified; else, it >> will just use the :underline from the latest glyph. > >Such a face will not be a fixed face, it will have to be recomputed >whenever the face of the text changes, right? E.g., if the face of >the text specifies some color, you'd want this additional face to have >the same colors, right? > We don't use the face itself, just to merge with the previous glyph. >So it doesn't seem to be a face that can be customized in the usual >sense. We could let the users specify face attributes they don't want >to see in face extension, though. Please look the proposed patch. It may need some improvements, but at least the functional part is a decent solution for all the issues in my opinion. --c6he4b3riwkrytbe Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="fix_36858.patch" diff --git a/lisp/faces.el b/lisp/faces.el index 5193c216d0..9c3eba0fff 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2510,7 +2510,7 @@ unwanted effects." ;; Definition stolen from display-line-numbers. (defface fill-column-indicator - '((t :inherit shadow :weight normal :slant normal + '((t :inherit extend-to-end-of-line :weight normal :slant normal :underline nil :overline nil :strike-through nil :box nil :inverse-video nil :stipple nil)) "Face for displaying fill column indicator. @@ -2694,12 +2694,20 @@ the same as `window-divider' face." :group 'basic-faces) (defface internal-border - '((t nil)) + '((t nil)) "Basic face for the internal border." :version "26.1" :group 'frames :group 'basic-faces) +(defface extend-to-end-of-line + '((t :weight normal :slant normal + :underline nil :overline nil :strike-through nil + :box nil :inverse-video nil :stipple nil)) + "Basic face to extend to end if line." + :version "27.1" + :group 'basic-faces) + (defface minibuffer-prompt '((((background dark)) :foreground "cyan") ;; Don't use blue because many users of the MS-DOS port customize diff --git a/src/dispextern.h b/src/dispextern.h index 4e947daa25..9a8bad6d08 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1780,6 +1780,7 @@ enum face_id WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID, INTERNAL_BORDER_FACE_ID, + EXTEND_TO_END_OF_LINE_FACE_ID, BASIC_FACE_ID_SENTINEL }; diff --git a/src/xdisp.c b/src/xdisp.c index 7338d2b7d4..738a6ca129 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -386,6 +386,7 @@ fill_column_indicator_column (struct it *it) { if (Vdisplay_fill_column_indicator && it->continuation_lines_width == 0 + && IT_CHARPOS (*it) < ZV && CHARACTERP (Vdisplay_fill_column_indicator_character)) { Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt) @@ -20468,6 +20469,9 @@ extend_face_to_end_of_line (struct it *it) it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil); } + const int extend_face_merged_id = + merge_faces (it->w, Qextend_to_end_of_line, 0, it->face_id); + #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) { @@ -20519,12 +20523,14 @@ extend_face_to_end_of_line (struct it *it) 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) + int indicator_column_x; + + if (!INT_MULTIPLY_WRAPV (indicator_column, + char_width, &indicator_column_x) + && !INT_ADD_WRAPV (it->lnum_pixel_width, + indicator_column_x, &indicator_column_x) + && indicator_column_x >= it->current_x + && indicator_column_x <= it->last_visible_x) { const char saved_char = it->char_to_display; const struct text_pos saved_pos = it->position; @@ -20533,14 +20539,15 @@ extend_face_to_end_of_line (struct it *it) 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 + /* The stretch width needs to consider the latter added glyph. */ const int stretch_width - = column_x - it->current_x - char_width; + = indicator_column_x - it->current_x - char_width; memset (&it->position, 0, sizeof it->position); it->avoid_cursor_p = true; it->object = Qnil; + it->face_id = extend_face_merged_id; /* Only generate a stretch glyph if there is distance between current_x and and the indicator position. */ @@ -20548,6 +20555,7 @@ extend_face_to_end_of_line (struct it *it) { 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); @@ -20555,24 +20563,29 @@ extend_face_to_end_of_line (struct it *it) /* Generate the glyph indicator only if append_space_for_newline didn't already. */ - if (it->current_x < column_x) + if (it->current_x < indicator_column_x) { + it->face_id + = merge_faces (it->w, Qextend_to_end_of_line, + 0, extend_face_merged_id); + 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; + it->face_id = extend_face_merged_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); + if (it->current_x < it->last_visible_x) { + it->char_to_display = ' '; + PRODUCE_GLYPHS (it); + } + + /* Restore the face after the indicator was generated. */ + it->face_id = saved_face_id; it->char_to_display = saved_char; it->position = saved_pos; @@ -20697,26 +20710,27 @@ 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 = extend_face_merged_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, + && INT_ADD_WRAPV (it->lnum_pixel_width, indicator_column, &indicator_column)) indicator_column = -1; do { int saved_face_id; - bool indicate = it->current_x == indicator_column; + const bool indicate = it->current_x == indicator_column; if (indicate) { 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_merged_id); it->c = it->char_to_display = XFIXNAT (Vdisplay_fill_column_indicator_character); } diff --git a/src/xfaces.c b/src/xfaces.c index c3cae7e2a6..a0b0d9c6f8 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -4598,6 +4598,7 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id) case WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID: name = Qwindow_divider_first_pixel; break; case WINDOW_DIVIDER_LAST_PIXEL_FACE_ID: name = Qwindow_divider_last_pixel; break; case INTERNAL_BORDER_FACE_ID: name = Qinternal_border; break; + case EXTEND_TO_END_OF_LINE_FACE_ID: name = Qextend_to_end_of_line; break; default: emacs_abort (); /* the caller is supposed to pass us a basic face id */ @@ -5293,6 +5294,7 @@ realize_basic_faces (struct frame *f) realize_named_face (f, Qwindow_divider_last_pixel, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID); realize_named_face (f, Qinternal_border, INTERNAL_BORDER_FACE_ID); + realize_named_face (f, Qextend_to_end_of_line, EXTEND_TO_END_OF_LINE_FACE_ID); /* Reflect changes in the `menu' face in menu bars. */ if (FRAME_FACE_CACHE (f)->menu_face_changed_p) @@ -6592,6 +6594,7 @@ syms_of_xfaces (void) DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel"); DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel"); DEFSYM (Qinternal_border, "internal-border"); + DEFSYM (Qextend_to_end_of_line, "extend-to-end-of-line"); /* TTY color-related functions (defined in tty-colors.el). */ DEFSYM (Qtty_color_desc, "tty-color-desc"); --c6he4b3riwkrytbe--