https://bugs.webkit.org/show_bug.cgi?id=138683
Reviewed by Darin Adler.
This patch changes how we check fonts for equality. In particular, this patch adds a
objectForEqualityCheck() to Cocoa's FontPlatformData, and callers should pass this object
to CFEqual() to determine if two platform fonts are equal. This patch also migrates all
call sites to using this function.
I don't want to implement operator==() because there are many cases where the same font
is compared against many others, and this solution is cleaner than caching a comparison
object inside the font object itself.
No new tests because this is covered by platform/mac/editing/input/devanagari-ligature.html.
* platform/graphics/FontPlatformData.h:
* platform/graphics/cocoa/FontPlatformDataCocoa.mm:
(WebCore::FontPlatformData::objectForEqualityCheck):
* platform/graphics/mac/ComplexTextControllerCoreText.mm:
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* platform/graphics/mac/GlyphPageTreeNodeMac.cpp:
(WebCore::GlyphPage::fill):
* platform/graphics/mac/SimpleFontDataMac.mm:
(WebCore::SimpleFontData::canRenderCombiningCharacterSequence):
* platform/spi/cocoa/CoreTextSPI.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177689
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-12-23 Myles C. Maxfield <mmaxfield@apple.com>
+
+ platform/mac/editing/input/devanagari-ligature.html is flaky on Yosemite, ligature fails to form
+ https://bugs.webkit.org/show_bug.cgi?id=138683
+
+ Reviewed by Darin Adler.
+
+ This patch changes how we check fonts for equality. In particular, this patch adds a
+ objectForEqualityCheck() to Cocoa's FontPlatformData, and callers should pass this object
+ to CFEqual() to determine if two platform fonts are equal. This patch also migrates all
+ call sites to using this function.
+
+ I don't want to implement operator==() because there are many cases where the same font
+ is compared against many others, and this solution is cleaner than caching a comparison
+ object inside the font object itself.
+
+ No new tests because this is covered by platform/mac/editing/input/devanagari-ligature.html.
+
+ * platform/graphics/FontPlatformData.h:
+ * platform/graphics/cocoa/FontPlatformDataCocoa.mm:
+ (WebCore::FontPlatformData::objectForEqualityCheck):
+ * platform/graphics/mac/ComplexTextControllerCoreText.mm:
+ (WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
+ * platform/graphics/mac/GlyphPageTreeNodeMac.cpp:
+ (WebCore::GlyphPage::fill):
+ * platform/graphics/mac/SimpleFontDataMac.mm:
+ (WebCore::SimpleFontData::canRenderCombiningCharacterSequence):
+ * platform/spi/cocoa/CoreTextSPI.h:
+
2014-12-23 Myles C. Maxfield <mmaxfield@apple.com>
[SVG -> OTF Converter] Make Placeholder a move-only type
void setFont(CTFontRef);
CTFontRef ctFont() const;
+ static RetainPtr<CFTypeRef> objectForEqualityCheck(CTFontRef);
+ RetainPtr<CFTypeRef> objectForEqualityCheck() const;
bool allowsLigatures() const;
bool roundsGlyphAdvances() const;
#import "config.h"
#import "FontPlatformData.h"
+#import "CoreTextSPI.h"
#import "SharedBuffer.h"
#import "WebCoreSystemInterface.h"
#import <wtf/text/WTFString.h>
return m_ctFont.get();
}
+RetainPtr<CFTypeRef> FontPlatformData::objectForEqualityCheck(CTFontRef ctFont)
+{
+#if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED <= 80000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000)
+ auto fontDescriptor = adoptCF(CTFontCopyFontDescriptor(ctFont));
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=138683 This is a shallow pointer compare for web fonts
+ // because the URL contains the address of the font. This means we might erroneously get false negatives.
+ RetainPtr<CFURLRef> url = adoptCF(static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(fontDescriptor.get(), kCTFontReferenceURLAttribute)));
+ ASSERT(CFGetTypeID(url.get()) == CFURLGetTypeID());
+ return url;
+#else
+ return adoptCF(CTFontCopyGraphicsFont(ctFont, 0));
+#endif
+}
+
+RetainPtr<CFTypeRef> FontPlatformData::objectForEqualityCheck() const
+{
+ return objectForEqualityCheck(ctFont());
+}
+
PassRefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
{
if (RetainPtr<CFDataRef> data = adoptCF(CGFontCopyTableForTag(cgFont(), table)))
CFDictionaryRef runAttributes = CTRunGetAttributes(ctRun);
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttributes, kCTFontAttributeName));
ASSERT(CFGetTypeID(runFont) == CTFontGetTypeID());
- if (!CFEqual(runFont, fontData->platformData().ctFont())) {
+ RetainPtr<CFTypeRef> runFontEqualityObject = FontPlatformData::objectForEqualityCheck(runFont);
+ if (!CFEqual(runFontEqualityObject.get(), fontData->platformData().objectForEqualityCheck().get())) {
// Begin trying to see if runFont matches any of the fonts in the fallback list.
- RetainPtr<CGFontRef> runCGFont = adoptCF(CTFontCopyGraphicsFont(runFont, 0));
unsigned i = 0;
for (const FontData* candidateFontData = m_font.fontDataAt(i); candidateFontData; candidateFontData = m_font.fontDataAt(++i)) {
runFontData = candidateFontData->fontDataForCharacter(baseCharacter);
- RetainPtr<CGFontRef> cgFont = adoptCF(CTFontCopyGraphicsFont(runFontData->platformData().ctFont(), 0));
- if (CFEqual(cgFont.get(), runCGFont.get()))
+ RetainPtr<CFTypeRef> runFontEqualityObject = runFontData->platformData().objectForEqualityCheck();
+ if (CFEqual(runFontEqualityObject.get(), runFontEqualityObject.get()))
break;
runFontData = 0;
}
Vector<CFIndex, 512> indexVector;
bool done = false;
- // For the CGFont comparison in the loop, use the CGFont that Core Text assigns to the CTFont. This may
- // be non-CFEqual to fontData->platformData().cgFont().
- RetainPtr<CGFontRef> cgFont = adoptCF(CTFontCopyGraphicsFont(fontData->platformData().ctFont(), 0));
+ RetainPtr<CFTypeRef> fontEqualityObject = fontData->platformData().objectForEqualityCheck();
for (CFIndex r = 0; r < runCount && !done ; ++r) {
// CTLine could map characters over multiple fonts using its own font fallback list.
CFDictionaryRef attributes = CTRunGetAttributes(ctRun);
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName));
- RetainPtr<CGFontRef> runCGFont = adoptCF(CTFontCopyGraphicsFont(runFont, 0));
- // Use CGFont here as CFEqual for CTFont counts all attributes for font.
- bool gotBaseFont = CFEqual(cgFont.get(), runCGFont.get());
+ bool gotBaseFont = CFEqual(fontEqualityObject.get(), FontPlatformData::objectForEqualityCheck(runFont).get());
if (gotBaseFont || fontData->platformData().isCompositeFontReference()) {
// This run uses the font we want. Extract glyphs.
CFIndex glyphCount = CTRunGetGlyphCount(ctRun);
if (!addResult.isNewEntry)
return addResult.iterator->value;
- RetainPtr<CGFontRef> cgFont = adoptCF(CTFontCopyGraphicsFont(platformData().ctFont(), 0));
+ RetainPtr<CFTypeRef> fontEqualityObject = platformData().objectForEqualityCheck();
ProviderInfo info = { characters, length, getCFStringAttributes(0, platformData().orientation()) };
RetainPtr<CTLineRef> line = adoptCF(CTLineCreateWithUniCharProvider(&provideStringAndAttributes, 0, &info));
ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID());
CFDictionaryRef runAttributes = CTRunGetAttributes(ctRun);
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttributes, kCTFontAttributeName));
- RetainPtr<CGFontRef> runCGFont = adoptCF(CTFontCopyGraphicsFont(runFont, 0));
- if (!CFEqual(runCGFont.get(), cgFont.get()))
+ if (!CFEqual(fontEqualityObject.get(), FontPlatformData::objectForEqualityCheck(runFont).get()))
return false;
}
typedef const UniChar* (*CTUniCharProviderCallback)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void* refCon);
typedef void (*CTUniCharDisposeCallback)(const UniChar* chars, void* refCon);
+extern const CFStringRef kCTFontReferenceURLAttribute;
+
#if PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1080)
#if !USE(APPLE_INTERNAL_SDK)
typedef CF_OPTIONS(uint32_t, CTFontTransformOptions)