Changeset 95391 in webkit
- Timestamp:
- Sep 18, 2011 9:52:31 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r95390 r95391 1 2011-09-18 Dan Bernstein <mitz@apple.com> 2 3 <rdar://problem/7860281> Decomposed text is displayed incorrectly when Verdana is specified 4 https://bugs.webkit.org/show_bug.cgi?id=68287 5 6 Reviewed by Dave Hyatt. 7 8 * platform/mac/fast/text/combining-character-sequence-fallback.html: Added. 9 * platform/mac/platform/mac/fast/text/combining-character-sequence-fallback-expected.png: Added. 10 * platform/mac/platform/mac/fast/text/combining-character-sequence-fallback-expected.txt: Added. 11 1 12 2011-09-18 Dan Bernstein <mitz@apple.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r95387 r95391 1 2011-09-18 Dan Bernstein <mitz@apple.com> 2 3 Allow Core Text to choose the fallback font for rendering a combining character sequence 4 5 Fixes <rdar://problem/7860281> Decomposed text is displayed incorrectly when Verdana is specified 6 https://bugs.webkit.org/show_bug.cgi?id=68287 7 8 Reviewed by Dave Hyatt. 9 10 Test: platform/mac/fast/text/combining-character-sequence-fallback.html 11 12 * WebCore.xcodeproj/project.pbxproj: Compile ComplexTextControllerCoreText.cpp as Objective-C++. 13 I am going to rename this file in a followup patch. 14 15 * platform/graphics/Font.h: Declared fontDataForCombiningCharacterSequence(). 16 17 * platform/graphics/SimpleFontData.h: Declared canRenderCombiningCharacterSequence() and added 18 a member variable to cache the results of calling this function. 19 20 * platform/graphics/mac/ComplexTextController.cpp: 21 (WebCore::ComplexTextController::offsetForPosition): Fixed a typo in a comment. 22 (WebCore::advanceByCombiningCharacterSequence): Added this helper function, which iterates over 23 characters until the end of a sequence of combining characters, zero-width joiners and zero-width 24 non-joiners. A single base characater followed by such a (possibly-empty) sequence is known as 25 a combining character sequence. This stretches the definition a little because the base character 26 may be a combining character as well. Returns false if an invalid UTF-16 sequence is encountered, 27 true otherwise. 28 (WebCore::ComplexTextController::collectComplexTextRuns): - Replaced the glyphData and nextGlyphData 29 variables each with a pair of variables, a SimpleFontData* and a boolean indicating whether a 30 character mapped to the missing glyph. This clarifies that this function does not use glyph IDs. 31 - Renamed the local variable newC to uppercaseCharacter. 32 - Changed to use advanceByCombiningCharacterSequence(). 33 - Changed to use Font::fontDataForCombiningCharacterSequence() instead of Font::glyphDataForCharacter(). 34 If there are combining marks and none of the fonts in the fallback list can render the sequence alone, 35 use the systemFallbackFontData() constant to indicate to collectComplexTextRunsForCharactersCoreText() 36 to allow Core Text to perform its own fallback. 37 - Stopped checking isSmallCaps against nextIsSmallCaps. It was redundant, since the small caps FontData 38 differs from the normal variant. 39 (WebCore::ComplexTextController::collectComplexTextRunsForCharacters): Moved the common logic to 40 handle the 0 fontData case from the ATSUI and Core Text continuations of this function into this function. 41 42 * platform/graphics/mac/ComplexTextController.h: 43 (WebCore::ComplexTextController::systemFallbackFontData): Added. This constant is used to indicate to 44 collectComplexTextRunsForCharactersCoreText() that it should allow Core Text to perform its own font 45 fallback. 46 47 * platform/graphics/mac/ComplexTextControllerATSUI.cpp: 48 (WebCore::ComplexTextController::collectComplexTextRunsForCharactersATSUI): Handle systemFallbackFontData() 49 by using the primary font data. 50 51 * platform/graphics/mac/ComplexTextControllerCoreText.cpp: 52 (-[CascadeList initWithFont:WebCore::character:]): Added. 53 (-[CascadeList count]): Added. 54 (-[CascadeList objectAtIndex:]): Added. Returns an entry from a cascade list of CTFontDescriptorRef 55 objects based on the font’s fallback list for the character. The list is initialized lazily. 56 (WebCore::ComplexTextController::collectComplexTextRunsForCharactersCoreText): Handle systemFallbackFontData() 57 by allowing Core Text to perform font fallback, starting with a cascade list based on the font’s fallback 58 list and possibly continuing with system fallback. 59 60 * platform/graphics/mac/FontMac.mm: 61 (WebCore::Font::fontDataForCombiningCharacterSequence): Added. If the sequence is only a base character, 62 calls through to glyphDataForCharacter(). Otherwise, iterates over the font’s fallback list for the 63 base character (and the system fallback font for that character), returning the first font that can 64 render the sequence, or 0 if there is none. 65 66 * platform/graphics/mac/SimpleFontDataMac.mm: 67 (WebCore::provideStringAndAttributes): Added this Core Text callback. 68 (WebCore::SimpleFontData::canRenderCombiningCharacterSequence): Added. Checks if Core Text can render 69 the sequence using only this font. Caches the result. 70 1 71 2011-09-17 Mihai Parparita <mihaip@chromium.org> 2 72 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r95372 r95391 7446 7446 37C2360F1097EE7700EF9F72 /* ComplexTextController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComplexTextController.h; sourceTree = "<group>"; }; 7447 7447 37C2381F1098C84200EF9F72 /* ComplexTextControllerATSUI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexTextControllerATSUI.cpp; sourceTree = "<group>"; }; 7448 37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexTextControllerCoreText.cpp; sourceTree = "<group>"; };7448 37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = ComplexTextControllerCoreText.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 7449 7449 37C28A6710F659CC008C7813 /* TypesettingFeatures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypesettingFeatures.h; sourceTree = "<group>"; }; 7450 7450 37C61F0012095C87007A3C67 /* AtomicStringKeyedMRUCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicStringKeyedMRUCache.h; sourceTree = "<group>"; }; -
trunk/Source/WebCore/platform/graphics/Font.h
r89733 r95391 140 140 const FontData* fontDataAt(unsigned) const; 141 141 GlyphData glyphDataForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const; 142 #if PLATFORM(MAC) 143 const SimpleFontData* fontDataForCombiningCharacterSequence(const UChar*, size_t length, FontDataVariant) const; 144 #endif 142 145 std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const; 143 146 bool primaryFontHasGlyphForCharacter(UChar32) const; -
trunk/Source/WebCore/platform/graphics/SimpleFontData.h
r90167 r95391 35 35 #include <wtf/OwnPtr.h> 36 36 #include <wtf/PassOwnPtr.h> 37 #include <wtf/text/StringHash.h> 37 38 38 39 #if USE(ATSUI) … … 177 178 #endif 178 179 180 #if PLATFORM(MAC) 181 bool canRenderCombiningCharacterSequence(const UChar*, size_t) const; 182 #endif 183 179 184 #if USE(ATSUI) 180 185 void checkShapesArabic() const; … … 290 295 #endif 291 296 297 #if PLATFORM(MAC) 298 mutable OwnPtr<HashMap<String, bool> > m_combiningCharacterSequenceSupport; 299 #endif 300 292 301 #if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX)) 293 302 bool m_isSystemFont; -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
r90798 r95391 152 152 // FIXME: The search stops at the boundaries of complexTextRun. In theory, it should go on into neighboring ComplexTextRuns 153 153 // derived from the same CTLine. In practice, we do not expect there to be more than one CTRun in a CTLine, as no 154 // reordering and onfont fallback should occur within a CTLine.154 // reordering and no font fallback should occur within a CTLine. 155 155 if (clusterEnd - clusterStart > 1) { 156 156 clusterWidth = adjustedAdvance; … … 185 185 } 186 186 187 static bool advanceByCombiningCharacterSequence(const UChar*& iterator, const UChar* end, UChar32& baseCharacter, unsigned& markCount) 188 { 189 ASSERT(iterator < end); 190 191 markCount = 0; 192 193 baseCharacter = *iterator++; 194 195 if (U16_IS_SURROGATE(baseCharacter)) { 196 if (!U16_IS_LEAD(baseCharacter)) 197 return false; 198 if (iterator == end) 199 return false; 200 UChar trail = *iterator++; 201 if (!U16_IS_TRAIL(trail)) 202 return false; 203 baseCharacter = U16_GET_SUPPLEMENTARY(baseCharacter, trail); 204 } 205 206 // Consume marks. 207 while (iterator < end && ((U_GET_GC_MASK(*iterator) & U_GC_M_MASK) || *iterator == zeroWidthJoiner || *iterator == zeroWidthNonJoiner)) { 208 iterator++; 209 markCount++; 210 } 211 212 return true; 213 } 214 187 215 void ComplexTextController::collectComplexTextRuns() 188 216 { … … 190 218 return; 191 219 192 // We break up glyph run generation for the string by FontData and (if needed) the use of small caps.220 // We break up glyph run generation for the string by FontData. 193 221 const UChar* cp = m_run.characters(); 194 222 … … 200 228 const UChar* end = cp + m_end; 201 229 202 GlyphData glyphData;203 GlyphData nextGlyphData;204 205 bool isSurrogate = U16_IS_SURROGATE(*curr);206 if (isSurrogate) { 207 if (!U16_IS_SURROGATE_LEAD(curr[0]) || curr + 1 == end || !U16_IS_TRAIL(curr[1]))208 return;209 nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[0], curr[1]), false);210 } else211 nextGlyphData = m_font.glyphDataForCharacter(*curr, false);212 213 UChar newC= 0;230 const SimpleFontData* fontData; 231 bool isMissingGlyph; 232 const SimpleFontData* nextFontData; 233 bool nextIsMissingGlyph; 234 235 unsigned markCount; 236 const UChar* sequenceStart = curr; 237 UChar32 baseCharacter; 238 if (!advanceByCombiningCharacterSequence(curr, end, baseCharacter, markCount)) 239 return; 240 241 UChar uppercaseCharacter = 0; 214 242 215 243 bool isSmallCaps; 216 bool nextIsSmallCaps = !isSurrogate && m_font.isSmallCaps() && !(U_GET_GC_MASK(*curr) & U_GC_M_MASK) && (newC = u_toupper(*curr)) != *curr; 217 218 if (nextIsSmallCaps) 219 m_smallCapsBuffer[curr - cp] = newC; 220 221 while (true) { 222 curr = curr + (isSurrogate ? 2 : 1); 223 if (curr == end) 224 break; 225 226 glyphData = nextGlyphData; 244 bool nextIsSmallCaps = m_font.isSmallCaps() && !(U_GET_GC_MASK(baseCharacter) & U_GC_M_MASK) && (uppercaseCharacter = u_toupper(baseCharacter)) != baseCharacter; 245 246 if (nextIsSmallCaps) { 247 m_smallCapsBuffer[sequenceStart - cp] = uppercaseCharacter; 248 for (unsigned i = 0; i < markCount; ++i) 249 m_smallCapsBuffer[sequenceStart - cp + i + 1] = sequenceStart[i + 1]; 250 } 251 252 nextIsMissingGlyph = false; 253 nextFontData = m_font.fontDataForCombiningCharacterSequence(sequenceStart, curr - sequenceStart, nextIsSmallCaps ? SmallCapsVariant : NormalVariant); 254 if (!nextFontData) { 255 if (markCount) 256 nextFontData = systemFallbackFontData(); 257 else 258 nextIsMissingGlyph = true; 259 } 260 261 while (curr < end) { 262 fontData = nextFontData; 263 isMissingGlyph = nextIsMissingGlyph; 227 264 isSmallCaps = nextIsSmallCaps; 228 265 int index = curr - cp; 229 isSurrogate = U16_IS_SURROGATE(*curr); 230 UChar c = *curr; 231 bool forceSmallCaps = !isSurrogate && isSmallCaps && (U_GET_GC_MASK(c) & U_GC_M_MASK); 232 if (isSurrogate) { 233 if (!U16_IS_SURROGATE_LEAD(curr[0]) || curr + 1 == end || !U16_IS_TRAIL(curr[1])) 234 return; 235 nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[0], curr[1]), false); 236 } else 237 nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps ? SmallCapsVariant : AutoVariant); 238 239 if (!isSurrogate && m_font.isSmallCaps()) { 240 nextIsSmallCaps = forceSmallCaps || (newC = u_toupper(c)) != c; 241 if (nextIsSmallCaps) 242 m_smallCapsBuffer[index] = forceSmallCaps ? c : newC; 266 267 if (!advanceByCombiningCharacterSequence(curr, end, baseCharacter, markCount)) 268 return; 269 270 if (m_font.isSmallCaps()) { 271 nextIsSmallCaps = (uppercaseCharacter = u_toupper(baseCharacter)) != baseCharacter; 272 if (nextIsSmallCaps) { 273 m_smallCapsBuffer[index] = uppercaseCharacter; 274 for (unsigned i = 0; i < markCount; ++i) 275 m_smallCapsBuffer[index + i + 1] = cp[index + i + 1]; 276 } 243 277 } 244 278 245 if (nextGlyphData.fontData != glyphData.fontData || nextIsSmallCaps != isSmallCaps || !nextGlyphData.glyph != !glyphData.glyph) { 279 nextIsMissingGlyph = false; 280 nextFontData = m_font.fontDataForCombiningCharacterSequence(cp + index, curr - cp - index, nextIsSmallCaps ? SmallCapsVariant : NormalVariant); 281 if (!nextFontData) { 282 if (markCount) 283 nextFontData = systemFallbackFontData(); 284 else 285 nextIsMissingGlyph = true; 286 } 287 288 if (nextFontData != fontData || nextIsMissingGlyph != isMissingGlyph) { 246 289 int itemStart = static_cast<int>(indexOfFontTransition); 247 290 int itemLength = index - indexOfFontTransition; 248 collectComplexTextRunsForCharacters((isSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, glyphData.glyph ? glyphData.fontData : 0);291 collectComplexTextRunsForCharacters((isSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, !isMissingGlyph ? fontData : 0); 249 292 indexOfFontTransition = index; 250 293 } … … 254 297 if (itemLength) { 255 298 int itemStart = indexOfFontTransition; 256 collectComplexTextRunsForCharacters((nextIsSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, nextGlyphData.glyph ? nextGlyphData.fontData : 0);299 collectComplexTextRunsForCharacters((nextIsSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, !nextIsMissingGlyph ? nextFontData : 0); 257 300 } 258 301 … … 291 334 void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData) 292 335 { 336 if (!fontData) { 337 // Create a run of missing glyphs from the primary font. 338 m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation, length, m_run.ltr())); 339 return; 340 } 341 293 342 #if USE(CORE_TEXT) && USE(ATSUI) 294 343 if (shouldUseATSUIAPI()) -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h
r89733 r95391 81 81 82 82 private: 83 static const SimpleFontData* systemFallbackFontData() { return reinterpret_cast<const SimpleFontData*>(-1); } 84 83 85 class ComplexTextRun : public RefCounted<ComplexTextRun> { 84 86 public: -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
r85507 r95391 316 316 void ComplexTextController::collectComplexTextRunsForCharactersATSUI(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData) 317 317 { 318 if (!fontData) { 319 // Create a run of missing glyphs from the primary font. 320 m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation, length, m_run.ltr())); 321 return; 322 } 318 ASSERT_ARG(fontData, fontData); 319 320 if (fontData == systemFallbackFont()) 321 fontData = m_font.primaryFont(); 323 322 324 323 if (m_fallbackFonts && fontData != m_font.primaryFont()) -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
r88487 r95391 1 1 /* 2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 31 31 #include "Font.h" 32 #include "FontCache.h" 32 33 #include "TextRun.h" 33 34 #include "WebCoreSystemInterface.h" … … 47 48 } 48 49 #endif 50 51 @interface CascadeList : NSArray { 52 @private 53 const WebCore::Font* _font; 54 UChar32 _character; 55 NSUInteger _count; 56 Vector<RetainPtr<CTFontDescriptorRef>, 16> _fontDescriptors; 57 } 58 59 - (id)initWithFont:(const WebCore::Font*)font character:(UChar32)character; 60 61 @end 62 63 @implementation CascadeList 64 65 - (id)initWithFont:(const WebCore::Font*)font character:(UChar32)character 66 { 67 if (!(self = [super init])) 68 return nil; 69 70 _font = font; 71 _character = character; 72 73 for (const WebCore::FontFamily* family = &font->family(); family; family = family->next()) 74 _count++; 75 76 return self; 77 } 78 79 - (NSUInteger)count 80 { 81 return _count; 82 } 83 84 - (id)objectAtIndex:(NSUInteger)index 85 { 86 CTFontDescriptorRef fontDescriptor; 87 if (index < _fontDescriptors.size()) { 88 if ((fontDescriptor = _fontDescriptors[index].get())) 89 return (id)fontDescriptor; 90 } else 91 _fontDescriptors.grow(index + 1); 92 93 const WebCore::SimpleFontData* fontData = _font->fontDataAt(index)->fontDataForCharacter(_character); 94 fontDescriptor = CTFontCopyFontDescriptor(fontData->platformData().ctFont()); 95 _fontDescriptors[index] = RetainPtr<CTFontDescriptorRef>(AdoptCF, fontDescriptor); 96 return (id)fontDescriptor; 97 } 98 99 @end 49 100 50 101 namespace WebCore { … … 130 181 void ComplexTextController::collectComplexTextRunsForCharactersCoreText(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData) 131 182 { 132 if (!fontData) { 133 // Create a run of missing glyphs from the primary font. 134 m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation, length, m_run.ltr())); 135 return; 136 } 137 138 if (m_fallbackFonts && fontData != m_font.primaryFont()) 139 m_fallbackFonts->add(fontData); 183 ASSERT_ARG(fontData, fontData); 184 185 bool isSystemFallback = false; 186 187 RetainPtr<CFDictionaryRef> stringAttributes; 188 if (fontData == systemFallbackFontData()) { 189 // FIXME: This code path does not support small caps. 190 isSystemFallback = true; 191 192 UChar32 baseCharacter; 193 U16_GET(cp, 0, 0, length, baseCharacter); 194 fontData = m_font.fontDataAt(0)->fontDataForCharacter(baseCharacter); 195 196 RetainPtr<CascadeList> cascadeList(AdoptNS, [[CascadeList alloc] initWithFont:&m_font character:baseCharacter]); 197 198 stringAttributes.adoptCF(CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()))); 199 static const void* attributeKeys[] = { kCTFontCascadeListAttribute }; 200 const void* values[] = { cascadeList.get() }; 201 RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocatorDefault, attributeKeys, values, sizeof(attributeKeys) / sizeof(*attributeKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 202 RetainPtr<CTFontDescriptorRef> fontDescriptor(AdoptCF, CTFontDescriptorCreateWithAttributes(attributes.get())); 203 RetainPtr<CTFontRef> fontWithCascadeList(AdoptCF, CTFontCreateCopyWithAttributes(fontData->platformData().ctFont(), m_font.pixelSize(), 0, fontDescriptor.get())); 204 CFDictionarySetValue((CFMutableDictionaryRef)stringAttributes.get(), kCTFontAttributeName, fontWithCascadeList.get()); 205 } else 206 stringAttributes = fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()); 140 207 141 208 RetainPtr<CTLineRef> line; … … 151 218 152 219 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 153 ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()) };220 ProviderInfo info = { cp, length, stringAttributes.get() }; 154 221 RetainPtr<CTTypesetterRef> typesetter(AdoptCF, wkCreateCTTypesetterWithUniCharProviderAndOptions(&provideStringAndAttributes, 0, &info, m_run.ltr() ? ltrTypesetterOptions : rtlTypesetterOptions)); 155 222 #else 156 223 RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, cp, length, kCFAllocatorNull)); 157 RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation())));224 RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), stringAttributes.get())); 158 225 RetainPtr<CTTypesetterRef> typesetter(AdoptCF, CTTypesetterCreateWithAttributedStringAndOptions(attributedString.get(), m_run.ltr() ? ltrTypesetterOptions : rtlTypesetterOptions)); 159 226 #endif … … 161 228 line.adoptCF(CTTypesetterCreateLine(typesetter.get(), CFRangeMake(0, 0))); 162 229 } else { 163 ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()) };230 ProviderInfo info = { cp, length, stringAttributes.get() }; 164 231 165 232 line.adoptCF(wkCreateCTLineWithUniCharProvider(&provideStringAndAttributes, 0, &info)); … … 176 243 ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); 177 244 CFRange runRange = CTRunGetStringRange(ctRun); 178 m_complexTextRuns.append(ComplexTextRun::create(ctRun, fontData, cp, stringLocation, length, runRange)); 245 const SimpleFontData* runFontData = fontData; 246 if (isSystemFallback) { 247 CFDictionaryRef runAttributes = CTRunGetAttributes(ctRun); 248 CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttributes, kCTFontAttributeName)); 249 ASSERT(CFGetTypeID(runFont) == CTFontGetTypeID()); 250 if (!CFEqual(runFont, fontData->platformData().ctFont())) { 251 // Rather than using runFont as an NSFont and wrapping it in a FontPlatformData, go through 252 // the font cache and ultimately through NSFontManager in order to get an NSFont with the right 253 // NSFontRenderingMode. 254 RetainPtr<CFStringRef> fontName(AdoptCF, CTFontCopyPostScriptName(runFont)); 255 if (CFEqual(fontName.get(), CFSTR("LastResort"))) { 256 m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation + runRange.location, runRange.length, m_run.ltr())); 257 continue; 258 } 259 runFontData = fontCache()->getCachedFontData(m_font.fontDescription(), fontName.get(), false, FontCache::DoNotRetain); 260 if (m_fallbackFonts && runFontData != m_font.primaryFont()) 261 m_fallbackFonts->add(runFontData); 262 } 263 } 264 if (m_fallbackFonts && runFontData != m_font.primaryFont()) 265 m_fallbackFonts->add(fontData); 266 267 m_complexTextRuns.append(ComplexTextRun::create(ctRun, runFontData, cp, stringLocation, length, runRange)); 179 268 } 180 269 } -
trunk/Source/WebCore/platform/graphics/mac/FontMac.mm
r95070 r95391 3 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 4 * (C) 2000 Dirk Mueller (mueller@kde.org) 5 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc.5 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. 6 6 * 7 7 * This library is free software; you can redistribute it and/or … … 250 250 } 251 251 252 } 252 const SimpleFontData* Font::fontDataForCombiningCharacterSequence(const UChar* characters, size_t length, FontDataVariant variant) const 253 { 254 UChar32 baseCharacter; 255 size_t baseCharacterLength = 0; 256 U16_NEXT(characters, baseCharacterLength, length, baseCharacter); 257 258 GlyphData baseCharacterGlyphData = glyphDataForCharacter(baseCharacter, false, variant); 259 260 if (length == baseCharacterLength) 261 return baseCharacterGlyphData.glyph ? baseCharacterGlyphData.fontData : 0; 262 263 bool triedBaseCharacterFontData = false; 264 265 unsigned i = 0; 266 for (const FontData* fontData = fontDataAt(0); fontData; fontData = fontDataAt(++i)) { 267 const SimpleFontData* simpleFontData = fontData->fontDataForCharacter(baseCharacter); 268 if (variant != NormalVariant) { 269 if (const SimpleFontData* variantFontData = simpleFontData->variantFontData(m_fontDescription, variant)) 270 simpleFontData = variantFontData; 271 } 272 273 if (simpleFontData == baseCharacterGlyphData.fontData) 274 triedBaseCharacterFontData = true; 275 276 if (simpleFontData->canRenderCombiningCharacterSequence(characters, length)) 277 return simpleFontData; 278 } 279 280 if (!triedBaseCharacterFontData && baseCharacterGlyphData.fontData && baseCharacterGlyphData.fontData->canRenderCombiningCharacterSequence(characters, length)) 281 return baseCharacterGlyphData.fontData; 282 283 return 0; 284 } 285 286 } -
trunk/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
r93376 r95391 1 1 /* 2 * Copyright (C) 2005, 2006 Apple Computer, Inc.All rights reserved.2 * Copyright (C) 2005, 2006, 2010, 2011 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2006 Alexey Proskuryakov 4 4 * … … 6 6 * modification, are permitted provided that the following conditions 7 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 8 13 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 * THE POSSIBILITY OF SUCH DAMAGE. 28 25 */ 29 26 … … 417 414 } 418 415 416 struct ProviderInfo { 417 const UChar* characters; 418 size_t length; 419 CFDictionaryRef attributes; 420 }; 421 422 static const UniChar* provideStringAndAttributes(CFIndex stringIndex, CFIndex* count, CFDictionaryRef* attributes, void* context) 423 { 424 ProviderInfo* info = static_cast<struct ProviderInfo*>(context); 425 if (stringIndex < 0 || static_cast<size_t>(stringIndex) >= info->length) 426 return 0; 427 428 *count = info->length - stringIndex; 429 *attributes = info->attributes; 430 return info->characters + stringIndex; 431 } 432 433 bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters, size_t length) const 434 { 435 ASSERT(isMainThread()); 436 437 if (!m_combiningCharacterSequenceSupport) 438 m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool>); 439 440 pair<WTF::HashMap<String, bool>::iterator, bool> addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false); 441 if (!addResult.second) 442 return addResult.first->second; 443 444 RetainPtr<CGFontRef> cgFont(AdoptCF, CTFontCopyGraphicsFont(platformData().ctFont(), 0)); 445 446 ProviderInfo info = { characters, length, getCFStringAttributes(0, platformData().orientation()) }; 447 RetainPtr<CTLineRef> line(AdoptCF, wkCreateCTLineWithUniCharProvider(&provideStringAndAttributes, 0, &info)); 448 449 CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); 450 CFIndex runCount = CFArrayGetCount(runArray); 451 452 for (CFIndex r = 0; r < runCount; r++) { 453 CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); 454 ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); 455 CFDictionaryRef runAttributes = CTRunGetAttributes(ctRun); 456 CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttributes, kCTFontAttributeName)); 457 RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0)); 458 if (!CFEqual(runCGFont.get(), cgFont.get())) 459 return false; 460 } 461 462 addResult.first->second = true; 463 return true; 464 } 465 419 466 } // namespace WebCore
Note: See TracChangeset
for help on using the changeset viewer.