unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: Calculating screen relative X when horizontal scrolling.
@ 2018-10-20  9:55 Keith David Bershatsky
  0 siblings, 0 replies; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-20  9:55 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

When line numbers are _not_ displayed, it->current_x - it->first_visible_x yields the correct relative_x when calling (scroll-left INTEGER).  Partially displayed characters are supported at the far left of the screen in that scenario.

In the (scroll-left 11) situation (with the first visible text character being a middle dot with a pixel width of 11), the first wide character 'の' is already hidden off to the left of the screen.  However, that hidden wide character 'の' is apparently affecting the ability to obtain the correct it->first-visible_x / it->current_x.  In other words, the situation does not appear to be caused by virtue of the first _visible_ text character to the immediate right of the line numbers.

Is there a test you can think of for these situations such that I can instruct Emacs _when_ to use a _modified_ it->first-visible_x / it->current_x for purposes of calculating the relative_x?

Here are the printouts from my debugging stderr messages....  The line beginning with "POSITION ..." is generated when moving IT on the current line and stopping at each new X.  The line beginning with "Glyph# ..." is generated by a modified version of dump_glyph_row, which lets us see the real it->current_x when the glyph was actually drawn on the screen.


(scroll-left 9)

POSITION     X    Y HPOS VPOS HSCL MIN_H 1ST_X LNUMW  TYPE N   F   W     C D
      19    99  204    0    9    9     0    99    44  CHAR 1  24  18 12398 の

Glyph# Rel.X Type       Pos O   W     Code Face LR     X    Y HPOS VPOS C
     0     0    C        -1 0  11 0x000020   17 00     0   24    0    0  
     1    11    C        -1 0  11 0x000031   17 00    11   24    0    0 1
     2    22    C        -1 0  11 0x000030   17 00    22   24    0    0 0
     3    33    C        -1 0  11 0x000020   17 00    33   24    0    0  
     4    44    C        19 B  18 0x00306e   24 00   143  204    4    9 の


(scroll-left 10)

POSITION     X    Y HPOS VPOS HSCL MIN_H 1ST_X LNUMW  TYPE N   F   W     C D
      19    99  204    0    9   10     0   110    44  CHAR 1  24  18 12398 の

Glyph# Rel.X Type       Pos O   W     Code Face LR     X    Y HPOS VPOS C
     0     0    C        -1 0  11 0x000020   17 00     0   24    0    0  
     1    11    C        -1 0  11 0x000031   17 00    11   24    0    0 1
     2    22    C        -1 0  11 0x000030   17 00    22   24    0    0 0
     3    33    C        -1 0  11 0x000020   17 00    33   24    0    0  
     4    44    C        19 B  18 0x00306e   24 00   143  204    3    9 の


(scroll-left 11)

POSITION     X    Y HPOS VPOS HSCL MIN_H 1ST_X LNUMW  TYPE N   F   W     C D
      20   117  204    0    9   11     0   121    44  CHAR 1  19  11   183 ·

Glyph# Rel.X Type       Pos O   W     Code Face LR     X    Y HPOS VPOS C
     0     0    C        -1 0  11 0x000020   17 00     0   24    0    0  
     1    11    C        -1 0  11 0x000031   17 00    11   24    0    0 1
     2    22    C        -1 0  11 0x000030   17 00    22   24    0    0 0
     3    33    C        -1 0  11 0x000020   17 00    33   24    0    0  
     4    44    C        20 B  11 0x0000b7   19 00   161  204    4    9 ·

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

> Date: [10-20-2018 00:13:26] <20 Oct 2018 10:13:26 +0300>
> From: Eli Zaretskii <eliz@gnu.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> CC: emacs-devel@gnu.org
> Subject: Re: Calculating screen relative X when horizontal scrolling.
> 
> > Date:  Fri, 19 Oct 2018 12:58:56 -0700
> > From:  Keith David Bershatsky <esq@lawlist.com>
> > Cc:  emacs-devel@gnu.org
> >
> > For reference point of this particular analysis:
> >
> > it->lnum_pixel_width == 44
> 
> Are your problems limited to the situation where line numbers are
> displayed?
> 
> > To help me see what is happening, I put in a few new entries just above 'glyph->charpos = ' in all six (6) locations within xdisp.c and assigned a new "gizmo" (for lack of knowing the proper name) like this 'glyph->x = it->current_x;' with the appropriate corresponding entry for glyph->x in dispextern.h.  In the custom dump glyph row (discussed above), I can see that glyph->x for the first 'の' character is actually 143, not 99.
> 
> Since 143 = 99 + 44, and first_visible_x for scroll-left of 9 is 99 in
> your case, I think everything is OK.  You just need to account for
> lnum_pixel_width, which is 44 in this case.
> 
> When you change scroll-left to 10, a wide character such as 'の' will
> not move off the display if line numbers are displayed, because we
> don't know how to draw partial characters in that mode.  This might be
> considered a bug in the current display code.  But I don't think this
> should affect your code.



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: Calculating screen relative X when horizontal scrolling.
@ 2018-10-24 20:40 Keith David Bershatsky
  0 siblings, 0 replies; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-24 20:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

