From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Po Lu Newsgroups: gmane.emacs.devel Subject: Re: Making `x-underline-at-descent-line' a face attribute Date: Fri, 07 Jan 2022 19:04:50 +0800 Message-ID: <877dbbyffx.fsf@yahoo.com> References: <87lezt5v7h.fsf.ref@yahoo.com> <87lezt5v7h.fsf@yahoo.com> <83r19l8d94.fsf@gnu.org> <87wnjd434b.fsf@yahoo.com> <83ee5l8433.fsf@gnu.org> <877dbd3vdk.fsf@yahoo.com> <8335m17z17.fsf@gnu.org> <87tueg1iei.fsf@yahoo.com> <83zgo858a2.fsf@gnu.org> <871r1kyq3e.fsf@yahoo.com> <83mtk854rt.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="7436"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Jan 07 13:12:47 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n5o6w-0001fQ-40 for ged-emacs-devel@m.gmane-mx.org; Fri, 07 Jan 2022 13:12:46 +0100 Original-Received: from localhost ([::1]:39154 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n5o6u-0001Dd-Uu for ged-emacs-devel@m.gmane-mx.org; Fri, 07 Jan 2022 07:12:44 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:45756) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n5n40-0001Sp-GZ for emacs-devel@gnu.org; Fri, 07 Jan 2022 06:05:40 -0500 Original-Received: from sonic304-21.consmr.mail.ne1.yahoo.com ([66.163.191.147]:35848) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n5n3p-00020F-2E for emacs-devel@gnu.org; Fri, 07 Jan 2022 06:05:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1641553499; bh=7DSX28OlVpYc/FI9UBn0KReL2BdnfyhHnHtQZTdk4zQ=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=bLi1exVgZMNnDlKWHqXHU0TPPYAfNBrls2HXBLt1965zy9ULCK514O/+vCOmlafbDsK+oZZ9plqdfgBzF4QXNadrOMYlcpNAoc8ZDhvKXTpet6SRXcpPRb9kRkrpWaUcDgHqqOgyt5HQEuXgOX5ITtknBP8BD7bN+wxhmpyLE77I1RMJ3gKPj42qkNtJjBJn69d4RqIOaG6QqTVp3olijTPpcvMOtteNZT+/fkYmBBbVkDuYDSukcIz09nCe0xTAziGAu70h8no73ELaFvBKkryNBwPYl+Vsq+KWzmRlYmEDraXLHV90u34vylQCV5SDDnxSVYiLLBx64WDufko2LQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1641553499; bh=5t5tul+XN8YBbg67p4FCUI9xCbV4PigXGeK+9ekJYNU=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=SgW4PiCozfgGS612Sls/d6CTESpG+uU7ugEmbVH1JJPh1cPlZFwFaPfOdOQ2BRXstG33rTIRLad67uoezLbmeORkuhEuzoQRbqiaizbV1+CeCxCc9WIJdmSYqZKANdhuW6aw9rgIfFNhPRWPs+riF343+5SHmjFQGsevyKXVS/JCtQX3Fq0Ldt7vr0VmEobHfaU4tVpMGcMQ8urrJunT/w9p8nn5E2r7F/5ObBhFWd69hNQ2CspDYpaaSN14jINOFKSmbKlGS8fTXwGGqEEudQAFy+HA29tWQk24BBdFPp57ck7TruADwdd0lw2DStijed3eWtES/Qo8wtzvAJj2Jw== X-YMail-OSG: NkHExLIVM1ngFyaEBwPSrIE1Oc4189_Ng2hW1gv7YvKnm6oJ7pzjjb54.N5WIby nXYXEgSzSxAHNr1lAf2_PbL24ywEtJu.xfVqPyKsyPj2jkib.NpJFo4aXSzcAKiBbynQo3gGAm8X 02xJc8DhwpKU4p.hOhpLqOf04Icz1LPJcKj4VC1EmRx_FMvxov.EV6P39sPJl56zEY7MK9Hhkfpp H3MFF.reXwT1YvVl8F46dK_T.xg3Tbw3dGr29TCR8wLpTiIRIDppRBDSP3qAAPvpSpYEO4SE0XaY du9Tashumtaf9U1BEONQeMhmi2bSm.EsW6SFhXNFAn3MzEqogMGHvb4XF0PzWDVn3X.VeGQeF6Pl ukOs4Z63mMUBeJpz17Gn_LM07AKH.M9cKqC_NF95lrtEQt8NvgAumm5XSrBHOgYcsoGelRTB5bFB lGFXJcxN8jyPAsy4bOEbu8JwJGFCJFRum0zpXh667C1j9QW3GVnEnXNLrfxqsgAsCfCvhFN9GE2f OO34v_CS_vLFeMO.9ICFeevElhI9_tNbrhjgmstLINqGdKfVmwsS.Bv0J3_gwFuHXLNI3tUXWP7X szZJ9eNWxyuHOZx63qZtrrAlOKayhSNC2fhd1KztlHU5gbG5GcruKYecavpCWVsUXdZXGt8kU2OC o9aUJvgu7SvhOB7hBnJDT8eo3XoF5YIx63eJ6CF4GPc2FmFrvDjiS2L3VbJzoHUJ8unDlrh6bOBn Gz7F4xuaMaE0xSMuTCG.rpV.Y153SBJYm5ZrxblPddoepe9JY7JmspO1rTM4QGAZBU3BCA_PfFp0 iFA4NTZ.q4q9KHyMu9a9Ur9pjQtGNnwCKSd96ptKj2 X-Sonic-MF: Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Fri, 7 Jan 2022 11:04:59 +0000 Original-Received: by kubenode514.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID f8409dcd70b19538879fd9ec11e9f757; Fri, 07 Jan 2022 11:04:55 +0000 (UTC) In-Reply-To: <83mtk854rt.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 07 Jan 2022 10:28:06 +0200") X-Mailer: WebService/1.1.19551 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Received-SPF: pass client-ip=66.163.191.147; envelope-from=luangruo@yahoo.com; helo=sonic304-21.consmr.mail.ne1.yahoo.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FILL_THIS_FORM=0.001, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_LOAN=0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 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-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:284411 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> From: Po Lu >> Cc: emacs-devel@gnu.org >> Date: Fri, 07 Jan 2022 15:14:45 +0800 >> >> Thanks, one last question (before I start to implement this): what would >> you recommend as a special value of `:underline'? >> >> Would it be okay to add a new property to the property list that is >> already accepted as such a value? > > Yes, something like > > (:color COLOR :style STYLE :position POS) > > where POS can be t (with the same effect as non-nil value of > x-underline-at-descent-line) or (if you want to get fancy) a number, > to specify an explicit offset from the baseline. Thanks, I implemented that, though I haven't written any documentation yet. It would be nice if someone could test the attached diff on MS-Windows. BTW, there's a `hash' parameter in struct face, but I can't find where it's calculated. I assume I have to the hashing take any new fields into account, but I don't know how. Can you help with this? Thanks. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=test.diff diff --git a/src/dispextern.h b/src/dispextern.h index 954992a0ec..368507732c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1720,6 +1720,12 @@ #define FONT_TOO_HIGH(ft) \ int box_vertical_line_width; int box_horizontal_line_width; + + /* The amount of pixels above the descent line the underline should + be displayed. It does not take effect unless + `underline_at_descent_line_p` is t. */ + int underline_pixels_above_descent_line; + /* Type of box drawn. A value of FACE_NO_BOX means no box is drawn around text in this face. A value of FACE_SIMPLE_BOX means a box of width box_line_width is drawn in color box_color. A value of @@ -1753,6 +1759,9 @@ #define FONT_TOO_HIGH(ft) \ bool_bf strike_through_color_defaulted_p : 1; bool_bf box_color_defaulted_p : 1; + /* True means the underline should be drawn at the descent line. */ + bool_bf underline_at_descent_line_p : 1; + /* TTY appearances. Colors are found in `lface' with empty color string meaning the default color of the TTY. */ bool_bf tty_bold_p : 1; diff --git a/src/haikuterm.c b/src/haikuterm.c index 2239770de9..560ce913ac 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -608,7 +608,12 @@ haiku_draw_text_decoration (struct glyph_string *s, struct face *face, unsigned long thickness, position; int y; - if (s->prev && s->prev && s->prev->hl == DRAW_MOUSE_FACE) + if (s->prev + && s->prev->face->underline == FACE_UNDER_LINE + && (s->prev->face->underline_at_descent_line_p + == s->face->underline_at_descent_line_p) + && (s->prev->face->underline_pixels_above_descent_line + == s->face->underline_pixels_above_descent_line)) { struct face *prev_face = s->prev->face; @@ -639,7 +644,8 @@ haiku_draw_text_decoration (struct glyph_string *s, struct face *face, val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_underline_at_descent_line, s->w)); underline_at_descent_line - = !(NILP (val) || EQ (val, Qunbound)); + = (!(NILP (val) || EQ (val, Qunbound)) + || s->face->underline_at_descent_line_p); val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_use_underline_position_properties, s->w)); @@ -652,7 +658,9 @@ haiku_draw_text_decoration (struct glyph_string *s, struct face *face, else thickness = 1; if (underline_at_descent_line) - position = (s->height - thickness) - (s->ybase - s->y); + position = ((s->height - thickness) + - (s->ybase - s->y) + - s->face->underline_pixels_above_descent_line); else { /* Get the underline position. This is the diff --git a/src/nsterm.m b/src/nsterm.m index a15dc47a22..4f60cc737d 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3265,7 +3265,11 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. /* If the prev was underlined, match its appearance. */ if (s->prev && s->prev->face->underline == FACE_UNDER_LINE - && s->prev->underline_thickness > 0) + && s->prev->underline_thickness > 0 + && (s->prev->face->underline_at_descent_line_p + == s->face->underline_at_descent_line_p) + && (s->prev->face->underline_pixels_above_descent_line + == s->face->underline_pixels_above_descent_line)) { thickness = s->prev->underline_thickness; position = s->prev->underline_position; @@ -3286,7 +3290,8 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_underline_at_descent_line, s->w)); - underline_at_descent_line = !(NILP (val) || EQ (val, Qunbound)); + underline_at_descent_line = (!(NILP (val) || EQ (val, Qunbound)) + || s->face->underline_at_descent_line_p); val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_use_underline_position_properties, s->w)); @@ -3299,7 +3304,8 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. /* Determine the offset of underlining from the baseline. */ if (underline_at_descent_line) - position = descent - thickness; + position = (descent - thickness + - s->face->underline_pixels_above_descent_line); else if (use_underline_position_properties && font && font->underline_position >= 0) position = font->underline_position; @@ -3308,7 +3314,8 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. else position = minimum_offset; - position = max (position, minimum_offset); + if (!s->face->underline_pixels_above_descent_line) + position = max (position, minimum_offset); /* Ensure underlining is not cropped. */ if (descent <= position) diff --git a/src/w32term.c b/src/w32term.c index 700c492cc3..78777f153c 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2564,7 +2564,11 @@ w32_draw_glyph_string (struct glyph_string *s) int y; if (s->prev - && s->prev->face->underline == FACE_UNDER_LINE) + && s->prev->face->underline == FACE_UNDER_LINE + && (s->prev->face->underline_at_descent_line_p + == s->face->underline_at_descent_line_p) + && (s->prev->face->underline_pixels_above_descent_line + == s->face->underline_pixels_above_descent_line)) { /* We use the same underline style as the previous one. */ thickness = s->prev->underline_thickness; @@ -2587,7 +2591,8 @@ w32_draw_glyph_string (struct glyph_string *s) val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_underline_at_descent_line, s->w)); underline_at_descent_line - = !(NILP (val) || EQ (val, Qunbound)); + = (!(NILP (val) || EQ (val, Qunbound)) + || s->face->underline_at_descent_line_p); val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_use_underline_position_properties, s->w)); @@ -2601,7 +2606,9 @@ w32_draw_glyph_string (struct glyph_string *s) thickness = 1; if (underline_at_descent_line || !font) - position = (s->height - thickness) - (s->ybase - s->y); + position = ((s->height - thickness) + - (s->ybase - s->y) + - s->face->underline_pixels_above_descent_line); else { /* Get the underline position. This is the @@ -2619,7 +2626,12 @@ w32_draw_glyph_string (struct glyph_string *s) else position = (font->descent + 1) / 2; } - position = max (position, minimum_offset); + + if (!(s->face->underline_at_descent_line_p + /* Ignore minimum_offset if the amount of pixels + was explictly specified. */ + && s->face->underline_pixels_above_descent_line)) + position = max (position, minimum_offset); } /* Check the sanity of thickness and position. We should avoid drawing underline out of the current line area. */ diff --git a/src/xfaces.c b/src/xfaces.c index 3fd31b7f22..8064d47c94 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6041,6 +6041,8 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] face->underline = FACE_UNDER_LINE; face->underline_defaulted_p = true; face->underline_color = 0; + face->underline_at_descent_line_p = false; + face->underline_pixels_above_descent_line = 0; } else if (STRINGP (underline)) { @@ -6050,12 +6052,16 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] face->underline_color = load_color (f, face, underline, LFACE_UNDERLINE_INDEX); + face->underline_at_descent_line_p = false; + face->underline_pixels_above_descent_line = 0; } else if (NILP (underline)) { face->underline = FACE_NO_UNDERLINE; face->underline_defaulted_p = false; face->underline_color = 0; + face->underline_at_descent_line_p = false; + face->underline_pixels_above_descent_line = 0; } else if (CONSP (underline)) { @@ -6064,6 +6070,8 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] face->underline = FACE_UNDER_LINE; face->underline_color = 0; face->underline_defaulted_p = true; + face->underline_at_descent_line_p = false; + face->underline_pixels_above_descent_line = 0; /* FIXME? This is also not robust about checking the precise form. See comments in Finternal_set_lisp_face_attribute. */ @@ -6100,6 +6108,13 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] else if (EQ (value, Qwave)) face->underline = FACE_UNDER_WAVE; } + else if (EQ (keyword, QCposition)) + { + face->underline_at_descent_line_p = !NILP (value); + + if (FIXNATP (value)) + face->underline_pixels_above_descent_line = XFIXNAT (value); + } } } @@ -6915,6 +6930,7 @@ syms_of_xfaces (void) DEFSYM (QCcolor, ":color"); DEFSYM (QCline_width, ":line-width"); DEFSYM (QCstyle, ":style"); + DEFSYM (QCposition, ":position"); DEFSYM (Qline, "line"); DEFSYM (Qwave, "wave"); DEFSYM (Qreleased_button, "released-button"); diff --git a/src/xterm.c b/src/xterm.c index b284fdd312..717e946538 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -4131,8 +4131,12 @@ x_draw_glyph_string (struct glyph_string *s) unsigned long thickness, position; int y; - if (s->prev && - s->prev->face->underline == FACE_UNDER_LINE) + if (s->prev + && s->prev->face->underline == FACE_UNDER_LINE + && (s->prev->face->underline_at_descent_line_p + == s->face->underline_at_descent_line_p) + && (s->prev->face->underline_pixels_above_descent_line + == s->face->underline_pixels_above_descent_line)) { /* We use the same underline style as the previous one. */ thickness = s->prev->underline_thickness; @@ -4155,7 +4159,8 @@ x_draw_glyph_string (struct glyph_string *s) val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_underline_at_descent_line, s->w)); underline_at_descent_line - = !(NILP (val) || EQ (val, Qunbound)); + = (!(NILP (val) || EQ (val, Qunbound)) + || s->face->underline_at_descent_line_p); val = (WINDOW_BUFFER_LOCAL_VALUE (Qx_use_underline_position_properties, s->w)); @@ -4168,7 +4173,9 @@ x_draw_glyph_string (struct glyph_string *s) else thickness = 1; if (underline_at_descent_line) - position = (s->height - thickness) - (s->ybase - s->y); + position = ((s->height - thickness) + - (s->ybase - s->y) + - s->face->underline_pixels_above_descent_line); else { /* Get the underline position. This is the @@ -4188,12 +4195,16 @@ x_draw_glyph_string (struct glyph_string *s) else position = minimum_offset; } - position = max (position, minimum_offset); + + /* Ignore minimum_offset if the amount of pixels was + explictly specified. */ + if (!s->face->underline_pixels_above_descent_line) + position = max (position, minimum_offset); } /* Check the sanity of thickness and position. We should avoid drawing underline out of the current line area. */ - if (s->y + s->height <= s->ybase + position) - position = (s->height - 1) - (s->ybase - s->y); + if (s->y + s->height <= s->ybase + position) + position = (s->height - 1) - (s->ybase - s->y); if (s->y + s->height < s->ybase + position + thickness) thickness = (s->y + s->height) - (s->ybase + position); s->underline_thickness = thickness; --=-=-=--