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;