Subject: bug#40897: Negation of pixel-width :width expressions does not work

From: Eli Zaretskii <[email-masked]>
Date: Fri, 01 May 2020 13:05:37 +0300

> From: Pip Cet <[email-masked]>
> Date: Fri, 1 May 2020 09:41:51 +0000
> Cc: [email-masked]
> 
> On Mon, Apr 27, 2020 at 2:32 PM Eli Zaretskii <[email-masked]> wrote:
> > > From: Pip Cet <[email-masked]>
> > > Date: Mon, 27 Apr 2020 08:47:50 +0000
> > You say (3) is difficult to fix, but the patch below does succeed in
> > preventing the stack overflow, so I don't think I understand why you
> > thought this to be difficult.  What am I missing?
> 
> Circular lists can have a cycle of length greater than one. However, a
> simple limitation of how deeply we recurse into the display spec would
> work, and potentially be more robust. Would you agree with that?

Yes, I agree.  But maybe we should do that in addition to the simple
check I suggested, as that is much faster.  Of course, I have no idea
of the relative frequency of each of these use cases, but a single EQ
test seems a small price to pay.

> Thank you for your other explanations. I've taken the opportunity to
> have a look at the redisplay code. I'll confess it's a bit
> overwhelming in its complexity, and my understanding so far is
> tentative

Feel free to ask questions, I'm very much interested in spreading the
knowledge about the display engine internals among as many regular
contributors as possible.

> but it seems to me like it "essentially" goes from buffer text to
> the glyph matrix in one shot: there's no intermediate state that
> represents what CSS would call the "resolved style" of the document.

I'm no CSS expert, but AFAIU we don't have a single equivalent of what
CSS can do.  We do have a large portion of that, though: the faces.
There, we do have the equivalent of the "resolved style", IIUC: the
"realized face", see xfaces.c.  As part of producing the glyphs in the
glyph matrices, the display engine does realize faces that were not
(yet) realized, for example, when it finds a character whose
appearance is affected by several sources of face information (text
properties, overlays, mouse-face, etc.).  But this is done on the fly,
without a separate pass: the pertinent faces are merged in the
appropriate order, then the merged face is realized and cached, and
the iteration through text continues using this cached face ID.  See
the function handle_stop in xdisp.c, which is the focal point for
handling anything "unusual" the display engine bumps into while
walking the text to display.

> Trying to write this email, I'm realizing I need to think about this
> more: I still think the current state of things, where we call Lisp as
> part of redisplay but usually don't rely on it, is much better than to
> exclude Lisp from the process entirely.

We don't exclude Lisp entirely.  You will see quite a few hooks we
call along the way, and also some non-hooks; a notable example of the
latter is fontification-functions.  What I'm saying is that we need to
keep this in check, for those use cases and situations which are
important and cannot be reasonably supported via variables or simple
forms.  We shouldn't add Lisp calls in redisplay "just because we
can."