Changeset 177637 in webkit


Ignore:
Timestamp:
Dec 22, 2014 11:14:58 AM (9 years ago)
Author:
Antti Koivisto
Message:

Generic font code should not know about SVG font missing glyph
https://bugs.webkit.org/show_bug.cgi?id=139864

Reviewed by Andreas Kling and Myles Maxfield.

The defined missing glyph is an SVG font concept and should be handled in SVG code.

  • platform/graphics/FontGlyphs.cpp:

(WebCore::FontGlyphs::glyphDataForSystemFallback):
(WebCore::FontGlyphs::glyphDataForVariant):

Return null glyph instead of the missing glyph (the missing glyph was already a null glyph in all non-svg-font cases).
Use early return style.

  • platform/graphics/FontGlyphs.h:
  • platform/graphics/SegmentedFontData.cpp:
  • platform/graphics/SimpleFontData.cpp:

(WebCore::SimpleFontData::platformGlyphInit):

  • platform/graphics/SimpleFontData.h:

Remove the missingGlyph member.

  • platform/graphics/WidthIterator.cpp:

(WebCore::WidthIterator::advanceInternal):

Explicitly skip over null glyphs. Before they had non-null fontData and would get skipped implicitly.

  • platform/graphics/mac/SimpleFontDataMac.mm:
  • rendering/svg/SVGTextRunRenderingContext.cpp:

(WebCore::missingGlyphForFont):

Get the missing glyph from the SVG font element.

(WebCore::SVGTextRunRenderingContext::glyphDataForCharacter):

Return the missing glyph if the normal lookup didn't produce results.

  • svg/SVGFontData.cpp:

(WebCore::SVGFontData::initializeFontData):

Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r177630 r177637  
     12014-12-22  Antti Koivisto  <antti@apple.com>
     2
     3        Generic font code should not know about SVG font missing glyph
     4        https://bugs.webkit.org/show_bug.cgi?id=139864
     5
     6        Reviewed by Andreas Kling and Myles Maxfield.
     7
     8        The defined missing glyph is an SVG font concept and should be handled in SVG code.
     9
     10        * platform/graphics/FontGlyphs.cpp:
     11        (WebCore::FontGlyphs::glyphDataForSystemFallback):
     12        (WebCore::FontGlyphs::glyphDataForVariant):
     13
     14            Return null glyph instead of the missing glyph (the missing glyph was already a null glyph in all non-svg-font cases).
     15            Use early return style.
     16
     17        * platform/graphics/FontGlyphs.h:
     18        * platform/graphics/SegmentedFontData.cpp:
     19        * platform/graphics/SimpleFontData.cpp:
     20        (WebCore::SimpleFontData::platformGlyphInit):
     21        * platform/graphics/SimpleFontData.h:
     22
     23            Remove the missingGlyph member.
     24
     25        * platform/graphics/WidthIterator.cpp:
     26        (WebCore::WidthIterator::advanceInternal):
     27
     28            Explicitly skip over null glyphs. Before they had non-null fontData and would get skipped implicitly.
     29
     30        * platform/graphics/mac/SimpleFontDataMac.mm:
     31        * rendering/svg/SVGTextRunRenderingContext.cpp:
     32        (WebCore::missingGlyphForFont):
     33
     34            Get the missing glyph from the SVG font element.
     35
     36        (WebCore::SVGTextRunRenderingContext::glyphDataForCharacter):
     37
     38            Return the missing glyph if the normal lookup didn't produce results.
     39
     40        * svg/SVGFontData.cpp:
     41        (WebCore::SVGFontData::initializeFontData):
     42
    1432014-12-22  Chris Dumez  <cdumez@apple.com>
    244
  • trunk/Source/WebCore/platform/graphics/FontGlyphs.cpp

    r177490 r177637  
    3232#include "Font.h"
    3333#include "FontCache.h"
     34#include "GlyphPageTreeNode.h"
    3435#include "SegmentedFontData.h"
    3536
     
    278279    const SimpleFontData* originalFontData = primaryFontData(description)->fontDataForCharacter(c);
    279280    RefPtr<SimpleFontData> characterFontData = fontCache().systemFallbackForCharacters(description, originalFontData, m_isForPlatformFont, codeUnits, codeUnitsLength);
    280     if (characterFontData) {
    281         if (characterFontData->platformData().orientation() == Vertical && !characterFontData->hasVerticalGlyphs() && Font::isCJKIdeographOrSymbol(c))
    282             variant = BrokenIdeographVariant;
    283         if (variant != NormalVariant)
    284             characterFontData = characterFontData->variantFontData(description, variant);
    285     }
    286     if (characterFontData) {
    287         // Got the fallback glyph and font.
    288         GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData.get(), pageNumber)->page();
    289         GlyphData data = fallbackPage && fallbackPage->fontDataForCharacter(c) ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
    290         // Cache it so we don't have to do system fallback again next time.
    291         if (variant == NormalVariant) {
    292             node.page()->setGlyphDataForCharacter(c, data.glyph, data.fontData);
    293             data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node.level()));
    294             if (!Font::isCJKIdeographOrSymbol(c) && data.fontData->platformData().orientation() != Horizontal && !data.fontData->isTextOrientationFallback())
    295                 return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, pageNumber);
    296         }
    297         return data;
    298     }
    299 
    300     // Even system fallback can fail; use the missing glyph in that case.
    301     // FIXME: It would be nicer to use the missing glyph from the last resort font instead.
    302     GlyphData data = primarySimpleFontData(description)->missingGlyphData();
    303     if (variant == NormalVariant) {
     281    if (!characterFontData)
     282        return GlyphData();
     283
     284    if (characterFontData->platformData().orientation() == Vertical && !characterFontData->hasVerticalGlyphs() && Font::isCJKIdeographOrSymbol(c))
     285        variant = BrokenIdeographVariant;
     286    if (variant != NormalVariant) {
     287        characterFontData = characterFontData->variantFontData(description, variant);
     288        ASSERT(characterFontData);
     289    }
     290
     291    GlyphData data;
     292    if (GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData.get(), pageNumber)->page())
     293        data = fallbackPage->glyphDataForCharacter(c);
     294
     295    // Cache it so we don't have to do system fallback again next time.
     296    if (variant == NormalVariant && data.glyph) {
    304297        node.page()->setGlyphDataForCharacter(c, data.glyph, data.fontData);
    305298        data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node.level()));
     299        if (!Font::isCJKIdeographOrSymbol(c) && data.fontData->platformData().orientation() != Horizontal && !data.fontData->isTextOrientationFallback())
     300            return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, pageNumber);
    306301    }
    307302    return data;
     
    322317                GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData.get(), pageNumber);
    323318                GlyphPage* variantPage = variantNode->page();
    324                 if (variantPage) {
    325                     GlyphData data = variantPage->glyphDataForCharacter(c);
    326                     if (data.fontData)
    327                         return data;
    328                 }
     319                if (variantPage)
     320                    return variantPage->glyphDataForCharacter(c);
    329321
    330322                // Do not attempt system fallback off the variantFontData. This is the very unlikely case that
    331323                // a font has the lowercase character but the small caps font does not have its uppercase version.
    332                 return variantFontData->missingGlyphData();
     324                return GlyphData();
    333325            }
    334326
  • trunk/Source/WebCore/platform/graphics/FontGlyphs.h

    r177490 r177637  
    2323
    2424#include "FontSelector.h"
     25#include "GlyphPage.h"
    2526#include "SimpleFontData.h"
    2627#include "WidthCache.h"
  • trunk/Source/WebCore/platform/graphics/SegmentedFontData.cpp

    r177316 r177637  
    2727#include "SegmentedFontData.h"
    2828
     29#include "GlyphPageTreeNode.h"
    2930#include "SimpleFontData.h"
    3031#include <wtf/Assertions.h>
  • trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp

    r175960 r177637  
    3636#include "Font.h"
    3737#include "FontCache.h"
     38#include "GlyphPageTreeNode.h"
    3839#include "OpenTypeMathData.h"
    3940#include <wtf/MathExtras.h>
     
    125126        determinePitch();
    126127        m_zeroWidthSpaceGlyph = 0;
    127         m_missingGlyphData.fontData = this;
    128         m_missingGlyphData.glyph = 0;
    129128        return;
    130129    }
     
    150149    if (m_zeroWidthSpaceGlyph == m_spaceGlyph)
    151150        m_zeroWidthSpaceGlyph = 0;
    152 
    153     m_missingGlyphData.fontData = this;
    154     m_missingGlyphData.glyph = 0;
    155151}
    156152
  • trunk/Source/WebCore/platform/graphics/SimpleFontData.h

    r177527 r177637  
    3232#include "GlyphBuffer.h"
    3333#include "GlyphMetricsMap.h"
    34 #include "GlyphPageTreeNode.h"
    3534#include "OpenTypeMathData.h"
    3635#if ENABLE(OPENTYPE_VERTICAL)
     
    6160namespace WebCore {
    6261
     62class GlyphPage;
    6363class FontDescription;
    6464class SharedBuffer;
     65struct GlyphData;
    6566struct WidthIterator;
    6667
     
    181182    virtual bool isSegmented() const override;
    182183
    183     const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
    184     void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; }
    185 
    186184#ifndef NDEBUG
    187185    virtual String description() const override;
     
    272270
    273271    Glyph m_zeroWidthSpaceGlyph;
    274 
    275     GlyphData m_missingGlyphData;
    276272
    277273    struct DerivedFontData {
  • trunk/Source/WebCore/platform/graphics/WidthIterator.cpp

    r174297 r177637  
    180180        const GlyphData& glyphData = glyphDataForCharacter(character, rtl, currentCharacter, advanceLength, normalizedSpacesStringCache);
    181181        Glyph glyph = glyphData.glyph;
     182        if (!glyph) {
     183            textIterator.advance(advanceLength);
     184            continue;
     185        }
    182186        const SimpleFontData* fontData = glyphData.fontData;
    183 
    184187        ASSERT(fontData);
    185188
  • trunk/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm

    r177527 r177637  
    3636#import "FontCache.h"
    3737#import "FontDescription.h"
     38#import "GlyphPageTreeNode.h"
    3839#import "SharedBuffer.h"
    3940#import "WebCoreSystemInterface.h"
  • trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp

    r177490 r177637  
    291291}
    292292
     293static GlyphData missingGlyphForFont(const Font& font)
     294{
     295    const SimpleFontData* primaryFontData = font.primaryFont();
     296    if (!primaryFontData->isSVGFont())
     297        return GlyphData();
     298    SVGFontElement* fontElement;
     299    SVGFontFaceElement* fontFaceElement;
     300    svgFontAndFontFaceElementForFontData(primaryFontData, fontFaceElement, fontElement);
     301    return GlyphData(fontElement->missingGlyph(), primaryFontData);
     302}
     303
    293304GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, WidthIterator& iterator, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength, String& normalizedSpacesStringCache)
    294305{
    295     const SimpleFontData* primaryFont = font.primaryFont();
    296     ASSERT(primaryFont);
    297 
    298306    GlyphData glyphData = font.glyphDataForCharacter(character, mirror, AutoVariant);
    299 
    300     // Check if we have the missing glyph data, in which case we can just return.
    301     GlyphData missingGlyphData = primaryFont->missingGlyphData();
    302     if (glyphData.glyph == missingGlyphData.glyph && glyphData.fontData == missingGlyphData.fontData) {
    303         ASSERT(glyphData.fontData);
    304         return glyphData;
    305     }
     307    if (!glyphData.glyph)
     308        return missingGlyphForFont(font);
     309
     310    ASSERT(glyphData.fontData);
    306311
    307312    // Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage.
    308     if (glyphData.fontData && !glyphData.fontData->isSVGFont()) {
     313    if (!glyphData.fontData->isSVGFont()) {
    309314        auto& elementRenderer = is<RenderElement>(renderer()) ? downcast<RenderElement>(renderer()) : *renderer().parent();
    310315        if (Element* parentRendererElement = elementRenderer.element()) {
    311316            if (is<SVGAltGlyphElement>(*parentRendererElement))
    312                 glyphData.fontData = primaryFont;
     317                glyphData.fontData = font.primaryFont();
    313318        }
    314319    }
    315320
    316     const SimpleFontData* fontData = glyphData.fontData;
    317     if (!fontData || !fontData->isSVGFont())
     321    if (!glyphData.fontData->isSVGFont())
    318322        return glyphData;
    319323
    320324    SVGFontElement* fontElement = nullptr;
    321325    SVGFontFaceElement* fontFaceElement = nullptr;
    322     const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
     326    const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(glyphData.fontData, fontFaceElement, fontElement);
    323327    if (!svgFontData)
    324328        return glyphData;
     
    330334    if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength, normalizedSpacesStringCache))
    331335        return glyphData;
     336
     337    GlyphData missingGlyphData = missingGlyphForFont(font);
    332338    if (missingGlyphData.glyph)
    333339        return missingGlyphData;
  • trunk/Source/WebCore/svg/SVGFontData.cpp

    r176298 r177637  
    2323#include "SVGFontData.h"
    2424
     25#include "GlyphPageTreeNode.h"
    2526#include "RenderElement.h"
    2627#include "SVGAltGlyphElement.h"
     
    6465    ASSERT(svgFontFaceElement);
    6566
    66     SVGFontElement* svgFontElement = svgFontFaceElement->associatedFontElement();
    67     ASSERT(svgFontElement);
    68     GlyphData missingGlyphData;
    69     missingGlyphData.fontData = fontData;
    70     missingGlyphData.glyph = svgFontElement->missingGlyph();
    71     fontData->setMissingGlyphData(missingGlyphData);
    72 
    7367    fontData->setZeroWidthSpaceGlyph(0);
    7468    fontData->determinePitch();
Note: See TracChangeset for help on using the changeset viewer.