Changeset 177490 in webkit
- Timestamp:
- Dec 18, 2014 4:16:12 AM (9 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r177462 r177490 1 2014-12-18 Antti Koivisto <antti@apple.com> 2 3 Stop returning GlyphPage from various Font functions 4 https://bugs.webkit.org/show_bug.cgi?id=139627 5 6 Reviewed by Darin Adler. 7 8 These are progressions. We now correctly draw the specified missing glyph. 9 10 * platform/mac/svg/W3C-SVG-1.1/fonts-glyph-03-t-expected.png: 11 * platform/mac/svg/W3C-SVG-1.1/fonts-glyph-03-t-expected.txt: 12 * platform/mac/svg/custom/glyph-selection-lang-attribute-expected.png: 13 * svg/custom/glyph-selection-lang-attribute-expected.txt: 14 1 15 2014-12-17 Daniel Bates <dabates@apple.com> 2 16 -
trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/fonts-glyph-03-t-expected.txt
r103407 r177490 3 3 layer at (0,0) size 480x360 4 4 RenderSVGRoot {svg} at (0,0) size 480x360 5 RenderSVGContainer {g} at (50,10) size 2 8x2605 RenderSVGContainer {g} at (50,10) size 25x260 6 6 RenderSVGHiddenContainer {defs} at (0,0) size 0x0 7 RenderSVGContainer {g} at (50,10) size 2 8x2607 RenderSVGContainer {g} at (50,10) size 25x260 8 8 RenderSVGText {text} at (50,10) size 25x50 contains 1 chunk(s) 9 9 RenderSVGInlineText {#text} at (0,0) size 25x50 … … 15 15 RenderSVGInlineText {#text} at (0,0) size 25x50 16 16 chunk 1 text run 1 at (50.00,190.00) startOffset 0 endOffset 1 width 25.00: "a" 17 RenderSVGText {text} at (50,220) size 2 8x50 contains 1 chunk(s)18 RenderSVGInlineText {#text} at (0,0) size 2 8x5019 chunk 1 text run 1 at (50.00,260.00) startOffset 0 endOffset 1 width 2 8.00: "a"17 RenderSVGText {text} at (50,220) size 25x50 contains 1 chunk(s) 18 RenderSVGInlineText {#text} at (0,0) size 25x50 19 chunk 1 text run 1 at (50.00,260.00) startOffset 0 endOffset 1 width 25.00: "a" 20 20 RenderSVGText {text} at (10,304) size 284x46 contains 1 chunk(s) 21 21 RenderSVGInlineText {#text} at (0,0) size 284x46 -
trunk/LayoutTests/svg/custom/glyph-selection-lang-attribute-expected.txt
r149088 r177490 4 4 RenderSVGRoot {svg} at (0,0) size 800x600 5 5 RenderSVGHiddenContainer {defs} at (0,0) size 0x0 6 RenderSVGContainer {g} at (83,16) size 4 7x5516 RenderSVGContainer {g} at (83,16) size 42x551 7 7 RenderSVGText {text} at (50,10) size 25x50 contains 1 chunk(s) 8 8 RenderSVGInlineText {#text} at (0,0) size 25x50 … … 11 11 RenderSVGInlineText {#text} at (0,0) size 25x50 12 12 chunk 1 text run 1 at (50.00,120.00) startOffset 0 endOffset 1 width 24.90: "a" 13 RenderSVGText {text} at (50,150) size 2 8x50 contains 1 chunk(s)14 RenderSVGInlineText {#text} at (0,0) size 2 8x5015 chunk 1 text run 1 at (50.00,190.00) startOffset 0 endOffset 1 width 2 7.60: "a"16 RenderSVGText {text} at (50,220) size 2 8x50 contains 1 chunk(s)17 RenderSVGInlineText {#text} at (0,0) size 2 8x5018 chunk 1 text run 1 at (50.00,260.00) startOffset 0 endOffset 1 width 2 7.60: "a"19 RenderSVGText {text} at (50,290) size 2 8x50 contains 1 chunk(s)20 RenderSVGInlineText {#text} at (0,0) size 2 8x5021 chunk 1 text run 1 at (50.00,330.00) startOffset 0 endOffset 1 width 2 7.60: "a"13 RenderSVGText {text} at (50,150) size 25x50 contains 1 chunk(s) 14 RenderSVGInlineText {#text} at (0,0) size 25x50 15 chunk 1 text run 1 at (50.00,190.00) startOffset 0 endOffset 1 width 24.90: "a" 16 RenderSVGText {text} at (50,220) size 25x50 contains 1 chunk(s) 17 RenderSVGInlineText {#text} at (0,0) size 25x50 18 chunk 1 text run 1 at (50.00,260.00) startOffset 0 endOffset 1 width 24.90: "a" 19 RenderSVGText {text} at (50,290) size 25x50 contains 1 chunk(s) 20 RenderSVGInlineText {#text} at (0,0) size 25x50 21 chunk 1 text run 1 at (50.00,330.00) startOffset 0 endOffset 1 width 24.90: "a" 22 22 RenderSVGContainer {g} at (250,16) size 42x551 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,0.00)}] 23 23 RenderSVGText {text} at (50,10) size 25x50 contains 1 chunk(s) -
trunk/Source/WebCore/ChangeLog
r177489 r177490 1 2014-12-18 Antti Koivisto <antti@apple.com> 2 3 Stop returning GlyphPage from various Font functions 4 https://bugs.webkit.org/show_bug.cgi?id=139627 5 6 Reviewed by Darin Adler. 7 8 Make all 9 10 std::pair<GlyphData, GlyphPage*> glyphDataAndPage*(...) 11 12 style functions to just return GlyphData only. The GlyphPage value was only used for an obscure SVG fallback case. 13 14 * platform/graphics/Font.h: 15 (WebCore::Font::glyphDataForCharacter): 16 (WebCore::Font::glyphDataAndPageForCharacter): Deleted. 17 * platform/graphics/FontGlyphs.cpp: 18 (WebCore::glyphDataForCJKCharacterWithoutSyntheticItalic): 19 (WebCore::glyphDataForNonCJKCharacterWithGlyphOrientation): 20 (WebCore::FontGlyphs::glyphDataForSystemFallback): 21 (WebCore::FontGlyphs::glyphDataForVariant): 22 (WebCore::FontGlyphs::glyphDataForCharacter): 23 (WebCore::glyphDataAndPageForCJKCharacterWithoutSyntheticItalic): Deleted. 24 (WebCore::glyphDataAndPageForNonCJKCharacterWithGlyphOrientation): Deleted. 25 (WebCore::FontGlyphs::glyphDataAndPageForSystemFallback): Deleted. 26 (WebCore::FontGlyphs::glyphDataAndPageForVariant): Deleted. 27 (WebCore::FontGlyphs::glyphDataAndPageForCharacter): Deleted. 28 * platform/graphics/FontGlyphs.h: 29 (WebCore::FontGlyphs::GlyphPagesStateSaver::GlyphPagesStateSaver): Deleted. 30 (WebCore::FontGlyphs::GlyphPagesStateSaver::~GlyphPagesStateSaver): Deleted. 31 32 No longer needed. 33 34 * rendering/svg/SVGTextRunRenderingContext.cpp: 35 (WebCore::SVGTextRunRenderingContext::glyphDataForCharacter): 36 37 Simplify by not trying to resolve fallbacks in case context sensitive (based on lang attribute etc) 38 glyph selection fails. Instead just fall back to a default font. This behavior is not specified 39 anywhere as far as I can see. (normal non-context sensitive fallbacks will still work fine). 40 This removes the need to hackishly mutate glyph pages. 41 42 Also fix a bug where we didn't use the specified missing glyph when context sensitive selection failed. 43 1 44 2014-12-18 Chris Dumez <cdumez@apple.com> 2 45 -
trunk/Source/WebCore/platform/graphics/Font.h
r174489 r177490 188 188 GlyphData glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant = AutoVariant) const 189 189 { 190 return glyphDataAndPageForCharacter(c, mirror, variant).first;190 return m_glyphs->glyphDataForCharacter(m_fontDescription, c, mirror, variant); 191 191 } 192 192 #if PLATFORM(COCOA) 193 193 const SimpleFontData* fontDataForCombiningCharacterSequence(const UChar*, size_t length, FontDataVariant) const; 194 194 #endif 195 std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(UChar32 c, bool mirror, FontDataVariant variant) const196 {197 return m_glyphs->glyphDataAndPageForCharacter(m_fontDescription, c, mirror, variant);198 }199 195 bool primaryFontHasGlyphForCharacter(UChar32) const; 200 196 -
trunk/Source/WebCore/platform/graphics/FontGlyphs.cpp
r177229 r177490 210 210 } 211 211 212 static inline std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCJKCharacterWithoutSyntheticItalic(UChar32 character, GlyphData& data, GlyphPage* page, unsigned pageNumber) 212 #if PLATFORM(COCOA) 213 static GlyphData glyphDataForCJKCharacterWithoutSyntheticItalic(UChar32 character, GlyphData& data, unsigned pageNumber) 213 214 { 214 215 RefPtr<SimpleFontData> nonItalicFontData = data.fontData->nonSyntheticItalicFontData(); … … 218 219 GlyphData nonItalicData = nonItalicPage->glyphDataForCharacter(character); 219 220 if (nonItalicData.fontData) 220 return std::make_pair(nonItalicData, nonItalicPage); 221 } 222 return std::make_pair(data, page); 223 } 221 return nonItalicData; 222 } 223 return data; 224 } 225 #endif 224 226 225 static inline std::pair<GlyphData, GlyphPage*> glyphDataAndPageForNonCJKCharacterWithGlyphOrientation(UChar32 character, NonCJKGlyphOrientation orientation, GlyphData& data, GlyphPage* page, unsigned pageNumber)227 static GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(UChar32 character, NonCJKGlyphOrientation orientation, GlyphData& data, unsigned pageNumber) 226 228 { 227 229 if (orientation == NonCJKGlyphOrientationUpright || shouldIgnoreRotation(character)) { … … 233 235 // If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright. 234 236 if (data.glyph == uprightData.glyph) 235 return std::make_pair(data, page);237 return data; 236 238 // The glyphs are distinct, meaning that the font has a vertical-right glyph baked into it. We can't use that 237 239 // glyph, so we fall back to the upright data and use the horizontal glyph. 238 240 if (uprightData.fontData) 239 return std::make_pair(uprightData, uprightPage);241 return uprightData; 240 242 } 241 243 } else if (orientation == NonCJKGlyphOrientationVerticalRight) { … … 248 250 // into it. 249 251 if (data.glyph != verticalRightData.glyph) 250 return std::make_pair(data, page);252 return data; 251 253 // The glyphs are identical, meaning that we should just use the horizontal glyph. 252 254 if (verticalRightData.fontData) 253 return std::make_pair(verticalRightData, verticalRightPage);255 return verticalRightData; 254 256 } 255 257 } 256 return std::make_pair(data, page);257 } 258 259 std::pair<GlyphData, GlyphPage*> FontGlyphs::glyphDataAndPageForSystemFallback(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode& node)258 return data; 259 } 260 261 GlyphData FontGlyphs::glyphDataForSystemFallback(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode& node) 260 262 { 261 263 ASSERT(node.page()); … … 291 293 data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node.level())); 292 294 if (!Font::isCJKIdeographOrSymbol(c) && data.fontData->platformData().orientation() != Horizontal && !data.fontData->isTextOrientationFallback()) 293 return glyphData AndPageForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, fallbackPage, pageNumber);295 return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, pageNumber); 294 296 } 295 return std::make_pair(data, node.page());297 return data; 296 298 } 297 299 … … 303 305 data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node.level())); 304 306 } 305 return std::make_pair(data, node.page());306 } 307 308 std::pair<GlyphData, GlyphPage*> FontGlyphs::glyphDataAndPageForVariant(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode*& node)307 return data; 308 } 309 310 GlyphData FontGlyphs::glyphDataForVariant(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode*& node) 309 311 { 310 312 while (true) { … … 316 318 RefPtr<SimpleFontData> variantFontData = data.fontData->variantFontData(description, variant); 317 319 if (!variantFontData) 318 return std::make_pair(data, page);320 return data; 319 321 320 322 GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData.get(), pageNumber); … … 323 325 GlyphData data = variantPage->glyphDataForCharacter(c); 324 326 if (data.fontData) 325 return std::make_pair(data, variantPage);327 return data; 326 328 } 327 329 328 330 // Do not attempt system fallback off the variantFontData. This is the very unlikely case that 329 331 // a font has the lowercase character but the small caps font does not have its uppercase version. 330 return std::make_pair(variantFontData->missingGlyphData(), page);332 return variantFontData->missingGlyphData(); 331 333 } 332 334 333 335 if (node->isSystemFallback()) 334 return glyphData AndPageForSystemFallback(c, description, variant, pageNumber, *node);336 return glyphDataForSystemFallback(c, description, variant, pageNumber, *node); 335 337 } 336 338 … … 339 341 } 340 342 341 std::pair<GlyphData, GlyphPage*> FontGlyphs::glyphDataAndPageForCharacter(const FontDescription& description, UChar32 c, bool mirror, FontDataVariant variant)343 GlyphData FontGlyphs::glyphDataForCharacter(const FontDescription& description, UChar32 c, bool mirror, FontDataVariant variant) 342 344 { 343 345 ASSERT(isMainThread()); … … 365 367 366 368 if (variant != NormalVariant) 367 return glyphData AndPageForVariant(c, description, variant, pageNumber, node);369 return glyphDataForVariant(c, description, variant, pageNumber, node); 368 370 369 371 while (true) { … … 373 375 if (data.fontData->platformData().orientation() == Vertical && !data.fontData->isTextOrientationFallback()) { 374 376 if (!Font::isCJKIdeographOrSymbol(c)) 375 return glyphData AndPageForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, page, pageNumber);377 return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, pageNumber); 376 378 377 379 if (!data.fontData->hasVerticalGlyphs()) { 378 380 // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs 379 381 // to make sure you get a square (even for broken glyphs like symbols used for punctuation). 380 return glyphData AndPageForVariant(c, description, BrokenIdeographVariant, pageNumber, node);382 return glyphDataForVariant(c, description, BrokenIdeographVariant, pageNumber, node); 381 383 } 382 384 #if PLATFORM(COCOA) 383 385 if (data.fontData->platformData().syntheticOblique()) 384 return glyphData AndPageForCJKCharacterWithoutSyntheticItalic(c, data, page, pageNumber);386 return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data, pageNumber); 385 387 #endif 386 388 } 387 389 388 return std::make_pair(data, page);390 return data; 389 391 } 390 392 391 393 if (node->isSystemFallback()) 392 return glyphData AndPageForSystemFallback(c, description, variant, pageNumber, *node);394 return glyphDataForSystemFallback(c, description, variant, pageNumber, *node); 393 395 } 394 396 -
trunk/Source/WebCore/platform/graphics/FontGlyphs.h
r177259 r177490 48 48 typedef HashMap<int, GlyphPageTreeNode*, DefaultHash<int>::Hash> GlyphPages; 49 49 50 class GlyphPagesStateSaver {51 public:52 GlyphPagesStateSaver(FontGlyphs& glyphs)53 : m_glyphs(glyphs)54 , m_pages(glyphs.m_pages)55 , m_pageZero(glyphs.m_pageZero)56 {57 }58 59 ~GlyphPagesStateSaver()60 {61 m_glyphs.m_pages = m_pages;62 m_glyphs.m_pageZero = m_pageZero;63 }64 65 private:66 FontGlyphs& m_glyphs;67 GlyphPages& m_pages;68 GlyphPageTreeNode* m_pageZero;69 };70 71 50 static Ref<FontGlyphs> create(PassRefPtr<FontSelector> fontSelector) { return adoptRef(*new FontGlyphs(fontSelector)); } 72 51 static Ref<FontGlyphs> createForPlatformFont(const FontPlatformData& platformData) { return adoptRef(*new FontGlyphs(platformData)); } … … 76 55 bool isForPlatformFont() const { return m_isForPlatformFont; } 77 56 78 std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(const FontDescription&, UChar32, bool mirror, FontDataVariant);57 GlyphData glyphDataForCharacter(const FontDescription&, UChar32, bool mirror, FontDataVariant); 79 58 80 59 bool isFixedPitch(const FontDescription&); … … 99 78 FontGlyphs(const FontPlatformData&); 100 79 101 std::pair<GlyphData, GlyphPage*> glyphDataAndPageForSystemFallback(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode&);102 std::pair<GlyphData, GlyphPage*> glyphDataAndPageForVariant(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode*&);80 GlyphData glyphDataForSystemFallback(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode&); 81 GlyphData glyphDataForVariant(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode*&); 103 82 104 83 WEBCORE_EXPORT void releaseFontData(); -
trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
r174619 r177490 296 296 ASSERT(primaryFont); 297 297 298 std::pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror, AutoVariant); 299 GlyphData glyphData = pair.first; 298 GlyphData glyphData = font.glyphDataForCharacter(character, mirror, AutoVariant); 300 299 301 300 // Check if we have the missing glyph data, in which case we can just return. … … 306 305 } 307 306 308 // Save data from the font fallback list because we may modify it later. Do this before the309 // potential change to glyphData.fontData below.310 FontGlyphs* glyph = font.glyphs();311 ASSERT(glyph);312 FontGlyphs::GlyphPagesStateSaver glyphPagesSaver(*glyph);313 314 307 // Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage. 315 const SimpleFontData* originalFontData = glyphData.fontData;316 308 if (glyphData.fontData && !glyphData.fontData->isSVGFont()) { 317 309 auto& elementRenderer = is<RenderElement>(renderer()) ? downcast<RenderElement>(renderer()) : *renderer().parent(); … … 323 315 324 316 const SimpleFontData* fontData = glyphData.fontData; 325 if (fontData) { 326 if (!fontData->isSVGFont()) 327 return glyphData; 328 329 SVGFontElement* fontElement = nullptr; 330 SVGFontFaceElement* fontFaceElement = nullptr; 331 332 const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement); 333 if (!fontElement || !fontFaceElement) 334 return glyphData; 335 336 // If we got here, we're dealing with a glyph defined in a SVG Font. 337 // The returned glyph by glyphDataAndPageForCharacter() is a glyph stored in the SVG Font glyph table. 338 // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its 339 // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that. 340 if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength, normalizedSpacesStringCache)) 341 return glyphData; 342 } 343 344 GlyphPage* page = pair.second; 345 ASSERT(page); 346 347 // No suitable glyph found that is compatible with the requirments (same language, arabic-form, orientation etc.) 348 // Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily 349 // remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly. 350 page->setGlyphDataForCharacter(character, 0, nullptr); 351 352 // Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before. 353 GlyphData fallbackGlyphData = font.glyphDataForCharacter(character, mirror); 354 ASSERT(fallbackGlyphData.fontData != fontData); 355 356 // Restore original state of the SVG Font glyph table and the current font fallback list, 357 // to assure the next lookup of the same glyph won't immediately return the fallback glyph. 358 page->setGlyphDataForCharacter(character, glyphData.glyph, originalFontData); 359 ASSERT(fallbackGlyphData.fontData); 360 return fallbackGlyphData; 317 if (!fontData || !fontData->isSVGFont()) 318 return glyphData; 319 320 SVGFontElement* fontElement = nullptr; 321 SVGFontFaceElement* fontFaceElement = nullptr; 322 const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement); 323 if (!svgFontData) 324 return glyphData; 325 326 // If we got here, we're dealing with a glyph defined in a SVG Font. 327 // The returned glyph by glyphDataForCharacter() is a glyph stored in the SVG Font glyph table. 328 // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its 329 // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that. 330 if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength, normalizedSpacesStringCache)) 331 return glyphData; 332 if (missingGlyphData.glyph) 333 return missingGlyphData; 334 335 // SVG font context sensitive selection failed and there is no defined missing glyph. Drop down to a default font. 336 // The behavior does not seem to be specified. For simplicity we don't try to resolve font fallbacks context-sensitively. 337 FontDescription fallbackDescription = font.fontDescription(); 338 fallbackDescription.setFamilies(Vector<AtomicString> { sansSerifFamily }); 339 Font fallbackFont(fallbackDescription, font.letterSpacing(), font.wordSpacing()); 340 fallbackFont.update(font.fontSelector()); 341 342 return fallbackFont.glyphDataForCharacter(character, mirror, AutoVariant); 361 343 } 362 344
Note: See TracChangeset
for help on using the changeset viewer.