Mercurial > emacs
comparison src/xdisp.c @ 55244:c5bad07bbb95
(init_iterator): Handle line-spacing float value.
Initialize override_ascent member.
(append_space_for_newline): Reset override_ascent.
Remove use_default_face.
(calc_line_height_property): New function to calculate value of
line-height and line-spacing properties. Look at overlays, too.
Set override_ascent, override_descent, override_boff members when
using another face than the current face. Float values are now
relative to the frame default font, by default; accept a cons
of ratio and face name to specify value relative to a specific face.
(x_produce_glyphs): Use calc_line_height_property.
Use override_ascent etc. when set to handle different face heights.
A negative line-spacing property value is interpreted as a total
line height, rather than inter-line spacing.
(note_mouse_highlight): Allocate room for 40 overlays initially.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Thu, 29 Apr 2004 22:37:52 +0000 |
parents | d6780b4bbfa5 |
children | c2bea9cc10a3 6ae3d2810507 |
comparison
equal
deleted
inserted
replaced
55243:fa2641411db1 | 55244:c5bad07bbb95 |
---|---|
2071 if (base_face_id == DEFAULT_FACE_ID | 2071 if (base_face_id == DEFAULT_FACE_ID |
2072 && FRAME_WINDOW_P (it->f)) | 2072 && FRAME_WINDOW_P (it->f)) |
2073 { | 2073 { |
2074 if (NATNUMP (current_buffer->extra_line_spacing)) | 2074 if (NATNUMP (current_buffer->extra_line_spacing)) |
2075 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing); | 2075 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing); |
2076 else if (FLOATP (current_buffer->extra_line_spacing)) | |
2077 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing) | |
2078 * FRAME_LINE_HEIGHT (it->f)); | |
2076 else if (it->f->extra_line_spacing > 0) | 2079 else if (it->f->extra_line_spacing > 0) |
2077 it->extra_line_spacing = it->f->extra_line_spacing; | 2080 it->extra_line_spacing = it->f->extra_line_spacing; |
2078 } | 2081 } |
2079 | 2082 |
2080 /* If realized faces have been removed, e.g. because of face | 2083 /* If realized faces have been removed, e.g. because of face |
2088 | 2091 |
2089 /* Current value of the `slice', `space-width', and 'height' properties. */ | 2092 /* Current value of the `slice', `space-width', and 'height' properties. */ |
2090 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil; | 2093 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil; |
2091 it->space_width = Qnil; | 2094 it->space_width = Qnil; |
2092 it->font_height = Qnil; | 2095 it->font_height = Qnil; |
2096 it->override_ascent = -1; | |
2093 | 2097 |
2094 /* Are control characters displayed as `^C'? */ | 2098 /* Are control characters displayed as `^C'? */ |
2095 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow); | 2099 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow); |
2096 | 2100 |
2097 /* -1 means everything between a CR and the following line end | 2101 /* -1 means everything between a CR and the following line end |
14200 face = FACE_FROM_ID (it->f, it->face_id); | 14204 face = FACE_FROM_ID (it->f, it->face_id); |
14201 it->face_id = FACE_FOR_CHAR (it->f, face, 0); | 14205 it->face_id = FACE_FOR_CHAR (it->f, face, 0); |
14202 | 14206 |
14203 PRODUCE_GLYPHS (it); | 14207 PRODUCE_GLYPHS (it); |
14204 | 14208 |
14205 it->use_default_face = 0; | 14209 it->override_ascent = -1; |
14206 it->constrain_row_ascent_descent_p = 0; | 14210 it->constrain_row_ascent_descent_p = 0; |
14207 it->current_x = saved_x; | 14211 it->current_x = saved_x; |
14208 it->object = saved_object; | 14212 it->object = saved_object; |
14209 it->position = saved_pos; | 14213 it->position = saved_pos; |
14210 it->what = saved_what; | 14214 it->what = saved_what; |
18508 } | 18512 } |
18509 | 18513 |
18510 take_vertical_position_into_account (it); | 18514 take_vertical_position_into_account (it); |
18511 } | 18515 } |
18512 | 18516 |
18517 /* Calculate line-height and line-spacing properties. | |
18518 An integer value specifies explicit pixel value. | |
18519 A float value specifies relative value to current face height. | |
18520 A cons (float . face-name) specifies relative value to | |
18521 height of specified face font. | |
18522 | |
18523 Returns height in pixels, or nil. */ | |
18524 | |
18525 static Lisp_Object | |
18526 calc_line_height_property (it, prop, font, boff) | |
18527 struct it *it; | |
18528 Lisp_Object prop; | |
18529 XFontStruct *font; | |
18530 int boff; | |
18531 { | |
18532 Lisp_Object val; | |
18533 Lisp_Object face_name = Qnil; | |
18534 int ascent, descent, height, override; | |
18535 | |
18536 val = Fget_char_property (make_number (IT_CHARPOS (*it)), | |
18537 prop, it->object); | |
18538 | |
18539 if (NILP (val)) | |
18540 return val; | |
18541 | |
18542 if (INTEGERP (val)) | |
18543 return val; | |
18544 | |
18545 if (CONSP (val)) | |
18546 { | |
18547 face_name = XCDR (val); | |
18548 val = XCAR (val); | |
18549 } | |
18550 else if (SYMBOLP (val)) | |
18551 { | |
18552 face_name = val; | |
18553 val = Qnil; | |
18554 } | |
18555 | |
18556 override = EQ (prop, Qline_height); | |
18557 | |
18558 if (NILP (face_name)) | |
18559 { | |
18560 font = FRAME_FONT (it->f); | |
18561 boff = FRAME_BASELINE_OFFSET (it->f); | |
18562 } | |
18563 else if (EQ (face_name, Qt)) | |
18564 { | |
18565 override = 0; | |
18566 } | |
18567 else | |
18568 { | |
18569 int face_id; | |
18570 struct face *face; | |
18571 struct font_info *font_info; | |
18572 | |
18573 face_id = lookup_named_face (it->f, face_name, ' '); | |
18574 if (face_id < 0) | |
18575 return -1; | |
18576 | |
18577 face = FACE_FROM_ID (it->f, face_id); | |
18578 font = face->font; | |
18579 if (font == NULL) | |
18580 return -1; | |
18581 | |
18582 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | |
18583 boff = font_info->baseline_offset; | |
18584 if (font_info->vertical_centering) | |
18585 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | |
18586 } | |
18587 | |
18588 ascent = FONT_BASE (font) + boff; | |
18589 descent = FONT_DESCENT (font) - boff; | |
18590 | |
18591 if (override) | |
18592 { | |
18593 it->override_ascent = ascent; | |
18594 it->override_descent = descent; | |
18595 it->override_boff = boff; | |
18596 } | |
18597 | |
18598 height = ascent + descent; | |
18599 if (FLOATP (val)) | |
18600 height = (int)(XFLOAT_DATA (val) * height); | |
18601 else if (INTEGERP (val)) | |
18602 height *= XINT (val); | |
18603 | |
18604 return make_number (height); | |
18605 } | |
18606 | |
18607 | |
18513 /* RIF: | 18608 /* RIF: |
18514 Produce glyphs/get display metrics for the display element IT is | 18609 Produce glyphs/get display metrics for the display element IT is |
18515 loaded with. See the description of struct display_iterator in | 18610 loaded with. See the description of struct display_iterator in |
18516 dispextern.h for an overview of struct display_iterator. */ | 18611 dispextern.h for an overview of struct display_iterator. */ |
18517 | 18612 |
18594 /* Either unibyte or ASCII. */ | 18689 /* Either unibyte or ASCII. */ |
18595 int stretched_p; | 18690 int stretched_p; |
18596 | 18691 |
18597 it->nglyphs = 1; | 18692 it->nglyphs = 1; |
18598 | 18693 |
18599 if (it->use_default_face) | |
18600 { | |
18601 font = FRAME_FONT (it->f); | |
18602 boff = FRAME_BASELINE_OFFSET (it->f); | |
18603 } | |
18604 | |
18605 pcm = rif->per_char_metric (font, &char2b, | 18694 pcm = rif->per_char_metric (font, &char2b, |
18606 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display)); | 18695 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display)); |
18607 | 18696 |
18608 it->ascent = FONT_BASE (font) + boff; | 18697 if (it->override_ascent >= 0) |
18609 it->descent = FONT_DESCENT (font) - boff; | 18698 { |
18699 it->ascent = it->override_ascent; | |
18700 it->descent = it->override_descent; | |
18701 boff = it->override_boff; | |
18702 } | |
18703 else | |
18704 { | |
18705 it->ascent = FONT_BASE (font) + boff; | |
18706 it->descent = FONT_DESCENT (font) - boff; | |
18707 } | |
18610 | 18708 |
18611 if (pcm) | 18709 if (pcm) |
18612 { | 18710 { |
18613 it->phys_ascent = pcm->ascent + boff; | 18711 it->phys_ascent = pcm->ascent + boff; |
18614 it->phys_descent = pcm->descent - boff; | 18712 it->phys_descent = pcm->descent - boff; |
18707 { | 18805 { |
18708 /* A newline has no width but we need the height of the line. | 18806 /* A newline has no width but we need the height of the line. |
18709 But if previous part of the line set a height, don't | 18807 But if previous part of the line set a height, don't |
18710 increase that height */ | 18808 increase that height */ |
18711 | 18809 |
18712 Lisp_Object lsp, lh; | 18810 Lisp_Object height, spacing; |
18713 | 18811 |
18812 it->override_ascent = -1; | |
18714 it->pixel_width = 0; | 18813 it->pixel_width = 0; |
18715 it->nglyphs = 0; | 18814 it->nglyphs = 0; |
18716 | 18815 |
18717 lh = Fget_text_property (make_number (IT_CHARPOS (*it)), | 18816 height = calc_line_height_property(it, Qline_height, font, boff); |
18718 Qline_height, it->object); | 18817 |
18719 | 18818 if (it->override_ascent >= 0) |
18720 if (EQ (lh, Qt)) | |
18721 { | 18819 { |
18722 it->use_default_face = 1; | 18820 it->ascent = it->override_ascent; |
18723 font = FRAME_FONT (it->f); | 18821 it->descent = it->override_descent; |
18724 boff = FRAME_BASELINE_OFFSET (it->f); | 18822 boff = it->override_boff; |
18725 font_info = NULL; | |
18726 } | 18823 } |
18727 | 18824 else |
18728 it->ascent = FONT_BASE (font) + boff; | 18825 { |
18729 it->descent = FONT_DESCENT (font) - boff; | 18826 it->ascent = FONT_BASE (font) + boff; |
18730 | 18827 it->descent = FONT_DESCENT (font) - boff; |
18731 if (EQ (lh, make_number (0))) | 18828 } |
18829 | |
18830 if (EQ (height, make_number(0))) | |
18732 { | 18831 { |
18733 if (it->descent > it->max_descent) | 18832 if (it->descent > it->max_descent) |
18734 { | 18833 { |
18735 it->ascent += it->descent - it->max_descent; | 18834 it->ascent += it->descent - it->max_descent; |
18736 it->descent = it->max_descent; | 18835 it->descent = it->max_descent; |
18745 it->constrain_row_ascent_descent_p = 1; | 18844 it->constrain_row_ascent_descent_p = 1; |
18746 extra_line_spacing = 0; | 18845 extra_line_spacing = 0; |
18747 } | 18846 } |
18748 else | 18847 else |
18749 { | 18848 { |
18750 int explicit_height = -1; | |
18751 it->phys_ascent = it->ascent; | 18849 it->phys_ascent = it->ascent; |
18752 it->phys_descent = it->descent; | 18850 it->phys_descent = it->descent; |
18753 | 18851 |
18754 if ((it->max_ascent > 0 || it->max_descent > 0) | 18852 if ((it->max_ascent > 0 || it->max_descent > 0) |
18755 && face->box != FACE_NO_BOX | 18853 && face->box != FACE_NO_BOX |
18756 && face->box_line_width > 0) | 18854 && face->box_line_width > 0) |
18757 { | 18855 { |
18758 it->ascent += face->box_line_width; | 18856 it->ascent += face->box_line_width; |
18759 it->descent += face->box_line_width; | 18857 it->descent += face->box_line_width; |
18760 } | 18858 } |
18761 if (INTEGERP (lh)) | 18859 if (!NILP (height) |
18762 explicit_height = XINT (lh); | 18860 && XINT (height) > it->ascent + it->descent) |
18763 else if (FLOATP (lh)) | 18861 it->ascent = XINT (height) - it->descent; |
18764 explicit_height = (it->phys_ascent + it->phys_descent) | |
18765 * XFLOAT_DATA (lh); | |
18766 | |
18767 if (explicit_height > it->ascent + it->descent) | |
18768 it->ascent = explicit_height - it->descent; | |
18769 } | 18862 } |
18770 | 18863 |
18771 lsp = Fget_text_property (make_number (IT_CHARPOS (*it)), | 18864 spacing = calc_line_height_property(it, Qline_spacing, font, boff); |
18772 Qline_spacing, it->object); | 18865 if (!NILP (spacing)) |
18773 if (INTEGERP (lsp)) | 18866 { |
18774 extra_line_spacing = XINT (lsp); | 18867 int sp = XINT (spacing); |
18775 else if (FLOATP (lsp)) | 18868 if (sp < 0) |
18776 extra_line_spacing = (it->phys_ascent + it->phys_descent) | 18869 extra_line_spacing = (-sp) - (it->phys_ascent + it->phys_descent); |
18777 * XFLOAT_DATA (lsp); | 18870 else |
18871 extra_line_spacing = sp; | |
18872 } | |
18778 } | 18873 } |
18779 else if (it->char_to_display == '\t') | 18874 else if (it->char_to_display == '\t') |
18780 { | 18875 { |
18781 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f); | 18876 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f); |
18782 int x = it->current_x + it->continuation_lines_width; | 18877 int x = it->current_x + it->continuation_lines_width; |
19149 because this isn't true for images with `:ascent 100'. */ | 19244 because this isn't true for images with `:ascent 100'. */ |
19150 xassert (it->ascent >= 0 && it->descent >= 0); | 19245 xassert (it->ascent >= 0 && it->descent >= 0); |
19151 if (it->area == TEXT_AREA) | 19246 if (it->area == TEXT_AREA) |
19152 it->current_x += it->pixel_width; | 19247 it->current_x += it->pixel_width; |
19153 | 19248 |
19154 it->descent += extra_line_spacing; | 19249 if (extra_line_spacing > 0) |
19250 it->descent += extra_line_spacing; | |
19155 | 19251 |
19156 it->max_ascent = max (it->max_ascent, it->ascent); | 19252 it->max_ascent = max (it->max_ascent, it->ascent); |
19157 it->max_descent = max (it->max_descent, it->descent); | 19253 it->max_descent = max (it->max_descent, it->descent); |
19158 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); | 19254 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); |
19159 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); | 19255 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); |
20813 position = make_number (pos); | 20909 position = make_number (pos); |
20814 | 20910 |
20815 if (BUFFERP (object)) | 20911 if (BUFFERP (object)) |
20816 { | 20912 { |
20817 /* Put all the overlays we want in a vector in overlay_vec. | 20913 /* Put all the overlays we want in a vector in overlay_vec. |
20818 Store the length in len. If there are more than 10, make | 20914 Store the length in len. If there are more than 40, make |
20819 enough space for all, and try again. */ | 20915 enough space for all, and try again. */ |
20820 len = 10; | 20916 len = 40; |
20821 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); | 20917 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); |
20822 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0); | 20918 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0); |
20823 if (noverlays > len) | 20919 if (noverlays > len) |
20824 { | 20920 { |
20825 len = noverlays; | 20921 len = noverlays; |