+static void
+macfont_handle_font_change_notification (CFNotificationCenterRef center,
+ void *observer,
+ CFStringRef name, const void *object,
+ CFDictionaryRef userInfo)
+{
+ macfont_invalidate_family_cache ();
+ macfont_invalidate_available_families_cache ();
+}
+
+static void
+macfont_init_font_change_handler (void)
+{
+ static bool initialized = false;
+
+ if (initialized)
+ return;
+
+ initialized = true;
+ CFNotificationCenterAddObserver
+ (CFNotificationCenterGetLocalCenter (), NULL,
+ macfont_handle_font_change_notification,
+ kCTFontManagerRegisteredFontsChangedNotification,
+ NULL, CFNotificationSuspensionBehaviorCoalesce);
+}
+
+static CFArrayRef
+macfont_copy_available_families_cache (void)
+{
+ macfont_init_font_change_handler ();
+
+ if (macfont_available_families_cache == NULL)
+ macfont_available_families_cache = mac_font_create_available_families ();
+
+ return (macfont_available_families_cache
+ ? CFRetain (macfont_available_families_cache) : NULL);
+}
+
+static CFStringRef
+macfont_create_family_with_symbol (Lisp_Object symbol)
+{
+ CFStringRef result = NULL, family_name;
+ CFDictionaryRef attributes = NULL;
+ CTFontDescriptorRef pat_desc = NULL;
+
+ if (macfont_get_family_cache_if_present (symbol, &result))
+ return result ? CFRetain (result) : NULL;
+
+ family_name = cfstring_create_with_string_noencode (SYMBOL_NAME (symbol));
+ if (family_name)
+ {
+ attributes =
+ CFDictionaryCreate (NULL,
+ (const void **) &kCTFontFamilyNameAttribute,
+ (const void **) &family_name, 1,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFRelease (family_name);
+ }
+ if (attributes)
+ {
+ pat_desc = CTFontDescriptorCreateWithAttributes (attributes);
+ CFRelease (attributes);
+ }
+ if (pat_desc)
+ {
+ CTFontDescriptorRef desc =
+ CTFontDescriptorCreateMatchingFontDescriptor (pat_desc, NULL);