Mercurial > emacs
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 |