#define GC_BACK_COLOR(gc) (&(gc)->back_color)
#define GC_FONT(gc) ((gc)->xgcv.font)
#define FRAME_NORMAL_GC(f) ((f)->output_data.mac->normal_gc)
-#define CG_SET_FILL_COLOR(context, color) \
+
+#define CG_SET_FILL_COLOR(context, color) \
CGContextSetRGBFillColor (context, \
RED_FROM_ULONG (color) / 255.0f, \
GREEN_FROM_ULONG (color) / 255.0f, \
BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
-#define CG_SET_STROKE_COLOR(context, color) \
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ do { \
+ if (CGColorGetTypeID != NULL) \
+ CGContextSetFillColorWithColor (context, cg_color); \
+ else \
+ CG_SET_FILL_COLOR (context, color); \
+ } while (0)
+#else
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CGContextSetFillColorWithColor (context, cg_color)
+#endif
+#else
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CG_SET_FILL_COLOR (context, color)
+#endif
+#define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, gc) \
+ CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
+ (gc)->cg_fore_color)
+#define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, gc) \
+ CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.background, \
+ (gc)->cg_back_color)
+
+
+#define CG_SET_STROKE_COLOR(context, color) \
CGContextSetRGBStrokeColor (context, \
RED_FROM_ULONG (color) / 255.0f, \
GREEN_FROM_ULONG (color) / 255.0f, \
BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ do { \
+ if (CGColorGetTypeID != NULL) \
+ CGContextSetStrokeColorWithColor (context, cg_color); \
+ else \
+ CG_SET_STROKE_COLOR (context, color); \
+ } while (0)
+#else
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CGContextSetStrokeColorWithColor (context, cg_color)
+#endif
+#else
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CG_SET_STROKE_COLOR (context, color)
+#endif
+#define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, gc) \
+ CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
+ (gc)->cg_fore_color)
+
#if USE_CG_DRAWING
#define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
static int max_fringe_bmp = 0;
static CGImageRef *fringe_bmp = 0;
+static CGColorSpaceRef mac_cg_color_space_rgb;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static CGColorRef mac_cg_color_black;
+#endif
+
+static void
+init_cg_color ()
+{
+ mac_cg_color_space_rgb = CGColorSpaceCreateDeviceRGB ();
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ /* Don't check the availability of CGColorCreate; this symbol is
+ defined even in Mac OS X 10.1. */
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ float rgba[] = {0.0f, 0.0f, 0.0f, 1.0f};
+
+ mac_cg_color_black = CGColorCreate (mac_cg_color_space_rgb, rgba);
+ }
+#endif
+}
+
static CGContextRef
mac_begin_cg_clip (f, gc)
struct frame *f;
gy1 += 0.5f, gy2 += 0.5f;
context = mac_begin_cg_clip (f, gc);
- CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+ CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextBeginPath (context);
CGContextMoveToPoint (context, gx1, gy1);
CGContextAddLineToPoint (context, gx2, gy2);
CGContextRef context;
context = mac_begin_cg_clip (f, gc);
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect (context, CGRectMake (x, y, width, height));
mac_end_cg_clip (f);
#else
GC gc = FRAME_NORMAL_GC (f);
context = mac_begin_cg_clip (f, NULL);
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
FRAME_PIXEL_HEIGHT (f)));
mac_end_cg_clip (f);
context = mac_begin_cg_clip (f, gc);
if (!overlay_p)
{
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect (context, dest_rect);
}
CGContextClipToRect (context, dest_rect);
CGContextScaleCTM (context, 1, -1);
CGContextTranslateCTM (context, 0, -port_height);
if (CGImageIsMask (image))
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextDrawImage (context,
CGRectMake (dest_x - src_x,
port_height - (dest_y - src_y
CGContextRef context;
context = mac_begin_cg_clip (f, gc);
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextFillRect (context, CGRectMake (x, y, width, height));
mac_end_cg_clip (f);
#else
CGContextRef context;
context = mac_begin_cg_clip (f, gc);
- CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+ CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextStrokeRect (context,
CGRectMake (x + 0.5f, y + 0.5f, width, height));
mac_end_cg_clip (f);
#endif
if (bg_width)
{
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect
(context,
CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
#if !USE_CG_DRAWING
}
#endif
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
err = ATSUSetLayoutControls (text_layout,
sizeof (tags) / sizeof (tags[0]),
tags, sizes, values);
UniChar ch = c;
err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
- if (err == noErr)
+ if (err == noErr
+ && (font_ascent_return || font_descent_return || overall_return))
{
ATSTrapezoid glyph_bounds;
#endif
if (bg_width)
{
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect
(context,
CGRectMake (gx, y - FONT_BASE (GC_FONT (gc)),
#if !USE_CG_DRAWING
}
#endif
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextSetFont (context, GC_FONT (gc)->cg_font);
CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize);
if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold)
GC gc = xmalloc (sizeof (*gc));
bzero (gc, sizeof (*gc));
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ gc->cg_fore_color = gc->cg_back_color = mac_cg_color_black;
+ CGColorRetain (gc->cg_fore_color);
+ CGColorRetain (gc->cg_back_color);
+ }
+#endif
XChangeGC (display, gc, mask, xgcv);
return gc;
{
if (gc->clip_region)
DisposeRgn (gc->clip_region);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ CGColorRelease (gc->cg_fore_color);
+ CGColorRelease (gc->cg_back_color);
+#endif
xfree (gc);
}
gc->fore_color.red = RED16_FROM_ULONG (color);
gc->fore_color.green = GREEN16_FROM_ULONG (color);
gc->fore_color.blue = BLUE16_FROM_ULONG (color);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ CGColorRelease (gc->cg_fore_color);
+ if (color == 0)
+ {
+ gc->cg_fore_color = mac_cg_color_black;
+ CGColorRetain (gc->cg_fore_color);
+ }
+ else
+ {
+ float rgba[4];
+
+ rgba[0] = gc->fore_color.red / 65535.0f;
+ rgba[1] = gc->fore_color.green / 65535.0f;
+ rgba[2] = gc->fore_color.blue / 65535.0f;
+ rgba[3] = 1.0f;
+ gc->cg_fore_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+ }
+ }
+#endif
}
}
gc->back_color.red = RED16_FROM_ULONG (color);
gc->back_color.green = GREEN16_FROM_ULONG (color);
gc->back_color.blue = BLUE16_FROM_ULONG (color);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ CGColorRelease (gc->cg_back_color);
+ if (color == 0)
+ {
+ gc->cg_back_color = mac_cg_color_black;
+ CGColorRetain (gc->cg_back_color);
+ }
+ else
+ {
+ float rgba[4];
+
+ rgba[0] = gc->back_color.red / 65535.0f;
+ rgba[1] = gc->back_color.green / 65535.0f;
+ rgba[2] = gc->back_color.blue / 65535.0f;
+ rgba[3] = 1.0f;
+ gc->cg_back_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+ }
+ }
+#endif
}
}
static Lisp_Object atsu_font_id_hash;
/* Alist linking Font Manager style to face attributes. */
static Lisp_Object fm_style_face_attributes_alist;
-static Lisp_Object Vmac_atsu_font_table;
extern Lisp_Object QCfamily, QCweight, QCslant, Qnormal, Qbold, Qitalic;
#endif
}
#if USE_ATSUI
+static FMFontStyle
+fm_get_style_from_font (font)
+ FMFont font;
+{
+ OSStatus err;
+ FMFontStyle style = normal;
+ ByteCount len;
+ UInt16 mac_style;
+ FMFontFamily font_family;
+#define FONT_HEADER_MAC_STYLE_OFFSET (4*4 + 2*2 + 8*2 + 2*4)
+
+ /* FMGetFontFamilyInstanceFromFont returns `normal' as the style of
+ some font (e.g., Optima) even if it is `bold'. */
+ err = FMGetFontTable (font, 'head', FONT_HEADER_MAC_STYLE_OFFSET,
+ sizeof (mac_style), &mac_style, &len);
+ if (err == noErr
+ && len >= FONT_HEADER_MAC_STYLE_OFFSET + sizeof (mac_style))
+ style = EndianU16_BtoN (mac_style);
+ else
+ FMGetFontFamilyInstanceFromFont (font, &font_family, &style);
+
+ return style;
+}
+
+static ATSUFontID
+atsu_find_font_from_family_name (family)
+ const char *family;
+{
+ struct Lisp_Hash_Table *h = XHASH_TABLE (atsu_font_id_hash);
+ unsigned hash_code;
+ int i;
+ Lisp_Object rest, best;
+ FMFontStyle min_style, style;
+
+ i = hash_lookup (h, make_unibyte_string (family, strlen (family)),
+ &hash_code);
+ if (i < 0)
+ return kATSUInvalidFontID;
+
+ rest = HASH_VALUE (h, i);
+ if (INTEGERP (rest) || (CONSP (rest) && INTEGERP (XCDR (rest))))
+ return cons_to_long (rest);
+
+ rest = Fnreverse (rest);
+ best = XCAR (rest);
+ rest = XCDR (rest);
+ if (!NILP (rest)
+ && (min_style = fm_get_style_from_font (cons_to_long (best))) != normal)
+ do
+ {
+ style = fm_get_style_from_font (cons_to_long (XCAR (rest)));
+ if (style < min_style)
+ {
+ best = XCAR (rest);
+ if (style == normal)
+ break;
+ else
+ min_style = style;
+ }
+ rest = XCDR (rest);
+ }
+ while (!NILP (rest));
+
+ HASH_VALUE (h, i) = best;
+ return cons_to_long (best);
+}
+
static Lisp_Object
fm_style_to_face_attributes (fm_style)
FMFontStyle fm_style;
return tem;
}
+
+static Lisp_Object
+atsu_find_font_family_name (font_id)
+ ATSUFontID font_id;
+{
+ OSStatus err;
+ ByteCount len;
+ Lisp_Object family = Qnil;
+
+ err = ATSUFindFontName (font_id, kFontFamilyName,
+ kFontMacintoshPlatform, kFontNoScript,
+ kFontNoLanguage, 0, NULL, &len, NULL);
+ if (err == noErr)
+ {
+ family = make_uninit_string (len);
+ err = ATSUFindFontName (font_id, kFontFamilyName,
+ kFontMacintoshPlatform, kFontNoScript,
+ kFontNoLanguage, len, SDATA (family),
+ NULL, NULL);
+ }
+ if (err == noErr)
+ decode_mac_font_name (SDATA (family), len + 1, Qnil);
+
+ return family;
+}
+
+Lisp_Object
+mac_atsu_font_face_attributes (font_id)
+ ATSUFontID font_id;
+{
+ Lisp_Object family, style_attrs;
+
+ family = atsu_find_font_family_name (font_id);
+ if (NILP (family))
+ return Qnil;
+ style_attrs = fm_style_to_face_attributes (fm_get_style_from_font (font_id));
+ return Fcons (QCfamily, Fcons (family, style_attrs));
+}
#endif
/* Sets up the table font_name_table to contain the list of all fonts
unsigned hash_code;
ItemCount nfonts, i;
ATSUFontID *font_ids = NULL;
- Ptr name;
- ByteCount name_len;
- Lisp_Object family;
+ Lisp_Object prev_family = Qnil;
+ int j;
atsu_font_id_hash =
make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
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)
+ Lisp_Object family;
+
+ family = atsu_find_font_family_name (font_ids[i]);
+ if (NILP (family) || SREF (family, 0) == '.')
continue;
- name = xmalloc (name_len + 1);
- name[name_len] = '\0';
- err = ATSUFindFontName (font_ids[i], kFontFamilyName,
- kFontMacintoshPlatform, kFontNoScript,
- kFontNoLanguage, name_len, name,
- NULL, NULL);
- if (err == noErr)
+ if (!NILP (Fequal (prev_family, family)))
+ family = prev_family;
+ else
+ j = hash_lookup (h, family, &hash_code);
+ if (j < 0)
{
- FMFontFamily ff;
- FMFontStyle style = normal;
-
- decode_mac_font_name (name, name_len + 1, Qnil);
- family = make_unibyte_string (name, name_len);
- FMGetFontFamilyInstanceFromFont (font_ids[i], &ff, &style);
- Fputhash ((font_ids[i] > MOST_POSITIVE_FIXNUM
- ? make_float (font_ids[i])
- : make_number (font_ids[i])),
- Fcons (QCfamily,
- Fcons (family,
- fm_style_to_face_attributes (style))),
- Vmac_atsu_font_table);
- if (*name != '.'
- && hash_lookup (h, family, &hash_code) < 0)
- {
- add_mac_font_name (name, 0, normal, "iso10646-1");
- hash_put (h, family, long_to_cons (font_ids[i]),
- hash_code);
- }
+ add_mac_font_name (SDATA (family), 0, normal, "iso10646-1");
+ j = hash_put (h, family, Fcons (long_to_cons (font_ids[i]),
+ Qnil), hash_code);
}
- xfree (name);
+ else if (EQ (prev_family, family))
+ HASH_VALUE (h, j) = Fcons (long_to_cons (font_ids[i]),
+ HASH_VALUE (h, j));
+ prev_family = family;
}
if (font_ids)
xfree (font_ids);
{kAllTypographicFeaturesType, kDiacriticsType};
static const ATSUFontFeatureSelector selectors[] =
{kAllTypeFeaturesOffSelector, kDecomposeDiacriticsSelector};
- Lisp_Object font_id_cons;
FMFontStyle style;
- font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)),
- atsu_font_id_hash, Qnil);
- if (NILP (font_id_cons))
- return NULL;
- font_id = cons_to_long (font_id_cons);
+ font_id = atsu_find_font_from_family_name (family);
+ if (font_id == kATSUInvalidFontID)
+ return;
size_fixed = Long2Fix (size);
bold_p = (fontface & bold) != 0;
italic_p = (fontface & italic) != 0;
continue;
else if (c == 0x7f)
{
- c = 0x9f;
- continue;
+#if USE_CG_TEXT_DRAWING
+ if (font->cg_glyphs)
+ {
+ c = 0x9f;
+ pcm = NULL;
+ continue;
+ }
+#endif
+ break;
}
- mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
+ mac_query_char_extents (font->mac_style, c, NULL, NULL,
+ pcm ? pcm + c : NULL,
#if USE_CG_TEXT_DRAWING
(font->cg_glyphs ? font->cg_glyphs + c
: NULL)
font->cg_font = NULL;
xfree (font->cg_glyphs);
font->cg_glyphs = NULL;
+ if (pcm == NULL)
+ break;
}
#endif
}
else
#endif
{
+ OSStatus err;
FontInfo the_fontinfo;
int is_two_byte_font;
sizeof (XCharStruct) * (0xff - 0x20 + 1));
space_bounds = font->bounds.per_char;
- mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
- space_bounds, NULL);
+ err = mac_query_char_extents (NULL, 0x20, &font->ascent,
+ &font->descent, space_bounds, NULL);
+ if (err != noErr || space_bounds->width <= 0)
+ {
+ mac_unload_font (&one_mac_display_info, font);
+ return NULL;
+ }
for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
extern OSErr init_coercion_handler P_ ((void));
/* Drag and Drop */
-OSErr install_drag_handler P_ ((WindowRef));
-void remove_drag_handler P_ ((WindowRef));
+extern OSErr install_drag_handler P_ ((WindowRef));
+extern void remove_drag_handler P_ ((WindowRef));
+
+/* Showing help echo string during menu tracking */
+extern OSStatus install_menu_target_item_handler P_ ((WindowPtr));
#if USE_CARBON_EVENTS
#ifdef MAC_OSX
extern void init_service_handler ();
static Lisp_Object Qservice, Qpaste, Qperform;
#endif
+
/* Window Event Handler */
static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
EventRef, void *);
{
mac_store_apple_event (class_key, id_key, &apple_event);
AEDisposeDesc (&apple_event);
- /* Post a harmless event so as to wake up from
- ReceiveNextEvent. */
- mac_post_mouse_moved_event ();
+ mac_wakeup_from_rne ();
}
}
}
#endif
if (err == noErr)
err = install_drag_handler (window);
+ if (err == noErr)
+ err = install_menu_target_item_handler (window);
return err;
}
#if __MWERKS__
/* set creator and type for files created by MSL */
- _fcreator = 'EMAx';
+ _fcreator = MAC_EMACS_CREATOR_CODE;
_ftype = 'TEXT';
#endif
#else
FrontWindow ()
#endif
- != window_ptr)
+ != window_ptr
+ || (mac_window_to_frame (window_ptr)
+ != dpyinfo->x_focus_frame))
SelectWindow (window_ptr);
else
{
#endif
#if USE_CG_DRAWING
+ init_cg_color ();
+
mac_init_fringe ();
#endif
Fcons (list3 (build_string ("mac-roman"),
make_number (smRoman), Qnil), Qnil);
-#if USE_ATSUI
- DEFVAR_LISP ("mac-atsu-font-table", &Vmac_atsu_font_table,
- doc: /* Hash table of ATSU font IDs vs plist of attributes and values. */);
- Vmac_atsu_font_table =
- make_hash_table (Qeql, make_number (DEFAULT_HASH_SIZE),
- make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil, Qnil);
-#endif
#if USE_MAC_TSM
DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
doc: /* Overlay used to display Mac TSM active input area. */);