I may have located the source of the bug inside move_it_in_display_line_to, which is where the wrong it->first-visible_x / it->current_x arise.  I would imagine that it->hpos is also wrong.  I have no idea how to fix it, but have nevertheless put in some messages demonstrating the numbers desired.

The problem appears to be isolated to simulating what the screen looks like using move_it_in_display_line_to.  it->current_x is correct when IT gets to the second character after the line numbers, but is wrong for the first character to the immediate right of the line numbers.  As far as I can tell, it->first_visible_x and it->hpos never straighten themselves out in this situation.

Just a recap, since the thread has grown a bit in size and the initial thread is already somewhat old.  I am using a frame-char-width of 11 for standard English letters, and am limiting my testing to (scroll-left 8, 9, 10 and 11), with the following test line of miscellaneous characters of varying widths:

("Google の click-tracking コードをリンクの url から取り除きます") ("Google 検索結果のテーブルを縦方向で揃えて幅を狭めます") ("すべてのページに w3m が扱える name アンカーを追加します") ("http://*.hp.infoseek.co.jp/* で広告を取り除きます") ("http://linux.ascii24.com/linux/* で広告を取り除きます") ("ミクシィ用フィルタ") ("朝日新聞用フィルタ") ("すべてのページでインラインフレームを取り除きます")

/* *************************************************************************** */
/* MULTIPLE CURSORS */

  if (new_x > it->first_visible_x)
    {
      /* If we have reached the visible portion of the
         screen line, produce the line number if needed.  */
      if (line_number_pending)
        {

          int saved_x = it->current_x;

          Lisp_Object character = Fchar_to_string (make_number (it->c));
          line_number_pending = false;
          it->current_x = it->first_visible_x;
          maybe_produce_line_number (it);

          if (saved_x + it->lnum_pixel_width ==
                it->current_x + new_x - it->first_visible_x)
            fprintf (stderr, "\nfirst_x (%d) | current_x (%d) of (%s)\n",
                             saved_x - it->pixel_width,
                             saved_x - it->pixel_width + it->lnum_pixel_width,
                             ((!NILP (character)
                               && it->c == 9)
                                 ? "\\t"
                               : (!NILP (character)
                                  && it->c == 10)
                                 ? "\\n"
                               : (!NILP (character)
                                  && it->c != 9
                                  && it->c != 10)
                                 ? SSDATA (character)
                               : "?"));

          it->current_x += new_x - it->first_visible_x;
        }
      /* Glyph is visible.  Increment number of glyphs that
         would be displayed.  */
      ++it->hpos;
    }

/* *************************************************************************** */



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: Calculating screen relative X when horizontal scrolling.
@ 2018-10-19 20:02 Keith David Bershatsky
  0 siblings, 0 replies; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-19 20:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Amendment to prior email ...

Instead of:  "The first character 'の' which was at a relative_x of 55 in a (scroll-left 9) situation, is still at a relative_x of 55 in a (scroll-left 10) situation".

I should have said:  "The first character 'の' which was at a relative_x of 44 in a (scroll-left 9) situation, is still at a relative_x of 44 in a (scroll-left 10) situation".

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

