diff options
| author | Kim F. Storm | 2004-04-29 22:37:52 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2004-04-29 22:37:52 +0000 |
| commit | a9e5c93275d3d9ebbd89da4efd89d9e31ec3cf4e (patch) | |
| tree | 1dd1ea6bf12f02850a3cca9c94b51a7b6db4602f | |
| parent | d956147cecb190296dafd598866fa505dacfeaf8 (diff) | |
| download | emacs-a9e5c93275d3d9ebbd89da4efd89d9e31ec3cf4e.tar.gz emacs-a9e5c93275d3d9ebbd89da4efd89d9e31ec3cf4e.zip | |
(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.
| -rw-r--r-- | src/xdisp.c | 176 |
1 files changed, 136 insertions, 40 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 08a5db4df39..2ae2a7333ee 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2073,6 +2073,9 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) | |||
| 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 | } |
| @@ -2090,6 +2093,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) | |||
| 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); |
| @@ -14202,7 +14206,7 @@ append_space_for_newline (it, default_face_p) | |||
| 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; |
| @@ -18510,6 +18514,97 @@ produce_stretch_glyph (it) | |||
| 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 |
| @@ -18596,17 +18691,20 @@ x_produce_glyphs (it) | |||
| 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 | { |
| @@ -18709,26 +18807,27 @@ x_produce_glyphs (it) | |||
| 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); | ||
| 18719 | 18817 | ||
| 18720 | if (EQ (lh, Qt)) | 18818 | if (it->override_ascent >= 0) |
| 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; | 18823 | } |
| 18824 | else | ||
| 18825 | { | ||
| 18826 | it->ascent = FONT_BASE (font) + boff; | ||
| 18827 | it->descent = FONT_DESCENT (font) - boff; | ||
| 18726 | } | 18828 | } |
| 18727 | 18829 | ||
| 18728 | it->ascent = FONT_BASE (font) + boff; | 18830 | if (EQ (height, make_number(0))) |
| 18729 | it->descent = FONT_DESCENT (font) - boff; | ||
| 18730 | |||
| 18731 | if (EQ (lh, make_number (0))) | ||
| 18732 | { | 18831 | { |
| 18733 | if (it->descent > it->max_descent) | 18832 | if (it->descent > it->max_descent) |
| 18734 | { | 18833 | { |
| @@ -18747,7 +18846,6 @@ x_produce_glyphs (it) | |||
| 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 | ||
| @@ -18758,23 +18856,20 @@ x_produce_glyphs (it) | |||
| 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 | { |
| @@ -19151,7 +19246,8 @@ x_produce_glyphs (it) | |||
| 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); |
| @@ -20815,9 +20911,9 @@ note_mouse_highlight (f, x, y) | |||
| 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) |