[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#30226: Fixing it->pixel_width / it->current_x when tabs and line num
From: |
Keith David Bershatsky |
Subject: |
bug#30226: Fixing it->pixel_width / it->current_x when tabs and line numbers. |
Date: |
Sat, 27 Jan 2018 13:20:55 -0800 |
Thank you, Eli, for looking into #30226.
> Your problem description talks about it->pixel_width, not about
> glyph->pixel_width, but the latter should be equal to the former . . .,
>
* * *
>
> I don't understand why you are saying that it->current_x is wrong.
> What is that assertion based on? Maybe there's some misunderstanding
> of what current_x is and relative to what position does it measure the
> X coordinate. Can you tell what you expected current_x to be in some
> specific situation (i.e., specific horizontal scroll of the display
> in the above scenario), and what you really found?
dump-glyph-row is _correct_, assuming that a redisplay has occurred prior to
calling that function.
Feature request 17684 (i.e., crosshairs) uses move_it_in_display_line_to -- by
increments of it.pixel_width -- to dump various values for each character in
the current line. I reproduce issue #30226 by placing IT at the beginning of
the current line (i.e., it.current_x == 0) and iterating over each character in
that line:
move_it_in_display_line_to (&it, ZV, it.current_x + it.pixel_width,
MOVE_TO_POS | MOVE_TO_X);
Your outline of the steps needed to reproduce this issue requires a few
additional steps:
Step 0.5) Build a new Emacs 26 with the reduced/simplified function named
bug-30226 (written below); and, add `defsubr (&Sbug_30226);` to syms_of_xdisp.
Step 1) No changes.
Step 2) No changes.
Step 3) No changes.
Step 4) Instead of typing "M-: (scroll-left 1) RET", type "M-: (bug-30226)
RET". w->hscroll should now equal 1. In step 4, there is a _hiccup_ with the
initial value of it->pixel_width being wrong as to the tab STRETCH, and the
subsequent value of it->pixel_width is correct as to the tab STRETCH.
1. NOTHING
it.c (0)
w->hscroll (1)
it.current_x (0)
it.pixel_width (0)
2. TAB CHARACTER
it.c (187)
w->hscroll (1)
it.current_x (0)
it.pixel_width (7)
3. TAB STRETCH
it.c (9)
w->hscroll (1)
it.current_x (7)
it.pixel_width (49)
4. TAB STRETCH
it.c (9)
w->hscroll (1)
it.current_x (35)
it.pixel_width (42)
5. TEXT
it.c (72)
w->hscroll (1)
it.current_x (77)
it.pixel_width (7)
* * *
Row Start End Used oE><\CTZFesm X Y W H V A P
==============================================================================
12 455 467 17 111000110000 0 192 154 16 16 12 12
-1 -1 0
-1 -1
-1 -1
Glyph# Type Pos O W Code C Face LR
0 C -1 0 7 0x000020 29 00
1 C -1 0 7 0x000031 1 29 00
2 C -1 0 7 0x000033 3 29 00
3 C -1 0 7 0x000020 29 00
4 S 455 B 42 0x000000 31 00
5 C 456 B 7 0x000048 H 0 00
6 C 457 B 7 0x000065 e 0 00
7 C 458 B 7 0x00006c l 0 00
8 C 459 B 7 0x00006c l 0 00
9 C 460 B 7 0x00006f o 0 00
10 C 461 B 7 0x00002d - 0 00
11 C 462 B 7 0x000077 w 0 00
12 C 463 B 7 0x00006f o 0 00
13 C 464 B 7 0x000072 r 0 00
14 C 465 B 7 0x00006c l 0 00
15 C 466 B 7 0x000064 d 0 00
16 C 0 0 7 0x000020 0 00
Step 5) Type "M-: (bug-30226) RET". w->hscroll should now equal 2. In step 5,
the value for it->pixel_width is wrong as to the tab STRETCH and it->current_x
is wrong as to the characters that follow the tab STRETCH -- probably because
it->pixel_width of the tab STRETCH was wrong.
1. NOTHING
it.c (0)
w->hscroll (2)
it.current_x (0)
it.pixel_width (0)
2. TAB CHARACTER
it.c (187)
w->hscroll (2)
it.current_x (0)
it.pixel_width (7)
3. TAB STRETCH
it.c (9)
w->hscroll (2)
it.current_x (7)
it.pixel_width (49)
4. TEXT
it.c (72)
w->hscroll (2)
it.current_x (84)
it.pixel_width (7)
* * *
Row Start End Used oE><\CTZFesm X Y W H V A P
==============================================================================
12 455 467 17 111000110000 0 192 147 16 16 12 12
-1 -1 0
-1 -1
-1 -1
Glyph# Type Pos O W Code C Face LR
0 C -1 0 7 0x000020 29 00
1 C -1 0 7 0x000031 1 29 00
2 C -1 0 7 0x000033 3 29 00
3 C -1 0 7 0x000020 29 00
4 S 455 B 35 0x000000 31 00
5 C 456 B 7 0x000048 H 0 00
6 C 457 B 7 0x000065 e 0 00
7 C 458 B 7 0x00006c l 0 00
8 C 459 B 7 0x00006c l 0 00
9 C 460 B 7 0x00006f o 0 00
10 C 461 B 7 0x00002d - 0 00
11 C 462 B 7 0x000077 w 0 00
12 C 463 B 7 0x00006f o 0 00
13 C 464 B 7 0x000072 r 0 00
14 C 465 B 7 0x00006c l 0 00
15 C 466 B 7 0x000064 d 0 00
16 C 0 0 7 0x000020 0 00
I have further reduced/simplified our test function (below) that uses
move_it_in_display_line_to to iterate over each character in the current line,
and print the relevant values to STDERR as the iteration is occurring. At the
very end of the test function, dump_glyph_row is called (following a forced
redisplay) to help us compare its values to the previous values returned
subsequent to each call of move_it_in_display_line_to.
DEFUN ("bug-30226", Fbug_30226, Sbug_30226, 0, 0, 0,
doc: /* Debug the pixel-width of a stretch tab. */)
(void)
{
Fscroll_left (make_number (1), Qnil);
struct window *w = decode_live_window (selected_window);
struct frame *f = XFRAME (w->frame);
struct it it;
void *itdata = bidi_shelve_cache ();
enum move_it_result rc = MOVE_X_REACHED;
struct text_pos start_text_position;
int count = 1;
/*
******************************************************************************
START DISPLAY -- w->start
******************************************************************************
*/
/* Begin the journey at w->start. */
SET_TEXT_POS_FROM_MARKER (start_text_position, w->start);
start_display (&it, w, start_text_position);
struct face *face = FACE_FROM_ID (it.f, it.face_id);
struct font *font = face->font;
/*
******************************************************************************
GO TO THE BEGINNING OF THE CURRENT LINE.
******************************************************************************
*/
/* Place the IT on the current line containing PT. */
int voffset = (WINDOW_HEADER_LINE_HEIGHT (w) > 0
&& w->output_cursor.vpos > 0)
? w->output_cursor.vpos - 1
: w->output_cursor.vpos;
if (voffset > 0)
move_it_by_lines (&it, voffset);
/*
******************************************************************************
MOVE IT OVER EACH CHARACTER ON THE CURRENT LINE.
******************************************************************************
*/
while (true)
{
if (ITERATOR_AT_END_OF_LINE_P (&it)
|| FETCH_BYTE (IT_BYTEPOS (it)) == '\n'
|| rc == MOVE_POS_MATCH_OR_ZV)
break;
/*
******************************************************************************
DUMP RELEVANT GLYPH INFORMATION
******************************************************************************
*/
if (w->hscroll > 0)
{
int w_hscroll = w->hscroll;
fprintf (stderr, "\n%d. %s\n\
it.c (%d)\n\
w->hscroll (%d)\n\
it.current_x (%d)\n\
it.pixel_width (%d)\n",
count,
(it.c == 0
? "NOTHING"
: it.c == 187
? "TAB CHARACTER"
: it.c == '\t'
? "TAB STRETCH"
: "TEXT"),
it.c,
w_hscroll,
it.current_x,
it.pixel_width);
}
/*
******************************************************************************
MOVE IT -- INCREMENT == IT.PIXEL_WIDTH
******************************************************************************
*/
rc = move_it_in_display_line_to (&it, ZV, it.current_x + it.pixel_width,
MOVE_TO_POS | MOVE_TO_X);
count = count + 1;
if (rc == MOVE_LINE_CONTINUED)
break;
if (it.current_x - it.first_visible_x + font->space_width >=
window_box_width (w, TEXT_AREA))
break;
}
/*
******************************************************************************
REDISPLAY AND DUMP_GLPYH_ROW
******************************************************************************
*/
redisplay_internal ();
fprintf (stderr, "\n");
struct glyph_row *glyph_row = MATRIX_ROW (w->current_matrix, it.vpos);
dump_glyph_row (glyph_row, it.vpos, 2);
bidi_unshelve_cache (itdata, false);
return Qnil;
}