> Date: [10-19-2018 12:23:34] <19 Oct 2018 22:23:34 +0300>
> From: Eli Zaretskii <eliz@gnu.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> CC: emacs-devel@gnu.org
> Subject: Re: Calculating screen relative X when horizontal scrolling.
> 
> > Date:  Wed, 17 Oct 2018 13:43:49 -0700
> > From:  Keith David Bershatsky <esq@lawlist.com>
> > Cc:  emacs-devel@gnu.org
> >
> > relative_x = it->current_x - ((window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f))
> 
> Can you tell why you don't use the simple approach:
> 
>   relative_x = it->current_x - it->first_visible_x;
> 
> ?



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: Calculating screen relative X when horizontal scrolling.
@ 2018-10-19 19:58 Keith David Bershatsky
  2018-10-20  7:13 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-19 19:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Thank you, Eli, for continuing to try and help with this particular issue -- greatly appreciated!

For reference point of this particular analysis:

it->lnum_pixel_width == 44

Evaluating (scroll-left 10) gives a temporary:  it->w->hscroll == 10

The first character 'の' which was at a relative_x of 55 in a (scroll-left 9) situation, is still at a relative_x of 55 in a (scroll-left 10) situation.  That character doesn't move move off the screen yet -- probably because it has a pixel width of 18; whereas, the frame_char_width is 11 for regular English characters.

it->current_x == 99 for the first character 'の'.

it->first_visible-x == 110.  Which is at odds with the previous statement.

My guess is that the first character 'の' is really at an it->current_x of 143; and, the it->first_visible_x would have to be 99.

I created my own custom dump glyph row which calculates the relative_x just like pgrowx in .gdbinit; i.e., add up all of the previous glyph->pixel_width up to the current location go get the relative_x at issue.

To help me see what is happening, I put in a few new entries just above 'glyph->charpos = ' in all six (6) locations within xdisp.c and assigned a new "gizmo" (for lack of knowing the proper name) like this 'glyph->x = it->current_x;' with the appropriate corresponding entry for glyph->x in dispextern.h.  In the custom dump glyph row (discussed above), I can see that glyph->x for the first 'の' character is actually 143, not 99.

