emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question about display engine


From: Eli Zaretskii
Subject: Re: Question about display engine
Date: Fri, 06 Sep 2019 16:28:20 +0300

> Date: Fri, 6 Sep 2019 12:30:23 +0200
> From: Ergus <address@hidden>
> Cc: address@hidden, address@hidden
> 
> the face should be extended after EOL means (somehow) that the
> attributes specified in the face are merged with the ones in other
> extensible faces to extend after EOL.

So the face we use after EOL should be the result of merging only
those faces which have their :extend attribute set to non-nil, is that
right?

> >face_id is initialized in init_iterator, which is always called once
> >before the first call to display_line.  Thereafter, any subsequent
> >call to display_line "inherits" the value of face_id left in the
> >iterator object at the end of the previous call to display_line.
> >
> I understood this later actually.
> >
> >
> >Whether this fits the logic of using extend_face_id, I cannot say yet;
> >see the above questions that describe my confusion.
> >
> It actually does... but when the it->face_id changes (for example the
> region ends in the middle of a line) the extend_face_id should know. 

Should it?  The way I see it, we don't need to care about
extend_face_id until we actually come to EOL.

> I am actually rethinking the whole code... but I need to understand
> better some details that are unclear for me. Like how to get the
> "extensible" face_id from a non extensible mixed merged face. Lets say
> 
> e = (a + b + c + d) where only a and c were extensible. Because if I don't
> have a cache/face I will need to recalculate that every time and find a
> way to remember how a face was composed... (remember that e was composed
> by a; b; c; d and then iterate over those ids, get_face_from_id and do a
> loop that if EXTENSIBLE-P will merges in extend_face_id. This will be
> sub efficient.

I don't think you need to remember anything, because Emacs "remembers"
for you.  All of those faces (a, b, c, d) will still be in effect at
EOL (i.e. at the position of the newline character); all you need is
to merge them there while ignoring those of them whose :extend
attribute is not set.

IOW, I thing extend_face_id should only be computed at EOL, either in
extend_face_to_end_of_line or in append_space_for_newline.  Because
you don't need that face ID before you come to EOL.

> The simplest case: suppose that we have (h == b) but h is extensible and
> b is not. they both will have different face_id because the vectors are
> different.
> 
> Merging (a + b + c + d) == (a + h + c + d) -> same face id
> but the extensible faces (a + c) != (a + h + c) -> different face_id
> 
> So I don't know how to face this if I want to do it at the EOL
> only. Because of that I was somehow searching for a method that could
> give me (a + h + c) or (a + c) on the fly every time... but this seems
> to be wrong implemented; so I need MORE help here.

I think the solution should be to have a variant of the code in
handle_face_prop such that it computes the face at EOL.  It would do
that by modifying face_at_buffer_position and face_at_string_position
to accept an additional argument EOL_P, which means merge only faces
which have their :extend attribute set.  Then the face ID computed for
this specially merged face should be used as extend_face_id.

Does this make sense?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]