emacs-devel
[Top][All Lists]
Advanced

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

Re: Question about display engine


From: martin rudalics
Subject: Re: Question about display engine
Date: Sat, 31 Aug 2019 09:29:13 +0200

> I thought we already agreed that there's no other way of having this
> feature than to realize a face at each EOL.

Then that's where we have been miscommunicating.  The whole idea
behind the extend_background, extend_underline, ... bits was to avoid
the full handle_stop rigmarole at EOL, like finding the overlays and
text properties and processing them in the right order.  All this was
already done at the last "real" stop position encountered by the
display engine and has not changed since then.

The only missing step is to process the :extend attribute of any face
merged.  For the normal background, this is the value of the
:background attribute of the last face that specified that attribute
and was merged in.  For the extended background this is the value of
the :background attribute of the last face that specified that
attribute, had the :extend attribute set and was merged in.

To put this into praxis, the face merger would maintain a shadow copy
of the background value.  That shadow value would not get overwritten
when merging in the :background attribute of a face that does not have
the :extend attribute set.  Eventually, we would wind up with two,
possibly distinct values of the background to realize - one for the
normal and the shadow value for the extended background.

If we wanted to realize both faces - the one to use for the current
face and the one to use for extension - immediately (eagerly as I
coined it earlier), we could do that right after merging terminates.
We probably would set up a pointer to the realized face to use for
extension, so the iterator, when arriving at EOL, would find it right
away and make it current.  That's all.

But we probably don't want to realize the face to use for extension
immediately and do it - as we agreed earlier - lazily when the
iterator arrives at EOL.  In my region/comment example, the comment
could have terminated before or at the EOL where it started, resulting
in a new stop position and we would have needlessly realized an
extended face.  Initially, that's where I wanted the extend_background
etc. bits to kick in, just that I wrongly thought that filling the end
of the line with the background of the default face would be
sufficient ...

Note: We could also try to find out whether there _is_ another stop
position before the next EOL after merging faces and, if there's none,
realize the extended face eagerly, but I'm not sure whether this idea
can be incorporated easily.

>> But they would still have to fully realize the face to use by merging
>> all faces at each newline.  This means we can do away with all those
>> precalculated extend_background, extend_... bits because they cease to
>> contribute anything to the solution.
>
> I don't think I understand what the "precalculated" part refers to.

Is it clear from what I wrote above?  The extend_background, ... bits
would remember the precalculated differences between the attributes
used for normal text and those for the extensions.

>> The only practical solution I see is to, instead of extend_background
>> bits, use extend_background colors.  In my example, this would mean
>> that when, at the stop position prescribed by the comment start text
>> property change, the face merger sets the background value of the face
>> to realize to that of the region and the extend_background value of
>> the face to realize to that of the comment.  The display engine would
>> then realize the face for writing the remainder of the line right from
>> extend_background instead of from background + extend_background.
>
> I don't see how this will help anything.  To remind you: the display
> engine manipulates face IDs, it doesn't know anything about the faces
> themselves, and in particular cannot magically exchange a face's
> background color for some other color.

But it knows where the background of a realized face is stored and
could easily realize a new face which is the same but for a different
background swapped in.  Hardly rocket science for the display engine.

So what we could do is to simply maintain a vector of the values for
background, underline, etc. calculated at the last real stop position
and whenever the display engine encounters a newline, realize a face
with the values of that vector replacing the current values, use that
face for the spaces at the rest of the line, and restore the old face
for the normal text on the next line (unless we have several newlines
in a row and similar optimizations).

> I don't think I see the tunnel.  I thought the issue was resolved when
> you posted your summary up-thread.  What am I missing?

When you saw my proposal to use a number of extend_background,
extend_underline, ... bits, your crystal ball should have complained
that multiple bits are useless because we would have to realize a new
face anyway at EOL.  A single flag (if at all) could have been set by
the face merger to detect the case where an attribute without the
:extend attribute set overwrote an attribute with the :extend
attribute set.  In my region/comment example this would have happened
where the no-extend :background of the region face overwrote the
extend :background of the comment face.  The display engine, whenever
it encountered the flag set at EOL, would have triggered a new face
merge (and avoided it otherwise).

That single flag approach wouldn't penalize the display engine if
attributes were extended by default.  In that case, the re-merging step
at EOL would be needed only in cases as used in my region/comment
example.  But if, as Ergus requested earlier, we did _not_ want to
extend attributes by default, the re-merge penalty would practically
happen at each EOL.

BTW: One problem with Ergus' proposal is that hacks like the one
proposed for Bug#15934 won't work any more.  For that bug, we could
obviously set the :extend attribute of the respective highlight line
face but all instances in the wild using the same hack already would
be affected by our change.

martin



reply via email to

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