diff options
Diffstat (limited to 'src/macterm.c')
| -rw-r--r-- | src/macterm.c | 145 |
1 files changed, 132 insertions, 13 deletions
diff --git a/src/macterm.c b/src/macterm.c index d3510dbf516..a51304f21da 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -281,6 +281,11 @@ extern void menubar_selection_callback (FRAME_PTR, int); | |||
| 281 | #if USE_CG_DRAWING | 281 | #if USE_CG_DRAWING |
| 282 | #define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context) | 282 | #define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context) |
| 283 | 283 | ||
| 284 | /* Fringe bitmaps. */ | ||
| 285 | |||
| 286 | static int max_fringe_bmp = 0; | ||
| 287 | static CGImageRef *fringe_bmp = 0; | ||
| 288 | |||
| 284 | static CGContextRef | 289 | static CGContextRef |
| 285 | mac_begin_cg_clip (f, gc) | 290 | mac_begin_cg_clip (f, gc) |
| 286 | struct frame *f; | 291 | struct frame *f; |
| @@ -509,6 +514,44 @@ mac_clear_window (f) | |||
| 509 | 514 | ||
| 510 | /* Mac replacement for XCopyArea. */ | 515 | /* Mac replacement for XCopyArea. */ |
| 511 | 516 | ||
| 517 | #if USE_CG_DRAWING | ||
| 518 | static void | ||
| 519 | mac_draw_cg_image (image, f, gc, src_x, src_y, width, height, | ||
| 520 | dest_x, dest_y, overlay_p) | ||
| 521 | CGImageRef image; | ||
| 522 | struct frame *f; | ||
| 523 | GC gc; | ||
| 524 | int src_x, src_y; | ||
| 525 | unsigned int width, height; | ||
| 526 | int dest_x, dest_y, overlay_p; | ||
| 527 | { | ||
| 528 | CGContextRef context; | ||
| 529 | float port_height = FRAME_PIXEL_HEIGHT (f); | ||
| 530 | CGRect dest_rect = CGRectMake (dest_x, dest_y, width, height); | ||
| 531 | |||
| 532 | context = mac_begin_cg_clip (f, gc); | ||
| 533 | if (!overlay_p) | ||
| 534 | { | ||
| 535 | CG_SET_FILL_COLOR (context, gc->xgcv.background); | ||
| 536 | CGContextFillRect (context, dest_rect); | ||
| 537 | } | ||
| 538 | CGContextClipToRect (context, dest_rect); | ||
| 539 | CGContextScaleCTM (context, 1, -1); | ||
| 540 | CGContextTranslateCTM (context, 0, -port_height); | ||
| 541 | if (CGImageIsMask (image)) | ||
| 542 | CG_SET_FILL_COLOR (context, gc->xgcv.foreground); | ||
| 543 | CGContextDrawImage (context, | ||
| 544 | CGRectMake (dest_x - src_x, | ||
| 545 | port_height - (dest_y - src_y | ||
| 546 | + CGImageGetHeight (image)), | ||
| 547 | CGImageGetWidth (image), | ||
| 548 | CGImageGetHeight (image)), | ||
| 549 | image); | ||
| 550 | mac_end_cg_clip (f); | ||
| 551 | } | ||
| 552 | |||
| 553 | #else /* !USE_CG_DRAWING */ | ||
| 554 | |||
| 512 | static void | 555 | static void |
| 513 | mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p) | 556 | mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p) |
| 514 | struct frame *f; | 557 | struct frame *f; |
| @@ -524,9 +567,6 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p) | |||
| 524 | bitmap.baseAddr = (char *)bits; | 567 | bitmap.baseAddr = (char *)bits; |
| 525 | SetRect (&(bitmap.bounds), 0, 0, width, height); | 568 | SetRect (&(bitmap.bounds), 0, 0, width, height); |
| 526 | 569 | ||
| 527 | #if USE_CG_DRAWING | ||
| 528 | mac_prepare_for_quickdraw (f); | ||
| 529 | #endif | ||
| 530 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); | 570 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); |
| 531 | 571 | ||
| 532 | RGBForeColor (GC_FORE_COLOR (gc)); | 572 | RGBForeColor (GC_FORE_COLOR (gc)); |
| @@ -552,6 +592,7 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p) | |||
| 552 | 592 | ||
| 553 | RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); | 593 | RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); |
| 554 | } | 594 | } |
| 595 | #endif /* !USE_CG_DRAWING */ | ||
| 555 | 596 | ||
| 556 | 597 | ||
| 557 | /* Mac replacement for XCreateBitmapFromBitmapData. */ | 598 | /* Mac replacement for XCreateBitmapFromBitmapData. */ |
| @@ -612,7 +653,15 @@ XCreatePixmap (display, w, width, height, depth) | |||
| 612 | SetPortWindowPort (w); | 653 | SetPortWindowPort (w); |
| 613 | 654 | ||
| 614 | SetRect (&r, 0, 0, width, height); | 655 | SetRect (&r, 0, 0, width, height); |
| 615 | err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0); | 656 | #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING |
| 657 | if (depth == 1) | ||
| 658 | #endif | ||
| 659 | err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0); | ||
| 660 | #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING | ||
| 661 | else | ||
| 662 | /* CreateCGImageFromPixMaps requires ARGB format. */ | ||
| 663 | err = QTNewGWorld (&pixmap, k32ARGBPixelFormat, &r, NULL, NULL, 0); | ||
| 664 | #endif | ||
| 616 | if (err != noErr) | 665 | if (err != noErr) |
| 617 | return NULL; | 666 | return NULL; |
| 618 | return pixmap; | 667 | return pixmap; |
| @@ -1295,6 +1344,7 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width) | |||
| 1295 | #endif | 1344 | #endif |
| 1296 | 1345 | ||
| 1297 | 1346 | ||
| 1347 | #if !USE_CG_DRAWING | ||
| 1298 | /* Mac replacement for XCopyArea: dest must be window. */ | 1348 | /* Mac replacement for XCopyArea: dest must be window. */ |
| 1299 | 1349 | ||
| 1300 | static void | 1350 | static void |
| @@ -1308,9 +1358,6 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y) | |||
| 1308 | { | 1358 | { |
| 1309 | Rect src_r, dest_r; | 1359 | Rect src_r, dest_r; |
| 1310 | 1360 | ||
| 1311 | #if USE_CG_DRAWING | ||
| 1312 | mac_prepare_for_quickdraw (f); | ||
| 1313 | #endif | ||
| 1314 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); | 1361 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); |
| 1315 | 1362 | ||
| 1316 | SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); | 1363 | SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); |
| @@ -1355,9 +1402,6 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y, | |||
| 1355 | { | 1402 | { |
| 1356 | Rect src_r, dest_r; | 1403 | Rect src_r, dest_r; |
| 1357 | 1404 | ||
| 1358 | #if USE_CG_DRAWING | ||
| 1359 | mac_prepare_for_quickdraw (f); | ||
| 1360 | #endif | ||
| 1361 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); | 1405 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); |
| 1362 | 1406 | ||
| 1363 | SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); | 1407 | SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); |
| @@ -1390,6 +1434,7 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y, | |||
| 1390 | 1434 | ||
| 1391 | RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); | 1435 | RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); |
| 1392 | } | 1436 | } |
| 1437 | #endif /* !USE_CG_DRAWING */ | ||
| 1393 | 1438 | ||
| 1394 | 1439 | ||
| 1395 | /* Mac replacement for XCopyArea: used only for scrolling. */ | 1440 | /* Mac replacement for XCopyArea: used only for scrolling. */ |
| @@ -2001,9 +2046,12 @@ x_draw_fringe_bitmap (w, row, p) | |||
| 2001 | #endif | 2046 | #endif |
| 2002 | } | 2047 | } |
| 2003 | 2048 | ||
| 2004 | if (p->which) | 2049 | if (p->which |
| 2050 | #if USE_CG_DRAWING | ||
| 2051 | && p->which < max_fringe_bmp | ||
| 2052 | #endif | ||
| 2053 | ) | ||
| 2005 | { | 2054 | { |
| 2006 | unsigned short *bits = p->bits + p->dh; | ||
| 2007 | XGCValues gcv; | 2055 | XGCValues gcv; |
| 2008 | 2056 | ||
| 2009 | XGetGCValues (display, face->gc, GCForeground, &gcv); | 2057 | XGetGCValues (display, face->gc, GCForeground, &gcv); |
| @@ -2012,14 +2060,64 @@ x_draw_fringe_bitmap (w, row, p) | |||
| 2012 | ? (p->overlay_p ? face->background | 2060 | ? (p->overlay_p ? face->background |
| 2013 | : f->output_data.mac->cursor_pixel) | 2061 | : f->output_data.mac->cursor_pixel) |
| 2014 | : face->foreground)); | 2062 | : face->foreground)); |
| 2063 | #if USE_CG_DRAWING | ||
| 2064 | mac_draw_cg_image (fringe_bmp[p->which], f, face->gc, 0, p->dh, | ||
| 2065 | p->wd, p->h, p->x, p->y, p->overlay_p); | ||
| 2066 | #else | ||
| 2015 | mac_draw_bitmap (f, face->gc, p->x, p->y, | 2067 | mac_draw_bitmap (f, face->gc, p->x, p->y, |
| 2016 | p->wd, p->h, bits, p->overlay_p); | 2068 | p->wd, p->h, p->bits + p->dh, p->overlay_p); |
| 2069 | #endif | ||
| 2017 | XSetForeground (display, face->gc, gcv.foreground); | 2070 | XSetForeground (display, face->gc, gcv.foreground); |
| 2018 | } | 2071 | } |
| 2019 | 2072 | ||
| 2020 | mac_reset_clip_rectangles (display, face->gc); | 2073 | mac_reset_clip_rectangles (display, face->gc); |
| 2021 | } | 2074 | } |
| 2022 | 2075 | ||
| 2076 | #if USE_CG_DRAWING | ||
| 2077 | static void | ||
| 2078 | mac_define_fringe_bitmap (which, bits, h, wd) | ||
| 2079 | int which; | ||
| 2080 | unsigned short *bits; | ||
| 2081 | int h, wd; | ||
| 2082 | { | ||
| 2083 | unsigned short *mask_bits; | ||
| 2084 | int i; | ||
| 2085 | CGDataProviderRef provider; | ||
| 2086 | |||
| 2087 | if (which >= max_fringe_bmp) | ||
| 2088 | { | ||
| 2089 | i = max_fringe_bmp; | ||
| 2090 | max_fringe_bmp = which + 20; | ||
| 2091 | fringe_bmp = (CGImageRef *) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (CGImageRef)); | ||
| 2092 | while (i < max_fringe_bmp) | ||
| 2093 | fringe_bmp[i++] = 0; | ||
| 2094 | } | ||
| 2095 | |||
| 2096 | for (i = 0; i < h; i++) | ||
| 2097 | bits[i] = ~bits[i]; | ||
| 2098 | provider = CGDataProviderCreateWithData (NULL, bits, | ||
| 2099 | sizeof (unsigned short) * h, NULL); | ||
| 2100 | if (provider) | ||
| 2101 | { | ||
| 2102 | fringe_bmp[which] = CGImageMaskCreate (wd, h, 1, 1, | ||
| 2103 | sizeof (unsigned short), | ||
| 2104 | provider, NULL, 0); | ||
| 2105 | CGDataProviderRelease (provider); | ||
| 2106 | } | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | static void | ||
| 2110 | mac_destroy_fringe_bitmap (which) | ||
| 2111 | int which; | ||
| 2112 | { | ||
| 2113 | if (which >= max_fringe_bmp) | ||
| 2114 | return; | ||
| 2115 | |||
| 2116 | if (fringe_bmp[which]) | ||
| 2117 | CGImageRelease (fringe_bmp[which]); | ||
| 2118 | fringe_bmp[which] = 0; | ||
| 2119 | } | ||
| 2120 | #endif | ||
| 2023 | 2121 | ||
| 2024 | 2122 | ||
| 2025 | /* This is called when starting Emacs and when restarting after | 2123 | /* This is called when starting Emacs and when restarting after |
| @@ -3191,15 +3289,26 @@ x_draw_image_foreground (s) | |||
| 3191 | { | 3289 | { |
| 3192 | x_set_glyph_string_clipping (s); | 3290 | x_set_glyph_string_clipping (s); |
| 3193 | 3291 | ||
| 3292 | #if USE_CG_DRAWING | ||
| 3293 | mac_draw_cg_image (s->img->data.ptr_val, | ||
| 3294 | s->f, s->gc, s->slice.x, s->slice.y, | ||
| 3295 | s->slice.width, s->slice.height, x, y, 1); | ||
| 3296 | #endif | ||
| 3194 | if (s->img->mask) | 3297 | if (s->img->mask) |
| 3298 | #if !USE_CG_DRAWING | ||
| 3195 | mac_copy_area_with_mask (s->img->pixmap, s->img->mask, | 3299 | mac_copy_area_with_mask (s->img->pixmap, s->img->mask, |
| 3196 | s->f, s->gc, s->slice.x, s->slice.y, | 3300 | s->f, s->gc, s->slice.x, s->slice.y, |
| 3197 | s->slice.width, s->slice.height, x, y); | 3301 | s->slice.width, s->slice.height, x, y); |
| 3302 | #else | ||
| 3303 | ; | ||
| 3304 | #endif | ||
| 3198 | else | 3305 | else |
| 3199 | { | 3306 | { |
| 3307 | #if !USE_CG_DRAWING | ||
| 3200 | mac_copy_area (s->img->pixmap, | 3308 | mac_copy_area (s->img->pixmap, |
| 3201 | s->f, s->gc, s->slice.x, s->slice.y, | 3309 | s->f, s->gc, s->slice.x, s->slice.y, |
| 3202 | s->slice.width, s->slice.height, x, y); | 3310 | s->slice.width, s->slice.height, x, y); |
| 3311 | #endif | ||
| 3203 | 3312 | ||
| 3204 | /* When the image has a mask, we can expect that at | 3313 | /* When the image has a mask, we can expect that at |
| 3205 | least part of a mouse highlight or a block cursor will | 3314 | least part of a mouse highlight or a block cursor will |
| @@ -10892,8 +11001,13 @@ static struct redisplay_interface x_redisplay_interface = | |||
| 10892 | x_get_glyph_overhangs, | 11001 | x_get_glyph_overhangs, |
| 10893 | x_fix_overlapping_area, | 11002 | x_fix_overlapping_area, |
| 10894 | x_draw_fringe_bitmap, | 11003 | x_draw_fringe_bitmap, |
| 11004 | #if USE_CG_DRAWING | ||
| 11005 | mac_define_fringe_bitmap, | ||
| 11006 | mac_destroy_fringe_bitmap, | ||
| 11007 | #else | ||
| 10895 | 0, /* define_fringe_bitmap */ | 11008 | 0, /* define_fringe_bitmap */ |
| 10896 | 0, /* destroy_fringe_bitmap */ | 11009 | 0, /* destroy_fringe_bitmap */ |
| 11010 | #endif | ||
| 10897 | mac_per_char_metric, | 11011 | mac_per_char_metric, |
| 10898 | mac_encode_char, | 11012 | mac_encode_char, |
| 10899 | mac_compute_glyph_string_overhangs, | 11013 | mac_compute_glyph_string_overhangs, |
| @@ -10970,6 +11084,11 @@ mac_initialize () | |||
| 10970 | MakeMeTheFrontProcess (); | 11084 | MakeMeTheFrontProcess (); |
| 10971 | #endif | 11085 | #endif |
| 10972 | #endif | 11086 | #endif |
| 11087 | |||
| 11088 | #if USE_CG_DRAWING | ||
| 11089 | mac_init_fringe (); | ||
| 11090 | #endif | ||
| 11091 | |||
| 10973 | UNBLOCK_INPUT; | 11092 | UNBLOCK_INPUT; |
| 10974 | } | 11093 | } |
| 10975 | 11094 | ||