15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if ENABLE(SVG_FONTS)
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGFontData.h"
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/SVGNames.h"
265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/XMLNames.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGTextRunRenderingContext.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGAltGlyphElement.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGFontElement.h"
31e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/svg/SVGFontFaceElement.h"
32e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/svg/SVGGlyphElement.h"
3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/fonts/Character.h"
34a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/SVGGlyph.h"
35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/SimpleFontData.h"
36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/WidthIterator.h"
37a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/text/TextRun.h"
38f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/text/StringBuilder.h"
39f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/unicode/CharacterNames.h"
40f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/unicode/Unicode.h"
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WTF;
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace Unicode;
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : CustomFontData()
496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    , m_svgFontFaceElement(fontFaceElement->createWeakRef())
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_horizontalOriginX(fontFaceElement->horizontalOriginX())
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_horizontalOriginY(fontFaceElement->horizontalOriginY())
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_horizontalAdvanceX(fontFaceElement->horizontalAdvanceX())
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_verticalOriginX(fontFaceElement->verticalOriginX())
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_verticalOriginY(fontFaceElement->verticalOriginY())
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_verticalAdvanceY(fontFaceElement->verticalAdvanceY())
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_ARG(fontFaceElement, fontFaceElement);
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
606f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochSVGFontData::~SVGFontData()
616f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{
626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch}
636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGFontData::initializeFontData(SimpleFontData* fontData, float fontSize)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontData);
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontElement* svgFontElement = svgFontFaceElement->associatedFontElement();
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(svgFontElement);
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphData missingGlyphData;
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    missingGlyphData.fontData = fontData;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    missingGlyphData.glyph = svgFontElement->missingGlyph();
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontData->setMissingGlyphData(missingGlyphData);
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontData->setZeroWidthSpaceGlyph(0);
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontData->determinePitch();
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned unitsPerEm = svgFontFaceElement->unitsPerEm();
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float scale = scaleEmToUnits(fontSize, unitsPerEm);
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float xHeight = svgFontFaceElement->xHeight() * scale;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float ascent = svgFontFaceElement->ascent() * scale;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float descent = svgFontFaceElement->descent() * scale;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float lineGap = 0.1f * fontSize;
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(fontData, 0)->page();
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!xHeight && glyphPageZero) {
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Fallback if x_heightAttr is not specified for the font element.
91c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        Glyph letterXGlyph = glyphPageZero->glyphForCharacter('x');
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        xHeight = letterXGlyph ? fontData->widthForGlyph(letterXGlyph) : 2 * ascent / 3;
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FontMetrics& fontMetrics = fontData->fontMetrics();
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontMetrics.setUnitsPerEm(unitsPerEm);
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontMetrics.setAscent(ascent);
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontMetrics.setDescent(descent);
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontMetrics.setLineGap(lineGap);
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap));
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontMetrics.setXHeight(xHeight);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!glyphPageZero) {
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fontData->setSpaceGlyph(0);
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fontData->setSpaceWidth(0);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fontData->setAvgCharWidth(0);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fontData->setMaxCharWidth(ascent);
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Calculate space width.
112c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    Glyph spaceGlyph = glyphPageZero->glyphForCharacter(' ');
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontData->setSpaceGlyph(spaceGlyph);
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontData->setSpaceWidth(fontData->widthForGlyph(spaceGlyph));
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Estimate average character width.
117c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    Glyph numeralZeroGlyph = glyphPageZero->glyphForCharacter('0');
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontData->setAvgCharWidth(numeralZeroGlyph ? fontData->widthForGlyph(numeralZeroGlyph) : fontData->spaceWidth());
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Estimate maximum character width.
121c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    Glyph letterWGlyph = glyphPageZero->glyphForCharacter('W');
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fontData->setMaxCharWidth(letterWGlyph ? fontData->widthForGlyph(letterWGlyph) : ascent);
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGFontData::widthForSVGGlyph(Glyph glyph, float fontSize) const
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1276f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // FIXME: (http://crbug.com/359380) Width calculation may be triggered after removeNode from the current editing impl.
1286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // The retrieved width is not being used, so here we return a dummy value.
1296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (shouldSkipDrawing())
1306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        return 0.0;
1316f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
1336f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
13407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    // RenderView::clearSelection is invoked while removing some element, e.g.
13507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    // Document::nodeWillBeRemoved => FrameSelection::nodeWillBeRemoved => RenderView::clearSelection.
13607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    // Since recalc style has not been executed yet, RenderStyle might have some reference to
13707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    // SVGFontFaceElement which was also removed.
13807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    // In this case, use default horizontalAdvanceX instead of associatedFontElement's one.
13907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (!svgFontFaceElement->inDocument())
14007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return m_horizontalAdvanceX * scaleEmToUnits(fontSize, svgFontFaceElement->unitsPerEm());
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(associatedFontElement);
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGGlyph svgGlyph = associatedFontElement->svgGlyphForGlyph(glyph);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGGlyphElement::inheritUnspecifiedAttributes(svgGlyph, this);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return svgGlyph.horizontalAdvanceX * scaleEmToUnits(fontSize, svgFontFaceElement->unitsPerEm());
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& glyphData, bool mirror, int currentCharacter, unsigned& advanceLength) const
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const TextRun& run = iterator.run();
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<SVGGlyph::ArabicForm>& arabicForms = iterator.arabicForms();
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(int(run.charactersLength()) >= currentCharacter);
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Associate text with arabic forms, if needed.
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String remainingTextInRun;
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (run.is8Bit()) {
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        remainingTextInRun = String(run.data8(currentCharacter), run.charactersLength() - currentCharacter);
16109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        remainingTextInRun = Character::normalizeSpaces(remainingTextInRun.characters8(), remainingTextInRun.length());
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        remainingTextInRun = String(run.data16(currentCharacter), run.charactersLength() - currentCharacter);
16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        remainingTextInRun = Character::normalizeSpaces(remainingTextInRun.characters16(), remainingTextInRun.length());
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (mirror)
168e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        remainingTextInRun = createStringWithMirroredCharacters(remainingTextInRun);
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!currentCharacter && arabicForms.isEmpty())
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        arabicForms = charactersWithArabicForm(remainingTextInRun, mirror);
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(associatedFontElement);
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* renderObject = 0;
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        renderObject = static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer();
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String language;
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isVerticalText = false;
18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    Vector<AtomicString> altGlyphNames;
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderObject) {
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(parentRenderObject);
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        isVerticalText = parentRenderObject->style()->svgStyle()->isVerticalWritingMode();
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            language = parentRenderObjectElement->getAttribute(XMLNames::langAttr);
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (isSVGAltGlyphElement(*parentRenderObjectElement)) {
193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!toSVGAltGlyphElement(*parentRenderObjectElement).hasValidGlyphElements(altGlyphNames))
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    altGlyphNames.clear();
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<SVGGlyph> glyphs;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t altGlyphNamesSize = altGlyphNames.size();
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (altGlyphNamesSize) {
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t index = 0; index < altGlyphNamesSize; ++index)
203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            associatedFontElement->collectGlyphsForAltGlyphReference(altGlyphNames[index], glyphs);
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Assign the unicodeStringLength now that its known.
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t glyphsSize = glyphs.size();
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0; i < glyphsSize; ++i)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            glyphs[i].unicodeStringLength = run.length();
209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
210926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Do not check alt glyphs for compatibility. Just return the first one.
211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Later code will fail if we do not do this and the glyph is incompatible.
212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (glyphsSize) {
213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            SVGGlyph& svgGlyph = glyphs[0];
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            glyphData.glyph = svgGlyph.tableEntry;
215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            advanceLength = svgGlyph.unicodeStringLength;
216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return true;
217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        associatedFontElement->collectGlyphsForString(remainingTextInRun, glyphs);
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t glyphsSize = glyphs.size();
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < glyphsSize; ++i) {
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        SVGGlyph& svgGlyph = glyphs[i];
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (svgGlyph.isPartOfLigature)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!isCompatibleGlyph(svgGlyph, isVerticalText, language, arabicForms, currentCharacter, currentCharacter + svgGlyph.unicodeStringLength))
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        glyphData.glyph = svgGlyph.tableEntry;
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        advanceLength = svgGlyph.unicodeStringLength;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGFontData::fillSVGGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) const
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontData->isCustomFont());
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontData->isSVGFont());
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontFaceElement* fontFaceElement = this->svgFontFaceElement();
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGFontElement* fontElement = fontFaceElement->associatedFontElement();
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(fontElement);
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (bufferLength == length)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return fillBMPGlyphs(fontElement, pageToFill, offset, length, buffer, fontData);
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(bufferLength == 2 * length);
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fillNonBMPGlyphs(fontElement, pageToFill, offset, length, buffer, fontData);
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGFontData::fillBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, const SimpleFontData* fontData) const
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool haveGlyphs = false;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<SVGGlyph> glyphs;
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < length; ++i) {
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String lookupString(buffer + i, 1);
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fontElement->collectGlyphsForString(lookupString, glyphs);
25910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (glyphs.isEmpty())
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Associate entry in glyph page with first valid SVGGlyph.
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If there are multiple valid ones, just take the first one. WidthIterator will take
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // care of matching to the correct glyph, if multiple ones are available, as that's
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // only possible within the context of a string (eg. arabic form matching).
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        haveGlyphs = true;
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pageToFill->setGlyphDataForIndex(offset + i, glyphs.first().tableEntry, fontData);
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        glyphs.clear();
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return haveGlyphs;
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGFontData::fillNonBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, const SimpleFontData* fontData) const
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool haveGlyphs = false;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<SVGGlyph> glyphs;
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < length; ++i) {
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Each character here consists of a surrogate pair
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String lookupString(buffer + i * 2, 2);
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fontElement->collectGlyphsForString(lookupString, glyphs);
28210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (glyphs.isEmpty())
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Associate entry in glyph page with first valid SVGGlyph.
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If there are multiple valid ones, just take the first one. WidthIterator will take
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // care of matching to the correct glyph, if multiple ones are available, as that's
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // only possible within the context of a string (eg. arabic form matching).
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        haveGlyphs = true;
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pageToFill->setGlyphDataForIndex(offset + i, glyphs.first().tableEntry, fontData);
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        glyphs.clear();
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return haveGlyphs;
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
297e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben MurdochString SVGFontData::createStringWithMirroredCharacters(const String& string) const
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
299e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (string.isEmpty())
300e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        return emptyString();
301e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
302e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    unsigned length = string.length();
303e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder mirroredCharacters;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mirroredCharacters.reserveCapacity(length);
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
307e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (string.is8Bit()) {
308e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        const LChar* characters = string.characters8();
309e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        for (unsigned i = 0; i < length; ++i)
310e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            mirroredCharacters.append(mirroredChar(characters[i]));
311e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    } else {
312e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        const UChar* characters = string.characters16();
313e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        unsigned i = 0;
314e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        while (i < length) {
315e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            UChar32 character;
316e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            U16_NEXT(characters, i, length, character);
317e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            mirroredCharacters.append(mirroredChar(character));
318e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        }
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return mirroredCharacters.toString();
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3246f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochSVGFontFaceElement* SVGFontData::svgFontFaceElement() const
3256f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{
3266f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // FIXME: SVGFontData should be only used from the document with the SVGFontFaceElement.
3276f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    RELEASE_ASSERT(m_svgFontFaceElement && m_svgFontFaceElement->inDocument());
3286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return m_svgFontFaceElement.get();
3296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch}
3306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
3316f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochbool SVGFontData::shouldSkipDrawing() const
3326f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{
3336f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // FIXME: (http://crbug.com/359380) Glyph may be referenced after removeNode from the current editing impl.
3346f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return !m_svgFontFaceElement || !m_svgFontFaceElement->inDocument();
3356f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch}
3366f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
340