Revert "Make all NS drawing be done from drawRect"

This reverts commit 7946445962.
This commit is contained in:
Alan Third 2019-07-28 15:19:19 +01:00
parent 6b955c26f6
commit 3ad7813296

View file

@ -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, &divider, 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, &divider, 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;