[I can certainly remove the above modifications to xdisp.c, but I don't think they hurt and they seem to be helpful to debug this particular issue.]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

> Date: [10-19-2018 12:23:34] <19 Oct 2018 22:23:34 +0300>
> From: Eli Zaretskii <eliz@gnu.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> CC: emacs-devel@gnu.org
> Subject: Re: Calculating screen relative X when horizontal scrolling.
> 
> > Date:  Wed, 17 Oct 2018 13:43:49 -0700
> > From:  Keith David Bershatsky <esq@lawlist.com>
> > Cc:  emacs-devel@gnu.org
> >
> > relative_x = it->current_x - ((window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f))
> 
> Can you tell why you don't use the simple approach:
> 
>   relative_x = it->current_x - it->first_visible_x;



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: Calculating screen relative X when horizontal scrolling.
@ 2018-10-17 20:43 Keith David Bershatsky
  2018-10-19 19:23 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-17 20:43 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

In addition to the explanation in the previous post about temporarily hijacking w->phys_cursor.x and setting it with my own relative x before calling draw_window_cursor, the following screenshots may help to explain (by way of visual example) the relative x that I am seeking when horizontal scrolling:

(scroll-left 9):  https://lawlist.com/images/scroll_left_09.png

(scroll-left 10):  https://lawlist.com/images/scroll_left_10.png

(scroll-left 11):  https://lawlist.com/images/scroll_left_11.png

In the (scroll-left 9) screenshot, the following code renders the _correct_ relative x for the entire current line.

relative_x = it->current_x - ((window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f))

However, that same code does not work when I evaluate (scroll-left 10) or (scroll-left 11).  The problem appears to have something to do with the varying pixel widths of the different characters.

The same problem arises when temporarily or semi-permanently scrolling _only_ the current line; i.e., when either of the following tests are _true_:

/* EXAMPLE:  (scroll-left 5); and, then press the left arrow key one time.*/
bool hscl_temp_p = (!it->w->suspend_auto_hscroll
                    && auto_hscroll_mode_p
                    && it->w->hscroll > 0
                    && it->w->min_hscroll == 0);

/* EXAMPLE:  C-u C-x < and do something that causes the current line to be
             horizontally scrolled differently. */
bool hscl_perm_p = (!it->w->suspend_auto_hscroll
                    && auto_hscroll_mode_p
                    && it->w->hscroll > 0
                    && it->w->min_hscroll > 0
                    && it->w->min_hscroll != it->w->hscroll);



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: Calculating screen relative X when horizontal scrolling.
@ 2018-10-17 17:54 Keith David Bershatsky
  0 siblings, 0 replies; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-17 17:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

I apologize for having misspoken about using the 3rd argument of draw_window_cursor to control the relative x coordinate of the fake cursor.  I had forgotten that I actually temporarily hijack w->phys_cursor.x and assign my own relative x just prior to calling draw_window_cursor.  Here is a snippet from the relevant section of feature requests 17684 (crosshairs) and 22873 (multiple fake cursors):

  /* Record some of the current values for the cursor and glyph_row. */
  bool phys_cursor_on_p = w->phys_cursor_on_p;
  struct glyph_row *glyph_row = MATRIX_ROW (w->current_matrix, vpos);
  bool cursor_in_fringe_p = glyph_row->cursor_in_fringe_p;
  bool reversed_p = glyph_row->reversed_p;
  ptrdiff_t phys_cursor_x = w->phys_cursor.x;
  ptrdiff_t phys_cursor_y = w->phys_cursor.y;
  ptrdiff_t phys_cursor_hpos = w->phys_cursor.hpos;
  ptrdiff_t phys_cursor_vpos = w->phys_cursor.vpos;
  ptrdiff_t phys_cursor_ascent = w->phys_cursor_ascent;
  ptrdiff_t phys_cursor_height = w->phys_cursor_height;
  ptrdiff_t phys_cursor_width = w->phys_cursor_width;
  enum text_cursor_kinds phys_cursor_type = w->phys_cursor_type;
  /* Hijack w->phys_cursor. */
  w->phys_cursor.x = x;
  w->phys_cursor.y = glyph_row->y;
  w->phys_cursor.hpos = hpos;
  w->phys_cursor.vpos = vpos;
  w->phys_cursor_type = cursor_type;
  w->phys_cursor_ascent = glyph_row->ascent;
  w->phys_cursor_height = glyph_row->height;
  w->phys_cursor_width = cursor_width;

  FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, true, active_cursor_p);

  /* Restore the previous values for w->phys_cursor and glyph_row. */
  w->phys_cursor_on_p = phys_cursor_on_p;
  w->phys_cursor.x = phys_cursor_x;
  w->phys_cursor.y = phys_cursor_y;
  w->phys_cursor.hpos = phys_cursor_hpos;
  w->phys_cursor.vpos = phys_cursor_vpos;
  w->phys_cursor_type = phys_cursor_type;
  glyph_row->cursor_in_fringe_p = cursor_in_fringe_p;
  glyph_row->reversed_p = reversed_p;
  w->phys_cursor_ascent = phys_cursor_ascent;
  w->phys_cursor_height = phys_cursor_height;
  w->phys_cursor_width = phys_cursor_width;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

> Date: [10-17-2018 09:25:41] <17 Oct 2018 19:25:41 +0300>
> From: Eli Zaretskii <eliz@gnu.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> CC: emacs-devel@gnu.org
> Subject: Re: Calculating screen relative X when horizontal scrolling.
> 
> > Date:  Tue, 16 Oct 2018 08:41:00 -0700
> > From:  Keith David Bershatsky <esq@lawlist.com>
> > Cc:  emacs-devel@gnu.org
> >
> > The x coordinate sought will be used as the 3rd argument to draw_window_cursor in conjunction with feature requests 17684 (crosshairs) and 22873 (multiple fake cursors).
> >
> > The method of calculation used in the initial post is off by a few pixels when dealing with each of the fact patterns described.  Here is a sample _current_ line (miscellaneous characters of varying pixel widths) where my calculations go awry:
> 
> I'm sorry, I still don't have a clear understanding of the issue.  In
> particular, the implementations of draw_window_cursor method don't use
> the 3rd argument for positioning the cursor.  So I still don't
> understand what you mean by "relative x".



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Re: Calculating screen relative X when horizontal scrolling.
@ 2018-10-16 15:41 Keith David Bershatsky
  2018-10-17 16:25 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-16 15:41 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Thank you, Eli, for looking at this particular thread.

The x coordinate sought will be used as the 3rd argument to draw_window_cursor in conjunction with feature requests 17684 (crosshairs) and 22873 (multiple fake cursors).

The method of calculation used in the initial post is off by a few pixels when dealing with each of the fact patterns described.  Here is a sample _current_ line (miscellaneous characters of varying pixel widths) where my calculations go awry:

