Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / SVGFontData.cpp
index 962e25d..7cf8028 100644 (file)
@@ -45,8 +45,8 @@ using namespace Unicode;
 namespace WebCore {
 
 SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
-    : CustomFontData(false)
-    , m_svgFontFaceElement(fontFaceElement)
+    : CustomFontData()
+    , m_svgFontFaceElement(fontFaceElement->createWeakRef())
     , m_horizontalOriginX(fontFaceElement->horizontalOriginX())
     , m_horizontalOriginY(fontFaceElement->horizontalOriginY())
     , m_horizontalAdvanceX(fontFaceElement->horizontalAdvanceX())
@@ -57,12 +57,15 @@ SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
     ASSERT_ARG(fontFaceElement, fontFaceElement);
 }
 
+SVGFontData::~SVGFontData()
+{
+}
+
 void SVGFontData::initializeFontData(SimpleFontData* fontData, float fontSize)
 {
     ASSERT(fontData);
 
     SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
-    ASSERT(svgFontFaceElement);
 
     SVGFontElement* svgFontElement = svgFontFaceElement->associatedFontElement();
     ASSERT(svgFontElement);
@@ -121,8 +124,20 @@ void SVGFontData::initializeFontData(SimpleFontData* fontData, float fontSize)
 
 float SVGFontData::widthForSVGGlyph(Glyph glyph, float fontSize) const
 {
+    // FIXME: (http://crbug.com/359380) Width calculation may be triggered after removeNode from the current editing impl.
+    // The retrieved width is not being used, so here we return a dummy value.
+    if (shouldSkipDrawing())
+        return 0.0;
+
     SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
-    ASSERT(svgFontFaceElement);
+
+    // RenderView::clearSelection is invoked while removing some element, e.g.
+    // Document::nodeWillBeRemoved => FrameSelection::nodeWillBeRemoved => RenderView::clearSelection.
+    // Since recalc style has not been executed yet, RenderStyle might have some reference to
+    // SVGFontFaceElement which was also removed.
+    // In this case, use default horizontalAdvanceX instead of associatedFontElement's one.
+    if (!svgFontFaceElement->inDocument())
+        return m_horizontalAdvanceX * scaleEmToUnits(fontSize, svgFontFaceElement->unitsPerEm());
 
     SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
     ASSERT(associatedFontElement);
@@ -155,8 +170,6 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
         arabicForms = charactersWithArabicForm(remainingTextInRun, mirror);
 
     SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
-    ASSERT(svgFontFaceElement);
-
     SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
     ASSERT(associatedFontElement);
 
@@ -176,8 +189,8 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
         if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
             language = parentRenderObjectElement->getAttribute(XMLNames::langAttr);
 
-            if (parentRenderObjectElement->hasTagName(SVGNames::altGlyphTag)) {
-                if (!toSVGAltGlyphElement(parentRenderObjectElement)->hasValidGlyphElements(altGlyphNames))
+            if (isSVGAltGlyphElement(*parentRenderObjectElement)) {
+                if (!toSVGAltGlyphElement(*parentRenderObjectElement).hasValidGlyphElements(altGlyphNames))
                     altGlyphNames.clear();
             }
         }
@@ -187,7 +200,7 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
     size_t altGlyphNamesSize = altGlyphNames.size();
     if (altGlyphNamesSize) {
         for (size_t index = 0; index < altGlyphNamesSize; ++index)
-            associatedFontElement->collectGlyphsForGlyphName(altGlyphNames[index], glyphs);
+            associatedFontElement->collectGlyphsForAltGlyphReference(altGlyphNames[index], glyphs);
 
         // Assign the unicodeStringLength now that its known.
         size_t glyphsSize = glyphs.size();
@@ -198,7 +211,6 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
         // Later code will fail if we do not do this and the glyph is incompatible.
         if (glyphsSize) {
             SVGGlyph& svgGlyph = glyphs[0];
-            iterator.setLastGlyphName(svgGlyph.glyphName);
             glyphData.glyph = svgGlyph.tableEntry;
             advanceLength = svgGlyph.unicodeStringLength;
             return true;
@@ -213,13 +225,11 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
             continue;
         if (!isCompatibleGlyph(svgGlyph, isVerticalText, language, arabicForms, currentCharacter, currentCharacter + svgGlyph.unicodeStringLength))
             continue;
-        iterator.setLastGlyphName(svgGlyph.glyphName);
         glyphData.glyph = svgGlyph.tableEntry;
         advanceLength = svgGlyph.unicodeStringLength;
         return true;
     }
 
-    iterator.setLastGlyphName(String());
     return false;
 }
 
@@ -229,8 +239,6 @@ bool SVGFontData::fillSVGGlyphPage(GlyphPage* pageToFill, unsigned offset, unsig
     ASSERT(fontData->isSVGFont());
 
     SVGFontFaceElement* fontFaceElement = this->svgFontFaceElement();
-    ASSERT(fontFaceElement);
-
     SVGFontElement* fontElement = fontFaceElement->associatedFontElement();
     ASSERT(fontElement);
 
@@ -248,10 +256,8 @@ bool SVGFontData::fillBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageToFi
     for (unsigned i = 0; i < length; ++i) {
         String lookupString(buffer + i, 1);
         fontElement->collectGlyphsForString(lookupString, glyphs);
-        if (glyphs.isEmpty()) {
-            pageToFill->setGlyphDataForIndex(offset + i, 0, 0);
+        if (glyphs.isEmpty())
             continue;
-        }
 
         // Associate entry in glyph page with first valid SVGGlyph.
         // If there are multiple valid ones, just take the first one. WidthIterator will take
@@ -273,10 +279,8 @@ bool SVGFontData::fillNonBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageT
         // Each character here consists of a surrogate pair
         String lookupString(buffer + i * 2, 2);
         fontElement->collectGlyphsForString(lookupString, glyphs);
-        if (glyphs.isEmpty()) {
-            pageToFill->setGlyphDataForIndex(offset + i, 0, 0);
+        if (glyphs.isEmpty())
             continue;
-        }
 
         // Associate entry in glyph page with first valid SVGGlyph.
         // If there are multiple valid ones, just take the first one. WidthIterator will take
@@ -317,6 +321,19 @@ String SVGFontData::createStringWithMirroredCharacters(const String& string) con
     return mirroredCharacters.toString();
 }
 
+SVGFontFaceElement* SVGFontData::svgFontFaceElement() const
+{
+    // FIXME: SVGFontData should be only used from the document with the SVGFontFaceElement.
+    RELEASE_ASSERT(m_svgFontFaceElement && m_svgFontFaceElement->inDocument());
+    return m_svgFontFaceElement.get();
+}
+
+bool SVGFontData::shouldSkipDrawing() const
+{
+    // FIXME: (http://crbug.com/359380) Glyph may be referenced after removeNode from the current editing impl.
+    return !m_svgFontFaceElement || !m_svgFontFaceElement->inDocument();
+}
+
 } // namespace WebCore
 
 #endif