Title: [187707] trunk/Source/WebCore
Revision
187707
Author
mmaxfi...@apple.com
Date
2015-07-31 21:06:30 -0700 (Fri, 31 Jul 2015)

Log Message

[OS X] Migrate to CTFontCreateForCharactersWithLanguage from [NSFont findFontLike:forString:withRange:inLanguage]
https://bugs.webkit.org/show_bug.cgi?id=147483

Reviewed by Dean Jackson.

[NSFont findFontLike:forString:withRange:inLanguage] doesn't properly handle its last argument. In
addition, we want to be moving away from NSFont in the first place and on to Core Text. This new
CoreText function correctly handles its language argument, which is required for language-specific
font fallback.

No new tests because there is no behavior change.

* platform/graphics/FontCache.cpp:
(WebCore::FontCache::purgeInactiveFontData):
* platform/graphics/FontCache.h:
(WebCore::FontCache::platformPurgeInactiveFontData):
* platform/graphics/mac/FontCacheMac.mm:
(WebCore::fallbackDedupSet):
(WebCore::FontCache::platformPurgeInactiveFontData):
(WebCore::lookupCTFont):
(WebCore::FontCache::systemFallbackForCharacters):
* platform/spi/cocoa/CoreTextSPI.h:
* platform/spi/mac/NSFontSPI.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (187706 => 187707)


--- trunk/Source/WebCore/ChangeLog	2015-08-01 03:41:07 UTC (rev 187706)
+++ trunk/Source/WebCore/ChangeLog	2015-08-01 04:06:30 UTC (rev 187707)
@@ -1,3 +1,29 @@
+2015-07-31  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        [OS X] Migrate to CTFontCreateForCharactersWithLanguage from [NSFont findFontLike:forString:withRange:inLanguage]
+        https://bugs.webkit.org/show_bug.cgi?id=147483
+
+        Reviewed by Dean Jackson.
+
+        [NSFont findFontLike:forString:withRange:inLanguage] doesn't properly handle its last argument. In
+        addition, we want to be moving away from NSFont in the first place and on to Core Text. This new
+        CoreText function correctly handles its language argument, which is required for language-specific
+        font fallback.
+
+        No new tests because there is no behavior change.
+
+        * platform/graphics/FontCache.cpp:
+        (WebCore::FontCache::purgeInactiveFontData):
+        * platform/graphics/FontCache.h:
+        (WebCore::FontCache::platformPurgeInactiveFontData):
+        * platform/graphics/mac/FontCacheMac.mm:
+        (WebCore::fallbackDedupSet):
+        (WebCore::FontCache::platformPurgeInactiveFontData):
+        (WebCore::lookupCTFont):
+        (WebCore::FontCache::systemFallbackForCharacters):
+        * platform/spi/cocoa/CoreTextSPI.h:
+        * platform/spi/mac/NSFontSPI.h:
+
 2015-07-31  Chris Dumez  <cdu...@apple.com>
 
         Drop dummy Timer callbacks

Modified: trunk/Source/WebCore/platform/graphics/FontCache.cpp (187706 => 187707)


--- trunk/Source/WebCore/platform/graphics/FontCache.cpp	2015-08-01 03:41:07 UTC (rev 187706)
+++ trunk/Source/WebCore/platform/graphics/FontCache.cpp	2015-08-01 04:06:30 UTC (rev 187707)
@@ -414,6 +414,7 @@
 {
     pruneUnreferencedEntriesFromFontCascadeCache();
     pruneSystemFallbackFonts();
+    platformPurgeInactiveFontData();
 
 #if PLATFORM(IOS)
     FontLocker fontLocker;

Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (187706 => 187707)


--- trunk/Source/WebCore/platform/graphics/FontCache.h	2015-08-01 03:41:07 UTC (rev 187706)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h	2015-08-01 04:06:30 UTC (rev 187707)
@@ -150,6 +150,7 @@
     WEBCORE_EXPORT size_t fontCount();
     WEBCORE_EXPORT size_t inactiveFontCount();
     WEBCORE_EXPORT void purgeInactiveFontData(unsigned count = UINT_MAX);
+    void platformPurgeInactiveFontData();
 
 #if PLATFORM(WIN)
     RefPtr<Font> fontFromDescriptionAndLogFont(const FontDescription&, const LOGFONT&, AtomicString& outFontFamilyName);
@@ -184,6 +185,12 @@
     friend class Font;
 };
 
+#if !PLATFORM(MAC)
+inline void FontCache::platformPurgeInactiveFontData()
+{
 }
+#endif
 
+}
+
 #endif

Modified: trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm (187706 => 187707)


--- trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm	2015-08-01 03:41:07 UTC (rev 187706)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm	2015-08-01 04:06:30 UTC (rev 187707)
@@ -459,22 +459,54 @@
     return knownFamilies.get().add(family).isNewEntry;
 }
 
