15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if ENABLE(SVG_FONTS)
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGTextRunRenderingContext.h"
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGInlineText.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGResourceSolidColor.h"
297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/svg/SVGRenderSupport.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGFontData.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGFontElement.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGFontFaceElement.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGGlyphElement.h"
3419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "platform/fonts/GlyphBuffer.h"
35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/WidthIterator.h"
36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h"
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline const SVGFontData* svgFontAndFontFaceElementForFontData(const SimpleFontData* fontData, SVGFontFaceElement*& fontFace, SVGFontElement*& font)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontData);
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontData->isCustomFont());
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontData->isSVGFont());
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    RefPtr<CustomFontData> customFontData = fontData->customFontData();
47e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    const SVGFontData* svgFontData = toSVGFontData(customFontData);
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // FIXME crbug.com/359380 : The current editing impl references the font after the svg font nodes are removed.
506f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (svgFontData->shouldSkipDrawing())
516f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        return 0;
526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontFace = svgFontData->svgFontFaceElement();
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontFace);
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    font = fontFace->associatedFontElement();
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return svgFontData;
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderObject* firstParentRendererForNonTextNode(RenderObject* renderer)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(renderer);
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return renderer->isText() ? renderer->parent() : renderer;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderObject* renderObjectFromRun(const TextRun& run)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer();
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, Glyph& glyphId) const
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WidthIterator it(&font, run);
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphBuffer glyphBuffer;
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    charsConsumed += it.advance(run.length(), &glyphBuffer);
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    glyphId = !glyphBuffer.isEmpty() ? glyphBuffer.glyphAt(0) : 0;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return it.runWidthSoFar();
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const TextRun& run, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontElement* fontElement = 0;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontFaceElement* fontFaceElement = 0;
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!fontElement || !fontFaceElement)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We can only paint SVGFonts if a context is available.
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* renderObject = renderObjectFromRun(run);
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(renderObject);
9402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isVerticalText = false;
967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (RenderObject* parentRenderObject = firstParentRendererForNonTextNode(renderObject)) {
977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        RenderStyle* parentRenderObjectStyle = parentRenderObject->style();
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(parentRenderObjectStyle);
99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        isVerticalText = parentRenderObjectStyle->svgStyle().isVerticalWritingMode();
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float scale = scaleEmToUnits(fontData->platformData().size(), fontFaceElement->unitsPerEm());
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatPoint glyphOrigin;
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    glyphOrigin.setX(svgFontData->horizontalOriginX() * scale);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    glyphOrigin.setY(svgFontData->horizontalOriginY() * scale);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1086f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    unsigned short resourceMode = context->textDrawingMode() == TextModeStroke ? ApplyToStrokeMode : ApplyToFillMode;
1096f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatPoint currentPoint = point;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = 0; i < numGlyphs; ++i) {
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Glyph glyph = glyphBuffer.glyphAt(from + i);
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!glyph)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        float advance = glyphBuffer.advanceAt(from + i).width();
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!svgGlyph.isPartOfLigature);
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(svgGlyph.tableEntry == glyph);
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        SVGGlyphElement::inheritUnspecifiedAttributes(svgGlyph, svgFontData);
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Support arbitary SVG content as glyph (currently limited to <glyph d="..."> situations).
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (svgGlyph.pathData.isEmpty()) {
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isVerticalText)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                currentPoint.move(0, advance);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                currentPoint.move(advance, 0);
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)         }
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isVerticalText) {
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            glyphOrigin.setX(svgGlyph.verticalOriginX * scale);
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            glyphOrigin.setY(svgGlyph.verticalOriginY * scale);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)         }
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AffineTransform glyphPathTransform;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        glyphPathTransform.translate(currentPoint.x() + glyphOrigin.x(), currentPoint.y() + glyphOrigin.y());
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        glyphPathTransform.scale(scale, -scale);
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Path glyphPath = svgGlyph.pathData;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        glyphPath.transform(glyphPathTransform);
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        SVGRenderSupport::fillOrStrokePath(context, resourceMode, glyphPath);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isVerticalText)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            currentPoint.move(0, advance);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            currentPoint.move(advance, 0);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, const TextRun& run, WidthIterator& iterator, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength)
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const SimpleFontData* primaryFont = font.primaryFont();
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(primaryFont);
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror);
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphData glyphData = pair.first;
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Check if we have the missing glyph data, in which case we can just return.
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphData missingGlyphData = primaryFont->missingGlyphData();
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (glyphData.glyph == missingGlyphData.glyph && glyphData.fontData == missingGlyphData.fontData) {
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(glyphData.fontData);
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return glyphData;
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Save data fromt he font fallback list because we may modify it later. Do this before the
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // potential change to glyphData.fontData below.
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FontFallbackList* fontList = font.fontList();
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontList);
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FontFallbackList::GlyphPagesStateSaver glyphPagesSaver(*fontList);
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage.
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const SimpleFontData* originalFontData = glyphData.fontData;
17651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (originalFontData && !originalFontData->isSVGFont()) {
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (TextRun::RenderingContext* renderingContext = run.renderingContext()) {
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* renderObject = static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer();
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(parentRenderObject);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (isSVGAltGlyphElement(*parentRenderObjectElement))
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    glyphData.fontData = primaryFont;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const SimpleFontData* fontData = glyphData.fontData;
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (fontData) {
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!fontData->isSVGFont())
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return glyphData;
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        SVGFontElement* fontElement = 0;
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        SVGFontFaceElement* fontFaceElement = 0;
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!fontElement || !fontFaceElement)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return glyphData;
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we got here, we're dealing with a glyph defined in a SVG Font.
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The returned glyph by glyphDataAndPageForCharacter() is a glyph stored in the SVG Font glyph table.
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that.
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength))
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return glyphData;
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphPage* page = pair.second;
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(page);
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // No suitable glyph found that is compatible with the requirments (same language, arabic-form, orientation etc.)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly.
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    page->setGlyphDataForCharacter(character, 0, 0);
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before.
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphData fallbackGlyphData = font.glyphDataForCharacter(character, mirror);
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fallbackGlyphData.fontData != fontData);
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Restore original state of the SVG Font glyph table and the current font fallback list,
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // to assure the next lookup of the same glyph won't immediately return the fallback glyph.
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    page->setGlyphDataForCharacter(character, glyphData.glyph, originalFontData);
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fallbackGlyphData.fontData);
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fallbackGlyphData;
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
230