--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+ RenderBlock {P} at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 635x18
+ text run at (0,0) width 635: "The blue text should be identical to, and overlap, the red text, so there should be no red pixels below."
+ RenderBlock {DIV} at (0,34) size 784x144
+ RenderBlock {DIV} at (0,0) size 784x144 [color=#FF0000]
+ RenderText {#text} at (0,0) size 256x144
+ text run at (0,0) width 256: "v a\x{300} e"
+ RenderBlock {DIV} at (0,0) size 784x144
+ RenderText {#text} at (0,0) size 256x144
+ text run at (0,0) width 256: "v \x{E0} e"
+2011-09-29 Dan Bernstein <mitz@apple.com>
+
+ <rdar://problem/10191243> Glyph variants (line final swashes) appear where they should not
+
+ Reviewed by Simon Fraser.
+
+ Test: fast/text/line-initial-and-final-swashes.html
+
+ Hoefler Text Italic enables line-initial and -final swashes by default, so disable them. This
+ change targets only this known-bad font rather than all fonts, because at least one font (Khmer MN)
+ incorrectly claims to have the line-initial feature enabled, but disabling it actually does
+ something different and bad (breaking some combining marks).
+
+ * platform/graphics/cocoa/FontPlatformDataCocoa.mm:
+ (WebCore::createFeatureSettingDictionary): Added this helper function.
+ (WebCore::cascadeToLastResortFontDescriptor): Deployed WTF_ARRAY_LENGTH().
+ (WebCore::cascadeToLastResortAndDisableSwashesFontDescriptor): Added. Returns a font descriptor
+ that, in addition to having a cascade list consisting of the last resort font, also has feature
+ settings to disable line-initial and line-final swashes.
+ (WebCore::FontPlatformData::ctFont): For Hoefler Text Italic, use cascadeToLastResortAndDisableSwashesFontDescriptor().
+
2011-09-29 Mark Hahnenberg <mhahnenberg@apple.com>
Unreviewed: resetting baseline for code generator bindings
return TextSpacingProportional;
}
+static CFDictionaryRef createFeatureSettingDictionary(int featureTypeIdentifier, int featureSelectorIdentifier)
+{
+ RetainPtr<CFNumberRef> featureTypeIdentifierNumber(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &featureTypeIdentifier));
+ RetainPtr<CFNumberRef> featureSelectorIdentifierNumber(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &featureSelectorIdentifier));
+
+ const void* settingKeys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
+ const void* settingValues[] = { featureTypeIdentifierNumber.get(), featureSelectorIdentifierNumber.get() };
+
+ return CFDictionaryCreate(kCFAllocatorDefault, settingKeys, settingValues, WTF_ARRAY_LENGTH(settingKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+}
+
static CTFontDescriptorRef cascadeToLastResortFontDescriptor()
{
static CTFontDescriptorRef descriptor;
const void* keys[] = { kCTFontCascadeListAttribute };
const void* descriptors[] = { CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0) };
- const void* values[] = { CFArrayCreate(kCFAllocatorDefault, descriptors, sizeof(descriptors) / sizeof(*descriptors), &kCFTypeArrayCallBacks) };
- RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys) / sizeof(*keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ const void* values[] = { CFArrayCreate(kCFAllocatorDefault, descriptors, WTF_ARRAY_LENGTH(descriptors), &kCFTypeArrayCallBacks) };
+ RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
descriptor = CTFontDescriptorCreateWithAttributes(attributes.get());
return descriptor;
}
+static CTFontDescriptorRef cascadeToLastResortAndDisableSwashesFontDescriptor()
+{
+ static CTFontDescriptorRef descriptor;
+ if (descriptor)
+ return descriptor;
+
+ RetainPtr<CFDictionaryRef> lineInitialSwashesOffSetting(AdoptCF, createFeatureSettingDictionary(kSmartSwashType, kLineInitialSwashesOffSelector));
+ RetainPtr<CFDictionaryRef> lineFinalSwashesOffSetting(AdoptCF, createFeatureSettingDictionary(kSmartSwashType, kLineFinalSwashesOffSelector));
+
+ const void* settingDictionaries[] = { lineInitialSwashesOffSetting.get(), lineFinalSwashesOffSetting.get() };
+ RetainPtr<CFArrayRef> featureSettings(AdoptCF, CFArrayCreate(kCFAllocatorDefault, settingDictionaries, WTF_ARRAY_LENGTH(settingDictionaries), &kCFTypeArrayCallBacks));
+
+ const void* keys[] = { kCTFontFeatureSettingsAttribute };
+ const void* values[] = { featureSettings.get() };
+ RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ descriptor = CTFontDescriptorCreateCopyWithAttributes(cascadeToLastResortFontDescriptor(), attributes.get());
+
+ return descriptor;
+}
+
// Adding a cascade list breaks the font on Leopard
static bool canSetCascadeListForCustomFont()
{
return m_CTFont.get();
m_CTFont = toCTFontRef(m_font);
- if (m_CTFont)
- m_CTFont.adoptCF(CTFontCreateCopyWithAttributes(m_CTFont.get(), m_size, 0, cascadeToLastResortFontDescriptor()));
- else
+ if (m_CTFont) {
+ CTFontDescriptorRef fontDescriptor;
+ RetainPtr<CFStringRef> postScriptName(AdoptCF, CTFontCopyPostScriptName(m_CTFont.get()));
+ // Hoefler Text Italic has line-initial and -final swashes enabled by default, so disable them.
+ if (CFEqual(postScriptName.get(), CFSTR("HoeflerText-Italic")))
+ fontDescriptor = cascadeToLastResortAndDisableSwashesFontDescriptor();
+ else
+ fontDescriptor = cascadeToLastResortFontDescriptor();
+ m_CTFont.adoptCF(CTFontCreateCopyWithAttributes(m_CTFont.get(), m_size, 0, fontDescriptor));
+ } else
m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, canSetCascadeListForCustomFont() ? cascadeToLastResortFontDescriptor() : 0));
if (m_widthVariant != RegularWidth) {