+typedef HashSet<RetainPtr<CTFontRef>, WTF::RetainPtrObjectHash<CTFontRef>, WTF::RetainPtrObjectHashTraits<CTFontRef>> FallbackDedupSet;
+static FallbackDedupSet& fallbackDedupSet()
+{
+    static NeverDestroyed<FallbackDedupSet> dedupSet;
+    return dedupSet.get();
+}
+
+void FontCache::platformPurgeInactiveFontData()
+{
+    // This only has to be consistent throughout an individual layout or paint.
+    fallbackDedupSet().clear();
+}
+
+static inline RetainPtr<CTFontRef> lookupCTFont(CTFontRef font, float fontSize, const UChar* characters, unsigned length)
+{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1090
+    if (!font) {
+        font = reinterpret_cast<CTFontRef>([NSFont userFontOfSize:fontSize]);
+        bool acceptable = true;
+        
+        RetainPtr<CFCharacterSetRef> characterSet = adoptCF(CTFontCopyCharacterSet(font));
+        for (auto character : StringView(characters, length).codePoints()) {
+            if (!CFCharacterSetIsLongCharacterMember(characterSet.get(), character)) {
+                acceptable = false;
+                break;
+            }
+        }
+        if (acceptable)
+            return font;
+    }
+#endif
+    CFIndex coveredLength = 0;
+    return adoptCF(CTFontCreateForCharactersWithLanguage(font, characters, length, nullptr, &coveredLength));
+}
+
 RefPtr<Font> FontCache::systemFallbackForCharacters(const FontDescription& description, const Font* originalFontData, bool isPlatformFont, const UChar* characters, unsigned length)
 {
-    UChar32 character;
-    U16_GET(characters, 0, 0, length, character);
     const FontPlatformData& platformData = originalFontData->platformData();
     NSFont *nsFont = platformData.nsFont();
+    RetainPtr<CTFontRef> result = lookupCTFont(platformData.font(), platformData.size(), characters, length);
+    if (!result)
+        return nullptr;
 
-    NSString *string = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(characters) length:length freeWhenDone:NO];
-    NSFont *substituteFont = [NSFont findFontLike:nsFont forString:string withRange:NSMakeRange(0, [string length]) inLanguage:nil];
-    [string release];
+    // FontCascade::drawGlyphBuffer() requires that there are no duplicate Font objects which refer to the same thing. This is enforced in
+    // FontCache::fontForPlatformData(), where our equality check is based on hashing the FontPlatformData, whose hash includes the raw CoreText
+    // font pointer.
+    NSFont *substituteFont = reinterpret_cast<NSFont *>(const_cast<__CTFont*>(fallbackDedupSet().add(result).iterator->get()));
 
-    if (!substituteFont && length == 1)
-        substituteFont = [NSFont findFontLike:nsFont forCharacter:characters[0] inLanguage:nil];
-    if (!substituteFont)
-        return 0;
-
     // Use the family name from the AppKit-supplied substitute font, requesting the
     // traits, weight, and size we want. One way this does better than the original
     // AppKit request is that it takes synthetic bold and oblique into account.
@@ -508,6 +540,8 @@
 
     if (traits != substituteFontTraits || weight != substituteFontWeight || !nsFont) {
         if (NSFont *bestVariation = [fontManager fontWithFamily:[substituteFont familyName] traits:traits weight:weight size:size]) {
+            UChar32 character;
+            U16_GET(characters, 0, 0, length, character);
             if (!nsFont || (([fontManager traitsOfFont:bestVariation] != substituteFontTraits || [fontManager weightOfFont:bestVariation] != substituteFontWeight)
                 && [[bestVariation coveredCharacterSet] longCharacterIsMember:character]))
                 substituteFont = bestVariation;

Modified: trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h (187706 => 187707)


--- trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h	2015-08-01 03:41:07 UTC (rev 187706)
+++ trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h	2015-08-01 04:06:30 UTC (rev 187707)
@@ -91,6 +91,7 @@
 
 bool CTFontDescriptorIsSystemUIFont(CTFontDescriptorRef);
 CTFontRef CTFontCreateForCSS(CFStringRef name, uint16_t weight, CTFontSymbolicTraits, CGFloat size);
+CTFontRef CTFontCreateForCharactersWithLanguage(CTFontRef currentFont, const UTF16Char *characters, CFIndex length, CFStringRef language, CFIndex *coveredLength);
 
 #if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
 extern const CFStringRef kCTUIFontTextStyleShortHeadline;

Modified: trunk/Source/WebCore/platform/spi/mac/NSFontSPI.h (187706 => 187707)


--- trunk/Source/WebCore/platform/spi/mac/NSFontSPI.h	2015-08-01 03:41:07 UTC (rev 187706)
+++ trunk/Source/WebCore/platform/spi/mac/NSFontSPI.h	2015-08-01 04:06:30 UTC (rev 187707)
@@ -35,9 +35,6 @@
 #else
 
 @interface NSFont (Private)
-+ (NSFont *)findFontLike:(NSFont *)aFont forCharacter:(UInt32)c inLanguage:(id) language;
-+ (NSFont *)findFontLike:(NSFont *)aFont forString:(NSString *)string withRange:(NSRange)range inLanguage:(id) language;
-
 + (NSFont *)systemFontOfSize:(CGFloat)size weight:(CGFloat)weight;
 @end
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to