(mac_draw_string_common, x_per_char_metric)
(mac_compute_glyph_string_overhangs, init_font_name_table) (XLoadQueryFont, mac_unload_font) [USE_ATSUI]: Add ATSUI support. (atsu_get_text_layout_with_text_ptr) [USE_ATSUI]: New function. (x_draw_glyph_string_background) (x_draw_glyph_string_foreground) [MAC_OS8 && USE_ATSUI]: Don't use XDrawImageString. Always draw background and foreground separately. (x_draw_glyph_string_foreground) [USE_ATSUI]: Don't use 8-bit functions for one-byte chars when using ATSUI-compatible fonts. (atsu_font_id_hash) [USE_ATSUI]: New variable. (syms_of_macterm) [USE_ATSUI]: Initialize and staticpro it. (XLoadQueryFont): Set min_byte1, max_byte1, min_char_or_byte2, and max_char_or_byte2 more in detail. (quit_char_comp, mac_check_for_quit_char) [MAC_OSX]: Remove functions.
This commit is contained in:
parent
04904a238e
commit
c3bd8190a2
1 changed files with 525 additions and 130 deletions
655
src/macterm.c
655
src/macterm.c
|
@ -658,6 +658,62 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height)
|
|||
#endif
|
||||
|
||||
|
||||
#if USE_ATSUI
|
||||
static OSStatus
|
||||
atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
|
||||
ConstUniCharArrayPtr text;
|
||||
UniCharCount text_length;
|
||||
ATSUStyle style;
|
||||
ATSUTextLayout *text_layout;
|
||||
{
|
||||
OSStatus err;
|
||||
static ATSUTextLayout saved_text_layout = NULL; /* not reentrant */
|
||||
|
||||
if (saved_text_layout == NULL)
|
||||
{
|
||||
UniCharCount lengths[] = {kATSUToTextEnd};
|
||||
ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag};
|
||||
ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
|
||||
static ATSLineLayoutOptions line_layout =
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
|
||||
kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics
|
||||
#else
|
||||
kATSLineIsDisplayOnly
|
||||
#endif
|
||||
;
|
||||
ATSUAttributeValuePtr values[] = {&line_layout};
|
||||
|
||||
err = ATSUCreateTextLayoutWithTextPtr (text,
|
||||
kATSUFromTextBeginning,
|
||||
kATSUToTextEnd,
|
||||
text_length,
|
||||
1, lengths, &style,
|
||||
&saved_text_layout);
|
||||
if (err == noErr)
|
||||
err = ATSUSetLayoutControls (saved_text_layout,
|
||||
sizeof (tags) / sizeof (tags[0]),
|
||||
tags, sizes, values);
|
||||
/* XXX: Should we do this? */
|
||||
if (err == noErr)
|
||||
err = ATSUSetTransientFontMatching (saved_text_layout, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ATSUSetRunStyle (saved_text_layout, style,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd);
|
||||
if (err == noErr)
|
||||
err = ATSUSetTextPointerLocation (saved_text_layout, text,
|
||||
kATSUFromTextBeginning,
|
||||
kATSUToTextEnd,
|
||||
text_length);
|
||||
}
|
||||
|
||||
if (err == noErr)
|
||||
*text_layout = saved_text_layout;
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode,
|
||||
bytes_per_char)
|
||||
|
@ -682,6 +738,89 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode,
|
|||
if (mode != srcOr)
|
||||
RGBBackColor (GC_BACK_COLOR (gc));
|
||||
|
||||
#if USE_ATSUI
|
||||
if (GC_FONT (gc)->mac_style)
|
||||
{
|
||||
OSErr err;
|
||||
ATSUTextLayout text_layout;
|
||||
|
||||
xassert (bytes_per_char == 2);
|
||||
|
||||
#ifndef WORDS_BIG_ENDIAN
|
||||
{
|
||||
int i;
|
||||
Unichar *text = (Unichar *)buf;
|
||||
|
||||
for (i = 0; i < nchars; i++)
|
||||
text[i] = buf[2*i] << 8 | buf[2*i+1];
|
||||
}
|
||||
#endif
|
||||
err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
|
||||
nchars,
|
||||
GC_FONT (gc)->mac_style,
|
||||
&text_layout);
|
||||
if (err == noErr)
|
||||
{
|
||||
#ifdef MAC_OSX
|
||||
if (NILP (Vmac_use_core_graphics))
|
||||
{
|
||||
#endif
|
||||
MoveTo (x, y);
|
||||
ATSUDrawText (text_layout,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd,
|
||||
kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
|
||||
#ifdef MAC_OSX
|
||||
}
|
||||
else
|
||||
{
|
||||
CGrafPtr port;
|
||||
CGContextRef context;
|
||||
Rect rect;
|
||||
RgnHandle region = NewRgn ();
|
||||
float port_height;
|
||||
ATSUAttributeTag tags[] = {kATSUCGContextTag};
|
||||
ByteCount sizes[] = {sizeof (CGContextRef)};
|
||||
ATSUAttributeValuePtr values[] = {&context};
|
||||
|
||||
GetPort (&port);
|
||||
QDBeginCGContext (port, &context);
|
||||
GetPortBounds (port, &rect);
|
||||
port_height = rect.bottom - rect.top;
|
||||
GetClip (region);
|
||||
GetRegionBounds (region, &rect);
|
||||
/* XXX: This is not correct if the clip region is not a
|
||||
simple rectangle. */
|
||||
CGContextClipToRect (context,
|
||||
CGRectMake (rect.left,
|
||||
port_height - rect.bottom,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top));
|
||||
DisposeRgn (region);
|
||||
CGContextSetRGBFillColor
|
||||
(context,
|
||||
RED_FROM_ULONG (gc->xgcv.foreground) / 255.0,
|
||||
GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0,
|
||||
BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0,
|
||||
1.0);
|
||||
err = ATSUSetLayoutControls (text_layout,
|
||||
sizeof (tags) / sizeof (tags[0]),
|
||||
tags, sizes, values);
|
||||
if (err == noErr)
|
||||
ATSUDrawText (text_layout,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd,
|
||||
Long2Fix (x), Long2Fix (port_height - y));
|
||||
ATSUClearLayoutControls (text_layout,
|
||||
sizeof (tags) / sizeof (tags[0]),
|
||||
tags);
|
||||
CGContextSynchronize (context);
|
||||
QDEndCGContext (port, &context);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
TextFont (GC_FONT (gc)->mac_fontnum);
|
||||
TextSize (GC_FONT (gc)->mac_fontsize);
|
||||
TextFace (GC_FONT (gc)->mac_fontface);
|
||||
|
@ -689,6 +828,9 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode,
|
|||
|
||||
MoveTo (x, y);
|
||||
DrawText (buf, 0, nchars * bytes_per_char);
|
||||
#if USE_ATSUI
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mode != srcOr)
|
||||
RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w)));
|
||||
|
@ -1549,6 +1691,61 @@ x_per_char_metric (font, char2b)
|
|||
|
||||
xassert (font && char2b);
|
||||
|
||||
#if USE_ATSUI
|
||||
if (font->mac_style)
|
||||
{
|
||||
if (char2b->byte1 >= font->min_byte1
|
||||
&& char2b->byte1 <= font->max_byte1
|
||||
&& char2b->byte2 >= font->min_char_or_byte2
|
||||
&& char2b->byte2 <= font->max_char_or_byte2)
|
||||
{
|
||||
pcm = (font->per_char
|
||||
+ ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
|
||||
* (char2b->byte1 - font->min_byte1))
|
||||
+ (char2b->byte2 - font->min_char_or_byte2));
|
||||
}
|
||||
|
||||
if (pcm && !pcm->valid_p)
|
||||
{
|
||||
OSErr err;
|
||||
ATSUTextLayout text_layout;
|
||||
UniChar c;
|
||||
int char_width;
|
||||
ATSTrapezoid glyph_bounds;
|
||||
Rect char_bounds;
|
||||
|
||||
c = (char2b->byte1 << 8) + char2b->byte2;
|
||||
BLOCK_INPUT;
|
||||
err = atsu_get_text_layout_with_text_ptr (&c, 1,
|
||||
font->mac_style,
|
||||
&text_layout);
|
||||
if (err == noErr)
|
||||
err = ATSUMeasureTextImage (text_layout,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd,
|
||||
0, 0, &char_bounds);
|
||||
|
||||
if (err == noErr)
|
||||
err = ATSUGetGlyphBounds (text_layout, 0, 0,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd,
|
||||
kATSUseFractionalOrigins, 1,
|
||||
&glyph_bounds, NULL);
|
||||
UNBLOCK_INPUT;
|
||||
if (err != noErr)
|
||||
pcm = NULL;
|
||||
else
|
||||
{
|
||||
xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
|
||||
== glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
|
||||
|
||||
char_width = Fix2Long (glyph_bounds.upperRight.x
|
||||
- glyph_bounds.upperLeft.x);
|
||||
STORE_XCHARSTRUCT (*pcm, char_width, char_bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
if (font->per_char != NULL)
|
||||
{
|
||||
if (font->min_byte1 == 0 && font->max_byte1 == 0)
|
||||
|
@ -1600,6 +1797,9 @@ x_per_char_metric (font, char2b)
|
|||
&& char2b->byte2 <= font->max_char_or_byte2)
|
||||
pcm = &font->max_bounds;
|
||||
}
|
||||
#if USE_ATSUI
|
||||
}
|
||||
#endif
|
||||
|
||||
return ((pcm == NULL
|
||||
|| (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
|
||||
|
@ -1925,6 +2125,35 @@ mac_compute_glyph_string_overhangs (s)
|
|||
Rect r;
|
||||
MacFontStruct *font = s->font;
|
||||
|
||||
#if USE_ATSUI
|
||||
if (font->mac_style)
|
||||
{
|
||||
OSErr err;
|
||||
ATSUTextLayout text_layout;
|
||||
UniChar *buf;
|
||||
int i;
|
||||
|
||||
SetRect (&r, 0, 0, 0, 0);
|
||||
buf = xmalloc (sizeof (UniChar) * s->nchars);
|
||||
if (buf)
|
||||
{
|
||||
for (i = 0; i < s->nchars; i++)
|
||||
buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2;
|
||||
|
||||
err = atsu_get_text_layout_with_text_ptr (buf, s->nchars,
|
||||
font->mac_style,
|
||||
&text_layout);
|
||||
if (err == noErr)
|
||||
err = ATSUMeasureTextImage (text_layout,
|
||||
kATSUFromTextBeginning,
|
||||
kATSUToTextEnd,
|
||||
0, 0, &r);
|
||||
xfree (buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
TextFont (font->mac_fontnum);
|
||||
TextSize (font->mac_fontsize);
|
||||
TextFace (font->mac_fontface);
|
||||
|
@ -1946,6 +2175,9 @@ mac_compute_glyph_string_overhangs (s)
|
|||
xfree (buf);
|
||||
}
|
||||
}
|
||||
#if USE_ATSUI
|
||||
}
|
||||
#endif
|
||||
|
||||
s->right_overhang = r.right > s->width ? r.right - s->width : 0;
|
||||
s->left_overhang = r.left < 0 ? -r.left : 0;
|
||||
|
@ -2003,7 +2235,7 @@ x_draw_glyph_string_background (s, force_p)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef MAC_OS8
|
||||
#if defined (MAC_OS8) && !USE_ATSUI
|
||||
if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||
|| s->font_not_found_p
|
||||
|| s->extends_to_end_of_line_p
|
||||
|
@ -2057,11 +2289,15 @@ x_draw_glyph_string_foreground (s)
|
|||
boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
|
||||
|
||||
/* If we can use 8-bit functions, condense S->char2b. */
|
||||
if (!s->two_byte_p)
|
||||
if (!s->two_byte_p
|
||||
#if USE_ATSUI
|
||||
&& GC_FONT (s->gc)->mac_style == NULL
|
||||
#endif
|
||||
)
|
||||
for (i = 0; i < s->nchars; ++i)
|
||||
char1b[i] = s->char2b[i].byte2;
|
||||
|
||||
#ifdef MAC_OS8
|
||||
#if defined (MAC_OS8) && !USE_ATSUI
|
||||
/* Draw text with XDrawString if background has already been
|
||||
filled. Otherwise, use XDrawImageString. (Note that
|
||||
XDrawImageString is usually faster than XDrawString.) Always
|
||||
|
@ -2072,14 +2308,18 @@ x_draw_glyph_string_foreground (s)
|
|||
#endif
|
||||
{
|
||||
/* Draw characters with 16-bit or 8-bit functions. */
|
||||
if (s->two_byte_p)
|
||||
if (s->two_byte_p
|
||||
#if USE_ATSUI
|
||||
|| GC_FONT (s->gc)->mac_style
|
||||
#endif
|
||||
)
|
||||
XDrawString16 (s->display, s->window, s->gc, x,
|
||||
s->ybase - boff, s->char2b, s->nchars);
|
||||
else
|
||||
XDrawString (s->display, s->window, s->gc, x,
|
||||
s->ybase - boff, char1b, s->nchars);
|
||||
}
|
||||
#ifdef MAC_OS8
|
||||
#if defined (MAC_OS8) && !USE_ATSUI
|
||||
else
|
||||
{
|
||||
if (s->two_byte_p)
|
||||
|
@ -6431,6 +6671,10 @@ static char **font_name_table = NULL;
|
|||
static int font_name_table_size = 0;
|
||||
static int font_name_count = 0;
|
||||
|
||||
#if USE_ATSUI
|
||||
static Lisp_Object atsu_font_id_hash;
|
||||
#endif
|
||||
|
||||
/* Alist linking character set strings to Mac text encoding and Emacs
|
||||
coding system. */
|
||||
static Lisp_Object Vmac_charset_info_alist;
|
||||
|
@ -6630,6 +6874,74 @@ init_font_name_table ()
|
|||
Lisp_Object text_encoding_info_alist;
|
||||
struct gcpro gcpro1;
|
||||
|
||||
text_encoding_info_alist = create_text_encoding_info_alist ();
|
||||
|
||||
#if USE_ATSUI
|
||||
if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode),
|
||||
text_encoding_info_alist)))
|
||||
{
|
||||
OSErr err;
|
||||
ItemCount nfonts, i;
|
||||
ATSUFontID *font_ids = NULL;
|
||||
Ptr name, prev_name = NULL;
|
||||
ByteCount name_len;
|
||||
|
||||
atsu_font_id_hash =
|
||||
make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
|
||||
make_float (DEFAULT_REHASH_SIZE),
|
||||
make_float (DEFAULT_REHASH_THRESHOLD),
|
||||
Qnil, Qnil, Qnil);;
|
||||
err = ATSUFontCount (&nfonts);
|
||||
if (err == noErr)
|
||||
font_ids = xmalloc (sizeof (ATSUFontID) * nfonts);
|
||||
if (font_ids)
|
||||
err = ATSUGetFontIDs (font_ids, nfonts, NULL);
|
||||
if (err == noErr)
|
||||
for (i = 0; i < nfonts; i++)
|
||||
{
|
||||
err = ATSUFindFontName (font_ids[i], kFontFamilyName,
|
||||
kFontMacintoshPlatform, kFontNoScript,
|
||||
kFontNoLanguage, 0, NULL, &name_len, NULL);
|
||||
if (err != noErr)
|
||||
continue;
|
||||
name = xmalloc (name_len + 1);
|
||||
if (name == NULL)
|
||||
continue;
|
||||
name[name_len] = '\0';
|
||||
err = ATSUFindFontName (font_ids[i], kFontFamilyName,
|
||||
kFontMacintoshPlatform, kFontNoScript,
|
||||
kFontNoLanguage, name_len, name,
|
||||
NULL, NULL);
|
||||
if (err == noErr
|
||||
&& *name != '.'
|
||||
&& (prev_name == NULL
|
||||
|| strcmp (name, prev_name) != 0))
|
||||
{
|
||||
static char *cs = "iso10646-1";
|
||||
|
||||
add_font_name_table_entry (mac_to_x_fontname (name, 0,
|
||||
normal, cs));
|
||||
add_font_name_table_entry (mac_to_x_fontname (name, 0,
|
||||
italic, cs));
|
||||
add_font_name_table_entry (mac_to_x_fontname (name, 0,
|
||||
bold, cs));
|
||||
add_font_name_table_entry (mac_to_x_fontname (name, 0,
|
||||
italic | bold, cs));
|
||||
Fputhash (Fdowncase (make_unibyte_string (name, name_len)),
|
||||
long_to_cons (font_ids[i]), atsu_font_id_hash);
|
||||
xfree (prev_name);
|
||||
prev_name = name;
|
||||
}
|
||||
else
|
||||
xfree (name);
|
||||
}
|
||||
if (prev_name)
|
||||
xfree (prev_name);
|
||||
if (font_ids)
|
||||
xfree (font_ids);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a dummy instance iterator here to avoid creating and
|
||||
destroying it in the loop. */
|
||||
if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr)
|
||||
|
@ -6642,8 +6954,6 @@ init_font_name_table ()
|
|||
return;
|
||||
}
|
||||
|
||||
text_encoding_info_alist = create_text_encoding_info_alist ();
|
||||
|
||||
GCPRO1 (text_encoding_info_alist);
|
||||
|
||||
while (FMGetNextFontFamily (&ffi, &ff) == noErr)
|
||||
|
@ -7140,6 +7450,9 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
Str255 mfontname, mfontname_decoded;
|
||||
Str31 charset;
|
||||
SInt16 fontnum;
|
||||
#if USE_ATSUI
|
||||
ATSUStyle mac_style = NULL;
|
||||
#endif
|
||||
Style fontface;
|
||||
#if TARGET_API_MAC_CARBON
|
||||
TextEncoding encoding;
|
||||
|
@ -7191,6 +7504,48 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
|
||||
x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded,
|
||||
&fontface, charset);
|
||||
#if USE_ATSUI
|
||||
if (strcmp (charset, "iso10646-1") == 0) /* XXX */
|
||||
{
|
||||
OSErr err;
|
||||
ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag,
|
||||
kATSUQDBoldfaceTag, kATSUQDItalicTag};
|
||||
ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed),
|
||||
sizeof (Boolean), sizeof (Boolean)};
|
||||
static ATSUFontID font_id;
|
||||
static Fixed size_fixed;
|
||||
static Boolean bold_p, italic_p;
|
||||
ATSUAttributeValuePtr values[] = {&font_id, &size_fixed,
|
||||
&bold_p, &italic_p};
|
||||
ATSUFontFeatureType types[] = {kAllTypographicFeaturesType};
|
||||
ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector};
|
||||
Lisp_Object font_id_cons;
|
||||
|
||||
font_id_cons = Fgethash (Fdowncase
|
||||
(make_unibyte_string (mfontname,
|
||||
strlen (mfontname))),
|
||||
atsu_font_id_hash, Qnil);
|
||||
if (NILP (font_id_cons))
|
||||
return NULL;
|
||||
font_id = cons_to_long (font_id_cons);
|
||||
size_fixed = Long2Fix (size);
|
||||
bold_p = (fontface & bold) != 0;
|
||||
italic_p = (fontface & italic) != 0;
|
||||
err = ATSUCreateStyle (&mac_style);
|
||||
if (err != noErr)
|
||||
return NULL;
|
||||
err = ATSUSetFontFeatures (mac_style, sizeof (types) / sizeof (types[0]),
|
||||
types, selectors);
|
||||
if (err != noErr)
|
||||
return NULL;
|
||||
err = ATSUSetAttributes (mac_style, sizeof (tags) / sizeof (tags[0]),
|
||||
tags, sizes, values);
|
||||
fontnum = -1;
|
||||
scriptcode = kTextEncodingMacUnicode;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
c2pstr (mfontname);
|
||||
#if TARGET_API_MAC_CARBON
|
||||
fontnum = FMGetFontFamilyFromName (mfontname);
|
||||
|
@ -7204,6 +7559,9 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
return NULL;
|
||||
scriptcode = FontToScript (fontnum);
|
||||
#endif
|
||||
#if USE_ATSUI
|
||||
}
|
||||
#endif
|
||||
|
||||
font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct));
|
||||
|
||||
|
@ -7211,6 +7569,9 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
font->mac_fontsize = size;
|
||||
font->mac_fontface = fontface;
|
||||
font->mac_scriptcode = scriptcode;
|
||||
#if USE_ATSUI
|
||||
font->mac_style = mac_style;
|
||||
#endif
|
||||
|
||||
/* Apple Japanese (SJIS) font is listed as both
|
||||
"*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
|
||||
|
@ -7221,6 +7582,91 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
|
||||
font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset);
|
||||
|
||||
#if USE_ATSUI
|
||||
if (font->mac_style)
|
||||
{
|
||||
OSErr err;
|
||||
ATSUTextLayout text_layout;
|
||||
UniChar c = 0x20;
|
||||
Rect char_bounds, min_bounds, max_bounds;
|
||||
int min_width, max_width;
|
||||
ATSTrapezoid glyph_bounds;
|
||||
|
||||
font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000);
|
||||
if (font->per_char == NULL)
|
||||
{
|
||||
mac_unload_font (&one_mac_display_info, font);
|
||||
return NULL;
|
||||
}
|
||||
bzero (font->per_char, sizeof (XCharStruct) * 0x10000);
|
||||
|
||||
err = atsu_get_text_layout_with_text_ptr (&c, 1,
|
||||
font->mac_style,
|
||||
&text_layout);
|
||||
if (err != noErr)
|
||||
{
|
||||
mac_unload_font (&one_mac_display_info, font);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (c = 0x20; c <= 0x7e; c++)
|
||||
{
|
||||
err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning);
|
||||
if (err == noErr)
|
||||
err = ATSUMeasureTextImage (text_layout,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd,
|
||||
0, 0, &char_bounds);
|
||||
if (err == noErr)
|
||||
err = ATSUGetGlyphBounds (text_layout, 0, 0,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd,
|
||||
kATSUseFractionalOrigins, 1,
|
||||
&glyph_bounds, NULL);
|
||||
if (err == noErr)
|
||||
{
|
||||
xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
|
||||
== glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
|
||||
|
||||
char_width = Fix2Long (glyph_bounds.upperRight.x
|
||||
- glyph_bounds.upperLeft.x);
|
||||
STORE_XCHARSTRUCT (font->per_char[c],
|
||||
char_width, char_bounds);
|
||||
if (c == 0x20)
|
||||
{
|
||||
min_width = max_width = char_width;
|
||||
min_bounds = max_bounds = char_bounds;
|
||||
font->ascent = -Fix2Long (glyph_bounds.upperLeft.y);
|
||||
font->descent = Fix2Long (glyph_bounds.lowerLeft.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (char_width > 0)
|
||||
{
|
||||
min_width = min (min_width, char_width);
|
||||
max_width = max (max_width, char_width);
|
||||
}
|
||||
if (!EmptyRect (&char_bounds))
|
||||
{
|
||||
SetRect (&min_bounds,
|
||||
max (min_bounds.left, char_bounds.left),
|
||||
max (min_bounds.top, char_bounds.top),
|
||||
min (min_bounds.right, char_bounds.right),
|
||||
min (min_bounds.bottom, char_bounds.bottom));
|
||||
UnionRect (&max_bounds, &char_bounds, &max_bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
|
||||
STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
|
||||
|
||||
font->min_byte1 = 0;
|
||||
font->max_byte1 = 0xff;
|
||||
font->min_char_or_byte2 = 0;
|
||||
font->max_char_or_byte2 = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
is_two_byte_font = font->mac_scriptcode == smJapanese ||
|
||||
font->mac_scriptcode == smTradChinese ||
|
||||
font->mac_scriptcode == smSimpChinese ||
|
||||
|
@ -7235,24 +7681,26 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
font->ascent = the_fontinfo.ascent;
|
||||
font->descent = the_fontinfo.descent;
|
||||
|
||||
font->min_byte1 = 0;
|
||||
if (is_two_byte_font)
|
||||
font->max_byte1 = 1;
|
||||
else
|
||||
font->max_byte1 = 0;
|
||||
font->min_char_or_byte2 = 0x20;
|
||||
font->max_char_or_byte2 = 0xff;
|
||||
|
||||
if (is_two_byte_font)
|
||||
{
|
||||
font->min_byte1 = 0xa1;
|
||||
font->max_byte1 = 0xfe;
|
||||
font->min_char_or_byte2 = 0xa1;
|
||||
font->max_char_or_byte2 = 0xfe;
|
||||
|
||||
/* Use the width of an "ideographic space" of that font because
|
||||
the_fontinfo.widMax returns the wrong width for some fonts. */
|
||||
switch (font->mac_scriptcode)
|
||||
{
|
||||
case smJapanese:
|
||||
font->min_byte1 = 0x81;
|
||||
font->max_byte1 = 0xfc;
|
||||
font->min_char_or_byte2 = 0x40;
|
||||
font->max_char_or_byte2 = 0xfc;
|
||||
char_width = StringWidth("\p\x81\x40");
|
||||
break;
|
||||
case smTradChinese:
|
||||
font->min_char_or_byte2 = 0x40;
|
||||
char_width = StringWidth("\p\xa1\x40");
|
||||
break;
|
||||
case smSimpChinese:
|
||||
|
@ -7264,9 +7712,15 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
}
|
||||
}
|
||||
else
|
||||
/* Do this instead of use the_fontinfo.widMax, which incorrectly
|
||||
returns 15 for 12-point Monaco! */
|
||||
char_width = CharWidth ('m');
|
||||
{
|
||||
font->min_byte1 = font->max_byte1 = 0;
|
||||
font->min_char_or_byte2 = 0x20;
|
||||
font->max_char_or_byte2 = 0xff;
|
||||
|
||||
/* Do this instead of use the_fontinfo.widMax, which incorrectly
|
||||
returns 15 for 12-point Monaco! */
|
||||
char_width = CharWidth ('m');
|
||||
}
|
||||
|
||||
if (is_two_byte_font)
|
||||
{
|
||||
|
@ -7285,55 +7739,56 @@ XLoadQueryFont (Display *dpy, char *fontname)
|
|||
}
|
||||
else
|
||||
{
|
||||
font->per_char = (XCharStruct *)
|
||||
xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
|
||||
{
|
||||
int c, min_width, max_width;
|
||||
Rect char_bounds, min_bounds, max_bounds;
|
||||
char ch;
|
||||
int c, min_width, max_width;
|
||||
Rect char_bounds, min_bounds, max_bounds;
|
||||
char ch;
|
||||
|
||||
min_width = max_width = char_width;
|
||||
SetRect (&min_bounds, -32767, -32767, 32767, 32767);
|
||||
SetRect (&max_bounds, 0, 0, 0, 0);
|
||||
for (c = 0x20; c <= 0xff; c++)
|
||||
{
|
||||
ch = c;
|
||||
char_width = CharWidth (ch);
|
||||
QDTextBounds (1, &ch, &char_bounds);
|
||||
STORE_XCHARSTRUCT (font->per_char[c - 0x20],
|
||||
char_width, char_bounds);
|
||||
/* Some Japanese fonts (in SJIS encoding) return 0 as the
|
||||
character width of 0x7f. */
|
||||
if (char_width > 0)
|
||||
{
|
||||
min_width = min (min_width, char_width);
|
||||
max_width = max (max_width, char_width);
|
||||
}
|
||||
if (!EmptyRect (&char_bounds))
|
||||
{
|
||||
SetRect (&min_bounds,
|
||||
max (min_bounds.left, char_bounds.left),
|
||||
max (min_bounds.top, char_bounds.top),
|
||||
min (min_bounds.right, char_bounds.right),
|
||||
min (min_bounds.bottom, char_bounds.bottom));
|
||||
UnionRect (&max_bounds, &char_bounds, &max_bounds);
|
||||
}
|
||||
}
|
||||
STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
|
||||
STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
|
||||
if (min_width == max_width
|
||||
&& max_bounds.left >= 0 && max_bounds.right <= max_width)
|
||||
{
|
||||
/* Fixed width and no overhangs. */
|
||||
xfree (font->per_char);
|
||||
font->per_char = NULL;
|
||||
}
|
||||
}
|
||||
font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
|
||||
|
||||
min_width = max_width = char_width;
|
||||
SetRect (&min_bounds, -32767, -32767, 32767, 32767);
|
||||
SetRect (&max_bounds, 0, 0, 0, 0);
|
||||
for (c = 0x20; c <= 0xff; c++)
|
||||
{
|
||||
ch = c;
|
||||
char_width = CharWidth (ch);
|
||||
QDTextBounds (1, &ch, &char_bounds);
|
||||
STORE_XCHARSTRUCT (font->per_char[c - 0x20],
|
||||
char_width, char_bounds);
|
||||
/* Some Japanese fonts (in SJIS encoding) return 0 as the
|
||||
character width of 0x7f. */
|
||||
if (char_width > 0)
|
||||
{
|
||||
min_width = min (min_width, char_width);
|
||||
max_width = max (max_width, char_width);
|
||||
}
|
||||
if (!EmptyRect (&char_bounds))
|
||||
{
|
||||
SetRect (&min_bounds,
|
||||
max (min_bounds.left, char_bounds.left),
|
||||
max (min_bounds.top, char_bounds.top),
|
||||
min (min_bounds.right, char_bounds.right),
|
||||
min (min_bounds.bottom, char_bounds.bottom));
|
||||
UnionRect (&max_bounds, &char_bounds, &max_bounds);
|
||||
}
|
||||
}
|
||||
STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
|
||||
STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
|
||||
if (min_width == max_width
|
||||
&& max_bounds.left >= 0 && max_bounds.right <= max_width)
|
||||
{
|
||||
/* Fixed width and no overhangs. */
|
||||
xfree (font->per_char);
|
||||
font->per_char = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TextFont (old_fontnum); /* restore previous font number, size and face */
|
||||
TextSize (old_fontsize);
|
||||
TextFace (old_fontface);
|
||||
#if USE_ATSUI
|
||||
}
|
||||
#endif
|
||||
|
||||
return font;
|
||||
}
|
||||
|
@ -7347,6 +7802,10 @@ mac_unload_font (dpyinfo, font)
|
|||
xfree (font->full_name);
|
||||
if (font->per_char)
|
||||
xfree (font->per_char);
|
||||
#if USE_ATSUI
|
||||
if (font->mac_style)
|
||||
ATSUDisposeStyle (font->mac_style);
|
||||
#endif
|
||||
xfree (font);
|
||||
}
|
||||
|
||||
|
@ -10189,75 +10648,6 @@ init_quit_char_handler ()
|
|||
|
||||
mac_determine_quit_char_modifiers();
|
||||
}
|
||||
|
||||
static Boolean
|
||||
quit_char_comp (EventRef inEvent, void *inCompData)
|
||||
{
|
||||
if (GetEventClass(inEvent) != kEventClassKeyboard)
|
||||
return false;
|
||||
if (GetEventKind(inEvent) != kEventRawKeyDown)
|
||||
return false;
|
||||
{
|
||||
UInt32 keyCode;
|
||||
UInt32 keyModifiers;
|
||||
GetEventParameter(inEvent, kEventParamKeyCode,
|
||||
typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
|
||||
if (keyCode != mac_quit_char_keycode)
|
||||
return false;
|
||||
GetEventParameter(inEvent, kEventParamKeyModifiers,
|
||||
typeUInt32, NULL, sizeof(UInt32), NULL, &keyModifiers);
|
||||
if (keyModifiers != mac_quit_char_modifiers)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
mac_check_for_quit_char ()
|
||||
{
|
||||
EventRef event;
|
||||
static EMACS_TIME last_check_time = { 0, 0 };
|
||||
static EMACS_TIME one_second = { 1, 0 };
|
||||
EMACS_TIME now, t;
|
||||
|
||||
/* If windows are not initialized, return immediately (keep it bouncin'). */
|
||||
if (!mac_quit_char_modifiers)
|
||||
return;
|
||||
|
||||
/* Don't check if last check is less than a second ago. */
|
||||
EMACS_GET_TIME (now);
|
||||
EMACS_SUB_TIME (t, now, last_check_time);
|
||||
if (EMACS_TIME_LT (t, one_second))
|
||||
return;
|
||||
last_check_time = now;
|
||||
|
||||
/* Redetermine modifiers because they are based on lisp variables */
|
||||
mac_determine_quit_char_modifiers ();
|
||||
|
||||
/* Fill the queue with events */
|
||||
BLOCK_INPUT;
|
||||
ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event);
|
||||
event = FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp,
|
||||
NULL);
|
||||
UNBLOCK_INPUT;
|
||||
if (event)
|
||||
{
|
||||
struct input_event e;
|
||||
|
||||
/* Use an input_event to emulate what the interrupt handler does. */
|
||||
EVENT_INIT (e);
|
||||
e.kind = ASCII_KEYSTROKE_EVENT;
|
||||
e.code = quit_char;
|
||||
e.arg = Qnil;
|
||||
e.modifiers = NULL;
|
||||
e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60);
|
||||
XSETFRAME (e.frame_or_window, mac_focus_frame (&one_mac_display_info));
|
||||
/* Remove event from queue to prevent looping. */
|
||||
RemoveEventFromQueue (GetMainEventQueue (), event);
|
||||
ReleaseEvent (event);
|
||||
kbd_buffer_store_event (&e);
|
||||
}
|
||||
}
|
||||
#endif /* MAC_OSX */
|
||||
|
||||
static void
|
||||
|
@ -10435,6 +10825,11 @@ syms_of_macterm ()
|
|||
Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
|
||||
staticpro (&Qmac_ready_for_drag_n_drop);
|
||||
|
||||
#if USE_ATSUI
|
||||
staticpro (&atsu_font_id_hash);
|
||||
atsu_font_id_hash = Qnil;
|
||||
#endif
|
||||
|
||||
DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
|
||||
doc: /* If not nil, Emacs uses toolkit scroll bars. */);
|
||||
#ifdef USE_TOOLKIT_SCROLL_BARS
|
||||
|
|
Loading…
Add table
Reference in a new issue