15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Apple Computer Inc. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Rob Buis <buis@kde.org> 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved. 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGInlineText.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSFontSelector.h" 295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/css/FontSize.h" 30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/StyleEngine.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/VisiblePosition.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGText.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGInlineTextBox.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGRenderingContext.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static PassRefPtr<StringImpl> applySVGWhitespaceRules(PassRefPtr<StringImpl> string, bool preserveWhiteSpace) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preserveWhiteSpace) { 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: When xml:space="preserve", the SVG user agent will do the following using a 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // copy of the original character data content. It will convert all newline and tab 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // characters into space characters. Then, it will draw all space characters, including 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // leading, trailing and multiple contiguous space characters. 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newString = string->replace('\t', ' '); 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newString = newString->replace('\n', ' '); 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newString = newString->replace('\r', ' '); 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newString.release(); 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: When xml:space="default", the SVG user agent will do the following using a 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // copy of the original character data content. First, it will remove all newline 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // characters. Then it will convert all tab characters into space characters. 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Then, it will strip off all leading and trailing space characters. 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Then, all contiguous space characters will be consolidated. 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newString = string->replace('\n', StringImpl::empty()); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newString = newString->replace('\r', StringImpl::empty()); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newString = newString->replace('\t', ' '); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newString.release(); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderSVGInlineText::RenderSVGInlineText(Node* n, PassRefPtr<StringImpl> string) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : RenderText(n, applySVGWhitespaceRules(string, false)) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_scalingFactor(1) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_layoutAttributes(this) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGInlineText::setTextInternal(PassRefPtr<StringImpl> text) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderText::setTextInternal(text); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this)) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) textRenderer->subtreeTextDidChange(this); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderText::styleDidChange(diff, oldStyle); 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScaledFont(); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool newPreserves = style() ? style()->whiteSpace() == PRE : false; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool oldPreserves = oldStyle ? oldStyle->whiteSpace() == PRE : false; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (oldPreserves && !newPreserves) { 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setText(applySVGWhitespaceRules(originalText(), false), true); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!oldPreserves && newPreserves) { 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setText(applySVGWhitespaceRules(originalText(), true), true); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!diff.needsFullLayout()) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The text metrics may be influenced by style changes. 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this)) 985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) textRenderer->setNeedsLayoutAndFullPaintInvalidation(); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineTextBox* RenderSVGInlineText::createTextBox() 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) InlineTextBox* box = new SVGInlineTextBox(*this); 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->setHasVirtualLogicalHeight(); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return box; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderSVGInlineText::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit*) 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box || !box->isInlineTextBox()) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) InlineTextBox* textBox = toInlineTextBox(box); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (static_cast<unsigned>(caretOffset) < textBox->start() || static_cast<unsigned>(caretOffset) > textBox->start() + textBox->len()) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Use the edge of the selection rect to determine the caret rect. 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (static_cast<unsigned>(caretOffset) < textBox->start() + textBox->len()) { 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect rect = textBox->localSelectionRect(caretOffset, caretOffset + 1); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit x = box->isLeftToRightDirection() ? rect.x() : rect.maxX(); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(x, rect.y(), caretWidth, rect.height()); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect rect = textBox->localSelectionRect(caretOffset - 1, caretOffset); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit x = box->isLeftToRightDirection() ? rect.maxX() : rect.x(); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(x, rect.y(), caretWidth, rect.height()); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatRect RenderSVGInlineText::floatLinesBoundingBox() const 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect boundingBox; 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) boundingBox.unite(box->calculateBoundaries()); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return boundingBox; 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect RenderSVGInlineText::linesBoundingBox() const 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return enclosingIntRect(floatLinesBoundingBox()); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderSVGInlineText::characterStartsNewTextChunk(int position) const 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(position >= 0); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(position < static_cast<int>(textLength())); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Each <textPath> element starts a new text chunk, regardless of any x/y values. 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!position && parent()->isSVGTextPath() && !previousSibling()) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SVGCharacterDataMap::const_iterator it = m_layoutAttributes.characterDataMap().find(static_cast<unsigned>(position + 1)); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (it == m_layoutAttributes.characterDataMap().end()) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return it->value.x != SVGTextLayoutAttributes::emptyValue() || it->value.y != SVGTextLayoutAttributes::emptyValue(); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 158f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)PositionWithAffinity RenderSVGInlineText::positionForPoint(const LayoutPoint& point) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstTextBox() || !textLength()) 161f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinity(0, DOWNSTREAM); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float baseline = m_scaledFont.fontMetrics().floatAscent(); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* containingBlock = this->containingBlock(); 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(containingBlock); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates. 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint absolutePoint(point); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) absolutePoint.moveBy(containingBlock->location()); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float closestDistance = std::numeric_limits<float>::max(); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float closestDistancePosition = 0; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SVGTextFragment* closestDistanceFragment = 0; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGInlineTextBox* closestDistanceBox = 0; 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform fragmentTransform; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box->isSVGInlineTextBox()) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 182591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SVGInlineTextBox* textBox = toSVGInlineTextBox(box); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<SVGTextFragment>& fragments = textBox->textFragments(); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned textFragmentsSize = fragments.size(); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < textFragmentsSize; ++i) { 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SVGTextFragment& fragment = fragments.at(i); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height); 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fragment.buildFragmentTransform(fragmentTransform); 190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) fragmentRect = fragmentTransform.mapRect(fragmentRect); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float distance = powf(fragmentRect.x() - absolutePoint.x(), 2) + 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) powf(fragmentRect.y() + fragmentRect.height() / 2 - absolutePoint.y(), 2); 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (distance < closestDistance) { 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) closestDistance = distance; 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) closestDistanceBox = textBox; 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) closestDistanceFragment = &fragment; 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) closestDistancePosition = fragmentRect.x(); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!closestDistanceFragment) 205f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinity(0, DOWNSTREAM); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int offset = closestDistanceBox->offsetForPositionInFragment(*closestDistanceFragment, absolutePoint.x() - closestDistancePosition, true); 208f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinity(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM); 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGInlineText::updateScaledFont() 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeNewScaledFontForStyle(this, style(), m_scalingFactor, m_scaledFont); 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, const RenderStyle* style, float& scalingFactor, Font& scaledFont) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(style); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(renderer); 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 221e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified. 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer); 2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (style->effectiveZoom() == 1 && (scalingFactor == 1 || !scalingFactor)) { 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scalingFactor = 1; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scaledFont = style->font(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 229d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (style->fontDescription().textRendering() == GeometricPrecision) 230e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch scalingFactor = 1; 231e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FontDescription fontDescription(style->fontDescription()); 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 234a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) Document& document = renderer->document(); 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: We need to better handle the case when we compute very small fonts below (below 1pt). 2368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) fontDescription.setComputedSize(FontSize::getComputedSizeFromSpecifiedSize(&document, scalingFactor, fontDescription.isAbsoluteSize(), fontDescription.specifiedSize(), DoNotUseSmartMinimumForFontSize)); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) scaledFont = Font(fontDescription); 239a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) scaledFont.update(document.styleEngine()->fontSelector()); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 243