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