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. */