Mercurial > emacs
changeset 55029:01ecdd56871c
(Qslice): New variable.
(syms_of_xdisp): Intern and staticpro it.
(pos_visible_p): Return pixel position in new x and y args.
(init_iterator): Reset it->slice info.
(handle_display_prop): Parse (slice ...) property.
(push_it, pop_it): Save/restore slice info.
(make_cursor_line_fully_visible): Fix 2004-04-14 change. Do not
force repositioning of tall row if window is vscrolled, as that
would reset vscroll.
(append_space): Set it->constrain_row_ascent_descent_p to avoid
increasing row height if row is non-empty.
(fill_image_glyph_string): Copy slice info.
(take_vertical_position_into_account): Simplify.
(produce_image_glyph): Handle iterator slice info, setup glyph
slice info. Do not force minimum line height.
(x_produce_glyphs): If it->constrain_row_ascent_descent_p is set,
do not increase height (ascent/descent) of non-empty row when
adding normal character glyph; instead reduce glyph ascent/descent
appropriately; if row is higher than current glyph, adjust glyph
descent/ascent to reposition glyph within the existing row.
Likewise, when char is newline, only set ascent/descent if row is
currently empty.
(note_mouse_highlight): Handle hotspots with sliced image.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Tue, 20 Apr 2004 22:19:09 +0000 |
parents | 0f5f3d0c5f4c |
children | 44eb66585062 |
files | src/xdisp.c |
diffstat | 1 files changed, 177 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xdisp.c Tue Apr 20 22:18:43 2004 +0000 +++ b/src/xdisp.c Tue Apr 20 22:19:09 2004 +0000 @@ -301,6 +301,7 @@ Lisp_Object Vdisplay_pixels_per_inch; Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height; Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise; +Lisp_Object Qslice; Lisp_Object Qcenter; Lisp_Object Qmargin, Qpointer; extern Lisp_Object Qheight; @@ -1235,9 +1236,9 @@ and header-lines heights. */ int -pos_visible_p (w, charpos, fully, exact_mode_line_heights_p) - struct window *w; - int charpos, *fully, exact_mode_line_heights_p; +pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p) + struct window *w; + int charpos, *fully, *x, *y, exact_mode_line_heights_p; { struct it it; struct text_pos top; @@ -1285,14 +1286,27 @@ visible_p = 1; *fully = bottom_y <= it.last_visible_y; } + if (visible_p && x) + { + *x = it.current_x; + *y = max (top_y + it.max_ascent - it.ascent, window_top_y); + } } else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y) { + struct it it2; + + it2 = it; move_it_by_lines (&it, 1, 0); if (charpos < IT_CHARPOS (it)) { visible_p = 1; - *fully = 0; + if (x) + { + move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS); + *x = it2.current_x; + *y = it2.current_y + it2.max_ascent - it2.ascent; + } } } @@ -1300,6 +1314,7 @@ set_buffer_internal_1 (old_buffer); current_header_line_height = current_mode_line_height = -1; + return visible_p; } @@ -2067,7 +2082,8 @@ if (FRAME_FACE_CACHE (it->f)->used == 0) recompute_basic_faces (it->f); - /* Current value of the `space-width', and 'height' properties. */ + /* Current value of the `slice', `space-width', and 'height' properties. */ + it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil; it->space_width = Qnil; it->font_height = Qnil; @@ -3275,8 +3291,9 @@ } /* Reset those iterator values set from display property values. */ + it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil; + it->space_width = Qnil; it->font_height = Qnil; - it->space_width = Qnil; it->voffset = 0; /* We don't support recursive `display' properties, i.e. string @@ -3295,6 +3312,7 @@ && !EQ (XCAR (prop), Qimage) && !EQ (XCAR (prop), Qspace) && !EQ (XCAR (prop), Qwhen) + && !EQ (XCAR (prop), Qslice) && !EQ (XCAR (prop), Qspace_width) && !EQ (XCAR (prop), Qheight) && !EQ (XCAR (prop), Qraise) @@ -3491,6 +3509,30 @@ it->space_width = value; } else if (CONSP (prop) + && EQ (XCAR (prop), Qslice)) + { + /* `(slice X Y WIDTH HEIGHT)'. */ + Lisp_Object tem; + + if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) + return 0; + + if (tem = XCDR (prop), CONSP (tem)) + { + it->slice.x = XCAR (tem); + if (tem = XCDR (tem), CONSP (tem)) + { + it->slice.y = XCAR (tem); + if (tem = XCDR (tem), CONSP (tem)) + { + it->slice.width = XCAR (tem); + if (tem = XCDR (tem), CONSP (tem)) + it->slice.height = XCAR (tem); + } + } + } + } + else if (CONSP (prop) && EQ (XCAR (prop), Qraise) && CONSP (XCDR (prop))) { @@ -4331,6 +4373,7 @@ p->string_nchars = it->string_nchars; p->area = it->area; p->multibyte_p = it->multibyte_p; + p->slice = it->slice; p->space_width = it->space_width; p->font_height = it->font_height; p->voffset = it->voffset; @@ -4363,6 +4406,7 @@ it->string_nchars = p->string_nchars; it->area = p->area; it->multibyte_p = p->multibyte_p; + it->slice = p->slice; it->space_width = p->space_width; it->font_height = p->font_height; it->voffset = p->voffset; @@ -10762,15 +10806,14 @@ if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row)) return 1; - if (force_p) - return 0; - /* If the row the cursor is in is taller than the window's height, it's not clear what to do, so do nothing. */ window_height = window_box_height (w); if (row->height >= window_height) - return 1; - + { + if (!force_p || w->vscroll) + return 1; + } return 0; #if 0 @@ -14154,8 +14197,12 @@ face = FACE_FROM_ID (it->f, it->face_id); it->face_id = FACE_FOR_CHAR (it->f, face, 0); + if (it->max_ascent > 0 || it->max_descent > 0) + it->constrain_row_ascent_descent_p = 1; + PRODUCE_GLYPHS (it); + it->constrain_row_ascent_descent_p = 0; it->current_x = saved_x; it->object = saved_object; it->position = saved_pos; @@ -17302,6 +17349,7 @@ xassert (s->first_glyph->type == IMAGE_GLYPH); s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); xassert (s->img); + s->slice = s->first_glyph->slice; s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); s->font = s->face->font; s->width = s->first_glyph->pixel_width; @@ -18100,7 +18148,7 @@ if (it->voffset < 0) /* Increase the ascent so that we can display the text higher in the line. */ - it->ascent += abs (it->voffset); + it->ascent -= it->voffset; else /* Increase the descent so that we can display the text lower in the line. */ @@ -18120,6 +18168,7 @@ struct image *img; struct face *face; int face_ascent, glyph_ascent; + struct glyph_slice slice; xassert (it->what == IT_IMAGE); @@ -18143,19 +18192,68 @@ /* Make sure X resources of the image is loaded. */ prepare_image_for_display (it->f, img); - it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face); - it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; - it->pixel_width = img->width + 2 * img->hmargin; + slice.x = slice.y = 0; + slice.width = img->width; + slice.height = img->height; + + if (INTEGERP (it->slice.x)) + slice.x = XINT (it->slice.x); + else if (FLOATP (it->slice.x)) + slice.x = XFLOAT_DATA (it->slice.x) * img->width; + + if (INTEGERP (it->slice.y)) + slice.y = XINT (it->slice.y); + else if (FLOATP (it->slice.y)) + slice.y = XFLOAT_DATA (it->slice.y) * img->height; + + if (INTEGERP (it->slice.width)) + slice.width = XINT (it->slice.width); + else if (FLOATP (it->slice.width)) + slice.width = XFLOAT_DATA (it->slice.width) * img->width; + + if (INTEGERP (it->slice.height)) + slice.height = XINT (it->slice.height); + else if (FLOATP (it->slice.height)) + slice.height = XFLOAT_DATA (it->slice.height) * img->height; + + if (slice.x >= img->width) + slice.x = img->width; + if (slice.y >= img->height) + slice.y = img->height; + if (slice.x + slice.width >= img->width) + slice.width = img->width - slice.x; + if (slice.y + slice.height > img->height) + slice.height = img->height - slice.y; + + if (slice.width == 0 || slice.height == 0) + return; + + it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice); + + it->descent = slice.height - glyph_ascent; + if (slice.y == 0) + it->descent += img->vmargin; + if (slice.y + slice.height == img->height) + it->descent += img->vmargin; + it->phys_descent = it->descent; + + it->pixel_width = slice.width; + if (slice.x == 0) + it->pixel_width += img->hmargin; + if (slice.x + slice.width == img->width) + it->pixel_width += img->hmargin; /* It's quite possible for images to have an ascent greater than their height, so don't get confused in that case. */ if (it->descent < 0) it->descent = 0; +#if 0 /* this breaks image tiling */ /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */ face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f); if (face_ascent > it->ascent) it->ascent = it->phys_ascent = face_ascent; +#endif it->nglyphs = 1; @@ -18163,13 +18261,15 @@ { if (face->box_line_width > 0) { - it->ascent += face->box_line_width; - it->descent += face->box_line_width; - } - - if (it->start_of_box_run_p) + if (slice.y == 0) + it->ascent += face->box_line_width; + if (slice.y + slice.height == img->height) + it->descent += face->box_line_width; + } + + if (it->start_of_box_run_p && slice.x == 0) it->pixel_width += abs (face->box_line_width); - if (it->end_of_box_run_p) + if (it->end_of_box_run_p && slice.x + slice.width == img->width) it->pixel_width += abs (face->box_line_width); } @@ -18198,6 +18298,7 @@ glyph->glyph_not_available_p = 0; glyph->face_id = it->face_id; glyph->u.img_id = img->id; + glyph->slice = slice; glyph->font_type = FONT_TYPE_UNKNOWN; ++it->glyph_row->used[area]; } @@ -18491,6 +18592,7 @@ 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; @@ -18503,11 +18605,27 @@ else { it->glyph_not_available_p = 1; - it->phys_ascent = FONT_BASE (font) + boff; - it->phys_descent = FONT_DESCENT (font) - boff; + it->phys_ascent = it->ascent; + it->phys_descent = it->descent; it->pixel_width = FONT_WIDTH (font); } + if (it->constrain_row_ascent_descent_p) + { + if (it->descent > it->max_descent) + { + it->ascent += it->descent - it->max_descent; + it->descent = it->max_descent; + } + if (it->ascent> it->max_ascent) + { + it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent); + it->ascent = it->max_ascent; + } + it->phys_ascent = min (it->phys_ascent, it->ascent); + it->phys_descent = min (it->phys_descent, it->descent); + } + /* If this is a space inside a region of text with `space-width' property, change its width. */ stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); @@ -18540,6 +18658,14 @@ if (face->overline_p) it->ascent += 2; + if (it->constrain_row_ascent_descent_p) + { + if (it->ascent > it->max_ascent) + it->ascent = it->max_ascent; + if (it->descent > it->max_descent) + it->descent = it->max_descent; + } + take_vertical_position_into_account (it); /* If we have to actually produce glyphs, do it. */ @@ -18566,13 +18692,31 @@ } else if (it->char_to_display == '\n') { - /* A newline has no width but we need the height of the line. */ + /* A newline has no width but we need the height of the line. + But if previous part of the line set a height, don't + increase that height */ + it->pixel_width = 0; it->nglyphs = 0; - it->ascent = it->phys_ascent = FONT_BASE (font) + boff; - it->descent = it->phys_descent = FONT_DESCENT (font) - boff; - - if (face->box != FACE_NO_BOX + + it->ascent = FONT_BASE (font) + boff; + it->descent = FONT_DESCENT (font) - boff; + + if (it->max_ascent > 0 || it->max_descent > 0) + { + it->ascent = it->descent = 0; + } + else + { + it->ascent = FONT_BASE (font) + boff; + it->descent = FONT_DESCENT (font) - boff; + } + + it->phys_ascent = it->ascent; + it->phys_descent = it->descent; + + if ((it->max_ascent > 0 || it->max_descent > 0) + && face->box != FACE_NO_BOX && face->box_line_width > 0) { it->ascent += face->box_line_width; @@ -20547,7 +20691,9 @@ Lisp_Object image_map, hotspot; if ((image_map = Fplist_get (XCDR (img->spec), QCmap), !NILP (image_map)) - && (hotspot = find_hot_spot (image_map, dx, dy), + && (hotspot = find_hot_spot (image_map, + glyph->slice.x + dx, + glyph->slice.y + dy), CONSP (hotspot)) && (hotspot = XCDR (hotspot), CONSP (hotspot))) { @@ -21584,6 +21730,8 @@ staticpro (&Qspace_width); Qraise = intern ("raise"); staticpro (&Qraise); + Qslice = intern ("slice"); + staticpro (&Qslice); Qspace = intern ("space"); staticpro (&Qspace); Qmargin = intern ("margin");