aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Third2019-07-28 15:19:19 +0100
committerAlan Third2020-01-24 16:05:41 +0000
commit3ad7813296760cecfd3fd35a5fb47930d61a573d (patch)
treebbad419bb6c66f43fab6fb649f30ae8e9bca4a30
parent6b955c26f66cf897a24fa61a0343461360b8baaa (diff)
downloademacs-3ad7813296760cecfd3fd35a5fb47930d61a573d.tar.gz
emacs-3ad7813296760cecfd3fd35a5fb47930d61a573d.zip
Revert "Make all NS drawing be done from drawRect"
This reverts commit 7946445962372c4255180af45cb7c857f1b0b5fa.
-rw-r--r--src/nsterm.m575
1 files changed, 320 insertions, 255 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index 5798d7111b1..222af19aa20 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -287,7 +287,12 @@ struct ns_display_info *x_display_list; /* Chain of existing displays */
287long context_menu_value = 0; 287long context_menu_value = 0;
288 288
289/* display update */ 289/* display update */
290static struct frame *ns_updating_frame;
291static NSView *focus_view = NULL;
290static int ns_window_num = 0; 292static int ns_window_num = 0;
293#ifdef NS_IMPL_GNUSTEP
294static NSRect uRect; // TODO: This is dead, remove it?
295#endif
291static BOOL gsaved = NO; 296static BOOL gsaved = NO;
292static BOOL ns_fake_keydown = NO; 297static BOOL ns_fake_keydown = NO;
293#ifdef NS_IMPL_COCOA 298#ifdef NS_IMPL_COCOA
@@ -1098,13 +1103,12 @@ ns_update_begin (struct frame *f)
1098 external (RIF) call; whole frame, called before gui_update_window_begin 1103 external (RIF) call; whole frame, called before gui_update_window_begin
1099 -------------------------------------------------------------------------- */ 1104 -------------------------------------------------------------------------- */
1100{ 1105{
1101#ifdef NS_IMPL_COCOA
1102 EmacsView *view = FRAME_NS_VIEW (f); 1106 EmacsView *view = FRAME_NS_VIEW (f);
1103
1104 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_begin"); 1107 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_begin");
1105 1108
1106 ns_update_auto_hide_menu_bar (); 1109 ns_update_auto_hide_menu_bar ();
1107 1110
1111#ifdef NS_IMPL_COCOA
1108 if ([view isFullscreen] && [view fsIsNative]) 1112 if ([view isFullscreen] && [view fsIsNative])
1109 { 1113 {
1110 // Fix reappearing tool bar in fullscreen for Mac OS X 10.7 1114 // Fix reappearing tool bar in fullscreen for Mac OS X 10.7
@@ -1114,6 +1118,36 @@ ns_update_begin (struct frame *f)
1114 [toolbar setVisible: tbar_visible]; 1118 [toolbar setVisible: tbar_visible];
1115 } 1119 }
1116#endif 1120#endif
1121
1122 ns_updating_frame = f;
1123 [view lockFocus];
1124
1125 /* drawRect may have been called for say the minibuffer, and then clip path
1126 is for the minibuffer. But the display engine may draw more because
1127 we have set the frame as garbaged. So reset clip path to the whole
1128 view. */
1129#ifdef NS_IMPL_COCOA
1130 {
1131 NSBezierPath *bp;
1132 NSRect r = [view frame];
1133 NSRect cr = [[view window] frame];
1134 /* If a large frame size is set, r may be larger than the window frame
1135 before constrained. In that case don't change the clip path, as we
1136 will clear in to the tool bar and title bar. */
1137 if (r.size.height
1138 + FRAME_NS_TITLEBAR_HEIGHT (f)
1139 + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height)
1140 {
1141 bp = [[NSBezierPath bezierPathWithRect: r] retain];
1142 [bp setClip];
1143 [bp release];
1144 }
1145 }
1146#endif
1147
1148#ifdef NS_IMPL_GNUSTEP
1149 uRect = NSMakeRect (0, 0, 0, 0);
1150#endif
1117} 1151}
1118 1152
1119 1153
@@ -1124,66 +1158,99 @@ ns_update_end (struct frame *f)
1124 external (RIF) call; for whole frame, called after gui_update_window_end 1158 external (RIF) call; for whole frame, called after gui_update_window_end
1125 -------------------------------------------------------------------------- */ 1159 -------------------------------------------------------------------------- */
1126{ 1160{
1161 EmacsView *view = FRAME_NS_VIEW (f);
1162
1127 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end"); 1163 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
1128 1164
1129/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ 1165/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
1130 MOUSE_HL_INFO (f)->mouse_face_defer = 0; 1166 MOUSE_HL_INFO (f)->mouse_face_defer = 0;
1131}
1132 1167
1168 block_input ();
1133 1169
1134static BOOL 1170 [view unlockFocus];
1135ns_clip_to_rect (struct frame *f, NSRect *r, int n) 1171 [[view window] flushWindow];
1172
1173 unblock_input ();
1174 ns_updating_frame = NULL;
1175}
1176
1177static void
1178ns_focus (struct frame *f, NSRect *r, int n)
1136/* -------------------------------------------------------------------------- 1179/* --------------------------------------------------------------------------
1137 Clip the drawing area to rectangle r in frame f. If drawing is not 1180 Internal: Focus on given frame. During small local updates this is used to
1138 currently possible mark r as dirty and return NO, otherwise return 1181 draw, however during large updates, ns_update_begin and ns_update_end are
1139 YES. 1182 called to wrap the whole thing, in which case these calls are stubbed out.
1183 Except, on GNUstep, we accumulate the rectangle being drawn into, because
1184 the back end won't do this automatically, and will just end up flushing
1185 the entire window.
1140 -------------------------------------------------------------------------- */ 1186 -------------------------------------------------------------------------- */
1141{ 1187{
1142 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_clip_to_rect"); 1188 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_focus");
1143 if (r) 1189 if (r != NULL)
1144 { 1190 {
1145 NSTRACE_RECT ("r", *r); 1191 NSTRACE_RECT ("r", *r);
1192 }
1146 1193
1147 if ([NSView focusView] == FRAME_NS_VIEW (f)) 1194 if (f != ns_updating_frame)
1195 {
1196 NSView *view = FRAME_NS_VIEW (f);
1197 if (view != focus_view)
1148 { 1198 {
1149 [[NSGraphicsContext currentContext] saveGraphicsState]; 1199 if (focus_view != NULL)
1150 if (n == 2) 1200 {
1151 NSRectClipList (r, 2); 1201 [focus_view unlockFocus];
1152 else 1202 [[focus_view window] flushWindow];
1153 NSRectClip (*r); 1203/*debug_lock--; */
1154 gsaved = YES; 1204 }
1155 1205
1156 return YES; 1206 if (view)
1157 } 1207 [view lockFocus];
1158 else 1208 focus_view = view;
1159 { 1209/*if (view) debug_lock++; */
1160 NSView *view = FRAME_NS_VIEW (f);
1161 int i;
1162 for (i = 0 ; i < n ; i++)
1163 [view setNeedsDisplayInRect:r[i]];
1164 } 1210 }
1165 } 1211 }
1166 1212
1167 return NO; 1213 /* clipping */
1214 if (r)
1215 {
1216 [[NSGraphicsContext currentContext] saveGraphicsState];
1217 if (n == 2)
1218 NSRectClipList (r, 2);
1219 else
1220 NSRectClip (*r);
1221 gsaved = YES;
1222 }
1168} 1223}
1169 1224
1170 1225
1171static void 1226static void
1172ns_reset_clipping (struct frame *f) 1227ns_unfocus (struct frame *f)
1173/* Internal: Restore the previous graphics state, unsetting any 1228/* --------------------------------------------------------------------------
1174 clipping areas. */ 1229 Internal: Remove focus on given frame
1230 -------------------------------------------------------------------------- */
1175{ 1231{
1176 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping"); 1232 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_unfocus");
1177 1233
1178 if (gsaved) 1234 if (gsaved)
1179 { 1235 {
1180 [[NSGraphicsContext currentContext] restoreGraphicsState]; 1236 [[NSGraphicsContext currentContext] restoreGraphicsState];
1181 gsaved = NO; 1237 gsaved = NO;
1182 } 1238 }
1239
1240 if (f != ns_updating_frame)
1241 {
1242 if (focus_view != NULL)
1243 {
1244 [focus_view unlockFocus];
1245 [[focus_view window] flushWindow];
1246 focus_view = NULL;
1247/*debug_lock--; */
1248 }
1249 }
1183} 1250}
1184 1251
1185 1252
1186static BOOL 1253static void
1187ns_clip_to_row (struct window *w, struct glyph_row *row, 1254ns_clip_to_row (struct window *w, struct glyph_row *row,
1188 enum glyph_row_area area, BOOL gc) 1255 enum glyph_row_area area, BOOL gc)
1189/* -------------------------------------------------------------------------- 1256/* --------------------------------------------------------------------------
@@ -1202,19 +1269,7 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
1202 clip_rect.size.width = window_width; 1269 clip_rect.size.width = window_width;
1203 clip_rect.size.height = row->visible_height; 1270 clip_rect.size.height = row->visible_height;
1204 1271
1205 return ns_clip_to_rect (f, &clip_rect, 1); 1272 ns_focus (f, &clip_rect, 1);
1206}
1207
1208
1209static void
1210ns_flush_display (struct frame *f)
1211/* Force the frame to redisplay. If areas have previously been marked
1212 dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call
1213 draw_rect: which will "expose" those areas. */
1214{
1215 block_input ();
1216 [FRAME_NS_VIEW (f) displayIfNeeded];
1217 unblock_input ();
1218} 1273}
1219 1274
1220 1275
@@ -2811,16 +2866,14 @@ ns_clear_frame (struct frame *f)
2811 r = [view bounds]; 2866 r = [view bounds];
2812 2867
2813 block_input (); 2868 block_input ();
2814 if (ns_clip_to_rect (f, &r, 1)) 2869 ns_focus (f, &r, 1);
2815 { 2870 [ns_lookup_indexed_color (NS_FACE_BACKGROUND
2816 [ns_lookup_indexed_color (NS_FACE_BACKGROUND 2871 (FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set];
2817 (FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set]; 2872 NSRectFill (r);
2818 NSRectFill (r); 2873 ns_unfocus (f);
2819 ns_reset_clipping (f); 2874
2820 2875 /* as of 2006/11 or so this is now needed */
2821 /* as of 2006/11 or so this is now needed */ 2876 ns_redraw_scroll_bars (f);
2822 ns_redraw_scroll_bars (f);
2823 }
2824 unblock_input (); 2877 unblock_input ();
2825} 2878}
2826 2879
@@ -2841,14 +2894,13 @@ ns_clear_frame_area (struct frame *f, int x, int y, int width, int height)
2841 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_clear_frame_area"); 2894 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_clear_frame_area");
2842 2895
2843 r = NSIntersectionRect (r, [view frame]); 2896 r = NSIntersectionRect (r, [view frame]);
2844 if (ns_clip_to_rect (f, &r, 1)) 2897 ns_focus (f, &r, 1);
2845 { 2898 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
2846 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
2847 2899
2848 NSRectFill (r); 2900 NSRectFill (r);
2849 2901
2850 ns_reset_clipping (f); 2902 ns_unfocus (f);
2851 } 2903 return;
2852} 2904}
2853 2905
2854static void 2906static void
@@ -2860,11 +2912,11 @@ ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
2860 { 2912 {
2861 hide_bell(); // Ensure the bell image isn't scrolled. 2913 hide_bell(); // Ensure the bell image isn't scrolled.
2862 2914
2863 /* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is 2915 ns_focus (f, &dest, 1);
2864 no obvious replacement so we may have to come up with our own. */
2865 [FRAME_NS_VIEW (f) scrollRect: src 2916 [FRAME_NS_VIEW (f) scrollRect: src
2866 by: NSMakeSize (dest.origin.x - src.origin.x, 2917 by: NSMakeSize (dest.origin.x - src.origin.x,
2867 dest.origin.y - src.origin.y)]; 2918 dest.origin.y - src.origin.y)];
2919 ns_unfocus (f);
2868 } 2920 }
2869} 2921}
2870 2922
@@ -3116,41 +3168,42 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3116 [ns_lookup_indexed_color(face->background, f) set]; 3168 [ns_lookup_indexed_color(face->background, f) set];
3117 NSRectFill (clearRect); 3169 NSRectFill (clearRect);
3118 } 3170 }
3171 }
3119 3172
3120 if (p->which) 3173 if (p->which)
3121 { 3174 {
3122 EmacsImage *img = bimgs[p->which - 1]; 3175 EmacsImage *img = bimgs[p->which - 1];
3123 3176
3124 if (!img) 3177 if (!img)
3125 { 3178 {
3126 // Note: For "periodic" images, allocate one EmacsImage for 3179 // Note: For "periodic" images, allocate one EmacsImage for
3127 // the base image, and use it for all dh:s. 3180 // the base image, and use it for all dh:s.
3128 unsigned short *bits = p->bits; 3181 unsigned short *bits = p->bits;
3129 int full_height = p->h + p->dh; 3182 int full_height = p->h + p->dh;
3130 int i; 3183 int i;
3131 unsigned char *cbits = xmalloc (full_height); 3184 unsigned char *cbits = xmalloc (full_height);
3132 3185
3133 for (i = 0; i < full_height; i++) 3186 for (i = 0; i < full_height; i++)
3134 cbits[i] = bits[i]; 3187 cbits[i] = bits[i];
3135 img = [[EmacsImage alloc] initFromXBM: cbits width: 8 3188 img = [[EmacsImage alloc] initFromXBM: cbits width: 8
3136 height: full_height 3189 height: full_height
3137 fg: 0 bg: 0 3190 fg: 0 bg: 0
3138 reverseBytes: NO]; 3191 reverseBytes: NO];
3139 bimgs[p->which - 1] = img; 3192 bimgs[p->which - 1] = img;
3140 xfree (cbits); 3193 xfree (cbits);
3141 } 3194 }
3142 3195
3143 3196
3144 { 3197 {
3145 NSColor *bm_color; 3198 NSColor *bm_color;
3146 if (!p->cursor_p) 3199 if (!p->cursor_p)
3147 bm_color = ns_lookup_indexed_color(face->foreground, f); 3200 bm_color = ns_lookup_indexed_color(face->foreground, f);
3148 else if (p->overlay_p) 3201 else if (p->overlay_p)
3149 bm_color = ns_lookup_indexed_color(face->background, f); 3202 bm_color = ns_lookup_indexed_color(face->background, f);
3150 else 3203 else
3151 bm_color = f->output_data.ns->cursor_color; 3204 bm_color = f->output_data.ns->cursor_color;
3152 [img setXBMColor: bm_color]; 3205 [img setXBMColor: bm_color];
3153 } 3206 }
3154 3207
3155 // Note: For periodic images, the full image height is "h + hd". 3208 // Note: For periodic images, the full image height is "h + hd".
3156 // By using the height h, a suitable part of the image is used. 3209 // By using the height h, a suitable part of the image is used.
@@ -3167,6 +3220,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3167 } 3220 }
3168 ns_reset_clipping (f); 3221 ns_reset_clipping (f);
3169 } 3222 }
3223 ns_unfocus (f);
3170} 3224}
3171 3225
3172 3226
@@ -3251,25 +3305,23 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3251 /* Prevent the cursor from being drawn outside the text area. */ 3305 /* Prevent the cursor from being drawn outside the text area. */
3252 r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA)); 3306 r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
3253 3307
3254 if (ns_clip_to_rect (f, &r, 1)) 3308 face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
3309 if (face && NS_FACE_BACKGROUND (face)
3310 == ns_index_color (FRAME_CURSOR_COLOR (f), f))
3255 { 3311 {
3256 face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id); 3312 [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
3257 if (face && NS_FACE_BACKGROUND (face) 3313 hollow_color = FRAME_CURSOR_COLOR (f);
3258 == ns_index_color (FRAME_CURSOR_COLOR (f), f)) 3314 }
3259 { 3315 else
3260 [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set]; 3316 [FRAME_CURSOR_COLOR (f) set];
3261 hollow_color = FRAME_CURSOR_COLOR (f);
3262 }
3263 else
3264 [FRAME_CURSOR_COLOR (f) set];
3265 3317
3266#ifdef NS_IMPL_COCOA 3318#ifdef NS_IMPL_COCOA
3267 /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph 3319 /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
3268 atomic. Cleaner ways of doing this should be investigated. 3320 atomic. Cleaner ways of doing this should be investigated.
3269 One way would be to set a global variable DRAWING_CURSOR 3321 One way would be to set a global variable DRAWING_CURSOR
3270 when making the call to draw_phys..(), don't focus in that 3322 when making the call to draw_phys..(), don't focus in that
3271 case, then move the ns_reset_clipping() here after that call. */ 3323 case, then move the ns_unfocus() here after that call. */
3272 NSDisableScreenUpdates (); 3324 NSDisableScreenUpdates ();
3273#endif 3325#endif
3274 3326
3275 switch (cursor_type) 3327 switch (cursor_type)
@@ -3300,6 +3352,7 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3300 NSRectFill (s); 3352 NSRectFill (s);
3301 break; 3353 break;
3302 } 3354 }
3355 ns_unfocus (f);
3303 3356
3304 /* Draw the character under the cursor. Other terms only draw 3357 /* Draw the character under the cursor. Other terms only draw
3305 the character on top of box cursors, so do the same here. */ 3358 the character on top of box cursors, so do the same here. */
@@ -3307,9 +3360,9 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3307 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 3360 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
3308 3361
3309#ifdef NS_IMPL_COCOA 3362#ifdef NS_IMPL_COCOA
3310 NSEnableScreenUpdates (); 3363 NSEnableScreenUpdates ();
3311#endif 3364#endif
3312 } 3365
3313} 3366}
3314 3367
3315 3368
@@ -3327,14 +3380,12 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
3327 3380
3328 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID); 3381 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
3329 3382
3330 if (ns_clip_to_rect (f, &r, 1)) 3383 ns_focus (f, &r, 1);
3331 { 3384 if (face)
3332 if (face) 3385 [ns_lookup_indexed_color(face->foreground, f) set];
3333 [ns_lookup_indexed_color(face->foreground, f) set];
3334 3386
3335 NSRectFill(r); 3387 NSRectFill(r);
3336 ns_reset_clipping (f); 3388 ns_unfocus (f);
3337 }
3338} 3389}
3339 3390
3340 3391
@@ -3361,40 +3412,39 @@ ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
3361 3412
3362 NSTRACE ("ns_draw_window_divider"); 3413 NSTRACE ("ns_draw_window_divider");
3363 3414
3364 if (ns_clip_to_rect (f, &divider, 1)) 3415 ns_focus (f, &divider, 1);
3365 {
3366 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
3367 /* A vertical divider, at least three pixels wide: Draw first and
3368 last pixels differently. */
3369 {
3370 [ns_lookup_indexed_color(color_first, f) set];
3371 NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0));
3372 [ns_lookup_indexed_color(color, f) set];
3373 NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0));
3374 [ns_lookup_indexed_color(color_last, f) set];
3375 NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0));
3376 }
3377 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
3378 /* A horizontal divider, at least three pixels high: Draw first and
3379 last pixels differently. */
3380 {
3381 [ns_lookup_indexed_color(color_first, f) set];
3382 NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1));
3383 [ns_lookup_indexed_color(color, f) set];
3384 NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2));
3385 [ns_lookup_indexed_color(color_last, f) set];
3386 NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1));
3387 }
3388 else
3389 {
3390 /* In any other case do not draw the first and last pixels
3391 differently. */
3392 [ns_lookup_indexed_color(color, f) set];
3393 NSRectFill(divider);
3394 }
3395 3416
3396 ns_reset_clipping (f); 3417 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
3418 /* A vertical divider, at least three pixels wide: Draw first and
3419 last pixels differently. */
3420 {
3421 [ns_lookup_indexed_color(color_first, f) set];
3422 NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0));
3423 [ns_lookup_indexed_color(color, f) set];
3424 NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0));
3425 [ns_lookup_indexed_color(color_last, f) set];
3426 NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0));
3397 } 3427 }
3428 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
3429 /* A horizontal divider, at least three pixels high: Draw first and
3430 last pixels differently. */
3431 {
3432 [ns_lookup_indexed_color(color_first, f) set];
3433 NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1));
3434 [ns_lookup_indexed_color(color, f) set];
3435 NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2));
3436 [ns_lookup_indexed_color(color_last, f) set];
3437 NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1));
3438 }
3439 else
3440 {
3441 /* In any other case do not draw the first and last pixels
3442 differently. */
3443 [ns_lookup_indexed_color(color, f) set];
3444 NSRectFill(divider);
3445 }
3446
3447 ns_unfocus (f);
3398} 3448}
3399 3449
3400static void 3450static void
@@ -4009,7 +4059,22 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
4009 { 4059 {
4010 n = ns_get_glyph_string_clip_rect (s, r); 4060 n = ns_get_glyph_string_clip_rect (s, r);
4011 4061
4012 if (ns_clip_to_rect (s->f, r, n)) 4062 ns_focus (s->f, r, n);
4063
4064 if (s->hl == DRAW_MOUSE_FACE)
4065 {
4066 face = FACE_FROM_ID_OR_NULL (s->f,
4067 MOUSE_HL_INFO (s->f)->mouse_face_face_id);
4068 if (!face)
4069 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
4070 }
4071 else
4072 face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4073
4074 bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
4075 fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
4076
4077 for (i = 0; i < n; ++i)
4013 { 4078 {
4014 /* FIXME: Why are we reusing the clipping rectangles? The 4079 /* FIXME: Why are we reusing the clipping rectangles? The
4015 other terms don't appear to do anything like this. */ 4080 other terms don't appear to do anything like this. */
@@ -4017,16 +4082,13 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
4017 4082
4018 if (s->hl == DRAW_MOUSE_FACE) 4083 if (s->hl == DRAW_MOUSE_FACE)
4019 { 4084 {
4020 face = FACE_FROM_ID_OR_NULL (s->f, 4085 int overrun, leftoverrun;
4021 MOUSE_HL_INFO (s->f)->mouse_face_face_id);
4022 if (!face)
4023 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
4024 }
4025 else
4026 face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4027 4086
4028 bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f); 4087 /* truncate to avoid overwriting fringe and/or scrollbar */
4029 fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f); 4088 overrun = max (0, (s->x + s->background_width)
4089 - (WINDOW_BOX_RIGHT_EDGE_X (s->w)
4090 - WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
4091 r[i].size.width -= overrun;
4030 4092
4031 for (i = 0; i < n; ++i) 4093 for (i = 0; i < n; ++i)
4032 { 4094 {
@@ -4051,39 +4113,52 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
4051 } 4113 }
4052 } 4114 }
4053 4115
4054 [bgCol set]; 4116 if (leftoverrun > 0)
4117 {
4118 r[i].origin.x += leftoverrun;
4119 r[i].size.width -= leftoverrun;
4120 }
4055 4121
4056 /* NOTE: under NS this is NOT used to draw cursors, but we must avoid 4122 /* XXX: Try to work between problem where a stretch glyph on
4057 overwriting cursor (usually when cursor on a tab). */ 4123 a partially-visible bottom row will clear part of the
4058 if (s->hl == DRAW_CURSOR) 4124 modeline, and another where list-buffers headers and similar
4059 { 4125 rows erroneously have visible_height set to 0. Not sure
4060 CGFloat x, width; 4126 where this is coming from as other terms seem not to show. */
4127 r[i].size.height = min (s->height, s->row->visible_height);
4128 }
4061 4129
4062 x = r[i].origin.x; 4130 [bgCol set];
4063 width = s->w->phys_cursor_width;
4064 r[i].size.width -= width;
4065 r[i].origin.x += width;
4066 4131
4067 NSRectFill (r[i]); 4132 /* NOTE: under NS this is NOT used to draw cursors, but we must avoid
4133 overwriting cursor (usually when cursor on a tab) */
4134 if (s->hl == DRAW_CURSOR)
4135 {
4136 CGFloat x, width;
4068 4137
4069 /* Draw overlining, etc. on the cursor. */ 4138 x = r[i].origin.x;
4070 if (s->w->phys_cursor_type == FILLED_BOX_CURSOR) 4139 width = s->w->phys_cursor_width;
4071 ns_draw_text_decoration (s, face, bgCol, width, x); 4140 r[i].size.width -= width;
4072 else 4141 r[i].origin.x += width;
4073 ns_draw_text_decoration (s, face, fgCol, width, x); 4142
4074 } 4143 NSRectFill (r[i]);
4075 else
4076 {
4077 NSRectFill (r[i]);
4078 }
4079 4144
4080 /* Draw overlining, etc. on the stretch glyph (or the part 4145 /* Draw overlining, etc. on the cursor. */
4081 of the stretch glyph after the cursor). */ 4146 if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
4082 ns_draw_text_decoration (s, face, fgCol, r[i].size.width, 4147 ns_draw_text_decoration (s, face, bgCol, width, x);
4083 r[i].origin.x); 4148 else
4149 ns_draw_text_decoration (s, face, fgCol, width, x);
4150 }
4151 else
4152 {
4153 NSRectFill (r[i]);
4084 } 4154 }
4085 ns_reset_clipping (s->f); 4155
4156 /* Draw overlining, etc. on the stretch glyph (or the part
4157 of the stretch glyph after the cursor). */
4158 ns_draw_text_decoration (s, face, fgCol, r[i].size.width,
4159 r[i].origin.x);
4086 } 4160 }
4161 ns_unfocus (s->f);
4087 s->background_filled_p = 1; 4162 s->background_filled_p = 1;
4088 } 4163 }
4089} 4164}
@@ -4233,11 +4308,9 @@ ns_draw_glyph_string (struct glyph_string *s)
4233 if (next->first_glyph->type != STRETCH_GLYPH) 4308 if (next->first_glyph->type != STRETCH_GLYPH)
4234 { 4309 {
4235 n = ns_get_glyph_string_clip_rect (s->next, r); 4310 n = ns_get_glyph_string_clip_rect (s->next, r);
4236 if (ns_clip_to_rect (s->f, r, n)) 4311 ns_focus (s->f, r, n);
4237 { 4312 ns_maybe_dumpglyphs_background (s->next, 1);
4238 ns_maybe_dumpglyphs_background (s->next, 1); 4313 ns_unfocus (s->f);
4239 ns_reset_clipping (s->f);
4240 }
4241 } 4314 }
4242 else 4315 else
4243 { 4316 {
@@ -4252,12 +4325,10 @@ ns_draw_glyph_string (struct glyph_string *s)
4252 || s->first_glyph->type == COMPOSITE_GLYPH)) 4325 || s->first_glyph->type == COMPOSITE_GLYPH))
4253 { 4326 {
4254 n = ns_get_glyph_string_clip_rect (s, r); 4327 n = ns_get_glyph_string_clip_rect (s, r);
4255 if (ns_clip_to_rect (s->f, r, n)) 4328 ns_focus (s->f, r, n);
4256 { 4329 ns_maybe_dumpglyphs_background (s, 1);
4257 ns_maybe_dumpglyphs_background (s, 1); 4330 ns_dumpglyphs_box_or_relief (s);
4258 ns_dumpglyphs_box_or_relief (s); 4331 ns_unfocus (s->f);
4259 ns_reset_clipping (s->f);
4260 }
4261 box_drawn_p = 1; 4332 box_drawn_p = 1;
4262 } 4333 }
4263 4334
@@ -4266,11 +4337,9 @@ ns_draw_glyph_string (struct glyph_string *s)
4266 4337
4267 case IMAGE_GLYPH: 4338 case IMAGE_GLYPH:
4268 n = ns_get_glyph_string_clip_rect (s, r); 4339 n = ns_get_glyph_string_clip_rect (s, r);
4269 if (ns_clip_to_rect (s->f, r, n)) 4340 ns_focus (s->f, r, n);
4270 { 4341 ns_dumpglyphs_image (s, r[0]);
4271 ns_dumpglyphs_image (s, r[0]); 4342 ns_unfocus (s->f);
4272 ns_reset_clipping (s->f);
4273 }
4274 break; 4343 break;
4275 4344
4276 case STRETCH_GLYPH: 4345 case STRETCH_GLYPH:
@@ -4280,68 +4349,66 @@ ns_draw_glyph_string (struct glyph_string *s)
4280 case CHAR_GLYPH: 4349 case CHAR_GLYPH:
4281 case COMPOSITE_GLYPH: 4350 case COMPOSITE_GLYPH:
4282 n = ns_get_glyph_string_clip_rect (s, r); 4351 n = ns_get_glyph_string_clip_rect (s, r);
4283 if (ns_clip_to_rect (s->f, r, n)) 4352 ns_focus (s->f, r, n);
4284 {
4285 if (s->for_overlaps || (s->cmp_from > 0
4286 && ! s->first_glyph->u.cmp.automatic))
4287 s->background_filled_p = 1;
4288 else
4289 ns_maybe_dumpglyphs_background
4290 (s, s->first_glyph->type == COMPOSITE_GLYPH);
4291 4353
4292 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) 4354 if (s->for_overlaps || (s->cmp_from > 0
4293 { 4355 && ! s->first_glyph->u.cmp.automatic))
4294 unsigned long tmp = NS_FACE_BACKGROUND (s->face); 4356 s->background_filled_p = 1;
4295 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face); 4357 else
4296 NS_FACE_FOREGROUND (s->face) = tmp; 4358 ns_maybe_dumpglyphs_background
4297 } 4359 (s, s->first_glyph->type == COMPOSITE_GLYPH);
4298 4360
4299 { 4361 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
4300 BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH; 4362 {
4363 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
4364 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
4365 NS_FACE_FOREGROUND (s->face) = tmp;
4366 }
4301 4367
4302 if (isComposite) 4368 {
4303 ns_draw_composite_glyph_string_foreground (s); 4369 BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
4304 else
4305 ns_draw_glyph_string_foreground (s);
4306 }
4307 4370
4308 { 4371 if (isComposite)
4309 NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0 4372 ns_draw_composite_glyph_string_foreground (s);
4310 ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face), 4373 else
4311 s->f) 4374 ns_draw_glyph_string_foreground (s);
4312 : FRAME_FOREGROUND_COLOR (s->f)); 4375 }
4313 [col set];
4314
4315 /* Draw underline, overline, strike-through. */
4316 ns_draw_text_decoration (s, s->face, col, s->width, s->x);
4317 }
4318 4376
4319 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) 4377 {
4320 { 4378 NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
4321 unsigned long tmp = NS_FACE_BACKGROUND (s->face); 4379 ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
4322 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face); 4380 s->f)
4323 NS_FACE_FOREGROUND (s->face) = tmp; 4381 : FRAME_FOREGROUND_COLOR (s->f));
4324 } 4382 [col set];
4383
4384 /* Draw underline, overline, strike-through. */
4385 ns_draw_text_decoration (s, s->face, col, s->width, s->x);
4386 }
4325 4387
4326 ns_reset_clipping (s->f); 4388 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
4389 {
4390 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
4391 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
4392 NS_FACE_FOREGROUND (s->face) = tmp;
4327 } 4393 }
4394
4395 ns_unfocus (s->f);
4328 break; 4396 break;
4329 4397
4330 case GLYPHLESS_GLYPH: 4398 case GLYPHLESS_GLYPH:
4331 n = ns_get_glyph_string_clip_rect (s, r); 4399 n = ns_get_glyph_string_clip_rect (s, r);
4332 if (ns_clip_to_rect (s->f, r, n)) 4400 ns_focus (s->f, r, n);
4333 { 4401
4334 if (s->for_overlaps || (s->cmp_from > 0 4402 if (s->for_overlaps || (s->cmp_from > 0
4335 && ! s->first_glyph->u.cmp.automatic)) 4403 && ! s->first_glyph->u.cmp.automatic))
4336 s->background_filled_p = 1; 4404 s->background_filled_p = 1;
4337 else 4405 else
4338 ns_maybe_dumpglyphs_background 4406 ns_maybe_dumpglyphs_background
4339 (s, s->first_glyph->type == COMPOSITE_GLYPH); 4407 (s, s->first_glyph->type == COMPOSITE_GLYPH);
4340 /* ... */ 4408 /* ... */
4341 /* Not yet implemented. */ 4409 /* Not yet implemented. */
4342 /* ... */ 4410 /* ... */
4343 ns_reset_clipping (s->f); 4411 ns_unfocus (s->f);
4344 }
4345 break; 4412 break;
4346 4413
4347 default: 4414 default:
@@ -4352,11 +4419,9 @@ ns_draw_glyph_string (struct glyph_string *s)
4352 if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX) 4419 if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX)
4353 { 4420 {
4354 n = ns_get_glyph_string_clip_rect (s, r); 4421 n = ns_get_glyph_string_clip_rect (s, r);
4355 if (ns_clip_to_rect (s->f, r, n)) 4422 ns_focus (s->f, r, n);
4356 { 4423 ns_dumpglyphs_box_or_relief (s);
4357 ns_dumpglyphs_box_or_relief (s); 4424 ns_unfocus (s->f);
4358 ns_reset_clipping (s->f);
4359 }
4360 } 4425 }
4361 4426
4362 s->num_clips = 0; 4427 s->num_clips = 0;