diff options
| author | Alan Third | 2018-09-28 20:23:07 +0100 |
|---|---|---|
| committer | Alan Third | 2018-09-28 20:23:46 +0100 |
| commit | 7946445962372c4255180af45cb7c857f1b0b5fa (patch) | |
| tree | 069baad0433140d7ccdc166bb8551b588cdf4d7c /src | |
| parent | 41fa88b99bebf7af62cdea0c0867b04e9b968db3 (diff) | |
| download | emacs-7946445962372c4255180af45cb7c857f1b0b5fa.tar.gz emacs-7946445962372c4255180af45cb7c857f1b0b5fa.zip | |
Make all NS drawing be done from drawRect
See bug#31904 and bug#32812.
* src/nsterm.m (ns_update_begin): Don't lock focus, only clip if there
is already a view focused.
(ns_update_end): Don't mess with view focusing any more.
(ns_focus): Only clip drawing if there is already a focused view,
otherwise mark area dirty for later drawing. Renamed ns_clip_to_rect.
All callers changed.
(ns_unfocus): Don't unfocus the view any more. Renamed
ns_reset_clipping. All callers changed.
(ns_clip_to_row): Update to match ns_clip_to_rect.
(ns_clear_frame):
(ns_clear_frame_area):
(ns_draw_fringe_bitmap):
(ns_draw_window_cursor):
(ns_draw_vertical_window_border):
(ns_draw_window_divider):
(ns_dumpglyphs_stretch):
(ns_draw_glyph_string): Only draw if ns_focus or ns_clip_to_row
return YES.
(ns_copy_bits): Remove superfluous calls to ns_(un)focus.
(ns_flush_display): New function.
Diffstat (limited to 'src')
| -rw-r--r-- | src/nsterm.m | 767 |
1 files changed, 376 insertions, 391 deletions
diff --git a/src/nsterm.m b/src/nsterm.m index 5ed71c9f8f1..954020dcde9 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -276,12 +276,7 @@ struct ns_display_info *x_display_list; /* Chain of existing displays */ | |||
| 276 | long context_menu_value = 0; | 276 | long context_menu_value = 0; |
| 277 | 277 | ||
| 278 | /* display update */ | 278 | /* display update */ |
| 279 | static struct frame *ns_updating_frame; | ||
| 280 | static NSView *focus_view = NULL; | ||
| 281 | static int ns_window_num = 0; | 279 | static int ns_window_num = 0; |
| 282 | #ifdef NS_IMPL_GNUSTEP | ||
| 283 | static NSRect uRect; // TODO: This is dead, remove it? | ||
| 284 | #endif | ||
| 285 | static BOOL gsaved = NO; | 280 | static BOOL gsaved = NO; |
| 286 | static BOOL ns_fake_keydown = NO; | 281 | static BOOL ns_fake_keydown = NO; |
| 287 | #ifdef NS_IMPL_COCOA | 282 | #ifdef NS_IMPL_COCOA |
| @@ -1039,12 +1034,13 @@ ns_update_begin (struct frame *f) | |||
| 1039 | external (RIF) call; whole frame, called before update_window_begin | 1034 | external (RIF) call; whole frame, called before update_window_begin |
| 1040 | -------------------------------------------------------------------------- */ | 1035 | -------------------------------------------------------------------------- */ |
| 1041 | { | 1036 | { |
| 1037 | #ifdef NS_IMPL_COCOA | ||
| 1042 | EmacsView *view = FRAME_NS_VIEW (f); | 1038 | EmacsView *view = FRAME_NS_VIEW (f); |
| 1039 | |||
| 1043 | NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_begin"); | 1040 | NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_begin"); |
| 1044 | 1041 | ||
| 1045 | ns_update_auto_hide_menu_bar (); | 1042 | ns_update_auto_hide_menu_bar (); |
| 1046 | 1043 | ||
| 1047 | #ifdef NS_IMPL_COCOA | ||
| 1048 | if ([view isFullscreen] && [view fsIsNative]) | 1044 | if ([view isFullscreen] && [view fsIsNative]) |
| 1049 | { | 1045 | { |
| 1050 | // Fix reappearing tool bar in fullscreen for Mac OS X 10.7 | 1046 | // Fix reappearing tool bar in fullscreen for Mac OS X 10.7 |
| @@ -1053,36 +1049,29 @@ ns_update_begin (struct frame *f) | |||
| 1053 | if (! tbar_visible != ! [toolbar isVisible]) | 1049 | if (! tbar_visible != ! [toolbar isVisible]) |
| 1054 | [toolbar setVisible: tbar_visible]; | 1050 | [toolbar setVisible: tbar_visible]; |
| 1055 | } | 1051 | } |
| 1056 | #endif | ||
| 1057 | |||
| 1058 | ns_updating_frame = f; | ||
| 1059 | [view lockFocus]; | ||
| 1060 | 1052 | ||
| 1061 | /* drawRect may have been called for say the minibuffer, and then clip path | 1053 | /* drawRect may have been called for say the minibuffer, and then clip path |
| 1062 | is for the minibuffer. But the display engine may draw more because | 1054 | is for the minibuffer. But the display engine may draw more because |
| 1063 | we have set the frame as garbaged. So reset clip path to the whole | 1055 | we have set the frame as garbaged. So reset clip path to the whole |
| 1064 | view. */ | 1056 | view. */ |
| 1065 | #ifdef NS_IMPL_COCOA | 1057 | /* FIXME: I don't think we need to do this. */ |
| 1066 | { | 1058 | if ([NSView focusView] == FRAME_NS_VIEW (f)) |
| 1067 | NSBezierPath *bp; | 1059 | { |
| 1068 | NSRect r = [view frame]; | 1060 | NSBezierPath *bp; |
| 1069 | NSRect cr = [[view window] frame]; | 1061 | NSRect r = [view frame]; |
| 1070 | /* If a large frame size is set, r may be larger than the window frame | 1062 | NSRect cr = [[view window] frame]; |
| 1071 | before constrained. In that case don't change the clip path, as we | 1063 | /* If a large frame size is set, r may be larger than the window frame |
| 1072 | will clear in to the tool bar and title bar. */ | 1064 | before constrained. In that case don't change the clip path, as we |
| 1073 | if (r.size.height | 1065 | will clear in to the tool bar and title bar. */ |
| 1074 | + FRAME_NS_TITLEBAR_HEIGHT (f) | 1066 | if (r.size.height |
| 1075 | + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) | 1067 | + FRAME_NS_TITLEBAR_HEIGHT (f) |
| 1076 | { | 1068 | + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) |
| 1077 | bp = [[NSBezierPath bezierPathWithRect: r] retain]; | 1069 | { |
| 1078 | [bp setClip]; | 1070 | bp = [[NSBezierPath bezierPathWithRect: r] retain]; |
| 1079 | [bp release]; | 1071 | [bp setClip]; |
| 1080 | } | 1072 | [bp release]; |
| 1081 | } | 1073 | } |
| 1082 | #endif | 1074 | } |
| 1083 | |||
| 1084 | #ifdef NS_IMPL_GNUSTEP | ||
| 1085 | uRect = NSMakeRect (0, 0, 0, 0); | ||
| 1086 | #endif | 1075 | #endif |
| 1087 | } | 1076 | } |
| 1088 | 1077 | ||
| @@ -1164,99 +1153,66 @@ ns_update_end (struct frame *f) | |||
| 1164 | external (RIF) call; for whole frame, called after update_window_end | 1153 | external (RIF) call; for whole frame, called after update_window_end |
| 1165 | -------------------------------------------------------------------------- */ | 1154 | -------------------------------------------------------------------------- */ |
| 1166 | { | 1155 | { |
| 1167 | EmacsView *view = FRAME_NS_VIEW (f); | ||
| 1168 | |||
| 1169 | NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end"); | 1156 | NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end"); |
| 1170 | 1157 | ||
| 1171 | /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ | 1158 | /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ |
| 1172 | MOUSE_HL_INFO (f)->mouse_face_defer = 0; | 1159 | MOUSE_HL_INFO (f)->mouse_face_defer = 0; |
| 1173 | |||
| 1174 | block_input (); | ||
| 1175 | |||
| 1176 | [view unlockFocus]; | ||
| 1177 | [[view window] flushWindow]; | ||
| 1178 | |||
| 1179 | unblock_input (); | ||
| 1180 | ns_updating_frame = NULL; | ||
| 1181 | } | 1160 | } |
| 1182 | 1161 | ||
| 1183 | static void | 1162 | |
| 1184 | ns_focus (struct frame *f, NSRect *r, int n) | 1163 | static BOOL |
| 1164 | ns_clip_to_rect (struct frame *f, NSRect *r, int n) | ||
| 1185 | /* -------------------------------------------------------------------------- | 1165 | /* -------------------------------------------------------------------------- |
| 1186 | Internal: Focus on given frame. During small local updates this is used to | 1166 | Clip the drawing area to rectangle r in frame f. If drawing is not |
| 1187 | draw, however during large updates, ns_update_begin and ns_update_end are | 1167 | currently possible mark r as dirty and return NO, otherwise return |
| 1188 | called to wrap the whole thing, in which case these calls are stubbed out. | 1168 | YES. |
| 1189 | Except, on GNUstep, we accumulate the rectangle being drawn into, because | ||
| 1190 | the back end won't do this automatically, and will just end up flushing | ||
| 1191 | the entire window. | ||
| 1192 | -------------------------------------------------------------------------- */ | 1169 | -------------------------------------------------------------------------- */ |
| 1193 | { | 1170 | { |
| 1194 | NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_focus"); | 1171 | NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_clip_to_rect"); |
| 1195 | if (r != NULL) | 1172 | if (r) |
| 1196 | { | 1173 | { |
| 1197 | NSTRACE_RECT ("r", *r); | 1174 | NSTRACE_RECT ("r", *r); |
| 1198 | } | ||
| 1199 | 1175 | ||
| 1200 | if (f != ns_updating_frame) | 1176 | if ([NSView focusView] == FRAME_NS_VIEW (f)) |
| 1201 | { | ||
| 1202 | NSView *view = FRAME_NS_VIEW (f); | ||
| 1203 | if (view != focus_view) | ||
| 1204 | { | 1177 | { |
| 1205 | if (focus_view != NULL) | 1178 | [[NSGraphicsContext currentContext] saveGraphicsState]; |
| 1206 | { | 1179 | if (n == 2) |
| 1207 | [focus_view unlockFocus]; | 1180 | NSRectClipList (r, 2); |
| 1208 | [[focus_view window] flushWindow]; | 1181 | else |
| 1209 | /*debug_lock--; */ | 1182 | NSRectClip (*r); |
| 1210 | } | 1183 | gsaved = YES; |
| 1211 | 1184 | ||
| 1212 | if (view) | 1185 | return YES; |
| 1213 | [view lockFocus]; | ||
| 1214 | focus_view = view; | ||
| 1215 | /*if (view) debug_lock++; */ | ||
| 1216 | } | 1186 | } |
| 1217 | } | ||
| 1218 | |||
| 1219 | /* clipping */ | ||
| 1220 | if (r) | ||
| 1221 | { | ||
| 1222 | [[NSGraphicsContext currentContext] saveGraphicsState]; | ||
| 1223 | if (n == 2) | ||
| 1224 | NSRectClipList (r, 2); | ||
| 1225 | else | 1187 | else |
| 1226 | NSRectClip (*r); | 1188 | { |
| 1227 | gsaved = YES; | 1189 | NSView *view = FRAME_NS_VIEW (f); |
| 1190 | int i; | ||
| 1191 | for (i = 0 ; i < n ; i++) | ||
| 1192 | [view setNeedsDisplayInRect:r[i]]; | ||
| 1193 | } | ||
| 1228 | } | 1194 | } |
| 1195 | |||
| 1196 | return NO; | ||
| 1229 | } | 1197 | } |
| 1230 | 1198 | ||
| 1231 | 1199 | ||
| 1232 | static void | 1200 | static void |
| 1233 | ns_unfocus (struct frame *f) | 1201 | ns_reset_clipping (struct frame *f) |
| 1234 | /* -------------------------------------------------------------------------- | 1202 | /* Internal: Restore the previous graphics state, unsetting any |
| 1235 | Internal: Remove focus on given frame | 1203 | clipping areas. */ |
| 1236 | -------------------------------------------------------------------------- */ | ||
| 1237 | { | 1204 | { |
| 1238 | NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_unfocus"); | 1205 | NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping"); |
| 1239 | 1206 | ||
| 1240 | if (gsaved) | 1207 | if (gsaved) |
| 1241 | { | 1208 | { |
| 1242 | [[NSGraphicsContext currentContext] restoreGraphicsState]; | 1209 | [[NSGraphicsContext currentContext] restoreGraphicsState]; |
| 1243 | gsaved = NO; | 1210 | gsaved = NO; |
| 1244 | } | 1211 | } |
| 1245 | |||
| 1246 | if (f != ns_updating_frame) | ||
| 1247 | { | ||
| 1248 | if (focus_view != NULL) | ||
| 1249 | { | ||
| 1250 | [focus_view unlockFocus]; | ||
| 1251 | [[focus_view window] flushWindow]; | ||
| 1252 | focus_view = NULL; | ||
| 1253 | /*debug_lock--; */ | ||
| 1254 | } | ||
| 1255 | } | ||
| 1256 | } | 1212 | } |
| 1257 | 1213 | ||
| 1258 | 1214 | ||
| 1259 | static void | 1215 | static BOOL |
| 1260 | ns_clip_to_row (struct window *w, struct glyph_row *row, | 1216 | ns_clip_to_row (struct window *w, struct glyph_row *row, |
| 1261 | enum glyph_row_area area, BOOL gc) | 1217 | enum glyph_row_area area, BOOL gc) |
| 1262 | /* -------------------------------------------------------------------------- | 1218 | /* -------------------------------------------------------------------------- |
| @@ -1275,7 +1231,19 @@ ns_clip_to_row (struct window *w, struct glyph_row *row, | |||
| 1275 | clip_rect.size.width = window_width; | 1231 | clip_rect.size.width = window_width; |
| 1276 | clip_rect.size.height = row->visible_height; | 1232 | clip_rect.size.height = row->visible_height; |
| 1277 | 1233 | ||
| 1278 | ns_focus (f, &clip_rect, 1); | 1234 | return ns_clip_to_rect (f, &clip_rect, 1); |
| 1235 | } | ||
| 1236 | |||
| 1237 | |||
| 1238 | static void | ||
| 1239 | ns_flush_display (struct frame *f) | ||
| 1240 | /* Force the frame to redisplay. If areas have previously been marked | ||
| 1241 | dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call | ||
| 1242 | draw_rect: which will "expose" those areas. */ | ||
| 1243 | { | ||
| 1244 | block_input (); | ||
| 1245 | [FRAME_NS_VIEW (f) displayIfNeeded]; | ||
| 1246 | unblock_input (); | ||
| 1279 | } | 1247 | } |
| 1280 | 1248 | ||
| 1281 | 1249 | ||
| @@ -2699,14 +2667,16 @@ ns_clear_frame (struct frame *f) | |||
| 2699 | r = [view bounds]; | 2667 | r = [view bounds]; |
| 2700 | 2668 | ||
| 2701 | block_input (); | 2669 | block_input (); |
| 2702 | ns_focus (f, &r, 1); | 2670 | if (ns_clip_to_rect (f, &r, 1)) |
| 2703 | [ns_lookup_indexed_color (NS_FACE_BACKGROUND | 2671 | { |
| 2704 | (FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set]; | 2672 | [ns_lookup_indexed_color (NS_FACE_BACKGROUND |
| 2705 | NSRectFill (r); | 2673 | (FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set]; |
| 2706 | ns_unfocus (f); | 2674 | NSRectFill (r); |
| 2707 | 2675 | ns_reset_clipping (f); | |
| 2708 | /* as of 2006/11 or so this is now needed */ | 2676 | |
| 2709 | ns_redraw_scroll_bars (f); | 2677 | /* as of 2006/11 or so this is now needed */ |
| 2678 | ns_redraw_scroll_bars (f); | ||
| 2679 | } | ||
| 2710 | unblock_input (); | 2680 | unblock_input (); |
| 2711 | } | 2681 | } |
| 2712 | 2682 | ||
| @@ -2727,13 +2697,14 @@ ns_clear_frame_area (struct frame *f, int x, int y, int width, int height) | |||
| 2727 | NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_clear_frame_area"); | 2697 | NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_clear_frame_area"); |
| 2728 | 2698 | ||
| 2729 | r = NSIntersectionRect (r, [view frame]); | 2699 | r = NSIntersectionRect (r, [view frame]); |
| 2730 | ns_focus (f, &r, 1); | 2700 | if (ns_clip_to_rect (f, &r, 1)) |
| 2731 | [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set]; | 2701 | { |
| 2702 | [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set]; | ||
| 2732 | 2703 | ||
| 2733 | NSRectFill (r); | 2704 | NSRectFill (r); |
| 2734 | 2705 | ||
| 2735 | ns_unfocus (f); | 2706 | ns_reset_clipping (f); |
| 2736 | return; | 2707 | } |
| 2737 | } | 2708 | } |
| 2738 | 2709 | ||
| 2739 | static void | 2710 | static void |
| @@ -2745,11 +2716,11 @@ ns_copy_bits (struct frame *f, NSRect src, NSRect dest) | |||
| 2745 | { | 2716 | { |
| 2746 | hide_bell(); // Ensure the bell image isn't scrolled. | 2717 | hide_bell(); // Ensure the bell image isn't scrolled. |
| 2747 | 2718 | ||
| 2748 | ns_focus (f, &dest, 1); | 2719 | /* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is |
| 2720 | no obvious replacement so we may have to come up with our own. */ | ||
| 2749 | [FRAME_NS_VIEW (f) scrollRect: src | 2721 | [FRAME_NS_VIEW (f) scrollRect: src |
| 2750 | by: NSMakeSize (dest.origin.x - src.origin.x, | 2722 | by: NSMakeSize (dest.origin.x - src.origin.x, |
| 2751 | dest.origin.y - src.origin.y)]; | 2723 | dest.origin.y - src.origin.y)]; |
| 2752 | ns_unfocus (f); | ||
| 2753 | } | 2724 | } |
| 2754 | } | 2725 | } |
| 2755 | 2726 | ||
| @@ -2960,85 +2931,86 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, | |||
| 2960 | } | 2931 | } |
| 2961 | 2932 | ||
| 2962 | /* Must clip because of partially visible lines. */ | 2933 | /* Must clip because of partially visible lines. */ |
| 2963 | ns_clip_to_row (w, row, ANY_AREA, YES); | 2934 | if (ns_clip_to_row (w, row, ANY_AREA, YES)) |
| 2964 | |||
| 2965 | if (!p->overlay_p) | ||
| 2966 | { | 2935 | { |
| 2967 | int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny; | 2936 | if (!p->overlay_p) |
| 2968 | |||
| 2969 | if (bx >= 0 && nx > 0) | ||
| 2970 | { | 2937 | { |
| 2971 | NSRect r = NSMakeRect (bx, by, nx, ny); | 2938 | int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny; |
| 2972 | NSRectClip (r); | ||
| 2973 | [ns_lookup_indexed_color (face->background, f) set]; | ||
| 2974 | NSRectFill (r); | ||
| 2975 | } | ||
| 2976 | } | ||
| 2977 | 2939 | ||
| 2978 | if (p->which) | 2940 | if (bx >= 0 && nx > 0) |
| 2979 | { | 2941 | { |
| 2980 | NSRect r = NSMakeRect (p->x, p->y, p->wd, p->h); | 2942 | NSRect r = NSMakeRect (bx, by, nx, ny); |
| 2981 | EmacsImage *img = bimgs[p->which - 1]; | 2943 | NSRectClip (r); |
| 2982 | 2944 | [ns_lookup_indexed_color (face->background, f) set]; | |
| 2983 | if (!img) | 2945 | NSRectFill (r); |
| 2984 | { | 2946 | } |
| 2985 | // Note: For "periodic" images, allocate one EmacsImage for | ||
| 2986 | // the base image, and use it for all dh:s. | ||
| 2987 | unsigned short *bits = p->bits; | ||
| 2988 | int full_height = p->h + p->dh; | ||
| 2989 | int i; | ||
| 2990 | unsigned char *cbits = xmalloc (full_height); | ||
| 2991 | |||
| 2992 | for (i = 0; i < full_height; i++) | ||
| 2993 | cbits[i] = bits[i]; | ||
| 2994 | img = [[EmacsImage alloc] initFromXBM: cbits width: 8 | ||
| 2995 | height: full_height | ||
| 2996 | fg: 0 bg: 0]; | ||
| 2997 | bimgs[p->which - 1] = img; | ||
| 2998 | xfree (cbits); | ||
| 2999 | } | 2947 | } |
| 3000 | 2948 | ||
| 3001 | NSTRACE_RECT ("r", r); | 2949 | if (p->which) |
| 2950 | { | ||
| 2951 | NSRect r = NSMakeRect (p->x, p->y, p->wd, p->h); | ||
| 2952 | EmacsImage *img = bimgs[p->which - 1]; | ||
| 3002 | 2953 | ||
| 3003 | NSRectClip (r); | 2954 | if (!img) |
| 3004 | /* Since we composite the bitmap instead of just blitting it, we need | 2955 | { |
| 3005 | to erase the whole background. */ | 2956 | // Note: For "periodic" images, allocate one EmacsImage for |
| 3006 | [ns_lookup_indexed_color(face->background, f) set]; | 2957 | // the base image, and use it for all dh:s. |
| 3007 | NSRectFill (r); | 2958 | unsigned short *bits = p->bits; |
| 2959 | int full_height = p->h + p->dh; | ||
| 2960 | int i; | ||
| 2961 | unsigned char *cbits = xmalloc (full_height); | ||
| 2962 | |||
| 2963 | for (i = 0; i < full_height; i++) | ||
| 2964 | cbits[i] = bits[i]; | ||
| 2965 | img = [[EmacsImage alloc] initFromXBM: cbits width: 8 | ||
| 2966 | height: full_height | ||
| 2967 | fg: 0 bg: 0]; | ||
| 2968 | bimgs[p->which - 1] = img; | ||
| 2969 | xfree (cbits); | ||
| 2970 | } | ||
| 3008 | 2971 | ||
| 3009 | { | 2972 | NSTRACE_RECT ("r", r); |
| 3010 | NSColor *bm_color; | ||
| 3011 | if (!p->cursor_p) | ||
| 3012 | bm_color = ns_lookup_indexed_color(face->foreground, f); | ||
| 3013 | else if (p->overlay_p) | ||
| 3014 | bm_color = ns_lookup_indexed_color(face->background, f); | ||
| 3015 | else | ||
| 3016 | bm_color = f->output_data.ns->cursor_color; | ||
| 3017 | [img setXBMColor: bm_color]; | ||
| 3018 | } | ||
| 3019 | 2973 | ||
| 3020 | #ifdef NS_IMPL_COCOA | 2974 | NSRectClip (r); |
| 3021 | // Note: For periodic images, the full image height is "h + hd". | 2975 | /* Since we composite the bitmap instead of just blitting it, we need |
| 3022 | // By using the height h, a suitable part of the image is used. | 2976 | to erase the whole background. */ |
| 3023 | NSRect fromRect = NSMakeRect(0, 0, p->wd, p->h); | 2977 | [ns_lookup_indexed_color(face->background, f) set]; |
| 2978 | NSRectFill (r); | ||
| 3024 | 2979 | ||
| 3025 | NSTRACE_RECT ("fromRect", fromRect); | 2980 | { |
| 2981 | NSColor *bm_color; | ||
| 2982 | if (!p->cursor_p) | ||
| 2983 | bm_color = ns_lookup_indexed_color(face->foreground, f); | ||
| 2984 | else if (p->overlay_p) | ||
| 2985 | bm_color = ns_lookup_indexed_color(face->background, f); | ||
| 2986 | else | ||
| 2987 | bm_color = f->output_data.ns->cursor_color; | ||
| 2988 | [img setXBMColor: bm_color]; | ||
| 2989 | } | ||
| 3026 | 2990 | ||
| 3027 | [img drawInRect: r | 2991 | #ifdef NS_IMPL_COCOA |
| 3028 | fromRect: fromRect | 2992 | // Note: For periodic images, the full image height is "h + hd". |
| 3029 | operation: NSCompositingOperationSourceOver | 2993 | // By using the height h, a suitable part of the image is used. |
| 3030 | fraction: 1.0 | 2994 | NSRect fromRect = NSMakeRect(0, 0, p->wd, p->h); |
| 3031 | respectFlipped: YES | 2995 | |
| 3032 | hints: nil]; | 2996 | NSTRACE_RECT ("fromRect", fromRect); |
| 2997 | |||
| 2998 | [img drawInRect: r | ||
| 2999 | fromRect: fromRect | ||
| 3000 | operation: NSCompositingOperationSourceOver | ||
| 3001 | fraction: 1.0 | ||
| 3002 | respectFlipped: YES | ||
| 3003 | hints: nil]; | ||
| 3033 | #else | 3004 | #else |
| 3034 | { | 3005 | { |
| 3035 | NSPoint pt = r.origin; | 3006 | NSPoint pt = r.origin; |
| 3036 | pt.y += p->h; | 3007 | pt.y += p->h; |
| 3037 | [img compositeToPoint: pt operation: NSCompositingOperationSourceOver]; | 3008 | [img compositeToPoint: pt operation: NSCompositingOperationSourceOver]; |
| 3038 | } | 3009 | } |
| 3039 | #endif | 3010 | #endif |
| 3011 | } | ||
| 3012 | ns_reset_clipping (f); | ||
| 3040 | } | 3013 | } |
| 3041 | ns_unfocus (f); | ||
| 3042 | } | 3014 | } |
| 3043 | 3015 | ||
| 3044 | 3016 | ||
| @@ -3120,67 +3092,66 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | |||
| 3120 | r.size.height = h; | 3092 | r.size.height = h; |
| 3121 | r.size.width = w->phys_cursor_width; | 3093 | r.size.width = w->phys_cursor_width; |
| 3122 | 3094 | ||
| 3123 | /* Prevent the cursor from being drawn outside the text area. */ | 3095 | /* Prevent the cursor from being drawn outside the text area. */ |
| 3124 | ns_clip_to_row (w, glyph_row, TEXT_AREA, NO); /* do ns_focus(f, &r, 1); if remove */ | 3096 | if (ns_clip_to_row (w, glyph_row, TEXT_AREA, NO)) |
| 3125 | |||
| 3126 | |||
| 3127 | face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id); | ||
| 3128 | if (face && NS_FACE_BACKGROUND (face) | ||
| 3129 | == ns_index_color (FRAME_CURSOR_COLOR (f), f)) | ||
| 3130 | { | 3097 | { |
| 3131 | [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set]; | 3098 | face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id); |
| 3132 | hollow_color = FRAME_CURSOR_COLOR (f); | 3099 | if (face && NS_FACE_BACKGROUND (face) |
| 3133 | } | 3100 | == ns_index_color (FRAME_CURSOR_COLOR (f), f)) |
| 3134 | else | 3101 | { |
| 3135 | [FRAME_CURSOR_COLOR (f) set]; | 3102 | [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set]; |
| 3103 | hollow_color = FRAME_CURSOR_COLOR (f); | ||
| 3104 | } | ||
| 3105 | else | ||
| 3106 | [FRAME_CURSOR_COLOR (f) set]; | ||
| 3136 | 3107 | ||
| 3137 | #ifdef NS_IMPL_COCOA | 3108 | #ifdef NS_IMPL_COCOA |
| 3138 | /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph | 3109 | /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph |
| 3139 | atomic. Cleaner ways of doing this should be investigated. | 3110 | atomic. Cleaner ways of doing this should be investigated. |
| 3140 | One way would be to set a global variable DRAWING_CURSOR | 3111 | One way would be to set a global variable DRAWING_CURSOR |
| 3141 | when making the call to draw_phys..(), don't focus in that | 3112 | when making the call to draw_phys..(), don't focus in that |
| 3142 | case, then move the ns_unfocus() here after that call. */ | 3113 | case, then move the ns_reset_clipping() here after that call. */ |
| 3143 | NSDisableScreenUpdates (); | 3114 | NSDisableScreenUpdates (); |
| 3144 | #endif | 3115 | #endif |
| 3145 | 3116 | ||
| 3146 | switch (cursor_type) | 3117 | switch (cursor_type) |
| 3147 | { | 3118 | { |
| 3148 | case DEFAULT_CURSOR: | 3119 | case DEFAULT_CURSOR: |
| 3149 | case NO_CURSOR: | 3120 | case NO_CURSOR: |
| 3150 | break; | 3121 | break; |
| 3151 | case FILLED_BOX_CURSOR: | 3122 | case FILLED_BOX_CURSOR: |
| 3152 | NSRectFill (r); | 3123 | NSRectFill (r); |
| 3153 | break; | 3124 | break; |
| 3154 | case HOLLOW_BOX_CURSOR: | 3125 | case HOLLOW_BOX_CURSOR: |
| 3155 | NSRectFill (r); | 3126 | NSRectFill (r); |
| 3156 | [hollow_color set]; | 3127 | [hollow_color set]; |
| 3157 | NSRectFill (NSInsetRect (r, 1, 1)); | 3128 | NSRectFill (NSInsetRect (r, 1, 1)); |
| 3158 | [FRAME_CURSOR_COLOR (f) set]; | 3129 | [FRAME_CURSOR_COLOR (f) set]; |
| 3159 | break; | 3130 | break; |
| 3160 | case HBAR_CURSOR: | 3131 | case HBAR_CURSOR: |
| 3161 | NSRectFill (r); | 3132 | NSRectFill (r); |
| 3162 | break; | 3133 | break; |
| 3163 | case BAR_CURSOR: | 3134 | case BAR_CURSOR: |
| 3164 | s = r; | 3135 | s = r; |
| 3165 | /* If the character under cursor is R2L, draw the bar cursor | 3136 | /* If the character under cursor is R2L, draw the bar cursor |
| 3166 | on the right of its glyph, rather than on the left. */ | 3137 | on the right of its glyph, rather than on the left. */ |
| 3167 | cursor_glyph = get_phys_cursor_glyph (w); | 3138 | cursor_glyph = get_phys_cursor_glyph (w); |
| 3168 | if ((cursor_glyph->resolved_level & 1) != 0) | 3139 | if ((cursor_glyph->resolved_level & 1) != 0) |
| 3169 | s.origin.x += cursor_glyph->pixel_width - s.size.width; | 3140 | s.origin.x += cursor_glyph->pixel_width - s.size.width; |
| 3170 | 3141 | ||
| 3171 | NSRectFill (s); | 3142 | NSRectFill (s); |
| 3172 | break; | 3143 | break; |
| 3173 | } | 3144 | } |
| 3174 | ns_unfocus (f); | 3145 | ns_reset_clipping (f); |
| 3175 | 3146 | ||
| 3176 | /* draw the character under the cursor */ | 3147 | /* draw the character under the cursor */ |
| 3177 | if (cursor_type != NO_CURSOR) | 3148 | if (cursor_type != NO_CURSOR) |
| 3178 | draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); | 3149 | draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); |
| 3179 | 3150 | ||
| 3180 | #ifdef NS_IMPL_COCOA | 3151 | #ifdef NS_IMPL_COCOA |
| 3181 | NSEnableScreenUpdates (); | 3152 | NSEnableScreenUpdates (); |
| 3182 | #endif | 3153 | #endif |
| 3183 | 3154 | } | |
| 3184 | } | 3155 | } |
| 3185 | 3156 | ||
| 3186 | 3157 | ||
| @@ -3198,12 +3169,14 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1) | |||
| 3198 | 3169 | ||
| 3199 | face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID); | 3170 | face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID); |
| 3200 | 3171 | ||
| 3201 | ns_focus (f, &r, 1); | 3172 | if (ns_clip_to_rect (f, &r, 1)) |
| 3202 | if (face) | 3173 | { |
| 3203 | [ns_lookup_indexed_color(face->foreground, f) set]; | 3174 | if (face) |
| 3175 | [ns_lookup_indexed_color(face->foreground, f) set]; | ||
| 3204 | 3176 | ||
| 3205 | NSRectFill(r); | 3177 | NSRectFill(r); |
| 3206 | ns_unfocus (f); | 3178 | ns_reset_clipping (f); |
| 3179 | } | ||
| 3207 | } | 3180 | } |
| 3208 | 3181 | ||
| 3209 | 3182 | ||
| @@ -3230,39 +3203,40 @@ ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) | |||
| 3230 | 3203 | ||
| 3231 | NSTRACE ("ns_draw_window_divider"); | 3204 | NSTRACE ("ns_draw_window_divider"); |
| 3232 | 3205 | ||
| 3233 | ns_focus (f, ÷r, 1); | 3206 | if (ns_clip_to_rect (f, ÷r, 1)) |
| 3234 | |||
| 3235 | if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3)) | ||
| 3236 | /* A vertical divider, at least three pixels wide: Draw first and | ||
| 3237 | last pixels differently. */ | ||
| 3238 | { | 3207 | { |
| 3239 | [ns_lookup_indexed_color(color_first, f) set]; | 3208 | if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3)) |
| 3240 | NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0)); | 3209 | /* A vertical divider, at least three pixels wide: Draw first and |
| 3241 | [ns_lookup_indexed_color(color, f) set]; | 3210 | last pixels differently. */ |
| 3242 | NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0)); | 3211 | { |
| 3243 | [ns_lookup_indexed_color(color_last, f) set]; | 3212 | [ns_lookup_indexed_color(color_first, f) set]; |
| 3244 | NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0)); | 3213 | NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0)); |
| 3245 | } | 3214 | [ns_lookup_indexed_color(color, f) set]; |
| 3246 | else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3)) | 3215 | NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0)); |
| 3247 | /* A horizontal divider, at least three pixels high: Draw first and | 3216 | [ns_lookup_indexed_color(color_last, f) set]; |
| 3248 | last pixels differently. */ | 3217 | NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0)); |
| 3249 | { | 3218 | } |
| 3250 | [ns_lookup_indexed_color(color_first, f) set]; | 3219 | else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3)) |
| 3251 | NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1)); | 3220 | /* A horizontal divider, at least three pixels high: Draw first and |
| 3252 | [ns_lookup_indexed_color(color, f) set]; | 3221 | last pixels differently. */ |
| 3253 | NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2)); | 3222 | { |
| 3254 | [ns_lookup_indexed_color(color_last, f) set]; | 3223 | [ns_lookup_indexed_color(color_first, f) set]; |
| 3255 | NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1)); | 3224 | NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1)); |
| 3256 | } | 3225 | [ns_lookup_indexed_color(color, f) set]; |
| 3257 | else | 3226 | NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2)); |
| 3258 | { | 3227 | [ns_lookup_indexed_color(color_last, f) set]; |
| 3259 | /* In any other case do not draw the first and last pixels | 3228 | NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1)); |
| 3260 | differently. */ | 3229 | } |
| 3261 | [ns_lookup_indexed_color(color, f) set]; | 3230 | else |
| 3262 | NSRectFill(divider); | 3231 | { |
| 3263 | } | 3232 | /* In any other case do not draw the first and last pixels |
| 3233 | differently. */ | ||
| 3234 | [ns_lookup_indexed_color(color, f) set]; | ||
| 3235 | NSRectFill(divider); | ||
| 3236 | } | ||
| 3264 | 3237 | ||
| 3265 | ns_unfocus (f); | 3238 | ns_reset_clipping (f); |
| 3239 | } | ||
| 3266 | } | 3240 | } |
| 3267 | 3241 | ||
| 3268 | static void | 3242 | static void |
| @@ -3846,83 +3820,84 @@ ns_dumpglyphs_stretch (struct glyph_string *s) | |||
| 3846 | n = ns_get_glyph_string_clip_rect (s, r); | 3820 | n = ns_get_glyph_string_clip_rect (s, r); |
| 3847 | *r = NSMakeRect (s->x, s->y, s->background_width, s->height); | 3821 | *r = NSMakeRect (s->x, s->y, s->background_width, s->height); |
| 3848 | 3822 | ||
| 3849 | ns_focus (s->f, r, n); | 3823 | if (ns_clip_to_rect (s->f, r, n)) |
| 3850 | |||
| 3851 | if (s->hl == DRAW_MOUSE_FACE) | ||
| 3852 | { | ||
| 3853 | face = FACE_FROM_ID_OR_NULL (s->f, | ||
| 3854 | MOUSE_HL_INFO (s->f)->mouse_face_face_id); | ||
| 3855 | if (!face) | ||
| 3856 | face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); | ||
| 3857 | } | ||
| 3858 | else | ||
| 3859 | face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | ||
| 3860 | |||
| 3861 | bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f); | ||
| 3862 | fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f); | ||
| 3863 | |||
| 3864 | for (i = 0; i < n; ++i) | ||
| 3865 | { | 3824 | { |
| 3866 | if (!s->row->full_width_p) | 3825 | if (s->hl == DRAW_MOUSE_FACE) |
| 3867 | { | 3826 | { |
| 3868 | int overrun, leftoverrun; | 3827 | face = FACE_FROM_ID_OR_NULL (s->f, |
| 3869 | 3828 | MOUSE_HL_INFO (s->f)->mouse_face_face_id); | |
| 3870 | /* truncate to avoid overwriting fringe and/or scrollbar */ | 3829 | if (!face) |
| 3871 | overrun = max (0, (s->x + s->background_width) | 3830 | face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); |
| 3872 | - (WINDOW_BOX_RIGHT_EDGE_X (s->w) | ||
| 3873 | - WINDOW_RIGHT_FRINGE_WIDTH (s->w))); | ||
| 3874 | r[i].size.width -= overrun; | ||
| 3875 | |||
| 3876 | /* truncate to avoid overwriting to left of the window box */ | ||
| 3877 | leftoverrun = (WINDOW_BOX_LEFT_EDGE_X (s->w) | ||
| 3878 | + WINDOW_LEFT_FRINGE_WIDTH (s->w)) - s->x; | ||
| 3879 | |||
| 3880 | if (leftoverrun > 0) | ||
| 3881 | { | ||
| 3882 | r[i].origin.x += leftoverrun; | ||
| 3883 | r[i].size.width -= leftoverrun; | ||
| 3884 | } | ||
| 3885 | |||
| 3886 | /* XXX: Try to work between problem where a stretch glyph on | ||
| 3887 | a partially-visible bottom row will clear part of the | ||
| 3888 | modeline, and another where list-buffers headers and similar | ||
| 3889 | rows erroneously have visible_height set to 0. Not sure | ||
| 3890 | where this is coming from as other terms seem not to show. */ | ||
| 3891 | r[i].size.height = min (s->height, s->row->visible_height); | ||
| 3892 | } | 3831 | } |
| 3832 | else | ||
| 3833 | face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | ||
| 3893 | 3834 | ||
| 3894 | [bgCol set]; | 3835 | bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f); |
| 3836 | fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f); | ||
| 3895 | 3837 | ||
| 3896 | /* NOTE: under NS this is NOT used to draw cursors, but we must avoid | 3838 | for (i = 0; i < n; ++i) |
| 3897 | overwriting cursor (usually when cursor on a tab) */ | ||
| 3898 | if (s->hl == DRAW_CURSOR) | ||
| 3899 | { | 3839 | { |
| 3900 | CGFloat x, width; | 3840 | if (!s->row->full_width_p) |
| 3841 | { | ||
| 3842 | int overrun, leftoverrun; | ||
| 3843 | |||
| 3844 | /* truncate to avoid overwriting fringe and/or scrollbar */ | ||
| 3845 | overrun = max (0, (s->x + s->background_width) | ||
| 3846 | - (WINDOW_BOX_RIGHT_EDGE_X (s->w) | ||
| 3847 | - WINDOW_RIGHT_FRINGE_WIDTH (s->w))); | ||
| 3848 | r[i].size.width -= overrun; | ||
| 3849 | |||
| 3850 | /* truncate to avoid overwriting to left of the window box */ | ||
| 3851 | leftoverrun = (WINDOW_BOX_LEFT_EDGE_X (s->w) | ||
| 3852 | + WINDOW_LEFT_FRINGE_WIDTH (s->w)) - s->x; | ||
| 3853 | |||
| 3854 | if (leftoverrun > 0) | ||
| 3855 | { | ||
| 3856 | r[i].origin.x += leftoverrun; | ||
| 3857 | r[i].size.width -= leftoverrun; | ||
| 3858 | } | ||
| 3859 | |||
| 3860 | /* XXX: Try to work between problem where a stretch glyph on | ||
| 3861 | a partially-visible bottom row will clear part of the | ||
| 3862 | modeline, and another where list-buffers headers and similar | ||
| 3863 | rows erroneously have visible_height set to 0. Not sure | ||
| 3864 | where this is coming from as other terms seem not to show. */ | ||
| 3865 | r[i].size.height = min (s->height, s->row->visible_height); | ||
| 3866 | } | ||
| 3867 | |||
| 3868 | [bgCol set]; | ||
| 3869 | |||
| 3870 | /* NOTE: under NS this is NOT used to draw cursors, but we must avoid | ||
| 3871 | overwriting cursor (usually when cursor on a tab). */ | ||
| 3872 | if (s->hl == DRAW_CURSOR) | ||
| 3873 | { | ||
| 3874 | CGFloat x, width; | ||
| 3901 | 3875 | ||
| 3902 | x = r[i].origin.x; | 3876 | x = r[i].origin.x; |
| 3903 | width = s->w->phys_cursor_width; | 3877 | width = s->w->phys_cursor_width; |
| 3904 | r[i].size.width -= width; | 3878 | r[i].size.width -= width; |
| 3905 | r[i].origin.x += width; | 3879 | r[i].origin.x += width; |
| 3906 | 3880 | ||
| 3907 | NSRectFill (r[i]); | 3881 | NSRectFill (r[i]); |
| 3908 | 3882 | ||
| 3909 | /* Draw overlining, etc. on the cursor. */ | 3883 | /* Draw overlining, etc. on the cursor. */ |
| 3910 | if (s->w->phys_cursor_type == FILLED_BOX_CURSOR) | 3884 | if (s->w->phys_cursor_type == FILLED_BOX_CURSOR) |
| 3911 | ns_draw_text_decoration (s, face, bgCol, width, x); | 3885 | ns_draw_text_decoration (s, face, bgCol, width, x); |
| 3886 | else | ||
| 3887 | ns_draw_text_decoration (s, face, fgCol, width, x); | ||
| 3888 | } | ||
| 3912 | else | 3889 | else |
| 3913 | ns_draw_text_decoration (s, face, fgCol, width, x); | 3890 | { |
| 3914 | } | 3891 | NSRectFill (r[i]); |
| 3915 | else | 3892 | } |
| 3916 | { | ||
| 3917 | NSRectFill (r[i]); | ||
| 3918 | } | ||
| 3919 | 3893 | ||
| 3920 | /* Draw overlining, etc. on the stretch glyph (or the part | 3894 | /* Draw overlining, etc. on the stretch glyph (or the part |
| 3921 | of the stretch glyph after the cursor). */ | 3895 | of the stretch glyph after the cursor). */ |
| 3922 | ns_draw_text_decoration (s, face, fgCol, r[i].size.width, | 3896 | ns_draw_text_decoration (s, face, fgCol, r[i].size.width, |
| 3923 | r[i].origin.x); | 3897 | r[i].origin.x); |
| 3898 | } | ||
| 3899 | ns_reset_clipping (s->f); | ||
| 3924 | } | 3900 | } |
| 3925 | ns_unfocus (s->f); | ||
| 3926 | s->background_filled_p = 1; | 3901 | s->background_filled_p = 1; |
| 3927 | } | 3902 | } |
| 3928 | } | 3903 | } |
| @@ -4072,9 +4047,11 @@ ns_draw_glyph_string (struct glyph_string *s) | |||
| 4072 | if (next->first_glyph->type != STRETCH_GLYPH) | 4047 | if (next->first_glyph->type != STRETCH_GLYPH) |
| 4073 | { | 4048 | { |
| 4074 | n = ns_get_glyph_string_clip_rect (s->next, r); | 4049 | n = ns_get_glyph_string_clip_rect (s->next, r); |
| 4075 | ns_focus (s->f, r, n); | 4050 | if (ns_clip_to_rect (s->f, r, n)) |
| 4076 | ns_maybe_dumpglyphs_background (s->next, 1); | 4051 | { |
| 4077 | ns_unfocus (s->f); | 4052 | ns_maybe_dumpglyphs_background (s->next, 1); |
| 4053 | ns_reset_clipping (s->f); | ||
| 4054 | } | ||
| 4078 | } | 4055 | } |
| 4079 | else | 4056 | else |
| 4080 | { | 4057 | { |
| @@ -4089,10 +4066,12 @@ ns_draw_glyph_string (struct glyph_string *s) | |||
| 4089 | || s->first_glyph->type == COMPOSITE_GLYPH)) | 4066 | || s->first_glyph->type == COMPOSITE_GLYPH)) |
| 4090 | { | 4067 | { |
| 4091 | n = ns_get_glyph_string_clip_rect (s, r); | 4068 | n = ns_get_glyph_string_clip_rect (s, r); |
| 4092 | ns_focus (s->f, r, n); | 4069 | if (ns_clip_to_rect (s->f, r, n)) |
| 4093 | ns_maybe_dumpglyphs_background (s, 1); | 4070 | { |
| 4094 | ns_dumpglyphs_box_or_relief (s); | 4071 | ns_maybe_dumpglyphs_background (s, 1); |
| 4095 | ns_unfocus (s->f); | 4072 | ns_dumpglyphs_box_or_relief (s); |
| 4073 | ns_reset_clipping (s->f); | ||
| 4074 | } | ||
| 4096 | box_drawn_p = 1; | 4075 | box_drawn_p = 1; |
| 4097 | } | 4076 | } |
| 4098 | 4077 | ||
| @@ -4101,9 +4080,11 @@ ns_draw_glyph_string (struct glyph_string *s) | |||
| 4101 | 4080 | ||
| 4102 | case IMAGE_GLYPH: | 4081 | case IMAGE_GLYPH: |
| 4103 | n = ns_get_glyph_string_clip_rect (s, r); | 4082 | n = ns_get_glyph_string_clip_rect (s, r); |
| 4104 | ns_focus (s->f, r, n); | 4083 | if (ns_clip_to_rect (s->f, r, n)) |
| 4105 | ns_dumpglyphs_image (s, r[0]); | 4084 | { |
| 4106 | ns_unfocus (s->f); | 4085 | ns_dumpglyphs_image (s, r[0]); |
| 4086 | ns_reset_clipping (s->f); | ||
| 4087 | } | ||
| 4107 | break; | 4088 | break; |
| 4108 | 4089 | ||
| 4109 | case STRETCH_GLYPH: | 4090 | case STRETCH_GLYPH: |
| @@ -4113,66 +4094,68 @@ ns_draw_glyph_string (struct glyph_string *s) | |||
| 4113 | case CHAR_GLYPH: | 4094 | case CHAR_GLYPH: |
| 4114 | case COMPOSITE_GLYPH: | 4095 | case COMPOSITE_GLYPH: |
| 4115 | n = ns_get_glyph_string_clip_rect (s, r); | 4096 | n = ns_get_glyph_string_clip_rect (s, r); |
| 4116 | ns_focus (s->f, r, n); | 4097 | if (ns_clip_to_rect (s->f, r, n)) |
| 4098 | { | ||
| 4099 | if (s->for_overlaps || (s->cmp_from > 0 | ||
| 4100 | && ! s->first_glyph->u.cmp.automatic)) | ||
| 4101 | s->background_filled_p = 1; | ||
| 4102 | else | ||
| 4103 | ns_maybe_dumpglyphs_background | ||
| 4104 | (s, s->first_glyph->type == COMPOSITE_GLYPH); | ||
| 4117 | 4105 | ||
| 4118 | if (s->for_overlaps || (s->cmp_from > 0 | 4106 | if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) |
| 4119 | && ! s->first_glyph->u.cmp.automatic)) | 4107 | { |
| 4120 | s->background_filled_p = 1; | 4108 | unsigned long tmp = NS_FACE_BACKGROUND (s->face); |
| 4121 | else | 4109 | NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face); |
| 4122 | ns_maybe_dumpglyphs_background | 4110 | NS_FACE_FOREGROUND (s->face) = tmp; |
| 4123 | (s, s->first_glyph->type == COMPOSITE_GLYPH); | 4111 | } |
| 4124 | 4112 | ||
| 4125 | if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) | 4113 | { |
| 4126 | { | 4114 | BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH; |
| 4127 | unsigned long tmp = NS_FACE_BACKGROUND (s->face); | ||
| 4128 | NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face); | ||
| 4129 | NS_FACE_FOREGROUND (s->face) = tmp; | ||
| 4130 | } | ||
| 4131 | 4115 | ||
| 4132 | { | 4116 | if (isComposite) |
| 4133 | BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH; | 4117 | ns_draw_composite_glyph_string_foreground (s); |
| 4118 | else | ||
| 4119 | ns_draw_glyph_string_foreground (s); | ||
| 4120 | } | ||
| 4134 | 4121 | ||
| 4135 | if (isComposite) | 4122 | { |
| 4136 | ns_draw_composite_glyph_string_foreground (s); | 4123 | NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0 |
| 4137 | else | 4124 | ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face), |
| 4138 | ns_draw_glyph_string_foreground (s); | 4125 | s->f) |
| 4139 | } | 4126 | : FRAME_FOREGROUND_COLOR (s->f)); |
| 4127 | [col set]; | ||
| 4128 | |||
| 4129 | /* Draw underline, overline, strike-through. */ | ||
| 4130 | ns_draw_text_decoration (s, s->face, col, s->width, s->x); | ||
| 4131 | } | ||
| 4140 | 4132 | ||
| 4141 | { | 4133 | if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) |
| 4142 | NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0 | 4134 | { |
| 4143 | ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face), | 4135 | unsigned long tmp = NS_FACE_BACKGROUND (s->face); |
| 4144 | s->f) | 4136 | NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face); |
| 4145 | : FRAME_FOREGROUND_COLOR (s->f)); | 4137 | NS_FACE_FOREGROUND (s->face) = tmp; |
| 4146 | [col set]; | 4138 | } |
| 4147 | |||
| 4148 | /* Draw underline, overline, strike-through. */ | ||
| 4149 | ns_draw_text_decoration (s, s->face, col, s->width, s->x); | ||
| 4150 | } | ||
| 4151 | 4139 | ||
| 4152 | if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) | 4140 | ns_reset_clipping (s->f); |
| 4153 | { | ||
| 4154 | unsigned long tmp = NS_FACE_BACKGROUND (s->face); | ||
| 4155 | NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face); | ||
| 4156 | NS_FACE_FOREGROUND (s->face) = tmp; | ||
| 4157 | } | 4141 | } |
| 4158 | |||
| 4159 | ns_unfocus (s->f); | ||
| 4160 | break; | 4142 | break; |
| 4161 | 4143 | ||
| 4162 | case GLYPHLESS_GLYPH: | 4144 | case GLYPHLESS_GLYPH: |
| 4163 | n = ns_get_glyph_string_clip_rect (s, r); | 4145 | n = ns_get_glyph_string_clip_rect (s, r); |
| 4164 | ns_focus (s->f, r, n); | 4146 | if (ns_clip_to_rect (s->f, r, n)) |
| 4165 | 4147 | { | |
| 4166 | if (s->for_overlaps || (s->cmp_from > 0 | 4148 | if (s->for_overlaps || (s->cmp_from > 0 |
| 4167 | && ! s->first_glyph->u.cmp.automatic)) | 4149 | && ! s->first_glyph->u.cmp.automatic)) |
| 4168 | s->background_filled_p = 1; | 4150 | s->background_filled_p = 1; |
| 4169 | else | 4151 | else |
| 4170 | ns_maybe_dumpglyphs_background | 4152 | ns_maybe_dumpglyphs_background |
| 4171 | (s, s->first_glyph->type == COMPOSITE_GLYPH); | 4153 | (s, s->first_glyph->type == COMPOSITE_GLYPH); |
| 4172 | /* ... */ | 4154 | /* ... */ |
| 4173 | /* Not yet implemented. */ | 4155 | /* Not yet implemented. */ |
| 4174 | /* ... */ | 4156 | /* ... */ |
| 4175 | ns_unfocus (s->f); | 4157 | ns_reset_clipping (s->f); |
| 4158 | } | ||
| 4176 | break; | 4159 | break; |
| 4177 | 4160 | ||
| 4178 | default: | 4161 | default: |
| @@ -4183,9 +4166,11 @@ ns_draw_glyph_string (struct glyph_string *s) | |||
| 4183 | if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX) | 4166 | if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX) |
| 4184 | { | 4167 | { |
| 4185 | n = ns_get_glyph_string_clip_rect (s, r); | 4168 | n = ns_get_glyph_string_clip_rect (s, r); |
| 4186 | ns_focus (s->f, r, n); | 4169 | if (ns_clip_to_rect (s->f, r, n)) |
| 4187 | ns_dumpglyphs_box_or_relief (s); | 4170 | { |
| 4188 | ns_unfocus (s->f); | 4171 | ns_dumpglyphs_box_or_relief (s); |
| 4172 | ns_reset_clipping (s->f); | ||
| 4173 | } | ||
| 4189 | } | 4174 | } |
| 4190 | 4175 | ||
| 4191 | s->num_clips = 0; | 4176 | s->num_clips = 0; |
| @@ -4991,7 +4976,7 @@ static struct redisplay_interface ns_redisplay_interface = | |||
| 4991 | ns_after_update_window_line, | 4976 | ns_after_update_window_line, |
| 4992 | ns_update_window_begin, | 4977 | ns_update_window_begin, |
| 4993 | ns_update_window_end, | 4978 | ns_update_window_end, |
| 4994 | 0, /* flush_display */ | 4979 | ns_flush_display, /* flush_display */ |
| 4995 | x_clear_window_mouse_face, | 4980 | x_clear_window_mouse_face, |
| 4996 | x_get_glyph_overhangs, | 4981 | x_get_glyph_overhangs, |
| 4997 | x_fix_overlapping_area, | 4982 | x_fix_overlapping_area, |