Mercurial > emacs
comparison src/xdisp.c @ 25188:6849f435f6e8
(compute_line_metrics): If first line's physical ascent
is larger than its logical ascent, use the physical ascent, and
make the row taller. Set row's overlapping_p flag.
(init_iterator): Reset physical line height info
after producing special glyphs.
(display_toolbar_line): Set physical line height info.
(compute_line_metrics): Ditto.
(display_line): Ditto.
(display_string): Ditto.
(reseat_at_next_visible_line_start): New parameter
on_newline_p.
(set_iterator_to_next): After delivering last char
from display vector, reseat on next visible line start if
dpvec_char_len < 0.
(next_element_from_buffer): Set dpvec_char_len to -1 for
selective display.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Fri, 06 Aug 1999 13:59:43 +0000 |
parents | 188fc8b67ea9 |
children | fbe149852f1c |
comparison
equal
deleted
inserted
replaced
25187:39feb68ed3c7 | 25188:6849f435f6e8 |
---|---|
641 void set_iterator_to_next P_ ((struct it *)); | 641 void set_iterator_to_next P_ ((struct it *)); |
642 static void reseat P_ ((struct it *, struct text_pos, int)); | 642 static void reseat P_ ((struct it *, struct text_pos, int)); |
643 static void reseat_1 P_ ((struct it *, struct text_pos, int)); | 643 static void reseat_1 P_ ((struct it *, struct text_pos, int)); |
644 static void back_to_previous_visible_line_start P_ ((struct it *)); | 644 static void back_to_previous_visible_line_start P_ ((struct it *)); |
645 static void reseat_at_previous_visible_line_start P_ ((struct it *)); | 645 static void reseat_at_previous_visible_line_start P_ ((struct it *)); |
646 static void reseat_at_next_visible_line_start P_ ((struct it *, int)); | |
646 static int next_element_from_display_vector P_ ((struct it *)); | 647 static int next_element_from_display_vector P_ ((struct it *)); |
647 static int next_element_from_string P_ ((struct it *)); | 648 static int next_element_from_string P_ ((struct it *)); |
648 static int next_element_from_c_string P_ ((struct it *)); | 649 static int next_element_from_c_string P_ ((struct it *)); |
649 static int next_element_from_buffer P_ ((struct it *)); | 650 static int next_element_from_buffer P_ ((struct it *)); |
650 static int next_element_from_image P_ ((struct it *)); | 651 static int next_element_from_image P_ ((struct it *)); |
1317 } | 1318 } |
1318 | 1319 |
1319 /* Reset these values to zero becaue the produce_special_glyphs | 1320 /* Reset these values to zero becaue the produce_special_glyphs |
1320 above has changed them. */ | 1321 above has changed them. */ |
1321 it->pixel_width = it->ascent = it->descent = 0; | 1322 it->pixel_width = it->ascent = it->descent = 0; |
1323 it->phys_ascent = it->phys_descent = 0; | |
1322 } | 1324 } |
1323 | 1325 |
1324 /* Set this after getting the dimensions of truncation and | 1326 /* Set this after getting the dimensions of truncation and |
1325 continuation glyphs, so that we don't produce glyphs when calling | 1327 continuation glyphs, so that we don't produce glyphs when calling |
1326 produce_special_glyphs, above. */ | 1328 produce_special_glyphs, above. */ |
3026 CHECK_IT (it); | 3028 CHECK_IT (it); |
3027 } | 3029 } |
3028 | 3030 |
3029 | 3031 |
3030 /* Reseat iterator IT on the next visible line start in the current | 3032 /* Reseat iterator IT on the next visible line start in the current |
3031 buffer. Skip over invisible text that is so because of selective | 3033 buffer. ON_NEWLINE_P non-zero means position IT on the newline |
3032 display. Compute faces, overlays etc at the new position. Note | 3034 preceding the line start. Skip over invisible text that is so |
3033 that this function does not skip over text that is invisible | 3035 because of selective display. Compute faces, overlays etc at the |
3034 because of text properties. */ | 3036 new position. Note that this function does not skip over text that |
3037 is invisible because of text properties. */ | |
3035 | 3038 |
3036 static void | 3039 static void |
3037 reseat_at_next_visible_line_start (it) | 3040 reseat_at_next_visible_line_start (it, on_newline_p) |
3038 struct it *it; | 3041 struct it *it; |
3042 int on_newline_p; | |
3039 { | 3043 { |
3040 /* Restore the buffer position when currently not delivering display | 3044 /* Restore the buffer position when currently not delivering display |
3041 elements from the current buffer. This is the case, for example, | 3045 elements from the current buffer. This is the case, for example, |
3042 when called at the end of a truncated overlay string. */ | 3046 when called at the end of a truncated overlay string. */ |
3043 while (it->sp) | 3047 while (it->sp) |
3068 if (it->selective > 0) | 3072 if (it->selective > 0) |
3069 while (IT_CHARPOS (*it) < ZV | 3073 while (IT_CHARPOS (*it) < ZV |
3070 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it), | 3074 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it), |
3071 it->selective)) | 3075 it->selective)) |
3072 forward_to_next_line_start (it); | 3076 forward_to_next_line_start (it); |
3077 | |
3078 /* Position on the newline if we should. */ | |
3079 if (on_newline_p && IT_CHARPOS (*it) > BEGV) | |
3080 { | |
3081 --IT_CHARPOS (*it); | |
3082 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); | |
3083 } | |
3073 | 3084 |
3074 /* Set the iterator there. The 0 as the last parameter of | 3085 /* Set the iterator there. The 0 as the last parameter of |
3075 reseat means don't force a text property lookup. The lookup | 3086 reseat means don't force a text property lookup. The lookup |
3076 is then only done if we've skipped past the iterator's | 3087 is then only done if we've skipped past the iterator's |
3077 check_charpos'es. This optimization is important because | 3088 check_charpos'es. This optimization is important because |
3425 { | 3436 { |
3426 /* The current display element of IT is a character from | 3437 /* The current display element of IT is a character from |
3427 current_buffer. Advance in the buffer, and maybe skip over | 3438 current_buffer. Advance in the buffer, and maybe skip over |
3428 invisible lines that are so because of selective display. */ | 3439 invisible lines that are so because of selective display. */ |
3429 if (ITERATOR_AT_END_OF_LINE_P (it)) | 3440 if (ITERATOR_AT_END_OF_LINE_P (it)) |
3430 reseat_at_next_visible_line_start (it); | 3441 reseat_at_next_visible_line_start (it, 0); |
3431 else | 3442 else |
3432 { | 3443 { |
3433 xassert (it->len != 0); | 3444 xassert (it->len != 0); |
3434 IT_BYTEPOS (*it) += it->len; | 3445 IT_BYTEPOS (*it) += it->len; |
3435 IT_CHARPOS (*it) += 1; | 3446 IT_CHARPOS (*it) += 1; |
3460 it->method = next_element_from_buffer; | 3471 it->method = next_element_from_buffer; |
3461 | 3472 |
3462 it->dpvec = NULL; | 3473 it->dpvec = NULL; |
3463 it->current.dpvec_index = -1; | 3474 it->current.dpvec_index = -1; |
3464 | 3475 |
3465 /* Consume the character which was displayed via IT->dpvec. */ | 3476 /* Skip over characters which were displayed via IT->dpvec. */ |
3466 if (it->dpvec_char_len) | 3477 if (it->dpvec_char_len < 0) |
3478 reseat_at_next_visible_line_start (it, 1); | |
3479 else if (it->dpvec_char_len > 0) | |
3467 { | 3480 { |
3468 it->len = it->dpvec_char_len; | 3481 it->len = it->dpvec_char_len; |
3469 set_iterator_to_next (it); | 3482 set_iterator_to_next (it); |
3470 } | 3483 } |
3471 } | 3484 } |
3873 if (it->selective > 0 | 3886 if (it->selective > 0 |
3874 && IT_CHARPOS (*it) + 1 < ZV | 3887 && IT_CHARPOS (*it) + 1 < ZV |
3875 && indented_beyond_p (IT_CHARPOS (*it) + 1, | 3888 && indented_beyond_p (IT_CHARPOS (*it) + 1, |
3876 IT_BYTEPOS (*it) + 1, | 3889 IT_BYTEPOS (*it) + 1, |
3877 it->selective)) | 3890 it->selective)) |
3878 next_element_from_ellipsis (it); | 3891 { |
3892 next_element_from_ellipsis (it); | |
3893 it->dpvec_char_len = -1; | |
3894 } | |
3879 } | 3895 } |
3880 else if (it->c == '\r' && it->selective == -1) | 3896 else if (it->c == '\r' && it->selective == -1) |
3881 { | 3897 { |
3882 /* A value of selective == -1 means that everything from the | 3898 /* A value of selective == -1 means that everything from the |
3883 CR to the end of the line is invisible, with maybe an | 3899 CR to the end of the line is invisible, with maybe an |
3884 ellipsis displayed for it. */ | 3900 ellipsis displayed for it. */ |
3885 next_element_from_ellipsis (it); | 3901 next_element_from_ellipsis (it); |
3902 it->dpvec_char_len = -1; | |
3886 } | 3903 } |
3887 } | 3904 } |
3888 } | 3905 } |
3889 | 3906 |
3890 /* Value is zero if end of buffer reached. */ | 3907 /* Value is zero if end of buffer reached. */ |
4249 it->continuation_lines_width = 0; | 4266 it->continuation_lines_width = 0; |
4250 break; | 4267 break; |
4251 | 4268 |
4252 case MOVE_LINE_TRUNCATED: | 4269 case MOVE_LINE_TRUNCATED: |
4253 it->continuation_lines_width = 0; | 4270 it->continuation_lines_width = 0; |
4254 reseat_at_next_visible_line_start (it); | 4271 reseat_at_next_visible_line_start (it, 0); |
4255 if ((op & MOVE_TO_POS) != 0 | 4272 if ((op & MOVE_TO_POS) != 0 |
4256 && IT_CHARPOS (*it) > to_charpos) | 4273 && IT_CHARPOS (*it) > to_charpos) |
4257 goto out; | 4274 goto out; |
4258 break; | 4275 break; |
4259 | 4276 |
5899 compute_line_metrics (it); | 5916 compute_line_metrics (it); |
5900 | 5917 |
5901 /* If line is empty, make it occupy the rest of the toolbar. */ | 5918 /* If line is empty, make it occupy the rest of the toolbar. */ |
5902 if (!row->displays_text_p) | 5919 if (!row->displays_text_p) |
5903 { | 5920 { |
5904 row->height = it->last_visible_y - row->y; | 5921 row->height = row->phys_height = it->last_visible_y - row->y; |
5905 row->ascent = 0; | 5922 row->ascent = row->phys_ascent = 0; |
5906 } | 5923 } |
5907 | 5924 |
5908 row->full_width_p = 1; | 5925 row->full_width_p = 1; |
5909 row->continued_p = 0; | 5926 row->continued_p = 0; |
5910 row->truncated_on_left_p = 0; | 5927 row->truncated_on_left_p = 0; |
9905 place the cursor on it. If so, the row's height hasn't been | 9922 place the cursor on it. If so, the row's height hasn't been |
9906 computed yet. */ | 9923 computed yet. */ |
9907 if (row->height == 0) | 9924 if (row->height == 0) |
9908 { | 9925 { |
9909 if (it->max_ascent + it->max_descent == 0) | 9926 if (it->max_ascent + it->max_descent == 0) |
9910 it->max_descent = CANON_Y_UNIT (it->f); | 9927 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f); |
9911 row->ascent = it->max_ascent; | 9928 row->ascent = it->max_ascent; |
9912 row->height = it->max_ascent + it->max_descent; | 9929 row->height = it->max_ascent + it->max_descent; |
9930 row->phys_ascent = it->max_phys_ascent; | |
9931 row->phys_height = it->max_phys_ascent + it->max_phys_descent; | |
9913 } | 9932 } |
9914 | 9933 |
9915 /* Compute the width of this line. */ | 9934 /* Compute the width of this line. */ |
9916 row->pixel_width = row->x; | 9935 row->pixel_width = row->x; |
9917 for (i = 0; i < row->used[TEXT_AREA]; ++i) | 9936 for (i = 0; i < row->used[TEXT_AREA]; ++i) |
9918 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width; | 9937 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width; |
9919 | 9938 |
9920 xassert (row->pixel_width >= 0); | 9939 xassert (row->pixel_width >= 0); |
9921 xassert (row->ascent >= 0 && row->height > 0); | 9940 xassert (row->ascent >= 0 && row->height > 0); |
9941 | |
9942 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row) | |
9943 || MATRIX_ROW_OVERLAPS_PRED_P (row)); | |
9944 | |
9945 /* If first line's physical ascent is larger than its logical | |
9946 ascent, use the physical ascent, and make the row taller. | |
9947 This makes accented characters fully visible. */ | |
9948 if (row == it->w->desired_matrix->rows | |
9949 && row->phys_ascent > row->ascent) | |
9950 { | |
9951 row->height += row->phys_ascent - row->ascent; | |
9952 row->ascent = row->phys_ascent; | |
9953 } | |
9922 | 9954 |
9923 /* Compute how much of the line is visible. */ | 9955 /* Compute how much of the line is visible. */ |
9924 row->visible_height = row->height; | 9956 row->visible_height = row->height; |
9925 | 9957 |
9926 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w); | 9958 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w); |
9934 } | 9966 } |
9935 } | 9967 } |
9936 else | 9968 else |
9937 { | 9969 { |
9938 row->pixel_width = row->used[TEXT_AREA]; | 9970 row->pixel_width = row->used[TEXT_AREA]; |
9939 row->ascent = 0; | 9971 row->ascent = row->phys_ascent = 0; |
9940 row->height = row->visible_height = 1; | 9972 row->height = row->phys_height = row->visible_height = 1; |
9941 } | 9973 } |
9942 | 9974 |
9943 /* Compute a hash code for this row. */ | 9975 /* Compute a hash code for this row. */ |
9944 row->hash = 0; | 9976 row->hash = 0; |
9945 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | 9977 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) |
9947 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff) | 9979 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff) |
9948 + row->glyphs[area][i].u.val | 9980 + row->glyphs[area][i].u.val |
9949 + (row->glyphs[area][i].type << 2)); | 9981 + (row->glyphs[area][i].type << 2)); |
9950 | 9982 |
9951 it->max_ascent = it->max_descent = 0; | 9983 it->max_ascent = it->max_descent = 0; |
9984 it->max_phys_ascent = it->max_phys_descent = 0; | |
9952 } | 9985 } |
9953 | 9986 |
9954 | 9987 |
9955 /* Append one space to the glyph row of iterator IT if doing a | 9988 /* Append one space to the glyph row of iterator IT if doing a |
9956 window-based redisplay. DEFAULT_FACE_P non-zero means let the | 9989 window-based redisplay. DEFAULT_FACE_P non-zero means let the |
10250 | 10283 |
10251 /* Get the initial row height. This is either the height of the | 10284 /* Get the initial row height. This is either the height of the |
10252 text hscrolled, if there is any, or zero. */ | 10285 text hscrolled, if there is any, or zero. */ |
10253 row->ascent = it->max_ascent; | 10286 row->ascent = it->max_ascent; |
10254 row->height = it->max_ascent + it->max_descent; | 10287 row->height = it->max_ascent + it->max_descent; |
10288 row->phys_ascent = it->max_phys_ascent; | |
10289 row->phys_height = it->max_phys_ascent + it->max_phys_descent; | |
10255 | 10290 |
10256 /* Loop generating characters. The loop is left with IT on the next | 10291 /* Loop generating characters. The loop is left with IT on the next |
10257 character to display. */ | 10292 character to display. */ |
10258 while (1) | 10293 while (1) |
10259 { | 10294 { |
10295 the next one. */ | 10330 the next one. */ |
10296 if (it->area != TEXT_AREA) | 10331 if (it->area != TEXT_AREA) |
10297 { | 10332 { |
10298 row->ascent = max (row->ascent, it->max_ascent); | 10333 row->ascent = max (row->ascent, it->max_ascent); |
10299 row->height = max (row->height, it->max_ascent + it->max_descent); | 10334 row->height = max (row->height, it->max_ascent + it->max_descent); |
10335 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); | |
10336 row->phys_height = max (row->phys_height, | |
10337 it->max_phys_ascent + it->max_phys_descent); | |
10300 set_iterator_to_next (it); | 10338 set_iterator_to_next (it); |
10301 continue; | 10339 continue; |
10302 } | 10340 } |
10303 | 10341 |
10304 /* Does the display element fit on the line? If we truncate | 10342 /* Does the display element fit on the line? If we truncate |
10318 && it->current_x < it->last_visible_x) | 10356 && it->current_x < it->last_visible_x) |
10319 { | 10357 { |
10320 ++it->hpos; | 10358 ++it->hpos; |
10321 row->ascent = max (row->ascent, it->max_ascent); | 10359 row->ascent = max (row->ascent, it->max_ascent); |
10322 row->height = max (row->height, it->max_ascent + it->max_descent); | 10360 row->height = max (row->height, it->max_ascent + it->max_descent); |
10361 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); | |
10362 row->phys_height = max (row->phys_height, | |
10363 it->max_phys_ascent + it->max_phys_descent); | |
10323 if (it->current_x - it->pixel_width < it->first_visible_x) | 10364 if (it->current_x - it->pixel_width < it->first_visible_x) |
10324 row->x = x - it->first_visible_x; | 10365 row->x = x - it->first_visible_x; |
10325 } | 10366 } |
10326 else | 10367 else |
10327 { | 10368 { |
10396 } | 10437 } |
10397 } | 10438 } |
10398 | 10439 |
10399 row->ascent = max (row->ascent, it->max_ascent); | 10440 row->ascent = max (row->ascent, it->max_ascent); |
10400 row->height = max (row->height, it->max_ascent + it->max_descent); | 10441 row->height = max (row->height, it->max_ascent + it->max_descent); |
10442 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); | |
10443 row->phys_height = max (row->phys_height, | |
10444 it->max_phys_ascent + it->max_phys_descent); | |
10401 | 10445 |
10402 /* End of this display line if row is continued. */ | 10446 /* End of this display line if row is continued. */ |
10403 if (row->continued_p) | 10447 if (row->continued_p) |
10404 break; | 10448 break; |
10405 } | 10449 } |
10446 produce_special_glyphs (it, IT_TRUNCATION); | 10490 produce_special_glyphs (it, IT_TRUNCATION); |
10447 } | 10491 } |
10448 | 10492 |
10449 row->truncated_on_right_p = 1; | 10493 row->truncated_on_right_p = 1; |
10450 it->continuation_lines_width = 0; | 10494 it->continuation_lines_width = 0; |
10451 reseat_at_next_visible_line_start (it); | 10495 reseat_at_next_visible_line_start (it, 0); |
10452 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; | 10496 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; |
10453 it->hpos = hpos_before; | 10497 it->hpos = hpos_before; |
10454 it->current_x = x_before; | 10498 it->current_x = x_before; |
10455 break; | 10499 break; |
10456 } | 10500 } |
11664 move_it_in_display_line_to (it, 100000, it->first_visible_x, | 11708 move_it_in_display_line_to (it, 100000, it->first_visible_x, |
11665 MOVE_TO_POS | MOVE_TO_X); | 11709 MOVE_TO_POS | MOVE_TO_X); |
11666 | 11710 |
11667 row->ascent = it->max_ascent; | 11711 row->ascent = it->max_ascent; |
11668 row->height = it->max_ascent + it->max_descent; | 11712 row->height = it->max_ascent + it->max_descent; |
11713 row->phys_ascent = it->max_phys_ascent; | |
11714 row->phys_height = it->max_phys_ascent + it->max_phys_descent; | |
11669 | 11715 |
11670 /* This condition is for the case that we are called with current_x | 11716 /* This condition is for the case that we are called with current_x |
11671 past last_visible_x. */ | 11717 past last_visible_x. */ |
11672 while (it->current_x < max_x) | 11718 while (it->current_x < max_x) |
11673 { | 11719 { |
11711 abort (); | 11757 abort (); |
11712 } | 11758 } |
11713 | 11759 |
11714 row->ascent = max (row->ascent, it->max_ascent); | 11760 row->ascent = max (row->ascent, it->max_ascent); |
11715 row->height = max (row->height, it->max_ascent + it->max_descent); | 11761 row->height = max (row->height, it->max_ascent + it->max_descent); |
11762 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); | |
11763 row->phys_height = max (row->phys_height, | |
11764 it->max_phys_ascent + it->max_phys_descent); | |
11716 x += glyph->pixel_width; | 11765 x += glyph->pixel_width; |
11717 ++i; | 11766 ++i; |
11718 } | 11767 } |
11719 | 11768 |
11720 /* Stop if max_x reached. */ | 11769 /* Stop if max_x reached. */ |