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