aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey2004-04-23 14:44:11 +0000
committerKaroly Lorentey2004-04-23 14:44:11 +0000
commitced7ed5611e2a6e60a5ac7a97e165545843d0fa9 (patch)
tree85194b67c680d1a37af652a4b614a7e1fcd336ba /src
parent6ad9aaa961f1ac376bdaa1a5516d0481e6c7fafa (diff)
parentf24814e0e9806db8d01c16b8d8592d6e9b9ee481 (diff)
downloademacs-ced7ed5611e2a6e60a5ac7a97e165545843d0fa9.tar.gz
emacs-ced7ed5611e2a6e60a5ac7a97e165545843d0fa9.zip
Merged in changes from CVS trunk.
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-230 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-231 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-232 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-233 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-234 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-235 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-236 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-237 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-238 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-239 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-240 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-152
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog121
-rw-r--r--src/dispextern.h54
-rw-r--r--src/dispnew.c24
-rw-r--r--src/fns.c15
-rw-r--r--src/fontset.c59
-rw-r--r--src/image.c12
-rw-r--r--src/keyboard.c57
-rw-r--r--src/keymap.c6
-rw-r--r--src/lisp.h7
-rw-r--r--src/macterm.c174
-rw-r--r--src/makefile.w32-in2
-rw-r--r--src/w32term.c153
-rw-r--r--src/w32term.h1
-rw-r--r--src/window.c95
-rw-r--r--src/window.h6
-rw-r--r--src/xdisp.c202
-rw-r--r--src/xterm.c154
-rw-r--r--src/xterm.h1
18 files changed, 802 insertions, 341 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index babc20c57c5..6bc622c8bff 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,110 @@
12004-04-23 Kenichi Handa <handa@m17n.org>
2
3 * fontset.c (Finternal_char_font): If POSITION is nil, return
4 font for displaying CH with the default face.
5
62004-04-23 Juanma Barranquero <lektu@terra.es>
7
8 * makefile.w32-in: Add "-*- makefile -*-" mode tag.
9
102004-04-21 Stefan Monnier <monnier@iro.umontreal.ca>
11
12 * lisp.h (XINT) [EXPLICIT_SIGN_EXTEND && !NO_UNION_TYPE]:
13 Don't make assumptions about the relative place of i and val.
14 (EQ) [!NO_UNION_TYPE]: Don't forget to check the type match as well.
15
162004-04-21 Kim F. Storm <storm@cua.dk>
17
18 * dispextern.h (struct glyph_slice): New struct.
19 (struct glyph): New member slice.
20 (GLYPH_SLICE_EQUAL_P): New macro.
21 (GLYPH_EQUAL_P): Use it.
22 (struct glyph_string): New member slice.
23 (struct it_slice): New struct.
24 (struct it): New member slice, add member to stack too.
25 New member constrain_row_ascent_descent_p.
26 (image_ascent): Add prototype.
27
28 * dispnew.c (buffer_posn_from_coords): Return full image width
29 and height even for image slices (posn is relative to full image).
30 (marginal_area_string): Adjust x0,y0 for image slice.
31
32 * image.c (image_ascent): Add slice arg; calculate ascent for
33 image slice (or full image).
34
35 * keyboard.c (Fposn_at_x_y, Fposn_at_point): New defuns.
36 (syms_of_keyboard): Defsubr them.
37
38 * lisp.h (pos_visible_p): Fix prototype.
39
40 * macterm.c (x_draw_relief_rect): Add top_p and bot_p args.
41 (x_draw_glyph_string_box): Fix call to x_draw_relief_rect.
42 (x_draw_image_foreground, x_draw_image_relief)
43 (x_draw_image_foreground_1, x_draw_image_glyph_string):
44 Draw sliced images.
45
46 * w32term.c (w32_draw_relief_rect): Add top_p and bot_p args.
47 (x_draw_glyph_string_box): Fix call to x_draw_relief_rect.
48 (x_draw_image_foreground, x_draw_image_relief)
49 (w32_draw_image_foreground_1, x_draw_image_glyph_string):
50 Draw sliced images.
51
52 * w32term.h (image_ascent): Remove prototype.
53
54 * window.c (Fpos_visible_in_window_p): Return pixel position if
55 PARTIALLY arg is non-nil. Simplify. Doc fix.
56 (Fwindow_vscroll, Fset_window_vscroll): Add optional PIXEL_P arg
57 to return/set vscroll in pixels.
58
59 * window.h (Fwindow_vscroll, Fset_window_vscroll): Fix EXFUN.
60
61 * xdisp.c (Qslice): New variable.
62 (syms_of_xdisp): Intern and staticpro it.
63 (pos_visible_p): Return pixel position in new x and y args.
64 (init_iterator): Reset it->slice info.
65 (handle_display_prop): Parse (slice ...) property.
66 (push_it, pop_it): Save/restore slice info.
67 (make_cursor_line_fully_visible): Fix 2004-04-14 change. Do not
68 force repositioning of tall row if window is vscrolled, as that
69 would reset vscroll.
70 (append_space): Set it->constrain_row_ascent_descent_p to avoid
71 increasing row height if row is non-empty.
72 (fill_image_glyph_string): Copy slice info.
73 (take_vertical_position_into_account): Simplify.
74 (produce_image_glyph): Handle iterator slice info, setup glyph
75 slice info. Do not force minimum line height.
76 (x_produce_glyphs): If it->constrain_row_ascent_descent_p is set,
77 do not increase height (ascent/descent) of non-empty row when
78 adding normal character glyph; instead reduce glyph ascent/descent
79 appropriately; if row is higher than current glyph, adjust glyph
80 descent/ascent to reposition glyph within the existing row.
81 Likewise, when char is newline, only set ascent/descent if row is
82 currently empty.
83 (note_mouse_highlight): Handle hotspots with sliced image.
84
85 * xterm.c (x_draw_relief_rect): Add top_p and bot_p args.
86 (x_draw_glyph_string_box): Fix call to x_draw_relief_rect.
87 (x_draw_image_foreground, x_draw_image_relief)
88 (x_draw_image_foreground_1, x_draw_image_glyph_string):
89 Draw sliced images.
90
91 * xterm.h (image_ascent): Remove prototype.
92
932004-04-20 Stefan Monnier <monnier@iro.umontreal.ca>
94
95 * keymap.c (Fkey_description): Fix the usual int/Lisp_Object mixup.
96
972004-04-20 John Paul Wallington <jpw@gnu.org>
98
99 * fns.c (Fassoc, Feql): Fix indentation.
100
101 * fontset.c (regularize_fontname): Rename from regulalize_fontname.
102
1032004-04-19 John Paul Wallington <jpw@gnu.org>
104
105 * fns.c (Feql): New function.
106 (syms_of_fns): Defsubr it.
107
12004-04-18 Jason Rumney <jasonr@gnu.org> 1082004-04-18 Jason Rumney <jasonr@gnu.org>
2 109
3 * w32select.c (Fw32_set_clipboard_data): Get sequence number 110 * w32select.c (Fw32_set_clipboard_data): Get sequence number
@@ -8461,16 +8568,16 @@
84612002-07-11 Juanma Barranquero <lektu@terra.es> 85682002-07-11 Juanma Barranquero <lektu@terra.es>
8462 8569
8463 * alloc.c, buffer.c, bytecode.c, callint.c, callproc.c, coding.c, 8570 * alloc.c, buffer.c, bytecode.c, callint.c, callproc.c, coding.c,
8464 * composite.c, dired.c, dispnew.c, editfns.c, emacs.c, eval.c, 8571 composite.c, dired.c, dispnew.c, editfns.c, emacs.c, eval.c,
8465 * fileio.c, fns.c, insdel.c, keyboard.c, keymap.c, lread.c, macfns.c, 8572 fileio.c, fns.c, insdel.c, keyboard.c, keymap.c, lread.c, macfns.c,
8466 * macmenu.c, macros.c, minibuf.c, print.c, process.c, sound.c, 8573 macmenu.c, macros.c, minibuf.c, print.c, process.c, sound.c,
8467 * textprop.c, w32fns.c, w32menu.c, window.c, xfaces.c, xfns.c, 8574 textprop.c, w32fns.c, w32menu.c, window.c, xfaces.c, xfns.c,
8468 * xmenu.c, xselect.c, xterm.c: Use SPECPDL_INDEX wherever makes sense. 8575 xmenu.c, xselect.c, xterm.c: Use SPECPDL_INDEX wherever makes sense.
8469 8576
84702002-07-10 Juanma Barranquero <lektu@terra.es> 85772002-07-10 Juanma Barranquero <lektu@terra.es>
8471 8578
8472 * lisp.h (SPECPDL_INDEX): Rename from BINDING_STACK_SIZE. All callers 8579 * lisp.h (SPECPDL_INDEX): Rename from BINDING_STACK_SIZE.
8473 changed. 8580 All callers changed.
8474 8581
84752002-07-09 Stefan Monnier <monnier@cs.yale.edu> 85822002-07-09 Stefan Monnier <monnier@cs.yale.edu>
8476 8583
diff --git a/src/dispextern.h b/src/dispextern.h
index 3b71002a304..a3fc28e2491 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -274,6 +274,17 @@ enum glyph_type
274}; 274};
275 275
276 276
277/* Structure describing how to use partial glyphs (images slicing) */
278
279struct glyph_slice
280{
281 unsigned x : 16;
282 unsigned y : 16;
283 unsigned width : 16;
284 unsigned height : 16;
285};
286
287
277/* Glyphs. 288/* Glyphs.
278 289
279 Be extra careful when changing this structure! Esp. make sure that 290 Be extra careful when changing this structure! Esp. make sure that
@@ -352,6 +363,8 @@ struct glyph
352 w32_char_font_type. Otherwise it equals FONT_TYPE_UNKNOWN. */ 363 w32_char_font_type. Otherwise it equals FONT_TYPE_UNKNOWN. */
353 unsigned font_type : 3; 364 unsigned font_type : 3;
354 365
366 struct glyph_slice slice;
367
355 /* A union of sub-structures for different glyph types. */ 368 /* A union of sub-structures for different glyph types. */
356 union 369 union
357 { 370 {
@@ -390,11 +403,20 @@ struct glyph
390#define CHAR_GLYPH_SPACE_P(GLYPH) \ 403#define CHAR_GLYPH_SPACE_P(GLYPH) \
391 (GLYPH_FROM_CHAR_GLYPH ((GLYPH)) == SPACEGLYPH) 404 (GLYPH_FROM_CHAR_GLYPH ((GLYPH)) == SPACEGLYPH)
392 405
406/* Are glyph slices of glyphs *X and *Y equal */
407
408#define GLYPH_SLICE_EQUAL_P(X, Y) \
409 ((X)->slice.x == (Y)->slice.x \
410 && (X)->slice.y == (Y)->slice.y \
411 && (X)->slice.width == (Y)->slice.width \
412 && (X)->slice.height == (Y)->slice.height)
413
393/* Are glyphs *X and *Y displayed equal? */ 414/* Are glyphs *X and *Y displayed equal? */
394 415
395#define GLYPH_EQUAL_P(X, Y) \ 416#define GLYPH_EQUAL_P(X, Y) \
396 ((X)->type == (Y)->type \ 417 ((X)->type == (Y)->type \
397 && (X)->u.val == (Y)->u.val \ 418 && (X)->u.val == (Y)->u.val \
419 && GLYPH_SLICE_EQUAL_P (X, Y) \
398 && (X)->face_id == (Y)->face_id \ 420 && (X)->face_id == (Y)->face_id \
399 && (X)->padding_p == (Y)->padding_p \ 421 && (X)->padding_p == (Y)->padding_p \
400 && (X)->left_box_line_p == (Y)->left_box_line_p \ 422 && (X)->left_box_line_p == (Y)->left_box_line_p \
@@ -1139,6 +1161,9 @@ struct glyph_string
1139 /* Image, if any. */ 1161 /* Image, if any. */
1140 struct image *img; 1162 struct image *img;
1141 1163
1164 /* Slice */
1165 struct glyph_slice slice;
1166
1142 struct glyph_string *next, *prev; 1167 struct glyph_string *next, *prev;
1143}; 1168};
1144 1169
@@ -1607,7 +1632,7 @@ extern int face_change_count;
1607 width and height of the bitmap, DH is the height adjustment (if 1632 width and height of the bitmap, DH is the height adjustment (if
1608 bitmap is periodic). X and Y are frame coordinates of the area to 1633 bitmap is periodic). X and Y are frame coordinates of the area to
1609 display the bitmap, DY is relative offset of the bitmap into that 1634 display the bitmap, DY is relative offset of the bitmap into that
1610 area. BX, NX, BY, NY specifies the area to clear if the bitmap 1635 area. BX, NX, BY, NY specifies the area to clear if the bitmap
1611 does not fill the entire area. FACE is the fringe face. */ 1636 does not fill the entire area. FACE is the fringe face. */
1612 1637
1613struct draw_fringe_bitmap_params 1638struct draw_fringe_bitmap_params
@@ -1718,6 +1743,15 @@ enum prop_idx
1718}; 1743};
1719 1744
1720 1745
1746struct it_slice
1747{
1748 Lisp_Object x;
1749 Lisp_Object y;
1750 Lisp_Object width;
1751 Lisp_Object height;
1752};
1753
1754
1721struct it 1755struct it
1722{ 1756{
1723 /* The window in which we iterate over current_buffer (or a string). */ 1757 /* The window in which we iterate over current_buffer (or a string). */
@@ -1830,6 +1864,7 @@ struct it
1830 unsigned multibyte_p : 1; 1864 unsigned multibyte_p : 1;
1831 unsigned string_from_display_prop_p : 1; 1865 unsigned string_from_display_prop_p : 1;
1832 unsigned display_ellipsis_p : 1; 1866 unsigned display_ellipsis_p : 1;
1867 struct it_slice slice;
1833 Lisp_Object space_width; 1868 Lisp_Object space_width;
1834 short voffset; 1869 short voffset;
1835 Lisp_Object font_height; 1870 Lisp_Object font_height;
@@ -1884,6 +1919,10 @@ struct it
1884 skipped due to selective display. */ 1919 skipped due to selective display. */
1885 unsigned face_before_selective_p : 1; 1920 unsigned face_before_selective_p : 1;
1886 1921
1922 /* If 1, adjust current glyph so it does not increase current row
1923 descent/ascent. */
1924 unsigned constrain_row_ascent_descent_p : 1;
1925
1887 /* The ID of the default face to use. One of DEFAULT_FACE_ID, 1926 /* The ID of the default face to use. One of DEFAULT_FACE_ID,
1888 MODE_LINE_FACE_ID, etc, depending on what we are displaying. */ 1927 MODE_LINE_FACE_ID, etc, depending on what we are displaying. */
1889 int base_face_id; 1928 int base_face_id;
@@ -1909,6 +1948,9 @@ struct it
1909 /* If what == IT_IMAGE, the id of the image to display. */ 1948 /* If what == IT_IMAGE, the id of the image to display. */
1910 int image_id; 1949 int image_id;
1911 1950
1951 /* Values from `slice' property. */
1952 struct it_slice slice;
1953
1912 /* Value of the `space-width' property, if any; nil if none. */ 1954 /* Value of the `space-width' property, if any; nil if none. */
1913 Lisp_Object space_width; 1955 Lisp_Object space_width;
1914 1956
@@ -2176,7 +2218,7 @@ struct redisplay_interface
2176 int (*encode_char) P_ ((int c, XChar2b *char2b, 2218 int (*encode_char) P_ ((int c, XChar2b *char2b,
2177 struct font_info *font_into, int *two_byte_p)); 2219 struct font_info *font_into, int *two_byte_p));
2178 2220
2179/* Compute left and right overhang of glyph string S. 2221/* Compute left and right overhang of glyph string S.
2180 A NULL pointer if platform does not support this. */ 2222 A NULL pointer if platform does not support this. */
2181 void (*compute_glyph_string_overhangs) P_ ((struct glyph_string *s)); 2223 void (*compute_glyph_string_overhangs) P_ ((struct glyph_string *s));
2182 2224
@@ -2204,7 +2246,7 @@ struct redisplay_interface
2204 void (*draw_vertical_window_border) P_ ((struct window *w, 2246 void (*draw_vertical_window_border) P_ ((struct window *w,
2205 int x, int y0, int y1)); 2247 int x, int y0, int y1));
2206 2248
2207/* Shift display of frame F to make room for inserted glyphs. 2249/* Shift display of frame F to make room for inserted glyphs.
2208 The area at pixel (X,Y) of width WIDTH and height HEIGHT is 2250 The area at pixel (X,Y) of width WIDTH and height HEIGHT is
2209 shifted right by SHIFT_BY pixels. */ 2251 shifted right by SHIFT_BY pixels. */
2210 void (*shift_glyphs_for_insert) P_ ((struct frame *f, 2252 void (*shift_glyphs_for_insert) P_ ((struct frame *f,
@@ -2519,7 +2561,7 @@ extern void add_to_log P_ ((char *, Lisp_Object, Lisp_Object));
2519extern int help_echo_showing_p; 2561extern int help_echo_showing_p;
2520extern int current_mode_line_height, current_header_line_height; 2562extern int current_mode_line_height, current_header_line_height;
2521extern Lisp_Object help_echo_string, help_echo_window; 2563extern Lisp_Object help_echo_string, help_echo_window;
2522extern Lisp_Object help_echo_object, previous_help_echo_string; 2564extern Lisp_Object help_echo_object, previous_help_echo_string;
2523extern int help_echo_pos; 2565extern int help_echo_pos;
2524extern struct frame *last_mouse_frame; 2566extern struct frame *last_mouse_frame;
2525extern int last_tool_bar_item; 2567extern int last_tool_bar_item;
@@ -2629,6 +2671,8 @@ unsigned long image_background P_ ((struct image *, struct frame *,
2629int image_background_transparent P_ ((struct image *, struct frame *, 2671int image_background_transparent P_ ((struct image *, struct frame *,
2630 XImagePtr_or_DC mask)); 2672 XImagePtr_or_DC mask));
2631 2673
2674int image_ascent P_ ((struct image *, struct face *, struct glyph_slice *));
2675
2632#endif 2676#endif
2633 2677
2634/* Defined in sysdep.c */ 2678/* Defined in sysdep.c */
@@ -2733,7 +2777,7 @@ extern int required_matrix_height P_ ((struct window *));
2733extern Lisp_Object buffer_posn_from_coords P_ ((struct window *, 2777extern Lisp_Object buffer_posn_from_coords P_ ((struct window *,
2734 int *, int *, 2778 int *, int *,
2735 struct display_pos *, 2779 struct display_pos *,
2736 Lisp_Object *, 2780 Lisp_Object *,
2737 int *, int *, int *, int *)); 2781 int *, int *, int *, int *));
2738extern Lisp_Object mode_line_string P_ ((struct window *, enum window_part, 2782extern Lisp_Object mode_line_string P_ ((struct window *, enum window_part,
2739 int *, int *, int *, 2783 int *, int *, int *,
diff --git a/src/dispnew.c b/src/dispnew.c
index f65a81fc5ef..fb78aa9c275 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5740,6 +5740,9 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
5740 struct text_pos startp; 5740 struct text_pos startp;
5741 Lisp_Object string; 5741 Lisp_Object string;
5742 struct glyph_row *row; 5742 struct glyph_row *row;
5743#ifdef HAVE_WINDOW_SYSTEM
5744 struct image *img = 0;
5745#endif
5743 int x0, x1; 5746 int x0, x1;
5744 5747
5745 current_buffer = XBUFFER (w->buffer); 5748 current_buffer = XBUFFER (w->buffer);
@@ -5765,7 +5768,6 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
5765#ifdef HAVE_WINDOW_SYSTEM 5768#ifdef HAVE_WINDOW_SYSTEM
5766 if (it.what == IT_IMAGE) 5769 if (it.what == IT_IMAGE)
5767 { 5770 {
5768 struct image *img;
5769 if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL 5771 if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
5770 && !NILP (img->spec)) 5772 && !NILP (img->spec))
5771 *object = img->spec; 5773 *object = img->spec;
@@ -5778,12 +5780,22 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
5778 if (it.hpos < row->used[TEXT_AREA]) 5780 if (it.hpos < row->used[TEXT_AREA])
5779 { 5781 {
5780 struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos; 5782 struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
5781 *width = glyph->pixel_width;
5782 *height = glyph->ascent + glyph->descent;
5783#ifdef HAVE_WINDOW_SYSTEM 5783#ifdef HAVE_WINDOW_SYSTEM
5784 if (glyph->type == IMAGE_GLYPH) 5784 if (img)
5785 *dy -= row->ascent - glyph->ascent; 5785 {
5786 *dy -= row->ascent - glyph->ascent;
5787 *dx += glyph->slice.x;
5788 *dy += glyph->slice.y;
5789 /* Image slices positions are still relative to the entire image */
5790 *width = img->width;
5791 *height = img->height;
5792 }
5793 else
5786#endif 5794#endif
5795 {
5796 *width = glyph->pixel_width;
5797 *height = glyph->ascent + glyph->descent;
5798 }
5787 } 5799 }
5788 else 5800 else
5789 { 5801 {
@@ -5949,6 +5961,8 @@ marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
5949 if (img != NULL) 5961 if (img != NULL)
5950 *object = img->spec; 5962 *object = img->spec;
5951 y0 -= row->ascent - glyph->ascent; 5963 y0 -= row->ascent - glyph->ascent;
5964 x0 += glyph->slice.x;
5965 y0 += glyph->slice.y;
5952 } 5966 }
5953#endif 5967#endif
5954 } 5968 }
diff --git a/src/fns.c b/src/fns.c
index adb262ee11d..bb215317864 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1560,7 +1560,7 @@ assq_no_quit (key, list)
1560DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0, 1560DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
1561 doc: /* Return non-nil if KEY is `equal' to the car of an element of LIST. 1561 doc: /* Return non-nil if KEY is `equal' to the car of an element of LIST.
1562The value is actually the first element of LIST whose car equals KEY. */) 1562The value is actually the first element of LIST whose car equals KEY. */)
1563 (key, list) 1563 (key, list)
1564 Lisp_Object key, list; 1564 Lisp_Object key, list;
1565{ 1565{
1566 Lisp_Object result, car; 1566 Lisp_Object result, car;
@@ -2135,6 +2135,18 @@ The PLIST is modified by side effects. */)
2135 return plist; 2135 return plist;
2136} 2136}
2137 2137
2138DEFUN ("eql", Feql, Seql, 2, 2, 0,
2139 doc: /* Return t if the two args are the same Lisp object.
2140Floating-point numbers of equal value are `eql', but they may not be `eq'. */)
2141 (obj1, obj2)
2142 Lisp_Object obj1, obj2;
2143{
2144 if (FLOATP (obj1))
2145 return internal_equal (obj1, obj2, 0, 0) ? Qt : Qnil;
2146 else
2147 return EQ (obj1, obj2) ? Qt : Qnil;
2148}
2149
2138DEFUN ("equal", Fequal, Sequal, 2, 2, 0, 2150DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
2139 doc: /* Return t if two Lisp objects have similar structure and contents. 2151 doc: /* Return t if two Lisp objects have similar structure and contents.
2140They must have the same data type. 2152They must have the same data type.
@@ -5740,6 +5752,7 @@ used if both `use-dialog-box' and this variable are non-nil. */);
5740 defsubr (&Sput); 5752 defsubr (&Sput);
5741 defsubr (&Slax_plist_get); 5753 defsubr (&Slax_plist_get);
5742 defsubr (&Slax_plist_put); 5754 defsubr (&Slax_plist_put);
5755 defsubr (&Seql);
5743 defsubr (&Sequal); 5756 defsubr (&Sequal);
5744 defsubr (&Sequal_including_properties); 5757 defsubr (&Sequal_including_properties);
5745 defsubr (&Sfillarray); 5758 defsubr (&Sfillarray);
diff --git a/src/fontset.c b/src/fontset.c
index ad9dd3ccd2f..aae6b9296ae 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -195,7 +195,7 @@ static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
195static int fontset_id_valid_p P_ ((int)); 195static int fontset_id_valid_p P_ ((int));
196static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); 196static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
197static Lisp_Object font_family_registry P_ ((Lisp_Object, int)); 197static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
198static Lisp_Object regulalize_fontname P_ ((Lisp_Object)); 198static Lisp_Object regularize_fontname P_ ((Lisp_Object));
199 199
200 200
201/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/ 201/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
@@ -1043,7 +1043,7 @@ check_fontset_name (name)
1043 string, maybe change FONTNAME to (FAMILY . REGISTRY). */ 1043 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1044 1044
1045static Lisp_Object 1045static Lisp_Object
1046regulalize_fontname (Lisp_Object fontname) 1046regularize_fontname (Lisp_Object fontname)
1047{ 1047{
1048 Lisp_Object family, registry; 1048 Lisp_Object family, registry;
1049 1049
@@ -1133,7 +1133,7 @@ name of a font, REGISTRY is a registry name of a font. */)
1133 if (!NILP (frame)) 1133 if (!NILP (frame))
1134 CHECK_LIVE_FRAME (frame); 1134 CHECK_LIVE_FRAME (frame);
1135 1135
1136 elt = Fcons (make_number (from), regulalize_fontname (fontname)); 1136 elt = Fcons (make_number (from), regularize_fontname (fontname));
1137 for (; from <= to; from++) 1137 for (; from <= to; from++)
1138 FONTSET_SET (fontset, from, elt); 1138 FONTSET_SET (fontset, from, elt);
1139 Foptimize_char_table (fontset); 1139 Foptimize_char_table (fontset);
@@ -1212,7 +1212,10 @@ If the named font is not yet loaded, return nil. */)
1212/* Return a cons (FONT-NAME . GLYPH-CODE). 1212/* Return a cons (FONT-NAME . GLYPH-CODE).
1213 FONT-NAME is the font name for the character at POSITION in the current 1213 FONT-NAME is the font name for the character at POSITION in the current
1214 buffer. This is computed from all the text properties and overlays 1214 buffer. This is computed from all the text properties and overlays
1215 that apply to POSITION. 1215 that apply to POSITION. POSTION may be nil, in which case,
1216 FONT-NAME is the font name for display the character CH with the
1217 default face.
1218
1216 GLYPH-CODE is the glyph code in the font to use for the character. 1219 GLYPH-CODE is the glyph code in the font to use for the character.
1217 1220
1218 If the 2nd optional arg CH is non-nil, it is a character to check 1221 If the 2nd optional arg CH is non-nil, it is a character to check
@@ -1225,7 +1228,8 @@ If the named font is not yet loaded, return nil. */)
1225 1228
1226 (2) The character code is invalid. 1229 (2) The character code is invalid.
1227 1230
1228 (3) The current buffer is not displayed in any window. 1231 (3) If POSITION is not nil, and the current buffer is not displayed
1232 in any window.
1229 1233
1230 In addition, the returned font name may not take into account of 1234 In addition, the returned font name may not take into account of
1231 such redisplay engine hooks as what used in jit-lock-mode if 1235 such redisplay engine hooks as what used in jit-lock-mode if
@@ -1240,31 +1244,42 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
1240 int pos, pos_byte, dummy; 1244 int pos, pos_byte, dummy;
1241 int face_id; 1245 int face_id;
1242 int c, code; 1246 int c, code;
1243 Lisp_Object window;
1244 struct window *w;
1245 struct frame *f; 1247 struct frame *f;
1246 struct face *face; 1248 struct face *face;
1247 1249
1248 CHECK_NUMBER_COERCE_MARKER (position); 1250 if (NILP (position))
1249 pos = XINT (position);
1250 if (pos < BEGV || pos >= ZV)
1251 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1252 pos_byte = CHAR_TO_BYTE (pos);
1253 if (NILP (ch))
1254 c = FETCH_CHAR (pos_byte);
1255 else
1256 { 1251 {
1257 CHECK_NATNUM (ch); 1252 CHECK_NATNUM (ch);
1258 c = XINT (ch); 1253 c = XINT (ch);
1254 f = XFRAME (selected_frame);
1255 face_id = DEFAULT_FACE_ID;
1256 }
1257 else
1258 {
1259 Lisp_Object window;
1260 struct window *w;
1261
1262 CHECK_NUMBER_COERCE_MARKER (position);
1263 pos = XINT (position);
1264 if (pos < BEGV || pos >= ZV)
1265 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1266 pos_byte = CHAR_TO_BYTE (pos);
1267 if (NILP (ch))
1268 c = FETCH_CHAR (pos_byte);
1269 else
1270 {
1271 CHECK_NATNUM (ch);
1272 c = XINT (ch);
1273 }
1274 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1275 if (NILP (window))
1276 return Qnil;
1277 w = XWINDOW (window);
1278 f = XFRAME (w->frame);
1279 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1259 } 1280 }
1260 if (! CHAR_VALID_P (c, 0)) 1281 if (! CHAR_VALID_P (c, 0))
1261 return Qnil; 1282 return Qnil;
1262 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1263 if (NILP (window))
1264 return Qnil;
1265 w = XWINDOW (window);
1266 f = XFRAME (w->frame);
1267 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1268 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c); 1283 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1269 face = FACE_FROM_ID (f, face_id); 1284 face = FACE_FROM_ID (f, face_id);
1270 if (! face->font || ! face->font_name) 1285 if (! face->font || ! face->font_name)
@@ -1540,7 +1555,7 @@ It is intended that this function is called only from
1540 1555
1541 elt = XCAR (tail); 1556 elt = XCAR (tail);
1542 target = Fcar (elt); 1557 target = Fcar (elt);
1543 elt = Fcons (Qnil, regulalize_fontname (Fcdr (elt))); 1558 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
1544 if (! CHAR_TABLE_P (target)) 1559 if (! CHAR_TABLE_P (target))
1545 { 1560 {
1546 int charset, c; 1561 int charset, c;
diff --git a/src/image.c b/src/image.c
index 66b004220d1..4c2bdb440e8 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1076,13 +1076,21 @@ prepare_image_for_display (f, img)
1076 drawn in face FACE. */ 1076 drawn in face FACE. */
1077 1077
1078int 1078int
1079image_ascent (img, face) 1079image_ascent (img, face, slice)
1080 struct image *img; 1080 struct image *img;
1081 struct face *face; 1081 struct face *face;
1082 struct glyph_slice *slice;
1082{ 1083{
1083 int height = img->height + img->vmargin; 1084 int height;
1084 int ascent; 1085 int ascent;
1085 1086
1087 if (slice->height == img->height)
1088 height = img->height + img->vmargin;
1089 else if (slice->y == 0)
1090 height = slice->height + img->vmargin;
1091 else
1092 height = slice->height;
1093
1086 if (img->ascent == CENTERED_IMAGE_ASCENT) 1094 if (img->ascent == CENTERED_IMAGE_ASCENT)
1087 { 1095 {
1088 if (face->font) 1096 if (face->font)
diff --git a/src/keyboard.c b/src/keyboard.c
index 330eef60c1e..2a1c1c89e87 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -10618,6 +10618,61 @@ The elements of this list correspond to the arguments of
10618 return Flist (sizeof (val) / sizeof (val[0]), val); 10618 return Flist (sizeof (val) / sizeof (val[0]), val);
10619} 10619}
10620 10620
10621DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 3, 0,
10622 doc: /* Return position information for pixel coordinates X and Y.
10623By default, X and Y are relative to text area of the selected window.
10624Optional third arg FRAME_OR_WINDOW non-nil specifies frame or window.
10625
10626The return value is similar to a mouse click position:
10627 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
10628 IMAGE (DX . DY) (WIDTH . HEIGHT))
10629The `posn-' functions access elements of such lists. */)
10630 (x, y, frame_or_window)
10631 Lisp_Object x, y, frame_or_window;
10632{
10633 if (NILP (frame_or_window))
10634 frame_or_window = selected_window;
10635
10636 if (WINDOWP (frame_or_window))
10637 {
10638 struct window *w;
10639
10640 CHECK_LIVE_WINDOW (frame_or_window);
10641
10642 w = XWINDOW (frame_or_window);
10643 XSETINT (x, (WINDOW_TO_FRAME_PIXEL_X (w, XINT (x))
10644 + window_box_left_offset (w, TEXT_AREA)));
10645 XSETINT (y, WINDOW_TO_FRAME_PIXEL_Y (w, XINT (y)));
10646 frame_or_window = w->frame;
10647 }
10648
10649 CHECK_LIVE_FRAME (frame_or_window);
10650
10651 return make_lispy_position (XFRAME (frame_or_window), &x, &y, 0);
10652}
10653
10654DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0,
10655 doc: /* Return position information for buffer POS in WINDOW.
10656POS defaults to point in WINDOW; WINDOW defaults to the selected window.
10657
10658Return nil if position is not visible in window. Otherwise,
10659the return value is similar to that returned by event-start for
10660a mouse click at the upper left corner of the glyph corresponding
10661to the given buffer position:
10662 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
10663 IMAGE (DX . DY) (WIDTH . HEIGHT))
10664The `posn-' functions access elements of such lists. */*/)
10665 (pos, window)
10666 Lisp_Object pos, window;
10667{
10668 Lisp_Object tem;
10669
10670 tem = Fpos_visible_in_window_p (pos, window, Qt);
10671 if (!NILP (tem))
10672 tem = Fposn_at_x_y (XCAR (tem), XCAR (XCDR (tem)), window);
10673 return tem;
10674}
10675
10621 10676
10622/* 10677/*
10623 * Set up a new kboard object with reasonable initial values. 10678 * Set up a new kboard object with reasonable initial values.
@@ -11047,6 +11102,8 @@ syms_of_keyboard ()
11047 defsubr (&Sset_input_mode); 11102 defsubr (&Sset_input_mode);
11048 defsubr (&Scurrent_input_mode); 11103 defsubr (&Scurrent_input_mode);
11049 defsubr (&Sexecute_extended_command); 11104 defsubr (&Sexecute_extended_command);
11105 defsubr (&Sposn_at_point);
11106 defsubr (&Sposn_at_x_y);
11050 11107
11051 DEFVAR_LISP ("last-command-char", &last_command_char, 11108 DEFVAR_LISP ("last-command-char", &last_command_char,
11052 doc: /* Last input event that was part of a command. */); 11109 doc: /* Last input event that was part of a command. */);
diff --git a/src/keymap.c b/src/keymap.c
index 0e68c38d677..a4aeea8ae63 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1959,14 +1959,14 @@ spaces are put between sequence elements, etc. */)
1959 int len = 0; 1959 int len = 0;
1960 int i, i_byte; 1960 int i, i_byte;
1961 Lisp_Object *args; 1961 Lisp_Object *args;
1962 int size = Flength (keys); 1962 int size = XINT (Flength (keys));
1963 Lisp_Object list; 1963 Lisp_Object list;
1964 Lisp_Object sep = build_string (" "); 1964 Lisp_Object sep = build_string (" ");
1965 Lisp_Object key; 1965 Lisp_Object key;
1966 int add_meta = 0; 1966 int add_meta = 0;
1967 1967
1968 if (!NILP (prefix)) 1968 if (!NILP (prefix))
1969 size += Flength (prefix); 1969 size += XINT (Flength (prefix));
1970 1970
1971 /* This has one extra element at the end that we don't pass to Fconcat. */ 1971 /* This has one extra element at the end that we don't pass to Fconcat. */
1972 args = (Lisp_Object *) alloca (size * 4 * sizeof (Lisp_Object)); 1972 args = (Lisp_Object *) alloca (size * 4 * sizeof (Lisp_Object));
@@ -1997,7 +1997,7 @@ spaces are put between sequence elements, etc. */)
1997 else if (VECTORP (list)) 1997 else if (VECTORP (list))
1998 size = XVECTOR (list)->size; 1998 size = XVECTOR (list)->size;
1999 else if (CONSP (list)) 1999 else if (CONSP (list))
2000 size = Flength (list); 2000 size = XINT (Flength (list));
2001 else 2001 else
2002 wrong_type_argument (Qarrayp, list); 2002 wrong_type_argument (Qarrayp, list);
2003 2003
diff --git a/src/lisp.h b/src/lisp.h
index 48b9c0c7912..bc67f4dbe67 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -382,7 +382,7 @@ enum pvec_type
382 382
383#ifdef EXPLICIT_SIGN_EXTEND 383#ifdef EXPLICIT_SIGN_EXTEND
384/* Make sure we sign-extend; compilers have been known to fail to do so. */ 384/* Make sure we sign-extend; compilers have been known to fail to do so. */
385#define XINT(a) (((a).i << (BITS_PER_EMACS_INT - VALBITS)) \ 385#define XINT(a) (((a).s.val << (BITS_PER_EMACS_INT - VALBITS)) \
386 >> (BITS_PER_EMACS_INT - VALBITS)) 386 >> (BITS_PER_EMACS_INT - VALBITS))
387#else 387#else
388#define XINT(a) ((a).s.val) 388#define XINT(a) ((a).s.val)
@@ -400,7 +400,7 @@ enum pvec_type
400extern Lisp_Object make_number (); 400extern Lisp_Object make_number ();
401#endif 401#endif
402 402
403#define EQ(x, y) ((x).s.val == (y).s.val) 403#define EQ(x, y) ((x).s.val == (y).s.val && (x).s.type == (y).s.type)
404 404
405#endif /* NO_UNION_TYPE */ 405#endif /* NO_UNION_TYPE */
406 406
@@ -2391,7 +2391,8 @@ void set_frame_cursor_types P_ ((struct frame *, Lisp_Object));
2391extern void syms_of_xdisp P_ ((void)); 2391extern void syms_of_xdisp P_ ((void));
2392extern void init_xdisp P_ ((void)); 2392extern void init_xdisp P_ ((void));
2393extern Lisp_Object safe_eval P_ ((Lisp_Object)); 2393extern Lisp_Object safe_eval P_ ((Lisp_Object));
2394extern int pos_visible_p P_ ((struct window *, int, int *, int)); 2394extern int pos_visible_p P_ ((struct window *, int, int *,
2395 int *, int *, int));
2395 2396
2396/* Defined in vm-limit.c. */ 2397/* Defined in vm-limit.c. */
2397extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ())); 2398extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
diff --git a/src/macterm.c b/src/macterm.c
index 93f3e734724..88f5fce468c 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -294,7 +294,6 @@ void deactivate_scroll_bars (FRAME_PTR);
294 294
295static int is_emacs_window (WindowPtr); 295static int is_emacs_window (WindowPtr);
296 296
297extern int image_ascent (struct image *, struct face *);
298int x_bitmap_icon (struct frame *, Lisp_Object); 297int x_bitmap_icon (struct frame *, Lisp_Object);
299void x_make_frame_visible (struct frame *); 298void x_make_frame_visible (struct frame *);
300 299
@@ -311,7 +310,7 @@ XFreePixmap (display, pixmap)
311 Display *display; /* not used */ 310 Display *display; /* not used */
312 Pixmap pixmap; 311 Pixmap pixmap;
313{ 312{
314 DisposeGWorld (pixmap); 313 DisposeGWorld (pixmap);
315} 314}
316 315
317 316
@@ -1283,7 +1282,7 @@ mac_draw_vertical_window_border (w, x, y0, y1)
1283 int x, y0, y1; 1282 int x, y0, y1;
1284{ 1283{
1285 struct frame *f = XFRAME (WINDOW_FRAME (w)); 1284 struct frame *f = XFRAME (WINDOW_FRAME (w));
1286 1285
1287 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), 1286 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
1288 f->output_data.mac->normal_gc, x, y0, x, y1); 1287 f->output_data.mac->normal_gc, x, y0, x, y1);
1289} 1288}
@@ -1525,7 +1524,7 @@ x_draw_fringe_bitmap (w, row, p)
1525 : face->foreground); 1524 : face->foreground);
1526 gcv.background = face->background; 1525 gcv.background = face->background;
1527 1526
1528 mac_draw_bitmap (display, window, &gcv, p->x, p->y, 1527 mac_draw_bitmap (display, window, &gcv, p->x, p->y,
1529 p->wd, p->h, bits, p->overlay_p); 1528 p->wd, p->h, bits, p->overlay_p);
1530 } 1529 }
1531 1530
@@ -1759,7 +1758,8 @@ static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap));
1759static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, 1758static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
1760 int, int, int)); 1759 int, int, int));
1761static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int, 1760static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
1762 int, int, int, int, Rect *)); 1761 int, int, int, int, int, int,
1762 Rect *));
1763static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, 1763static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
1764 int, int, int, Rect *)); 1764 int, int, int, Rect *));
1765 1765
@@ -2483,9 +2483,10 @@ x_setup_relief_colors (s)
2483 2483
2484static void 2484static void
2485x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, 2485x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2486 raised_p, left_p, right_p, clip_rect) 2486 raised_p, top_p, bot_p, left_p, right_p, clip_rect)
2487 struct frame *f; 2487 struct frame *f;
2488 int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p; 2488 int left_x, top_y, right_x, bottom_y, width;
2489 int top_p, bot_p, left_p, right_p, raised_p;
2489 Rect *clip_rect; 2490 Rect *clip_rect;
2490{ 2491{
2491 Display *dpy = FRAME_MAC_DISPLAY (f); 2492 Display *dpy = FRAME_MAC_DISPLAY (f);
@@ -2500,10 +2501,11 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2500 mac_set_clip_rectangle (dpy, window, clip_rect); 2501 mac_set_clip_rectangle (dpy, window, clip_rect);
2501 2502
2502 /* Top. */ 2503 /* Top. */
2503 for (i = 0; i < width; ++i) 2504 if (top_p)
2504 XDrawLine (dpy, window, gc, 2505 for (i = 0; i < width; ++i)
2505 left_x + i * left_p, top_y + i, 2506 XDrawLine (dpy, window, gc,
2506 right_x - i * right_p, top_y + i); 2507 left_x + i * left_p, top_y + i,
2508 right_x - i * right_p, top_y + i);
2507 2509
2508 /* Left. */ 2510 /* Left. */
2509 if (left_p) 2511 if (left_p)
@@ -2520,10 +2522,11 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2520 clip_rect); 2522 clip_rect);
2521 2523
2522 /* Bottom. */ 2524 /* Bottom. */
2523 for (i = 0; i < width; ++i) 2525 if (bot_p)
2524 XDrawLine (dpy, window, gc, 2526 for (i = 0; i < width; ++i)
2525 left_x + i * left_p, bottom_y - i, 2527 XDrawLine (dpy, window, gc,
2526 right_x - i * right_p, bottom_y - i); 2528 left_x + i * left_p, bottom_y - i,
2529 right_x - i * right_p, bottom_y - i);
2527 2530
2528 /* Right. */ 2531 /* Right. */
2529 if (right_p) 2532 if (right_p)
@@ -2629,7 +2632,7 @@ x_draw_glyph_string_box (s)
2629 { 2632 {
2630 x_setup_relief_colors (s); 2633 x_setup_relief_colors (s);
2631 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, 2634 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2632 width, raised_p, left_p, right_p, &clip_rect); 2635 width, raised_p, 1, 1, left_p, right_p, &clip_rect);
2633 } 2636 }
2634} 2637}
2635 2638
@@ -2640,21 +2643,22 @@ static void
2640x_draw_image_foreground (s) 2643x_draw_image_foreground (s)
2641 struct glyph_string *s; 2644 struct glyph_string *s;
2642{ 2645{
2643 int x; 2646 int x = s->x;
2644 int y = s->ybase - image_ascent (s->img, s->face); 2647 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2645 2648
2646 /* If first glyph of S has a left box line, start drawing it to the 2649 /* If first glyph of S has a left box line, start drawing it to the
2647 right of that line. */ 2650 right of that line. */
2648 if (s->face->box != FACE_NO_BOX 2651 if (s->face->box != FACE_NO_BOX
2649 && s->first_glyph->left_box_line_p) 2652 && s->first_glyph->left_box_line_p
2650 x = s->x + abs (s->face->box_line_width); 2653 && s->slice.x == 0)
2651 else 2654 x += abs (s->face->box_line_width);
2652 x = s->x;
2653 2655
2654 /* If there is a margin around the image, adjust x- and y-position 2656 /* If there is a margin around the image, adjust x- and y-position
2655 by that margin. */ 2657 by that margin. */
2656 x += s->img->hmargin; 2658 if (s->slice.x == 0)
2657 y += s->img->vmargin; 2659 x += s->img->hmargin;
2660 if (s->slice.y == 0)
2661 y += s->img->vmargin;
2658 2662
2659 if (s->img->pixmap) 2663 if (s->img->pixmap)
2660 { 2664 {
@@ -2667,11 +2671,12 @@ x_draw_image_foreground (s)
2667 CONVERT_TO_XRECT (clip_rect, nr); 2671 CONVERT_TO_XRECT (clip_rect, nr);
2668 image_rect.x = x; 2672 image_rect.x = x;
2669 image_rect.y = y; 2673 image_rect.y = y;
2670 image_rect.width = s->img->width; 2674 image_rect.width = s->slice.width;
2671 image_rect.height = s->img->height; 2675 image_rect.height = s->slice.height;
2672 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) 2676 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2673 mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask, 2677 mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask,
2674 s->window, s->gc, r.x - x, r.y - y, 2678 s->window, s->gc,
2679 s->slice.x + r.x - x, s->slice.y + r.y - y,
2675 r.width, r.height, r.x, r.y); 2680 r.width, r.height, r.x, r.y);
2676 } 2681 }
2677 else 2682 else
@@ -2683,11 +2688,12 @@ x_draw_image_foreground (s)
2683 CONVERT_TO_XRECT (clip_rect, nr); 2688 CONVERT_TO_XRECT (clip_rect, nr);
2684 image_rect.x = x; 2689 image_rect.x = x;
2685 image_rect.y = y; 2690 image_rect.y = y;
2686 image_rect.width = s->img->width; 2691 image_rect.width = s->slice.width;
2687 image_rect.height = s->img->height; 2692 image_rect.height = s->slice.height;
2688 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) 2693 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2689 mac_copy_area (s->display, s->img->pixmap, s->window, s->gc, 2694 mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
2690 r.x - x, r.y - y, r.width, r.height, r.x, r.y); 2695 s->slice.x + r.x - x, s->slice.y + r.y - y,
2696 r.width, r.height, r.x, r.y);
2691 2697
2692 /* When the image has a mask, we can expect that at 2698 /* When the image has a mask, we can expect that at
2693 least part of a mouse highlight or a block cursor will 2699 least part of a mouse highlight or a block cursor will
@@ -2699,15 +2705,17 @@ x_draw_image_foreground (s)
2699 { 2705 {
2700 int r = s->img->relief; 2706 int r = s->img->relief;
2701 if (r < 0) r = -r; 2707 if (r < 0) r = -r;
2702 mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r, 2708 mac_draw_rectangle (s->display, s->window, s->gc,
2703 s->img->width + r*2 - 1, s->img->height + r*2 - 1); 2709 x - r, y - r,
2710 s->slice.width + r*2 - 1,
2711 s->slice.height + r*2 - 1);
2704 } 2712 }
2705 } 2713 }
2706 } 2714 }
2707 else 2715 else
2708 /* Draw a rectangle if image could not be loaded. */ 2716 /* Draw a rectangle if image could not be loaded. */
2709 mac_draw_rectangle (s->display, s->window, s->gc, x, y, 2717 mac_draw_rectangle (s->display, s->window, s->gc, x, y,
2710 s->img->width - 1, s->img->height - 1); 2718 s->slice.width - 1, s->slice.height - 1);
2711} 2719}
2712 2720
2713 2721
@@ -2719,21 +2727,22 @@ x_draw_image_relief (s)
2719{ 2727{
2720 int x0, y0, x1, y1, thick, raised_p; 2728 int x0, y0, x1, y1, thick, raised_p;
2721 Rect r; 2729 Rect r;
2722 int x; 2730 int x = s->x;
2723 int y = s->ybase - image_ascent (s->img, s->face); 2731 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2724 2732
2725 /* If first glyph of S has a left box line, start drawing it to the 2733 /* If first glyph of S has a left box line, start drawing it to the
2726 right of that line. */ 2734 right of that line. */
2727 if (s->face->box != FACE_NO_BOX 2735 if (s->face->box != FACE_NO_BOX
2728 && s->first_glyph->left_box_line_p) 2736 && s->first_glyph->left_box_line_p
2729 x = s->x + abs (s->face->box_line_width); 2737 && s->slice.x == 0)
2730 else 2738 x += abs (s->face->box_line_width);
2731 x = s->x;
2732 2739
2733 /* If there is a margin around the image, adjust x- and y-position 2740 /* If there is a margin around the image, adjust x- and y-position
2734 by that margin. */ 2741 by that margin. */
2735 x += s->img->hmargin; 2742 if (s->slice.x == 0)
2736 y += s->img->vmargin; 2743 x += s->img->hmargin;
2744 if (s->slice.y == 0)
2745 y += s->img->vmargin;
2737 2746
2738 if (s->hl == DRAW_IMAGE_SUNKEN 2747 if (s->hl == DRAW_IMAGE_SUNKEN
2739 || s->hl == DRAW_IMAGE_RAISED) 2748 || s->hl == DRAW_IMAGE_RAISED)
@@ -2749,12 +2758,17 @@ x_draw_image_relief (s)
2749 2758
2750 x0 = x - thick; 2759 x0 = x - thick;
2751 y0 = y - thick; 2760 y0 = y - thick;
2752 x1 = x + s->img->width + thick - 1; 2761 x1 = x + s->slice.width + thick - 1;
2753 y1 = y + s->img->height + thick - 1; 2762 y1 = y + s->slice.height + thick - 1;
2754 2763
2755 x_setup_relief_colors (s); 2764 x_setup_relief_colors (s);
2756 get_glyph_string_clip_rect (s, &r); 2765 get_glyph_string_clip_rect (s, &r);
2757 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); 2766 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
2767 s->slice.y == 0,
2768 s->slice.y + s->slice.height == s->img->height,
2769 s->slice.x == 0,
2770 s->slice.x + s->slice.width == s->img->width,
2771 &r);
2758} 2772}
2759 2773
2760 2774
@@ -2765,33 +2779,37 @@ x_draw_image_foreground_1 (s, pixmap)
2765 struct glyph_string *s; 2779 struct glyph_string *s;
2766 Pixmap pixmap; 2780 Pixmap pixmap;
2767{ 2781{
2768 int x; 2782 int x = 0;
2769 int y = s->ybase - s->y - image_ascent (s->img, s->face); 2783 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
2770 2784
2771 /* If first glyph of S has a left box line, start drawing it to the 2785 /* If first glyph of S has a left box line, start drawing it to the
2772 right of that line. */ 2786 right of that line. */
2773 if (s->face->box != FACE_NO_BOX 2787 if (s->face->box != FACE_NO_BOX
2774 && s->first_glyph->left_box_line_p) 2788 && s->first_glyph->left_box_line_p
2775 x = abs (s->face->box_line_width); 2789 && s->slice.x == 0)
2776 else 2790 x += abs (s->face->box_line_width);
2777 x = 0;
2778 2791
2779 /* If there is a margin around the image, adjust x- and y-position 2792 /* If there is a margin around the image, adjust x- and y-position
2780 by that margin. */ 2793 by that margin. */
2781 x += s->img->hmargin; 2794 if (s->slice.x == 0)
2782 y += s->img->vmargin; 2795 x += s->img->hmargin;
2796 if (s->slice.y == 0)
2797 y += s->img->vmargin;
2783 2798
2784 if (s->img->pixmap) 2799 if (s->img->pixmap)
2785 { 2800 {
2786 if (s->img->mask) 2801 if (s->img->mask)
2787 mac_copy_area_with_mask_to_pixmap (s->display, s->img->pixmap, 2802 mac_copy_area_with_mask_to_pixmap (s->display, s->img->pixmap,
2788 s->img->mask, pixmap, s->gc, 2803 s->img->mask, pixmap, s->gc,
2789 0, 0, s->img->width, s->img->height, 2804 s->slice.x, s->slice.y,
2805 s->slice.width, s->slice.height,
2790 x, y); 2806 x, y);
2791 else 2807 else
2792 { 2808 {
2793 mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc, 2809 mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc,
2794 0, 0, s->img->width, s->img->height, x, y); 2810 s->slice.x, s->slice.y,
2811 s->slice.width, s->slice.height,
2812 x, y);
2795 2813
2796 /* When the image has a mask, we can expect that at 2814 /* When the image has a mask, we can expect that at
2797 least part of a mouse highlight or a block cursor will 2815 least part of a mouse highlight or a block cursor will
@@ -2804,15 +2822,15 @@ x_draw_image_foreground_1 (s, pixmap)
2804 int r = s->img->relief; 2822 int r = s->img->relief;
2805 if (r < 0) r = -r; 2823 if (r < 0) r = -r;
2806 mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r, 2824 mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r,
2807 s->img->width + r*2 - 1, 2825 s->slice.width + r*2 - 1,
2808 s->img->height + r*2 - 1); 2826 s->slice.height + r*2 - 1);
2809 } 2827 }
2810 } 2828 }
2811 } 2829 }
2812 else 2830 else
2813 /* Draw a rectangle if image could not be loaded. */ 2831 /* Draw a rectangle if image could not be loaded. */
2814 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y, 2832 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y,
2815 s->img->width - 1, s->img->height - 1); 2833 s->slice.width - 1, s->slice.height - 1);
2816} 2834}
2817 2835
2818 2836
@@ -2869,19 +2887,21 @@ x_draw_image_glyph_string (s)
2869 taller than image or if image has a clip mask to reduce 2887 taller than image or if image has a clip mask to reduce
2870 flickering. */ 2888 flickering. */
2871 s->stippled_p = s->face->stipple != 0; 2889 s->stippled_p = s->face->stipple != 0;
2872 if (height > s->img->height 2890 if (height > s->slice.height
2873 || s->img->hmargin 2891 || s->img->hmargin
2874 || s->img->vmargin 2892 || s->img->vmargin
2875 || s->img->mask 2893 || s->img->mask
2876 || s->img->pixmap == 0 2894 || s->img->pixmap == 0
2877 || s->width != s->background_width) 2895 || s->width != s->background_width)
2878 { 2896 {
2879 if (box_line_hwidth && s->first_glyph->left_box_line_p) 2897 x = s->x;
2880 x = s->x + box_line_hwidth; 2898 if (s->first_glyph->left_box_line_p
2881 else 2899 && s->slice.x == 0)
2882 x = s->x; 2900 x += box_line_hwidth;
2883 2901
2884 y = s->y + box_line_vwidth; 2902 y = s->y;
2903 if (s->slice.y == 0)
2904 y += box_line_vwidth;
2885 2905
2886 if (s->img->mask) 2906 if (s->img->mask)
2887 { 2907 {
@@ -3842,7 +3862,7 @@ glyph_rect (f, x, y, rect)
3842 3862
3843 /* x is to the right of the last glyph in the row. */ 3863 /* x is to the right of the last glyph in the row. */
3844 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx); 3864 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
3845 /* Shouldn't this be a pixel value? 3865 /* Shouldn't this be a pixel value?
3846 WINDOW_RIGHT_EDGE_X (w) seems to be the right value. 3866 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3847 ++KFS */ 3867 ++KFS */
3848 rect->right = WINDOW_RIGHT_EDGE_COL (w); 3868 rect->right = WINDOW_RIGHT_EDGE_COL (w);
@@ -3984,7 +4004,7 @@ mac_handle_tool_bar_click (f, button_event)
3984 if (button_event->what == mouseDown) 4004 if (button_event->what == mouseDown)
3985 handle_tool_bar_click (f, x, y, 1, 0); 4005 handle_tool_bar_click (f, x, y, 1, 0);
3986 else 4006 else
3987 handle_tool_bar_click (f, x, y, 0, 4007 handle_tool_bar_click (f, x, y, 0,
3988 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f), 4008 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f),
3989 button_event->modifiers)); 4009 button_event->modifiers));
3990} 4010}
@@ -4933,7 +4953,7 @@ x_new_font (f, fontname)
4933 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0) 4953 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
4934 { 4954 {
4935 int wid = FRAME_COLUMN_WIDTH (f); 4955 int wid = FRAME_COLUMN_WIDTH (f);
4936 FRAME_CONFIG_SCROLL_BAR_COLS (f) 4956 FRAME_CONFIG_SCROLL_BAR_COLS (f)
4937 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid; 4957 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
4938 } 4958 }
4939 else 4959 else
@@ -5826,7 +5846,7 @@ decode_mac_font_name (char *name, int size, short scriptcode)
5826 break; 5846 break;
5827 case smKorean: 5847 case smKorean:
5828 coding_system = Qeuc_kr; 5848 coding_system = Qeuc_kr;
5829 break; 5849 break;
5830 default: 5850 default:
5831 return; 5851 return;
5832 } 5852 }
@@ -6277,7 +6297,7 @@ mac_do_list_fonts (pattern, maxnames)
6277 if (fast_string_match (pattern_regex, fontname) >= 0) 6297 if (fast_string_match (pattern_regex, fontname) >= 0)
6278 { 6298 {
6279 font_list = Fcons (fontname, font_list); 6299 font_list = Fcons (fontname, font_list);
6280 6300
6281 n_fonts++; 6301 n_fonts++;
6282 if (maxnames > 0 && n_fonts >= maxnames) 6302 if (maxnames > 0 && n_fonts >= maxnames)
6283 break; 6303 break;
@@ -6987,7 +7007,7 @@ mac_get_emulated_btn ( UInt32 modifiers )
6987 if (modifiers & controlKey) 7007 if (modifiers & controlKey)
6988 result = cmdIs3 ? 2 : 1; 7008 result = cmdIs3 ? 2 : 1;
6989 else if (modifiers & optionKey) 7009 else if (modifiers & optionKey)
6990 result = cmdIs3 ? 1 : 2; 7010 result = cmdIs3 ? 1 : 2;
6991 } 7011 }
6992 return result; 7012 return result;
6993} 7013}
@@ -7020,7 +7040,7 @@ mac_get_mouse_btn (EventRef ref)
7020 switch (result) 7040 switch (result)
7021 { 7041 {
7022 case kEventMouseButtonPrimary: 7042 case kEventMouseButtonPrimary:
7023 if (Vmac_emulate_three_button_mouse == Qnil) 7043 if (Vmac_emulate_three_button_mouse == Qnil)
7024 return 0; 7044 return 0;
7025 else { 7045 else {
7026 UInt32 mods = 0; 7046 UInt32 mods = 0;
@@ -8189,7 +8209,7 @@ XTread_socket (int sd, int expected, struct input_event *hold_quit)
8189 switch (part_code) 8209 switch (part_code)
8190 { 8210 {
8191 case inMenuBar: 8211 case inMenuBar:
8192 if (er.what == mouseDown) 8212 if (er.what == mouseDown)
8193 { 8213 {
8194 struct frame *f = ((mac_output *) 8214 struct frame *f = ((mac_output *)
8195 GetWRefCon (FrontWindow ()))->mFP; 8215 GetWRefCon (FrontWindow ()))->mFP;
@@ -8269,7 +8289,7 @@ XTread_socket (int sd, int expected, struct input_event *hold_quit)
8269 else 8289 else
8270 mouse_tracking_in_progress = mouse_tracking_none; 8290 mouse_tracking_in_progress = mouse_tracking_none;
8271 window = window_from_coordinates (mwp->mFP, inev.x, inev.y, 0, 0, 0, 1); 8291 window = window_from_coordinates (mwp->mFP, inev.x, inev.y, 0, 0, 0, 1);
8272 8292
8273 if (EQ (window, mwp->mFP->tool_bar_window)) 8293 if (EQ (window, mwp->mFP->tool_bar_window))
8274 { 8294 {
8275 if (er.what == mouseDown) 8295 if (er.what == mouseDown)
@@ -8308,10 +8328,10 @@ XTread_socket (int sd, int expected, struct input_event *hold_quit)
8308 8328
8309 case inDrag: 8329 case inDrag:
8310#if TARGET_API_MAC_CARBON 8330#if TARGET_API_MAC_CARBON
8311 if (er.what == mouseDown) 8331 if (er.what == mouseDown)
8312 { 8332 {
8313 BitMap bm; 8333 BitMap bm;
8314 8334
8315 GetQDGlobalsScreenBits (&bm); 8335 GetQDGlobalsScreenBits (&bm);
8316 DragWindow (window_ptr, er.where, &bm.bounds); 8336 DragWindow (window_ptr, er.where, &bm.bounds);
8317 } 8337 }
@@ -8331,7 +8351,7 @@ XTread_socket (int sd, int expected, struct input_event *hold_quit)
8331 8351
8332 /* window resize handling added --ben */ 8352 /* window resize handling added --ben */
8333 case inGrow: 8353 case inGrow:
8334 if (er.what == mouseDown) 8354 if (er.what == mouseDown)
8335 { 8355 {
8336 do_grow_window(window_ptr, &er); 8356 do_grow_window(window_ptr, &er);
8337 break; 8357 break;
@@ -9186,10 +9206,10 @@ Otherwise the option key is used. */);
9186 useful for non-standard keyboard layouts. */); 9206 useful for non-standard keyboard layouts. */);
9187 Vmac_reverse_ctrl_meta = Qnil; 9207 Vmac_reverse_ctrl_meta = Qnil;
9188 9208
9189 DEFVAR_LISP ("mac-emulate-three-button-mouse", 9209 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9190 &Vmac_emulate_three_button_mouse, 9210 &Vmac_emulate_three_button_mouse,
9191 doc: /* t means that when the option-key is held down while pressing the 9211 doc: /* t means that when the option-key is held down while pressing the
9192 mouse button, the click will register as mouse-2 and while the 9212 mouse button, the click will register as mouse-2 and while the
9193 command-key is held down, the click will register as mouse-3. 9213 command-key is held down, the click will register as mouse-3.
9194 'reverse means that the the option-key will register for mouse-3 9214 'reverse means that the the option-key will register for mouse-3
9195 and the command-key will register for mouse-2. nil means that 9215 and the command-key will register for mouse-2. nil means that
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index c2a6e4a1eeb..7056d43af5f 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -1,4 +1,4 @@
1# Makefile for GNU Emacs on the Microsoft W32 API. 1# -*- Makefile -*- for GNU Emacs on the Microsoft W32 API.
2# Copyright (c) 2000-2001 Free Software Foundation, Inc. 2# Copyright (c) 2000-2001 Free Software Foundation, Inc.
3# 3#
4# This file is part of GNU Emacs. 4# This file is part of GNU Emacs.
diff --git a/src/w32term.c b/src/w32term.c
index 7f3b6b626de..24eabfba567 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1220,7 +1220,8 @@ static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
1220static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, 1220static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
1221 int, int, int)); 1221 int, int, int));
1222static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int, 1222static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
1223 int, int, int, int, RECT *)); 1223 int, int, int, int, int, int,
1224 RECT *));
1224static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, 1225static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
1225 int, int, int, RECT *)); 1226 int, int, int, RECT *));
1226 1227
@@ -1801,9 +1802,10 @@ x_setup_relief_colors (s)
1801 1802
1802static void 1803static void
1803w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, 1804w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
1804 raised_p, left_p, right_p, clip_rect) 1805 raised_p, top_p, bot_p, left_p, right_p, clip_rect)
1805 struct frame *f; 1806 struct frame *f;
1806 int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p; 1807 int left_x, top_y, right_x, bottom_y, width;
1808 int top_p, bot_p, left_p, right_p, raised_p;
1807 RECT *clip_rect; 1809 RECT *clip_rect;
1808{ 1810{
1809 int i; 1811 int i;
@@ -1818,10 +1820,11 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
1818 w32_set_clip_rectangle (hdc, clip_rect); 1820 w32_set_clip_rectangle (hdc, clip_rect);
1819 1821
1820 /* Top. */ 1822 /* Top. */
1821 for (i = 0; i < width; ++i) 1823 if (top_p)
1822 w32_fill_area (f, hdc, gc.foreground, 1824 for (i = 0; i < width; ++i)
1823 left_x + i * left_p, top_y + i, 1825 w32_fill_area (f, hdc, gc.foreground,
1824 right_x - left_x - i * (left_p + right_p ) + 1, 1); 1826 left_x + i * left_p, top_y + i,
1827 right_x - left_x - i * (left_p + right_p ) + 1, 1);
1825 1828
1826 /* Left. */ 1829 /* Left. */
1827 if (left_p) 1830 if (left_p)
@@ -1836,10 +1839,11 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
1836 gc.foreground = f->output_data.w32->white_relief.gc->foreground; 1839 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
1837 1840
1838 /* Bottom. */ 1841 /* Bottom. */
1839 for (i = 0; i < width; ++i) 1842 if (bot_p)
1840 w32_fill_area (f, hdc, gc.foreground, 1843 for (i = 0; i < width; ++i)
1841 left_x + i * left_p, bottom_y - i, 1844 w32_fill_area (f, hdc, gc.foreground,
1842 right_x - left_x - i * (left_p + right_p) + 1, 1); 1845 left_x + i * left_p, bottom_y - i,
1846 right_x - left_x - i * (left_p + right_p) + 1, 1);
1843 1847
1844 /* Right. */ 1848 /* Right. */
1845 if (right_p) 1849 if (right_p)
@@ -1949,7 +1953,7 @@ x_draw_glyph_string_box (s)
1949 { 1953 {
1950 x_setup_relief_colors (s); 1954 x_setup_relief_colors (s);
1951 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, 1955 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
1952 width, raised_p, left_p, right_p, &clip_rect); 1956 width, raised_p, 1, 1, left_p, right_p, &clip_rect);
1953 } 1957 }
1954} 1958}
1955 1959
@@ -1960,21 +1964,22 @@ static void
1960x_draw_image_foreground (s) 1964x_draw_image_foreground (s)
1961 struct glyph_string *s; 1965 struct glyph_string *s;
1962{ 1966{
1963 int x; 1967 int x = s->x;
1964 int y = s->ybase - image_ascent (s->img, s->face); 1968 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
1965 1969
1966 /* If first glyph of S has a left box line, start drawing it to the 1970 /* If first glyph of S has a left box line, start drawing it to the
1967 right of that line. */ 1971 right of that line. */
1968 if (s->face->box != FACE_NO_BOX 1972 if (s->face->box != FACE_NO_BOX
1969 && s->first_glyph->left_box_line_p) 1973 && s->first_glyph->left_box_line_p
1970 x = s->x + abs (s->face->box_line_width); 1974 && s->slice.x == 0)
1971 else 1975 x += abs (s->face->box_line_width);
1972 x = s->x;
1973 1976
1974 /* If there is a margin around the image, adjust x- and y-position 1977 /* If there is a margin around the image, adjust x- and y-position
1975 by that margin. */ 1978 by that margin. */
1976 x += s->img->hmargin; 1979 if (s->slice.x == 0)
1977 y += s->img->vmargin; 1980 x += s->img->hmargin;
1981 if (s->slice.y == 0)
1982 y += s->img->vmargin;
1978 1983
1979 SaveDC (s->hdc); 1984 SaveDC (s->hdc);
1980 1985
@@ -1996,12 +2001,12 @@ x_draw_image_foreground (s)
1996 SetTextColor (s->hdc, RGB (255, 255, 255)); 2001 SetTextColor (s->hdc, RGB (255, 255, 255));
1997 SetBkColor (s->hdc, RGB (0, 0, 0)); 2002 SetBkColor (s->hdc, RGB (0, 0, 0));
1998 2003
1999 BitBlt (s->hdc, x, y, s->img->width, s->img->height, 2004 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2000 compat_hdc, 0, 0, SRCINVERT); 2005 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2001 BitBlt (s->hdc, x, y, s->img->width, s->img->height, 2006 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2002 mask_dc, 0, 0, SRCAND); 2007 mask_dc, s->slice.x, s->slice.y, SRCAND);
2003 BitBlt (s->hdc, x, y, s->img->width, s->img->height, 2008 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2004 compat_hdc, 0, 0, SRCINVERT); 2009 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2005 2010
2006 SelectObject (mask_dc, mask_orig_obj); 2011 SelectObject (mask_dc, mask_orig_obj);
2007 DeleteDC (mask_dc); 2012 DeleteDC (mask_dc);
@@ -2011,8 +2016,8 @@ x_draw_image_foreground (s)
2011 SetTextColor (s->hdc, s->gc->foreground); 2016 SetTextColor (s->hdc, s->gc->foreground);
2012 SetBkColor (s->hdc, s->gc->background); 2017 SetBkColor (s->hdc, s->gc->background);
2013 2018
2014 BitBlt (s->hdc, x, y, s->img->width, s->img->height, 2019 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2015 compat_hdc, 0, 0, SRCCOPY); 2020 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
2016 2021
2017 /* When the image has a mask, we can expect that at 2022 /* When the image has a mask, we can expect that at
2018 least part of a mouse highlight or a block cursor will 2023 least part of a mouse highlight or a block cursor will
@@ -2025,7 +2030,8 @@ x_draw_image_foreground (s)
2025 int r = s->img->relief; 2030 int r = s->img->relief;
2026 if (r < 0) r = -r; 2031 if (r < 0) r = -r;
2027 w32_draw_rectangle (s->hdc, s->gc, x - r, y - r , 2032 w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
2028 s->img->width + r*2 - 1, s->img->height + r*2 - 1); 2033 s->slice.width + r*2 - 1,
2034 s->slice.height + r*2 - 1);
2029 } 2035 }
2030 } 2036 }
2031 2037
@@ -2036,8 +2042,8 @@ x_draw_image_foreground (s)
2036 DeleteDC (compat_hdc); 2042 DeleteDC (compat_hdc);
2037 } 2043 }
2038 else 2044 else
2039 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width -1, 2045 w32_draw_rectangle (s->hdc, s->gc, x, y,
2040 s->img->height - 1); 2046 s->slice.width - 1, s->slice.height - 1);
2041 2047
2042 RestoreDC (s->hdc ,-1); 2048 RestoreDC (s->hdc ,-1);
2043} 2049}
@@ -2052,21 +2058,22 @@ x_draw_image_relief (s)
2052{ 2058{
2053 int x0, y0, x1, y1, thick, raised_p; 2059 int x0, y0, x1, y1, thick, raised_p;
2054 RECT r; 2060 RECT r;
2055 int x; 2061 int x = s->x;
2056 int y = s->ybase - image_ascent (s->img, s->face); 2062 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2057 2063
2058 /* If first glyph of S has a left box line, start drawing it to the 2064 /* If first glyph of S has a left box line, start drawing it to the
2059 right of that line. */ 2065 right of that line. */
2060 if (s->face->box != FACE_NO_BOX 2066 if (s->face->box != FACE_NO_BOX
2061 && s->first_glyph->left_box_line_p) 2067 && s->first_glyph->left_box_line_p
2062 x = s->x + abs (s->face->box_line_width); 2068 && s->slice.x == 0)
2063 else 2069 x += abs (s->face->box_line_width);
2064 x = s->x;
2065 2070
2066 /* If there is a margin around the image, adjust x- and y-position 2071 /* If there is a margin around the image, adjust x- and y-position
2067 by that margin. */ 2072 by that margin. */
2068 x += s->img->hmargin; 2073 if (s->slice.x == 0)
2069 y += s->img->vmargin; 2074 x += s->img->hmargin;
2075 if (s->slice.y == 0)
2076 y += s->img->vmargin;
2070 2077
2071 if (s->hl == DRAW_IMAGE_SUNKEN 2078 if (s->hl == DRAW_IMAGE_SUNKEN
2072 || s->hl == DRAW_IMAGE_RAISED) 2079 || s->hl == DRAW_IMAGE_RAISED)
@@ -2082,12 +2089,17 @@ x_draw_image_relief (s)
2082 2089
2083 x0 = x - thick; 2090 x0 = x - thick;
2084 y0 = y - thick; 2091 y0 = y - thick;
2085 x1 = x + s->img->width + thick - 1; 2092 x1 = x + s->slice.width + thick - 1;
2086 y1 = y + s->img->height + thick - 1; 2093 y1 = y + s->slice.height + thick - 1;
2087 2094
2088 x_setup_relief_colors (s); 2095 x_setup_relief_colors (s);
2089 get_glyph_string_clip_rect (s, &r); 2096 get_glyph_string_clip_rect (s, &r);
2090 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); 2097 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
2098 s->slice.y == 0,
2099 s->slice.y + s->slice.height == s->img->height,
2100 s->slice.x == 0,
2101 s->slice.x + s->slice.width == s->img->width,
2102 &r);
2091} 2103}
2092 2104
2093 2105
@@ -2100,21 +2112,22 @@ w32_draw_image_foreground_1 (s, pixmap)
2100{ 2112{
2101 HDC hdc = CreateCompatibleDC (s->hdc); 2113 HDC hdc = CreateCompatibleDC (s->hdc);
2102 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap); 2114 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
2103 int x; 2115 int x = 0;
2104 int y = s->ybase - s->y - image_ascent (s->img, s->face); 2116 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
2105 2117
2106 /* If first glyph of S has a left box line, start drawing it to the 2118 /* If first glyph of S has a left box line, start drawing it to the
2107 right of that line. */ 2119 right of that line. */
2108 if (s->face->box != FACE_NO_BOX 2120 if (s->face->box != FACE_NO_BOX
2109 && s->first_glyph->left_box_line_p) 2121 && s->first_glyph->left_box_line_p
2110 x = abs (s->face->box_line_width); 2122 && s->slice.x == 0)
2111 else 2123 x += abs (s->face->box_line_width);
2112 x = 0;
2113 2124
2114 /* If there is a margin around the image, adjust x- and y-position 2125 /* If there is a margin around the image, adjust x- and y-position
2115 by that margin. */ 2126 by that margin. */
2116 x += s->img->hmargin; 2127 if (s->slice.x == 0)
2117 y += s->img->vmargin; 2128 x += s->img->hmargin;
2129 if (s->slice.y == 0)
2130 y += s->img->vmargin;
2118 2131
2119 if (s->img->pixmap) 2132 if (s->img->pixmap)
2120 { 2133 {
@@ -2130,12 +2143,12 @@ w32_draw_image_foreground_1 (s, pixmap)
2130 2143
2131 SetTextColor (hdc, RGB (0, 0, 0)); 2144 SetTextColor (hdc, RGB (0, 0, 0));
2132 SetBkColor (hdc, RGB (255, 255, 255)); 2145 SetBkColor (hdc, RGB (255, 255, 255));
2133 BitBlt (hdc, x, y, s->img->width, s->img->height, 2146 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2134 compat_hdc, 0, 0, SRCINVERT); 2147 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2135 BitBlt (hdc, x, y, s->img->width, s->img->height, 2148 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2136 mask_dc, 0, 0, SRCAND); 2149 mask_dc, s->slice.x, s->slice.y, SRCAND);
2137 BitBlt (hdc, x, y, s->img->width, s->img->height, 2150 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2138 compat_hdc, 0, 0, SRCINVERT); 2151 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2139 2152
2140 SelectObject (mask_dc, mask_orig_obj); 2153 SelectObject (mask_dc, mask_orig_obj);
2141 DeleteDC (mask_dc); 2154 DeleteDC (mask_dc);
@@ -2145,8 +2158,8 @@ w32_draw_image_foreground_1 (s, pixmap)
2145 SetTextColor (hdc, s->gc->foreground); 2158 SetTextColor (hdc, s->gc->foreground);
2146 SetBkColor (hdc, s->gc->background); 2159 SetBkColor (hdc, s->gc->background);
2147 2160
2148 BitBlt (hdc, x, y, s->img->width, s->img->height, 2161 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2149 compat_hdc, 0, 0, SRCCOPY); 2162 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
2150 2163
2151 /* When the image has a mask, we can expect that at 2164 /* When the image has a mask, we can expect that at
2152 least part of a mouse highlight or a block cursor will 2165 least part of a mouse highlight or a block cursor will
@@ -2158,8 +2171,9 @@ w32_draw_image_foreground_1 (s, pixmap)
2158 { 2171 {
2159 int r = s->img->relief; 2172 int r = s->img->relief;
2160 if (r < 0) r = -r; 2173 if (r < 0) r = -r;
2161 w32_draw_rectangle (hdc, s->gc, x - r, y - r , 2174 w32_draw_rectangle (hdc, s->gc, x - r, y - r,
2162 s->img->width + r*2 - 1, s->img->height + r*2 - 1); 2175 s->slice.width + r*2 - 1,
2176 s->slice.height + r*2 - 1);
2163 } 2177 }
2164 } 2178 }
2165 2179
@@ -2169,8 +2183,8 @@ w32_draw_image_foreground_1 (s, pixmap)
2169 DeleteDC (compat_hdc); 2183 DeleteDC (compat_hdc);
2170 } 2184 }
2171 else 2185 else
2172 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1, 2186 w32_draw_rectangle (hdc, s->gc, x, y,
2173 s->img->height - 1); 2187 s->slice.width - 1, s->slice.height - 1);
2174 2188
2175 SelectObject (hdc, orig_hdc_obj); 2189 SelectObject (hdc, orig_hdc_obj);
2176 DeleteDC (hdc); 2190 DeleteDC (hdc);
@@ -2229,19 +2243,22 @@ x_draw_image_glyph_string (s)
2229 taller than image or if image has a clip mask to reduce 2243 taller than image or if image has a clip mask to reduce
2230 flickering. */ 2244 flickering. */
2231 s->stippled_p = s->face->stipple != 0; 2245 s->stippled_p = s->face->stipple != 0;
2232 if (height > s->img->height 2246 if (height > s->slice.height
2233 || s->img->hmargin 2247 || s->img->hmargin
2234 || s->img->vmargin 2248 || s->img->vmargin
2235 || s->img->mask 2249 || s->img->mask
2236 || s->img->pixmap == 0 2250 || s->img->pixmap == 0
2237 || s->width != s->background_width) 2251 || s->width != s->background_width)
2238 { 2252 {
2239 if (box_line_hwidth && s->first_glyph->left_box_line_p) 2253 x = s->x;
2240 x = s->x + box_line_hwidth; 2254 if (s->first_glyph->left_box_line_p
2241 else 2255 && s->slice.x == 0)
2242 x = s->x; 2256 x += box_line_hwidth;
2257
2258 y = s->y;
2259 if (s->slice.y == 0)
2260 y += box_line_vwidth;
2243 2261
2244 y = s->y + box_line_vwidth;
2245#if 0 /* TODO: figure out if we need to do this on Windows. */ 2262#if 0 /* TODO: figure out if we need to do this on Windows. */
2246 if (s->img->mask) 2263 if (s->img->mask)
2247 { 2264 {
diff --git a/src/w32term.h b/src/w32term.h
index 68967ad7d24..f7c4c30064e 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -719,7 +719,6 @@ XGCValues *XCreateGC (void *, Window, unsigned long, XGCValues *);
719struct frame * check_x_frame (Lisp_Object); 719struct frame * check_x_frame (Lisp_Object);
720EXFUN (Fx_display_color_p, 1); 720EXFUN (Fx_display_color_p, 1);
721EXFUN (Fx_display_grayscale_p, 1); 721EXFUN (Fx_display_grayscale_p, 1);
722int image_ascent P_ ((struct image *, struct face *));
723 722
724#define FONT_TYPE_FOR_UNIBYTE(font, ch) \ 723#define FONT_TYPE_FOR_UNIBYTE(font, ch) \
725 ((font)->bdf ? BDF_1D_FONT : ANSI_FONT) 724 ((font)->bdf ? BDF_1D_FONT : ANSI_FONT)
diff --git a/src/window.c b/src/window.c
index b6546eee698..221d8bbbaf2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -324,7 +324,11 @@ DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
324Return nil if that position is scrolled vertically out of view. 324Return nil if that position is scrolled vertically out of view.
325If a character is only partially visible, nil is returned, unless the 325If a character is only partially visible, nil is returned, unless the
326optional argument PARTIALLY is non-nil. 326optional argument PARTIALLY is non-nil.
327POS defaults to point in WINDOW; WINDOW defaults to the selected window. */) 327POS defaults to point in WINDOW; WINDOW defaults to the selected window.
328
329If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
330return value is a list (X Y PARTIAL) where X and Y are the pixel relative
331coordinate */)
328 (pos, window, partially) 332 (pos, window, partially)
329 Lisp_Object pos, window, partially; 333 Lisp_Object pos, window, partially;
330{ 334{
@@ -332,8 +336,9 @@ POS defaults to point in WINDOW; WINDOW defaults to the selected window. */)
332 register int posint; 336 register int posint;
333 register struct buffer *buf; 337 register struct buffer *buf;
334 struct text_pos top; 338 struct text_pos top;
335 Lisp_Object in_window; 339 Lisp_Object in_window = Qnil;
336 int fully_p; 340 int fully_p = 1;
341 int x, y;
337 342
338 w = decode_window (window); 343 w = decode_window (window);
339 buf = XBUFFER (w->buffer); 344 buf = XBUFFER (w->buffer);
@@ -349,38 +354,20 @@ POS defaults to point in WINDOW; WINDOW defaults to the selected window. */)
349 else 354 else
350 posint = XMARKER (w->pointm)->charpos; 355 posint = XMARKER (w->pointm)->charpos;
351 356
352 /* If position is above window start, it's not visible. */ 357 /* If position is above window start or outside buffer boundaries,
353 if (posint < CHARPOS (top)) 358 or if window start is out of range, position is not visible. */
354 in_window = Qnil; 359 if (posint >= CHARPOS (top)
355 else if (XFASTINT (w->last_modified) >= BUF_MODIFF (buf) 360 && posint <= BUF_ZV (buf)
356 && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (buf) 361 && CHARPOS (top) >= BUF_BEGV (buf)
357 && posint < BUF_Z (buf) - XFASTINT (w->window_end_pos)) 362 && CHARPOS (top) <= BUF_ZV (buf)
358 { 363 && pos_visible_p (w, posint, &fully_p, &x, &y, NILP (partially))
359 /* If frame is up-to-date, and POSINT is < window end pos, use 364 && (!NILP (partially) || fully_p))
360 that info. This doesn't work for POSINT == end pos, because 365 in_window = Qt;
361 the window end pos is actually the position _after_ the last 366
362 char in the window. */ 367 if (!NILP (in_window) && !NILP (partially))
363 if (NILP (partially)) 368 in_window = Fcons (make_number (x),
364 { 369 Fcons (make_number (y),
365 pos_visible_p (w, posint, &fully_p, NILP (partially)); 370 Fcons (fully_p ? Qt : Qnil, Qnil)));
366 in_window = fully_p ? Qt : Qnil;
367 }
368 else
369 in_window = Qt;
370 }
371 else if (posint > BUF_ZV (buf))
372 in_window = Qnil;
373 else if (CHARPOS (top) < BUF_BEGV (buf) || CHARPOS (top) > BUF_ZV (buf))
374 /* If window start is out of range, do something reasonable. */
375 in_window = Qnil;
376 else
377 {
378 if (pos_visible_p (w, posint, &fully_p, NILP (partially)))
379 in_window = !NILP (partially) || fully_p ? Qt : Qnil;
380 else
381 in_window = Qnil;
382 }
383
384 return in_window; 371 return in_window;
385} 372}
386 373
@@ -3462,7 +3449,7 @@ DEFUN ("force-window-update", Fforce_window_update, Sforce_window_update,
3462 0, 1, 0, 3449 0, 1, 0,
3463 doc: /* Force redisplay of all windows. 3450 doc: /* Force redisplay of all windows.
3464If optional arg OBJECT is a window, force redisplay of that window only. 3451If optional arg OBJECT is a window, force redisplay of that window only.
3465If OBJECT is a buffer or buffer name, force redisplay of all windows 3452If OBJECT is a buffer or buffer name, force redisplay of all windows
3466displaying that buffer. */) 3453displaying that buffer. */)
3467 (object) 3454 (object)
3468 Lisp_Object object; 3455 Lisp_Object object;
@@ -3484,7 +3471,7 @@ displaying that buffer. */)
3484 ++update_mode_lines; 3471 ++update_mode_lines;
3485 return Qt; 3472 return Qt;
3486 } 3473 }
3487 3474
3488 if (STRINGP (object)) 3475 if (STRINGP (object))
3489 object = Fget_buffer (object); 3476 object = Fget_buffer (object);
3490 if (BUFFERP (object) && !NILP (XBUFFER (object)->name)) 3477 if (BUFFERP (object) && !NILP (XBUFFER (object)->name))
@@ -3549,7 +3536,7 @@ temp_output_buffer_show (buf)
3549 Lisp_Object prev_window, prev_buffer; 3536 Lisp_Object prev_window, prev_buffer;
3550 prev_window = selected_window; 3537 prev_window = selected_window;
3551 XSETBUFFER (prev_buffer, old); 3538 XSETBUFFER (prev_buffer, old);
3552 3539
3553 /* Select the window that was chosen, for running the hook. 3540 /* Select the window that was chosen, for running the hook.
3554 Note: Both Fselect_window and select_window_norecord may 3541 Note: Both Fselect_window and select_window_norecord may
3555 set-buffer to the buffer displayed in the window, 3542 set-buffer to the buffer displayed in the window,
@@ -6069,7 +6056,7 @@ If TYPE is t, use the frame's scroll-bar type. */)
6069 vertical_type = Qnil; 6056 vertical_type = Qnil;
6070 6057
6071 if (!(EQ (vertical_type, Qnil) 6058 if (!(EQ (vertical_type, Qnil)
6072 || EQ (vertical_type, Qleft) 6059 || EQ (vertical_type, Qleft)
6073 || EQ (vertical_type, Qright) 6060 || EQ (vertical_type, Qright)
6074 || EQ (vertical_type, Qt))) 6061 || EQ (vertical_type, Qt)))
6075 error ("Invalid type of vertical scroll bar"); 6062 error ("Invalid type of vertical scroll bar");
@@ -6118,12 +6105,13 @@ value. */)
6118 Smooth scrolling 6105 Smooth scrolling
6119 ***********************************************************************/ 6106 ***********************************************************************/
6120 6107
6121DEFUN ("window-vscroll", Fwindow_vscroll, Swindow_vscroll, 0, 1, 0, 6108DEFUN ("window-vscroll", Fwindow_vscroll, Swindow_vscroll, 0, 2, 0,
6122 doc: /* Return the amount by which WINDOW is scrolled vertically. 6109 doc: /* Return the amount by which WINDOW is scrolled vertically.
6123Use the selected window if WINDOW is nil or omitted. 6110Use the selected window if WINDOW is nil or omitted.
6124Value is a multiple of the canonical character height of WINDOW. */) 6111Normally, value is a multiple of the canonical character height of WINDOW;
6125 (window) 6112optional second arg PIXELS_P means value is measured in pixels. */)
6126 Lisp_Object window; 6113 (window, pixels_p)
6114 Lisp_Object window, pixels_p;
6127{ 6115{
6128 Lisp_Object result; 6116 Lisp_Object result;
6129 struct frame *f; 6117 struct frame *f;
@@ -6137,7 +6125,9 @@ Value is a multiple of the canonical character height of WINDOW. */)
6137 f = XFRAME (w->frame); 6125 f = XFRAME (w->frame);
6138 6126
6139 if (FRAME_WINDOW_P (f)) 6127 if (FRAME_WINDOW_P (f))
6140 result = FRAME_CANON_Y_FROM_PIXEL_Y (f, -w->vscroll); 6128 result = (NILP (pixels_p)
6129 ? FRAME_CANON_Y_FROM_PIXEL_Y (f, -w->vscroll)
6130 : make_number (-w->vscroll));
6141 else 6131 else
6142 result = make_number (0); 6132 result = make_number (0);
6143 return result; 6133 return result;
@@ -6145,12 +6135,13 @@ Value is a multiple of the canonical character height of WINDOW. */)
6145 6135
6146 6136
6147DEFUN ("set-window-vscroll", Fset_window_vscroll, Sset_window_vscroll, 6137DEFUN ("set-window-vscroll", Fset_window_vscroll, Sset_window_vscroll,
6148 2, 2, 0, 6138 2, 3, 0,
6149 doc: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL. 6139 doc: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
6150WINDOW nil means use the selected window. VSCROLL is a non-negative 6140WINDOW nil means use the selected window. Normally, VSCROLL is a
6151multiple of the canonical character height of WINDOW. */) 6141non-negative multiple of the canonical character height of WINDOW;
6152 (window, vscroll) 6142optional third arg PIXELS_P non-nil means that VSCROLL is in pixels. */)
6153 Lisp_Object window, vscroll; 6143 (window, vscroll, pixels_p)
6144 Lisp_Object window, vscroll, pixels_p;
6154{ 6145{
6155 struct window *w; 6146 struct window *w;
6156 struct frame *f; 6147 struct frame *f;
@@ -6168,7 +6159,9 @@ multiple of the canonical character height of WINDOW. */)
6168 { 6159 {
6169 int old_dy = w->vscroll; 6160 int old_dy = w->vscroll;
6170 6161
6171 w->vscroll = - FRAME_LINE_HEIGHT (f) * XFLOATINT (vscroll); 6162 w->vscroll = - (NILP (pixels_p)
6163 ? FRAME_LINE_HEIGHT (f) * XFLOATINT (vscroll)
6164 : XFLOATINT (vscroll));
6172 w->vscroll = min (w->vscroll, 0); 6165 w->vscroll = min (w->vscroll, 0);
6173 6166
6174 /* Adjust glyph matrix of the frame if the virtual display 6167 /* Adjust glyph matrix of the frame if the virtual display
@@ -6180,7 +6173,7 @@ multiple of the canonical character height of WINDOW. */)
6180 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 6173 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
6181 } 6174 }
6182 6175
6183 return Fwindow_vscroll (window); 6176 return Fwindow_vscroll (window, pixels_p);
6184} 6177}
6185 6178
6186 6179
diff --git a/src/window.h b/src/window.h
index ef81da43b4d..59052af96a5 100644
--- a/src/window.h
+++ b/src/window.h
@@ -320,7 +320,7 @@ struct window
320 | | +--------------------------- LEFT_MARGIN_COLS 320 | | +--------------------------- LEFT_MARGIN_COLS
321 | +------------------------------- LEFT_FRINGE_WIDTH 321 | +------------------------------- LEFT_FRINGE_WIDTH
322 +---------------------------------- LEFT_SCROLL_BAR_COLS 322 +---------------------------------- LEFT_SCROLL_BAR_COLS
323 323
324*/ 324*/
325 325
326 326
@@ -767,8 +767,8 @@ EXFUN (Fdisplay_buffer, 3);
767EXFUN (Fset_window_buffer, 3); 767EXFUN (Fset_window_buffer, 3);
768EXFUN (Fset_window_hscroll, 2); 768EXFUN (Fset_window_hscroll, 2);
769EXFUN (Fwindow_hscroll, 1); 769EXFUN (Fwindow_hscroll, 1);
770EXFUN (Fset_window_vscroll, 2); 770EXFUN (Fset_window_vscroll, 3);
771EXFUN (Fwindow_vscroll, 1); 771EXFUN (Fwindow_vscroll, 2);
772EXFUN (Fset_window_margins, 3); 772EXFUN (Fset_window_margins, 3);
773EXFUN (Fwindow_live_p, 1); 773EXFUN (Fwindow_live_p, 1);
774EXFUN (Fset_window_point, 2); 774EXFUN (Fset_window_point, 2);
diff --git a/src/xdisp.c b/src/xdisp.c
index 3c144f4f5f4..fd621fe301b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -301,6 +301,7 @@ extern Lisp_Object Qface, Qinvisible, Qwidth;
301Lisp_Object Vdisplay_pixels_per_inch; 301Lisp_Object Vdisplay_pixels_per_inch;
302Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height; 302Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise; 303Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304Lisp_Object Qslice;
304Lisp_Object Qcenter; 305Lisp_Object Qcenter;
305Lisp_Object Qmargin, Qpointer; 306Lisp_Object Qmargin, Qpointer;
306extern Lisp_Object Qheight; 307extern Lisp_Object Qheight;
@@ -1231,9 +1232,9 @@ line_bottom_y (it)
1231 and header-lines heights. */ 1232 and header-lines heights. */
1232 1233
1233int 1234int
1234pos_visible_p (w, charpos, fully, exact_mode_line_heights_p) 1235pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1235 struct window *w; 1236 struct window *w;
1236 int charpos, *fully, exact_mode_line_heights_p; 1237 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1237{ 1238{
1238 struct it it; 1239 struct it it;
1239 struct text_pos top; 1240 struct text_pos top;
@@ -1281,14 +1282,27 @@ pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1281 visible_p = 1; 1282 visible_p = 1;
1282 *fully = bottom_y <= it.last_visible_y; 1283 *fully = bottom_y <= it.last_visible_y;
1283 } 1284 }
1285 if (visible_p && x)
1286 {
1287 *x = it.current_x;
1288 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1289 }
1284 } 1290 }
1285 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y) 1291 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1286 { 1292 {
1293 struct it it2;
1294
1295 it2 = it;
1287 move_it_by_lines (&it, 1, 0); 1296 move_it_by_lines (&it, 1, 0);
1288 if (charpos < IT_CHARPOS (it)) 1297 if (charpos < IT_CHARPOS (it))
1289 { 1298 {
1290 visible_p = 1; 1299 visible_p = 1;
1291 *fully = 0; 1300 if (x)
1301 {
1302 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1303 *x = it2.current_x;
1304 *y = it2.current_y + it2.max_ascent - it2.ascent;
1305 }
1292 } 1306 }
1293 } 1307 }
1294 1308
@@ -1296,6 +1310,7 @@ pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1296 set_buffer_internal_1 (old_buffer); 1310 set_buffer_internal_1 (old_buffer);
1297 1311
1298 current_header_line_height = current_mode_line_height = -1; 1312 current_header_line_height = current_mode_line_height = -1;
1313
1299 return visible_p; 1314 return visible_p;
1300} 1315}
1301 1316
@@ -2063,7 +2078,8 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
2063 if (FRAME_FACE_CACHE (it->f)->used == 0) 2078 if (FRAME_FACE_CACHE (it->f)->used == 0)
2064 recompute_basic_faces (it->f); 2079 recompute_basic_faces (it->f);
2065 2080
2066 /* Current value of the `space-width', and 'height' properties. */ 2081 /* Current value of the `slice', `space-width', and 'height' properties. */
2082 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2067 it->space_width = Qnil; 2083 it->space_width = Qnil;
2068 it->font_height = Qnil; 2084 it->font_height = Qnil;
2069 2085
@@ -3271,8 +3287,9 @@ handle_display_prop (it)
3271 } 3287 }
3272 3288
3273 /* Reset those iterator values set from display property values. */ 3289 /* Reset those iterator values set from display property values. */
3274 it->font_height = Qnil; 3290 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3275 it->space_width = Qnil; 3291 it->space_width = Qnil;
3292 it->font_height = Qnil;
3276 it->voffset = 0; 3293 it->voffset = 0;
3277 3294
3278 /* We don't support recursive `display' properties, i.e. string 3295 /* We don't support recursive `display' properties, i.e. string
@@ -3291,6 +3308,7 @@ handle_display_prop (it)
3291 && !EQ (XCAR (prop), Qimage) 3308 && !EQ (XCAR (prop), Qimage)
3292 && !EQ (XCAR (prop), Qspace) 3309 && !EQ (XCAR (prop), Qspace)
3293 && !EQ (XCAR (prop), Qwhen) 3310 && !EQ (XCAR (prop), Qwhen)
3311 && !EQ (XCAR (prop), Qslice)
3294 && !EQ (XCAR (prop), Qspace_width) 3312 && !EQ (XCAR (prop), Qspace_width)
3295 && !EQ (XCAR (prop), Qheight) 3313 && !EQ (XCAR (prop), Qheight)
3296 && !EQ (XCAR (prop), Qraise) 3314 && !EQ (XCAR (prop), Qraise)
@@ -3487,6 +3505,30 @@ handle_single_display_prop (it, prop, object, position,
3487 it->space_width = value; 3505 it->space_width = value;
3488 } 3506 }
3489 else if (CONSP (prop) 3507 else if (CONSP (prop)
3508 && EQ (XCAR (prop), Qslice))
3509 {
3510 /* `(slice X Y WIDTH HEIGHT)'. */
3511 Lisp_Object tem;
3512
3513 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3514 return 0;
3515
3516 if (tem = XCDR (prop), CONSP (tem))
3517 {
3518 it->slice.x = XCAR (tem);
3519 if (tem = XCDR (tem), CONSP (tem))
3520 {
3521 it->slice.y = XCAR (tem);
3522 if (tem = XCDR (tem), CONSP (tem))
3523 {
3524 it->slice.width = XCAR (tem);
3525 if (tem = XCDR (tem), CONSP (tem))
3526 it->slice.height = XCAR (tem);
3527 }
3528 }
3529 }
3530 }
3531 else if (CONSP (prop)
3490 && EQ (XCAR (prop), Qraise) 3532 && EQ (XCAR (prop), Qraise)
3491 && CONSP (XCDR (prop))) 3533 && CONSP (XCDR (prop)))
3492 { 3534 {
@@ -4327,6 +4369,7 @@ push_it (it)
4327 p->string_nchars = it->string_nchars; 4369 p->string_nchars = it->string_nchars;
4328 p->area = it->area; 4370 p->area = it->area;
4329 p->multibyte_p = it->multibyte_p; 4371 p->multibyte_p = it->multibyte_p;
4372 p->slice = it->slice;
4330 p->space_width = it->space_width; 4373 p->space_width = it->space_width;
4331 p->font_height = it->font_height; 4374 p->font_height = it->font_height;
4332 p->voffset = it->voffset; 4375 p->voffset = it->voffset;
@@ -4359,6 +4402,7 @@ pop_it (it)
4359 it->string_nchars = p->string_nchars; 4402 it->string_nchars = p->string_nchars;
4360 it->area = p->area; 4403 it->area = p->area;
4361 it->multibyte_p = p->multibyte_p; 4404 it->multibyte_p = p->multibyte_p;
4405 it->slice = p->slice;
4362 it->space_width = p->space_width; 4406 it->space_width = p->space_width;
4363 it->font_height = p->font_height; 4407 it->font_height = p->font_height;
4364 it->voffset = p->voffset; 4408 it->voffset = p->voffset;
@@ -10758,15 +10802,14 @@ make_cursor_line_fully_visible (w, force_p)
10758 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row)) 10802 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10759 return 1; 10803 return 1;
10760 10804
10761 if (force_p)
10762 return 0;
10763
10764 /* If the row the cursor is in is taller than the window's height, 10805 /* If the row the cursor is in is taller than the window's height,
10765 it's not clear what to do, so do nothing. */ 10806 it's not clear what to do, so do nothing. */
10766 window_height = window_box_height (w); 10807 window_height = window_box_height (w);
10767 if (row->height >= window_height) 10808 if (row->height >= window_height)
10768 return 1; 10809 {
10769 10810 if (!force_p || w->vscroll)
10811 return 1;
10812 }
10770 return 0; 10813 return 0;
10771 10814
10772#if 0 10815#if 0
@@ -14153,8 +14196,12 @@ append_space (it, default_face_p)
14153 face = FACE_FROM_ID (it->f, it->face_id); 14196 face = FACE_FROM_ID (it->f, it->face_id);
14154 it->face_id = FACE_FOR_CHAR (it->f, face, 0); 14197 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14155 14198
14199 if (it->max_ascent > 0 || it->max_descent > 0)
14200 it->constrain_row_ascent_descent_p = 1;
14201
14156 PRODUCE_GLYPHS (it); 14202 PRODUCE_GLYPHS (it);
14157 14203
14204 it->constrain_row_ascent_descent_p = 0;
14158 it->current_x = saved_x; 14205 it->current_x = saved_x;
14159 it->object = saved_object; 14206 it->object = saved_object;
14160 it->position = saved_pos; 14207 it->position = saved_pos;
@@ -17301,6 +17348,7 @@ fill_image_glyph_string (s)
17301 xassert (s->first_glyph->type == IMAGE_GLYPH); 17348 xassert (s->first_glyph->type == IMAGE_GLYPH);
17302 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); 17349 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17303 xassert (s->img); 17350 xassert (s->img);
17351 s->slice = s->first_glyph->slice;
17304 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); 17352 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17305 s->font = s->face->font; 17353 s->font = s->face->font;
17306 s->width = s->first_glyph->pixel_width; 17354 s->width = s->first_glyph->pixel_width;
@@ -18099,7 +18147,7 @@ take_vertical_position_into_account (it)
18099 if (it->voffset < 0) 18147 if (it->voffset < 0)
18100 /* Increase the ascent so that we can display the text higher 18148 /* Increase the ascent so that we can display the text higher
18101 in the line. */ 18149 in the line. */
18102 it->ascent += abs (it->voffset); 18150 it->ascent -= it->voffset;
18103 else 18151 else
18104 /* Increase the descent so that we can display the text lower 18152 /* Increase the descent so that we can display the text lower
18105 in the line. */ 18153 in the line. */
@@ -18119,6 +18167,7 @@ produce_image_glyph (it)
18119 struct image *img; 18167 struct image *img;
18120 struct face *face; 18168 struct face *face;
18121 int face_ascent, glyph_ascent; 18169 int face_ascent, glyph_ascent;
18170 struct glyph_slice slice;
18122 18171
18123 xassert (it->what == IT_IMAGE); 18172 xassert (it->what == IT_IMAGE);
18124 18173
@@ -18142,19 +18191,68 @@ produce_image_glyph (it)
18142 /* Make sure X resources of the image is loaded. */ 18191 /* Make sure X resources of the image is loaded. */
18143 prepare_image_for_display (it->f, img); 18192 prepare_image_for_display (it->f, img);
18144 18193
18145 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face); 18194 slice.x = slice.y = 0;
18146 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; 18195 slice.width = img->width;
18147 it->pixel_width = img->width + 2 * img->hmargin; 18196 slice.height = img->height;
18197
18198 if (INTEGERP (it->slice.x))
18199 slice.x = XINT (it->slice.x);
18200 else if (FLOATP (it->slice.x))
18201 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18202
18203 if (INTEGERP (it->slice.y))
18204 slice.y = XINT (it->slice.y);
18205 else if (FLOATP (it->slice.y))
18206 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18207
18208 if (INTEGERP (it->slice.width))
18209 slice.width = XINT (it->slice.width);
18210 else if (FLOATP (it->slice.width))
18211 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18212
18213 if (INTEGERP (it->slice.height))
18214 slice.height = XINT (it->slice.height);
18215 else if (FLOATP (it->slice.height))
18216 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18217
18218 if (slice.x >= img->width)
18219 slice.x = img->width;
18220 if (slice.y >= img->height)
18221 slice.y = img->height;
18222 if (slice.x + slice.width >= img->width)
18223 slice.width = img->width - slice.x;
18224 if (slice.y + slice.height > img->height)
18225 slice.height = img->height - slice.y;
18226
18227 if (slice.width == 0 || slice.height == 0)
18228 return;
18229
18230 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18231
18232 it->descent = slice.height - glyph_ascent;
18233 if (slice.y == 0)
18234 it->descent += img->vmargin;
18235 if (slice.y + slice.height == img->height)
18236 it->descent += img->vmargin;
18237 it->phys_descent = it->descent;
18238
18239 it->pixel_width = slice.width;
18240 if (slice.x == 0)
18241 it->pixel_width += img->hmargin;
18242 if (slice.x + slice.width == img->width)
18243 it->pixel_width += img->hmargin;
18148 18244
18149 /* It's quite possible for images to have an ascent greater than 18245 /* It's quite possible for images to have an ascent greater than
18150 their height, so don't get confused in that case. */ 18246 their height, so don't get confused in that case. */
18151 if (it->descent < 0) 18247 if (it->descent < 0)
18152 it->descent = 0; 18248 it->descent = 0;
18153 18249
18250#if 0 /* this breaks image tiling */
18154 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */ 18251 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18155 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f); 18252 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18156 if (face_ascent > it->ascent) 18253 if (face_ascent > it->ascent)
18157 it->ascent = it->phys_ascent = face_ascent; 18254 it->ascent = it->phys_ascent = face_ascent;
18255#endif
18158 18256
18159 it->nglyphs = 1; 18257 it->nglyphs = 1;
18160 18258
@@ -18162,13 +18260,15 @@ produce_image_glyph (it)
18162 { 18260 {
18163 if (face->box_line_width > 0) 18261 if (face->box_line_width > 0)
18164 { 18262 {
18165 it->ascent += face->box_line_width; 18263 if (slice.y == 0)
18166 it->descent += face->box_line_width; 18264 it->ascent += face->box_line_width;
18265 if (slice.y + slice.height == img->height)
18266 it->descent += face->box_line_width;
18167 } 18267 }
18168 18268
18169 if (it->start_of_box_run_p) 18269 if (it->start_of_box_run_p && slice.x == 0)
18170 it->pixel_width += abs (face->box_line_width); 18270 it->pixel_width += abs (face->box_line_width);
18171 if (it->end_of_box_run_p) 18271 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18172 it->pixel_width += abs (face->box_line_width); 18272 it->pixel_width += abs (face->box_line_width);
18173 } 18273 }
18174 18274
@@ -18197,6 +18297,7 @@ produce_image_glyph (it)
18197 glyph->glyph_not_available_p = 0; 18297 glyph->glyph_not_available_p = 0;
18198 glyph->face_id = it->face_id; 18298 glyph->face_id = it->face_id;
18199 glyph->u.img_id = img->id; 18299 glyph->u.img_id = img->id;
18300 glyph->slice = slice;
18200 glyph->font_type = FONT_TYPE_UNKNOWN; 18301 glyph->font_type = FONT_TYPE_UNKNOWN;
18201 ++it->glyph_row->used[area]; 18302 ++it->glyph_row->used[area];
18202 } 18303 }
@@ -18488,8 +18589,9 @@ x_produce_glyphs (it)
18488 18589
18489 it->nglyphs = 1; 18590 it->nglyphs = 1;
18490 18591
18491 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b, 18592 pcm = FRAME_RIF (it->f)->per_char_metric
18492 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display)); 18593 (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18594
18493 it->ascent = FONT_BASE (font) + boff; 18595 it->ascent = FONT_BASE (font) + boff;
18494 it->descent = FONT_DESCENT (font) - boff; 18596 it->descent = FONT_DESCENT (font) - boff;
18495 18597
@@ -18502,11 +18604,27 @@ x_produce_glyphs (it)
18502 else 18604 else
18503 { 18605 {
18504 it->glyph_not_available_p = 1; 18606 it->glyph_not_available_p = 1;
18505 it->phys_ascent = FONT_BASE (font) + boff; 18607 it->phys_ascent = it->ascent;
18506 it->phys_descent = FONT_DESCENT (font) - boff; 18608 it->phys_descent = it->descent;
18507 it->pixel_width = FONT_WIDTH (font); 18609 it->pixel_width = FONT_WIDTH (font);
18508 } 18610 }
18509 18611
18612 if (it->constrain_row_ascent_descent_p)
18613 {
18614 if (it->descent > it->max_descent)
18615 {
18616 it->ascent += it->descent - it->max_descent;
18617 it->descent = it->max_descent;
18618 }
18619 if (it->ascent> it->max_ascent)
18620 {
18621 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18622 it->ascent = it->max_ascent;
18623 }
18624 it->phys_ascent = min (it->phys_ascent, it->ascent);
18625 it->phys_descent = min (it->phys_descent, it->descent);
18626 }
18627
18510 /* If this is a space inside a region of text with 18628 /* If this is a space inside a region of text with
18511 `space-width' property, change its width. */ 18629 `space-width' property, change its width. */
18512 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); 18630 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
@@ -18539,6 +18657,14 @@ x_produce_glyphs (it)
18539 if (face->overline_p) 18657 if (face->overline_p)
18540 it->ascent += 2; 18658 it->ascent += 2;
18541 18659
18660 if (it->constrain_row_ascent_descent_p)
18661 {
18662 if (it->ascent > it->max_ascent)
18663 it->ascent = it->max_ascent;
18664 if (it->descent > it->max_descent)
18665 it->descent = it->max_descent;
18666 }
18667
18542 take_vertical_position_into_account (it); 18668 take_vertical_position_into_account (it);
18543 18669
18544 /* If we have to actually produce glyphs, do it. */ 18670 /* If we have to actually produce glyphs, do it. */
@@ -18565,13 +18691,31 @@ x_produce_glyphs (it)
18565 } 18691 }
18566 else if (it->char_to_display == '\n') 18692 else if (it->char_to_display == '\n')
18567 { 18693 {
18568 /* A newline has no width but we need the height of the line. */ 18694 /* A newline has no width but we need the height of the line.
18695 But if previous part of the line set a height, don't
18696 increase that height */
18697
18569 it->pixel_width = 0; 18698 it->pixel_width = 0;
18570 it->nglyphs = 0; 18699 it->nglyphs = 0;
18571 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18572 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18573 18700
18574 if (face->box != FACE_NO_BOX 18701 it->ascent = FONT_BASE (font) + boff;
18702 it->descent = FONT_DESCENT (font) - boff;
18703
18704 if (it->max_ascent > 0 || it->max_descent > 0)
18705 {
18706 it->ascent = it->descent = 0;
18707 }
18708 else
18709 {
18710 it->ascent = FONT_BASE (font) + boff;
18711 it->descent = FONT_DESCENT (font) - boff;
18712 }
18713
18714 it->phys_ascent = it->ascent;
18715 it->phys_descent = it->descent;
18716
18717 if ((it->max_ascent > 0 || it->max_descent > 0)
18718 && face->box != FACE_NO_BOX
18575 && face->box_line_width > 0) 18719 && face->box_line_width > 0)
18576 { 18720 {
18577 it->ascent += face->box_line_width; 18721 it->ascent += face->box_line_width;
@@ -20544,7 +20688,9 @@ note_mouse_highlight (f, x, y)
20544 Lisp_Object image_map, hotspot; 20688 Lisp_Object image_map, hotspot;
20545 if ((image_map = Fplist_get (XCDR (img->spec), QCmap), 20689 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20546 !NILP (image_map)) 20690 !NILP (image_map))
20547 && (hotspot = find_hot_spot (image_map, dx, dy), 20691 && (hotspot = find_hot_spot (image_map,
20692 glyph->slice.x + dx,
20693 glyph->slice.y + dy),
20548 CONSP (hotspot)) 20694 CONSP (hotspot))
20549 && (hotspot = XCDR (hotspot), CONSP (hotspot))) 20695 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20550 { 20696 {
@@ -21583,6 +21729,8 @@ syms_of_xdisp ()
21583 staticpro (&Qspace_width); 21729 staticpro (&Qspace_width);
21584 Qraise = intern ("raise"); 21730 Qraise = intern ("raise");
21585 staticpro (&Qraise); 21731 staticpro (&Qraise);
21732 Qslice = intern ("slice");
21733 staticpro (&Qslice);
21586 Qspace = intern ("space"); 21734 Qspace = intern ("space");
21587 staticpro (&Qspace); 21735 staticpro (&Qspace);
21588 Qmargin = intern ("margin"); 21736 Qmargin = intern ("margin");
diff --git a/src/xterm.c b/src/xterm.c
index ea82a435b2b..838d4f2ad4b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -982,7 +982,8 @@ static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap));
982static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, 982static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
983 int, int, int)); 983 int, int, int));
984static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int, 984static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
985 int, int, int, int, XRectangle *)); 985 int, int, int, int, int, int,
986 XRectangle *));
986static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, 987static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
987 int, int, int, XRectangle *)); 988 int, int, int, XRectangle *));
988 989
@@ -2021,9 +2022,10 @@ x_setup_relief_colors (s)
2021 2022
2022static void 2023static void
2023x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, 2024x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2024 raised_p, left_p, right_p, clip_rect) 2025 raised_p, top_p, bot_p, left_p, right_p, clip_rect)
2025 struct frame *f; 2026 struct frame *f;
2026 int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p; 2027 int left_x, top_y, right_x, bottom_y, width;
2028 int top_p, bot_p, left_p, right_p, raised_p;
2027 XRectangle *clip_rect; 2029 XRectangle *clip_rect;
2028{ 2030{
2029 Display *dpy = FRAME_X_DISPLAY (f); 2031 Display *dpy = FRAME_X_DISPLAY (f);
@@ -2038,10 +2040,11 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2038 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); 2040 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2039 2041
2040 /* Top. */ 2042 /* Top. */
2041 for (i = 0; i < width; ++i) 2043 if (top_p)
2042 XDrawLine (dpy, window, gc, 2044 for (i = 0; i < width; ++i)
2043 left_x + i * left_p, top_y + i, 2045 XDrawLine (dpy, window, gc,
2044 right_x + 1 - i * right_p, top_y + i); 2046 left_x + i * left_p, top_y + i,
2047 right_x + 1 - i * right_p, top_y + i);
2045 2048
2046 /* Left. */ 2049 /* Left. */
2047 if (left_p) 2050 if (left_p)
@@ -2057,10 +2060,11 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2057 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); 2060 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2058 2061
2059 /* Bottom. */ 2062 /* Bottom. */
2060 for (i = 0; i < width; ++i) 2063 if (bot_p)
2061 XDrawLine (dpy, window, gc, 2064 for (i = 0; i < width; ++i)
2062 left_x + i * left_p, bottom_y - i, 2065 XDrawLine (dpy, window, gc,
2063 right_x + 1 - i * right_p, bottom_y - i); 2066 left_x + i * left_p, bottom_y - i,
2067 right_x + 1 - i * right_p, bottom_y - i);
2064 2068
2065 /* Right. */ 2069 /* Right. */
2066 if (right_p) 2070 if (right_p)
@@ -2168,7 +2172,7 @@ x_draw_glyph_string_box (s)
2168 { 2172 {
2169 x_setup_relief_colors (s); 2173 x_setup_relief_colors (s);
2170 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, 2174 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2171 width, raised_p, left_p, right_p, &clip_rect); 2175 width, raised_p, 1, 1, left_p, right_p, &clip_rect);
2172 } 2176 }
2173} 2177}
2174 2178
@@ -2179,21 +2183,22 @@ static void
2179x_draw_image_foreground (s) 2183x_draw_image_foreground (s)
2180 struct glyph_string *s; 2184 struct glyph_string *s;
2181{ 2185{
2182 int x; 2186 int x = s->x;
2183 int y = s->ybase - image_ascent (s->img, s->face); 2187 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2184 2188
2185 /* If first glyph of S has a left box line, start drawing it to the 2189 /* If first glyph of S has a left box line, start drawing it to the
2186 right of that line. */ 2190 right of that line. */
2187 if (s->face->box != FACE_NO_BOX 2191 if (s->face->box != FACE_NO_BOX
2188 && s->first_glyph->left_box_line_p) 2192 && s->first_glyph->left_box_line_p
2189 x = s->x + abs (s->face->box_line_width); 2193 && s->slice.x == 0)
2190 else 2194 x += abs (s->face->box_line_width);
2191 x = s->x;
2192 2195
2193 /* If there is a margin around the image, adjust x- and y-position 2196 /* If there is a margin around the image, adjust x- and y-position
2194 by that margin. */ 2197 by that margin. */
2195 x += s->img->hmargin; 2198 if (s->slice.x == 0)
2196 y += s->img->vmargin; 2199 x += s->img->hmargin;
2200 if (s->slice.y == 0)
2201 y += s->img->vmargin;
2197 2202
2198 if (s->img->pixmap) 2203 if (s->img->pixmap)
2199 { 2204 {
@@ -2218,11 +2223,12 @@ x_draw_image_foreground (s)
2218 get_glyph_string_clip_rect (s, &clip_rect); 2223 get_glyph_string_clip_rect (s, &clip_rect);
2219 image_rect.x = x; 2224 image_rect.x = x;
2220 image_rect.y = y; 2225 image_rect.y = y;
2221 image_rect.width = s->img->width; 2226 image_rect.width = s->slice.width;
2222 image_rect.height = s->img->height; 2227 image_rect.height = s->slice.height;
2223 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) 2228 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2224 XCopyArea (s->display, s->img->pixmap, s->window, s->gc, 2229 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2225 r.x - x, r.y - y, r.width, r.height, r.x, r.y); 2230 s->slice.x + r.x - x, s->slice.y + r.y - y,
2231 r.width, r.height, r.x, r.y);
2226 } 2232 }
2227 else 2233 else
2228 { 2234 {
@@ -2231,11 +2237,12 @@ x_draw_image_foreground (s)
2231 get_glyph_string_clip_rect (s, &clip_rect); 2237 get_glyph_string_clip_rect (s, &clip_rect);
2232 image_rect.x = x; 2238 image_rect.x = x;
2233 image_rect.y = y; 2239 image_rect.y = y;
2234 image_rect.width = s->img->width; 2240 image_rect.width = s->slice.width;
2235 image_rect.height = s->img->height; 2241 image_rect.height = s->slice.height;
2236 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) 2242 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2237 XCopyArea (s->display, s->img->pixmap, s->window, s->gc, 2243 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2238 r.x - x, r.y - y, r.width, r.height, r.x, r.y); 2244 s->slice.x + r.x - x, s->slice.y + r.y - y,
2245 r.width, r.height, r.x, r.y);
2239 2246
2240 /* When the image has a mask, we can expect that at 2247 /* When the image has a mask, we can expect that at
2241 least part of a mouse highlight or a block cursor will 2248 least part of a mouse highlight or a block cursor will
@@ -2247,15 +2254,17 @@ x_draw_image_foreground (s)
2247 { 2254 {
2248 int r = s->img->relief; 2255 int r = s->img->relief;
2249 if (r < 0) r = -r; 2256 if (r < 0) r = -r;
2250 XDrawRectangle (s->display, s->window, s->gc, x - r, y - r, 2257 XDrawRectangle (s->display, s->window, s->gc,
2251 s->img->width + r*2 - 1, s->img->height + r*2 - 1); 2258 x - r, y - r,
2259 s->slice.width + r*2 - 1,
2260 s->slice.height + r*2 - 1);
2252 } 2261 }
2253 } 2262 }
2254 } 2263 }
2255 else 2264 else
2256 /* Draw a rectangle if image could not be loaded. */ 2265 /* Draw a rectangle if image could not be loaded. */
2257 XDrawRectangle (s->display, s->window, s->gc, x, y, 2266 XDrawRectangle (s->display, s->window, s->gc, x, y,
2258 s->img->width - 1, s->img->height - 1); 2267 s->slice.width - 1, s->slice.height - 1);
2259} 2268}
2260 2269
2261 2270
@@ -2267,21 +2276,22 @@ x_draw_image_relief (s)
2267{ 2276{
2268 int x0, y0, x1, y1, thick, raised_p; 2277 int x0, y0, x1, y1, thick, raised_p;
2269 XRectangle r; 2278 XRectangle r;
2270 int x; 2279 int x = s->x;
2271 int y = s->ybase - image_ascent (s->img, s->face); 2280 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2272 2281
2273 /* If first glyph of S has a left box line, start drawing it to the 2282 /* If first glyph of S has a left box line, start drawing it to the
2274 right of that line. */ 2283 right of that line. */
2275 if (s->face->box != FACE_NO_BOX 2284 if (s->face->box != FACE_NO_BOX
2276 && s->first_glyph->left_box_line_p) 2285 && s->first_glyph->left_box_line_p
2277 x = s->x + abs (s->face->box_line_width); 2286 && s->slice.x == 0)
2278 else 2287 x += abs (s->face->box_line_width);
2279 x = s->x;
2280 2288
2281 /* If there is a margin around the image, adjust x- and y-position 2289 /* If there is a margin around the image, adjust x- and y-position
2282 by that margin. */ 2290 by that margin. */
2283 x += s->img->hmargin; 2291 if (s->slice.x == 0)
2284 y += s->img->vmargin; 2292 x += s->img->hmargin;
2293 if (s->slice.y == 0)
2294 y += s->img->vmargin;
2285 2295
2286 if (s->hl == DRAW_IMAGE_SUNKEN 2296 if (s->hl == DRAW_IMAGE_SUNKEN
2287 || s->hl == DRAW_IMAGE_RAISED) 2297 || s->hl == DRAW_IMAGE_RAISED)
@@ -2297,12 +2307,17 @@ x_draw_image_relief (s)
2297 2307
2298 x0 = x - thick; 2308 x0 = x - thick;
2299 y0 = y - thick; 2309 y0 = y - thick;
2300 x1 = x + s->img->width + thick - 1; 2310 x1 = x + s->slice.width + thick - 1;
2301 y1 = y + s->img->height + thick - 1; 2311 y1 = y + s->slice.height + thick - 1;
2302 2312
2303 x_setup_relief_colors (s); 2313 x_setup_relief_colors (s);
2304 get_glyph_string_clip_rect (s, &r); 2314 get_glyph_string_clip_rect (s, &r);
2305 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); 2315 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
2316 s->slice.y == 0,
2317 s->slice.y + s->slice.height == s->img->height,
2318 s->slice.x == 0,
2319 s->slice.x + s->slice.width == s->img->width,
2320 &r);
2306} 2321}
2307 2322
2308 2323
@@ -2313,21 +2328,22 @@ x_draw_image_foreground_1 (s, pixmap)
2313 struct glyph_string *s; 2328 struct glyph_string *s;
2314 Pixmap pixmap; 2329 Pixmap pixmap;
2315{ 2330{
2316 int x; 2331 int x = 0;
2317 int y = s->ybase - s->y - image_ascent (s->img, s->face); 2332 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
2318 2333
2319 /* If first glyph of S has a left box line, start drawing it to the 2334 /* If first glyph of S has a left box line, start drawing it to the
2320 right of that line. */ 2335 right of that line. */
2321 if (s->face->box != FACE_NO_BOX 2336 if (s->face->box != FACE_NO_BOX
2322 && s->first_glyph->left_box_line_p) 2337 && s->first_glyph->left_box_line_p
2323 x = abs (s->face->box_line_width); 2338 && s->slice.x == 0)
2324 else 2339 x += abs (s->face->box_line_width);
2325 x = 0;
2326 2340
2327 /* If there is a margin around the image, adjust x- and y-position 2341 /* If there is a margin around the image, adjust x- and y-position
2328 by that margin. */ 2342 by that margin. */
2329 x += s->img->hmargin; 2343 if (s->slice.x == 0)
2330 y += s->img->vmargin; 2344 x += s->img->hmargin;
2345 if (s->slice.y == 0)
2346 y += s->img->vmargin;
2331 2347
2332 if (s->img->pixmap) 2348 if (s->img->pixmap)
2333 { 2349 {
@@ -2349,13 +2365,15 @@ x_draw_image_foreground_1 (s, pixmap)
2349 XChangeGC (s->display, s->gc, mask, &xgcv); 2365 XChangeGC (s->display, s->gc, mask, &xgcv);
2350 2366
2351 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc, 2367 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2352 0, 0, s->img->width, s->img->height, x, y); 2368 s->slice.x, s->slice.y,
2369 s->slice.width, s->slice.height, x, y);
2353 XSetClipMask (s->display, s->gc, None); 2370 XSetClipMask (s->display, s->gc, None);
2354 } 2371 }
2355 else 2372 else
2356 { 2373 {
2357 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc, 2374 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2358 0, 0, s->img->width, s->img->height, x, y); 2375 s->slice.x, s->slice.y,
2376 s->slice.width, s->slice.height, x, y);
2359 2377
2360 /* When the image has a mask, we can expect that at 2378 /* When the image has a mask, we can expect that at
2361 least part of a mouse highlight or a block cursor will 2379 least part of a mouse highlight or a block cursor will
@@ -2368,14 +2386,15 @@ x_draw_image_foreground_1 (s, pixmap)
2368 int r = s->img->relief; 2386 int r = s->img->relief;
2369 if (r < 0) r = -r; 2387 if (r < 0) r = -r;
2370 XDrawRectangle (s->display, s->window, s->gc, x - r, y - r, 2388 XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
2371 s->img->width + r*2 - 1, s->img->height + r*2 - 1); 2389 s->slice.width + r*2 - 1,
2390 s->slice.height + r*2 - 1);
2372 } 2391 }
2373 } 2392 }
2374 } 2393 }
2375 else 2394 else
2376 /* Draw a rectangle if image could not be loaded. */ 2395 /* Draw a rectangle if image could not be loaded. */
2377 XDrawRectangle (s->display, pixmap, s->gc, x, y, 2396 XDrawRectangle (s->display, pixmap, s->gc, x, y,
2378 s->img->width - 1, s->img->height - 1); 2397 s->slice.width - 1, s->slice.height - 1);
2379} 2398}
2380 2399
2381 2400
@@ -2417,33 +2436,28 @@ static void
2417x_draw_image_glyph_string (s) 2436x_draw_image_glyph_string (s)
2418 struct glyph_string *s; 2437 struct glyph_string *s;
2419{ 2438{
2420 int x, y;
2421 int box_line_hwidth = abs (s->face->box_line_width); 2439 int box_line_hwidth = abs (s->face->box_line_width);
2422 int box_line_vwidth = max (s->face->box_line_width, 0); 2440 int box_line_vwidth = max (s->face->box_line_width, 0);
2423 int height; 2441 int height;
2424 Pixmap pixmap = None; 2442 Pixmap pixmap = None;
2425 2443
2426 height = s->height - 2 * box_line_vwidth; 2444 height = s->height;
2427 2445 if (s->slice.y == 0)
2446 height -= box_line_vwidth;
2447 if (s->slice.y + s->slice.height >= s->img->height)
2448 height -= box_line_vwidth;
2428 2449
2429 /* Fill background with face under the image. Do it only if row is 2450 /* Fill background with face under the image. Do it only if row is
2430 taller than image or if image has a clip mask to reduce 2451 taller than image or if image has a clip mask to reduce
2431 flickering. */ 2452 flickering. */
2432 s->stippled_p = s->face->stipple != 0; 2453 s->stippled_p = s->face->stipple != 0;
2433 if (height > s->img->height 2454 if (height > s->slice.height
2434 || s->img->hmargin 2455 || s->img->hmargin
2435 || s->img->vmargin 2456 || s->img->vmargin
2436 || s->img->mask 2457 || s->img->mask
2437 || s->img->pixmap == 0 2458 || s->img->pixmap == 0
2438 || s->width != s->background_width) 2459 || s->width != s->background_width)
2439 { 2460 {
2440 if (box_line_hwidth && s->first_glyph->left_box_line_p)
2441 x = s->x + box_line_hwidth;
2442 else
2443 x = s->x;
2444
2445 y = s->y + box_line_vwidth;
2446
2447 if (s->img->mask) 2461 if (s->img->mask)
2448 { 2462 {
2449 /* Create a pixmap as large as the glyph string. Fill it 2463 /* Create a pixmap as large as the glyph string. Fill it
@@ -2482,7 +2496,19 @@ x_draw_image_glyph_string (s)
2482 } 2496 }
2483 } 2497 }
2484 else 2498 else
2485 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height); 2499 {
2500 int x = s->x;
2501 int y = s->y;
2502
2503 if (s->first_glyph->left_box_line_p
2504 && s->slice.x == 0)
2505 x += box_line_hwidth;
2506
2507 if (s->slice.y == 0)
2508 y += box_line_vwidth;
2509
2510 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
2511 }
2486 2512
2487 s->background_filled_p = 1; 2513 s->background_filled_p = 1;
2488 } 2514 }
diff --git a/src/xterm.h b/src/xterm.h
index a350567cd46..56c1d059ac3 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -941,7 +941,6 @@ Lisp_Object display_x_get_resource P_ ((struct x_display_info *,
941struct frame *check_x_frame P_ ((Lisp_Object)); 941struct frame *check_x_frame P_ ((Lisp_Object));
942EXFUN (Fx_display_color_p, 1); 942EXFUN (Fx_display_color_p, 1);
943EXFUN (Fx_display_grayscale_p, 1); 943EXFUN (Fx_display_grayscale_p, 1);
944int image_ascent P_ ((struct image *, struct face *));
945extern void x_free_gcs P_ ((struct frame *)); 944extern void x_free_gcs P_ ((struct frame *));
946 945
947/* From xrdb.c. */ 946/* From xrdb.c. */