From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: Question about display engine Date: Mon, 12 Aug 2019 18:29:28 +0300 Message-ID: <831rxqtnaf.fsf@gnu.org> References: <83k1bpasic.fsf@gnu.org> <20190807155738.yviofsumjjhqueci@Ergus> <83imr9ar9f.fsf@gnu.org> <0975890b-37b4-428d-f6e5-5dcf894fb6be@gmx.at> <83ftmdapxm.fsf@gnu.org> <20190808083804.ta3evocyb4hirywj@Ergus> <20190808145015.2qaxwzwf4ws2i3er@Ergus> <83ftm98dgu.fsf@gnu.org> <5361a037-d204-b746-790f-ee2ea09459e6@gmx.at> <83o90vu6ws.fsf@gnu.org> Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="59471"; mail-complaints-to="usenet@blaine.gmane.org" Cc: spacibba@aol.com, emacs-devel@gnu.org To: martin rudalics Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Aug 12 17:30:21 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 1hxCH5-000FM4-7h for ged-emacs-devel@m.gmane.org; Mon, 12 Aug 2019 17:30:19 +0200 Original-Received: from localhost ([::1]:46414 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hxCH3-0000ZK-TZ for ged-emacs-devel@m.gmane.org; Mon, 12 Aug 2019 11:30:17 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43614) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hxCGa-0000Wv-56 for emacs-devel@gnu.org; Mon, 12 Aug 2019 11:29:49 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:52123) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hxCGZ-00045l-2L; Mon, 12 Aug 2019 11:29:47 -0400 Original-Received: from [176.228.60.248] (port=4110 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hxCGV-0001AQ-KX; Mon, 12 Aug 2019 11:29:45 -0400 In-reply-to: (message from martin rudalics on Mon, 12 Aug 2019 10:59:52 +0200) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] 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:239334 Archived-At: > Cc: spacibba@aol.com, emacs-devel@gnu.org > From: martin rudalics > Date: Mon, 12 Aug 2019 10:59:52 +0200 > > >> Answering this question should not be the task of a (face agnostic) > >> display engine. The face merging algorithm would have to decide > >> whether the :extend attribute of the winning face should cause an > >> extension of any attribute specified by that face. > > > > What is the "winning face" in this context? > > IIUC the last one found by face_at_buffer_position that explicitly > specified a value for the attribute in question. That is, the face > whose attribute is actually used by the display engine. Nitpicking: the display engine has no idea whose attributes it is using, see below. > > Not necessarily true: two or more faces could specify the same value > > of a particular attribute, including background and underlining. The > > :extend attribute could be different in some of these faces. > > Suppose the iterator is at a newline character within some highlighted > text within the region and wants to know the :background attribute at > that position. > > With a face-based solution, face_at_buffer_position will have looked > for a :background value provided by the default face, the highlight > face and the region face, in this order. The value of the :extend > attribute provided by the last face found that way is passed (in some > extend_background variable I presume) to the display engine so the > latter can determine whether the background shall be extended to the > window edge or not. If two or more faces of those merged specify :underline, and only one of them has a non-nil :extend, will extending the underline do what the users expect? (And shouldn't we simply disregard entirely a face whose :extend attribute is nil? What can such a face possibly contribute in this case?) > With an attribute-based solution, face_at_buffer_position will have > provided an appropriate value when the last face "found that way" is a > member of the 'extend-background' Lisp variable. > > A similar approach would be used to decide whether the rest of the > line should be underlined, overlined, boxed, appear in inverse-video > or whatever someone considers important (I suppose that none of these > should ever extend). You seem to assume that the iterator examines faces at every buffer position it passes, and in particular on the newline at EOL. But that's not what happens, because examining and merging faces is expensive, so Emacs avoids doing that unless necessary. We only examine faces where they change, and use next-single-property-change to find the next position where we should again examine the faces. In addition, face_at_buffer_position doesn't look for face attributes one by one. Instead, it finds all the source of the 'face' property that are in effect at the given position -- the default face, the face from text properties, and from all the overlays at that position -- and merges these attributes into a single attribute vector. Then it looks up a realized face with identical attributes, or realizes a new face if no such face exists. Thereafter, the iterator just uses that face until the next checkpoint. IOW, face_at_buffer_position returns an ID of a realized (i.e. fully specified) face created by merging several relevant sources of face information, and that realized face has no references to the names of the individual faces from which it was created, nor any memory of which non-unspecified attributes came from which face source. So to implement something like above, we will have to: . force face merging when we get to a newline (btw, what about continuation lines in this context? do we apply the extension logic to them as well?) . modify face_at_buffer_position and its subroutines to behave specially when called on a newline, and decide whether to merge or not merge attributes based on whatever data structures describe the preferences for extending those attributes; this would go at least two levels below face_at_buffer_position . do something similar in face_at_string_position, for display and overlay strings with embedded newlines Sounds like fun project. Volunteers are welcome.