("Google の click-tracking コードをリンクの url から取り除きます") ("Google 検索結果のテーブルを縦方向で揃えて幅を狭めます") ("すべてのページに w3m が扱える name アンカーを追加します") ("http://*.hp.infoseek.co.jp/* で広告を取り除きます") ("http://linux.ascii24.com/linux/* で広告を取り除きます") ("ミクシィ用フィルタ") ("朝日新聞用フィルタ") ("すべてのページでインラインフレームを取り除きます")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

> Date: [10-16-2018 07:48:35] <16 Oct 2018 17:48:35 +0300>
> From: Eli Zaretskii <eliz@gnu.org>
> To: Keith David Bershatsky <esq@lawlist.com>
> CC: emacs-devel@gnu.org
> Subject: Re: Calculating screen relative X when horizontal scrolling.
> 
> > Date: Mon, 15 Oct 2018 15:25:06 -0700
> > From: Keith David Bershatsky <esq@lawlist.com>
> >
> > I am having difficulty calculating the screen relative x in the following two (2) fact patterns.  How can I calculate the relative x for each fact pattern?
> 
> Please explain what do you mean by "relative x".  Relative to what?
> 
> Also, are you talking about the x coordinate of glyphs or about x
> coordinate of mouse events and such likes?



^ permalink raw reply	[flat|nested] 12+ messages in thread
* Calculating screen relative X when horizontal scrolling.
@ 2018-10-15 22:25 Keith David Bershatsky
  2018-10-16 14:48 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Keith David Bershatsky @ 2018-10-15 22:25 UTC (permalink / raw)
  To: Emacs Devel

I am having difficulty calculating the screen relative x in the following two (2) fact patterns.  How can I calculate the relative x for each fact pattern?


FACT PATTERN # 1:

1.  Current line is horizontally scrolled differently than all other lines in the window.

2.  Current line is truncated on the _left_

3.  display-line-numbers is non-nil.

4.  Current line has characters of varying pixel widths.

5.  hscl_temp_p == true


FACT PATTERN # 2:

1.  Current line is horizontally scrolled differently than all other lines in the window.

2.  Current line is truncated on the _left_

3.  display-line-numbers is non-nil.

4.  Current line has characters of varying pixel widths.

5.  hscl_perm_p == true


int frame_char_width = FRAME_COLUMN_WIDTH (it->f);

bool auto_hscroll_mode_p = EQ (Fbuffer_local_value (Qauto_hscroll_mode, it->w->contents), Qcurrent_line);

it hscl_first_hpos = window_hscroll_limited (it->w, it->f);

/* EXAMPLE:  (scroll-left 5); and, then press the left arrow key one time.*/
bool hscl_temp_p = (!it->w->suspend_auto_hscroll
                    && auto_hscroll_mode_p
                    && it->w->hscroll > 0
                    && it->w->min_hscroll == 0);

/* EXAMPLE:  C-u C-x < and do something that causes the current line to be
             horizontally scrolled differently. */
bool hscl_perm_p = (!it->w->suspend_auto_hscroll
                    && auto_hscroll_mode_p
                    && it->w->hscroll > 0
                    && it->w->min_hscroll > 0
                    && it->w->min_hscroll != it->w->hscroll);

int relative_x;

if (it->current_x > 0
    && hscl_perm_p)
  relative_x = it->current_x - (hscl_first_hpos * frame_char_width);
  else if (it->current_x > 0
           && hscl_temp_p)
    relative_x = it->current_x - (hscl_first_hpos * frame_char_width);



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2018-10-24 20:40 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-20  9:55 Calculating screen relative X when horizontal scrolling Keith David Bershatsky
  -- strict thread matches above, loose matches on Subject: below --
2018-10-24 20:40 Keith David Bershatsky
2018-10-19 20:02 Keith David Bershatsky
2018-10-19 19:58 Keith David Bershatsky
2018-10-20  7:13 ` Eli Zaretskii
2018-10-17 20:43 Keith David Bershatsky
2018-10-19 19:23 ` Eli Zaretskii
2018-10-17 17:54 Keith David Bershatsky
2018-10-16 15:41 Keith David Bershatsky
2018-10-17 16:25 ` Eli Zaretskii
2018-10-15 22:25 Keith David Bershatsky
2018-10-16 14:48 ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).