[Top][All Lists]

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

bug#44284: 27.1; with some Unicode font, scrolling upward with the mouse

From: Eli Zaretskii
Subject: bug#44284: 27.1; with some Unicode font, scrolling upward with the mouse wheel actually scrolls downward when the cursor needs repositioning
Date: Sun, 01 Nov 2020 18:15:04 +0200

> Date: Sun, 1 Nov 2020 01:24:30 +0100
> From: Vincent Lefevre <vincent@vinc17.net>
> Cc: 44284@debbugs.gnu.org
> The issue is in xdisp.c, function compute_line_metrics.
> With size 14, one gets row->height = 14 and everything is fine.
> With size 13, one gets row->height = 13 initially, but one enters
> the following condition:
>       /* If first line's physical ascent is larger than its logical
>          ascent, use the physical ascent, and make the row taller.
>          This makes accented characters fully visible.  */
>       if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
>         && row->phys_ascent > row->ascent)
>       {
>         row->height += row->phys_ascent - row->ascent;
>         row->ascent = row->phys_ascent;
>       }
> where row->height is increased to 14, hence the issue with the first
> line. One successively gets
>   it->current_y = 0
>   it->current_y = 14
>   it->current_y = 27
> adding 13 each time for the following lines.

Thanks, this makes sense.  But the reason for this is still TBD.

> With size 14:
> row->phys_ascent = 12
> row->ascent = 12
> With size 13:
> row->phys_ascent = 12
> row->ascent = 11
> I don't know where phys_ascent comes from, but it does not seem to be
> in the font description.

It does come from the font data, or at least it should.  See below.

> Anyway, this case is not handled correctly by Emacs.

I think the jury is still out on this issue.

> Note also that when building without cairo (--without-cairo), I get
> with size 13:
> row->phys_ascent = 11
> row->ascent = 11

Interesting.  Once you understand where did the value 12 come from,
perhaps you could see how things are different in a non-Cairo build.

Let me describe how row->phys_ascent is computed, so that you could
take a closer look.

In general, both the row->ascent and row->phys_ascent values are
computed from the metrics of the character glyphs of the screen line.
The difference between them is that the former is affected by various
features such as the line-spacing and text properties that modify the
height of the text, whereas the latter keeps the value gleaned from
the character metrics.

The row->ascent and row->phys_ascent are assigned by display_line,
using the maximum values of ascent and phys_ascent of all the glyphs
laid out on the screen line.  These latter values are tracked by
it->max_ascent and it->max_phys_ascent.  For each character
display_line examines, it calls gui_produce_glyphs (via the macro
PRODUCE_GLYPHS), and there we have this fragment:

          if (get_char_glyph_code (it->char_to_display, font, &char2b))
              pcm = get_per_char_metric (font, &char2b);
              if (pcm->width == 0
                  && pcm->rbearing == 0 && pcm->lbearing == 0)
                pcm = NULL;

          if (pcm)
              it->phys_ascent = pcm->ascent + boff;
              it->phys_descent = pcm->descent - boff;
              it->pixel_width = pcm->width;

This is where these values start: from the per-character metrics we
get from the font.  Near the end of gui_produce_glyphs, we have this:

  it->max_ascent = max (it->max_ascent, it->ascent);
  it->max_descent = max (it->max_descent, it->descent);
  it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
  it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);

This accumulates the maximum values of all the glyphs.  Back in
display_line we have, a little ways after the call to PRODUCE_GLYPHS:

          row->ascent = max (row->ascent, it->max_ascent);
          row->height = max (row->height, it->max_ascent + it->max_descent);
          row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
          row->phys_height = max (row->phys_height,
                                  it->max_phys_ascent + it->max_phys_descent);

(This is the mainline of the algorithm; you will see that there are
few special cases where we don't take the values from the font glyphs,
but from other sources.  Perhaps this could explain the strange
situation you see with this particular font.)

So now the question becomes: which of the characters on the window's
first screen line, or some other condition there, causes the
row->phys_ascent value become larger than row->ascent?  And why does
this not happen in a non-Cairo build?


reply via email to

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