Revert "Make all NS drawing be done from drawRect"
This reverts commit 7946445962
.
This commit is contained in:
parent
6b955c26f6
commit
3ad7813296
1 changed files with 327 additions and 262 deletions
589
src/nsterm.m
589
src/nsterm.m
|
@ -287,7 +287,12 @@ - (NSColor *)colorUsingDefaultColorSpace
|
|||
long context_menu_value = 0;
|
||||
|
||||
/* display update */
|
||||
static struct frame *ns_updating_frame;
|
||||
static NSView *focus_view = NULL;
|
||||
static int ns_window_num = 0;
|
||||
#ifdef NS_IMPL_GNUSTEP
|
||||
static NSRect uRect; // TODO: This is dead, remove it?
|
||||
#endif
|
||||
static BOOL gsaved = NO;
|
||||
static BOOL ns_fake_keydown = NO;
|
||||
#ifdef NS_IMPL_COCOA
|
||||
|
@ -1098,13 +1103,12 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
|||
external (RIF) call; whole frame, called before gui_update_window_begin
|
||||
-------------------------------------------------------------------------- */
|
||||
{
|
||||
#ifdef NS_IMPL_COCOA
|
||||
EmacsView *view = FRAME_NS_VIEW (f);
|
||||
|
||||
NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_begin");
|
||||
|
||||
ns_update_auto_hide_menu_bar ();
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
if ([view isFullscreen] && [view fsIsNative])
|
||||
{
|
||||
// Fix reappearing tool bar in fullscreen for Mac OS X 10.7
|
||||
|
@ -1114,6 +1118,36 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
|||
[toolbar setVisible: tbar_visible];
|
||||
}
|
||||
#endif
|
||||
|
||||
ns_updating_frame = f;
|
||||
[view lockFocus];
|
||||
|
||||
/* drawRect may have been called for say the minibuffer, and then clip path
|
||||
is for the minibuffer. But the display engine may draw more because
|
||||
we have set the frame as garbaged. So reset clip path to the whole
|
||||
view. */
|
||||
#ifdef NS_IMPL_COCOA
|
||||
{
|
||||
NSBezierPath *bp;
|
||||
NSRect r = [view frame];
|
||||
NSRect cr = [[view window] frame];
|
||||
/* If a large frame size is set, r may be larger than the window frame
|
||||
before constrained. In that case don't change the clip path, as we
|
||||
will clear in to the tool bar and title bar. */
|
||||
if (r.size.height
|
||||
+ FRAME_NS_TITLEBAR_HEIGHT (f)
|
||||
+ FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height)
|
||||
{
|
||||
bp = [[NSBezierPath bezierPathWithRect: r] retain];
|
||||
[bp setClip];
|
||||
[bp release];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NS_IMPL_GNUSTEP
|
||||
uRect = NSMakeRect (0, 0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1124,66 +1158,99 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
|||
external (RIF) call; for whole frame, called after gui_update_window_end
|
||||
-------------------------------------------------------------------------- */
|
||||
{
|
||||
EmacsView *view = FRAME_NS_VIEW (f);
|
||||
|
||||
NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
|
||||
|
||||
/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
|
||||
MOUSE_HL_INFO (f)->mouse_face_defer = 0;
|
||||
|
||||
block_input ();
|
||||
|
||||
[view unlockFocus];
|
||||
[[view window] flushWindow];
|
||||
|
||||
unblock_input ();
|
||||
ns_updating_frame = NULL;
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
ns_clip_to_rect (struct frame *f, NSRect *r, int n)
|
||||
static void
|
||||
ns_focus (struct frame *f, NSRect *r, int n)
|
||||
/* --------------------------------------------------------------------------
|
||||
Clip the drawing area to rectangle r in frame f. If drawing is not
|
||||
currently possible mark r as dirty and return NO, otherwise return
|
||||
YES.
|
||||
Internal: Focus on given frame. During small local updates this is used to
|
||||
draw, however during large updates, ns_update_begin and ns_update_end are
|
||||
called to wrap the whole thing, in which case these calls are stubbed out.
|
||||
Except, on GNUstep, we accumulate the rectangle being drawn into, because
|
||||
the back end won't do this automatically, and will just end up flushing
|
||||
the entire window.
|
||||
-------------------------------------------------------------------------- */
|
||||
{
|
||||
NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_clip_to_rect");
|
||||
if (r)
|
||||
NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_focus");
|
||||
if (r != NULL)
|
||||
{
|
||||
NSTRACE_RECT ("r", *r);
|
||||
}
|
||||
|
||||
if ([NSView focusView] == FRAME_NS_VIEW (f))
|
||||
if (f != ns_updating_frame)
|
||||
{
|
||||
NSView *view = FRAME_NS_VIEW (f);
|
||||
if (view != focus_view)
|
||||
{
|
||||
[[NSGraphicsContext currentContext] saveGraphicsState];
|
||||
if (n == 2)
|
||||
NSRectClipList (r, 2);
|
||||
else
|
||||
NSRectClip (*r);
|
||||
gsaved = YES;
|
||||
if (focus_view != NULL)
|
||||
{
|
||||
[focus_view unlockFocus];
|
||||
[[focus_view window] flushWindow];
|
||||
/*debug_lock--; */
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSView *view = FRAME_NS_VIEW (f);
|
||||
int i;
|
||||
for (i = 0 ; i < n ; i++)
|
||||
[view setNeedsDisplayInRect:r[i]];
|
||||
if (view)
|
||||
[view lockFocus];
|
||||
focus_view = view;
|
||||
/*if (view) debug_lock++; */
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
/* clipping */
|
||||
if (r)
|
||||
{
|
||||
[[NSGraphicsContext currentContext] saveGraphicsState];
|
||||
if (n == 2)
|
||||
NSRectClipList (r, 2);
|
||||
else
|
||||
NSRectClip (*r);
|
||||
gsaved = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ns_reset_clipping (struct frame *f)
|
||||
/* Internal: Restore the previous graphics state, unsetting any
|
||||
clipping areas. */
|
||||
ns_unfocus (struct frame *f)
|
||||
/* --------------------------------------------------------------------------
|
||||
Internal: Remove focus on given frame
|
||||
-------------------------------------------------------------------------- */
|
||||
{
|
||||
NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping");
|
||||
NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_unfocus");
|
||||
|
||||
if (gsaved)
|
||||
{
|
||||
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||
gsaved = NO;
|
||||
}
|
||||
|
||||
if (f != ns_updating_frame)
|
||||
{
|
||||
if (focus_view != NULL)
|
||||
{
|
||||
[focus_view unlockFocus];
|
||||
[[focus_view window] flushWindow];
|
||||
focus_view = NULL;
|
||||
/*debug_lock--; */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
static void
|
||||
ns_clip_to_row (struct window *w, struct glyph_row *row,
|
||||
enum glyph_row_area area, BOOL gc)
|
||||
/* --------------------------------------------------------------------------
|
||||
|
@ -1202,19 +1269,7 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
|||
clip_rect.size.width = window_width;
|
||||
clip_rect.size.height = row->visible_height;
|
||||
|
||||
return ns_clip_to_rect (f, &clip_rect, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ns_flush_display (struct frame *f)
|
||||
/* Force the frame to redisplay. If areas have previously been marked
|
||||
dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call
|
||||
draw_rect: which will "expose" those areas. */
|
||||
{
|
||||
block_input ();
|
||||
[FRAME_NS_VIEW (f) displayIfNeeded];
|
||||
unblock_input ();
|
||||
ns_focus (f, &clip_rect, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2811,16 +2866,14 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
r = [view bounds];
|
||||
|
||||
block_input ();
|
||||
if (ns_clip_to_rect (f, &r, 1))
|
||||
{
|
||||
[ns_lookup_indexed_color (NS_FACE_BACKGROUND
|
||||
(FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set];
|
||||
NSRectFill (r);
|
||||
ns_reset_clipping (f);
|
||||
ns_focus (f, &r, 1);
|
||||
[ns_lookup_indexed_color (NS_FACE_BACKGROUND
|
||||
(FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set];
|
||||
NSRectFill (r);
|
||||
ns_unfocus (f);
|
||||
|
||||
/* as of 2006/11 or so this is now needed */
|
||||
ns_redraw_scroll_bars (f);
|
||||
}
|
||||
/* as of 2006/11 or so this is now needed */
|
||||
ns_redraw_scroll_bars (f);
|
||||
unblock_input ();
|
||||
}
|
||||
|
||||
|
@ -2841,14 +2894,13 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_clear_frame_area");
|
||||
|
||||
r = NSIntersectionRect (r, [view frame]);
|
||||
if (ns_clip_to_rect (f, &r, 1))
|
||||
{
|
||||
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
|
||||
ns_focus (f, &r, 1);
|
||||
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
|
||||
|
||||
NSRectFill (r);
|
||||
NSRectFill (r);
|
||||
|
||||
ns_reset_clipping (f);
|
||||
}
|
||||
ns_unfocus (f);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2860,11 +2912,11 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
{
|
||||
hide_bell(); // Ensure the bell image isn't scrolled.
|
||||
|
||||
/* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is
|
||||
no obvious replacement so we may have to come up with our own. */
|
||||
ns_focus (f, &dest, 1);
|
||||
[FRAME_NS_VIEW (f) scrollRect: src
|
||||
by: NSMakeSize (dest.origin.x - src.origin.x,
|
||||
dest.origin.y - src.origin.y)];
|
||||
ns_unfocus (f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3116,41 +3168,42 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
[ns_lookup_indexed_color(face->background, f) set];
|
||||
NSRectFill (clearRect);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->which)
|
||||
{
|
||||
EmacsImage *img = bimgs[p->which - 1];
|
||||
|
||||
if (!img)
|
||||
{
|
||||
// Note: For "periodic" images, allocate one EmacsImage for
|
||||
// the base image, and use it for all dh:s.
|
||||
unsigned short *bits = p->bits;
|
||||
int full_height = p->h + p->dh;
|
||||
int i;
|
||||
unsigned char *cbits = xmalloc (full_height);
|
||||
if (!img)
|
||||
{
|
||||
// Note: For "periodic" images, allocate one EmacsImage for
|
||||
// the base image, and use it for all dh:s.
|
||||
unsigned short *bits = p->bits;
|
||||
int full_height = p->h + p->dh;
|
||||
int i;
|
||||
unsigned char *cbits = xmalloc (full_height);
|
||||
|
||||
for (i = 0; i < full_height; i++)
|
||||
cbits[i] = bits[i];
|
||||
img = [[EmacsImage alloc] initFromXBM: cbits width: 8
|
||||
height: full_height
|
||||
fg: 0 bg: 0
|
||||
reverseBytes: NO];
|
||||
bimgs[p->which - 1] = img;
|
||||
xfree (cbits);
|
||||
}
|
||||
for (i = 0; i < full_height; i++)
|
||||
cbits[i] = bits[i];
|
||||
img = [[EmacsImage alloc] initFromXBM: cbits width: 8
|
||||
height: full_height
|
||||
fg: 0 bg: 0
|
||||
reverseBytes: NO];
|
||||
bimgs[p->which - 1] = img;
|
||||
xfree (cbits);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
NSColor *bm_color;
|
||||
if (!p->cursor_p)
|
||||
bm_color = ns_lookup_indexed_color(face->foreground, f);
|
||||
else if (p->overlay_p)
|
||||
bm_color = ns_lookup_indexed_color(face->background, f);
|
||||
else
|
||||
bm_color = f->output_data.ns->cursor_color;
|
||||
[img setXBMColor: bm_color];
|
||||
}
|
||||
{
|
||||
NSColor *bm_color;
|
||||
if (!p->cursor_p)
|
||||
bm_color = ns_lookup_indexed_color(face->foreground, f);
|
||||
else if (p->overlay_p)
|
||||
bm_color = ns_lookup_indexed_color(face->background, f);
|
||||
else
|
||||
bm_color = f->output_data.ns->cursor_color;
|
||||
[img setXBMColor: bm_color];
|
||||
}
|
||||
|
||||
// Note: For periodic images, the full image height is "h + hd".
|
||||
// By using the height h, a suitable part of the image is used.
|
||||
|
@ -3167,6 +3220,7 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
}
|
||||
ns_reset_clipping (f);
|
||||
}
|
||||
ns_unfocus (f);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3251,25 +3305,23 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
|||
/* Prevent the cursor from being drawn outside the text area. */
|
||||
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
|
||||
|
||||
if (ns_clip_to_rect (f, &r, 1))
|
||||
face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
|
||||
if (face && NS_FACE_BACKGROUND (face)
|
||||
== ns_index_color (FRAME_CURSOR_COLOR (f), f))
|
||||
{
|
||||
face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
|
||||
if (face && NS_FACE_BACKGROUND (face)
|
||||
== ns_index_color (FRAME_CURSOR_COLOR (f), f))
|
||||
{
|
||||
[ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
|
||||
hollow_color = FRAME_CURSOR_COLOR (f);
|
||||
}
|
||||
else
|
||||
[FRAME_CURSOR_COLOR (f) set];
|
||||
[ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
|
||||
hollow_color = FRAME_CURSOR_COLOR (f);
|
||||
}
|
||||
else
|
||||
[FRAME_CURSOR_COLOR (f) set];
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
/* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
|
||||
atomic. Cleaner ways of doing this should be investigated.
|
||||
One way would be to set a global variable DRAWING_CURSOR
|
||||
when making the call to draw_phys..(), don't focus in that
|
||||
case, then move the ns_reset_clipping() here after that call. */
|
||||
NSDisableScreenUpdates ();
|
||||
/* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
|
||||
atomic. Cleaner ways of doing this should be investigated.
|
||||
One way would be to set a global variable DRAWING_CURSOR
|
||||
when making the call to draw_phys..(), don't focus in that
|
||||
case, then move the ns_unfocus() here after that call. */
|
||||
NSDisableScreenUpdates ();
|
||||
#endif
|
||||
|
||||
switch (cursor_type)
|
||||
|
@ -3300,6 +3352,7 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
|||
NSRectFill (s);
|
||||
break;
|
||||
}
|
||||
ns_unfocus (f);
|
||||
|
||||
/* Draw the character under the cursor. Other terms only draw
|
||||
the character on top of box cursors, so do the same here. */
|
||||
|
@ -3307,9 +3360,9 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
|||
draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
NSEnableScreenUpdates ();
|
||||
NSEnableScreenUpdates ();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -3327,14 +3380,12 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
|||
|
||||
face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
|
||||
|
||||
if (ns_clip_to_rect (f, &r, 1))
|
||||
{
|
||||
if (face)
|
||||
[ns_lookup_indexed_color(face->foreground, f) set];
|
||||
ns_focus (f, &r, 1);
|
||||
if (face)
|
||||
[ns_lookup_indexed_color(face->foreground, f) set];
|
||||
|
||||
NSRectFill(r);
|
||||
ns_reset_clipping (f);
|
||||
}
|
||||
NSRectFill(r);
|
||||
ns_unfocus (f);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3361,40 +3412,39 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
|||
|
||||
NSTRACE ("ns_draw_window_divider");
|
||||
|
||||
if (ns_clip_to_rect (f, ÷r, 1))
|
||||
{
|
||||
if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
|
||||
/* A vertical divider, at least three pixels wide: Draw first and
|
||||
last pixels differently. */
|
||||
{
|
||||
[ns_lookup_indexed_color(color_first, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0));
|
||||
[ns_lookup_indexed_color(color, f) set];
|
||||
NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0));
|
||||
[ns_lookup_indexed_color(color_last, f) set];
|
||||
NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0));
|
||||
}
|
||||
else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
|
||||
/* A horizontal divider, at least three pixels high: Draw first and
|
||||
last pixels differently. */
|
||||
{
|
||||
[ns_lookup_indexed_color(color_first, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1));
|
||||
[ns_lookup_indexed_color(color, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2));
|
||||
[ns_lookup_indexed_color(color_last, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In any other case do not draw the first and last pixels
|
||||
differently. */
|
||||
[ns_lookup_indexed_color(color, f) set];
|
||||
NSRectFill(divider);
|
||||
}
|
||||
ns_focus (f, ÷r, 1);
|
||||
|
||||
ns_reset_clipping (f);
|
||||
if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
|
||||
/* A vertical divider, at least three pixels wide: Draw first and
|
||||
last pixels differently. */
|
||||
{
|
||||
[ns_lookup_indexed_color(color_first, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0));
|
||||
[ns_lookup_indexed_color(color, f) set];
|
||||
NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0));
|
||||
[ns_lookup_indexed_color(color_last, f) set];
|
||||
NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0));
|
||||
}
|
||||
else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
|
||||
/* A horizontal divider, at least three pixels high: Draw first and
|
||||
last pixels differently. */
|
||||
{
|
||||
[ns_lookup_indexed_color(color_first, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1));
|
||||
[ns_lookup_indexed_color(color, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2));
|
||||
[ns_lookup_indexed_color(color_last, f) set];
|
||||
NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In any other case do not draw the first and last pixels
|
||||
differently. */
|
||||
[ns_lookup_indexed_color(color, f) set];
|
||||
NSRectFill(divider);
|
||||
}
|
||||
|
||||
ns_unfocus (f);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -4009,7 +4059,22 @@ Function modeled after x_draw_glyph_string_box ().
|
|||
{
|
||||
n = ns_get_glyph_string_clip_rect (s, r);
|
||||
|
||||
if (ns_clip_to_rect (s->f, r, n))
|
||||
ns_focus (s->f, r, n);
|
||||
|
||||
if (s->hl == DRAW_MOUSE_FACE)
|
||||
{
|
||||
face = FACE_FROM_ID_OR_NULL (s->f,
|
||||
MOUSE_HL_INFO (s->f)->mouse_face_face_id);
|
||||
if (!face)
|
||||
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
|
||||
}
|
||||
else
|
||||
face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
|
||||
|
||||
bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
|
||||
fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
/* FIXME: Why are we reusing the clipping rectangles? The
|
||||
other terms don't appear to do anything like this. */
|
||||
|
@ -4017,16 +4082,13 @@ Function modeled after x_draw_glyph_string_box ().
|
|||
|
||||
if (s->hl == DRAW_MOUSE_FACE)
|
||||
{
|
||||
face = FACE_FROM_ID_OR_NULL (s->f,
|
||||
MOUSE_HL_INFO (s->f)->mouse_face_face_id);
|
||||
if (!face)
|
||||
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
|
||||
}
|
||||
else
|
||||
face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
|
||||
int overrun, leftoverrun;
|
||||
|
||||
bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
|
||||
fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
|
||||
/* truncate to avoid overwriting fringe and/or scrollbar */
|
||||
overrun = max (0, (s->x + s->background_width)
|
||||
- (WINDOW_BOX_RIGHT_EDGE_X (s->w)
|
||||
- WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
|
||||
r[i].size.width -= overrun;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
|
@ -4051,39 +4113,52 @@ Function modeled after x_draw_glyph_string_box ().
|
|||
}
|
||||
}
|
||||
|
||||
[bgCol set];
|
||||
if (leftoverrun > 0)
|
||||
{
|
||||
r[i].origin.x += leftoverrun;
|
||||
r[i].size.width -= leftoverrun;
|
||||
}
|
||||
|
||||
/* NOTE: under NS this is NOT used to draw cursors, but we must avoid
|
||||
overwriting cursor (usually when cursor on a tab). */
|
||||
if (s->hl == DRAW_CURSOR)
|
||||
{
|
||||
CGFloat x, width;
|
||||
|
||||
x = r[i].origin.x;
|
||||
width = s->w->phys_cursor_width;
|
||||
r[i].size.width -= width;
|
||||
r[i].origin.x += width;
|
||||
|
||||
NSRectFill (r[i]);
|
||||
|
||||
/* Draw overlining, etc. on the cursor. */
|
||||
if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
|
||||
ns_draw_text_decoration (s, face, bgCol, width, x);
|
||||
else
|
||||
ns_draw_text_decoration (s, face, fgCol, width, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRectFill (r[i]);
|
||||
}
|
||||
|
||||
/* Draw overlining, etc. on the stretch glyph (or the part
|
||||
of the stretch glyph after the cursor). */
|
||||
ns_draw_text_decoration (s, face, fgCol, r[i].size.width,
|
||||
r[i].origin.x);
|
||||
/* XXX: Try to work between problem where a stretch glyph on
|
||||
a partially-visible bottom row will clear part of the
|
||||
modeline, and another where list-buffers headers and similar
|
||||
rows erroneously have visible_height set to 0. Not sure
|
||||
where this is coming from as other terms seem not to show. */
|
||||
r[i].size.height = min (s->height, s->row->visible_height);
|
||||
}
|
||||
ns_reset_clipping (s->f);
|
||||
|
||||
[bgCol set];
|
||||
|
||||
/* NOTE: under NS this is NOT used to draw cursors, but we must avoid
|
||||
overwriting cursor (usually when cursor on a tab) */
|
||||
if (s->hl == DRAW_CURSOR)
|
||||
{
|
||||
CGFloat x, width;
|
||||
|
||||
x = r[i].origin.x;
|
||||
width = s->w->phys_cursor_width;
|
||||
r[i].size.width -= width;
|
||||
r[i].origin.x += width;
|
||||
|
||||
NSRectFill (r[i]);
|
||||
|
||||
/* Draw overlining, etc. on the cursor. */
|
||||
if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
|
||||
ns_draw_text_decoration (s, face, bgCol, width, x);
|
||||
else
|
||||
ns_draw_text_decoration (s, face, fgCol, width, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRectFill (r[i]);
|
||||
}
|
||||
|
||||
/* Draw overlining, etc. on the stretch glyph (or the part
|
||||
of the stretch glyph after the cursor). */
|
||||
ns_draw_text_decoration (s, face, fgCol, r[i].size.width,
|
||||
r[i].origin.x);
|
||||
}
|
||||
ns_unfocus (s->f);
|
||||
s->background_filled_p = 1;
|
||||
}
|
||||
}
|
||||
|
@ -4233,11 +4308,9 @@ overwriting cursor (usually when cursor on a tab). */
|
|||
if (next->first_glyph->type != STRETCH_GLYPH)
|
||||
{
|
||||
n = ns_get_glyph_string_clip_rect (s->next, r);
|
||||
if (ns_clip_to_rect (s->f, r, n))
|
||||
{
|
||||
ns_maybe_dumpglyphs_background (s->next, 1);
|
||||
ns_reset_clipping (s->f);
|
||||
}
|
||||
ns_focus (s->f, r, n);
|
||||
ns_maybe_dumpglyphs_background (s->next, 1);
|
||||
ns_unfocus (s->f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4252,12 +4325,10 @@ overwriting cursor (usually when cursor on a tab). */
|
|||
|| s->first_glyph->type == COMPOSITE_GLYPH))
|
||||
{
|
||||
n = ns_get_glyph_string_clip_rect (s, r);
|
||||
if (ns_clip_to_rect (s->f, r, n))
|
||||
{
|
||||
ns_maybe_dumpglyphs_background (s, 1);
|
||||
ns_dumpglyphs_box_or_relief (s);
|
||||
ns_reset_clipping (s->f);
|
||||
}
|
||||
ns_focus (s->f, r, n);
|
||||
ns_maybe_dumpglyphs_background (s, 1);
|
||||
ns_dumpglyphs_box_or_relief (s);
|
||||
ns_unfocus (s->f);
|
||||
box_drawn_p = 1;
|
||||
}
|
||||
|
||||
|
@ -4266,11 +4337,9 @@ overwriting cursor (usually when cursor on a tab). */
|
|||
|
||||
case IMAGE_GLYPH:
|
||||
n = ns_get_glyph_string_clip_rect (s, r);
|
||||
if (ns_clip_to_rect (s->f, r, n))
|
||||
{
|
||||
ns_dumpglyphs_image (s, r[0]);
|
||||
ns_reset_clipping (s->f);
|
||||
}
|
||||
ns_focus (s->f, r, n);
|
||||
ns_dumpglyphs_image (s, r[0]);
|
||||
ns_unfocus (s->f);
|
||||
break;
|
||||
|
||||
case STRETCH_GLYPH:
|
||||
|
@ -4280,68 +4349,66 @@ overwriting cursor (usually when cursor on a tab). */
|
|||
case CHAR_GLYPH:
|
||||
case COMPOSITE_GLYPH:
|
||||
n = ns_get_glyph_string_clip_rect (s, r);
|
||||
if (ns_clip_to_rect (s->f, r, n))
|
||||
ns_focus (s->f, r, n);
|
||||
|
||||
if (s->for_overlaps || (s->cmp_from > 0
|
||||
&& ! s->first_glyph->u.cmp.automatic))
|
||||
s->background_filled_p = 1;
|
||||
else
|
||||
ns_maybe_dumpglyphs_background
|
||||
(s, s->first_glyph->type == COMPOSITE_GLYPH);
|
||||
|
||||
if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
|
||||
{
|
||||
if (s->for_overlaps || (s->cmp_from > 0
|
||||
&& ! s->first_glyph->u.cmp.automatic))
|
||||
s->background_filled_p = 1;
|
||||
else
|
||||
ns_maybe_dumpglyphs_background
|
||||
(s, s->first_glyph->type == COMPOSITE_GLYPH);
|
||||
|
||||
if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
|
||||
{
|
||||
unsigned long tmp = NS_FACE_BACKGROUND (s->face);
|
||||
NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
|
||||
NS_FACE_FOREGROUND (s->face) = tmp;
|
||||
}
|
||||
|
||||
{
|
||||
BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
|
||||
|
||||
if (isComposite)
|
||||
ns_draw_composite_glyph_string_foreground (s);
|
||||
else
|
||||
ns_draw_glyph_string_foreground (s);
|
||||
}
|
||||
|
||||
{
|
||||
NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
|
||||
? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
|
||||
s->f)
|
||||
: FRAME_FOREGROUND_COLOR (s->f));
|
||||
[col set];
|
||||
|
||||
/* Draw underline, overline, strike-through. */
|
||||
ns_draw_text_decoration (s, s->face, col, s->width, s->x);
|
||||
}
|
||||
|
||||
if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
|
||||
{
|
||||
unsigned long tmp = NS_FACE_BACKGROUND (s->face);
|
||||
NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
|
||||
NS_FACE_FOREGROUND (s->face) = tmp;
|
||||
}
|
||||
|
||||
ns_reset_clipping (s->f);
|
||||
unsigned long tmp = NS_FACE_BACKGROUND (s->face);
|
||||
NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
|
||||
NS_FACE_FOREGROUND (s->face) = tmp;
|
||||
}
|
||||
|
||||
{
|
||||
BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
|
||||
|
||||
if (isComposite)
|
||||
ns_draw_composite_glyph_string_foreground (s);
|
||||
else
|
||||
ns_draw_glyph_string_foreground (s);
|
||||
}
|
||||
|
||||
{
|
||||
NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
|
||||
? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
|
||||
s->f)
|
||||
: FRAME_FOREGROUND_COLOR (s->f));
|
||||
[col set];
|
||||
|
||||
/* Draw underline, overline, strike-through. */
|
||||
ns_draw_text_decoration (s, s->face, col, s->width, s->x);
|
||||
}
|
||||
|
||||
if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
|
||||
{
|
||||
unsigned long tmp = NS_FACE_BACKGROUND (s->face);
|
||||
NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
|
||||
NS_FACE_FOREGROUND (s->face) = tmp;
|
||||
}
|
||||
|
||||
ns_unfocus (s->f);
|
||||
break;
|
||||
|
||||
case GLYPHLESS_GLYPH:
|
||||
n = ns_get_glyph_string_clip_rect (s, r);
|
||||
if (ns_clip_to_rect (s->f, r, n))
|
||||
{
|
||||
if (s->for_overlaps || (s->cmp_from > 0
|
||||
&& ! s->first_glyph->u.cmp.automatic))
|
||||
s->background_filled_p = 1;
|
||||
else
|
||||
ns_maybe_dumpglyphs_background
|
||||
(s, s->first_glyph->type == COMPOSITE_GLYPH);
|
||||
/* ... */
|
||||
/* Not yet implemented. */
|
||||
/* ... */
|
||||
ns_reset_clipping (s->f);
|
||||
}
|
||||
ns_focus (s->f, r, n);
|
||||
|
||||
if (s->for_overlaps || (s->cmp_from > 0
|
||||
&& ! s->first_glyph->u.cmp.automatic))
|
||||
s->background_filled_p = 1;
|
||||
else
|
||||
ns_maybe_dumpglyphs_background
|
||||
(s, s->first_glyph->type == COMPOSITE_GLYPH);
|
||||
/* ... */
|
||||
/* Not yet implemented. */
|
||||
/* ... */
|
||||
ns_unfocus (s->f);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4352,11 +4419,9 @@ overwriting cursor (usually when cursor on a tab). */
|
|||
if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX)
|
||||
{
|
||||
n = ns_get_glyph_string_clip_rect (s, r);
|
||||
if (ns_clip_to_rect (s->f, r, n))
|
||||
{
|
||||
ns_dumpglyphs_box_or_relief (s);
|
||||
ns_reset_clipping (s->f);
|
||||
}
|
||||
ns_focus (s->f, r, n);
|
||||
ns_dumpglyphs_box_or_relief (s);
|
||||
ns_unfocus (s->f);
|
||||
}
|
||||
|
||||
s->num_clips = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue