Mercurial > hg > xemacs-beta
diff src/redisplay-msw.c @ 227:0e522484dd2a r20-5b12
Import from CVS: tag r20-5b12
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:12:37 +0200 |
parents | 2c611d1463a6 |
children | 41f2f0e326e9 |
line wrap: on
line diff
--- a/src/redisplay-msw.c Mon Aug 13 10:11:42 2007 +0200 +++ b/src/redisplay-msw.c Mon Aug 13 10:12:37 2007 +0200 @@ -289,8 +289,10 @@ || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) bg_pmap = Qnil; - FillRect (FRAME_MSWINDOWS_DC (f), &rect, - COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background))); + /* #### This deals only with solid colors */ + mswindows_update_gc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, + cachel->background, Qnil, Qnil); + ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); } @@ -307,11 +309,13 @@ struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); struct face_cachel *cachel; - Lisp_Object font; + Lisp_Object font = Qnil; int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); HBRUSH brush; HDC hdc = FRAME_MSWINDOWS_DC (f); int real_char_p = (rb->type == RUNE_CHAR && rb->object.chr.ch != '\n'); + char *p_char = NULL; + int n_char = 0; RECT rect = { xpos, dl->ypos - dl->ascent, xpos + width, @@ -331,33 +335,37 @@ font = FACE_CACHEL_FONT (cachel, Vcharset_ascii); } - /* Clear the area */ - if (focus) - cachel = WINDOW_FACE_CACHEL (w, + + if (focus && real_char_p) + { + p_char = (char*) &rb->object.chr.ch; + n_char = 1; + } + + cachel = WINDOW_FACE_CACHEL (w, get_builtin_face_cache_index (w, Vtext_cursor_face)); - else if (!real_char_p) - cachel = WINDOW_FACE_CACHEL (w, rb->findex); + mswindows_update_gc (hdc, font, cachel->foreground, + cachel->background, Qnil, Qnil); + ExtTextOut (FRAME_MSWINDOWS_DC (f), xpos, dl->ypos, ETO_OPAQUE, + &rect, p_char, n_char, NULL); - brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background)); - FillRect (hdc, &rect, brush); + if (focus) + return; + + InflateRect (&rect, -1, -1); if (real_char_p) { - /* XXX FIXME: Need to clip if dl->clip!=0. How rare is this case? */ - /* Output the underlying character */ - mswindows_update_gc (hdc, font, cachel->foreground, - cachel->background, Qnil, Qnil); - TextOut(hdc, xpos, dl->ypos, (char*) &rb->object.chr.ch, 1); + p_char = (char*) &rb->object.chr.ch; + n_char = 1; } - if (!focus) - { - /* Draw hollow rectangle in cursor's background color */ - cachel = WINDOW_FACE_CACHEL (w, - get_builtin_face_cache_index (w, Vtext_cursor_face)); - brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background)); - FrameRect (hdc, &rect, brush); - } + cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? rb->findex + : get_builtin_face_cache_index (w, Vdefault_face))); + mswindows_update_gc (hdc, Qnil, cachel->foreground, + cachel->background, Qnil, Qnil); + ExtTextOut (FRAME_MSWINDOWS_DC (f), xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, + &rect, p_char, n_char, NULL); } @@ -437,52 +445,83 @@ Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); int this_width; - int need_clipping; RECT rect = { clip_start, dl->ypos - dl->ascent, clip_end, dl->ypos + dl->descent - dl->clip }; - HRGN region; if (EQ (font, Vthe_null_font_instance)) continue; mswindows_update_gc (hdc, font, cachel->foreground, - cachel->background, Qnil, Qnil); + NILP(bg_pmap) ? cachel->background : Qnil, + Qnil, Qnil); this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); - need_clipping = (dl->clip || clip_start > xpos || - clip_end < xpos + this_width); - if (need_clipping) - { - region = CreateRectRgn (rect.left, rect.top, - rect.right, rect.bottom); - SelectClipRgn (hdc, region); - } - - /* TextOut only clears the area equal to the height of - 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 (fi->ascent < dl->ascent || fi->descent < dl->descent-dl->clip) - FillRect (hdc, &rect, - COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (cachel->background))); + /* #### bg_pmap should be output here */ assert (runs[i].dimension == 1); /* XXX FIXME */ - TextOut(hdc, xpos, dl->ypos, (char *) runs[i].ptr, runs[i].len); + ExtTextOut (hdc, xpos, dl->ypos, + NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, + &rect, (char *) runs[i].ptr, runs[i].len, NULL); /* XXX FIXME? X does underline/strikethrough here we will do it as part of face's font */ - if (need_clipping) - { - SelectClipRgn (hdc, NULL); - DeleteObject (region); - } - xpos += this_width; } } + +#ifdef HAVE_SCROLLBARS +/* + * This function paints window's deadbox, a rectangle between window + * borders and two short edges of both scrollbars. + * + * Function checks whether deadbox intersects with the rectangle pointed + * to by PRC, and paints only the intersection + */ +static void +mswindows_redisplay_deadbox_maybe (CONST struct window *w, + CONST RECT* prc) +{ + int sbh = window_scrollbar_height (w); + int sbw = window_scrollbar_width (w); + RECT rect_dead, rect_paint; + struct frame *f; + if (sbh == 0 || sbw == 0) + return; + + f = XFRAME (WINDOW_FRAME (w)); + if (f->scrollbar_on_left) + { + rect_dead.left = WINDOW_LEFT (w); + rect_dead.right = WINDOW_LEFT (w) + sbw; + } + else + { + rect_dead.left = WINDOW_RIGHT (w) - sbw; + rect_dead.right = WINDOW_RIGHT (w); + } + + if (f->scrollbar_on_top) + { + rect_dead.top = WINDOW_TOP (w); + rect_dead.bottom = WINDOW_TOP (w) + sbh; + } + else + { + int modh = window_modeline_height (w); + rect_dead.top = WINDOW_BOTTOM (w) - modh - sbh; + rect_dead.bottom = WINDOW_BOTTOM (w) - modh; + } + + if (IntersectRect (&rect_paint, &rect_dead, prc)) + FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint, + (HBRUSH)GetClassLong (FRAME_MSWINDOWS_HANDLE(f), GCL_HBRBACKGROUND)); +} + +#endif /* HAVE_SCROLLBARS */ + /***************************************************************************** mswindows_redraw_exposed_window @@ -497,8 +536,11 @@ { struct frame *f = XFRAME (w->frame); int line; - int start_x, start_y, end_x, end_y; int orig_windows_structure_changed; + RECT rect_window = { WINDOW_LEFT (w), WINDOW_TOP (w), + WINDOW_RIGHT (w), WINDOW_BOTTOM (w) }; + RECT rect_expose = { x, y, x + width, y + height }; + RECT rect_draw; display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); @@ -514,23 +556,13 @@ } /* If the window doesn't intersect the exposed region, we're done here. */ - if (x >= WINDOW_RIGHT (w) || (x + width) <= WINDOW_LEFT (w) - || y >= WINDOW_BOTTOM (w) || (y + height) <= WINDOW_TOP (w)) - { + if (!IntersectRect (&rect_draw, &rect_window, &rect_expose)) return; - } - else - { - start_x = max (WINDOW_LEFT (w), x); - end_x = min (WINDOW_RIGHT (w), (x + width)); - start_y = max (WINDOW_TOP (w), y); - end_y = min (WINDOW_BOTTOM (w), y + height); - /* We do this to make sure that the 3D modelines get redrawn if - they are in the exposed region. */ - orig_windows_structure_changed = f->windows_structure_changed; - f->windows_structure_changed = 1; - } + /* We do this to make sure that the 3D modelines get redrawn if + they are in the exposed region. */ + orig_windows_structure_changed = f->windows_structure_changed; + f->windows_structure_changed = 1; if (window_needs_vertical_divider (w)) { @@ -543,9 +575,9 @@ int top_y = cdl->ypos - cdl->ascent; int bottom_y = cdl->ypos + cdl->descent; - if (bottom_y >= start_y) + if (bottom_y >= rect_draw.top) { - if (top_y > end_y) + if (top_y > rect_draw.bottom) { if (line == 0) continue; @@ -554,7 +586,8 @@ } else { - output_display_line (w, 0, cdla, line, start_x, end_x); + output_display_line (w, 0, cdla, line, + rect_draw.left, rect_draw.right); } } } @@ -564,7 +597,11 @@ /* If there have never been any face cache_elements created, then this expose event doesn't actually have anything to do. */ if (Dynarr_largest (w->face_cachels)) - redisplay_clear_bottom_of_window (w, cdla, start_y, end_y); + redisplay_clear_bottom_of_window (w, cdla, rect_draw.top, rect_draw.bottom); + +#ifdef HAVE_SCROLLBARS + mswindows_redisplay_deadbox_maybe (w, &rect_expose); +#endif } /***************************************************************************** @@ -977,8 +1014,7 @@ /* Draw the divider line */ color = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); mswindows_update_gc(FRAME_MSWINDOWS_DC(f), Qnil, Qnil, color, Qnil, Qnil); - brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (color)); - FillRect (FRAME_MSWINDOWS_DC(f), &rect, brush); + ExtTextOut (FRAME_MSWINDOWS_DC(f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); if (shadow_width) DrawEdge (FRAME_MSWINDOWS_DC(f), &rect, shadow_width==1 ? BDR_RAISEDINNER : EDGE_RAISED, @@ -1092,18 +1128,22 @@ /* XX FIXME: Get brush from background_pixmap here */ assert(0); + FillRect (FRAME_MSWINDOWS_DC(f), &rect, brush); } else { Lisp_Object color = (w ? WINDOW_FACE_CACHEL_BACKGROUND (w, findex) : FACE_BACKGROUND (Vdefault_face, locale)); - brush = COLOR_INSTANCE_MSWINDOWS_BRUSH (XCOLOR_INSTANCE (color)); + mswindows_update_gc(FRAME_MSWINDOWS_DC(f), Qnil, Qnil, color, Qnil, Qnil); + ExtTextOut (FRAME_MSWINDOWS_DC(f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); } - FillRect (FRAME_MSWINDOWS_DC(f), &rect, brush); +#ifdef HAVE_SCROLLBARS + if (WINDOWP (locale)) + mswindows_redisplay_deadbox_maybe (w, &rect); +#endif } - /***************************************************************************** mswindows_clear_to_window_end