[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: |
Sun, 28 Jan 2018 11:52:48 -0800 |
> Bottom line: to get accurate values of pixel width, you need to
> subtract it->current_x value at some position from current_x at the
> next glyph position. This is the only reliable way to obtain accurate
> pixel width values when using the move_it_* functions.
Thank you, Eli, for the detailed explanation regarding what is happening
underneath the Emacs hood. The "bottom line" method does not seem to be
working in this example to calculate the tab STRETCH because it.current_x of
the character that _follows_ the tab STRETCH is wrong when w->hscroll >= 2. In
the revised bug-30226 function below: When w->hscroll >= 2, we take the
it.current_x of the letter "H" in "Hello-world" (which is ostensibly 84); and,
we subtract (it.first_visible_x + it.lnum_pixel_width). This gives us a
purported tab STRETCH of 42; however, it should really be 35.
A. This is the first (1st) time we call the revised bug-30226 [w->hscroll ==
1]:
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)
"Bottom Line" method -- pixel-width of tab STRETCH: 0
4. TAB STRETCH
it.c (9)
w->hscroll (1)
it.current_x (35)
it.pixel_width (42)
"Bottom Line" method -- pixel-width of tab STRETCH: 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
B. This is the second (2nd) time we call the revised bug-30226 [w->hscroll ==
2]:
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)
"Bottom Line" method -- pixel-width of tab STRETCH: 42
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
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;
int previous_character = 0;
/*
******************************************************************************
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;
/*
******************************************************************************
HYPOTHETICAL CALCULATION OF PIXEL-WIDTH
******************************************************************************
*/
if (w->hscroll > 0
&& previous_character == '\t')
fprintf (stderr, "\n\"Bottom Line\" method -- pixel-width of tab
STRETCH: %d\n",
it.current_x - (it.first_visible_x + it.lnum_pixel_width));
/*
******************************************************************************
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
******************************************************************************
*/
previous_character = it.c;
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;
}