comparison src/macterm.c @ 90242:5e2d3828e89f

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-91 Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 581-597) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 133-141) - Update from CVS - Merge from emacs--cvs-trunk--0 - Update from CVS: texi/gnus.texi (RSS): Fix key description. - Update from CVS: texi/gnus.texi (Document Server Internals): Addition.
author Miles Bader <miles@gnu.org>
date Sat, 15 Oct 2005 00:26:05 +0000
parents aa89c814f853 abad34f080c4
children c8c3c8dbe333
comparison
equal deleted inserted replaced
90241:c293a93ebacf 90242:5e2d3828e89f
270 extern void menubar_selection_callback (FRAME_PTR, int); 270 extern void menubar_selection_callback (FRAME_PTR, int);
271 271
272 #define GC_FORE_COLOR(gc) (&(gc)->fore_color) 272 #define GC_FORE_COLOR(gc) (&(gc)->fore_color)
273 #define GC_BACK_COLOR(gc) (&(gc)->back_color) 273 #define GC_BACK_COLOR(gc) (&(gc)->back_color)
274 #define GC_FONT(gc) ((gc)->xgcv.font) 274 #define GC_FONT(gc) ((gc)->xgcv.font)
275 #define GC_CLIP_REGION(gc) ((gc)->clip_region)
275 #define MAC_WINDOW_NORMAL_GC(w) (((mac_output *) GetWRefCon (w))->normal_gc) 276 #define MAC_WINDOW_NORMAL_GC(w) (((mac_output *) GetWRefCon (w))->normal_gc)
277
278 static RgnHandle saved_port_clip_region = NULL;
279
280 static void
281 mac_begin_clip (region)
282 RgnHandle region;
283 {
284 static RgnHandle new_region = NULL;
285
286 if (saved_port_clip_region == NULL)
287 saved_port_clip_region = NewRgn ();
288 if (new_region == NULL)
289 new_region = NewRgn ();
290
291 if (region)
292 {
293 GetClip (saved_port_clip_region);
294 SectRgn (saved_port_clip_region, region, new_region);
295 SetClip (new_region);
296 }
297 }
298
299 static void
300 mac_end_clip (region)
301 RgnHandle region;
302 {
303 if (region)
304 SetClip (saved_port_clip_region);
305 }
276 306
277 307
278 /* X display function emulation */ 308 /* X display function emulation */
279 309
280 void 310 void
297 { 327 {
298 SetPortWindowPort (w); 328 SetPortWindowPort (w);
299 329
300 RGBForeColor (GC_FORE_COLOR (gc)); 330 RGBForeColor (GC_FORE_COLOR (gc));
301 331
332 mac_begin_clip (GC_CLIP_REGION (gc));
302 MoveTo (x1, y1); 333 MoveTo (x1, y1);
303 LineTo (x2, y2); 334 LineTo (x2, y2);
335 mac_end_clip (GC_CLIP_REGION (gc));
304 } 336 }
305 337
306 void 338 void
307 mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2) 339 mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
308 Display *display; 340 Display *display;
339 SetPortWindowPort (w); 371 SetPortWindowPort (w);
340 372
341 RGBBackColor (GC_BACK_COLOR (gc)); 373 RGBBackColor (GC_BACK_COLOR (gc));
342 SetRect (&r, x, y, x + width, y + height); 374 SetRect (&r, x, y, x + width, y + height);
343 375
376 mac_begin_clip (GC_CLIP_REGION (gc));
344 EraseRect (&r); 377 EraseRect (&r);
378 mac_end_clip (GC_CLIP_REGION (gc));
345 379
346 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); 380 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w)));
347 } 381 }
348 382
349 383
406 440
407 RGBForeColor (GC_FORE_COLOR (gc)); 441 RGBForeColor (GC_FORE_COLOR (gc));
408 RGBBackColor (GC_BACK_COLOR (gc)); 442 RGBBackColor (GC_BACK_COLOR (gc));
409 SetRect (&r, x, y, x + width, y + height); 443 SetRect (&r, x, y, x + width, y + height);
410 444
445 mac_begin_clip (GC_CLIP_REGION (gc));
411 #if TARGET_API_MAC_CARBON 446 #if TARGET_API_MAC_CARBON
412 LockPortBits (GetWindowPort (w)); 447 LockPortBits (GetWindowPort (w));
413 CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)), 448 CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)),
414 &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0); 449 &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0);
415 UnlockPortBits (GetWindowPort (w)); 450 UnlockPortBits (GetWindowPort (w));
416 #else /* not TARGET_API_MAC_CARBON */ 451 #else /* not TARGET_API_MAC_CARBON */
417 CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r, 452 CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
418 overlay_p ? srcOr : srcCopy, 0); 453 overlay_p ? srcOr : srcCopy, 0);
419 #endif /* not TARGET_API_MAC_CARBON */ 454 #endif /* not TARGET_API_MAC_CARBON */
455 mac_end_clip (GC_CLIP_REGION (gc));
420 456
421 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); 457 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w)));
422 }
423
424
425 /* Mac replacement for XSetClipRectangles. */
426
427 static void
428 mac_set_clip_rectangle (display, w, r)
429 Display *display;
430 WindowPtr w;
431 Rect *r;
432 {
433 SetPortWindowPort (w);
434
435 ClipRect (r);
436 }
437
438
439 /* Mac replacement for XSetClipMask. */
440
441 static void
442 mac_reset_clipping (display, w)
443 Display *display;
444 WindowPtr w;
445 {
446 Rect r;
447
448 SetPortWindowPort (w);
449
450 SetRect (&r, -32767, -32767, 32767, 32767);
451 ClipRect (&r);
452 } 458 }
453 459
454 460
455 /* Mac replacement for XCreateBitmapFromBitmapData. */ 461 /* Mac replacement for XCreateBitmapFromBitmapData. */
456 462
577 SetPortWindowPort (w); 583 SetPortWindowPort (w);
578 584
579 RGBForeColor (GC_FORE_COLOR (gc)); 585 RGBForeColor (GC_FORE_COLOR (gc));
580 SetRect (&r, x, y, x + width, y + height); 586 SetRect (&r, x, y, x + width, y + height);
581 587
588 mac_begin_clip (GC_CLIP_REGION (gc));
582 PaintRect (&r); /* using foreground color of gc */ 589 PaintRect (&r); /* using foreground color of gc */
590 mac_end_clip (GC_CLIP_REGION (gc));
583 } 591 }
584 592
585 593
586 #if 0 /* TODO: figure out if we need to do this on Mac. */ 594 #if 0 /* TODO: figure out if we need to do this on Mac. */
587 static void 595 static void
625 SetPortWindowPort (w); 633 SetPortWindowPort (w);
626 634
627 RGBForeColor (GC_FORE_COLOR (gc)); 635 RGBForeColor (GC_FORE_COLOR (gc));
628 SetRect (&r, x, y, x + width + 1, y + height + 1); 636 SetRect (&r, x, y, x + width + 1, y + height + 1);
629 637
638 mac_begin_clip (GC_CLIP_REGION (gc));
630 FrameRect (&r); /* using foreground color of gc */ 639 FrameRect (&r); /* using foreground color of gc */
640 mac_end_clip (GC_CLIP_REGION (gc));
631 } 641 }
632 642
633 643
634 #if 0 /* TODO: figure out if we need to do this on Mac. */ 644 #if 0 /* TODO: figure out if we need to do this on Mac. */
635 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */ 645 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
678 ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)}; 688 ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
679 static ATSLineLayoutOptions line_layout = 689 static ATSLineLayoutOptions line_layout =
680 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 690 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
681 kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics 691 kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics
682 #else 692 #else
683 kATSLineIsDisplayOnly 693 kATSLineIsDisplayOnly | kATSLineFractDisable
684 #endif 694 #endif
685 ; 695 ;
686 ATSUAttributeValuePtr values[] = {&line_layout}; 696 ATSUAttributeValuePtr values[] = {&line_layout};
687 697
688 err = ATSUCreateTextLayoutWithTextPtr (text, 698 err = ATSUCreateTextLayoutWithTextPtr (text,
782 { 792 {
783 #ifdef MAC_OSX 793 #ifdef MAC_OSX
784 if (NILP (Vmac_use_core_graphics)) 794 if (NILP (Vmac_use_core_graphics))
785 { 795 {
786 #endif 796 #endif
797 mac_begin_clip (GC_CLIP_REGION (gc));
787 MoveTo (x, y); 798 MoveTo (x, y);
788 ATSUDrawText (text_layout, 799 ATSUDrawText (text_layout,
789 kATSUFromTextBeginning, kATSUToTextEnd, 800 kATSUFromTextBeginning, kATSUToTextEnd,
790 kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); 801 kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
802 mac_end_clip (GC_CLIP_REGION (gc));
791 #ifdef MAC_OSX 803 #ifdef MAC_OSX
792 } 804 }
793 else 805 else
794 { 806 {
795 CGrafPtr port; 807 CGrafPtr port;
796 CGContextRef context; 808 CGContextRef context;
797 Rect rect; 809 Rect rect;
798 RgnHandle region = NewRgn ();
799 float port_height; 810 float port_height;
800 ATSUAttributeTag tags[] = {kATSUCGContextTag}; 811 ATSUAttributeTag tags[] = {kATSUCGContextTag};
801 ByteCount sizes[] = {sizeof (CGContextRef)}; 812 ByteCount sizes[] = {sizeof (CGContextRef)};
802 ATSUAttributeValuePtr values[] = {&context}; 813 ATSUAttributeValuePtr values[] = {&context};
803 814
804 GetPort (&port); 815 GetPort (&port);
805 QDBeginCGContext (port, &context); 816 QDBeginCGContext (port, &context);
806 GetPortBounds (port, &rect); 817 GetPortBounds (port, &rect);
807 port_height = rect.bottom - rect.top; 818 port_height = rect.bottom - rect.top;
808 GetClip (region); 819 if (gc->n_clip_rects)
809 GetRegionBounds (region, &rect); 820 {
810 /* XXX: This is not correct if the clip region is not a 821 CGContextTranslateCTM (context, 0, port_height);
811 simple rectangle. */ 822 CGContextScaleCTM (context, 1, -1);
812 CGContextClipToRect (context, 823 CGContextClipToRects (context, gc->clip_rects,
813 CGRectMake (rect.left, 824 gc->n_clip_rects);
814 port_height - rect.bottom, 825 CGContextScaleCTM (context, 1, -1);
815 rect.right - rect.left, 826 CGContextTranslateCTM (context, 0, -port_height);
816 rect.bottom - rect.top)); 827 }
817 DisposeRgn (region);
818 CGContextSetRGBFillColor 828 CGContextSetRGBFillColor
819 (context, 829 (context,
820 RED_FROM_ULONG (gc->xgcv.foreground) / 255.0, 830 RED_FROM_ULONG (gc->xgcv.foreground) / 255.0,
821 GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0, 831 GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0,
822 BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0, 832 BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0,
843 TextFont (GC_FONT (gc)->mac_fontnum); 853 TextFont (GC_FONT (gc)->mac_fontnum);
844 TextSize (GC_FONT (gc)->mac_fontsize); 854 TextSize (GC_FONT (gc)->mac_fontsize);
845 TextFace (GC_FONT (gc)->mac_fontface); 855 TextFace (GC_FONT (gc)->mac_fontface);
846 TextMode (mode); 856 TextMode (mode);
847 857
858 mac_begin_clip (GC_CLIP_REGION (gc));
848 MoveTo (x, y); 859 MoveTo (x, y);
849 DrawText (buf, 0, nchars * bytes_per_char); 860 DrawText (buf, 0, nchars * bytes_per_char);
861 mac_end_clip (GC_CLIP_REGION (gc));
850 #if USE_ATSUI 862 #if USE_ATSUI
851 } 863 }
852 #endif 864 #endif
853 865
854 if (mode != srcOr) 866 if (mode != srcOr)
943 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); 955 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
944 956
945 ForeColor (blackColor); 957 ForeColor (blackColor);
946 BackColor (whiteColor); 958 BackColor (whiteColor);
947 959
960 mac_begin_clip (GC_CLIP_REGION (gc));
948 LockPixels (GetGWorldPixMap (src)); 961 LockPixels (GetGWorldPixMap (src));
949 #if TARGET_API_MAC_CARBON 962 #if TARGET_API_MAC_CARBON
950 LockPortBits (GetWindowPort (dest)); 963 LockPortBits (GetWindowPort (dest));
951 CopyBits (GetPortBitMapForCopyBits (src), 964 CopyBits (GetPortBitMapForCopyBits (src),
952 GetPortBitMapForCopyBits (GetWindowPort (dest)), 965 GetPortBitMapForCopyBits (GetWindowPort (dest)),
955 #else /* not TARGET_API_MAC_CARBON */ 968 #else /* not TARGET_API_MAC_CARBON */
956 CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits), 969 CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits),
957 &src_r, &dest_r, srcCopy, 0); 970 &src_r, &dest_r, srcCopy, 0);
958 #endif /* not TARGET_API_MAC_CARBON */ 971 #endif /* not TARGET_API_MAC_CARBON */
959 UnlockPixels (GetGWorldPixMap (src)); 972 UnlockPixels (GetGWorldPixMap (src));
973 mac_end_clip (GC_CLIP_REGION (gc));
960 974
961 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); 975 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest)));
962 } 976 }
963 977
964 978
981 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); 995 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
982 996
983 ForeColor (blackColor); 997 ForeColor (blackColor);
984 BackColor (whiteColor); 998 BackColor (whiteColor);
985 999
1000 mac_begin_clip (GC_CLIP_REGION (gc));
986 LockPixels (GetGWorldPixMap (src)); 1001 LockPixels (GetGWorldPixMap (src));
987 LockPixels (GetGWorldPixMap (mask)); 1002 LockPixels (GetGWorldPixMap (mask));
988 #if TARGET_API_MAC_CARBON 1003 #if TARGET_API_MAC_CARBON
989 LockPortBits (GetWindowPort (dest)); 1004 LockPortBits (GetWindowPort (dest));
990 CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask), 1005 CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
995 CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits), 1010 CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
996 &(dest->portBits), &src_r, &src_r, &dest_r); 1011 &(dest->portBits), &src_r, &src_r, &dest_r);
997 #endif /* not TARGET_API_MAC_CARBON */ 1012 #endif /* not TARGET_API_MAC_CARBON */
998 UnlockPixels (GetGWorldPixMap (mask)); 1013 UnlockPixels (GetGWorldPixMap (mask));
999 UnlockPixels (GetGWorldPixMap (src)); 1014 UnlockPixels (GetGWorldPixMap (src));
1015 mac_end_clip (GC_CLIP_REGION (gc));
1000 1016
1001 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); 1017 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest)));
1002 } 1018 }
1003 1019
1004 1020
1031 1047
1032 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid 1048 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1033 color mapping in CopyBits. Otherwise, it will be slow. */ 1049 color mapping in CopyBits. Otherwise, it will be slow. */
1034 ForeColor (blackColor); 1050 ForeColor (blackColor);
1035 BackColor (whiteColor); 1051 BackColor (whiteColor);
1052 mac_begin_clip (GC_CLIP_REGION (gc));
1036 CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0); 1053 CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
1054 mac_end_clip (GC_CLIP_REGION (gc));
1037 1055
1038 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); 1056 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w)));
1039 #endif /* not TARGET_API_MAC_CARBON */ 1057 #endif /* not TARGET_API_MAC_CARBON */
1040 } 1058 }
1041 1059
1166 void 1184 void
1167 XFreeGC (display, gc) 1185 XFreeGC (display, gc)
1168 Display *display; 1186 Display *display;
1169 GC gc; 1187 GC gc;
1170 { 1188 {
1189 if (gc->clip_region)
1190 DisposeRgn (gc->clip_region);
1171 xfree (gc); 1191 xfree (gc);
1172 } 1192 }
1173 1193
1174 1194
1175 /* Mac replacement for XGetGCValues. */ 1195 /* Mac replacement for XGetGCValues. */
1233 Display *display; 1253 Display *display;
1234 GC gc; 1254 GC gc;
1235 XFontStruct *font; 1255 XFontStruct *font;
1236 { 1256 {
1237 gc->xgcv.font = font; 1257 gc->xgcv.font = font;
1258 }
1259
1260
1261 /* Mac replacement for XSetClipRectangles. */
1262
1263 static void
1264 mac_set_clip_rectangles (display, gc, rectangles, n)
1265 Display *display;
1266 GC gc;
1267 Rect *rectangles;
1268 int n;
1269 {
1270 int i;
1271
1272 if (n < 0 || n > MAX_CLIP_RECTS)
1273 abort ();
1274 if (n == 0)
1275 {
1276 if (gc->clip_region)
1277 {
1278 DisposeRgn (gc->clip_region);
1279 gc->clip_region = NULL;
1280 }
1281 }
1282 else
1283 {
1284 if (gc->clip_region == NULL)
1285 gc->clip_region = NewRgn ();
1286 RectRgn (gc->clip_region, rectangles);
1287 if (n > 1)
1288 {
1289 RgnHandle region = NewRgn ();
1290
1291 for (i = 1; i < n; i++)
1292 {
1293 RectRgn (region, rectangles + i);
1294 UnionRgn (gc->clip_region, region, gc->clip_region);
1295 }
1296 DisposeRgn (region);
1297 }
1298 }
1299 #if defined (MAC_OSX) && USE_ATSUI
1300 gc->n_clip_rects = n;
1301
1302 for (i = 0; i < n; i++)
1303 {
1304 Rect *rect = rectangles + i;
1305
1306 gc->clip_rects[i] = CGRectMake (rect->left, rect->top,
1307 rect->right - rect->left,
1308 rect->bottom - rect->top);
1309 }
1310 #endif
1311 }
1312
1313
1314 /* Mac replacement for XSetClipMask. */
1315
1316 static INLINE void
1317 mac_reset_clip_rectangles (display, gc)
1318 Display *display;
1319 GC gc;
1320 {
1321 mac_set_clip_rectangles (display, gc, NULL, 0);
1238 } 1322 }
1239 1323
1240 1324
1241 /* Mac replacement for XSetWindowBackground. */ 1325 /* Mac replacement for XSetWindowBackground. */
1242 1326
1647 mac_draw_bitmap (display, window, face->gc, p->x, p->y, 1731 mac_draw_bitmap (display, window, face->gc, p->x, p->y,
1648 p->wd, p->h, bits, p->overlay_p); 1732 p->wd, p->h, bits, p->overlay_p);
1649 XSetForeground (display, face->gc, gcv.foreground); 1733 XSetForeground (display, face->gc, gcv.foreground);
1650 } 1734 }
1651 1735
1652 mac_reset_clipping (display, window); 1736 mac_reset_clip_rectangles (display, gc);
1653 } 1737 }
1654 1738
1655 1739
1656 1740
1657 /* This is called when starting Emacs and when restarting after 1741 /* This is called when starting Emacs and when restarting after
1681 /* Function prototypes of this page. */ 1765 /* Function prototypes of this page. */
1682 1766
1683 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); 1767 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
1684 static int mac_encode_char P_ ((int, XChar2b *, struct font_info *, 1768 static int mac_encode_char P_ ((int, XChar2b *, struct font_info *,
1685 struct charset *, int *)); 1769 struct charset *, int *));
1686
1687
1688 /* Return a pointer to per-char metric information in FONT of a
1689 character pointed by B which is a pointer to an XChar2b. */
1690
1691 #define PER_CHAR_METRIC(font, b) \
1692 ((font)->per_char \
1693 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1694 + (((font)->min_byte1 || (font)->max_byte1) \
1695 ? (((b)->byte1 - (font)->min_byte1) \
1696 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1697 : 0)) \
1698 : &((font)->max_bounds))
1699 1770
1700 1771
1701 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B 1772 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1702 is not contained in the font. */ 1773 is not contained in the font. */
1703 1774
2125 2196
2126 static INLINE void 2197 static INLINE void
2127 x_set_glyph_string_clipping (s) 2198 x_set_glyph_string_clipping (s)
2128 struct glyph_string *s; 2199 struct glyph_string *s;
2129 { 2200 {
2130 Rect r; 2201 Rect rects[MAX_CLIP_RECTS];
2131 get_glyph_string_clip_rect (s, &r); 2202 int n;
2132 mac_set_clip_rectangle (s->display, s->window, &r); 2203
2204 n = get_glyph_string_clip_rects (s, rects, MAX_CLIP_RECTS);
2205 mac_set_clip_rectangles (s->display, s->gc, rects, n);
2133 } 2206 }
2134 2207
2135 2208
2136 /* RIF: 2209 /* RIF:
2137 Compute left and right overhang of glyph string S. If S is a glyph 2210 Compute left and right overhang of glyph string S. If S is a glyph
2323 /* Draw text with XDrawString if background has already been 2396 /* Draw text with XDrawString if background has already been
2324 filled. Otherwise, use XDrawImageString. (Note that 2397 filled. Otherwise, use XDrawImageString. (Note that
2325 XDrawImageString is usually faster than XDrawString.) Always 2398 XDrawImageString is usually faster than XDrawString.) Always
2326 use XDrawImageString when drawing the cursor so that there is 2399 use XDrawImageString when drawing the cursor so that there is
2327 no chance that characters under a box cursor are invisible. */ 2400 no chance that characters under a box cursor are invisible. */
2328 if (s->for_overlaps_p 2401 if (s->for_overlaps
2329 || (s->background_filled_p && s->hl != DRAW_CURSOR)) 2402 || (s->background_filled_p && s->hl != DRAW_CURSOR))
2330 #endif 2403 #endif
2331 { 2404 {
2332 /* Draw characters with 16-bit or 8-bit functions. */ 2405 /* Draw characters with 16-bit or 8-bit functions. */
2333 if (s->two_byte_p 2406 if (s->two_byte_p
2344 #if defined (MAC_OS8) && !USE_ATSUI 2417 #if defined (MAC_OS8) && !USE_ATSUI
2345 else 2418 else
2346 { 2419 {
2347 if (s->two_byte_p) 2420 if (s->two_byte_p)
2348 XDrawImageString16 (s->display, s->window, s->gc, x, 2421 XDrawImageString16 (s->display, s->window, s->gc, x,
2349 s->ybase - boff, s->char2b, s->nchars); 2422 s->ybase - boff, s->char2b, s->nchars);
2350 else 2423 else
2351 XDrawImageString (s->display, s->window, s->gc, x, 2424 XDrawImageString (s->display, s->window, s->gc, x,
2352 s->ybase - boff, char1b, s->nchars); 2425 s->ybase - boff, char1b, s->nchars);
2353 } 2426 }
2354 #endif 2427 #endif
2752 2825
2753 if (raised_p) 2826 if (raised_p)
2754 gc = f->output_data.mac->white_relief.gc; 2827 gc = f->output_data.mac->white_relief.gc;
2755 else 2828 else
2756 gc = f->output_data.mac->black_relief.gc; 2829 gc = f->output_data.mac->black_relief.gc;
2757 mac_set_clip_rectangle (dpy, window, clip_rect); 2830 mac_set_clip_rectangles (dpy, gc, clip_rect, 1);
2758 2831
2759 /* Top. */ 2832 /* Top. */
2760 if (top_p) 2833 if (top_p)
2761 for (i = 0; i < width; ++i) 2834 for (i = 0; i < width; ++i)
2762 XDrawLine (dpy, window, gc, 2835 XDrawLine (dpy, window, gc,
2767 if (left_p) 2840 if (left_p)
2768 for (i = 0; i < width; ++i) 2841 for (i = 0; i < width; ++i)
2769 XDrawLine (dpy, window, gc, 2842 XDrawLine (dpy, window, gc,
2770 left_x + i, top_y + i, left_x + i, bottom_y - i); 2843 left_x + i, top_y + i, left_x + i, bottom_y - i);
2771 2844
2772 mac_reset_clipping (dpy, window); 2845 mac_reset_clip_rectangles (dpy, gc);
2773 if (raised_p) 2846 if (raised_p)
2774 gc = f->output_data.mac->black_relief.gc; 2847 gc = f->output_data.mac->black_relief.gc;
2775 else 2848 else
2776 gc = f->output_data.mac->white_relief.gc; 2849 gc = f->output_data.mac->white_relief.gc;
2777 mac_set_clip_rectangle (dpy, window, 2850 mac_set_clip_rectangles (dpy, gc, clip_rect, 1);
2778 clip_rect);
2779 2851
2780 /* Bottom. */ 2852 /* Bottom. */
2781 if (bot_p) 2853 if (bot_p)
2782 for (i = 0; i < width; ++i) 2854 for (i = 0; i < width; ++i)
2783 XDrawLine (dpy, window, gc, 2855 XDrawLine (dpy, window, gc,
2788 if (right_p) 2860 if (right_p)
2789 for (i = 0; i < width; ++i) 2861 for (i = 0; i < width; ++i)
2790 XDrawLine (dpy, window, gc, 2862 XDrawLine (dpy, window, gc,
2791 right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1); 2863 right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1);
2792 2864
2793 mac_reset_clipping (dpy, window); 2865 mac_reset_clip_rectangles (dpy, gc);
2794 } 2866 }
2795 2867
2796 2868
2797 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y, 2869 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2798 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to 2870 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2810 { 2882 {
2811 XGCValues xgcv; 2883 XGCValues xgcv;
2812 2884
2813 XGetGCValues (s->display, s->gc, GCForeground, &xgcv); 2885 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2814 XSetForeground (s->display, s->gc, s->face->box_color); 2886 XSetForeground (s->display, s->gc, s->face->box_color);
2815 mac_set_clip_rectangle (s->display, s->window, clip_rect); 2887 mac_set_clip_rectangles (s->display, s->gc, clip_rect, 1);
2816 2888
2817 /* Top. */ 2889 /* Top. */
2818 XFillRectangle (s->display, s->window, s->gc, 2890 XFillRectangle (s->display, s->window, s->gc,
2819 left_x, top_y, right_x - left_x + 1, width); 2891 left_x, top_y, right_x - left_x + 1, width);
2820 2892
2831 if (right_p) 2903 if (right_p)
2832 XFillRectangle (s->display, s->window, s->gc, 2904 XFillRectangle (s->display, s->window, s->gc,
2833 right_x - width + 1, top_y, width, bottom_y - top_y + 1); 2905 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2834 2906
2835 XSetForeground (s->display, s->gc, xgcv.foreground); 2907 XSetForeground (s->display, s->gc, xgcv.foreground);
2836 mac_reset_clipping (s->display, s->window); 2908 mac_reset_clip_rectangles (s->display, s->gc);
2837 } 2909 }
2838 2910
2839 2911
2840 /* Draw a box around glyph string S. */ 2912 /* Draw a box around glyph string S. */
2841 2913
3185 { 3257 {
3186 x_draw_image_foreground_1 (s, pixmap); 3258 x_draw_image_foreground_1 (s, pixmap);
3187 x_set_glyph_string_clipping (s); 3259 x_set_glyph_string_clipping (s);
3188 mac_copy_area (s->display, pixmap, s->window, s->gc, 3260 mac_copy_area (s->display, pixmap, s->window, s->gc,
3189 0, 0, s->background_width, s->height, s->x, s->y); 3261 0, 0, s->background_width, s->height, s->x, s->y);
3190 mac_reset_clipping (s->display, s->window);
3191 XFreePixmap (s->display, pixmap); 3262 XFreePixmap (s->display, pixmap);
3192 } 3263 }
3193 else 3264 else
3194 #endif 3265 #endif
3195 x_draw_image_foreground (s); 3266 x_draw_image_foreground (s);
3237 } 3308 }
3238 else 3309 else
3239 gc = s->face->gc; 3310 gc = s->face->gc;
3240 3311
3241 get_glyph_string_clip_rect (s, &r); 3312 get_glyph_string_clip_rect (s, &r);
3242 mac_set_clip_rectangle (s->display, s->window, &r); 3313 mac_set_clip_rectangles (s->display, gc, &r, 1);
3243 3314
3244 #if 0 /* MAC_TODO: stipple */ 3315 #if 0 /* MAC_TODO: stipple */
3245 if (s->face->stipple) 3316 if (s->face->stipple)
3246 { 3317 {
3247 /* Fill background with a stipple pattern. */ 3318 /* Fill background with a stipple pattern. */
3250 XSetFillStyle (s->display, gc, FillSolid); 3321 XSetFillStyle (s->display, gc, FillSolid);
3251 } 3322 }
3252 else 3323 else
3253 #endif /* MAC_TODO */ 3324 #endif /* MAC_TODO */
3254 mac_erase_rectangle (s->window, gc, x, y, w, h); 3325 mac_erase_rectangle (s->window, gc, x, y, w, h);
3255
3256 mac_reset_clipping (s->display, s->window);
3257 } 3326 }
3258 } 3327 }
3259 else if (!s->background_filled_p) 3328 else if (!s->background_filled_p)
3260 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width, 3329 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
3261 s->height); 3330 s->height);
3274 3343
3275 /* If S draws into the background of its successor that does not 3344 /* If S draws into the background of its successor that does not
3276 draw a cursor, draw the background of the successor first so that 3345 draw a cursor, draw the background of the successor first so that
3277 S can draw into it. This makes S->next use XDrawString instead 3346 S can draw into it. This makes S->next use XDrawString instead
3278 of XDrawImageString. */ 3347 of XDrawImageString. */
3279 if (s->next && s->right_overhang && !s->for_overlaps_p 3348 if (s->next && s->right_overhang && !s->for_overlaps
3280 && s->next->hl != DRAW_CURSOR) 3349 && s->next->hl != DRAW_CURSOR)
3281 { 3350 {
3282 xassert (s->next->img == NULL); 3351 xassert (s->next->img == NULL);
3283 x_set_glyph_string_gc (s->next); 3352 x_set_glyph_string_gc (s->next);
3284 x_set_glyph_string_clipping (s->next); 3353 x_set_glyph_string_clipping (s->next);
3288 /* Set up S->gc, set clipping and draw S. */ 3357 /* Set up S->gc, set clipping and draw S. */
3289 x_set_glyph_string_gc (s); 3358 x_set_glyph_string_gc (s);
3290 3359
3291 /* Draw relief (if any) in advance for char/composition so that the 3360 /* Draw relief (if any) in advance for char/composition so that the
3292 glyph string can be drawn over it. */ 3361 glyph string can be drawn over it. */
3293 if (!s->for_overlaps_p 3362 if (!s->for_overlaps
3294 && s->face->box != FACE_NO_BOX 3363 && s->face->box != FACE_NO_BOX
3295 && (s->first_glyph->type == CHAR_GLYPH 3364 && (s->first_glyph->type == CHAR_GLYPH
3296 || s->first_glyph->type == COMPOSITE_GLYPH)) 3365 || s->first_glyph->type == COMPOSITE_GLYPH))
3297 3366
3298 { 3367 {
3314 case STRETCH_GLYPH: 3383 case STRETCH_GLYPH:
3315 x_draw_stretch_glyph_string (s); 3384 x_draw_stretch_glyph_string (s);
3316 break; 3385 break;
3317 3386
3318 case CHAR_GLYPH: 3387 case CHAR_GLYPH:
3319 if (s->for_overlaps_p) 3388 if (s->for_overlaps)
3320 s->background_filled_p = 1; 3389 s->background_filled_p = 1;
3321 else 3390 else
3322 x_draw_glyph_string_background (s, 0); 3391 x_draw_glyph_string_background (s, 0);
3323 x_draw_glyph_string_foreground (s); 3392 x_draw_glyph_string_foreground (s);
3324 break; 3393 break;
3325 3394
3326 case COMPOSITE_GLYPH: 3395 case COMPOSITE_GLYPH:
3327 if (s->for_overlaps_p || s->gidx > 0) 3396 if (s->for_overlaps || s->gidx > 0)
3328 s->background_filled_p = 1; 3397 s->background_filled_p = 1;
3329 else 3398 else
3330 x_draw_glyph_string_background (s, 1); 3399 x_draw_glyph_string_background (s, 1);
3331 x_draw_composite_glyph_string_foreground (s); 3400 x_draw_composite_glyph_string_foreground (s);
3332 break; 3401 break;
3333 3402
3334 default: 3403 default:
3335 abort (); 3404 abort ();
3336 } 3405 }
3337 3406
3338 if (!s->for_overlaps_p) 3407 if (!s->for_overlaps)
3339 { 3408 {
3340 /* Draw underline. */ 3409 /* Draw underline. */
3341 if (s->face->underline_p) 3410 if (s->face->underline_p)
3342 { 3411 {
3343 unsigned long h = 1; 3412 unsigned long h = 1;
3400 if (!relief_drawn_p && s->face->box != FACE_NO_BOX) 3469 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3401 x_draw_glyph_string_box (s); 3470 x_draw_glyph_string_box (s);
3402 } 3471 }
3403 3472
3404 /* Reset clipping. */ 3473 /* Reset clipping. */
3405 mac_reset_clipping (s->display, s->window); 3474 mac_reset_clip_rectangles (s->display, s->gc);
3406 } 3475 }
3407 3476
3408 /* Shift display to make room for inserted glyphs. */ 3477 /* Shift display to make room for inserted glyphs. */
3409 3478
3410 void 3479 void
4083 another motion event, so we can check again the next time it moves. */ 4152 another motion event, so we can check again the next time it moves. */
4084 4153
4085 static Point last_mouse_motion_position; 4154 static Point last_mouse_motion_position;
4086 static Lisp_Object last_mouse_motion_frame; 4155 static Lisp_Object last_mouse_motion_frame;
4087 4156
4088 static void 4157 static int
4089 note_mouse_movement (frame, pos) 4158 note_mouse_movement (frame, pos)
4090 FRAME_PTR frame; 4159 FRAME_PTR frame;
4091 Point *pos; 4160 Point *pos;
4092 { 4161 {
4093 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame); 4162 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
4114 dpyinfo->mouse_face_mouse_frame = 0; 4183 dpyinfo->mouse_face_mouse_frame = 0;
4115 if (!dpyinfo->grabbed) 4184 if (!dpyinfo->grabbed)
4116 rif->define_frame_cursor (frame, 4185 rif->define_frame_cursor (frame,
4117 frame->output_data.mac->nontext_cursor); 4186 frame->output_data.mac->nontext_cursor);
4118 } 4187 }
4188 return 1;
4119 } 4189 }
4120 /* Has the mouse moved off the glyph it was on at the last sighting? */ 4190 /* Has the mouse moved off the glyph it was on at the last sighting? */
4121 else if (pos->h < last_mouse_glyph.left 4191 if (pos->h < last_mouse_glyph.left
4122 || pos->h >= last_mouse_glyph.right 4192 || pos->h >= last_mouse_glyph.right
4123 || pos->v < last_mouse_glyph.top 4193 || pos->v < last_mouse_glyph.top
4124 || pos->v >= last_mouse_glyph.bottom) 4194 || pos->v >= last_mouse_glyph.bottom)
4125 { 4195 {
4126 frame->mouse_moved = 1; 4196 frame->mouse_moved = 1;
4127 last_mouse_scroll_bar = Qnil; 4197 last_mouse_scroll_bar = Qnil;
4128 note_mouse_highlight (frame, pos->h, pos->v); 4198 note_mouse_highlight (frame, pos->h, pos->v);
4129 } 4199 /* Remember which glyph we're now on. */
4200 remember_mouse_glyph (frame, pos->h, pos->v, &last_mouse_glyph);
4201 return 1;
4202 }
4203
4204 return 0;
4130 } 4205 }
4131 4206
4132 4207
4133 /************************************************************************ 4208 /************************************************************************
4134 Mouse Face 4209 Mouse Face
4135 ************************************************************************/ 4210 ************************************************************************/
4136
4137 static int glyph_rect P_ ((struct frame *f, int, int, Rect *));
4138
4139 4211
4140 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */ 4212 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
4141 4213
4142 static void 4214 static void
4143 redo_mouse_highlight () 4215 redo_mouse_highlight ()
4145 if (!NILP (last_mouse_motion_frame) 4217 if (!NILP (last_mouse_motion_frame)
4146 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame))) 4218 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
4147 note_mouse_highlight (XFRAME (last_mouse_motion_frame), 4219 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
4148 last_mouse_motion_position.h, 4220 last_mouse_motion_position.h,
4149 last_mouse_motion_position.v); 4221 last_mouse_motion_position.v);
4150 }
4151
4152
4153 /* Try to determine frame pixel position and size of the glyph under
4154 frame pixel coordinates X/Y on frame F . Return the position and
4155 size in *RECT. Value is non-zero if we could compute these
4156 values. */
4157
4158 static int
4159 glyph_rect (f, x, y, rect)
4160 struct frame *f;
4161 int x, y;
4162 Rect *rect;
4163 {
4164 Lisp_Object window;
4165
4166 window = window_from_coordinates (f, x, y, 0, &x, &y, 0);
4167
4168 if (!NILP (window))
4169 {
4170 struct window *w = XWINDOW (window);
4171 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
4172 struct glyph_row *end = r + w->current_matrix->nrows - 1;
4173
4174 for (; r < end && r->enabled_p; ++r)
4175 if (r->y <= y && r->y + r->height > y)
4176 {
4177 /* Found the row at y. */
4178 struct glyph *g = r->glyphs[TEXT_AREA];
4179 struct glyph *end = g + r->used[TEXT_AREA];
4180 int gx;
4181
4182 rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
4183 rect->bottom = rect->top + r->height;
4184
4185 if (x < r->x)
4186 {
4187 /* x is to the left of the first glyph in the row. */
4188 /* Shouldn't this be a pixel value?
4189 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
4190 ++KFS */
4191 rect->left = WINDOW_LEFT_EDGE_COL (w);
4192 rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x);
4193 return 1;
4194 }
4195
4196 for (gx = r->x; g < end; gx += g->pixel_width, ++g)
4197 if (gx <= x && gx + g->pixel_width > x)
4198 {
4199 /* x is on a glyph. */
4200 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
4201 rect->right = rect->left + g->pixel_width;
4202 return 1;
4203 }
4204
4205 /* x is to the right of the last glyph in the row. */
4206 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
4207 /* Shouldn't this be a pixel value?
4208 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
4209 ++KFS */
4210 rect->right = WINDOW_RIGHT_EDGE_COL (w);
4211 return 1;
4212 }
4213 }
4214
4215 /* The y is not on any row. */
4216 return 0;
4217 }
4218
4219 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
4220
4221 /* Record the position of the mouse in last_mouse_glyph. */
4222 static void
4223 remember_mouse_glyph (f1, gx, gy)
4224 struct frame * f1;
4225 int gx, gy;
4226 {
4227 if (!glyph_rect (f1, gx, gy, &last_mouse_glyph))
4228 {
4229 int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
4230 int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
4231
4232 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
4233 round down even for negative values. */
4234 if (gx < 0)
4235 gx -= width - 1;
4236 if (gy < 0)
4237 gy -= height - 1;
4238 #if 0
4239 /* This was the original code from XTmouse_position, but it seems
4240 to give the position of the glyph diagonally next to the one
4241 the mouse is over. */
4242 gx = (gx + width - 1) / width * width;
4243 gy = (gy + height - 1) / height * height;
4244 #else
4245 gx = gx / width * width;
4246 gy = gy / height * height;
4247 #endif
4248
4249 last_mouse_glyph.left = gx;
4250 last_mouse_glyph.top = gy;
4251 last_mouse_glyph.right = gx + width;
4252 last_mouse_glyph.bottom = gy + height;
4253 }
4254 } 4222 }
4255 4223
4256 4224
4257 static struct frame * 4225 static struct frame *
4258 mac_focus_frame (dpyinfo) 4226 mac_focus_frame (dpyinfo)
4267 return SELECTED_FRAME (); 4235 return SELECTED_FRAME ();
4268 } 4236 }
4269 4237
4270 4238
4271 /* Return the current position of the mouse. 4239 /* Return the current position of the mouse.
4272 *fp should be a frame which indicates which display to ask about. 4240 *FP should be a frame which indicates which display to ask about.
4273 4241
4274 If the mouse movement started in a scroll bar, set *fp, *bar_window, 4242 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
4275 and *part to the frame, window, and scroll bar part that the mouse 4243 and *PART to the frame, window, and scroll bar part that the mouse
4276 is over. Set *x and *y to the portion and whole of the mouse's 4244 is over. Set *X and *Y to the portion and whole of the mouse's
4277 position on the scroll bar. 4245 position on the scroll bar.
4278 4246
4279 If the mouse movement started elsewhere, set *fp to the frame the 4247 If the mouse movement started elsewhere, set *FP to the frame the
4280 mouse is on, *bar_window to nil, and *x and *y to the character cell 4248 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
4281 the mouse is over. 4249 the mouse is over.
4282 4250
4283 Set *time to the server time-stamp for the time at which the mouse 4251 Set *TIME to the server time-stamp for the time at which the mouse
4284 was at this position. 4252 was at this position.
4285 4253
4286 Don't store anything if we don't have a valid set of values to report. 4254 Don't store anything if we don't have a valid set of values to report.
4287 4255
4288 This clears the mouse_moved flag, so we can wait for the next mouse 4256 This clears the mouse_moved flag, so we can wait for the next mouse
4295 Lisp_Object *bar_window; 4263 Lisp_Object *bar_window;
4296 enum scroll_bar_part *part; 4264 enum scroll_bar_part *part;
4297 Lisp_Object *x, *y; 4265 Lisp_Object *x, *y;
4298 unsigned long *time; 4266 unsigned long *time;
4299 { 4267 {
4300 Point mouse_pos; 4268 FRAME_PTR f1;
4301 int ignore1, ignore2;
4302 struct frame *f = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp));
4303 WindowPtr wp = FRAME_MAC_WINDOW (f);
4304 Lisp_Object frame, tail;
4305 4269
4306 BLOCK_INPUT; 4270 BLOCK_INPUT;
4307 4271
4308 if (! NILP (last_mouse_scroll_bar) && insist == 0) 4272 if (! NILP (last_mouse_scroll_bar) && insist == 0)
4309 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); 4273 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
4310 else 4274 else
4311 { 4275 {
4276 Lisp_Object frame, tail;
4277
4312 /* Clear the mouse-moved flag for every frame on this display. */ 4278 /* Clear the mouse-moved flag for every frame on this display. */
4313 FOR_EACH_FRAME (tail, frame) 4279 FOR_EACH_FRAME (tail, frame)
4314 XFRAME (frame)->mouse_moved = 0; 4280 XFRAME (frame)->mouse_moved = 0;
4315 4281
4316 last_mouse_scroll_bar = Qnil; 4282 last_mouse_scroll_bar = Qnil;
4317 4283
4318 SetPortWindowPort (wp); 4284 if (FRAME_MAC_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
4319 4285 && FRAME_LIVE_P (last_mouse_frame))
4320 GetMouse (&mouse_pos); 4286 f1 = last_mouse_frame;
4321 4287 else
4322 pixel_to_glyph_coords (f, mouse_pos.h, mouse_pos.v, &ignore1, &ignore2, 4288 f1 = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp));
4323 &last_mouse_glyph, insist); 4289
4324 4290 if (f1)
4325 *bar_window = Qnil; 4291 {
4326 *part = scroll_bar_handle; 4292 /* Ok, we found a frame. Store all the values.
4327 *fp = f; 4293 last_mouse_glyph is a rectangle used to reduce the
4328 XSETINT (*x, mouse_pos.h); 4294 generation of mouse events. To not miss any motion
4329 XSETINT (*y, mouse_pos.v); 4295 events, we must divide the frame into rectangles of the
4330 *time = last_mouse_movement_time; 4296 size of the smallest character that could be displayed
4297 on it, i.e. into the same rectangles that matrices on
4298 the frame are divided into. */
4299 Point mouse_pos;
4300
4301 SetPortWindowPort (FRAME_MAC_WINDOW (f1));
4302 GetMouse (&mouse_pos);
4303 remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v,
4304 &last_mouse_glyph);
4305
4306 *bar_window = Qnil;
4307 *part = 0;
4308 *fp = f1;
4309 XSETINT (*x, mouse_pos.h);
4310 XSETINT (*y, mouse_pos.v);
4311 *time = last_mouse_movement_time;
4312 }
4331 } 4313 }
4332 4314
4333 UNBLOCK_INPUT; 4315 UNBLOCK_INPUT;
4334 } 4316 }
4335 4317
5273 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); 5255 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
5274 clip_rect.top = max (clip_rect.top, window_y); 5256 clip_rect.top = max (clip_rect.top, window_y);
5275 clip_rect.right = clip_rect.left + window_width; 5257 clip_rect.right = clip_rect.left + window_width;
5276 clip_rect.bottom = clip_rect.top + row->visible_height; 5258 clip_rect.bottom = clip_rect.top + row->visible_height;
5277 5259
5278 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), &clip_rect); 5260 mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f), gc, &clip_rect, 1);
5279 } 5261 }
5280 5262
5281 5263
5282 /* Draw a hollow box cursor on window W in glyph row ROW. */ 5264 /* Draw a hollow box cursor on window W in glyph row ROW. */
5283 5265
5316 gc = dpyinfo->scratch_cursor_gc; 5298 gc = dpyinfo->scratch_cursor_gc;
5317 5299
5318 /* Set clipping, draw the rectangle, and reset clipping again. */ 5300 /* Set clipping, draw the rectangle, and reset clipping again. */
5319 x_clip_to_row (w, row, TEXT_AREA, gc); 5301 x_clip_to_row (w, row, TEXT_AREA, gc);
5320 mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h); 5302 mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h);
5321 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); 5303 mac_reset_clip_rectangles (dpy, gc);
5322 } 5304 }
5323 5305
5324 5306
5325 /* Draw a bar cursor on window W in glyph row ROW. 5307 /* Draw a bar cursor on window W in glyph row ROW.
5326 5308
5400 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y + 5382 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
5401 row->height - width), 5383 row->height - width),
5402 cursor_glyph->pixel_width, 5384 cursor_glyph->pixel_width,
5403 width); 5385 width);
5404 5386
5405 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); 5387 mac_reset_clip_rectangles (dpy, gc);
5406 } 5388 }
5407 } 5389 }
5408 5390
5409 5391
5410 /* RIF: Define cursor CURSOR on frame F. */ 5392 /* RIF: Define cursor CURSOR on frame F. */
6775 /* the global font name table */ 6757 /* the global font name table */
6776 static char **font_name_table = NULL; 6758 static char **font_name_table = NULL;
6777 static int font_name_table_size = 0; 6759 static int font_name_table_size = 0;
6778 static int font_name_count = 0; 6760 static int font_name_count = 0;
6779 6761
6762 /* Alist linking font family names to Font Manager font family
6763 references (which can also be used as QuickDraw font IDs). We use
6764 an alist because hash tables are not ready when the terminal frame
6765 for Mac OS Classic is created. */
6766 static Lisp_Object fm_font_family_alist;
6780 #if USE_ATSUI 6767 #if USE_ATSUI
6768 /* Hash table linking font family names to ATSU font IDs. */
6781 static Lisp_Object atsu_font_id_hash; 6769 static Lisp_Object atsu_font_id_hash;
6782 #endif 6770 #endif
6783 6771
6784 /* Alist linking character set strings to Mac text encoding and Emacs 6772 /* Alist linking character set strings to Mac text encoding and Emacs
6785 coding system. */ 6773 coding system. */
6825 Lisp_Object coding_system; 6813 Lisp_Object coding_system;
6826 { 6814 {
6827 struct coding_system coding; 6815 struct coding_system coding;
6828 char *buf, *p; 6816 char *buf, *p;
6829 6817
6818 if (!NILP (coding_system) && !NILP (Fcoding_system_p (coding_system)))
6819 {
6820 for (p = name; *p; p++)
6821 if (!isascii (*p) || iscntrl (*p))
6822 break;
6823
6824 if (*p)
6825 {
6826 #if 0
6827 /* MAC_TODO: Fix encoding system... */
6828 setup_coding_system (coding_system, &coding);
6829 coding.src_multibyte = 0;
6830 coding.dst_multibyte = 1;
6831 coding.mode |= CODING_MODE_LAST_BLOCK;
6832 coding.composing = COMPOSITION_DISABLED;
6833 buf = (char *) alloca (size);
6834
6835 decode_coding (&coding, name, buf, strlen (name), size - 1);
6836 bcopy (buf, name, coding.produced);
6837 name[coding.produced] = '\0';
6838 #endif
6839 }
6840 }
6841
6842 /* If there's just one occurrence of '-' in the family name, it is
6843 replaced with '_'. (More than one occurrence of '-' means a
6844 "FOUNDRY-FAMILY-CHARSET"-style name.) */
6845 p = strchr (name, '-');
6846 if (p && strchr (p + 1, '-') == NULL)
6847 *p = '_';
6848
6830 for (p = name; *p; p++) 6849 for (p = name; *p; p++)
6831 if (!isascii (*p) || iscntrl (*p)) 6850 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6832 break; 6851 for some locales. */
6833 6852 if (isascii (*p))
6834 if (*p == '\0' 6853 *p = tolower (*p);
6835 || NILP (coding_system) || NILP (Fcoding_system_p (coding_system)))
6836 return;
6837
6838 #if 0
6839 /* MAC_TODO: Fix encoding system... */
6840 setup_coding_system (coding_system, &coding);
6841 coding.src_multibyte = 0;
6842 coding.dst_multibyte = 1;
6843 coding.mode |= CODING_MODE_LAST_BLOCK;
6844 coding.dst_bytes = MAX_MULTsize;
6845 coding.destination = (char *) alloca (size);
6846 coding_decode_c_string(&coding, name, strlen(name), qNil);
6847
6848 decode_coding (&coding, name, buf, strlen (name), size - 1);
6849 bcopy (buf, name, coding.produced);
6850 name[coding.produced] = '\0';
6851 #endif
6852 } 6854 }
6853 6855
6854 6856
6855 static char * 6857 static char *
6856 mac_to_x_fontname (name, size, style, charset) 6858 mac_to_x_fontname (name, size, style, charset)
6885 *p = tolower (*p); 6887 *p = tolower (*p);
6886 return result; 6888 return result;
6887 } 6889 }
6888 6890
6889 6891
6890 /* Convert an X font spec to the corresponding mac font name, which 6892 /* Parse fully-specified and instantiated X11 font spec XF, and store
6891 can then be passed to GetFNum after conversion to a Pascal string. 6893 the results to FAMILY, *SIZE, *STYLE, and CHARSET. Return 1 if the
6892 For ordinary Mac fonts, this should just be their names, like 6894 parsing succeeded, and 0 otherwise. For FAMILY and CHARSET, the
6893 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts 6895 caller must allocate at least 256 and 32 bytes respectively. For
6894 collection contain their charset designation in their names, like 6896 ordinary Mac fonts, the value stored to FAMILY should just be their
6895 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font 6897 names, like "monaco", "Taipei", etc. Fonts converted from the GNU
6896 names are handled accordingly. */ 6898 intlfonts collection contain their charset designation in their
6897 static void 6899 names, like "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both
6898 x_font_name_to_mac_font_name (xf, mf, mf_decoded, style, cs) 6900 types of font names are handled accordingly. */
6899 char *xf, *mf, *mf_decoded; 6901
6902 const int kDefaultFontSize = 12;
6903
6904 static int
6905 parse_x_font_name (xf, family, size, style, charset)
6906 char *xf, *family;
6907 int *size;
6900 Style *style; 6908 Style *style;
6901 char *cs; 6909 char *charset;
6902 { 6910 {
6903 Str31 foundry; 6911 Str31 foundry, weight;
6904 Str255 family; 6912 int point_size, avgwidth;
6905 char weight[20], slant[2], *p; 6913 char slant[2], *p;
6906 Lisp_Object charset_info, coding_system = Qnil; 6914
6907 struct coding_system coding; 6915 if (sscanf (xf, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]-%*[^-]-%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
6908 6916 foundry, family, weight, slant, size,
6909 strcpy (mf, ""); 6917 &point_size, &avgwidth, charset) != 8
6910 6918 && sscanf (xf, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
6911 if (sscanf (xf, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", 6919 foundry, family, weight, slant, size,
6912 foundry, family, weight, slant, cs) != 5 && 6920 &point_size, &avgwidth, charset) != 8)
6913 sscanf (xf, "-%31[^-]-%255[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", 6921 return 0;
6914 foundry, family, weight, slant, cs) != 5) 6922
6915 return; 6923 if (*size == 0)
6924 {
6925 if (point_size > 0)
6926 *size = point_size / 10;
6927 else if (avgwidth > 0)
6928 *size = avgwidth / 10;
6929 }
6930 if (*size == 0)
6931 *size = kDefaultFontSize;
6916 6932
6917 *style = normal; 6933 *style = normal;
6918 if (strcmp (weight, "bold") == 0) 6934 if (strcmp (weight, "bold") == 0)
6919 *style |= bold; 6935 *style |= bold;
6920 if (*slant == 'i') 6936 if (*slant == 'i')
6921 *style |= italic; 6937 *style |= italic;
6922 6938
6923 charset_info = Fassoc (build_string (cs), Vmac_charset_info_alist); 6939 if (NILP (Fassoc (build_string (charset), Vmac_charset_info_alist)))
6924 if (!NILP (charset_info)) 6940 {
6925 { 6941 int foundry_len = strlen (foundry), family_len = strlen (family);
6926 strcpy (mf_decoded, family); 6942
6927 coding_system = Fcar (Fcdr (Fcdr (charset_info))); 6943 if (foundry_len + family_len + strlen (charset) + 2 < sizeof (Str255))
6928 } 6944 {
6929 else 6945 /* Like sprintf (family, "%s-%s-%s", foundry, family, charset),
6930 sprintf (mf_decoded, "%s-%s-%s", foundry, family, cs); 6946 but take overlap into account. */
6931 6947 memmove (family + foundry_len + 1, family, family_len);
6932 for (p = mf_decoded; *p; p++) 6948 memcpy (family, foundry, foundry_len);
6933 if (!isascii (*p) || iscntrl (*p)) 6949 family[foundry_len] = '-';
6934 break; 6950 family[foundry_len + 1 + family_len] = '-';
6935 6951 strcpy (family + foundry_len + 1 + family_len + 1, charset);
6936 if (*p == '\0' 6952 }
6937 || NILP (coding_system) || NILP (Fcoding_system_p (coding_system))) 6953 else
6938 strcpy (mf, mf_decoded); 6954 return 0;
6939 #if 0 6955 }
6940 /* MAC_TODO: Fix coding system to use objects */ 6956
6941 else 6957 for (p = family; *p; p++)
6942 { 6958 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6943 setup_coding_system (coding_system, &coding); 6959 for some locales. */
6944 coding.src_multibyte = 1; 6960 if (isascii (*p))
6945 coding.dst_multibyte = 0; 6961 *p = tolower (*p);
6946 coding.mode |= CODING_MODE_LAST_BLOCK; 6962
6947 encode_coding (&coding, mf_decoded, mf, 6963 return 1;
6948 strlen (mf_decoded), sizeof (Str255) - 1);
6949 mf[coding.produced] = '\0';
6950 }
6951 #endif
6952 } 6964 }
6953 6965
6954 6966
6955 static void 6967 static void
6956 add_font_name_table_entry (char *font_name) 6968 add_font_name_table_entry (char *font_name)
7023 name[name_len] = '\0'; 7035 name[name_len] = '\0';
7024 err = ATSUFindFontName (font_ids[i], kFontFamilyName, 7036 err = ATSUFindFontName (font_ids[i], kFontFamilyName,
7025 kFontMacintoshPlatform, kFontNoScript, 7037 kFontMacintoshPlatform, kFontNoScript,
7026 kFontNoLanguage, name_len, name, 7038 kFontNoLanguage, name_len, name,
7027 NULL, NULL); 7039 NULL, NULL);
7040 if (err == noErr)
7041 decode_mac_font_name (name, name_len + 1, Qnil);
7028 if (err == noErr 7042 if (err == noErr
7029 && *name != '.' 7043 && *name != '.'
7030 && (prev_name == NULL 7044 && (prev_name == NULL
7031 || strcmp (name, prev_name) != 0)) 7045 || strcmp (name, prev_name) != 0))
7032 { 7046 {
7038 italic, cs)); 7052 italic, cs));
7039 add_font_name_table_entry (mac_to_x_fontname (name, 0, 7053 add_font_name_table_entry (mac_to_x_fontname (name, 0,
7040 bold, cs)); 7054 bold, cs));
7041 add_font_name_table_entry (mac_to_x_fontname (name, 0, 7055 add_font_name_table_entry (mac_to_x_fontname (name, 0,
7042 italic | bold, cs)); 7056 italic | bold, cs));
7043 Fputhash (Fdowncase (make_unibyte_string (name, name_len)), 7057 Fputhash (make_unibyte_string (name, name_len),
7044 long_to_cons (font_ids[i]), atsu_font_id_hash); 7058 long_to_cons (font_ids[i]), atsu_font_id_hash);
7045 xfree (prev_name); 7059 xfree (prev_name);
7046 prev_name = name; 7060 prev_name = name;
7047 } 7061 }
7048 else 7062 else
7088 if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr) 7102 if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr)
7089 break; 7103 break;
7090 sc = GetTextEncodingBase (encoding); 7104 sc = GetTextEncodingBase (encoding);
7091 text_encoding_info = assq_no_quit (make_number (sc), 7105 text_encoding_info = assq_no_quit (make_number (sc),
7092 text_encoding_info_alist); 7106 text_encoding_info_alist);
7093 if (!NILP (text_encoding_info)) 7107 if (NILP (text_encoding_info))
7094 decode_mac_font_name (name, sizeof (name),
7095 XCAR (XCDR (text_encoding_info)));
7096 else
7097 text_encoding_info = assq_no_quit (make_number (kTextEncodingMacRoman), 7108 text_encoding_info = assq_no_quit (make_number (kTextEncodingMacRoman),
7098 text_encoding_info_alist); 7109 text_encoding_info_alist);
7110 decode_mac_font_name (name, sizeof (name),
7111 XCAR (XCDR (text_encoding_info)));
7112 fm_font_family_alist = Fcons (Fcons (build_string (name),
7113 make_number (ff)),
7114 fm_font_family_alist);
7099 7115
7100 /* Point the instance iterator at the current font family. */ 7116 /* Point the instance iterator at the current font family. */
7101 if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr) 7117 if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
7102 break; 7118 break;
7103 7119
7172 7188
7173 TextFont (fontnum); 7189 TextFont (fontnum);
7174 scriptcode = FontToScript (fontnum); 7190 scriptcode = FontToScript (fontnum);
7175 text_encoding_info = assq_no_quit (make_number (scriptcode), 7191 text_encoding_info = assq_no_quit (make_number (scriptcode),
7176 text_encoding_info_alist); 7192 text_encoding_info_alist);
7177 if (!NILP (text_encoding_info)) 7193 if (NILP (text_encoding_info))
7178 decode_mac_font_name (name, sizeof (name),
7179 XCAR (XCDR (text_encoding_info)));
7180 else
7181 text_encoding_info = assq_no_quit (make_number (smRoman), 7194 text_encoding_info = assq_no_quit (make_number (smRoman),
7182 text_encoding_info_alist); 7195 text_encoding_info_alist);
7196 decode_mac_font_name (name, sizeof (name),
7197 XCAR (XCDR (text_encoding_info)));
7198 fm_font_family_alist = Fcons (Fcons (build_string (name),
7199 make_number (fontnum)),
7200 fm_font_family_alist);
7183 do 7201 do
7184 { 7202 {
7185 HLock (font_handle); 7203 HLock (font_handle);
7186 7204
7187 if (GetResourceSizeOnDisk (font_handle) 7205 if (GetResourceSizeOnDisk (font_handle)
7233 for (i = 0; i < font_name_count; i++) 7251 for (i = 0; i < font_name_count; i++)
7234 xfree (font_name_table[i]); 7252 xfree (font_name_table[i]);
7235 xfree (font_name_table); 7253 xfree (font_name_table);
7236 font_name_table = NULL; 7254 font_name_table = NULL;
7237 font_name_table_size = font_name_count = 0; 7255 font_name_table_size = font_name_count = 0;
7256 fm_font_family_alist = Qnil;
7238 } 7257 }
7239 7258
7240 7259
7241 enum xlfd_scalable_field_index 7260 enum xlfd_scalable_field_index
7242 { 7261 {
7541 7560
7542 return 1; 7561 return 1;
7543 } 7562 }
7544 7563
7545 7564
7546 const int kDefaultFontSize = 12;
7547
7548
7549 /* XLoadQueryFont creates and returns an internal representation for a 7565 /* XLoadQueryFont creates and returns an internal representation for a
7550 font in a MacFontStruct struct. There is really no concept 7566 font in a MacFontStruct struct. There is really no concept
7551 corresponding to "loading" a font on the Mac. But we check its 7567 corresponding to "loading" a font on the Mac. But we check its
7552 existence and find the font number and all other information for it 7568 existence and find the font number and all other information for it
7553 and store them in the returned MacFontStruct. */ 7569 and store them in the returned MacFontStruct. */
7554 7570
7555 static MacFontStruct * 7571 static MacFontStruct *
7556 XLoadQueryFont (Display *dpy, char *fontname) 7572 XLoadQueryFont (Display *dpy, char *fontname)
7557 { 7573 {
7558 int i, size, point_size, avgwidth, is_two_byte_font, char_width; 7574 int i, size, char_width;
7559 char *name; 7575 char *name;
7560 GrafPtr port; 7576 Str255 family;
7561 SInt16 old_fontnum, old_fontsize;
7562 Style old_fontface;
7563 Str255 mfontname, mfontname_decoded;
7564 Str31 charset; 7577 Str31 charset;
7565 SInt16 fontnum; 7578 SInt16 fontnum;
7566 #if USE_ATSUI 7579 #if USE_ATSUI
7567 ATSUStyle mac_style = NULL; 7580 ATSUStyle mac_style = NULL;
7568 #endif 7581 #endif
7572 int scriptcode; 7585 int scriptcode;
7573 #else 7586 #else
7574 short scriptcode; 7587 short scriptcode;
7575 #endif 7588 #endif
7576 MacFontStruct *font; 7589 MacFontStruct *font;
7577 FontInfo the_fontinfo;
7578 #ifdef MAC_OSX
7579 UInt32 old_flags, new_flags;
7580 #endif
7581 7590
7582 if (is_fully_specified_xlfd (fontname)) 7591 if (is_fully_specified_xlfd (fontname))
7583 name = fontname; 7592 name = fontname;
7584 else 7593 else
7585 { 7594 {
7589 if (NILP (matched_fonts)) 7598 if (NILP (matched_fonts))
7590 return NULL; 7599 return NULL;
7591 name = SDATA (XCAR (matched_fonts)); 7600 name = SDATA (XCAR (matched_fonts));
7592 } 7601 }
7593 7602
7594 GetPort (&port); /* save the current font number used */ 7603 if (parse_x_font_name (name, family, &size, &fontface, charset) == 0)
7595 #if TARGET_API_MAC_CARBON 7604 return NULL;
7596 old_fontnum = GetPortTextFont (port); 7605
7597 old_fontsize = GetPortTextSize (port);
7598 old_fontface = GetPortTextFace (port);
7599 #else
7600 old_fontnum = port->txFont;
7601 old_fontsize = port->txSize;
7602 old_fontface = port->txFace;
7603 #endif
7604
7605 if (sscanf (name, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%*s", &size, &point_size, &avgwidth) != 3)
7606 size = 0;
7607 else
7608 {
7609 if (size == 0)
7610 if (point_size > 0)
7611 size = point_size / 10;
7612 else if (avgwidth > 0)
7613 size = avgwidth / 10;
7614 }
7615 if (size == 0)
7616 size = kDefaultFontSize;
7617
7618 x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded,
7619 &fontface, charset);
7620 #if USE_ATSUI 7606 #if USE_ATSUI
7621 if (strcmp (charset, "iso10646-1") == 0) /* XXX */ 7607 if (strcmp (charset, "iso10646-1") == 0) /* XXX */
7622 { 7608 {
7623 OSErr err; 7609 OSErr err;
7624 ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag, 7610 ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag,
7631 ATSUAttributeValuePtr values[] = {&font_id, &size_fixed, 7617 ATSUAttributeValuePtr values[] = {&font_id, &size_fixed,
7632 &bold_p, &italic_p}; 7618 &bold_p, &italic_p};
7633 ATSUFontFeatureType types[] = {kAllTypographicFeaturesType}; 7619 ATSUFontFeatureType types[] = {kAllTypographicFeaturesType};
7634 ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector}; 7620 ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector};
7635 Lisp_Object font_id_cons; 7621 Lisp_Object font_id_cons;
7636 7622
7637 font_id_cons = Fgethash (Fdowncase 7623 font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)),
7638 (make_unibyte_string (mfontname,
7639 strlen (mfontname))),
7640 atsu_font_id_hash, Qnil); 7624 atsu_font_id_hash, Qnil);
7641 if (NILP (font_id_cons)) 7625 if (NILP (font_id_cons))
7642 return NULL; 7626 return NULL;
7643 font_id = cons_to_long (font_id_cons); 7627 font_id = cons_to_long (font_id_cons);
7644 size_fixed = Long2Fix (size); 7628 size_fixed = Long2Fix (size);
7655 tags, sizes, values); 7639 tags, sizes, values);
7656 fontnum = -1; 7640 fontnum = -1;
7657 scriptcode = kTextEncodingMacUnicode; 7641 scriptcode = kTextEncodingMacUnicode;
7658 } 7642 }
7659 else 7643 else
7660 { 7644 #endif
7661 #endif 7645 {
7662 c2pstr (mfontname); 7646 Lisp_Object tmp = Fassoc (build_string (family), fm_font_family_alist);
7647
7648 if (NILP (tmp))
7649 return NULL;
7650 fontnum = XINT (XCDR (tmp));
7663 #if TARGET_API_MAC_CARBON 7651 #if TARGET_API_MAC_CARBON
7664 fontnum = FMGetFontFamilyFromName (mfontname); 7652 if (FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr)
7665 if (fontnum == kInvalidFontFamily 7653 return NULL;
7666 || FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr) 7654 scriptcode = GetTextEncodingBase (encoding);
7667 return NULL;
7668 scriptcode = GetTextEncodingBase (encoding);
7669 #else 7655 #else
7670 GetFNum (mfontname, &fontnum); 7656 scriptcode = FontToScript (fontnum);
7671 if (fontnum == 0) 7657 #endif
7672 return NULL; 7658 }
7673 scriptcode = FontToScript (fontnum);
7674 #endif
7675 #if USE_ATSUI
7676 }
7677 #endif
7678 7659
7679 font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct)); 7660 font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct));
7680 7661
7681 font->mac_fontnum = fontnum; 7662 font->mac_fontnum = fontnum;
7682 font->mac_fontsize = size; 7663 font->mac_fontsize = size;
7691 (Roman script) in init_font_name_table (). The latter should be 7672 (Roman script) in init_font_name_table (). The latter should be
7692 treated as a one-byte font. */ 7673 treated as a one-byte font. */
7693 if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0) 7674 if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0)
7694 font->mac_scriptcode = smRoman; 7675 font->mac_scriptcode = smRoman;
7695 7676
7696 font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset); 7677 font->full_name = mac_to_x_fontname (family, size, fontface, charset);
7697 7678
7698 #if USE_ATSUI 7679 #if USE_ATSUI
7699 if (font->mac_style) 7680 if (font->mac_style)
7700 { 7681 {
7701 OSErr err; 7682 OSErr err;
7776 font->max_byte1 = 0xff; 7757 font->max_byte1 = 0xff;
7777 font->min_char_or_byte2 = 0; 7758 font->min_char_or_byte2 = 0;
7778 font->max_char_or_byte2 = 0xff; 7759 font->max_char_or_byte2 = 0xff;
7779 } 7760 }
7780 else 7761 else
7781 { 7762 #endif
7782 #endif 7763 {
7783 is_two_byte_font = font->mac_scriptcode == smJapanese || 7764 GrafPtr port;
7784 font->mac_scriptcode == smTradChinese || 7765 SInt16 old_fontnum, old_fontsize;
7785 font->mac_scriptcode == smSimpChinese || 7766 Style old_fontface;
7786 font->mac_scriptcode == smKorean; 7767 FontInfo the_fontinfo;
7787 7768 int is_two_byte_font;
7788 TextFont (fontnum); 7769
7789 TextSize (size); 7770 /* Save the current font number used. */
7790 TextFace (fontface); 7771 GetPort (&port);
7791 7772 #if TARGET_API_MAC_CARBON
7792 GetFontInfo (&the_fontinfo); 7773 old_fontnum = GetPortTextFont (port);
7793 7774 old_fontsize = GetPortTextSize (port);
7794 font->ascent = the_fontinfo.ascent; 7775 old_fontface = GetPortTextFace (port);
7795 font->descent = the_fontinfo.descent; 7776 #else
7796 7777 old_fontnum = port->txFont;
7797 if (is_two_byte_font) 7778 old_fontsize = port->txSize;
7798 { 7779 old_fontface = port->txFace;
7799 font->min_byte1 = 0xa1; 7780 #endif
7800 font->max_byte1 = 0xfe; 7781
7801 font->min_char_or_byte2 = 0xa1; 7782 TextFont (fontnum);
7802 font->max_char_or_byte2 = 0xfe; 7783 TextSize (size);
7803 7784 TextFace (fontface);
7804 /* Use the width of an "ideographic space" of that font because 7785
7805 the_fontinfo.widMax returns the wrong width for some fonts. */ 7786 GetFontInfo (&the_fontinfo);
7806 switch (font->mac_scriptcode) 7787
7807 { 7788 font->ascent = the_fontinfo.ascent;
7808 case smJapanese: 7789 font->descent = the_fontinfo.descent;
7809 font->min_byte1 = 0x81; 7790
7810 font->max_byte1 = 0xfc; 7791 is_two_byte_font = (font->mac_scriptcode == smJapanese
7811 font->min_char_or_byte2 = 0x40; 7792 || font->mac_scriptcode == smTradChinese
7812 font->max_char_or_byte2 = 0xfc; 7793 || font->mac_scriptcode == smSimpChinese
7813 char_width = StringWidth("\p\x81\x40"); 7794 || font->mac_scriptcode == smKorean);
7814 break; 7795
7815 case smTradChinese: 7796 if (is_two_byte_font)
7816 font->min_char_or_byte2 = 0x40;
7817 char_width = StringWidth("\p\xa1\x40");
7818 break;
7819 case smSimpChinese:
7820 char_width = StringWidth("\p\xa1\xa1");
7821 break;
7822 case smKorean:
7823 char_width = StringWidth("\p\xa1\xa1");
7824 break;
7825 }
7826 }
7827 else
7828 {
7829 font->min_byte1 = font->max_byte1 = 0;
7830 font->min_char_or_byte2 = 0x20;
7831 font->max_char_or_byte2 = 0xff;
7832
7833 /* Do this instead of use the_fontinfo.widMax, which incorrectly
7834 returns 15 for 12-point Monaco! */
7835 char_width = CharWidth ('m');
7836 }
7837
7838 if (is_two_byte_font)
7839 {
7840 font->per_char = NULL;
7841
7842 if (fontface & italic)
7843 font->max_bounds.rbearing = char_width + 1;
7844 else
7845 font->max_bounds.rbearing = char_width;
7846 font->max_bounds.lbearing = 0;
7847 font->max_bounds.width = char_width;
7848 font->max_bounds.ascent = the_fontinfo.ascent;
7849 font->max_bounds.descent = the_fontinfo.descent;
7850
7851 font->min_bounds = font->max_bounds;
7852 }
7853 else
7854 {
7855 int c, min_width, max_width;
7856 Rect char_bounds, min_bounds, max_bounds;
7857 char ch;
7858
7859 font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7860
7861 min_width = max_width = char_width;
7862 SetRect (&min_bounds, -32767, -32767, 32767, 32767);
7863 SetRect (&max_bounds, 0, 0, 0, 0);
7864 for (c = 0x20; c <= 0xff; c++)
7865 { 7797 {
7866 ch = c; 7798 font->min_byte1 = 0xa1;
7867 char_width = CharWidth (ch); 7799 font->max_byte1 = 0xfe;
7868 QDTextBounds (1, &ch, &char_bounds); 7800 font->min_char_or_byte2 = 0xa1;
7869 STORE_XCHARSTRUCT (font->per_char[c - 0x20], 7801 font->max_char_or_byte2 = 0xfe;
7870 char_width, char_bounds); 7802
7871 /* Some Japanese fonts (in SJIS encoding) return 0 as the 7803 /* Use the width of an "ideographic space" of that font
7872 character width of 0x7f. */ 7804 because the_fontinfo.widMax returns the wrong width for
7873 if (char_width > 0) 7805 some fonts. */
7806 switch (font->mac_scriptcode)
7874 { 7807 {
7875 min_width = min (min_width, char_width); 7808 case smJapanese:
7876 max_width = max (max_width, char_width); 7809 font->min_byte1 = 0x81;
7877 } 7810 font->max_byte1 = 0xfc;
7878 if (!EmptyRect (&char_bounds)) 7811 font->min_char_or_byte2 = 0x40;
7879 { 7812 font->max_char_or_byte2 = 0xfc;
7880 SetRect (&min_bounds, 7813 char_width = StringWidth("\p\x81\x40");
7881 max (min_bounds.left, char_bounds.left), 7814 break;
7882 max (min_bounds.top, char_bounds.top), 7815 case smTradChinese:
7883 min (min_bounds.right, char_bounds.right), 7816 font->min_char_or_byte2 = 0x40;
7884 min (min_bounds.bottom, char_bounds.bottom)); 7817 char_width = StringWidth("\p\xa1\x40");
7885 UnionRect (&max_bounds, &char_bounds, &max_bounds); 7818 break;
7819 case smSimpChinese:
7820 char_width = StringWidth("\p\xa1\xa1");
7821 break;
7822 case smKorean:
7823 char_width = StringWidth("\p\xa1\xa1");
7824 break;
7886 } 7825 }
7887 } 7826 }
7888 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); 7827 else
7889 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7890 if (min_width == max_width
7891 && max_bounds.left >= 0 && max_bounds.right <= max_width)
7892 { 7828 {
7893 /* Fixed width and no overhangs. */ 7829 font->min_byte1 = font->max_byte1 = 0;
7894 xfree (font->per_char); 7830 font->min_char_or_byte2 = 0x20;
7831 font->max_char_or_byte2 = 0xff;
7832
7833 /* Do this instead of use the_fontinfo.widMax, which
7834 incorrectly returns 15 for 12-point Monaco! */
7835 char_width = CharWidth ('m');
7836 }
7837
7838 if (is_two_byte_font)
7839 {
7895 font->per_char = NULL; 7840 font->per_char = NULL;
7841
7842 if (fontface & italic)
7843 font->max_bounds.rbearing = char_width + 1;
7844 else
7845 font->max_bounds.rbearing = char_width;
7846 font->max_bounds.lbearing = 0;
7847 font->max_bounds.width = char_width;
7848 font->max_bounds.ascent = the_fontinfo.ascent;
7849 font->max_bounds.descent = the_fontinfo.descent;
7850
7851 font->min_bounds = font->max_bounds;
7896 } 7852 }
7897 } 7853 else
7898 7854 {
7899 TextFont (old_fontnum); /* restore previous font number, size and face */ 7855 int c, min_width, max_width;
7900 TextSize (old_fontsize); 7856 Rect char_bounds, min_bounds, max_bounds;
7901 TextFace (old_fontface); 7857 char ch;
7902 #if USE_ATSUI 7858
7903 } 7859 font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7904 #endif 7860 bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1));
7861
7862 min_width = max_width = char_width;
7863 SetRect (&min_bounds, -32767, -32767, 32767, 32767);
7864 SetRect (&max_bounds, 0, 0, 0, 0);
7865 for (c = 0x20; c <= 0xff; c++)
7866 {
7867 ch = c;
7868 char_width = CharWidth (ch);
7869 QDTextBounds (1, &ch, &char_bounds);
7870 STORE_XCHARSTRUCT (font->per_char[c - 0x20],
7871 char_width, char_bounds);
7872 /* Some Japanese fonts (in SJIS encoding) return 0 as
7873 the character width of 0x7f. */
7874 if (char_width > 0)
7875 {
7876 min_width = min (min_width, char_width);
7877 max_width = max (max_width, char_width);
7878 }
7879 if (!EmptyRect (&char_bounds))
7880 {
7881 SetRect (&min_bounds,
7882 max (min_bounds.left, char_bounds.left),
7883 max (min_bounds.top, char_bounds.top),
7884 min (min_bounds.right, char_bounds.right),
7885 min (min_bounds.bottom, char_bounds.bottom));
7886 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7887 }
7888 }
7889 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7890 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7891 if (min_width == max_width
7892 && max_bounds.left >= 0 && max_bounds.right <= max_width)
7893 {
7894 /* Fixed width and no overhangs. */
7895 xfree (font->per_char);
7896 font->per_char = NULL;
7897 }
7898 }
7899
7900 /* Restore previous font number, size and face. */
7901 TextFont (old_fontnum);
7902 TextSize (old_fontsize);
7903 TextFace (old_fontface);
7904 }
7905 7905
7906 return font; 7906 return font;
7907 } 7907 }
7908 7908
7909 7909
10054 #if !USE_CARBON_EVENTS 10054 #if !USE_CARBON_EVENTS
10055 SetRectRgn (mouse_region, er.where.h, er.where.v, 10055 SetRectRgn (mouse_region, er.where.h, er.where.v,
10056 er.where.h + 1, er.where.v + 1); 10056 er.where.h + 1, er.where.v + 1);
10057 #endif 10057 #endif
10058 previous_help_echo_string = help_echo_string; 10058 previous_help_echo_string = help_echo_string;
10059 help_echo_string = help_echo_object = help_echo_window = Qnil; 10059 help_echo_string = Qnil;
10060 help_echo_pos = -1;
10061 10060
10062 if (dpyinfo->grabbed && last_mouse_frame 10061 if (dpyinfo->grabbed && last_mouse_frame
10063 && FRAME_LIVE_P (last_mouse_frame)) 10062 && FRAME_LIVE_P (last_mouse_frame))
10064 f = last_mouse_frame; 10063 f = last_mouse_frame;
10065 else 10064 else
10114 inev.frame_or_window = window; 10113 inev.frame_or_window = window;
10115 } 10114 }
10116 10115
10117 last_window=window; 10116 last_window=window;
10118 } 10117 }
10119 note_mouse_movement (f, &mouse_pos); 10118 if (!note_mouse_movement (f, &mouse_pos))
10119 help_echo_string = previous_help_echo_string;
10120 } 10120 }
10121 } 10121 }
10122 10122
10123 /* If the contents of the global variable 10123 /* If the contents of the global variable
10124 help_echo_string has changed, generate a 10124 help_echo_string has changed, generate a
10929 #endif 10929 #endif
10930 10930
10931 staticpro (&Qreverse); 10931 staticpro (&Qreverse);
10932 Qreverse = intern ("reverse"); 10932 Qreverse = intern ("reverse");
10933 10933
10934 staticpro (&Qmac_ready_for_drag_n_drop);
10935 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
10936
10934 staticpro (&x_display_name_list); 10937 staticpro (&x_display_name_list);
10935 x_display_name_list = Qnil; 10938 x_display_name_list = Qnil;
10936 10939
10937 staticpro (&last_mouse_scroll_bar); 10940 staticpro (&last_mouse_scroll_bar);
10938 last_mouse_scroll_bar = Qnil; 10941 last_mouse_scroll_bar = Qnil;
10939 10942
10940 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); 10943 staticpro (&fm_font_family_alist);
10941 staticpro (&Qmac_ready_for_drag_n_drop); 10944 fm_font_family_alist = Qnil;
10942 10945
10943 #if USE_ATSUI 10946 #if USE_ATSUI
10944 staticpro (&atsu_font_id_hash); 10947 staticpro (&atsu_font_id_hash);
10945 atsu_font_id_hash = Qnil; 10948 atsu_font_id_hash = Qnil;
10946 #endif 10949 #endif