comparison src/macterm.c @ 83428:d0eee3282e6b

Merged from miles@gnu.org--gnu-2005 (patch 678-680) Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-678 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-679 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-680 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-468
author Karoly Lorentey <lorentey@elte.hu>
date Thu, 29 Dec 2005 04:41:02 +0000
parents b64b7e867d0a 114d965dfb60
children de425e4eb0bc
comparison
equal deleted inserted replaced
83427:2afc49c9f0c0 83428:d0eee3282e6b
66 66
67 #include <ctype.h> 67 #include <ctype.h>
68 #include <errno.h> 68 #include <errno.h>
69 #include <setjmp.h> 69 #include <setjmp.h>
70 #include <sys/stat.h> 70 #include <sys/stat.h>
71 #include <sys/param.h>
72 71
73 #include "charset.h" 72 #include "charset.h"
74 #include "coding.h" 73 #include "coding.h"
75 #include "frame.h" 74 #include "frame.h"
76 #include "dispextern.h" 75 #include "dispextern.h"
257 enum scroll_bar_part *, 256 enum scroll_bar_part *,
258 Lisp_Object *, Lisp_Object *, 257 Lisp_Object *, Lisp_Object *,
259 unsigned long *)); 258 unsigned long *));
260 259
261 static int is_emacs_window P_ ((WindowPtr)); 260 static int is_emacs_window P_ ((WindowPtr));
262 261 static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
263 static void XSetFont P_ ((Display *, GC, XFontStruct *)); 262 static void XSetFont P_ ((Display *, GC, XFontStruct *));
264 263
265 /* Defined in macmenu.h. */ 264 /* Defined in macmenu.h. */
266 extern void menubar_selection_callback (FRAME_PTR, int); 265 extern void menubar_selection_callback (FRAME_PTR, int);
267 266
866 { 865 {
867 mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcCopy, 2); 866 mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcCopy, 2);
868 } 867 }
869 868
870 869
870 /* Mac replacement for XQueryTextExtents, but takes a character. If
871 STYLE is NULL, measurement is done by QuickDraw Text routines for
872 the font of the current graphics port. If CG_GLYPH is not NULL,
873 *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
874
875 static OSErr
876 mac_query_char_extents (style, c,
877 font_ascent_return, font_descent_return,
878 overall_return, cg_glyph)
879 #if USE_ATSUI
880 ATSUStyle style;
881 #else
882 void *style;
883 #endif
884 int c;
885 int *font_ascent_return, *font_descent_return;
886 XCharStruct *overall_return;
871 #if USE_CG_TEXT_DRAWING 887 #if USE_CG_TEXT_DRAWING
872 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); 888 CGGlyph *cg_glyph;
873 889 #else
890 void *cg_glyph;
891 #endif
892 {
893 OSErr err = noErr;
894 int width;
895 Rect char_bounds;
896
897 #if USE_ATSUI
898 if (style)
899 {
900 ATSUTextLayout text_layout;
901 UniChar ch = c;
902
903 err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
904 if (err == noErr)
905 {
906 ATSTrapezoid glyph_bounds;
907
908 err = ATSUGetGlyphBounds (text_layout, 0, 0,
909 kATSUFromTextBeginning, kATSUToTextEnd,
910 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
911 kATSUseFractionalOrigins,
912 #else
913 kATSUseDeviceOrigins,
914 #endif
915 1, &glyph_bounds, NULL);
916 if (err == noErr)
917 {
918 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
919 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
920
921 width = Fix2Long (glyph_bounds.upperRight.x
922 - glyph_bounds.upperLeft.x);
923 if (font_ascent_return)
924 *font_ascent_return = -Fix2Long (glyph_bounds.upperLeft.y);
925 if (font_descent_return)
926 *font_descent_return = Fix2Long (glyph_bounds.lowerLeft.y);
927 }
928 }
929 if (err == noErr && overall_return)
930 {
931 err = ATSUMeasureTextImage (text_layout,
932 kATSUFromTextBeginning, kATSUToTextEnd,
933 0, 0, &char_bounds);
934 if (err == noErr)
935 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
936 #if USE_CG_TEXT_DRAWING
937 if (err == noErr && cg_glyph)
938 {
939 OSErr err1;
940 ATSUGlyphInfoArray glyph_info_array;
941 ByteCount count = sizeof (ATSUGlyphInfoArray);
942
943 err1 = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
944 kATSUToTextEnd, NULL, NULL, NULL);
945 if (err1 == noErr)
946 err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
947 kATSUToTextEnd, &count,
948 &glyph_info_array);
949 if (err1 == noErr)
950 {
951 xassert (glyph_info_array.glyphs[0].glyphID);
952 *cg_glyph = glyph_info_array.glyphs[0].glyphID;
953 }
954 else
955 *cg_glyph = 0;
956 }
957 #endif
958 }
959 }
960 else
961 #endif
962 {
963 if (font_ascent_return || font_descent_return)
964 {
965 FontInfo font_info;
966
967 GetFontInfo (&font_info);
968 if (font_ascent_return)
969 *font_ascent_return = font_info.ascent;
970 if (font_descent_return)
971 *font_descent_return = font_info.descent;
972 }
973 if (overall_return)
974 {
975 char ch = c;
976
977 width = CharWidth (ch);
978 QDTextBounds (1, &ch, &char_bounds);
979 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
980 }
981 }
982
983 return err;
984 }
985
986
987 /* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
988
989 static int
990 mac_text_extents_16 (font_struct, string, nchars, overall_return)
991 XFontStruct *font_struct;
992 XChar2b *string;
993 int nchars;
994 XCharStruct *overall_return;
995 {
996 int i;
997 short width = 0, lbearing = 0, rbearing = 0;
998 XCharStruct *pcm;
999
1000 for (i = 0; i < nchars; i++)
1001 {
1002 pcm = mac_per_char_metric (font_struct, string, 0);
1003 if (pcm == NULL)
1004 width += FONT_WIDTH (font_struct);
1005 else
1006 {
1007 lbearing = min (lbearing, width + pcm->lbearing);
1008 rbearing = max (rbearing, width + pcm->rbearing);
1009 width += pcm->width;
1010 }
1011 string++;
1012 }
1013
1014 overall_return->lbearing = lbearing;
1015 overall_return->rbearing = rbearing;
1016 overall_return->width = width;
1017
1018 /* What's the meaning of the return value of XTextExtents16? */
1019 }
1020
1021
1022 #if USE_CG_TEXT_DRAWING
874 static int cg_text_anti_aliasing_threshold = 8; 1023 static int cg_text_anti_aliasing_threshold = 8;
875 1024
876 static void 1025 static void
877 init_cg_text_anti_aliasing_threshold () 1026 init_cg_text_anti_aliasing_threshold ()
878 { 1027 {
908 gy = port_height - y; 1057 gy = port_height - y;
909 glyphs = (CGGlyph *)buf; 1058 glyphs = (CGGlyph *)buf;
910 advances = xmalloc (sizeof (CGSize) * nchars); 1059 advances = xmalloc (sizeof (CGSize) * nchars);
911 for (i = 0; i < nchars; i++) 1060 for (i = 0; i < nchars; i++)
912 { 1061 {
913 advances[i].width = x_per_char_metric (GC_FONT (gc), buf)->width; 1062 XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0);
1063
1064 advances[i].width = pcm->width;
914 advances[i].height = 0; 1065 advances[i].height = 0;
915 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2]; 1066 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2];
916 buf++; 1067 buf++;
917 } 1068 }
918 1069
1722 xassert (font && char2b); 1873 xassert (font && char2b);
1723 1874
1724 #if USE_ATSUI 1875 #if USE_ATSUI
1725 if (font->mac_style) 1876 if (font->mac_style)
1726 { 1877 {
1727 if (char2b->byte1 >= font->min_byte1 1878 XCharStructRow **row = font->bounds.rows + char2b->byte1;
1728 && char2b->byte1 <= font->max_byte1 1879
1729 && char2b->byte2 >= font->min_char_or_byte2 1880 if (*row == NULL)
1730 && char2b->byte2 <= font->max_char_or_byte2)
1731 { 1881 {
1732 pcm = (font->per_char 1882 *row = xmalloc (sizeof (XCharStructRow));
1733 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1883 if (*row)
1734 * (char2b->byte1 - font->min_byte1)) 1884 bzero (*row, sizeof (XCharStructRow));
1735 + (char2b->byte2 - font->min_char_or_byte2));
1736 } 1885 }
1737 1886 if (*row)
1738 if (pcm && !pcm->valid_p)
1739 { 1887 {
1740 OSErr err; 1888 pcm = (*row)->per_char + char2b->byte2;
1741 ATSUTextLayout text_layout; 1889 if (!XCHARSTRUCTROW_CHAR_VALID_P (*row, char2b->byte2))
1742 UniChar c;
1743 int char_width;
1744 ATSTrapezoid glyph_bounds;
1745 Rect char_bounds;
1746
1747 c = (char2b->byte1 << 8) + char2b->byte2;
1748 BLOCK_INPUT;
1749 err = atsu_get_text_layout_with_text_ptr (&c, 1,
1750 font->mac_style,
1751 &text_layout);
1752 if (err == noErr)
1753 err = ATSUMeasureTextImage (text_layout,
1754 kATSUFromTextBeginning, kATSUToTextEnd,
1755 0, 0, &char_bounds);
1756
1757 if (err == noErr)
1758 err = ATSUGetGlyphBounds (text_layout, 0, 0,
1759 kATSUFromTextBeginning, kATSUToTextEnd,
1760 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1761 kATSUseFractionalOrigins,
1762 #else
1763 kATSUseDeviceOrigins,
1764 #endif
1765 1, &glyph_bounds, NULL);
1766 UNBLOCK_INPUT;
1767 if (err != noErr)
1768 pcm = NULL;
1769 else
1770 { 1890 {
1771 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x 1891 BLOCK_INPUT;
1772 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); 1892 mac_query_char_extents (font->mac_style,
1773 1893 (char2b->byte1 << 8) + char2b->byte2,
1774 char_width = Fix2Long (glyph_bounds.upperRight.x 1894 NULL, NULL, pcm, NULL);
1775 - glyph_bounds.upperLeft.x); 1895 UNBLOCK_INPUT;
1776 STORE_XCHARSTRUCT (*pcm, char_width, char_bounds); 1896 XCHARSTRUCTROW_SET_CHAR_VALID (*row, char2b->byte2);
1777 } 1897 }
1778 } 1898 }
1779 } 1899 }
1780 else 1900 else
1781 { 1901 {
1782 #endif 1902 #endif
1783 if (font->per_char != NULL) 1903 if (font->bounds.per_char != NULL)
1784 { 1904 {
1785 if (font->min_byte1 == 0 && font->max_byte1 == 0) 1905 if (font->min_byte1 == 0 && font->max_byte1 == 0)
1786 { 1906 {
1787 /* min_char_or_byte2 specifies the linear character index 1907 /* min_char_or_byte2 specifies the linear character index
1788 corresponding to the first element of the per_char array, 1908 corresponding to the first element of the per_char array,
1791 A character with byte2 less than min_char_or_byte2 or 1911 A character with byte2 less than min_char_or_byte2 or
1792 greater max_char_or_byte2 is not in the font. */ 1912 greater max_char_or_byte2 is not in the font. */
1793 if (char2b->byte1 == 0 1913 if (char2b->byte1 == 0
1794 && char2b->byte2 >= font->min_char_or_byte2 1914 && char2b->byte2 >= font->min_char_or_byte2
1795 && char2b->byte2 <= font->max_char_or_byte2) 1915 && char2b->byte2 <= font->max_char_or_byte2)
1796 pcm = font->per_char + char2b->byte2 - font->min_char_or_byte2; 1916 pcm = font->bounds.per_char
1917 + (char2b->byte2 - font->min_char_or_byte2);
1797 } 1918 }
1798 else 1919 else
1799 { 1920 {
1800 /* If either min_byte1 or max_byte1 are nonzero, both 1921 /* If either min_byte1 or max_byte1 are nonzero, both
1801 min_char_or_byte2 and max_char_or_byte2 are less than 1922 min_char_or_byte2 and max_char_or_byte2 are less than
1813 if (char2b->byte1 >= font->min_byte1 1934 if (char2b->byte1 >= font->min_byte1
1814 && char2b->byte1 <= font->max_byte1 1935 && char2b->byte1 <= font->max_byte1
1815 && char2b->byte2 >= font->min_char_or_byte2 1936 && char2b->byte2 >= font->min_char_or_byte2
1816 && char2b->byte2 <= font->max_char_or_byte2) 1937 && char2b->byte2 <= font->max_char_or_byte2)
1817 { 1938 {
1818 pcm = (font->per_char 1939 pcm = (font->bounds.per_char
1819 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1940 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
1820 * (char2b->byte1 - font->min_byte1)) 1941 * (char2b->byte1 - font->min_byte1))
1821 + (char2b->byte2 - font->min_char_or_byte2)); 1942 + (char2b->byte2 - font->min_char_or_byte2));
1822 } 1943 }
1823 } 1944 }
2155 mac_compute_glyph_string_overhangs (s) 2276 mac_compute_glyph_string_overhangs (s)
2156 struct glyph_string *s; 2277 struct glyph_string *s;
2157 { 2278 {
2158 if (s->cmp == NULL 2279 if (s->cmp == NULL
2159 && s->first_glyph->type == CHAR_GLYPH) 2280 && s->first_glyph->type == CHAR_GLYPH)
2160 { 2281 if (!s->two_byte_p
2161 Rect r;
2162 MacFontStruct *font = s->font;
2163
2164 #if USE_ATSUI 2282 #if USE_ATSUI
2165 if (font->mac_style) 2283 || s->font->mac_style
2166 { 2284 #endif
2167 OSErr err; 2285 )
2168 ATSUTextLayout text_layout; 2286 {
2169 UniChar *buf; 2287 XCharStruct cs;
2170 int i; 2288
2171 2289 mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
2172 SetRect (&r, 0, 0, 0, 0); 2290 s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
2173 buf = xmalloc (sizeof (UniChar) * s->nchars); 2291 s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
2174 if (buf) 2292 }
2175 { 2293 else
2176 for (i = 0; i < s->nchars; i++) 2294 {
2177 buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2; 2295 Rect r;
2178 2296 MacFontStruct *font = s->font;
2179 err = atsu_get_text_layout_with_text_ptr (buf, s->nchars, 2297
2180 font->mac_style, 2298 TextFont (font->mac_fontnum);
2181 &text_layout); 2299 TextSize (font->mac_fontsize);
2182 if (err == noErr) 2300 TextFace (font->mac_fontface);
2183 err = ATSUMeasureTextImage (text_layout, 2301
2184 kATSUFromTextBeginning,
2185 kATSUToTextEnd,
2186 0, 0, &r);
2187 xfree (buf);
2188 }
2189 }
2190 else
2191 {
2192 #endif
2193 TextFont (font->mac_fontnum);
2194 TextSize (font->mac_fontsize);
2195 TextFace (font->mac_fontface);
2196
2197 if (s->two_byte_p)
2198 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r); 2302 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
2199 else 2303
2200 { 2304 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
2201 int i; 2305 s->left_overhang = r.left < 0 ? -r.left : 0;
2202 char *buf = xmalloc (s->nchars); 2306 }
2203
2204 if (buf == NULL)
2205 SetRect (&r, 0, 0, 0, 0);
2206 else
2207 {
2208 for (i = 0; i < s->nchars; ++i)
2209 buf[i] = s->char2b[i].byte2;
2210 QDTextBounds (s->nchars, buf, &r);
2211 xfree (buf);
2212 }
2213 }
2214 #if USE_ATSUI
2215 }
2216 #endif
2217
2218 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
2219 s->left_overhang = r.left < 0 ? -r.left : 0;
2220 }
2221 } 2307 }
2222 2308
2223 2309
2224 /* Fill rectangle X, Y, W, H with background color of glyph string S. */ 2310 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2225 2311
7373 and store them in the returned MacFontStruct. */ 7459 and store them in the returned MacFontStruct. */
7374 7460
7375 static MacFontStruct * 7461 static MacFontStruct *
7376 XLoadQueryFont (Display *dpy, char *fontname) 7462 XLoadQueryFont (Display *dpy, char *fontname)
7377 { 7463 {
7378 int i, size, char_width; 7464 int size;
7379 char *name; 7465 char *name;
7380 Str255 family; 7466 Str255 family;
7381 Str31 charset; 7467 Str31 charset;
7382 SInt16 fontnum; 7468 SInt16 fontnum;
7383 #if USE_ATSUI 7469 #if USE_ATSUI
7390 int scriptcode; 7476 int scriptcode;
7391 #else 7477 #else
7392 short scriptcode; 7478 short scriptcode;
7393 #endif 7479 #endif
7394 MacFontStruct *font; 7480 MacFontStruct *font;
7481 XCharStruct *space_bounds = NULL, *pcm;
7395 7482
7396 if (is_fully_specified_xlfd (fontname)) 7483 if (is_fully_specified_xlfd (fontname))
7397 name = fontname; 7484 name = fontname;
7398 else 7485 else
7399 { 7486 {
7486 7573
7487 #if USE_ATSUI 7574 #if USE_ATSUI
7488 if (font->mac_style) 7575 if (font->mac_style)
7489 { 7576 {
7490 OSErr err; 7577 OSErr err;
7491 ATSUTextLayout text_layout; 7578 UniChar c;
7492 UniChar c = 0x20; 7579
7493 Rect char_bounds, min_bounds, max_bounds; 7580 font->min_byte1 = 0;
7494 int min_width, max_width; 7581 font->max_byte1 = 0xff;
7495 ATSTrapezoid glyph_bounds; 7582 font->min_char_or_byte2 = 0;
7496 7583 font->max_char_or_byte2 = 0xff;
7497 font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000); 7584
7498 if (font->per_char == NULL) 7585 font->bounds.rows = xmalloc (sizeof (XCharStructRow *) * 0x100);
7586 if (font->bounds.rows == NULL)
7499 { 7587 {
7500 mac_unload_font (&one_mac_display_info, font); 7588 mac_unload_font (&one_mac_display_info, font);
7501 return NULL; 7589 return NULL;
7502 } 7590 }
7503 bzero (font->per_char, sizeof (XCharStruct) * 0x10000); 7591 bzero (font->bounds.rows, sizeof (XCharStructRow *) * 0x100);
7592 font->bounds.rows[0] = xmalloc (sizeof (XCharStructRow));
7593 if (font->bounds.rows[0] == NULL)
7594 {
7595 mac_unload_font (&one_mac_display_info, font);
7596 return NULL;
7597 }
7598 bzero (font->bounds.rows[0], sizeof (XCharStructRow));
7504 7599
7505 #if USE_CG_TEXT_DRAWING 7600 #if USE_CG_TEXT_DRAWING
7506 { 7601 {
7507 FMFontFamily font_family; 7602 FMFontFamily font_family;
7508 FMFontStyle style; 7603 FMFontStyle style;
7523 if (font->cg_font) 7618 if (font->cg_font)
7524 font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100); 7619 font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100);
7525 if (font->cg_glyphs) 7620 if (font->cg_glyphs)
7526 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100); 7621 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
7527 #endif 7622 #endif
7528 7623 space_bounds = font->bounds.rows[0]->per_char + 0x20;
7529 err = atsu_get_text_layout_with_text_ptr (&c, 1, 7624 err = mac_query_char_extents (font->mac_style, 0x20,
7530 font->mac_style, 7625 &font->ascent, &font->descent,
7531 &text_layout); 7626 space_bounds,
7627 #if USE_CG_TEXT_DRAWING
7628 (font->cg_glyphs ? font->cg_glyphs + 0x20
7629 : NULL)
7630 #else
7631 NULL
7632 #endif
7633 );
7532 if (err != noErr) 7634 if (err != noErr)
7533 { 7635 {
7534 mac_unload_font (&one_mac_display_info, font); 7636 mac_unload_font (&one_mac_display_info, font);
7535 return NULL; 7637 return NULL;
7536 } 7638 }
7537 7639 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], 0x20);
7538 for (c = 0x20; c <= 0xff; c++) 7640
7641 pcm = font->bounds.rows[0]->per_char;
7642 for (c = 0x21; c <= 0xff; c++)
7539 { 7643 {
7540 if (c == 0xad) 7644 if (c == 0xad)
7541 /* Soft hyphen is not supported in ATSUI. */ 7645 /* Soft hyphen is not supported in ATSUI. */
7542 continue; 7646 continue;
7543 else if (c == 0x7f) 7647 else if (c == 0x7f)
7544 { 7648 {
7545 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7546 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7547 c = 0x9f; 7649 c = 0x9f;
7548 continue; 7650 continue;
7549 } 7651 }
7550 7652
7551 err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning); 7653 mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
7552 if (err == noErr) 7654 #if USE_CG_TEXT_DRAWING
7553 err = ATSUMeasureTextImage (text_layout, 7655 (font->cg_glyphs ? font->cg_glyphs + c
7554 kATSUFromTextBeginning, kATSUToTextEnd, 7656 : NULL)
7555 0, 0, &char_bounds);
7556 if (err == noErr)
7557 err = ATSUGetGlyphBounds (text_layout, 0, 0,
7558 kATSUFromTextBeginning, kATSUToTextEnd,
7559 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
7560 kATSUseFractionalOrigins,
7561 #else 7657 #else
7562 kATSUseDeviceOrigins, 7658 NULL
7563 #endif 7659 #endif
7564 1, &glyph_bounds, NULL); 7660 );
7565 if (err == noErr) 7661 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], c);
7662
7663 #if USE_CG_TEXT_DRAWING
7664 if (font->cg_glyphs && font->cg_glyphs[c] == 0)
7566 { 7665 {
7567 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x 7666 /* Don't use CG text drawing if font substitution occurs in
7568 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); 7667 ASCII or Latin-1 characters. */
7569 7668 CGFontRelease (font->cg_font);
7570 char_width = Fix2Long (glyph_bounds.upperRight.x 7669 font->cg_font = NULL;
7571 - glyph_bounds.upperLeft.x); 7670 xfree (font->cg_glyphs);
7572 STORE_XCHARSTRUCT (font->per_char[c], 7671 font->cg_glyphs = NULL;
7573 char_width, char_bounds);
7574 if (c == 0x20)
7575 {
7576 min_width = max_width = char_width;
7577 min_bounds = max_bounds = char_bounds;
7578 font->ascent = -Fix2Long (glyph_bounds.upperLeft.y);
7579 font->descent = Fix2Long (glyph_bounds.lowerLeft.y);
7580 }
7581 else
7582 {
7583 if (char_width > 0)
7584 {
7585 min_width = min (min_width, char_width);
7586 max_width = max (max_width, char_width);
7587 }
7588 if (!EmptyRect (&char_bounds))
7589 {
7590 SetRect (&min_bounds,
7591 max (min_bounds.left, char_bounds.left),
7592 max (min_bounds.top, char_bounds.top),
7593 min (min_bounds.right, char_bounds.right),
7594 min (min_bounds.bottom, char_bounds.bottom));
7595 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7596 }
7597 }
7598 } 7672 }
7599 #if USE_CG_TEXT_DRAWING
7600 if (err == noErr && char_width > 0 && font->cg_font)
7601 {
7602 ATSUGlyphInfoArray glyph_info_array;
7603 ByteCount count = sizeof (ATSUGlyphInfoArray);
7604
7605 err = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
7606 kATSUToTextEnd, NULL, NULL, NULL);
7607 if (err == noErr)
7608 err = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
7609 kATSUToTextEnd, &count,
7610 &glyph_info_array);
7611 if (err == noErr)
7612 font->cg_glyphs[c] = glyph_info_array.glyphs[0].glyphID;
7613 else
7614 {
7615 /* Don't use CG text drawing if font substitution
7616 occurs in ASCII or Latin-1 characters. */
7617 CGFontRelease (font->cg_font);
7618 font->cg_font = NULL;
7619 xfree (font->cg_glyphs);
7620 font->cg_glyphs = NULL;
7621 }
7622 }
7623 #endif 7673 #endif
7624 } 7674 }
7625
7626 font->min_byte1 = 0;
7627 font->max_byte1 = 0xff;
7628 font->min_char_or_byte2 = 0;
7629 font->max_char_or_byte2 = 0xff;
7630 } 7675 }
7631 else 7676 else
7632 #endif 7677 #endif
7633 { 7678 {
7634 GrafPtr port; 7679 GrafPtr port;
7663 || font->mac_scriptcode == smSimpChinese 7708 || font->mac_scriptcode == smSimpChinese
7664 || font->mac_scriptcode == smKorean); 7709 || font->mac_scriptcode == smKorean);
7665 7710
7666 if (is_two_byte_font) 7711 if (is_two_byte_font)
7667 { 7712 {
7713 int char_width;
7714
7668 font->min_byte1 = 0xa1; 7715 font->min_byte1 = 0xa1;
7669 font->max_byte1 = 0xfe; 7716 font->max_byte1 = 0xfe;
7670 font->min_char_or_byte2 = 0xa1; 7717 font->min_char_or_byte2 = 0xa1;
7671 font->max_char_or_byte2 = 0xfe; 7718 font->max_char_or_byte2 = 0xfe;
7672 7719
7691 break; 7738 break;
7692 case smKorean: 7739 case smKorean:
7693 char_width = StringWidth("\p\xa1\xa1"); 7740 char_width = StringWidth("\p\xa1\xa1");
7694 break; 7741 break;
7695 } 7742 }
7696 } 7743
7697 else 7744 font->bounds.per_char = NULL;
7698 {
7699 font->min_byte1 = font->max_byte1 = 0;
7700 font->min_char_or_byte2 = 0x20;
7701 font->max_char_or_byte2 = 0xff;
7702
7703 /* Do this instead of use the_fontinfo.widMax, which
7704 incorrectly returns 15 for 12-point Monaco! */
7705 char_width = CharWidth ('m');
7706 }
7707
7708 if (is_two_byte_font)
7709 {
7710 font->per_char = NULL;
7711 7745
7712 if (fontface & italic) 7746 if (fontface & italic)
7713 font->max_bounds.rbearing = char_width + 1; 7747 font->max_bounds.rbearing = char_width + 1;
7714 else 7748 else
7715 font->max_bounds.rbearing = char_width; 7749 font->max_bounds.rbearing = char_width;
7720 7754
7721 font->min_bounds = font->max_bounds; 7755 font->min_bounds = font->max_bounds;
7722 } 7756 }
7723 else 7757 else
7724 { 7758 {
7725 int c, min_width, max_width; 7759 int c;
7726 Rect char_bounds, min_bounds, max_bounds; 7760
7727 char ch; 7761 font->min_byte1 = font->max_byte1 = 0;
7728 7762 font->min_char_or_byte2 = 0x20;
7729 font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); 7763 font->max_char_or_byte2 = 0xff;
7730 bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1)); 7764
7731 7765 font->bounds.per_char =
7732 min_width = max_width = char_width; 7766 xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7733 SetRect (&min_bounds, -32767, -32767, 32767, 32767); 7767 if (font->bounds.per_char == NULL)
7734 SetRect (&max_bounds, 0, 0, 0, 0);
7735 for (c = 0x20; c <= 0xff; c++)
7736 { 7768 {
7737 if (c == 0x7f) 7769 mac_unload_font (&one_mac_display_info, font);
7738 { 7770 return NULL;
7739 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7740 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7741 continue;
7742 }
7743
7744 ch = c;
7745 char_width = CharWidth (ch);
7746 QDTextBounds (1, &ch, &char_bounds);
7747 STORE_XCHARSTRUCT (font->per_char[c - 0x20],
7748 char_width, char_bounds);
7749 /* Some Japanese fonts (in SJIS encoding) return 0 as
7750 the character width of 0x7f. */
7751 if (char_width > 0)
7752 {
7753 min_width = min (min_width, char_width);
7754 max_width = max (max_width, char_width);
7755 }
7756 if (!EmptyRect (&char_bounds))
7757 {
7758 SetRect (&min_bounds,
7759 max (min_bounds.left, char_bounds.left),
7760 max (min_bounds.top, char_bounds.top),
7761 min (min_bounds.right, char_bounds.right),
7762 min (min_bounds.bottom, char_bounds.bottom));
7763 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7764 }
7765 } 7771 }
7766 if (min_width == max_width 7772 bzero (font->bounds.per_char,
7767 && max_bounds.left >= 0 && max_bounds.right <= max_width) 7773 sizeof (XCharStruct) * (0xff - 0x20 + 1));
7768 { 7774
7769 /* Fixed width and no overhangs. */ 7775 space_bounds = font->bounds.per_char;
7770 xfree (font->per_char); 7776 mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
7771 font->per_char = NULL; 7777 space_bounds, NULL);
7772 } 7778
7779 for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
7780 mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
7773 } 7781 }
7774 7782
7775 /* Restore previous font number, size and face. */ 7783 /* Restore previous font number, size and face. */
7776 TextFont (old_fontnum); 7784 TextFont (old_fontnum);
7777 TextSize (old_fontsize); 7785 TextSize (old_fontsize);
7778 TextFace (old_fontface); 7786 TextFace (old_fontface);
7787 }
7788
7789 if (space_bounds)
7790 {
7791 int c;
7792
7793 font->min_bounds = font->max_bounds = *space_bounds;
7794 for (c = 0x21, pcm = space_bounds + 1; c <= 0x7f; c++, pcm++)
7795 if (pcm->width > 0)
7796 {
7797 font->min_bounds.lbearing = min (font->min_bounds.lbearing,
7798 pcm->lbearing);
7799 font->min_bounds.rbearing = min (font->min_bounds.rbearing,
7800 pcm->rbearing);
7801 font->min_bounds.width = min (font->min_bounds.width,
7802 pcm->width);
7803 font->min_bounds.ascent = min (font->min_bounds.ascent,
7804 pcm->ascent);
7805
7806 font->max_bounds.lbearing = max (font->max_bounds.lbearing,
7807 pcm->lbearing);
7808 font->max_bounds.rbearing = max (font->max_bounds.rbearing,
7809 pcm->rbearing);
7810 font->max_bounds.width = max (font->max_bounds.width,
7811 pcm->width);
7812 font->max_bounds.ascent = max (font->max_bounds.ascent,
7813 pcm->ascent);
7814 }
7815 if (
7816 #if USE_ATSUI
7817 font->mac_style == NULL &&
7818 #endif
7819 font->max_bounds.width == font->min_bounds.width
7820 && font->min_bounds.lbearing >= 0
7821 && font->max_bounds.rbearing <= font->max_bounds.width)
7822 {
7823 /* Fixed width and no overhangs. */
7824 xfree (font->bounds.per_char);
7825 font->bounds.per_char = NULL;
7826 }
7779 } 7827 }
7780 7828
7781 #if !defined (MAC_OS8) || USE_ATSUI 7829 #if !defined (MAC_OS8) || USE_ATSUI
7782 /* AppKit and WebKit do some adjustment to the heights of Courier, 7830 /* AppKit and WebKit do some adjustment to the heights of Courier,
7783 Helvetica, and Times. This only works on the environments where 7831 Helvetica, and Times. This only works on the environments where
7795 mac_unload_font (dpyinfo, font) 7843 mac_unload_font (dpyinfo, font)
7796 struct mac_display_info *dpyinfo; 7844 struct mac_display_info *dpyinfo;
7797 XFontStruct *font; 7845 XFontStruct *font;
7798 { 7846 {
7799 xfree (font->full_name); 7847 xfree (font->full_name);
7800 if (font->per_char)
7801 xfree (font->per_char);
7802 #if USE_ATSUI 7848 #if USE_ATSUI
7803 if (font->mac_style) 7849 if (font->mac_style)
7804 ATSUDisposeStyle (font->mac_style); 7850 {
7851 int i;
7852
7853 for (i = font->min_byte1; i <= font->max_byte1; i++)
7854 if (font->bounds.rows[i])
7855 xfree (font->bounds.rows[i]);
7856 xfree (font->bounds.rows);
7857 ATSUDisposeStyle (font->mac_style);
7858 }
7859 else
7860 #endif
7861 if (font->bounds.per_char)
7862 xfree (font->bounds.per_char);
7805 #if USE_CG_TEXT_DRAWING 7863 #if USE_CG_TEXT_DRAWING
7806 if (font->cg_font) 7864 if (font->cg_font)
7807 CGFontRelease (font->cg_font); 7865 CGFontRelease (font->cg_font);
7808 if (font->cg_glyphs) 7866 if (font->cg_glyphs)
7809 xfree (font->cg_glyphs); 7867 xfree (font->cg_glyphs);
7810 #endif
7811 #endif 7868 #endif
7812 xfree (font); 7869 xfree (font);
7813 } 7870 }
7814 7871
7815 7872
8141 extern Lisp_Object Qundefined; 8198 extern Lisp_Object Qundefined;
8142 extern void init_apple_event_handler P_ ((void)); 8199 extern void init_apple_event_handler P_ ((void));
8143 extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID, 8200 extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
8144 Lisp_Object *, Lisp_Object *, 8201 Lisp_Object *, Lisp_Object *,
8145 Lisp_Object *)); 8202 Lisp_Object *));
8203 extern OSErr init_coercion_handler P_ ((void));
8146 8204
8147 #if TARGET_API_MAC_CARBON 8205 #if TARGET_API_MAC_CARBON
8148 /* Drag and Drop */ 8206 /* Drag and Drop */
8149 static pascal OSErr mac_do_track_drag (DragTrackingMessage, WindowPtr, void*, DragReference); 8207 static pascal OSErr mac_do_track_drag (DragTrackingMessage, WindowPtr, void*, DragReference);
8150 static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference); 8208 static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference);
9147 /* Only handle file references. */ 9205 /* Only handle file references. */
9148 GetDragItemReferenceNumber (theDrag, index, &theItem); 9206 GetDragItemReferenceNumber (theDrag, index, &theItem);
9149 result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags); 9207 result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
9150 if (result == noErr) 9208 if (result == noErr)
9151 { 9209 {
9152 #ifdef MAC_OSX 9210 OSErr err;
9153 FSRef fref; 9211 AEDesc desc;
9154 #endif 9212
9155 char unix_path_name[MAXPATHLEN]; 9213 err = GetFlavorData (theDrag, theItem, flavorTypeHFS,
9156 9214 &data, &size, 0L);
9157 GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L); 9215 if (err == noErr)
9158 #ifdef MAC_OSX 9216 err = AECoercePtr (typeFSS, &data.fileSpec, sizeof (FSSpec),
9159 /* Use Carbon routines, otherwise it converts the file name 9217 TYPE_FILE_NAME, &desc);
9160 to /Macintosh HD/..., which is not correct. */ 9218 if (err == noErr)
9161 FSpMakeFSRef (&data.fileSpec, &fref); 9219 {
9162 if (! FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name))); 9220 Lisp_Object file;
9163 #else 9221
9164 if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name, 9222 /* x-dnd functions expect undecoded filenames. */
9165 sizeof (unix_path_name) - 1) == noErr) 9223 file = make_uninit_string (AEGetDescDataSize (&desc));
9166 #endif 9224 err = AEGetDescData (&desc, SDATA (file), SBYTES (file));
9167 /* x-dnd functions expect undecoded filenames. */ 9225 if (err == noErr)
9168 file_list = Fcons (make_unibyte_string (unix_path_name, 9226 file_list = Fcons (file, file_list);
9169 strlen (unix_path_name)), 9227 AEDisposeDesc (&desc);
9170 file_list); 9228 }
9171 } 9229 }
9172 } 9230 }
9173 /* If there are items in the list, construct an event and post it to 9231 /* If there are items in the list, construct an event and post it to
9174 the queue like an interrupt using kbd_buffer_store_event. */ 9232 the queue like an interrupt using kbd_buffer_store_event. */
9175 if (!NILP (file_list)) 9233 if (!NILP (file_list))
9256 #endif 9314 #endif
9257 9315
9258 init_emacs_passwd_dir (); 9316 init_emacs_passwd_dir ();
9259 9317
9260 init_environ (); 9318 init_environ ();
9319
9320 init_coercion_handler ();
9261 9321
9262 initialize_applescript (); 9322 initialize_applescript ();
9263 9323
9264 init_apple_event_handler (); 9324 init_apple_event_handler ();
9265 9325
10646 10706
10647 init_menu_bar (); 10707 init_menu_bar ();
10648 #endif /* USE_CARBON_EVENTS */ 10708 #endif /* USE_CARBON_EVENTS */
10649 10709
10650 #ifdef MAC_OSX 10710 #ifdef MAC_OSX
10711 init_coercion_handler ();
10712
10651 init_apple_event_handler (); 10713 init_apple_event_handler ();
10652 10714
10653 if (!inhibit_window_system) 10715 if (!inhibit_window_system)
10654 MakeMeTheFrontProcess (); 10716 MakeMeTheFrontProcess ();
10655 #endif 10717 #endif