Index: redisplay-msw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-msw.c,v retrieving revision 1.28.2.6 diff -u -r1.28.2.6 redisplay-msw.c --- redisplay-msw.c 1999/08/24 08:38:43 1.28.2.6 +++ redisplay-msw.c 1999/08/25 16:02:41 @@ -294,11 +294,13 @@ of its face. ****************************************************************************/ static void -mswindows_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos) +mswindows_output_blank (struct window *w, struct display_line *dl, + struct rune *rb, int start_pixpos) { struct frame *f = XFRAME (w->frame); - RECT rect = { rb->xpos, dl->ypos-dl->ascent, - rb->xpos+rb->width, dl->ypos+dl->descent-dl->clip }; + RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), + rb->xpos+rb->width, + DISPLAY_LINE_YEND (dl) }; struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); @@ -352,9 +354,9 @@ char *p_char = NULL; int n_char = 0; RECT rect = { xpos, - dl->ypos - dl->ascent, + DISPLAY_LINE_YPOS (dl), xpos + width, - dl->ypos + dl->descent - dl->clip}; + DISPLAY_LINE_YEND (dl) }; Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, WINDOW_BUFFER (w)); int bar_p = image_p || !NILP (bar); @@ -499,9 +501,9 @@ /* sort out the destination rectangle */ height = DISPLAY_LINE_HEIGHT (dl); rect.left = clip_start; - rect.top = dl->ypos - dl->ascent; + rect.top = DISPLAY_LINE_YPOS (dl); rect.right = clip_end; - rect.bottom = height + dl->ypos - dl->ascent; + rect.bottom = rect.top + height; /* output the background pixmap if there is one */ bg_pmap = cachel->background_pixmap; @@ -543,14 +545,14 @@ this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); /* cope with fonts taller than lines */ - if ((int) fi->height < (int) (height + dl->clip)) + if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) { int clear_start = max (xpos, clip_start); int clear_end = min (xpos + this_width, clip_end); { redisplay_clear_region (window, findex, clear_start, - dl->ypos - dl->ascent, + DISPLAY_LINE_YPOS (dl), clear_end - clear_start, height); /* output pixmap calls this so we have to recall to get correct @@ -794,12 +796,11 @@ for (line = 0; line < Dynarr_length (cdla); line++) { struct display_line *cdl = Dynarr_atp (cdla, line); - int top_y = cdl->ypos - cdl->ascent; - int bottom_y = cdl->ypos + cdl->descent; - if (bottom_y >= rect_draw.top) + if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl) + >= rect_draw.top) { - if (top_y > rect_draw.bottom) + if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom) { if (line == 0) continue; @@ -1086,10 +1087,9 @@ else if (rb->object.chr.ch == '\n') { /* Clear in case a cursor was formerly here. */ - int height = DISPLAY_LINE_HEIGHT (dl); - - redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, - rb->width, height); + redisplay_clear_region (window, findex, xpos, + DISPLAY_LINE_YPOS (dl), + rb->width, DISPLAY_LINE_HEIGHT (dl)); elt++; } } Index: redisplay-output.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-output.c,v retrieving revision 1.11.2.12 diff -u -r1.11.2.12 redisplay-output.c --- redisplay-output.c 1999/08/24 08:38:44 1.11.2.12 +++ redisplay-output.c 1999/08/25 16:03:18 @@ -598,6 +598,7 @@ (cdl && (cdl->ypos != ddl->ypos || cdl->ascent != ddl->ascent || cdl->descent != ddl->descent || + cdl->top_clip != ddl->top_clip || cdl->clip != ddl->clip))) { int x, y, width, height; @@ -605,9 +606,9 @@ must_sync = 1; x = start_pixpos; - y = ddl->ypos - ddl->ascent; + y = DISPLAY_LINE_YPOS (ddl); width = min (next_start_pixpos, block_end) - x; - height = ddl->ascent + ddl->descent - ddl->clip; + height = DISPLAY_LINE_HEIGHT (ddl); if (x < ddl->bounds.left_in) { @@ -722,8 +723,8 @@ if (f->windows_structure_changed || f->faces_changed || clear_border || f->clear) { - int y = ddl->ypos - ddl->ascent; - int height = ddl->ascent + ddl->descent - ddl->clip; + int y = DISPLAY_LINE_YPOS (ddl); + int height = DISPLAY_LINE_HEIGHT (ddl); if (ddl->modeline) { @@ -1489,18 +1490,6 @@ { /* assume dest->xpos >= 0 */ int clear_x; -#if 0 - /* This works because xoffset can be -ve as well as +ve */ - if (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width) - { - if (glyphsrc->xoffset > 0) - clear_width = dest->width - glyphsrc->xoffset; - else - clear_width = dest->width; - } - else - clear_width = glyphsrc->width; -#endif if (glyphsrc->xoffset > 0) { @@ -1519,20 +1508,21 @@ } else { + int yoffset = (glyphsrc->yoffset > 0 ? glyphsrc->yoffset : 0); /* first the top box */ - if (glyphsrc->yoffset > 0) + if (yoffset > 0) { redisplay_clear_region (window, findex, clear_x, dest->ypos, - glyphsrc->width, glyphsrc->yoffset); + glyphsrc->width, yoffset); } /* Then the bottom box */ - if (glyphsrc->yoffset + glyphsrc->height < dest->height) + if (yoffset + glyphsrc->height < dest->height) { redisplay_clear_region (window, findex, clear_x, - dest->ypos + glyphsrc->yoffset + glyphsrc->height, + dest->ypos + yoffset + glyphsrc->height, glyphsrc->width, - dest->height - (glyphsrc->yoffset + glyphsrc->height)); + dest->height - (yoffset + glyphsrc->height)); } } @@ -1672,7 +1662,7 @@ dest->height = DISPLAY_LINE_HEIGHT (dl); src->xoffset = -xoffset; - src->yoffset = 0; + src->yoffset = -dl->top_clip; src->width = 0; src->height = 0; Index: redisplay-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-x.c,v retrieving revision 1.23.2.9 diff -u -r1.23.2.9 redisplay-x.c --- redisplay-x.c 1999/08/24 08:38:44 1.23.2.9 +++ redisplay-x.c 1999/08/25 16:04:22 @@ -402,10 +402,10 @@ else if (rb->object.chr.ch == '\n') { /* Clear in case a cursor was formerly here. */ - int height = dl->ascent + dl->descent - dl->clip; - - redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, - rb->width, height); + redisplay_clear_region (window, findex, xpos, + DISPLAY_LINE_YPOS (dl), + rb->width, + DISPLAY_LINE_HEIGHT (dl)); elt++; } } @@ -815,7 +815,7 @@ if (width < 0) width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); - height = dl->ascent + dl->descent - dl->clip; + height = DISPLAY_LINE_HEIGHT (dl); /* Regularize the variables passed in. */ @@ -872,7 +872,7 @@ if (bgc) XFillRectangle (dpy, x_win, bgc, clip_start, - dl->ypos - dl->ascent, clip_end - clip_start, + DISPLAY_LINE_YPOS (dl), clip_end - clip_start, height); for (i = 0; i < nruns; i++) @@ -893,7 +893,7 @@ the given font. It is possible that a font is being displayed on a line taller than it is, so this would cause us to fail to clear some areas. */ - if ((int) fi->height < (int) (height + dl->clip)) + if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) { int clear_start = max (xpos, clip_start); int clear_end = min (xpos + this_width, clip_end); @@ -904,8 +904,8 @@ ypos1_string = dl->ypos - fi->ascent; ypos2_string = dl->ypos + fi->descent; - ypos1_line = dl->ypos - dl->ascent; - ypos2_line = dl->ypos + dl->descent - dl->clip; + ypos1_line = DISPLAY_LINE_YPOS (dl); + ypos2_line = ypos1_line + DISPLAY_LINE_HEIGHT (dl); /* Make sure we don't clear below the real bottom of the line. */ @@ -964,7 +964,7 @@ clip_box[0].width = clip_end - clip_start; clip_box[0].height = height; - XSetClipRectangles (dpy, gc, clip_start, dl->ypos - dl->ascent, + XSetClipRectangles (dpy, gc, clip_start, DISPLAY_LINE_YPOS (dl), clip_box, 1, Unsorted); } @@ -1124,12 +1124,12 @@ tmp_y = dl->ypos - bogusly_obtained_ascent_value; tmp_height = cursor_height; - if (tmp_y + tmp_height > (int) (dl->ypos - dl->ascent + height)) + if (tmp_y + tmp_height > (int) (DISPLAY_LINE_YPOS(dl) + height)) { - tmp_y = dl->ypos - dl->ascent + height - tmp_height; - if (tmp_y < (int) (dl->ypos - dl->ascent)) - tmp_y = dl->ypos - dl->ascent; - tmp_height = dl->ypos - dl->ascent + height - tmp_y; + tmp_y = DISPLAY_LINE_YPOS (dl) + height - tmp_height; + if (tmp_y < (int) (DISPLAY_LINE_YPOS (dl))) + tmp_y = DISPLAY_LINE_YPOS (dl); + tmp_height = DISPLAY_LINE_YPOS (dl) + height - tmp_y; } if (need_clipping) @@ -1381,9 +1381,9 @@ buffer); int x = rb->xpos; - int y = dl->ypos - dl->ascent; + int y = DISPLAY_LINE_YPOS (dl); int width = rb->width; - int height = dl->ascent + dl->descent - dl->clip; + int height = DISPLAY_LINE_HEIGHT (dl); if (start_pixpos > x) { @@ -1477,10 +1477,10 @@ int x = rb->xpos; int width = rb->width; - int height = dl->ascent + dl->descent - dl->clip; + int height = DISPLAY_LINE_HEIGHT (dl); int ypos1, ypos2, ypos3, ypos4; - ypos1 = dl->ypos - dl->ascent; + ypos1 = DISPLAY_LINE_YPOS (dl); ypos2 = ypos1 + rb->object.hline.yoffset; ypos3 = ypos2 + rb->object.hline.thickness; ypos4 = dl->ypos + dl->descent - dl->clip; @@ -1846,9 +1846,9 @@ WINDOW_BUFFER (w)); int x = xpos; - int y = dl->ypos - dl->ascent; + int y = DISPLAY_LINE_YPOS (dl); int width = EOL_CURSOR_WIDTH; - int height = dl->ascent + dl->descent - dl->clip; + int height = DISPLAY_LINE_HEIGHT (dl); int cursor_height, cursor_y; int defheight, defascent; Index: redisplay.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.c,v retrieving revision 1.55.2.11 diff -u -r1.55.2.11 redisplay.c --- redisplay.c 1999/08/16 11:18:54 1.55.2.11 +++ redisplay.c 1999/08/25 16:05:00 @@ -5066,6 +5066,7 @@ struct buffer *b = XBUFFER (w->buffer); int ypos = WINDOW_TEXT_TOP (w); int yend; /* set farther down */ + int yclip = WINDOW_TEXT_TOP_CLIP (w); prop_block_dynarr *prop; layout_bounds bounds; @@ -5142,15 +5143,36 @@ dlp->offset = 0; start_pos = generate_display_line (w, dlp, 1, start_pos, w->hscroll, &prop, type); - dlp->ypos = ypos + dlp->ascent; + + if (yclip > dlp->ascent) + { + /* this should never happen, but if it does just display the + whole line */ + yclip = 0; + } + + dlp->ypos = (ypos + dlp->ascent) - yclip; ypos = dlp->ypos + dlp->descent; + /* See if we've been asked to start midway through a line, for + partial display line scrolling. */ + if (yclip) + { + dlp->top_clip = yclip; + yclip = 0; + } + else + dlp->top_clip = 0; + if (ypos > yend) { int visible_height = dlp->ascent + dlp->descent; dlp->clip = (ypos - yend); - visible_height -= dlp->clip; + /* Although this seems strange we could have a single very + tall line visible for which we need to account for both + the top clip and the bottom clip. */ + visible_height -= (dlp->clip + dlp->top_clip); if (visible_height < VERTICAL_CLIP (w, 1)) { @@ -5412,6 +5434,7 @@ if (cdl->ypos != ddl->ypos || cdl->ascent != ddl->ascent || cdl->descent != ddl->descent + || cdl->top_clip != ddl->top_clip || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1) || old_start != ddl->bufpos @@ -5585,6 +5608,7 @@ if (cdl->ypos != ddl->ypos || cdl->ascent != ddl->ascent || cdl->descent != ddl->descent + || cdl->top_clip != ddl->top_clip || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)) { Index: redisplay.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.h,v retrieving revision 1.7.2.6 diff -u -r1.7.2.6 redisplay.h --- redisplay.h 1999/08/24 08:38:45 1.7.2.6 +++ redisplay.h 1999/08/25 16:05:02 @@ -145,8 +145,8 @@ /* HLINE */ struct { - int thickness; /* how thick to make hline */ - int yoffset; /* how far down from top of line to put top */ + short thickness; /* how thick to make hline */ + short yoffset; /* how far down from top of line to put top */ } hline; } object; /* actual rune object */ }; @@ -273,6 +273,8 @@ pixel-row itself, I think. */ unsigned short clip; /* amount of bottom of line to clip in pixels.*/ + unsigned short top_clip; /* amount of top of line to clip + in pixels.*/ Bufpos bufpos; /* first buffer position on line */ Bufpos end_bufpos; /* last buffer position on line */ Charcount offset; /* adjustment to bufpos vals */ @@ -301,9 +303,11 @@ }; #define DISPLAY_LINE_HEIGHT(dl) \ -(dl->ascent + dl->descent - dl->clip) +(dl->ascent + dl->descent - (dl->clip + dl->top_clip)) #define DISPLAY_LINE_YPOS(dl) \ -(dl->ypos - dl->ascent) +(dl->ypos - (dl->ascent - dl->top_clip)) +#define DISPLAY_LINE_YEND(dl) \ +((dl->ypos + dl->descent) - dl->clip) typedef struct { Index: window.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/window.c,v retrieving revision 1.41.2.13 diff -u -r1.41.2.13 window.c --- window.c 1999/08/08 20:53:41 1.41.2.13 +++ window.c 1999/08/25 16:05:22 @@ -3910,7 +3910,8 @@ -/* Scroll contents of window WINDOW up N lines. */ +/* Scroll contents of window WINDOW up N lines. If N < (top line height / + average line height) then we just adjust the top clip. */ void window_scroll (Lisp_Object window, Lisp_Object n, int direction, Error_behavior errb) @@ -3920,6 +3921,9 @@ int selected = EQ (window, Fselected_window (Qnil)); int value = 0; Lisp_Object point, tem; + display_line_dynarr *dla; + int fheight, fwidth, modeline = 0; + struct display_line* dl; if (selected) point = make_int (BUF_PT (b)); @@ -3949,6 +3953,7 @@ window, Qnil); Fset_marker (w->start[CURRENT_DISP], point, w->buffer); w->start_at_line_beg = beginning_of_line_p (b, XINT (point)); + WINDOW_TEXT_TOP_CLIP (w) = 0; MARK_WINDOWS_CHANGED (w); } @@ -3992,82 +3997,138 @@ { return; } - else if (value > 0) - { - int vtarget; - Bufpos startp, old_start; - - old_start = marker_position (w->start[CURRENT_DISP]); - startp = vmotion (w, old_start, value, &vtarget); - if (vtarget < value && - (w->window_end_pos[CURRENT_DISP] == -1 - || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b)))) + /* Determine parameters to test for partial line scrolling with. */ + dla = window_display_lines (w, CURRENT_DISP); + default_face_height_and_width (window, &fheight, &fwidth); + + if (Dynarr_length (dla) >= 1) + modeline = Dynarr_atp (dla, 0)->modeline; + + dl = Dynarr_atp (dla, modeline); + + if (value > 0) + { + /* Go for partial display line scrolling. This just means bumping + the clip by a reasonable amount and redisplaying, everything else + remains unchanged. */ + if (Dynarr_length (dla) >= (1 + modeline) + && + (dl->ascent - dl->top_clip) - fheight * value > 0) { - maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb); - return; + WINDOW_TEXT_TOP_CLIP (w) += value * fheight; + MARK_WINDOWS_CHANGED (w); } else { - set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), - w->buffer); - w->force_start = 1; - w->start_at_line_beg = beginning_of_line_p (b, startp); - MARK_WINDOWS_CHANGED (w); + int vtarget; + Bufpos startp, old_start; + + if (WINDOW_TEXT_TOP_CLIP (w)) + { + WINDOW_TEXT_TOP_CLIP (w) = 0; + MARK_WINDOWS_CHANGED (w); + } - if (!point_would_be_visible (w, startp, XINT (point))) + old_start = marker_position (w->start[CURRENT_DISP]); + startp = vmotion (w, old_start, value, &vtarget); + + if (vtarget < value && + (w->window_end_pos[CURRENT_DISP] == -1 + || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b)))) { - if (selected) - BUF_SET_PT (b, startp); - else - set_marker_restricted (w->pointm[CURRENT_DISP], - make_int (startp), - w->buffer); + maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb); + return; + } + else + { + set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), + w->buffer); + w->force_start = 1; + w->start_at_line_beg = beginning_of_line_p (b, startp); + MARK_WINDOWS_CHANGED (w); + + if (!point_would_be_visible (w, startp, XINT (point))) + { + if (selected) + BUF_SET_PT (b, startp); + else + set_marker_restricted (w->pointm[CURRENT_DISP], + make_int (startp), + w->buffer); + } } } } else if (value < 0) { - int vtarget; - Bufpos startp, old_start; - - old_start = marker_position (w->start[CURRENT_DISP]); - startp = vmotion (w, old_start, value, &vtarget); - - if (vtarget > value - && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) + /* Go for partial display line scrolling. This just means bumping + the clip by a reasonable amount and redisplaying, everything else + remains unchanged. */ + if (Dynarr_length (dla) >= (1 + modeline) + && + (dl->ascent - dl->top_clip) - fheight * value < + (dl->ascent + dl->descent - dl->clip) + && + WINDOW_TEXT_TOP_CLIP (w) + value * fheight > 0) { - maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); - return; + WINDOW_TEXT_TOP_CLIP (w) += value * fheight; + MARK_WINDOWS_CHANGED (w); } else { - set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), - w->buffer); - w->force_start = 1; - w->start_at_line_beg = beginning_of_line_p (b, startp); - MARK_WINDOWS_CHANGED (w); - - if (!point_would_be_visible (w, startp, XINT (point))) + int vtarget; + Bufpos startp, old_start; + + if (WINDOW_TEXT_TOP_CLIP (w)) { - Bufpos new_point; - - if (MINI_WINDOW_P (w)) - new_point = startp; - else - new_point = start_of_last_line (w, startp); - - if (selected) - BUF_SET_PT (b, new_point); - else - set_marker_restricted (w->pointm[CURRENT_DISP], - make_int (new_point), - w->buffer); + WINDOW_TEXT_TOP_CLIP (w) = 0; + MARK_WINDOWS_CHANGED (w); + } + + old_start = marker_position (w->start[CURRENT_DISP]); + startp = vmotion (w, old_start, value, &vtarget); + + if (vtarget > value + && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) + { + maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); + return; } + else + { + set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), + w->buffer); + w->force_start = 1; + w->start_at_line_beg = beginning_of_line_p (b, startp); + MARK_WINDOWS_CHANGED (w); + + if (!point_would_be_visible (w, startp, XINT (point))) + { + Bufpos new_point; + + if (MINI_WINDOW_P (w)) + new_point = startp; + else + new_point = start_of_last_line (w, startp); + + if (selected) + BUF_SET_PT (b, new_point); + else + set_marker_restricted (w->pointm[CURRENT_DISP], + make_int (new_point), + w->buffer); + } + } } } else /* value == 0 && direction == -1 */ { + if (WINDOW_TEXT_TOP_CLIP (w)) + { + WINDOW_TEXT_TOP_CLIP (w) = 0; + MARK_WINDOWS_CHANGED (w); + } if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) { maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); @@ -4105,7 +4166,6 @@ } } } - } DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /* Index: window.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/window.h,v retrieving revision 1.13.2.3 diff -u -r1.13.2.3 window.h --- window.h 1999/07/16 19:05:45 1.13.2.3 +++ window.h 1999/08/25 16:07:22 @@ -130,6 +130,14 @@ int hscroll; /* Idem for the window's modeline */ int modeline_hscroll; + /* Amount to clip off the top line for pixel-based scrolling. Point + will remain constant but this will be incremented to + incrementally shift lines up. */ + int top_yoffset; + /* Amount to clip off the left of the lines for pixel-based + scrolling. Hscroll will remain constant but this will be + incremented to incrementally shift lines left.*/ + int left_xoffset; /* Number saying how recently window was selected */ Lisp_Object use_time; /* text.modified of displayed buffer as of last time display completed */ @@ -382,6 +390,7 @@ /* XEmacs window size and positioning macros. */ #define WINDOW_TOP(w) ((w)->pixel_top) #define WINDOW_TEXT_TOP(w) (WINDOW_TOP (w) + window_top_gutter_height (w)) +#define WINDOW_TEXT_TOP_CLIP(w) ((w)->top_yoffset) #define WINDOW_BOTTOM(w) ((w)->pixel_top + (w)->pixel_height) #define WINDOW_TEXT_BOTTOM(w) (WINDOW_BOTTOM (w) - window_bottom_gutter_height (w)) #define WINDOW_LEFT(w) ((w)->pixel_left)