mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 12:21:25 -08:00
(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.
This commit is contained in:
parent
d956147cec
commit
a9e5c93275
1 changed files with 136 additions and 40 deletions
176
src/xdisp.c
176
src/xdisp.c
|
|
@ -2073,6 +2073,9 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
|
|||
{
|
||||
if (NATNUMP (current_buffer->extra_line_spacing))
|
||||
it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
|
||||
else if (FLOATP (current_buffer->extra_line_spacing))
|
||||
it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
|
||||
* FRAME_LINE_HEIGHT (it->f));
|
||||
else if (it->f->extra_line_spacing > 0)
|
||||
it->extra_line_spacing = it->f->extra_line_spacing;
|
||||
}
|
||||
|
|
@ -2090,6 +2093,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
|
|||
it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
|
||||
it->space_width = Qnil;
|
||||
it->font_height = Qnil;
|
||||
it->override_ascent = -1;
|
||||
|
||||
/* Are control characters displayed as `^C'? */
|
||||
it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
|
||||
|
|
@ -14202,7 +14206,7 @@ append_space_for_newline (it, default_face_p)
|
|||
|
||||
PRODUCE_GLYPHS (it);
|
||||
|
||||
it->use_default_face = 0;
|
||||
it->override_ascent = -1;
|
||||
it->constrain_row_ascent_descent_p = 0;
|
||||
it->current_x = saved_x;
|
||||
it->object = saved_object;
|
||||
|
|
@ -18510,6 +18514,97 @@ produce_stretch_glyph (it)
|
|||
take_vertical_position_into_account (it);
|
||||
}
|
||||
|
||||
/* Calculate line-height and line-spacing properties.
|
||||
An integer value specifies explicit pixel value.
|
||||
A float value specifies relative value to current face height.
|
||||
A cons (float . face-name) specifies relative value to
|
||||
height of specified face font.
|
||||
|
||||
Returns height in pixels, or nil. */
|
||||
|
||||
static Lisp_Object
|
||||
calc_line_height_property (it, prop, font, boff)
|
||||
struct it *it;
|
||||
Lisp_Object prop;
|
||||
XFontStruct *font;
|
||||
int boff;
|
||||
{
|
||||
Lisp_Object val;
|
||||
Lisp_Object face_name = Qnil;
|
||||
int ascent, descent, height, override;
|
||||
|
||||
val = Fget_char_property (make_number (IT_CHARPOS (*it)),
|
||||
prop, it->object);
|
||||
|
||||
if (NILP (val))
|
||||
return val;
|
||||
|
||||
if (INTEGERP (val))
|
||||
return val;
|
||||
|
||||
if (CONSP (val))
|
||||
{
|
||||
face_name = XCDR (val);
|
||||
val = XCAR (val);
|
||||
}
|
||||
else if (SYMBOLP (val))
|
||||
{
|
||||
face_name = val;
|
||||
val = Qnil;
|
||||
}
|
||||
|
||||
override = EQ (prop, Qline_height);
|
||||
|
||||
if (NILP (face_name))
|
||||
{
|
||||
font = FRAME_FONT (it->f);
|
||||
boff = FRAME_BASELINE_OFFSET (it->f);
|
||||
}
|
||||
else if (EQ (face_name, Qt))
|
||||
{
|
||||
override = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int face_id;
|
||||
struct face *face;
|
||||
struct font_info *font_info;
|
||||
|
||||
face_id = lookup_named_face (it->f, face_name, ' ');
|
||||
if (face_id < 0)
|
||||
return -1;
|
||||
|
||||
face = FACE_FROM_ID (it->f, face_id);
|
||||
font = face->font;
|
||||
if (font == NULL)
|
||||
return -1;
|
||||
|
||||
font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
|
||||
boff = font_info->baseline_offset;
|
||||
if (font_info->vertical_centering)
|
||||
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
|
||||
}
|
||||
|
||||
ascent = FONT_BASE (font) + boff;
|
||||
descent = FONT_DESCENT (font) - boff;
|
||||
|
||||
if (override)
|
||||
{
|
||||
it->override_ascent = ascent;
|
||||
it->override_descent = descent;
|
||||
it->override_boff = boff;
|
||||
}
|
||||
|
||||
height = ascent + descent;
|
||||
if (FLOATP (val))
|
||||
height = (int)(XFLOAT_DATA (val) * height);
|
||||
else if (INTEGERP (val))
|
||||
height *= XINT (val);
|
||||
|
||||
return make_number (height);
|
||||
}
|
||||
|
||||
|
||||
/* RIF:
|
||||
Produce glyphs/get display metrics for the display element IT is
|
||||
loaded with. See the description of struct display_iterator in
|
||||
|
|
@ -18596,17 +18691,20 @@ x_produce_glyphs (it)
|
|||
|
||||
it->nglyphs = 1;
|
||||
|
||||
if (it->use_default_face)
|
||||
{
|
||||
font = FRAME_FONT (it->f);
|
||||
boff = FRAME_BASELINE_OFFSET (it->f);
|
||||
}
|
||||
|
||||
pcm = rif->per_char_metric (font, &char2b,
|
||||
FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
|
||||
|
||||
it->ascent = FONT_BASE (font) + boff;
|
||||
it->descent = FONT_DESCENT (font) - boff;
|
||||
if (it->override_ascent >= 0)
|
||||
{
|
||||
it->ascent = it->override_ascent;
|
||||
it->descent = it->override_descent;
|
||||
boff = it->override_boff;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->ascent = FONT_BASE (font) + boff;
|
||||
it->descent = FONT_DESCENT (font) - boff;
|
||||
}
|
||||
|
||||
if (pcm)
|
||||
{
|
||||
|
|
@ -18709,26 +18807,27 @@ x_produce_glyphs (it)
|
|||
But if previous part of the line set a height, don't
|
||||
increase that height */
|
||||
|
||||
Lisp_Object lsp, lh;
|
||||
Lisp_Object height, spacing;
|
||||
|
||||
it->override_ascent = -1;
|
||||
it->pixel_width = 0;
|
||||
it->nglyphs = 0;
|
||||
|
||||
lh = Fget_text_property (make_number (IT_CHARPOS (*it)),
|
||||
Qline_height, it->object);
|
||||
height = calc_line_height_property(it, Qline_height, font, boff);
|
||||
|
||||
if (EQ (lh, Qt))
|
||||
if (it->override_ascent >= 0)
|
||||
{
|
||||
it->use_default_face = 1;
|
||||
font = FRAME_FONT (it->f);
|
||||
boff = FRAME_BASELINE_OFFSET (it->f);
|
||||
font_info = NULL;
|
||||
it->ascent = it->override_ascent;
|
||||
it->descent = it->override_descent;
|
||||
boff = it->override_boff;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->ascent = FONT_BASE (font) + boff;
|
||||
it->descent = FONT_DESCENT (font) - boff;
|
||||
}
|
||||
|
||||
it->ascent = FONT_BASE (font) + boff;
|
||||
it->descent = FONT_DESCENT (font) - boff;
|
||||
|
||||
if (EQ (lh, make_number (0)))
|
||||
if (EQ (height, make_number(0)))
|
||||
{
|
||||
if (it->descent > it->max_descent)
|
||||
{
|
||||
|
|
@ -18747,7 +18846,6 @@ x_produce_glyphs (it)
|
|||
}
|
||||
else
|
||||
{
|
||||
int explicit_height = -1;
|
||||
it->phys_ascent = it->ascent;
|
||||
it->phys_descent = it->descent;
|
||||
|
||||
|
|
@ -18758,23 +18856,20 @@ x_produce_glyphs (it)
|
|||
it->ascent += face->box_line_width;
|
||||
it->descent += face->box_line_width;
|
||||
}
|
||||
if (INTEGERP (lh))
|
||||
explicit_height = XINT (lh);
|
||||
else if (FLOATP (lh))
|
||||
explicit_height = (it->phys_ascent + it->phys_descent)
|
||||
* XFLOAT_DATA (lh);
|
||||
|
||||
if (explicit_height > it->ascent + it->descent)
|
||||
it->ascent = explicit_height - it->descent;
|
||||
if (!NILP (height)
|
||||
&& XINT (height) > it->ascent + it->descent)
|
||||
it->ascent = XINT (height) - it->descent;
|
||||
}
|
||||
|
||||
lsp = Fget_text_property (make_number (IT_CHARPOS (*it)),
|
||||
Qline_spacing, it->object);
|
||||
if (INTEGERP (lsp))
|
||||
extra_line_spacing = XINT (lsp);
|
||||
else if (FLOATP (lsp))
|
||||
extra_line_spacing = (it->phys_ascent + it->phys_descent)
|
||||
* XFLOAT_DATA (lsp);
|
||||
spacing = calc_line_height_property(it, Qline_spacing, font, boff);
|
||||
if (!NILP (spacing))
|
||||
{
|
||||
int sp = XINT (spacing);
|
||||
if (sp < 0)
|
||||
extra_line_spacing = (-sp) - (it->phys_ascent + it->phys_descent);
|
||||
else
|
||||
extra_line_spacing = sp;
|
||||
}
|
||||
}
|
||||
else if (it->char_to_display == '\t')
|
||||
{
|
||||
|
|
@ -19151,7 +19246,8 @@ x_produce_glyphs (it)
|
|||
if (it->area == TEXT_AREA)
|
||||
it->current_x += it->pixel_width;
|
||||
|
||||
it->descent += extra_line_spacing;
|
||||
if (extra_line_spacing > 0)
|
||||
it->descent += extra_line_spacing;
|
||||
|
||||
it->max_ascent = max (it->max_ascent, it->ascent);
|
||||
it->max_descent = max (it->max_descent, it->descent);
|
||||
|
|
@ -20815,9 +20911,9 @@ note_mouse_highlight (f, x, y)
|
|||
if (BUFFERP (object))
|
||||
{
|
||||
/* Put all the overlays we want in a vector in overlay_vec.
|
||||
Store the length in len. If there are more than 10, make
|
||||
Store the length in len. If there are more than 40, make
|
||||
enough space for all, and try again. */
|
||||
len = 10;
|
||||
len = 40;
|
||||
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
|
||||
noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
|
||||
if (noverlays > len)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue