Index: ui/gfx/font_fallback_mac.mm |
diff --git a/ui/gfx/font_fallback_mac.mm b/ui/gfx/font_fallback_mac.mm |
index 6ad582dcc8edb42bf4307373ff6c44fb8545af35..6cfc7e36b8b713de6d9cfacfd347fcc0279bd98e 100644 |
--- a/ui/gfx/font_fallback_mac.mm |
+++ b/ui/gfx/font_fallback_mac.mm |
@@ -4,32 +4,45 @@ |
#include "ui/gfx/font_fallback.h" |
-#include <dlfcn.h> |
+#include <CoreText/CoreText.h> |
#import <Foundation/Foundation.h> |
-#include <string> |
-#include <vector> |
#include "base/mac/foundation_util.h" |
#import "base/mac/mac_util.h" |
+#include "base/mac/scoped_cftyperef.h" |
#import "base/strings/sys_string_conversions.h" |
#include "ui/gfx/font.h" |
-// TODO(thakis): Remove this prototype once the deployment target is 10.8+. |
-extern "C" CFArrayRef CTFontCopyDefaultCascadeListForLanguages( |
- CTFontRef font, |
- CFArrayRef languagePrefList); |
- |
namespace gfx { |
+namespace { |
+ |
+// CTFontCreateForString() sometimes re-wraps its result in a new CTFontRef with |
+// identical attributes. This wastes time shaping the text run and confounds |
+// Skia's internal typeface cache. |
+bool FontsEqual(CTFontRef lhs, CTFontRef rhs) { |
+ if (lhs == rhs) |
+ return true; |
+ |
+ // Compare ATSFontRef typeface IDs. These are typedef uint32_t. Typically if |
+ // RenderText decided to hunt for a fallback in the first place, this check |
+ // fails and FontsEqual returns here. |
+ if (CTFontGetPlatformFont(lhs, nil) != CTFontGetPlatformFont(rhs, nil)) |
+ return false; |
+ |
+ // Comparing addresses of descriptors seems to be sufficient for other cases. |
+ base::ScopedCFTypeRef<CTFontDescriptorRef> lhs_descriptor( |
+ CTFontCopyFontDescriptor(lhs)); |
+ base::ScopedCFTypeRef<CTFontDescriptorRef> rhs_descriptor( |
+ CTFontCopyFontDescriptor(rhs)); |
+ return lhs_descriptor.get() == rhs_descriptor.get(); |
+} |
+ |
+} // namespace |
std::vector<Font> GetFallbackFonts(const Font& font) { |
// On Mac "There is a system default cascade list (which is polymorphic, based |
// on the user's language setting and current font)" - CoreText Programming |
// Guide. |
- // The CoreText APIs provide CTFontCreateForString(font, string, range), but |
- // it requires a text string "hint", and the returned font can't be |
- // represented by name for easy retrieval later. |
- // In 10.8, CTFontCopyDefaultCascadeListForLanguages(font, language_list) |
- // showed up which is a good fit GetFallbackFonts(). |
NSArray* languages = [[NSUserDefaults standardUserDefaults] |
stringArrayForKey:@"AppleLanguages"]; |
CFArrayRef languages_cf = base::mac::NSToCFCast(languages); |
@@ -56,4 +69,21 @@ std::vector<Font> GetFallbackFonts(const Font& font) { |
return fallback_fonts; |
} |
+bool GetFallbackFont(const Font& font, |
+ const base::char16* text, |
+ int text_length, |
+ Font* result) { |
+ base::ScopedCFTypeRef<CFStringRef> cf_string( |
+ CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, text, text_length, |
+ kCFAllocatorNull)); |
+ CTFontRef ct_font = base::mac::NSToCFCast(font.GetNativeFont()); |
+ base::ScopedCFTypeRef<CTFontRef> ct_result( |
+ CTFontCreateForString(ct_font, cf_string, {0, text_length})); |
+ if (FontsEqual(ct_font, ct_result)) |
+ return false; |
+ |
+ *result = Font(base::mac::CFToNSCast(ct_result.get())); |
+ return true; |
+} |
+ |
} // namespace gfx |