diff options
Diffstat (limited to 'src/macterm.c')
| -rw-r--r-- | src/macterm.c | 889 |
1 files changed, 446 insertions, 443 deletions
diff --git a/src/macterm.c b/src/macterm.c index c9d91607573..83561639cbf 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -270,8 +270,38 @@ extern void menubar_selection_callback (FRAME_PTR, int); | |||
| 270 | #define GC_FORE_COLOR(gc) (&(gc)->fore_color) | 270 | #define GC_FORE_COLOR(gc) (&(gc)->fore_color) |
| 271 | #define GC_BACK_COLOR(gc) (&(gc)->back_color) | 271 | #define GC_BACK_COLOR(gc) (&(gc)->back_color) |
| 272 | #define GC_FONT(gc) ((gc)->xgcv.font) | 272 | #define GC_FONT(gc) ((gc)->xgcv.font) |
| 273 | #define GC_CLIP_REGION(gc) ((gc)->clip_region) | ||
| 273 | #define MAC_WINDOW_NORMAL_GC(w) (((mac_output *) GetWRefCon (w))->normal_gc) | 274 | #define MAC_WINDOW_NORMAL_GC(w) (((mac_output *) GetWRefCon (w))->normal_gc) |
| 274 | 275 | ||
| 276 | static RgnHandle saved_port_clip_region = NULL; | ||
| 277 | |||
| 278 | static void | ||
| 279 | mac_begin_clip (region) | ||
| 280 | RgnHandle region; | ||
| 281 | { | ||
| 282 | static RgnHandle new_region = NULL; | ||
| 283 | |||
| 284 | if (saved_port_clip_region == NULL) | ||
| 285 | saved_port_clip_region = NewRgn (); | ||
| 286 | if (new_region == NULL) | ||
| 287 | new_region = NewRgn (); | ||
| 288 | |||
| 289 | if (region) | ||
| 290 | { | ||
| 291 | GetClip (saved_port_clip_region); | ||
| 292 | SectRgn (saved_port_clip_region, region, new_region); | ||
| 293 | SetClip (new_region); | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | static void | ||
| 298 | mac_end_clip (region) | ||
| 299 | RgnHandle region; | ||
| 300 | { | ||
| 301 | if (region) | ||
| 302 | SetClip (saved_port_clip_region); | ||
| 303 | } | ||
| 304 | |||
| 275 | 305 | ||
| 276 | /* X display function emulation */ | 306 | /* X display function emulation */ |
| 277 | 307 | ||
| @@ -297,8 +327,10 @@ XDrawLine (display, w, gc, x1, y1, x2, y2) | |||
| 297 | 327 | ||
| 298 | RGBForeColor (GC_FORE_COLOR (gc)); | 328 | RGBForeColor (GC_FORE_COLOR (gc)); |
| 299 | 329 | ||
| 330 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 300 | MoveTo (x1, y1); | 331 | MoveTo (x1, y1); |
| 301 | LineTo (x2, y2); | 332 | LineTo (x2, y2); |
| 333 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 302 | } | 334 | } |
| 303 | 335 | ||
| 304 | void | 336 | void |
| @@ -339,7 +371,9 @@ mac_erase_rectangle (w, gc, x, y, width, height) | |||
| 339 | RGBBackColor (GC_BACK_COLOR (gc)); | 371 | RGBBackColor (GC_BACK_COLOR (gc)); |
| 340 | SetRect (&r, x, y, x + width, y + height); | 372 | SetRect (&r, x, y, x + width, y + height); |
| 341 | 373 | ||
| 374 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 342 | EraseRect (&r); | 375 | EraseRect (&r); |
| 376 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 343 | 377 | ||
| 344 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); | 378 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); |
| 345 | } | 379 | } |
| @@ -406,6 +440,7 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p) | |||
| 406 | RGBBackColor (GC_BACK_COLOR (gc)); | 440 | RGBBackColor (GC_BACK_COLOR (gc)); |
| 407 | SetRect (&r, x, y, x + width, y + height); | 441 | SetRect (&r, x, y, x + width, y + height); |
| 408 | 442 | ||
| 443 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 409 | #if TARGET_API_MAC_CARBON | 444 | #if TARGET_API_MAC_CARBON |
| 410 | LockPortBits (GetWindowPort (w)); | 445 | LockPortBits (GetWindowPort (w)); |
| 411 | CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)), | 446 | CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)), |
| @@ -415,41 +450,12 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p) | |||
| 415 | CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r, | 450 | CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r, |
| 416 | overlay_p ? srcOr : srcCopy, 0); | 451 | overlay_p ? srcOr : srcCopy, 0); |
| 417 | #endif /* not TARGET_API_MAC_CARBON */ | 452 | #endif /* not TARGET_API_MAC_CARBON */ |
| 453 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 418 | 454 | ||
| 419 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); | 455 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); |
| 420 | } | 456 | } |
| 421 | 457 | ||
| 422 | 458 | ||
| 423 | /* Mac replacement for XSetClipRectangles. */ | ||
| 424 | |||
| 425 | static void | ||
| 426 | mac_set_clip_rectangle (display, w, r) | ||
| 427 | Display *display; | ||
| 428 | WindowPtr w; | ||
| 429 | Rect *r; | ||
| 430 | { | ||
| 431 | SetPortWindowPort (w); | ||
| 432 | |||
| 433 | ClipRect (r); | ||
| 434 | } | ||
| 435 | |||
| 436 | |||
| 437 | /* Mac replacement for XSetClipMask. */ | ||
| 438 | |||
| 439 | static void | ||
| 440 | mac_reset_clipping (display, w) | ||
| 441 | Display *display; | ||
| 442 | WindowPtr w; | ||
| 443 | { | ||
| 444 | Rect r; | ||
| 445 | |||
| 446 | SetPortWindowPort (w); | ||
| 447 | |||
| 448 | SetRect (&r, -32767, -32767, 32767, 32767); | ||
| 449 | ClipRect (&r); | ||
| 450 | } | ||
| 451 | |||
| 452 | |||
| 453 | /* Mac replacement for XCreateBitmapFromBitmapData. */ | 459 | /* Mac replacement for XCreateBitmapFromBitmapData. */ |
| 454 | 460 | ||
| 455 | static void | 461 | static void |
| @@ -577,7 +583,9 @@ XFillRectangle (display, w, gc, x, y, width, height) | |||
| 577 | RGBForeColor (GC_FORE_COLOR (gc)); | 583 | RGBForeColor (GC_FORE_COLOR (gc)); |
| 578 | SetRect (&r, x, y, x + width, y + height); | 584 | SetRect (&r, x, y, x + width, y + height); |
| 579 | 585 | ||
| 586 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 580 | PaintRect (&r); /* using foreground color of gc */ | 587 | PaintRect (&r); /* using foreground color of gc */ |
| 588 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 581 | } | 589 | } |
| 582 | 590 | ||
| 583 | 591 | ||
| @@ -625,7 +633,9 @@ mac_draw_rectangle (display, w, gc, x, y, width, height) | |||
| 625 | RGBForeColor (GC_FORE_COLOR (gc)); | 633 | RGBForeColor (GC_FORE_COLOR (gc)); |
| 626 | SetRect (&r, x, y, x + width + 1, y + height + 1); | 634 | SetRect (&r, x, y, x + width + 1, y + height + 1); |
| 627 | 635 | ||
| 636 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 628 | FrameRect (&r); /* using foreground color of gc */ | 637 | FrameRect (&r); /* using foreground color of gc */ |
| 638 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 629 | } | 639 | } |
| 630 | 640 | ||
| 631 | 641 | ||
| @@ -678,7 +688,7 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout) | |||
| 678 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 | 688 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 |
| 679 | kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics | 689 | kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics |
| 680 | #else | 690 | #else |
| 681 | kATSLineIsDisplayOnly | 691 | kATSLineIsDisplayOnly | kATSLineFractDisable |
| 682 | #endif | 692 | #endif |
| 683 | ; | 693 | ; |
| 684 | ATSUAttributeValuePtr values[] = {&line_layout}; | 694 | ATSUAttributeValuePtr values[] = {&line_layout}; |
| @@ -782,10 +792,12 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | |||
| 782 | if (NILP (Vmac_use_core_graphics)) | 792 | if (NILP (Vmac_use_core_graphics)) |
| 783 | { | 793 | { |
| 784 | #endif | 794 | #endif |
| 795 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 785 | MoveTo (x, y); | 796 | MoveTo (x, y); |
| 786 | ATSUDrawText (text_layout, | 797 | ATSUDrawText (text_layout, |
| 787 | kATSUFromTextBeginning, kATSUToTextEnd, | 798 | kATSUFromTextBeginning, kATSUToTextEnd, |
| 788 | kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); | 799 | kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); |
| 800 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 789 | #ifdef MAC_OSX | 801 | #ifdef MAC_OSX |
| 790 | } | 802 | } |
| 791 | else | 803 | else |
| @@ -793,7 +805,6 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | |||
| 793 | CGrafPtr port; | 805 | CGrafPtr port; |
| 794 | CGContextRef context; | 806 | CGContextRef context; |
| 795 | Rect rect; | 807 | Rect rect; |
| 796 | RgnHandle region = NewRgn (); | ||
| 797 | float port_height; | 808 | float port_height; |
| 798 | ATSUAttributeTag tags[] = {kATSUCGContextTag}; | 809 | ATSUAttributeTag tags[] = {kATSUCGContextTag}; |
| 799 | ByteCount sizes[] = {sizeof (CGContextRef)}; | 810 | ByteCount sizes[] = {sizeof (CGContextRef)}; |
| @@ -803,16 +814,15 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | |||
| 803 | QDBeginCGContext (port, &context); | 814 | QDBeginCGContext (port, &context); |
| 804 | GetPortBounds (port, &rect); | 815 | GetPortBounds (port, &rect); |
| 805 | port_height = rect.bottom - rect.top; | 816 | port_height = rect.bottom - rect.top; |
| 806 | GetClip (region); | 817 | if (gc->n_clip_rects) |
| 807 | GetRegionBounds (region, &rect); | 818 | { |
| 808 | /* XXX: This is not correct if the clip region is not a | 819 | CGContextTranslateCTM (context, 0, port_height); |
| 809 | simple rectangle. */ | 820 | CGContextScaleCTM (context, 1, -1); |
| 810 | CGContextClipToRect (context, | 821 | CGContextClipToRects (context, gc->clip_rects, |
| 811 | CGRectMake (rect.left, | 822 | gc->n_clip_rects); |
| 812 | port_height - rect.bottom, | 823 | CGContextScaleCTM (context, 1, -1); |
| 813 | rect.right - rect.left, | 824 | CGContextTranslateCTM (context, 0, -port_height); |
| 814 | rect.bottom - rect.top)); | 825 | } |
| 815 | DisposeRgn (region); | ||
| 816 | CGContextSetRGBFillColor | 826 | CGContextSetRGBFillColor |
| 817 | (context, | 827 | (context, |
| 818 | RED_FROM_ULONG (gc->xgcv.foreground) / 255.0, | 828 | RED_FROM_ULONG (gc->xgcv.foreground) / 255.0, |
| @@ -843,8 +853,10 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | |||
| 843 | TextFace (GC_FONT (gc)->mac_fontface); | 853 | TextFace (GC_FONT (gc)->mac_fontface); |
| 844 | TextMode (mode); | 854 | TextMode (mode); |
| 845 | 855 | ||
| 856 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 846 | MoveTo (x, y); | 857 | MoveTo (x, y); |
| 847 | DrawText (buf, 0, nchars * bytes_per_char); | 858 | DrawText (buf, 0, nchars * bytes_per_char); |
| 859 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 848 | #if USE_ATSUI | 860 | #if USE_ATSUI |
| 849 | } | 861 | } |
| 850 | #endif | 862 | #endif |
| @@ -943,6 +955,7 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x, | |||
| 943 | ForeColor (blackColor); | 955 | ForeColor (blackColor); |
| 944 | BackColor (whiteColor); | 956 | BackColor (whiteColor); |
| 945 | 957 | ||
| 958 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 946 | LockPixels (GetGWorldPixMap (src)); | 959 | LockPixels (GetGWorldPixMap (src)); |
| 947 | #if TARGET_API_MAC_CARBON | 960 | #if TARGET_API_MAC_CARBON |
| 948 | LockPortBits (GetWindowPort (dest)); | 961 | LockPortBits (GetWindowPort (dest)); |
| @@ -955,6 +968,7 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x, | |||
| 955 | &src_r, &dest_r, srcCopy, 0); | 968 | &src_r, &dest_r, srcCopy, 0); |
| 956 | #endif /* not TARGET_API_MAC_CARBON */ | 969 | #endif /* not TARGET_API_MAC_CARBON */ |
| 957 | UnlockPixels (GetGWorldPixMap (src)); | 970 | UnlockPixels (GetGWorldPixMap (src)); |
| 971 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 958 | 972 | ||
| 959 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); | 973 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); |
| 960 | } | 974 | } |
| @@ -981,6 +995,7 @@ mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y, | |||
| 981 | ForeColor (blackColor); | 995 | ForeColor (blackColor); |
| 982 | BackColor (whiteColor); | 996 | BackColor (whiteColor); |
| 983 | 997 | ||
| 998 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 984 | LockPixels (GetGWorldPixMap (src)); | 999 | LockPixels (GetGWorldPixMap (src)); |
| 985 | LockPixels (GetGWorldPixMap (mask)); | 1000 | LockPixels (GetGWorldPixMap (mask)); |
| 986 | #if TARGET_API_MAC_CARBON | 1001 | #if TARGET_API_MAC_CARBON |
| @@ -995,6 +1010,7 @@ mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y, | |||
| 995 | #endif /* not TARGET_API_MAC_CARBON */ | 1010 | #endif /* not TARGET_API_MAC_CARBON */ |
| 996 | UnlockPixels (GetGWorldPixMap (mask)); | 1011 | UnlockPixels (GetGWorldPixMap (mask)); |
| 997 | UnlockPixels (GetGWorldPixMap (src)); | 1012 | UnlockPixels (GetGWorldPixMap (src)); |
| 1013 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 998 | 1014 | ||
| 999 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); | 1015 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); |
| 1000 | } | 1016 | } |
| @@ -1031,7 +1047,9 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y) | |||
| 1031 | color mapping in CopyBits. Otherwise, it will be slow. */ | 1047 | color mapping in CopyBits. Otherwise, it will be slow. */ |
| 1032 | ForeColor (blackColor); | 1048 | ForeColor (blackColor); |
| 1033 | BackColor (whiteColor); | 1049 | BackColor (whiteColor); |
| 1050 | mac_begin_clip (GC_CLIP_REGION (gc)); | ||
| 1034 | CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0); | 1051 | CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0); |
| 1052 | mac_end_clip (GC_CLIP_REGION (gc)); | ||
| 1035 | 1053 | ||
| 1036 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); | 1054 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); |
| 1037 | #endif /* not TARGET_API_MAC_CARBON */ | 1055 | #endif /* not TARGET_API_MAC_CARBON */ |
| @@ -1166,6 +1184,8 @@ XFreeGC (display, gc) | |||
| 1166 | Display *display; | 1184 | Display *display; |
| 1167 | GC gc; | 1185 | GC gc; |
| 1168 | { | 1186 | { |
| 1187 | if (gc->clip_region) | ||
| 1188 | DisposeRgn (gc->clip_region); | ||
| 1169 | xfree (gc); | 1189 | xfree (gc); |
| 1170 | } | 1190 | } |
| 1171 | 1191 | ||
| @@ -1236,6 +1256,70 @@ XSetFont (display, gc, font) | |||
| 1236 | } | 1256 | } |
| 1237 | 1257 | ||
| 1238 | 1258 | ||
| 1259 | /* Mac replacement for XSetClipRectangles. */ | ||
| 1260 | |||
| 1261 | static void | ||
| 1262 | mac_set_clip_rectangles (display, gc, rectangles, n) | ||
| 1263 | Display *display; | ||
| 1264 | GC gc; | ||
| 1265 | Rect *rectangles; | ||
| 1266 | int n; | ||
| 1267 | { | ||
| 1268 | int i; | ||
| 1269 | |||
| 1270 | if (n < 0 || n > MAX_CLIP_RECTS) | ||
| 1271 | abort (); | ||
| 1272 | if (n == 0) | ||
| 1273 | { | ||
| 1274 | if (gc->clip_region) | ||
| 1275 | { | ||
| 1276 | DisposeRgn (gc->clip_region); | ||
| 1277 | gc->clip_region = NULL; | ||
| 1278 | } | ||
| 1279 | } | ||
| 1280 | else | ||
| 1281 | { | ||
| 1282 | if (gc->clip_region == NULL) | ||
| 1283 | gc->clip_region = NewRgn (); | ||
| 1284 | RectRgn (gc->clip_region, rectangles); | ||
| 1285 | if (n > 1) | ||
| 1286 | { | ||
| 1287 | RgnHandle region = NewRgn (); | ||
| 1288 | |||
| 1289 | for (i = 1; i < n; i++) | ||
| 1290 | { | ||
| 1291 | RectRgn (region, rectangles + i); | ||
| 1292 | UnionRgn (gc->clip_region, region, gc->clip_region); | ||
| 1293 | } | ||
| 1294 | DisposeRgn (region); | ||
| 1295 | } | ||
| 1296 | } | ||
| 1297 | #if defined (MAC_OSX) && USE_ATSUI | ||
| 1298 | gc->n_clip_rects = n; | ||
| 1299 | |||
| 1300 | for (i = 0; i < n; i++) | ||
| 1301 | { | ||
| 1302 | Rect *rect = rectangles + i; | ||
| 1303 | |||
| 1304 | gc->clip_rects[i] = CGRectMake (rect->left, rect->top, | ||
| 1305 | rect->right - rect->left, | ||
| 1306 | rect->bottom - rect->top); | ||
| 1307 | } | ||
| 1308 | #endif | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | |||
| 1312 | /* Mac replacement for XSetClipMask. */ | ||
| 1313 | |||
| 1314 | static INLINE void | ||
| 1315 | mac_reset_clip_rectangles (display, gc) | ||
| 1316 | Display *display; | ||
| 1317 | GC gc; | ||
| 1318 | { | ||
| 1319 | mac_set_clip_rectangles (display, gc, NULL, 0); | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | |||
| 1239 | /* Mac replacement for XSetWindowBackground. */ | 1323 | /* Mac replacement for XSetWindowBackground. */ |
| 1240 | 1324 | ||
| 1241 | void | 1325 | void |
| @@ -1647,7 +1731,7 @@ x_draw_fringe_bitmap (w, row, p) | |||
| 1647 | XSetForeground (display, face->gc, gcv.foreground); | 1731 | XSetForeground (display, face->gc, gcv.foreground); |
| 1648 | } | 1732 | } |
| 1649 | 1733 | ||
| 1650 | mac_reset_clipping (display, window); | 1734 | mac_reset_clip_rectangles (display, gc); |
| 1651 | } | 1735 | } |
| 1652 | 1736 | ||
| 1653 | 1737 | ||
| @@ -1682,19 +1766,6 @@ static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); | |||
| 1682 | static int mac_encode_char P_ ((int, XChar2b *, struct font_info *, int *)); | 1766 | static int mac_encode_char P_ ((int, XChar2b *, struct font_info *, int *)); |
| 1683 | 1767 | ||
| 1684 | 1768 | ||
| 1685 | /* Return a pointer to per-char metric information in FONT of a | ||
| 1686 | character pointed by B which is a pointer to an XChar2b. */ | ||
| 1687 | |||
| 1688 | #define PER_CHAR_METRIC(font, b) \ | ||
| 1689 | ((font)->per_char \ | ||
| 1690 | ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \ | ||
| 1691 | + (((font)->min_byte1 || (font)->max_byte1) \ | ||
| 1692 | ? (((b)->byte1 - (font)->min_byte1) \ | ||
| 1693 | * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \ | ||
| 1694 | : 0)) \ | ||
| 1695 | : &((font)->max_bounds)) | ||
| 1696 | |||
| 1697 | |||
| 1698 | /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B | 1769 | /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B |
| 1699 | is not contained in the font. */ | 1770 | is not contained in the font. */ |
| 1700 | 1771 | ||
| @@ -2122,9 +2193,11 @@ static INLINE void | |||
| 2122 | x_set_glyph_string_clipping (s) | 2193 | x_set_glyph_string_clipping (s) |
| 2123 | struct glyph_string *s; | 2194 | struct glyph_string *s; |
| 2124 | { | 2195 | { |
| 2125 | Rect r; | 2196 | Rect rects[MAX_CLIP_RECTS]; |
| 2126 | get_glyph_string_clip_rect (s, &r); | 2197 | int n; |
| 2127 | mac_set_clip_rectangle (s->display, s->window, &r); | 2198 | |
| 2199 | n = get_glyph_string_clip_rects (s, rects, MAX_CLIP_RECTS); | ||
| 2200 | mac_set_clip_rectangles (s->display, s->gc, rects, n); | ||
| 2128 | } | 2201 | } |
| 2129 | 2202 | ||
| 2130 | 2203 | ||
| @@ -2320,7 +2393,7 @@ x_draw_glyph_string_foreground (s) | |||
| 2320 | XDrawImageString is usually faster than XDrawString.) Always | 2393 | XDrawImageString is usually faster than XDrawString.) Always |
| 2321 | use XDrawImageString when drawing the cursor so that there is | 2394 | use XDrawImageString when drawing the cursor so that there is |
| 2322 | no chance that characters under a box cursor are invisible. */ | 2395 | no chance that characters under a box cursor are invisible. */ |
| 2323 | if (s->for_overlaps_p | 2396 | if (s->for_overlaps |
| 2324 | || (s->background_filled_p && s->hl != DRAW_CURSOR)) | 2397 | || (s->background_filled_p && s->hl != DRAW_CURSOR)) |
| 2325 | #endif | 2398 | #endif |
| 2326 | { | 2399 | { |
| @@ -2341,7 +2414,7 @@ x_draw_glyph_string_foreground (s) | |||
| 2341 | { | 2414 | { |
| 2342 | if (s->two_byte_p) | 2415 | if (s->two_byte_p) |
| 2343 | XDrawImageString16 (s->display, s->window, s->gc, x, | 2416 | XDrawImageString16 (s->display, s->window, s->gc, x, |
| 2344 | s->ybase - boff, s->char2b, s->nchars); | 2417 | s->ybase - boff, s->char2b, s->nchars); |
| 2345 | else | 2418 | else |
| 2346 | XDrawImageString (s->display, s->window, s->gc, x, | 2419 | XDrawImageString (s->display, s->window, s->gc, x, |
| 2347 | s->ybase - boff, char1b, s->nchars); | 2420 | s->ybase - boff, char1b, s->nchars); |
| @@ -2749,7 +2822,7 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, | |||
| 2749 | gc = f->output_data.mac->white_relief.gc; | 2822 | gc = f->output_data.mac->white_relief.gc; |
| 2750 | else | 2823 | else |
| 2751 | gc = f->output_data.mac->black_relief.gc; | 2824 | gc = f->output_data.mac->black_relief.gc; |
| 2752 | mac_set_clip_rectangle (dpy, window, clip_rect); | 2825 | mac_set_clip_rectangles (dpy, gc, clip_rect, 1); |
| 2753 | 2826 | ||
| 2754 | /* Top. */ | 2827 | /* Top. */ |
| 2755 | if (top_p) | 2828 | if (top_p) |
| @@ -2764,13 +2837,12 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, | |||
| 2764 | XDrawLine (dpy, window, gc, | 2837 | XDrawLine (dpy, window, gc, |
| 2765 | left_x + i, top_y + i, left_x + i, bottom_y - i); | 2838 | left_x + i, top_y + i, left_x + i, bottom_y - i); |
| 2766 | 2839 | ||
| 2767 | mac_reset_clipping (dpy, window); | 2840 | mac_reset_clip_rectangles (dpy, gc); |
| 2768 | if (raised_p) | 2841 | if (raised_p) |
| 2769 | gc = f->output_data.mac->black_relief.gc; | 2842 | gc = f->output_data.mac->black_relief.gc; |
| 2770 | else | 2843 | else |
| 2771 | gc = f->output_data.mac->white_relief.gc; | 2844 | gc = f->output_data.mac->white_relief.gc; |
| 2772 | mac_set_clip_rectangle (dpy, window, | 2845 | mac_set_clip_rectangles (dpy, gc, clip_rect, 1); |
| 2773 | clip_rect); | ||
| 2774 | 2846 | ||
| 2775 | /* Bottom. */ | 2847 | /* Bottom. */ |
| 2776 | if (bot_p) | 2848 | if (bot_p) |
| @@ -2785,7 +2857,7 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, | |||
| 2785 | XDrawLine (dpy, window, gc, | 2857 | XDrawLine (dpy, window, gc, |
| 2786 | right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1); | 2858 | right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1); |
| 2787 | 2859 | ||
| 2788 | mac_reset_clipping (dpy, window); | 2860 | mac_reset_clip_rectangles (dpy, gc); |
| 2789 | } | 2861 | } |
| 2790 | 2862 | ||
| 2791 | 2863 | ||
| @@ -2807,7 +2879,7 @@ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, | |||
| 2807 | 2879 | ||
| 2808 | XGetGCValues (s->display, s->gc, GCForeground, &xgcv); | 2880 | XGetGCValues (s->display, s->gc, GCForeground, &xgcv); |
| 2809 | XSetForeground (s->display, s->gc, s->face->box_color); | 2881 | XSetForeground (s->display, s->gc, s->face->box_color); |
| 2810 | mac_set_clip_rectangle (s->display, s->window, clip_rect); | 2882 | mac_set_clip_rectangles (s->display, s->gc, clip_rect, 1); |
| 2811 | 2883 | ||
| 2812 | /* Top. */ | 2884 | /* Top. */ |
| 2813 | XFillRectangle (s->display, s->window, s->gc, | 2885 | XFillRectangle (s->display, s->window, s->gc, |
| @@ -2828,7 +2900,7 @@ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, | |||
| 2828 | right_x - width + 1, top_y, width, bottom_y - top_y + 1); | 2900 | right_x - width + 1, top_y, width, bottom_y - top_y + 1); |
| 2829 | 2901 | ||
| 2830 | XSetForeground (s->display, s->gc, xgcv.foreground); | 2902 | XSetForeground (s->display, s->gc, xgcv.foreground); |
| 2831 | mac_reset_clipping (s->display, s->window); | 2903 | mac_reset_clip_rectangles (s->display, s->gc); |
| 2832 | } | 2904 | } |
| 2833 | 2905 | ||
| 2834 | 2906 | ||
| @@ -3182,7 +3254,6 @@ x_draw_image_glyph_string (s) | |||
| 3182 | x_set_glyph_string_clipping (s); | 3254 | x_set_glyph_string_clipping (s); |
| 3183 | mac_copy_area (s->display, pixmap, s->window, s->gc, | 3255 | mac_copy_area (s->display, pixmap, s->window, s->gc, |
| 3184 | 0, 0, s->background_width, s->height, s->x, s->y); | 3256 | 0, 0, s->background_width, s->height, s->x, s->y); |
| 3185 | mac_reset_clipping (s->display, s->window); | ||
| 3186 | XFreePixmap (s->display, pixmap); | 3257 | XFreePixmap (s->display, pixmap); |
| 3187 | } | 3258 | } |
| 3188 | else | 3259 | else |
| @@ -3234,7 +3305,7 @@ x_draw_stretch_glyph_string (s) | |||
| 3234 | gc = s->face->gc; | 3305 | gc = s->face->gc; |
| 3235 | 3306 | ||
| 3236 | get_glyph_string_clip_rect (s, &r); | 3307 | get_glyph_string_clip_rect (s, &r); |
| 3237 | mac_set_clip_rectangle (s->display, s->window, &r); | 3308 | mac_set_clip_rectangles (s->display, gc, &r, 1); |
| 3238 | 3309 | ||
| 3239 | #if 0 /* MAC_TODO: stipple */ | 3310 | #if 0 /* MAC_TODO: stipple */ |
| 3240 | if (s->face->stipple) | 3311 | if (s->face->stipple) |
| @@ -3247,8 +3318,6 @@ x_draw_stretch_glyph_string (s) | |||
| 3247 | else | 3318 | else |
| 3248 | #endif /* MAC_TODO */ | 3319 | #endif /* MAC_TODO */ |
| 3249 | mac_erase_rectangle (s->window, gc, x, y, w, h); | 3320 | mac_erase_rectangle (s->window, gc, x, y, w, h); |
| 3250 | |||
| 3251 | mac_reset_clipping (s->display, s->window); | ||
| 3252 | } | 3321 | } |
| 3253 | } | 3322 | } |
| 3254 | else if (!s->background_filled_p) | 3323 | else if (!s->background_filled_p) |
| @@ -3271,7 +3340,7 @@ x_draw_glyph_string (s) | |||
| 3271 | draw a cursor, draw the background of the successor first so that | 3340 | draw a cursor, draw the background of the successor first so that |
| 3272 | S can draw into it. This makes S->next use XDrawString instead | 3341 | S can draw into it. This makes S->next use XDrawString instead |
| 3273 | of XDrawImageString. */ | 3342 | of XDrawImageString. */ |
| 3274 | if (s->next && s->right_overhang && !s->for_overlaps_p | 3343 | if (s->next && s->right_overhang && !s->for_overlaps |
| 3275 | && s->next->hl != DRAW_CURSOR) | 3344 | && s->next->hl != DRAW_CURSOR) |
| 3276 | { | 3345 | { |
| 3277 | xassert (s->next->img == NULL); | 3346 | xassert (s->next->img == NULL); |
| @@ -3285,7 +3354,7 @@ x_draw_glyph_string (s) | |||
| 3285 | 3354 | ||
| 3286 | /* Draw relief (if any) in advance for char/composition so that the | 3355 | /* Draw relief (if any) in advance for char/composition so that the |
| 3287 | glyph string can be drawn over it. */ | 3356 | glyph string can be drawn over it. */ |
| 3288 | if (!s->for_overlaps_p | 3357 | if (!s->for_overlaps |
| 3289 | && s->face->box != FACE_NO_BOX | 3358 | && s->face->box != FACE_NO_BOX |
| 3290 | && (s->first_glyph->type == CHAR_GLYPH | 3359 | && (s->first_glyph->type == CHAR_GLYPH |
| 3291 | || s->first_glyph->type == COMPOSITE_GLYPH)) | 3360 | || s->first_glyph->type == COMPOSITE_GLYPH)) |
| @@ -3311,7 +3380,7 @@ x_draw_glyph_string (s) | |||
| 3311 | break; | 3380 | break; |
| 3312 | 3381 | ||
| 3313 | case CHAR_GLYPH: | 3382 | case CHAR_GLYPH: |
| 3314 | if (s->for_overlaps_p) | 3383 | if (s->for_overlaps) |
| 3315 | s->background_filled_p = 1; | 3384 | s->background_filled_p = 1; |
| 3316 | else | 3385 | else |
| 3317 | x_draw_glyph_string_background (s, 0); | 3386 | x_draw_glyph_string_background (s, 0); |
| @@ -3319,7 +3388,7 @@ x_draw_glyph_string (s) | |||
| 3319 | break; | 3388 | break; |
| 3320 | 3389 | ||
| 3321 | case COMPOSITE_GLYPH: | 3390 | case COMPOSITE_GLYPH: |
| 3322 | if (s->for_overlaps_p || s->gidx > 0) | 3391 | if (s->for_overlaps || s->gidx > 0) |
| 3323 | s->background_filled_p = 1; | 3392 | s->background_filled_p = 1; |
| 3324 | else | 3393 | else |
| 3325 | x_draw_glyph_string_background (s, 1); | 3394 | x_draw_glyph_string_background (s, 1); |
| @@ -3330,7 +3399,7 @@ x_draw_glyph_string (s) | |||
| 3330 | abort (); | 3399 | abort (); |
| 3331 | } | 3400 | } |
| 3332 | 3401 | ||
| 3333 | if (!s->for_overlaps_p) | 3402 | if (!s->for_overlaps) |
| 3334 | { | 3403 | { |
| 3335 | /* Draw underline. */ | 3404 | /* Draw underline. */ |
| 3336 | if (s->face->underline_p) | 3405 | if (s->face->underline_p) |
| @@ -3397,7 +3466,7 @@ x_draw_glyph_string (s) | |||
| 3397 | } | 3466 | } |
| 3398 | 3467 | ||
| 3399 | /* Reset clipping. */ | 3468 | /* Reset clipping. */ |
| 3400 | mac_reset_clipping (s->display, s->window); | 3469 | mac_reset_clip_rectangles (s->display, s->gc); |
| 3401 | } | 3470 | } |
| 3402 | 3471 | ||
| 3403 | /* Shift display to make room for inserted glyphs. */ | 3472 | /* Shift display to make room for inserted glyphs. */ |
| @@ -4121,6 +4190,8 @@ note_mouse_movement (frame, pos) | |||
| 4121 | frame->mouse_moved = 1; | 4190 | frame->mouse_moved = 1; |
| 4122 | last_mouse_scroll_bar = Qnil; | 4191 | last_mouse_scroll_bar = Qnil; |
| 4123 | note_mouse_highlight (frame, pos->h, pos->v); | 4192 | note_mouse_highlight (frame, pos->h, pos->v); |
| 4193 | /* Remember which glyph we're now on. */ | ||
| 4194 | remember_mouse_glyph (frame, pos->h, pos->v, &last_mouse_glyph); | ||
| 4124 | } | 4195 | } |
| 4125 | } | 4196 | } |
| 4126 | 4197 | ||
| @@ -4129,9 +4200,6 @@ note_mouse_movement (frame, pos) | |||
| 4129 | Mouse Face | 4200 | Mouse Face |
| 4130 | ************************************************************************/ | 4201 | ************************************************************************/ |
| 4131 | 4202 | ||
| 4132 | static int glyph_rect P_ ((struct frame *f, int, int, Rect *)); | ||
| 4133 | |||
| 4134 | |||
| 4135 | /* MAC TODO: This should be called from somewhere (or removed) ++KFS */ | 4203 | /* MAC TODO: This should be called from somewhere (or removed) ++KFS */ |
| 4136 | 4204 | ||
| 4137 | static void | 4205 | static void |
| @@ -4145,110 +4213,6 @@ redo_mouse_highlight () | |||
| 4145 | } | 4213 | } |
| 4146 | 4214 | ||
| 4147 | 4215 | ||
| 4148 | /* Try to determine frame pixel position and size of the glyph under | ||
| 4149 | frame pixel coordinates X/Y on frame F . Return the position and | ||
| 4150 | size in *RECT. Value is non-zero if we could compute these | ||
| 4151 | values. */ | ||
| 4152 | |||
| 4153 | static int | ||
| 4154 | glyph_rect (f, x, y, rect) | ||
| 4155 | struct frame *f; | ||
| 4156 | int x, y; | ||
| 4157 | Rect *rect; | ||
| 4158 | { | ||
| 4159 | Lisp_Object window; | ||
| 4160 | |||
| 4161 | window = window_from_coordinates (f, x, y, 0, &x, &y, 0); | ||
| 4162 | |||
| 4163 | if (!NILP (window)) | ||
| 4164 | { | ||
| 4165 | struct window *w = XWINDOW (window); | ||
| 4166 | struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); | ||
| 4167 | struct glyph_row *end = r + w->current_matrix->nrows - 1; | ||
| 4168 | |||
| 4169 | for (; r < end && r->enabled_p; ++r) | ||
| 4170 | if (r->y <= y && r->y + r->height > y) | ||
| 4171 | { | ||
| 4172 | /* Found the row at y. */ | ||
| 4173 | struct glyph *g = r->glyphs[TEXT_AREA]; | ||
| 4174 | struct glyph *end = g + r->used[TEXT_AREA]; | ||
| 4175 | int gx; | ||
| 4176 | |||
| 4177 | rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y); | ||
| 4178 | rect->bottom = rect->top + r->height; | ||
| 4179 | |||
| 4180 | if (x < r->x) | ||
| 4181 | { | ||
| 4182 | /* x is to the left of the first glyph in the row. */ | ||
| 4183 | /* Shouldn't this be a pixel value? | ||
| 4184 | WINDOW_LEFT_EDGE_X (w) seems to be the right value. | ||
| 4185 | ++KFS */ | ||
| 4186 | rect->left = WINDOW_LEFT_EDGE_COL (w); | ||
| 4187 | rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x); | ||
| 4188 | return 1; | ||
| 4189 | } | ||
| 4190 | |||
| 4191 | for (gx = r->x; g < end; gx += g->pixel_width, ++g) | ||
| 4192 | if (gx <= x && gx + g->pixel_width > x) | ||
| 4193 | { | ||
| 4194 | /* x is on a glyph. */ | ||
| 4195 | rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx); | ||
| 4196 | rect->right = rect->left + g->pixel_width; | ||
| 4197 | return 1; | ||
| 4198 | } | ||
| 4199 | |||
| 4200 | /* x is to the right of the last glyph in the row. */ | ||
| 4201 | rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx); | ||
| 4202 | /* Shouldn't this be a pixel value? | ||
| 4203 | WINDOW_RIGHT_EDGE_X (w) seems to be the right value. | ||
| 4204 | ++KFS */ | ||
| 4205 | rect->right = WINDOW_RIGHT_EDGE_COL (w); | ||
| 4206 | return 1; | ||
| 4207 | } | ||
| 4208 | } | ||
| 4209 | |||
| 4210 | /* The y is not on any row. */ | ||
| 4211 | return 0; | ||
| 4212 | } | ||
| 4213 | |||
| 4214 | /* MAC TODO: This should be called from somewhere (or removed) ++KFS */ | ||
| 4215 | |||
| 4216 | /* Record the position of the mouse in last_mouse_glyph. */ | ||
| 4217 | static void | ||
| 4218 | remember_mouse_glyph (f1, gx, gy) | ||
| 4219 | struct frame * f1; | ||
| 4220 | int gx, gy; | ||
| 4221 | { | ||
| 4222 | if (!glyph_rect (f1, gx, gy, &last_mouse_glyph)) | ||
| 4223 | { | ||
| 4224 | int width = FRAME_SMALLEST_CHAR_WIDTH (f1); | ||
| 4225 | int height = FRAME_SMALLEST_FONT_HEIGHT (f1); | ||
| 4226 | |||
| 4227 | /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to | ||
| 4228 | round down even for negative values. */ | ||
| 4229 | if (gx < 0) | ||
| 4230 | gx -= width - 1; | ||
| 4231 | if (gy < 0) | ||
| 4232 | gy -= height - 1; | ||
| 4233 | #if 0 | ||
| 4234 | /* This was the original code from XTmouse_position, but it seems | ||
| 4235 | to give the position of the glyph diagonally next to the one | ||
| 4236 | the mouse is over. */ | ||
| 4237 | gx = (gx + width - 1) / width * width; | ||
| 4238 | gy = (gy + height - 1) / height * height; | ||
| 4239 | #else | ||
| 4240 | gx = gx / width * width; | ||
| 4241 | gy = gy / height * height; | ||
| 4242 | #endif | ||
| 4243 | |||
| 4244 | last_mouse_glyph.left = gx; | ||
| 4245 | last_mouse_glyph.top = gy; | ||
| 4246 | last_mouse_glyph.right = gx + width; | ||
| 4247 | last_mouse_glyph.bottom = gy + height; | ||
| 4248 | } | ||
| 4249 | } | ||
| 4250 | |||
| 4251 | |||
| 4252 | static struct frame * | 4216 | static struct frame * |
| 4253 | mac_focus_frame (dpyinfo) | 4217 | mac_focus_frame (dpyinfo) |
| 4254 | struct mac_display_info *dpyinfo; | 4218 | struct mac_display_info *dpyinfo; |
| @@ -4264,18 +4228,18 @@ mac_focus_frame (dpyinfo) | |||
| 4264 | 4228 | ||
| 4265 | 4229 | ||
| 4266 | /* Return the current position of the mouse. | 4230 | /* Return the current position of the mouse. |
| 4267 | *fp should be a frame which indicates which display to ask about. | 4231 | *FP should be a frame which indicates which display to ask about. |
| 4268 | 4232 | ||
| 4269 | If the mouse movement started in a scroll bar, set *fp, *bar_window, | 4233 | If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW, |
| 4270 | and *part to the frame, window, and scroll bar part that the mouse | 4234 | and *PART to the frame, window, and scroll bar part that the mouse |
| 4271 | is over. Set *x and *y to the portion and whole of the mouse's | 4235 | is over. Set *X and *Y to the portion and whole of the mouse's |
| 4272 | position on the scroll bar. | 4236 | position on the scroll bar. |
| 4273 | 4237 | ||
| 4274 | If the mouse movement started elsewhere, set *fp to the frame the | 4238 | If the mouse movement started elsewhere, set *FP to the frame the |
| 4275 | mouse is on, *bar_window to nil, and *x and *y to the character cell | 4239 | mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell |
| 4276 | the mouse is over. | 4240 | the mouse is over. |
| 4277 | 4241 | ||
| 4278 | Set *time to the server time-stamp for the time at which the mouse | 4242 | Set *TIME to the server time-stamp for the time at which the mouse |
| 4279 | was at this position. | 4243 | was at this position. |
| 4280 | 4244 | ||
| 4281 | Don't store anything if we don't have a valid set of values to report. | 4245 | Don't store anything if we don't have a valid set of values to report. |
| @@ -4292,11 +4256,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) | |||
| 4292 | Lisp_Object *x, *y; | 4256 | Lisp_Object *x, *y; |
| 4293 | unsigned long *time; | 4257 | unsigned long *time; |
| 4294 | { | 4258 | { |
| 4295 | Point mouse_pos; | 4259 | FRAME_PTR f1; |
| 4296 | int ignore1, ignore2; | ||
| 4297 | struct frame *f = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp)); | ||
| 4298 | WindowPtr wp = FRAME_MAC_WINDOW (f); | ||
| 4299 | Lisp_Object frame, tail; | ||
| 4300 | 4260 | ||
| 4301 | BLOCK_INPUT; | 4261 | BLOCK_INPUT; |
| 4302 | 4262 | ||
| @@ -4304,25 +4264,43 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) | |||
| 4304 | x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); | 4264 | x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); |
| 4305 | else | 4265 | else |
| 4306 | { | 4266 | { |
| 4267 | Lisp_Object frame, tail; | ||
| 4268 | |||
| 4307 | /* Clear the mouse-moved flag for every frame on this display. */ | 4269 | /* Clear the mouse-moved flag for every frame on this display. */ |
| 4308 | FOR_EACH_FRAME (tail, frame) | 4270 | FOR_EACH_FRAME (tail, frame) |
| 4309 | XFRAME (frame)->mouse_moved = 0; | 4271 | XFRAME (frame)->mouse_moved = 0; |
| 4310 | 4272 | ||
| 4311 | last_mouse_scroll_bar = Qnil; | 4273 | last_mouse_scroll_bar = Qnil; |
| 4312 | 4274 | ||
| 4313 | SetPortWindowPort (wp); | 4275 | if (FRAME_MAC_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame |
| 4314 | 4276 | && FRAME_LIVE_P (last_mouse_frame)) | |
| 4315 | GetMouse (&mouse_pos); | 4277 | f1 = last_mouse_frame; |
| 4316 | 4278 | else | |
| 4317 | pixel_to_glyph_coords (f, mouse_pos.h, mouse_pos.v, &ignore1, &ignore2, | 4279 | f1 = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp)); |
| 4318 | &last_mouse_glyph, insist); | ||
| 4319 | 4280 | ||
| 4320 | *bar_window = Qnil; | 4281 | if (f1) |
| 4321 | *part = scroll_bar_handle; | 4282 | { |
| 4322 | *fp = f; | 4283 | /* Ok, we found a frame. Store all the values. |
| 4323 | XSETINT (*x, mouse_pos.h); | 4284 | last_mouse_glyph is a rectangle used to reduce the |
| 4324 | XSETINT (*y, mouse_pos.v); | 4285 | generation of mouse events. To not miss any motion |
| 4325 | *time = last_mouse_movement_time; | 4286 | events, we must divide the frame into rectangles of the |
| 4287 | size of the smallest character that could be displayed | ||
| 4288 | on it, i.e. into the same rectangles that matrices on | ||
| 4289 | the frame are divided into. */ | ||
| 4290 | Point mouse_pos; | ||
| 4291 | |||
| 4292 | SetPortWindowPort (FRAME_MAC_WINDOW (f1)); | ||
| 4293 | GetMouse (&mouse_pos); | ||
| 4294 | remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v, | ||
| 4295 | &last_mouse_glyph); | ||
| 4296 | |||
| 4297 | *bar_window = Qnil; | ||
| 4298 | *part = 0; | ||
| 4299 | *fp = f1; | ||
| 4300 | XSETINT (*x, mouse_pos.h); | ||
| 4301 | XSETINT (*y, mouse_pos.v); | ||
| 4302 | *time = last_mouse_movement_time; | ||
| 4303 | } | ||
| 4326 | } | 4304 | } |
| 4327 | 4305 | ||
| 4328 | UNBLOCK_INPUT; | 4306 | UNBLOCK_INPUT; |
| @@ -5270,7 +5248,7 @@ x_clip_to_row (w, row, area, gc) | |||
| 5270 | clip_rect.right = clip_rect.left + window_width; | 5248 | clip_rect.right = clip_rect.left + window_width; |
| 5271 | clip_rect.bottom = clip_rect.top + row->visible_height; | 5249 | clip_rect.bottom = clip_rect.top + row->visible_height; |
| 5272 | 5250 | ||
| 5273 | mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), &clip_rect); | 5251 | mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f), gc, &clip_rect, 1); |
| 5274 | } | 5252 | } |
| 5275 | 5253 | ||
| 5276 | 5254 | ||
| @@ -5313,7 +5291,7 @@ x_draw_hollow_cursor (w, row) | |||
| 5313 | /* Set clipping, draw the rectangle, and reset clipping again. */ | 5291 | /* Set clipping, draw the rectangle, and reset clipping again. */ |
| 5314 | x_clip_to_row (w, row, TEXT_AREA, gc); | 5292 | x_clip_to_row (w, row, TEXT_AREA, gc); |
| 5315 | mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h); | 5293 | mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h); |
| 5316 | mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); | 5294 | mac_reset_clip_rectangles (dpy, gc); |
| 5317 | } | 5295 | } |
| 5318 | 5296 | ||
| 5319 | 5297 | ||
| @@ -5397,7 +5375,7 @@ x_draw_bar_cursor (w, row, width, kind) | |||
| 5397 | cursor_glyph->pixel_width, | 5375 | cursor_glyph->pixel_width, |
| 5398 | width); | 5376 | width); |
| 5399 | 5377 | ||
| 5400 | mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); | 5378 | mac_reset_clip_rectangles (dpy, gc); |
| 5401 | } | 5379 | } |
| 5402 | } | 5380 | } |
| 5403 | 5381 | ||
| @@ -6761,7 +6739,13 @@ static char **font_name_table = NULL; | |||
| 6761 | static int font_name_table_size = 0; | 6739 | static int font_name_table_size = 0; |
| 6762 | static int font_name_count = 0; | 6740 | static int font_name_count = 0; |
| 6763 | 6741 | ||
| 6742 | /* Alist linking font family names to Font Manager font family | ||
| 6743 | references (which can also be used as QuickDraw font IDs). We use | ||
| 6744 | an alist because hash tables are not ready when the terminal frame | ||
| 6745 | for Mac OS Classic is created. */ | ||
| 6746 | static Lisp_Object fm_font_family_alist; | ||
| 6764 | #if USE_ATSUI | 6747 | #if USE_ATSUI |
| 6748 | /* Hash table linking font family names to ATSU font IDs. */ | ||
| 6765 | static Lisp_Object atsu_font_id_hash; | 6749 | static Lisp_Object atsu_font_id_hash; |
| 6766 | #endif | 6750 | #endif |
| 6767 | 6751 | ||
| @@ -6811,24 +6795,39 @@ decode_mac_font_name (name, size, coding_system) | |||
| 6811 | struct coding_system coding; | 6795 | struct coding_system coding; |
| 6812 | char *buf, *p; | 6796 | char *buf, *p; |
| 6813 | 6797 | ||
| 6814 | for (p = name; *p; p++) | 6798 | if (!NILP (coding_system) && !NILP (Fcoding_system_p (coding_system))) |
| 6815 | if (!isascii (*p) || iscntrl (*p)) | 6799 | { |
| 6816 | break; | 6800 | for (p = name; *p; p++) |
| 6801 | if (!isascii (*p) || iscntrl (*p)) | ||
| 6802 | break; | ||
| 6817 | 6803 | ||
| 6818 | if (*p == '\0' | 6804 | if (*p) |
| 6819 | || NILP (coding_system) || NILP (Fcoding_system_p (coding_system))) | 6805 | { |
| 6820 | return; | 6806 | setup_coding_system (coding_system, &coding); |
| 6807 | coding.src_multibyte = 0; | ||
| 6808 | coding.dst_multibyte = 1; | ||
| 6809 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 6810 | coding.composing = COMPOSITION_DISABLED; | ||
| 6811 | buf = (char *) alloca (size); | ||
| 6812 | |||
| 6813 | decode_coding (&coding, name, buf, strlen (name), size - 1); | ||
| 6814 | bcopy (buf, name, coding.produced); | ||
| 6815 | name[coding.produced] = '\0'; | ||
| 6816 | } | ||
| 6817 | } | ||
| 6821 | 6818 | ||
| 6822 | setup_coding_system (coding_system, &coding); | 6819 | /* If there's just one occurrence of '-' in the family name, it is |
| 6823 | coding.src_multibyte = 0; | 6820 | replaced with '_'. (More than one occurrence of '-' means a |
| 6824 | coding.dst_multibyte = 1; | 6821 | "FOUNDRY-FAMILY-CHARSET"-style name.) */ |
| 6825 | coding.mode |= CODING_MODE_LAST_BLOCK; | 6822 | p = strchr (name, '-'); |
| 6826 | coding.composing = COMPOSITION_DISABLED; | 6823 | if (p && strchr (p + 1, '-') == NULL) |
| 6827 | buf = (char *) alloca (size); | 6824 | *p = '_'; |
| 6828 | 6825 | ||
| 6829 | decode_coding (&coding, name, buf, strlen (name), size - 1); | 6826 | for (p = name; *p; p++) |
| 6830 | bcopy (buf, name, coding.produced); | 6827 | /* On Mac OS X 10.3, tolower also converts non-ASCII characters |
| 6831 | name[coding.produced] = '\0'; | 6828 | for some locales. */ |
| 6829 | if (isascii (*p)) | ||
| 6830 | *p = tolower (*p); | ||
| 6832 | } | 6831 | } |
| 6833 | 6832 | ||
| 6834 | 6833 | ||
| @@ -6867,32 +6866,46 @@ mac_to_x_fontname (name, size, style, charset) | |||
| 6867 | } | 6866 | } |
| 6868 | 6867 | ||
| 6869 | 6868 | ||
| 6870 | /* Convert an X font spec to the corresponding mac font name, which | 6869 | /* Parse fully-specified and instantiated X11 font spec XF, and store |
| 6871 | can then be passed to GetFNum after conversion to a Pascal string. | 6870 | the results to FAMILY, *SIZE, *STYLE, and CHARSET. Return 1 if the |
| 6872 | For ordinary Mac fonts, this should just be their names, like | 6871 | parsing succeeded, and 0 otherwise. For FAMILY and CHARSET, the |
| 6873 | "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts | 6872 | caller must allocate at least 256 and 32 bytes respectively. For |
| 6874 | collection contain their charset designation in their names, like | 6873 | ordinary Mac fonts, the value stored to FAMILY should just be their |
| 6875 | "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font | 6874 | names, like "monaco", "Taipei", etc. Fonts converted from the GNU |
| 6876 | names are handled accordingly. */ | 6875 | intlfonts collection contain their charset designation in their |
| 6877 | static void | 6876 | names, like "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both |
| 6878 | x_font_name_to_mac_font_name (xf, mf, mf_decoded, style, cs) | 6877 | types of font names are handled accordingly. */ |
| 6879 | char *xf, *mf, *mf_decoded; | 6878 | |
| 6879 | const int kDefaultFontSize = 12; | ||
| 6880 | |||
| 6881 | static int | ||
| 6882 | parse_x_font_name (xf, family, size, style, charset) | ||
| 6883 | char *xf, *family; | ||
| 6884 | int *size; | ||
| 6880 | Style *style; | 6885 | Style *style; |
| 6881 | char *cs; | 6886 | char *charset; |
| 6882 | { | 6887 | { |
| 6883 | Str31 foundry; | 6888 | Str31 foundry, weight; |
| 6884 | Str255 family; | 6889 | int point_size, avgwidth; |
| 6885 | char weight[20], slant[2], *p; | 6890 | char slant[2], *p; |
| 6886 | Lisp_Object charset_info, coding_system = Qnil; | ||
| 6887 | struct coding_system coding; | ||
| 6888 | 6891 | ||
| 6889 | strcpy (mf, ""); | 6892 | if (sscanf (xf, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]-%*[^-]-%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s", |
| 6893 | foundry, family, weight, slant, size, | ||
| 6894 | &point_size, &avgwidth, charset) != 8 | ||
| 6895 | && sscanf (xf, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s", | ||
| 6896 | foundry, family, weight, slant, size, | ||
| 6897 | &point_size, &avgwidth, charset) != 8) | ||
| 6898 | return 0; | ||
| 6890 | 6899 | ||
| 6891 | if (sscanf (xf, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", | 6900 | if (*size == 0) |
| 6892 | foundry, family, weight, slant, cs) != 5 && | 6901 | { |
| 6893 | sscanf (xf, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", | 6902 | if (point_size > 0) |
| 6894 | foundry, family, weight, slant, cs) != 5) | 6903 | *size = point_size / 10; |
| 6895 | return; | 6904 | else if (avgwidth > 0) |
| 6905 | *size = avgwidth / 10; | ||
| 6906 | } | ||
| 6907 | if (*size == 0) | ||
| 6908 | *size = kDefaultFontSize; | ||
| 6896 | 6909 | ||
| 6897 | *style = normal; | 6910 | *style = normal; |
| 6898 | if (strcmp (weight, "bold") == 0) | 6911 | if (strcmp (weight, "bold") == 0) |
| @@ -6900,32 +6913,31 @@ x_font_name_to_mac_font_name (xf, mf, mf_decoded, style, cs) | |||
| 6900 | if (*slant == 'i') | 6913 | if (*slant == 'i') |
| 6901 | *style |= italic; | 6914 | *style |= italic; |
| 6902 | 6915 | ||
| 6903 | charset_info = Fassoc (build_string (cs), Vmac_charset_info_alist); | 6916 | if (NILP (Fassoc (build_string (charset), Vmac_charset_info_alist))) |
| 6904 | if (!NILP (charset_info)) | ||
| 6905 | { | 6917 | { |
| 6906 | strcpy (mf_decoded, family); | 6918 | int foundry_len = strlen (foundry), family_len = strlen (family); |
| 6907 | coding_system = Fcar (Fcdr (Fcdr (charset_info))); | 6919 | |
| 6920 | if (foundry_len + family_len + strlen (charset) + 2 < sizeof (Str255)) | ||
| 6921 | { | ||
| 6922 | /* Like sprintf (family, "%s-%s-%s", foundry, family, charset), | ||
| 6923 | but take overlap into account. */ | ||
| 6924 | memmove (family + foundry_len + 1, family, family_len); | ||
| 6925 | memcpy (family, foundry, foundry_len); | ||
| 6926 | family[foundry_len] = '-'; | ||
| 6927 | family[foundry_len + 1 + family_len] = '-'; | ||
| 6928 | strcpy (family + foundry_len + 1 + family_len + 1, charset); | ||
| 6929 | } | ||
| 6930 | else | ||
| 6931 | return 0; | ||
| 6908 | } | 6932 | } |
| 6909 | else | ||
| 6910 | sprintf (mf_decoded, "%s-%s-%s", foundry, family, cs); | ||
| 6911 | 6933 | ||
| 6912 | for (p = mf_decoded; *p; p++) | 6934 | for (p = family; *p; p++) |
| 6913 | if (!isascii (*p) || iscntrl (*p)) | 6935 | /* On Mac OS X 10.3, tolower also converts non-ASCII characters |
| 6914 | break; | 6936 | for some locales. */ |
| 6937 | if (isascii (*p)) | ||
| 6938 | *p = tolower (*p); | ||
| 6915 | 6939 | ||
| 6916 | if (*p == '\0' | 6940 | return 1; |
| 6917 | || NILP (coding_system) || NILP (Fcoding_system_p (coding_system))) | ||
| 6918 | strcpy (mf, mf_decoded); | ||
| 6919 | else | ||
| 6920 | { | ||
| 6921 | setup_coding_system (coding_system, &coding); | ||
| 6922 | coding.src_multibyte = 1; | ||
| 6923 | coding.dst_multibyte = 0; | ||
| 6924 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 6925 | encode_coding (&coding, mf_decoded, mf, | ||
| 6926 | strlen (mf_decoded), sizeof (Str255) - 1); | ||
| 6927 | mf[coding.produced] = '\0'; | ||
| 6928 | } | ||
| 6929 | } | 6941 | } |
| 6930 | 6942 | ||
| 6931 | 6943 | ||
| @@ -7002,6 +7014,8 @@ init_font_name_table () | |||
| 7002 | kFontMacintoshPlatform, kFontNoScript, | 7014 | kFontMacintoshPlatform, kFontNoScript, |
| 7003 | kFontNoLanguage, name_len, name, | 7015 | kFontNoLanguage, name_len, name, |
| 7004 | NULL, NULL); | 7016 | NULL, NULL); |
| 7017 | if (err == noErr) | ||
| 7018 | decode_mac_font_name (name, name_len + 1, Qnil); | ||
| 7005 | if (err == noErr | 7019 | if (err == noErr |
| 7006 | && *name != '.' | 7020 | && *name != '.' |
| 7007 | && (prev_name == NULL | 7021 | && (prev_name == NULL |
| @@ -7017,7 +7031,7 @@ init_font_name_table () | |||
| 7017 | bold, cs)); | 7031 | bold, cs)); |
| 7018 | add_font_name_table_entry (mac_to_x_fontname (name, 0, | 7032 | add_font_name_table_entry (mac_to_x_fontname (name, 0, |
| 7019 | italic | bold, cs)); | 7033 | italic | bold, cs)); |
| 7020 | Fputhash (Fdowncase (make_unibyte_string (name, name_len)), | 7034 | Fputhash (make_unibyte_string (name, name_len), |
| 7021 | long_to_cons (font_ids[i]), atsu_font_id_hash); | 7035 | long_to_cons (font_ids[i]), atsu_font_id_hash); |
| 7022 | xfree (prev_name); | 7036 | xfree (prev_name); |
| 7023 | prev_name = name; | 7037 | prev_name = name; |
| @@ -7067,12 +7081,14 @@ init_font_name_table () | |||
| 7067 | sc = GetTextEncodingBase (encoding); | 7081 | sc = GetTextEncodingBase (encoding); |
| 7068 | text_encoding_info = assq_no_quit (make_number (sc), | 7082 | text_encoding_info = assq_no_quit (make_number (sc), |
| 7069 | text_encoding_info_alist); | 7083 | text_encoding_info_alist); |
| 7070 | if (!NILP (text_encoding_info)) | 7084 | if (NILP (text_encoding_info)) |
| 7071 | decode_mac_font_name (name, sizeof (name), | ||
| 7072 | XCAR (XCDR (text_encoding_info))); | ||
| 7073 | else | ||
| 7074 | text_encoding_info = assq_no_quit (make_number (kTextEncodingMacRoman), | 7085 | text_encoding_info = assq_no_quit (make_number (kTextEncodingMacRoman), |
| 7075 | text_encoding_info_alist); | 7086 | text_encoding_info_alist); |
| 7087 | decode_mac_font_name (name, sizeof (name), | ||
| 7088 | XCAR (XCDR (text_encoding_info))); | ||
| 7089 | fm_font_family_alist = Fcons (Fcons (build_string (name), | ||
| 7090 | make_number (ff)), | ||
| 7091 | fm_font_family_alist); | ||
| 7076 | 7092 | ||
| 7077 | /* Point the instance iterator at the current font family. */ | 7093 | /* Point the instance iterator at the current font family. */ |
| 7078 | if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr) | 7094 | if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr) |
| @@ -7151,12 +7167,14 @@ init_font_name_table () | |||
| 7151 | scriptcode = FontToScript (fontnum); | 7167 | scriptcode = FontToScript (fontnum); |
| 7152 | text_encoding_info = assq_no_quit (make_number (scriptcode), | 7168 | text_encoding_info = assq_no_quit (make_number (scriptcode), |
| 7153 | text_encoding_info_alist); | 7169 | text_encoding_info_alist); |
| 7154 | if (!NILP (text_encoding_info)) | 7170 | if (NILP (text_encoding_info)) |
| 7155 | decode_mac_font_name (name, sizeof (name), | ||
| 7156 | XCAR (XCDR (text_encoding_info))); | ||
| 7157 | else | ||
| 7158 | text_encoding_info = assq_no_quit (make_number (smRoman), | 7171 | text_encoding_info = assq_no_quit (make_number (smRoman), |
| 7159 | text_encoding_info_alist); | 7172 | text_encoding_info_alist); |
| 7173 | decode_mac_font_name (name, sizeof (name), | ||
| 7174 | XCAR (XCDR (text_encoding_info))); | ||
| 7175 | fm_font_family_alist = Fcons (Fcons (build_string (name), | ||
| 7176 | make_number (fontnum)), | ||
| 7177 | fm_font_family_alist); | ||
| 7160 | do | 7178 | do |
| 7161 | { | 7179 | { |
| 7162 | HLock (font_handle); | 7180 | HLock (font_handle); |
| @@ -7212,6 +7230,7 @@ mac_clear_font_name_table () | |||
| 7212 | xfree (font_name_table); | 7230 | xfree (font_name_table); |
| 7213 | font_name_table = NULL; | 7231 | font_name_table = NULL; |
| 7214 | font_name_table_size = font_name_count = 0; | 7232 | font_name_table_size = font_name_count = 0; |
| 7233 | fm_font_family_alist = Qnil; | ||
| 7215 | } | 7234 | } |
| 7216 | 7235 | ||
| 7217 | 7236 | ||
| @@ -7520,9 +7539,6 @@ is_fully_specified_xlfd (char *p) | |||
| 7520 | } | 7539 | } |
| 7521 | 7540 | ||
| 7522 | 7541 | ||
| 7523 | const int kDefaultFontSize = 12; | ||
| 7524 | |||
| 7525 | |||
| 7526 | /* XLoadQueryFont creates and returns an internal representation for a | 7542 | /* XLoadQueryFont creates and returns an internal representation for a |
| 7527 | font in a MacFontStruct struct. There is really no concept | 7543 | font in a MacFontStruct struct. There is really no concept |
| 7528 | corresponding to "loading" a font on the Mac. But we check its | 7544 | corresponding to "loading" a font on the Mac. But we check its |
| @@ -7532,12 +7548,9 @@ const int kDefaultFontSize = 12; | |||
| 7532 | static MacFontStruct * | 7548 | static MacFontStruct * |
| 7533 | XLoadQueryFont (Display *dpy, char *fontname) | 7549 | XLoadQueryFont (Display *dpy, char *fontname) |
| 7534 | { | 7550 | { |
| 7535 | int i, size, point_size, avgwidth, is_two_byte_font, char_width; | 7551 | int i, size, char_width; |
| 7536 | char *name; | 7552 | char *name; |
| 7537 | GrafPtr port; | 7553 | Str255 family; |
| 7538 | SInt16 old_fontnum, old_fontsize; | ||
| 7539 | Style old_fontface; | ||
| 7540 | Str255 mfontname, mfontname_decoded; | ||
| 7541 | Str31 charset; | 7554 | Str31 charset; |
| 7542 | SInt16 fontnum; | 7555 | SInt16 fontnum; |
| 7543 | #if USE_ATSUI | 7556 | #if USE_ATSUI |
| @@ -7551,10 +7564,6 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7551 | short scriptcode; | 7564 | short scriptcode; |
| 7552 | #endif | 7565 | #endif |
| 7553 | MacFontStruct *font; | 7566 | MacFontStruct *font; |
| 7554 | FontInfo the_fontinfo; | ||
| 7555 | #ifdef MAC_OSX | ||
| 7556 | UInt32 old_flags, new_flags; | ||
| 7557 | #endif | ||
| 7558 | 7567 | ||
| 7559 | if (is_fully_specified_xlfd (fontname)) | 7568 | if (is_fully_specified_xlfd (fontname)) |
| 7560 | name = fontname; | 7569 | name = fontname; |
| @@ -7568,32 +7577,9 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7568 | name = SDATA (XCAR (matched_fonts)); | 7577 | name = SDATA (XCAR (matched_fonts)); |
| 7569 | } | 7578 | } |
| 7570 | 7579 | ||
| 7571 | GetPort (&port); /* save the current font number used */ | 7580 | if (parse_x_font_name (name, family, &size, &fontface, charset) == 0) |
| 7572 | #if TARGET_API_MAC_CARBON | 7581 | return NULL; |
| 7573 | old_fontnum = GetPortTextFont (port); | ||
| 7574 | old_fontsize = GetPortTextSize (port); | ||
| 7575 | old_fontface = GetPortTextFace (port); | ||
| 7576 | #else | ||
| 7577 | old_fontnum = port->txFont; | ||
| 7578 | old_fontsize = port->txSize; | ||
| 7579 | old_fontface = port->txFace; | ||
| 7580 | #endif | ||
| 7581 | |||
| 7582 | if (sscanf (name, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%*s", &size, &point_size, &avgwidth) != 3) | ||
| 7583 | size = 0; | ||
| 7584 | else | ||
| 7585 | { | ||
| 7586 | if (size == 0) | ||
| 7587 | if (point_size > 0) | ||
| 7588 | size = point_size / 10; | ||
| 7589 | else if (avgwidth > 0) | ||
| 7590 | size = avgwidth / 10; | ||
| 7591 | } | ||
| 7592 | if (size == 0) | ||
| 7593 | size = kDefaultFontSize; | ||
| 7594 | 7582 | ||
| 7595 | x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded, | ||
| 7596 | &fontface, charset); | ||
| 7597 | #if USE_ATSUI | 7583 | #if USE_ATSUI |
| 7598 | if (strcmp (charset, "iso10646-1") == 0) /* XXX */ | 7584 | if (strcmp (charset, "iso10646-1") == 0) /* XXX */ |
| 7599 | { | 7585 | { |
| @@ -7610,10 +7596,8 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7610 | ATSUFontFeatureType types[] = {kAllTypographicFeaturesType}; | 7596 | ATSUFontFeatureType types[] = {kAllTypographicFeaturesType}; |
| 7611 | ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector}; | 7597 | ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector}; |
| 7612 | Lisp_Object font_id_cons; | 7598 | Lisp_Object font_id_cons; |
| 7613 | 7599 | ||
| 7614 | font_id_cons = Fgethash (Fdowncase | 7600 | font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)), |
| 7615 | (make_unibyte_string (mfontname, | ||
| 7616 | strlen (mfontname))), | ||
| 7617 | atsu_font_id_hash, Qnil); | 7601 | atsu_font_id_hash, Qnil); |
| 7618 | if (NILP (font_id_cons)) | 7602 | if (NILP (font_id_cons)) |
| 7619 | return NULL; | 7603 | return NULL; |
| @@ -7634,24 +7618,21 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7634 | scriptcode = kTextEncodingMacUnicode; | 7618 | scriptcode = kTextEncodingMacUnicode; |
| 7635 | } | 7619 | } |
| 7636 | else | 7620 | else |
| 7637 | { | ||
| 7638 | #endif | 7621 | #endif |
| 7639 | c2pstr (mfontname); | 7622 | { |
| 7623 | Lisp_Object tmp = Fassoc (build_string (family), fm_font_family_alist); | ||
| 7624 | |||
| 7625 | if (NILP (tmp)) | ||
| 7626 | return NULL; | ||
| 7627 | fontnum = XINT (XCDR (tmp)); | ||
| 7640 | #if TARGET_API_MAC_CARBON | 7628 | #if TARGET_API_MAC_CARBON |
| 7641 | fontnum = FMGetFontFamilyFromName (mfontname); | 7629 | if (FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr) |
| 7642 | if (fontnum == kInvalidFontFamily | 7630 | return NULL; |
| 7643 | || FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr) | 7631 | scriptcode = GetTextEncodingBase (encoding); |
| 7644 | return NULL; | ||
| 7645 | scriptcode = GetTextEncodingBase (encoding); | ||
| 7646 | #else | 7632 | #else |
| 7647 | GetFNum (mfontname, &fontnum); | 7633 | scriptcode = FontToScript (fontnum); |
| 7648 | if (fontnum == 0) | ||
| 7649 | return NULL; | ||
| 7650 | scriptcode = FontToScript (fontnum); | ||
| 7651 | #endif | 7634 | #endif |
| 7652 | #if USE_ATSUI | ||
| 7653 | } | 7635 | } |
| 7654 | #endif | ||
| 7655 | 7636 | ||
| 7656 | font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct)); | 7637 | font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct)); |
| 7657 | 7638 | ||
| @@ -7670,7 +7651,7 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7670 | if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0) | 7651 | if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0) |
| 7671 | font->mac_scriptcode = smRoman; | 7652 | font->mac_scriptcode = smRoman; |
| 7672 | 7653 | ||
| 7673 | font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset); | 7654 | font->full_name = mac_to_x_fontname (family, size, fontface, charset); |
| 7674 | 7655 | ||
| 7675 | #if USE_ATSUI | 7656 | #if USE_ATSUI |
| 7676 | if (font->mac_style) | 7657 | if (font->mac_style) |
| @@ -7755,130 +7736,149 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7755 | font->max_char_or_byte2 = 0xff; | 7736 | font->max_char_or_byte2 = 0xff; |
| 7756 | } | 7737 | } |
| 7757 | else | 7738 | else |
| 7739 | #endif | ||
| 7758 | { | 7740 | { |
| 7741 | GrafPtr port; | ||
| 7742 | SInt16 old_fontnum, old_fontsize; | ||
| 7743 | Style old_fontface; | ||
| 7744 | FontInfo the_fontinfo; | ||
| 7745 | int is_two_byte_font; | ||
| 7746 | |||
| 7747 | /* Save the current font number used. */ | ||
| 7748 | GetPort (&port); | ||
| 7749 | #if TARGET_API_MAC_CARBON | ||
| 7750 | old_fontnum = GetPortTextFont (port); | ||
| 7751 | old_fontsize = GetPortTextSize (port); | ||
| 7752 | old_fontface = GetPortTextFace (port); | ||
| 7753 | #else | ||
| 7754 | old_fontnum = port->txFont; | ||
| 7755 | old_fontsize = port->txSize; | ||
| 7756 | old_fontface = port->txFace; | ||
| 7759 | #endif | 7757 | #endif |
| 7760 | is_two_byte_font = font->mac_scriptcode == smJapanese || | ||
| 7761 | font->mac_scriptcode == smTradChinese || | ||
| 7762 | font->mac_scriptcode == smSimpChinese || | ||
| 7763 | font->mac_scriptcode == smKorean; | ||
| 7764 | 7758 | ||
| 7765 | TextFont (fontnum); | 7759 | TextFont (fontnum); |
| 7766 | TextSize (size); | 7760 | TextSize (size); |
| 7767 | TextFace (fontface); | 7761 | TextFace (fontface); |
| 7768 | 7762 | ||
| 7769 | GetFontInfo (&the_fontinfo); | 7763 | GetFontInfo (&the_fontinfo); |
| 7770 | 7764 | ||
| 7771 | font->ascent = the_fontinfo.ascent; | 7765 | font->ascent = the_fontinfo.ascent; |
| 7772 | font->descent = the_fontinfo.descent; | 7766 | font->descent = the_fontinfo.descent; |
| 7773 | 7767 | ||
| 7774 | if (is_two_byte_font) | 7768 | is_two_byte_font = (font->mac_scriptcode == smJapanese |
| 7775 | { | 7769 | || font->mac_scriptcode == smTradChinese |
| 7776 | font->min_byte1 = 0xa1; | 7770 | || font->mac_scriptcode == smSimpChinese |
| 7777 | font->max_byte1 = 0xfe; | 7771 | || font->mac_scriptcode == smKorean); |
| 7778 | font->min_char_or_byte2 = 0xa1; | ||
| 7779 | font->max_char_or_byte2 = 0xfe; | ||
| 7780 | 7772 | ||
| 7781 | /* Use the width of an "ideographic space" of that font because | 7773 | if (is_two_byte_font) |
| 7782 | the_fontinfo.widMax returns the wrong width for some fonts. */ | 7774 | { |
| 7783 | switch (font->mac_scriptcode) | 7775 | font->min_byte1 = 0xa1; |
| 7784 | { | 7776 | font->max_byte1 = 0xfe; |
| 7785 | case smJapanese: | 7777 | font->min_char_or_byte2 = 0xa1; |
| 7786 | font->min_byte1 = 0x81; | 7778 | font->max_char_or_byte2 = 0xfe; |
| 7787 | font->max_byte1 = 0xfc; | 7779 | |
| 7788 | font->min_char_or_byte2 = 0x40; | 7780 | /* Use the width of an "ideographic space" of that font |
| 7789 | font->max_char_or_byte2 = 0xfc; | 7781 | because the_fontinfo.widMax returns the wrong width for |
| 7790 | char_width = StringWidth("\p\x81\x40"); | 7782 | some fonts. */ |
| 7791 | break; | 7783 | switch (font->mac_scriptcode) |
| 7792 | case smTradChinese: | 7784 | { |
| 7793 | font->min_char_or_byte2 = 0x40; | 7785 | case smJapanese: |
| 7794 | char_width = StringWidth("\p\xa1\x40"); | 7786 | font->min_byte1 = 0x81; |
| 7795 | break; | 7787 | font->max_byte1 = 0xfc; |
| 7796 | case smSimpChinese: | 7788 | font->min_char_or_byte2 = 0x40; |
| 7797 | char_width = StringWidth("\p\xa1\xa1"); | 7789 | font->max_char_or_byte2 = 0xfc; |
| 7798 | break; | 7790 | char_width = StringWidth("\p\x81\x40"); |
| 7799 | case smKorean: | 7791 | break; |
| 7800 | char_width = StringWidth("\p\xa1\xa1"); | 7792 | case smTradChinese: |
| 7801 | break; | 7793 | font->min_char_or_byte2 = 0x40; |
| 7802 | } | 7794 | char_width = StringWidth("\p\xa1\x40"); |
| 7803 | } | 7795 | break; |
| 7804 | else | 7796 | case smSimpChinese: |
| 7805 | { | 7797 | char_width = StringWidth("\p\xa1\xa1"); |
| 7806 | font->min_byte1 = font->max_byte1 = 0; | 7798 | break; |
| 7807 | font->min_char_or_byte2 = 0x20; | 7799 | case smKorean: |
| 7808 | font->max_char_or_byte2 = 0xff; | 7800 | char_width = StringWidth("\p\xa1\xa1"); |
| 7801 | break; | ||
| 7802 | } | ||
| 7803 | } | ||
| 7804 | else | ||
| 7805 | { | ||
| 7806 | font->min_byte1 = font->max_byte1 = 0; | ||
| 7807 | font->min_char_or_byte2 = 0x20; | ||
| 7808 | font->max_char_or_byte2 = 0xff; | ||
| 7809 | 7809 | ||
| 7810 | /* Do this instead of use the_fontinfo.widMax, which incorrectly | 7810 | /* Do this instead of use the_fontinfo.widMax, which |
| 7811 | returns 15 for 12-point Monaco! */ | 7811 | incorrectly returns 15 for 12-point Monaco! */ |
| 7812 | char_width = CharWidth ('m'); | 7812 | char_width = CharWidth ('m'); |
| 7813 | } | 7813 | } |
| 7814 | 7814 | ||
| 7815 | if (is_two_byte_font) | 7815 | if (is_two_byte_font) |
| 7816 | { | 7816 | { |
| 7817 | font->per_char = NULL; | 7817 | font->per_char = NULL; |
| 7818 | 7818 | ||
| 7819 | if (fontface & italic) | 7819 | if (fontface & italic) |
| 7820 | font->max_bounds.rbearing = char_width + 1; | 7820 | font->max_bounds.rbearing = char_width + 1; |
| 7821 | else | 7821 | else |
| 7822 | font->max_bounds.rbearing = char_width; | 7822 | font->max_bounds.rbearing = char_width; |
| 7823 | font->max_bounds.lbearing = 0; | 7823 | font->max_bounds.lbearing = 0; |
| 7824 | font->max_bounds.width = char_width; | 7824 | font->max_bounds.width = char_width; |
| 7825 | font->max_bounds.ascent = the_fontinfo.ascent; | 7825 | font->max_bounds.ascent = the_fontinfo.ascent; |
| 7826 | font->max_bounds.descent = the_fontinfo.descent; | 7826 | font->max_bounds.descent = the_fontinfo.descent; |
| 7827 | 7827 | ||
| 7828 | font->min_bounds = font->max_bounds; | 7828 | font->min_bounds = font->max_bounds; |
| 7829 | } | 7829 | } |
| 7830 | else | 7830 | else |
| 7831 | { | 7831 | { |
| 7832 | int c, min_width, max_width; | 7832 | int c, min_width, max_width; |
| 7833 | Rect char_bounds, min_bounds, max_bounds; | 7833 | Rect char_bounds, min_bounds, max_bounds; |
| 7834 | char ch; | 7834 | char ch; |
| 7835 | 7835 | ||
| 7836 | font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); | 7836 | font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); |
| 7837 | bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1)); | ||
| 7837 | 7838 | ||
| 7838 | min_width = max_width = char_width; | 7839 | min_width = max_width = char_width; |
| 7839 | SetRect (&min_bounds, -32767, -32767, 32767, 32767); | 7840 | SetRect (&min_bounds, -32767, -32767, 32767, 32767); |
| 7840 | SetRect (&max_bounds, 0, 0, 0, 0); | 7841 | SetRect (&max_bounds, 0, 0, 0, 0); |
| 7841 | for (c = 0x20; c <= 0xff; c++) | 7842 | for (c = 0x20; c <= 0xff; c++) |
| 7842 | { | ||
| 7843 | ch = c; | ||
| 7844 | char_width = CharWidth (ch); | ||
| 7845 | QDTextBounds (1, &ch, &char_bounds); | ||
| 7846 | STORE_XCHARSTRUCT (font->per_char[c - 0x20], | ||
| 7847 | char_width, char_bounds); | ||
| 7848 | /* Some Japanese fonts (in SJIS encoding) return 0 as the | ||
| 7849 | character width of 0x7f. */ | ||
| 7850 | if (char_width > 0) | ||
| 7851 | { | 7843 | { |
| 7852 | min_width = min (min_width, char_width); | 7844 | ch = c; |
| 7853 | max_width = max (max_width, char_width); | 7845 | char_width = CharWidth (ch); |
| 7846 | QDTextBounds (1, &ch, &char_bounds); | ||
| 7847 | STORE_XCHARSTRUCT (font->per_char[c - 0x20], | ||
| 7848 | char_width, char_bounds); | ||
| 7849 | /* Some Japanese fonts (in SJIS encoding) return 0 as | ||
| 7850 | the character width of 0x7f. */ | ||
| 7851 | if (char_width > 0) | ||
| 7852 | { | ||
| 7853 | min_width = min (min_width, char_width); | ||
| 7854 | max_width = max (max_width, char_width); | ||
| 7855 | } | ||
| 7856 | if (!EmptyRect (&char_bounds)) | ||
| 7857 | { | ||
| 7858 | SetRect (&min_bounds, | ||
| 7859 | max (min_bounds.left, char_bounds.left), | ||
| 7860 | max (min_bounds.top, char_bounds.top), | ||
| 7861 | min (min_bounds.right, char_bounds.right), | ||
| 7862 | min (min_bounds.bottom, char_bounds.bottom)); | ||
| 7863 | UnionRect (&max_bounds, &char_bounds, &max_bounds); | ||
| 7864 | } | ||
| 7854 | } | 7865 | } |
| 7855 | if (!EmptyRect (&char_bounds)) | 7866 | STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); |
| 7867 | STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); | ||
| 7868 | if (min_width == max_width | ||
| 7869 | && max_bounds.left >= 0 && max_bounds.right <= max_width) | ||
| 7856 | { | 7870 | { |
| 7857 | SetRect (&min_bounds, | 7871 | /* Fixed width and no overhangs. */ |
| 7858 | max (min_bounds.left, char_bounds.left), | 7872 | xfree (font->per_char); |
| 7859 | max (min_bounds.top, char_bounds.top), | 7873 | font->per_char = NULL; |
| 7860 | min (min_bounds.right, char_bounds.right), | ||
| 7861 | min (min_bounds.bottom, char_bounds.bottom)); | ||
| 7862 | UnionRect (&max_bounds, &char_bounds, &max_bounds); | ||
| 7863 | } | 7874 | } |
| 7864 | } | 7875 | } |
| 7865 | STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); | ||
| 7866 | STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); | ||
| 7867 | if (min_width == max_width | ||
| 7868 | && max_bounds.left >= 0 && max_bounds.right <= max_width) | ||
| 7869 | { | ||
| 7870 | /* Fixed width and no overhangs. */ | ||
| 7871 | xfree (font->per_char); | ||
| 7872 | font->per_char = NULL; | ||
| 7873 | } | ||
| 7874 | } | ||
| 7875 | 7876 | ||
| 7876 | TextFont (old_fontnum); /* restore previous font number, size and face */ | 7877 | /* Restore previous font number, size and face. */ |
| 7877 | TextSize (old_fontsize); | 7878 | TextFont (old_fontnum); |
| 7878 | TextFace (old_fontface); | 7879 | TextSize (old_fontsize); |
| 7879 | #if USE_ATSUI | 7880 | TextFace (old_fontface); |
| 7880 | } | 7881 | } |
| 7881 | #endif | ||
| 7882 | 7882 | ||
| 7883 | return font; | 7883 | return font; |
| 7884 | } | 7884 | } |
| @@ -10907,14 +10907,17 @@ syms_of_macterm () | |||
| 10907 | staticpro (&Qreverse); | 10907 | staticpro (&Qreverse); |
| 10908 | Qreverse = intern ("reverse"); | 10908 | Qreverse = intern ("reverse"); |
| 10909 | 10909 | ||
| 10910 | staticpro (&Qmac_ready_for_drag_n_drop); | ||
| 10911 | Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); | ||
| 10912 | |||
| 10910 | staticpro (&x_display_name_list); | 10913 | staticpro (&x_display_name_list); |
| 10911 | x_display_name_list = Qnil; | 10914 | x_display_name_list = Qnil; |
| 10912 | 10915 | ||
| 10913 | staticpro (&last_mouse_scroll_bar); | 10916 | staticpro (&last_mouse_scroll_bar); |
| 10914 | last_mouse_scroll_bar = Qnil; | 10917 | last_mouse_scroll_bar = Qnil; |
| 10915 | 10918 | ||
| 10916 | Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); | 10919 | staticpro (&fm_font_family_alist); |
| 10917 | staticpro (&Qmac_ready_for_drag_n_drop); | 10920 | fm_font_family_alist = Qnil; |
| 10918 | 10921 | ||
| 10919 | #if USE_ATSUI | 10922 | #if USE_ATSUI |
| 10920 | staticpro (&atsu_font_id_hash); | 10923 | staticpro (&atsu_font_id_hash); |