comparison src/macterm.c @ 67733:330ac31a0c82

(mac_per_char_metric): Add prototype. (x_per_char_metric) [USE_CG_TEXT_DRAWING]: Remove prototype. (mac_query_char_extents): New function. (x_per_char_metric): Use it. (XLoadQueryFont): Likewise. Consolidate min/max_bounds calculations. [USE_CG_TEXT_DRAWING] (mac_draw_string_cg): Use mac_per_char_metric instead of x_per_char_metric. (mac_text_extents_16): New function. (mac_compute_glyph_string_overhangs): Use it. (mac_unload_font): Free member `bounds' in struct MacFontStruct.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Thu, 22 Dec 2005 08:17:10 +0000
parents ea51bc4acb2e
children 114d965dfb60
comparison
equal deleted inserted replaced
67732:caacdc1a999e 67733:330ac31a0c82
257 enum scroll_bar_part *, 257 enum scroll_bar_part *,
258 Lisp_Object *, Lisp_Object *, 258 Lisp_Object *, Lisp_Object *,
259 unsigned long *)); 259 unsigned long *));
260 260
261 static int is_emacs_window P_ ((WindowPtr)); 261 static int is_emacs_window P_ ((WindowPtr));
262 262 static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
263 static void XSetFont P_ ((Display *, GC, XFontStruct *)); 263 static void XSetFont P_ ((Display *, GC, XFontStruct *));
264 264
265 /* Defined in macmenu.h. */ 265 /* Defined in macmenu.h. */
266 extern void menubar_selection_callback (FRAME_PTR, int); 266 extern void menubar_selection_callback (FRAME_PTR, int);
267 267
866 { 866 {
867 mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcCopy, 2); 867 mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcCopy, 2);
868 } 868 }
869 869
870 870
871 /* Mac replacement for XQueryTextExtents, but takes a character. If
872 STYLE is NULL, measurement is done by QuickDraw Text routines for
873 the font of the current graphics port. If CG_GLYPH is not NULL,
874 *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
875
876 static OSErr
877 mac_query_char_extents (style, c,
878 font_ascent_return, font_descent_return,
879 overall_return, cg_glyph)
880 #if USE_ATSUI
881 ATSUStyle style;
882 #else
883 void *style;
884 #endif
885 int c;
886 int *font_ascent_return, *font_descent_return;
887 XCharStruct *overall_return;
871 #if USE_CG_TEXT_DRAWING 888 #if USE_CG_TEXT_DRAWING
872 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); 889 CGGlyph *cg_glyph;
873 890 #else
891 void *cg_glyph;
892 #endif
893 {
894 OSErr err = noErr;
895 int width;
896 Rect char_bounds;
897
898 #if USE_ATSUI
899 if (style)
900 {
901 ATSUTextLayout text_layout;
902 UniChar ch = c;
903
904 err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
905 if (err == noErr)
906 {
907 ATSTrapezoid glyph_bounds;
908
909 err = ATSUGetGlyphBounds (text_layout, 0, 0,
910 kATSUFromTextBeginning, kATSUToTextEnd,
911 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
912 kATSUseFractionalOrigins,
913 #else
914 kATSUseDeviceOrigins,
915 #endif
916 1, &glyph_bounds, NULL);
917 if (err == noErr)
918 {
919 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
920 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
921
922 width = Fix2Long (glyph_bounds.upperRight.x
923 - glyph_bounds.upperLeft.x);
924 if (font_ascent_return)
925 *font_ascent_return = -Fix2Long (glyph_bounds.upperLeft.y);
926 if (font_descent_return)
927 *font_descent_return = Fix2Long (glyph_bounds.lowerLeft.y);
928 }
929 }
930 if (err == noErr && overall_return)
931 {
932 err = ATSUMeasureTextImage (text_layout,
933 kATSUFromTextBeginning, kATSUToTextEnd,
934 0, 0, &char_bounds);
935 if (err == noErr)
936 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
937 #if USE_CG_TEXT_DRAWING
938 if (err == noErr && cg_glyph)
939 {
940 OSErr err1;
941 ATSUGlyphInfoArray glyph_info_array;
942 ByteCount count = sizeof (ATSUGlyphInfoArray);
943
944 err1 = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
945 kATSUToTextEnd, NULL, NULL, NULL);
946 if (err1 == noErr)
947 err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
948 kATSUToTextEnd, &count,
949 &glyph_info_array);
950 if (err1 == noErr)
951 {
952 xassert (glyph_info_array.glyphs[0].glyphID);
953 *cg_glyph = glyph_info_array.glyphs[0].glyphID;
954 }
955 else
956 *cg_glyph = 0;
957 }
958 #endif
959 }
960 }
961 else
962 #endif
963 {
964 if (font_ascent_return || font_descent_return)
965 {
966 FontInfo font_info;
967
968 GetFontInfo (&font_info);
969 if (font_ascent_return)
970 *font_ascent_return = font_info.ascent;
971 if (font_descent_return)
972 *font_descent_return = font_info.descent;
973 }
974 if (overall_return)
975 {
976 char ch = c;
977
978 width = CharWidth (ch);
979 QDTextBounds (1, &ch, &char_bounds);
980 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
981 }
982 }
983
984 return err;
985 }
986
987
988 /* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
989
990 static int
991 mac_text_extents_16 (font_struct, string, nchars, overall_return)
992 XFontStruct *font_struct;
993 XChar2b *string;
994 int nchars;
995 XCharStruct *overall_return;
996 {
997 int i;
998 short width = 0, lbearing = 0, rbearing = 0;
999 XCharStruct *pcm;
1000
1001 for (i = 0; i < nchars; i++)
1002 {
1003 pcm = mac_per_char_metric (font_struct, string, 0);
1004 if (pcm == NULL)
1005 width += FONT_WIDTH (font_struct);
1006 else
1007 {
1008 lbearing = min (lbearing, width + pcm->lbearing);
1009 rbearing = max (rbearing, width + pcm->rbearing);
1010 width += pcm->width;
1011 }
1012 string++;
1013 }
1014
1015 overall_return->lbearing = lbearing;
1016 overall_return->rbearing = rbearing;
1017 overall_return->width = width;
1018
1019 /* What's the meaning of the return value of XTextExtents16? */
1020 }
1021
1022
1023 #if USE_CG_TEXT_DRAWING
874 static int cg_text_anti_aliasing_threshold = 8; 1024 static int cg_text_anti_aliasing_threshold = 8;
875 1025
876 static void 1026 static void
877 init_cg_text_anti_aliasing_threshold () 1027 init_cg_text_anti_aliasing_threshold ()
878 { 1028 {
908 gy = port_height - y; 1058 gy = port_height - y;
909 glyphs = (CGGlyph *)buf; 1059 glyphs = (CGGlyph *)buf;
910 advances = xmalloc (sizeof (CGSize) * nchars); 1060 advances = xmalloc (sizeof (CGSize) * nchars);
911 for (i = 0; i < nchars; i++) 1061 for (i = 0; i < nchars; i++)
912 { 1062 {
913 advances[i].width = x_per_char_metric (GC_FONT (gc), buf)->width; 1063 XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0);
1064
1065 advances[i].width = pcm->width;
914 advances[i].height = 0; 1066 advances[i].height = 0;
915 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2]; 1067 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2];
916 buf++; 1068 buf++;
917 } 1069 }
918 1070
1722 xassert (font && char2b); 1874 xassert (font && char2b);
1723 1875
1724 #if USE_ATSUI 1876 #if USE_ATSUI
1725 if (font->mac_style) 1877 if (font->mac_style)
1726 { 1878 {
1727 if (char2b->byte1 >= font->min_byte1 1879 XCharStructRow **row = font->bounds.rows + char2b->byte1;
1728 && char2b->byte1 <= font->max_byte1 1880
1729 && char2b->byte2 >= font->min_char_or_byte2 1881 if (*row == NULL)
1730 && char2b->byte2 <= font->max_char_or_byte2)
1731 { 1882 {
1732 pcm = (font->per_char 1883 *row = xmalloc (sizeof (XCharStructRow));
1733 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1884 if (*row)
1734 * (char2b->byte1 - font->min_byte1)) 1885 bzero (*row, sizeof (XCharStructRow));
1735 + (char2b->byte2 - font->min_char_or_byte2));
1736 } 1886 }
1737 1887 if (*row)
1738 if (pcm && !pcm->valid_p)
1739 { 1888 {
1740 OSErr err; 1889 pcm = (*row)->per_char + char2b->byte2;
1741 ATSUTextLayout text_layout; 1890 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 { 1891 {
1771 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x 1892 BLOCK_INPUT;
1772 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); 1893 mac_query_char_extents (font->mac_style,
1773 1894 (char2b->byte1 << 8) + char2b->byte2,
1774 char_width = Fix2Long (glyph_bounds.upperRight.x 1895 NULL, NULL, pcm, NULL);
1775 - glyph_bounds.upperLeft.x); 1896 UNBLOCK_INPUT;
1776 STORE_XCHARSTRUCT (*pcm, char_width, char_bounds); 1897 XCHARSTRUCTROW_SET_CHAR_VALID (*row, char2b->byte2);
1777 } 1898 }
1778 } 1899 }
1779 } 1900 }
1780 else 1901 else
1781 { 1902 {
1782 #endif 1903 #endif
1783 if (font->per_char != NULL) 1904 if (font->bounds.per_char != NULL)
1784 { 1905 {
1785 if (font->min_byte1 == 0 && font->max_byte1 == 0) 1906 if (font->min_byte1 == 0 && font->max_byte1 == 0)
1786 { 1907 {
1787 /* min_char_or_byte2 specifies the linear character index 1908 /* min_char_or_byte2 specifies the linear character index
1788 corresponding to the first element of the per_char array, 1909 corresponding to the first element of the per_char array,
1791 A character with byte2 less than min_char_or_byte2 or 1912 A character with byte2 less than min_char_or_byte2 or
1792 greater max_char_or_byte2 is not in the font. */ 1913 greater max_char_or_byte2 is not in the font. */
1793 if (char2b->byte1 == 0 1914 if (char2b->byte1 == 0
1794 && char2b->byte2 >= font->min_char_or_byte2 1915 && char2b->byte2 >= font->min_char_or_byte2
1795 && char2b->byte2 <= font->max_char_or_byte2) 1916 && char2b->byte2 <= font->max_char_or_byte2)
1796 pcm = font->per_char + char2b->byte2 - font->min_char_or_byte2; 1917 pcm = font->bounds.per_char
1918 + (char2b->byte2 - font->min_char_or_byte2);
1797 } 1919 }
1798 else 1920 else
1799 { 1921 {
1800 /* If either min_byte1 or max_byte1 are nonzero, both 1922 /* If either min_byte1 or max_byte1 are nonzero, both
1801 min_char_or_byte2 and max_char_or_byte2 are less than 1923 min_char_or_byte2 and max_char_or_byte2 are less than
1813 if (char2b->byte1 >= font->min_byte1 1935 if (char2b->byte1 >= font->min_byte1
1814 && char2b->byte1 <= font->max_byte1 1936 && char2b->byte1 <= font->max_byte1
1815 && char2b->byte2 >= font->min_char_or_byte2 1937 && char2b->byte2 >= font->min_char_or_byte2
1816 && char2b->byte2 <= font->max_char_or_byte2) 1938 && char2b->byte2 <= font->max_char_or_byte2)
1817 { 1939 {
1818 pcm = (font->per_char 1940 pcm = (font->bounds.per_char
1819 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1941 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
1820 * (char2b->byte1 - font->min_byte1)) 1942 * (char2b->byte1 - font->min_byte1))
1821 + (char2b->byte2 - font->min_char_or_byte2)); 1943 + (char2b->byte2 - font->min_char_or_byte2));
1822 } 1944 }
1823 } 1945 }
2155 mac_compute_glyph_string_overhangs (s) 2277 mac_compute_glyph_string_overhangs (s)
2156 struct glyph_string *s; 2278 struct glyph_string *s;
2157 { 2279 {
2158 if (s->cmp == NULL 2280 if (s->cmp == NULL
2159 && s->first_glyph->type == CHAR_GLYPH) 2281 && s->first_glyph->type == CHAR_GLYPH)
2160 { 2282 if (!s->two_byte_p
2161 Rect r;
2162 MacFontStruct *font = s->font;
2163
2164 #if USE_ATSUI 2283 #if USE_ATSUI
2165 if (font->mac_style) 2284 || s->font->mac_style
2166 { 2285 #endif
2167 OSErr err; 2286 )
2168 ATSUTextLayout text_layout; 2287 {
2169 UniChar *buf; 2288 XCharStruct cs;
2170 int i; 2289
2171 2290 mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
2172 SetRect (&r, 0, 0, 0, 0); 2291 s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
2173 buf = xmalloc (sizeof (UniChar) * s->nchars); 2292 s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
2174 if (buf) 2293 }
2175 { 2294 else
2176 for (i = 0; i < s->nchars; i++) 2295 {
2177 buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2; 2296 Rect r;
2178 2297 MacFontStruct *font = s->font;
2179 err = atsu_get_text_layout_with_text_ptr (buf, s->nchars, 2298
2180 font->mac_style, 2299 TextFont (font->mac_fontnum);
2181 &text_layout); 2300 TextSize (font->mac_fontsize);
2182 if (err == noErr) 2301 TextFace (font->mac_fontface);
2183 err = ATSUMeasureTextImage (text_layout, 2302
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); 2303 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
2199 else 2304
2200 { 2305 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
2201 int i; 2306 s->left_overhang = r.left < 0 ? -r.left : 0;
2202 char *buf = xmalloc (s->nchars); 2307 }
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 } 2308 }
2222 2309
2223 2310
2224 /* Fill rectangle X, Y, W, H with background color of glyph string S. */ 2311 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2225 2312
7373 and store them in the returned MacFontStruct. */ 7460 and store them in the returned MacFontStruct. */
7374 7461
7375 static MacFontStruct * 7462 static MacFontStruct *
7376 XLoadQueryFont (Display *dpy, char *fontname) 7463 XLoadQueryFont (Display *dpy, char *fontname)
7377 { 7464 {
7378 int i, size, char_width; 7465 int size;
7379 char *name; 7466 char *name;
7380 Str255 family; 7467 Str255 family;
7381 Str31 charset; 7468 Str31 charset;
7382 SInt16 fontnum; 7469 SInt16 fontnum;
7383 #if USE_ATSUI 7470 #if USE_ATSUI
7390 int scriptcode; 7477 int scriptcode;
7391 #else 7478 #else
7392 short scriptcode; 7479 short scriptcode;
7393 #endif 7480 #endif
7394 MacFontStruct *font; 7481 MacFontStruct *font;
7482 XCharStruct *space_bounds = NULL, *pcm;
7395 7483
7396 if (is_fully_specified_xlfd (fontname)) 7484 if (is_fully_specified_xlfd (fontname))
7397 name = fontname; 7485 name = fontname;
7398 else 7486 else
7399 { 7487 {
7486 7574
7487 #if USE_ATSUI 7575 #if USE_ATSUI
7488 if (font->mac_style) 7576 if (font->mac_style)
7489 { 7577 {
7490 OSErr err; 7578 OSErr err;
7491 ATSUTextLayout text_layout; 7579 UniChar c;
7492 UniChar c = 0x20; 7580
7493 Rect char_bounds, min_bounds, max_bounds; 7581 font->min_byte1 = 0;
7494 int min_width, max_width; 7582 font->max_byte1 = 0xff;
7495 ATSTrapezoid glyph_bounds; 7583 font->min_char_or_byte2 = 0;
7496 7584 font->max_char_or_byte2 = 0xff;
7497 font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000); 7585
7498 if (font->per_char == NULL) 7586 font->bounds.rows = xmalloc (sizeof (XCharStructRow *) * 0x100);
7587 if (font->bounds.rows == NULL)
7499 { 7588 {
7500 mac_unload_font (&one_mac_display_info, font); 7589 mac_unload_font (&one_mac_display_info, font);
7501 return NULL; 7590 return NULL;
7502 } 7591 }
7503 bzero (font->per_char, sizeof (XCharStruct) * 0x10000); 7592 bzero (font->bounds.rows, sizeof (XCharStructRow *) * 0x100);
7593 font->bounds.rows[0] = xmalloc (sizeof (XCharStructRow));
7594 if (font->bounds.rows[0] == NULL)
7595 {
7596 mac_unload_font (&one_mac_display_info, font);
7597 return NULL;
7598 }
7599 bzero (font->bounds.rows[0], sizeof (XCharStructRow));
7504 7600
7505 #if USE_CG_TEXT_DRAWING 7601 #if USE_CG_TEXT_DRAWING
7506 { 7602 {
7507 FMFontFamily font_family; 7603 FMFontFamily font_family;
7508 FMFontStyle style; 7604 FMFontStyle style;
7523 if (font->cg_font) 7619 if (font->cg_font)
7524 font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100); 7620 font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100);
7525 if (font->cg_glyphs) 7621 if (font->cg_glyphs)
7526 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100); 7622 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
7527 #endif 7623 #endif
7528 7624 space_bounds = font->bounds.rows[0]->per_char + 0x20;
7529 err = atsu_get_text_layout_with_text_ptr (&c, 1, 7625 err = mac_query_char_extents (font->mac_style, 0x20,
7530 font->mac_style, 7626 &font->ascent, &font->descent,
7531 &text_layout); 7627 space_bounds,
7628 #if USE_CG_TEXT_DRAWING
7629 (font->cg_glyphs ? font->cg_glyphs + 0x20
7630 : NULL)
7631 #else
7632 NULL
7633 #endif
7634 );
7532 if (err != noErr) 7635 if (err != noErr)
7533 { 7636 {
7534 mac_unload_font (&one_mac_display_info, font); 7637 mac_unload_font (&one_mac_display_info, font);
7535 return NULL; 7638 return NULL;
7536 } 7639 }
7537 7640 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], 0x20);
7538 for (c = 0x20; c <= 0xff; c++) 7641
7642 pcm = font->bounds.rows[0]->per_char;
7643 for (c = 0x21; c <= 0xff; c++)
7539 { 7644 {
7540 if (c == 0xad) 7645 if (c == 0xad)
7541 /* Soft hyphen is not supported in ATSUI. */ 7646 /* Soft hyphen is not supported in ATSUI. */
7542 continue; 7647 continue;
7543 else if (c == 0x7f) 7648 else if (c == 0x7f)
7544 { 7649 {
7545 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7546 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7547 c = 0x9f; 7650 c = 0x9f;
7548 continue; 7651 continue;
7549 } 7652 }
7550 7653
7551 err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning); 7654 mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
7552 if (err == noErr) 7655 #if USE_CG_TEXT_DRAWING
7553 err = ATSUMeasureTextImage (text_layout, 7656 (font->cg_glyphs ? font->cg_glyphs + c
7554 kATSUFromTextBeginning, kATSUToTextEnd, 7657 : 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 7658 #else
7562 kATSUseDeviceOrigins, 7659 NULL
7563 #endif 7660 #endif
7564 1, &glyph_bounds, NULL); 7661 );
7565 if (err == noErr) 7662 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], c);
7663
7664 #if USE_CG_TEXT_DRAWING
7665 if (font->cg_glyphs && font->cg_glyphs[c] == 0)
7566 { 7666 {
7567 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x 7667 /* Don't use CG text drawing if font substitution occurs in
7568 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); 7668 ASCII or Latin-1 characters. */
7569 7669 CGFontRelease (font->cg_font);
7570 char_width = Fix2Long (glyph_bounds.upperRight.x 7670 font->cg_font = NULL;
7571 - glyph_bounds.upperLeft.x); 7671 xfree (font->cg_glyphs);
7572 STORE_XCHARSTRUCT (font->per_char[c], 7672 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 } 7673 }
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 7674 #endif
7624 } 7675 }
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 } 7676 }
7631 else 7677 else
7632 #endif 7678 #endif
7633 { 7679 {
7634 GrafPtr port; 7680 GrafPtr port;
7663 || font->mac_scriptcode == smSimpChinese 7709 || font->mac_scriptcode == smSimpChinese
7664 || font->mac_scriptcode == smKorean); 7710 || font->mac_scriptcode == smKorean);
7665 7711
7666 if (is_two_byte_font) 7712 if (is_two_byte_font)
7667 { 7713 {
7714 int char_width;
7715
7668 font->min_byte1 = 0xa1; 7716 font->min_byte1 = 0xa1;
7669 font->max_byte1 = 0xfe; 7717 font->max_byte1 = 0xfe;
7670 font->min_char_or_byte2 = 0xa1; 7718 font->min_char_or_byte2 = 0xa1;
7671 font->max_char_or_byte2 = 0xfe; 7719 font->max_char_or_byte2 = 0xfe;
7672 7720
7691 break; 7739 break;
7692 case smKorean: 7740 case smKorean:
7693 char_width = StringWidth("\p\xa1\xa1"); 7741 char_width = StringWidth("\p\xa1\xa1");
7694 break; 7742 break;
7695 } 7743 }
7696 } 7744
7697 else 7745 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 7746
7712 if (fontface & italic) 7747 if (fontface & italic)
7713 font->max_bounds.rbearing = char_width + 1; 7748 font->max_bounds.rbearing = char_width + 1;
7714 else 7749 else
7715 font->max_bounds.rbearing = char_width; 7750 font->max_bounds.rbearing = char_width;
7720 7755
7721 font->min_bounds = font->max_bounds; 7756 font->min_bounds = font->max_bounds;
7722 } 7757 }
7723 else 7758 else
7724 { 7759 {
7725 int c, min_width, max_width; 7760 int c;
7726 Rect char_bounds, min_bounds, max_bounds; 7761
7727 char ch; 7762 font->min_byte1 = font->max_byte1 = 0;
7728 7763 font->min_char_or_byte2 = 0x20;
7729 font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); 7764 font->max_char_or_byte2 = 0xff;
7730 bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1)); 7765
7731 7766 font->bounds.per_char =
7732 min_width = max_width = char_width; 7767 xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7733 SetRect (&min_bounds, -32767, -32767, 32767, 32767); 7768 if (font->bounds.per_char == NULL)
7734 SetRect (&max_bounds, 0, 0, 0, 0);
7735 for (c = 0x20; c <= 0xff; c++)
7736 { 7769 {
7737 if (c == 0x7f) 7770 mac_unload_font (&one_mac_display_info, font);
7738 { 7771 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 } 7772 }
7766 if (min_width == max_width 7773 bzero (font->bounds.per_char,
7767 && max_bounds.left >= 0 && max_bounds.right <= max_width) 7774 sizeof (XCharStruct) * (0xff - 0x20 + 1));
7768 { 7775
7769 /* Fixed width and no overhangs. */ 7776 space_bounds = font->bounds.per_char;
7770 xfree (font->per_char); 7777 mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
7771 font->per_char = NULL; 7778 space_bounds, NULL);
7772 } 7779
7780 for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
7781 mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
7773 } 7782 }
7774 7783
7775 /* Restore previous font number, size and face. */ 7784 /* Restore previous font number, size and face. */
7776 TextFont (old_fontnum); 7785 TextFont (old_fontnum);
7777 TextSize (old_fontsize); 7786 TextSize (old_fontsize);
7778 TextFace (old_fontface); 7787 TextFace (old_fontface);
7788 }
7789
7790 if (space_bounds)
7791 {
7792 int c;
7793
7794 font->min_bounds = font->max_bounds = *space_bounds;
7795 for (c = 0x21, pcm = space_bounds + 1; c <= 0x7f; c++, pcm++)
7796 if (pcm->width > 0)
7797 {
7798 font->min_bounds.lbearing = min (font->min_bounds.lbearing,
7799 pcm->lbearing);
7800 font->min_bounds.rbearing = min (font->min_bounds.rbearing,
7801 pcm->rbearing);
7802 font->min_bounds.width = min (font->min_bounds.width,
7803 pcm->width);
7804 font->min_bounds.ascent = min (font->min_bounds.ascent,
7805 pcm->ascent);
7806
7807 font->max_bounds.lbearing = max (font->max_bounds.lbearing,
7808 pcm->lbearing);
7809 font->max_bounds.rbearing = max (font->max_bounds.rbearing,
7810 pcm->rbearing);
7811 font->max_bounds.width = max (font->max_bounds.width,
7812 pcm->width);
7813 font->max_bounds.ascent = max (font->max_bounds.ascent,
7814 pcm->ascent);
7815 }
7816 if (
7817 #if USE_ATSUI
7818 font->mac_style == NULL &&
7819 #endif
7820 font->max_bounds.width == font->min_bounds.width
7821 && font->min_bounds.lbearing >= 0
7822 && font->max_bounds.rbearing <= font->max_bounds.width)
7823 {
7824 /* Fixed width and no overhangs. */
7825 xfree (font->bounds.per_char);
7826 font->bounds.per_char = NULL;
7827 }
7779 } 7828 }
7780 7829
7781 #if !defined (MAC_OS8) || USE_ATSUI 7830 #if !defined (MAC_OS8) || USE_ATSUI
7782 /* AppKit and WebKit do some adjustment to the heights of Courier, 7831 /* AppKit and WebKit do some adjustment to the heights of Courier,
7783 Helvetica, and Times. This only works on the environments where 7832 Helvetica, and Times. This only works on the environments where
7795 mac_unload_font (dpyinfo, font) 7844 mac_unload_font (dpyinfo, font)
7796 struct mac_display_info *dpyinfo; 7845 struct mac_display_info *dpyinfo;
7797 XFontStruct *font; 7846 XFontStruct *font;
7798 { 7847 {
7799 xfree (font->full_name); 7848 xfree (font->full_name);
7800 if (font->per_char)
7801 xfree (font->per_char);
7802 #if USE_ATSUI 7849 #if USE_ATSUI
7803 if (font->mac_style) 7850 if (font->mac_style)
7804 ATSUDisposeStyle (font->mac_style); 7851 {
7852 int i;
7853
7854 for (i = font->min_byte1; i <= font->max_byte1; i++)
7855 if (font->bounds.rows[i])
7856 xfree (font->bounds.rows[i]);
7857 xfree (font->bounds.rows);
7858 ATSUDisposeStyle (font->mac_style);
7859 }
7860 else
7861 #endif
7862 if (font->bounds.per_char)
7863 xfree (font->bounds.per_char);
7805 #if USE_CG_TEXT_DRAWING 7864 #if USE_CG_TEXT_DRAWING
7806 if (font->cg_font) 7865 if (font->cg_font)
7807 CGFontRelease (font->cg_font); 7866 CGFontRelease (font->cg_font);
7808 if (font->cg_glyphs) 7867 if (font->cg_glyphs)
7809 xfree (font->cg_glyphs); 7868 xfree (font->cg_glyphs);
7810 #endif
7811 #endif 7869 #endif
7812 xfree (font); 7870 xfree (font);
7813 } 7871 }
7814 7872
7815 7873