[Cocoa] Delete unnecessary WebCascadeList in ComplexTextController
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 May 2018 05:29:31 +0000 (05:29 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 May 2018 05:29:31 +0000 (05:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186007

Reviewed by Zalan Bujtas.

Inside ComplexTextController::collectComplexTextRuns(), we chop up text based on which fonts should be
used to render which grapheme clusters. For each grapheme cluster, we run through the font-family list
in FontCascade::fontForCombiningCharacterSequence() and find the first font that can render the cluster.
If no items can render the cluster, we construct a WebCascadeList and let CoreText try to figure out
which fonts can render which clusters.

Except there's no point, because we just determined that no font in the list can be used to render the
cluster. CoreText isn't magic; it isn't going to somehow disagree with us. WebCascadeList is just
useless code.

No new tests because there is no behavior change.

* platform/graphics/mac/ComplexTextControllerCoreText.mm:
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
(-[WebCascadeList initWithFont:character:]): Deleted.
(-[WebCascadeList count]): Deleted.
(-[WebCascadeList objectAtIndex:]): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232223 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm

index 0b5eb7a..a244858 100644 (file)
@@ -1,5 +1,30 @@
 2018-05-25  Myles C. Maxfield  <mmaxfield@apple.com>
 
+        [Cocoa] Delete unnecessary WebCascadeList in ComplexTextController
+        https://bugs.webkit.org/show_bug.cgi?id=186007
+
+        Reviewed by Zalan Bujtas.
+
+        Inside ComplexTextController::collectComplexTextRuns(), we chop up text based on which fonts should be
+        used to render which grapheme clusters. For each grapheme cluster, we run through the font-family list
+        in FontCascade::fontForCombiningCharacterSequence() and find the first font that can render the cluster.
+        If no items can render the cluster, we construct a WebCascadeList and let CoreText try to figure out
+        which fonts can render which clusters.
+
+        Except there's no point, because we just determined that no font in the list can be used to render the
+        cluster. CoreText isn't magic; it isn't going to somehow disagree with us. WebCascadeList is just
+        useless code.
+
+        No new tests because there is no behavior change.
+
+        * platform/graphics/mac/ComplexTextControllerCoreText.mm:
+        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
+        (-[WebCascadeList initWithFont:character:]): Deleted.
+        (-[WebCascadeList count]): Deleted.
+        (-[WebCascadeList objectAtIndex:]): Deleted.
+
+2018-05-25  Myles C. Maxfield  <mmaxfield@apple.com>
+
         Improve the performance of Font::canRenderCombiningCharacterSequence()
         https://bugs.webkit.org/show_bug.cgi?id=185933
 
index 4c01b65..7326db7 100644 (file)
 #include <wtf/WeakPtr.h>
 #include <CoreText/CoreText.h>
 
-// Note: CTFontDescriptorRefs can live forever in caches inside CoreText, so this object can too.
-@interface WebCascadeList : NSArray {
-    @private
-    WeakPtr<WebCore::FontCascade> _font;
-    UChar32 _character;
-    NSUInteger _count;
-    Vector<RetainPtr<CTFontDescriptorRef>, 16> _fontDescriptors;
-}
-
-- (id)initWithFont:(const WebCore::FontCascade*)font character:(UChar32)character;
-
-@end
-
-@implementation WebCascadeList
-
-- (id)initWithFont:(const WebCore::FontCascade*)font character:(UChar32)character
-{
-    if (!(self = [super init]))
-        return nil;
-
-    _font = font->createWeakPtr();
-    _character = character;
-
-    // By the time a WebCascadeList is used, the FontCascade has already been asked to realize all of its
-    // Fonts, so this loop does not hit the FontCache.
-    while (!_font->fallbackRangesAt(_count).isNull())
-        _count++;
-
-    return self;
-}
-
-- (NSUInteger)count
-{
-    return _font ? _count : 0;
-}
-
-- (id)objectAtIndex:(NSUInteger)index
-{
-    if (!_font)
-        return nil;
-
-    CTFontDescriptorRef fontDescriptor;
-    if (index < _fontDescriptors.size()) {
-        if ((fontDescriptor = _fontDescriptors[index].get()))
-            return (id)fontDescriptor;
-    } else
-        _fontDescriptors.grow(index + 1);
-
-    const WebCore::Font* font = _font->fallbackRangesAt(index).fontForCharacter(_character);
-    if (!font)
-        font = &_font->fallbackRangesAt(index).fontForFirstRange();
-    fontDescriptor = CTFontCopyFontDescriptor(font->platformData().ctFont());
-    _fontDescriptors[index] = adoptCF(fontDescriptor);
-    return (id)fontDescriptor;
-}
-
-@end
-
 namespace WebCore {
 
 ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd)
@@ -191,16 +133,9 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
         font = m_font.fallbackRangesAt(0).fontForCharacter(baseCharacter);
         if (!font)
             font = &m_font.fallbackRangesAt(0).fontForFirstRange();
-
-        RetainPtr<WebCascadeList> cascadeList = adoptNS([[WebCascadeList alloc] initWithFont:&m_font character:baseCharacter]);
-
         stringAttributes = adoptCF(CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, font->getCFStringAttributes(m_font.enableKerning(), font->platformData().orientation())));
-        static const void* attributeKeys[] = { kCTFontCascadeListAttribute };
-        const void* values[] = { cascadeList.get() };
-        RetainPtr<CFDictionaryRef> attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, attributeKeys, values, sizeof(attributeKeys) / sizeof(*attributeKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-        RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
-        RetainPtr<CTFontRef> fontWithCascadeList = adoptCF(CTFontCreateCopyWithAttributes(font->platformData().ctFont(), m_font.pixelSize(), 0, fontDescriptor.get()));
-        CFDictionarySetValue(const_cast<CFMutableDictionaryRef>(stringAttributes.get()), kCTFontAttributeName, fontWithCascadeList.get());
+        // We don't know which font should be used to render this grapheme cluster, so enable CoreText's fallback mechanism by using the CTFont which doesn't have CoreText's fallback disabled.
+        CFDictionarySetValue(const_cast<CFMutableDictionaryRef>(stringAttributes.get()), kCTFontAttributeName, font->platformData().font());
     } else
         stringAttributes = font->getCFStringAttributes(m_font.enableKerning(), font->platformData().orientation());
 
@@ -236,6 +171,8 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
         ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID());
         CFRange runRange = CTRunGetStringRange(ctRun);
         const Font* runFont = font;
+        // If isSystemFallback is false, it means we disabled CoreText's font fallback mechanism, which means all the runs must use this exact font.
+        // Therefore, we only need to inspect which font was actually used if isSystemFallback is true.
         if (isSystemFallback) {
             CFDictionaryRef runAttributes = CTRunGetAttributes(ctRun);
             CTFontRef runCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttributes, kCTFontAttributeName));