15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1999 Lars Knoll (knoll@kde.org) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 2000 Dirk Mueller (mueller@kde.org) 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) 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) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderText.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Text.h" 3019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "core/editing/TextIterator.h" 311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/FrameView.h" 3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/frame/Settings.h" 3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/html/parser/TextResourceDecoder.h" 34bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/rendering/AbstractInlineTextBox.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/EllipsisBox.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/InlineTextBox.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderBlock.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderCombineText.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h" 41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/rendering/TextRunConstructor.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/break_lines.h" 4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/fonts/Character.h" 44323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "platform/fonts/FontCache.h" 451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatQuad.h" 4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/text/BidiResolver.h" 471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/TextBreakIterator.h" 4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/text/TextRunIterator.h" 4902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/text/StringBuffer.h" 503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "wtf/text/StringBuilder.h" 5102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/unicode/CharacterNames.h" 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WTF; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace Unicode; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct SameSizeAsRenderText : public RenderObject { 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t bitfields : 16; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float widths[4]; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String text; 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void* pointers[2]; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)COMPILE_ASSERT(sizeof(RenderText) == sizeof(SameSizeAsRenderText), RenderText_should_stay_small); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class SecureTextTimer; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef HashMap<RenderText*, SecureTextTimer*> SecureTextTimerMap; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static SecureTextTimerMap* gSecureTextTimers = 0; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class SecureTextTimer FINAL : public TimerBase { 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SecureTextTimer(RenderText* renderText) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_renderText(renderText) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_lastTypedCharacterOffset(-1) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void restartWithNewText(unsigned lastTypedCharacterOffset) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTypedCharacterOffset = lastTypedCharacterOffset; 828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (Settings* settings = m_renderText->document().settings()) 83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) startOneShot(settings->passwordEchoDurationInSeconds(), FROM_HERE); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void invalidate() { m_lastTypedCharacterOffset = -1; } 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned lastTypedCharacterOffset() { return m_lastTypedCharacterOffset; } 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual void fired() OVERRIDE 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(gSecureTextTimers->contains(m_renderText)); 92e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch m_renderText->setText(m_renderText->text().impl(), true /* forcing setting text as it may be masked later */); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderText* m_renderText; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_lastTypedCharacterOffset; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void makeCapitalized(String* string, UChar previous) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (string->isNull()) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = string->length(); 1055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) const StringImpl& input = *string->impl(); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 107197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (length >= std::numeric_limits<unsigned>::max()) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CRASH(); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuffer<UChar> stringWithPrevious(length + 1); 1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci stringWithPrevious[0] = previous == noBreakSpace ? space : previous; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 1; i < length + 1; i++) { 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Replace   with a real space since ICU no longer treats   as a word separator. 1145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (input[i - 1] == noBreakSpace) 1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci stringWithPrevious[i] = space; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) stringWithPrevious[i] = input[i - 1]; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TextBreakIterator* boundary = wordBreakIterator(stringWithPrevious.characters(), length + 1); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!boundary) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) StringBuilder result; 1255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) result.reserveCapacity(length); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t endOfWord; 1281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) int32_t startOfWord = boundary->first(); 1291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) for (endOfWord = boundary->next(); endOfWord != TextBreakDone; startOfWord = endOfWord, endOfWord = boundary->next()) { 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startOfWord) // Ignore first char of previous string 1315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) result.append(input[startOfWord - 1] == noBreakSpace ? noBreakSpace : toTitleCase(stringWithPrevious[startOfWord])); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = startOfWord + 1; i < endOfWord; i++) 1335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) result.append(input[i - 1]); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) *string = result.toString(); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str) 140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : RenderObject(!node || node->isDocumentNode() ? 0 : node) 141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_hasTab(false) 142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_linesDirty(false) 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_containsReversedText(false) 144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_knownToHaveNoOverflowAndNoFallbackFonts(false) 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_minWidth(-1) 146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_maxWidth(-1) 147591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch , m_firstLineMinWidth(0) 148591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch , m_lastLineLineMinWidth(0) 149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_text(str) 150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_firstTextBox(0) 151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_lastTextBox(0) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME: Some clients of RenderText (and subclasses) pass Document as node to create anonymous renderer. 155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // They should be switched to passing null and using setDocumentForAnonymous. 156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (node && node->isDocumentNode()) 157926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setDocumentForAnonymous(toDocument(node)); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isAllASCII = m_text.containsOnlyASCII(); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath(); 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setIsText(); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) view()->frameView()->incrementVisuallyNonEmptyCharacterCount(m_text.length()); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderText::~RenderText() 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_firstTextBox); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_lastTextBox); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char* RenderText::renderName() const 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return "RenderText"; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::isTextFragment() const 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::isWordBreak() const 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // There is no need to ever schedule paint invalidations from a style change of a text run, since 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // we already did this for the parent of the text run. 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We do have to schedule layouts, though, since a style change can force us to 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // need to relayout. 19710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (diff.needsFullLayout()) { 1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci setNeedsLayoutAndPrefWidthsRecalc(); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = false; 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* newStyle = style(); 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE; 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE; 2051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity()) 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transformText(); 207e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 208f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // This is an optimization that kicks off font load before layout. 209f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // In order to make it fast, we only check if the first character of the 210f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // text is included in the unicode ranges of the fonts. 211e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!text().containsOnlyWhitespace()) 212f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu newStyle->font().willUseFontData(text().characterStartingAt(0)); 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::removeAndDestroyTextBoxes() 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!documentBeingDestroyed()) { 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstTextBox()) { 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isBR()) { 220d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RootInlineBox* next = firstTextBox()->root().nextRootBox(); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->markDirty(); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->remove(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (parent()) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parent()->dirtyLinesFromChangedChild(this); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) deleteTextBoxes(); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::willBeDestroyed() 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->take(this) : 0) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete secureTextTimer; 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeAndDestroyTextBoxes(); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject::willBeDestroyed(); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::extractTextBox(InlineTextBox* box) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = box->prevTextBox(); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box == m_firstTextBox) 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = 0; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->prevTextBox()) 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->prevTextBox()->setNextTextBox(0); 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->setPreviousTextBox(0); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox()) 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->setExtracted(); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::attachTextBox(InlineTextBox* box) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_lastTextBox) { 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox->setNextTextBox(box); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->setPreviousTextBox(m_lastTextBox); 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = box; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* last = box; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox()) { 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->setExtracted(false); 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) last = curr; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = last; 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::removeTextBox(InlineTextBox* box) 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box == m_firstTextBox) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = box->nextTextBox(); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box == m_lastTextBox) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = box->prevTextBox(); 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->nextTextBox()) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->nextTextBox()->setPreviousTextBox(box->prevTextBox()); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->prevTextBox()) 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->prevTextBox()->setNextTextBox(box->nextTextBox()); 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::deleteTextBoxes() 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstTextBox()) { 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* next; 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = next) { 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next = curr->nextTextBox(); 298f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) curr->destroy(); 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = m_lastTextBox = 0; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> RenderText::originalText() const 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* e = node(); 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (e && e->isTextNode()) ? toText(e)->dataImpl() : 0; 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 31019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)String RenderText::plainText() const 31119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){ 31219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (node()) 313c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return blink::plainText(rangeOfContents(node()).get()); 31419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) 31519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) // FIXME: this is just a stopgap until TextIterator is adapted to support generated text. 31619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) StringBuilder plainTextBuilder; 31719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) for (InlineTextBox* textBox = firstTextBox(); textBox; textBox = textBox->nextTextBox()) { 31819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) String text = m_text.substring(textBox->start(), textBox->len()).simplifyWhiteSpace(WTF::DoNotStripWhiteSpace); 31919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) plainTextBuilder.append(text); 32019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (textBox->nextTextBox() && textBox->nextTextBox()->start() > textBox->end() && text.length() && !text.right(1).containsOnlyWhitespace()) 3217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci plainTextBuilder.append(space); 32219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) } 32319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) return plainTextBuilder.toString(); 32419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)} 32519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rects.append(enclosingIntRect(FloatRect(accumulatedOffset + box->topLeft(), box->size()))); 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigned end, bool useSelectionHeight) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 334197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch unsigned realEnd = std::min(box->end() + 1, end); 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect r = box->localSelectionRect(start, realEnd); 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (r.height()) { 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!useSelectionHeight) { 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Change the height and y position (or width and x for vertical text) 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // because selectionRect uses selection-specific values. 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isHorizontal()) { 34106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) r.setHeight(box->height()); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setY(box->y()); 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 34406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) r.setWidth(box->width()); 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setX(box->x()); 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return FloatRect(r); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return FloatRect(); 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX 35602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 35702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // function to take ints causes various internal mismatches. But selectionRect takes ints, and 35802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX. 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(end == UINT_MAX || end <= INT_MAX); 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(start <= INT_MAX); 362197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch start = std::min(start, static_cast<unsigned>(INT_MAX)); 363197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch end = std::min(end, static_cast<unsigned>(INT_MAX)); 36402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: box->end() returns the index of the last character, not the index past it 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (start <= box->start() && box->end() < end) { 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect r = box->calculateBoundaries(); 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (useSelectionHeight) { 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect selectionRect = box->localSelectionRect(start, end); 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isHorizontal()) { 372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setHeight(selectionRect.height().toFloat()); 373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setY(selectionRect.y().toFloat()); 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 375d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setWidth(selectionRect.width().toFloat()); 376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setX(selectionRect.x().toFloat()); 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 379926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) rects.append(localToAbsoluteQuad(r, 0, wasFixed).enclosingBoundingBox()); 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rect.isZero()) 384926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) rects.append(localToAbsoluteQuad(rect, 0, wasFixed).enclosingBoundingBox()); 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigned endPos) 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box) 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 39302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned short truncation = box->truncation(); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (truncation == cNoTruncation) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 39702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect rect; 399d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (EllipsisBox* ellipsis = box->root().ellipsisBox()) { 400197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch int ellipsisStartPosition = std::max<int>(startPos - box->start(), 0); 401197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch int ellipsisEndPosition = std::min<int>(endPos - box->start(), box->len()); 40202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The ellipsis should be considered to be selected if the end of 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the selection is past the beginning of the truncation and the 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // beginning of the selection is before or at the beginning of the truncation. 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= truncation) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ellipsis->selectionRect(); 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 40902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 41202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, ClippingOption option) const 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect boundaries = box->calculateBoundaries(); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Shorten the width of this text box if it ends in an ellipsis. 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch. 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(box, 0, textLength()) : IntRect(); 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ellipsisRect.isEmpty()) { 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->isHorizontalWritingMode()) 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) boundaries.setWidth(ellipsisRect.maxX() - boundaries.x()); 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 427926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) quads.append(localToAbsoluteQuad(boundaries, 0, wasFixed)); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 43002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) absoluteQuads(quads, wasFixed, NoClipping); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX 43902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 44002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // function to take ints causes various internal mismatches. But selectionRect takes ints, and 44102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX. 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(end == UINT_MAX || end <= INT_MAX); 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(start <= INT_MAX); 445197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch start = std::min(start, static_cast<unsigned>(INT_MAX)); 446197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch end = std::min(end, static_cast<unsigned>(INT_MAX)); 44702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: box->end() returns the index of the last character, not the index past it 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (start <= box->start() && box->end() < end) { 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect r = box->calculateBoundaries(); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (useSelectionHeight) { 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect selectionRect = box->localSelectionRect(start, end); 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isHorizontal()) { 455d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setHeight(selectionRect.height().toFloat()); 456d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setY(selectionRect.y().toFloat()); 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 458d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setWidth(selectionRect.width().toFloat()); 459d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) r.setX(selectionRect.x().toFloat()); 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 462926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) quads.append(localToAbsoluteQuad(r, 0, wasFixed)); 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rect.isZero()) 466926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) quads.append(localToAbsoluteQuad(rect, 0, wasFixed)); 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPositionIsNotAtStart }; 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* box, ShouldAffinityBeDownstream& shouldAffinityBeDownstream) 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = AlwaysDownstream; 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the x coordinate is equal to the left edge of this box 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the affinity must be downstream so the position doesn't jump back to the previous line 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // except when box is the first box in the line 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointLineDirection <= box->logicalLeft()) { 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = !box->prevLeafChild() ? UpstreamIfPositionIsNotAtStart : AlwaysDownstream; 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and the x coordinate is to the left of the right edge of this box 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // check to see if position goes in this box 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointLineDirection < box->logicalRight()) { 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // box is first on line 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and the x coordinate is to the left of the first text box left edge 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box->prevLeafChildIgnoringLineBreak() && pointLineDirection < box->logicalLeft()) 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box->nextLeafChildIgnoringLineBreak()) { 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // box is last on line 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and the x coordinate is to the right of the last text box right edge 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // generate VisiblePosition, use UPSTREAM affinity if possible 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 508f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)static PositionWithAffinity createPositionWithAffinityForBox(const InlineBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream) 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EAffinity affinity = VP_DEFAULT_AFFINITY; 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (shouldAffinityBeDownstream) { 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AlwaysDownstream: 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) affinity = DOWNSTREAM; 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AlwaysUpstream: 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) affinity = VP_UPSTREAM_IF_POSSIBLE; 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UpstreamIfPositionIsNotAtStart: 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM; 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 522d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) int textStartOffset = box->renderer().isText() ? toRenderText(box->renderer()).textStartOffset() : 0; 523d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return box->renderer().createPositionWithAffinity(offset + textStartOffset, affinity); 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 526f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream) 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(box); 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(offset >= 0); 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (offset && static_cast<unsigned>(offset) < box->len()) 532f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->start() + offset, shouldAffinityBeDownstream); 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool positionIsAtStartOfBox = !offset; 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (positionIsAtStartOfBox == box->isLeftToRightDirection()) { 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // offset is on the left edge 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((prevBox && prevBox->bidiLevel() == box->bidiLevel()) 540d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || box->renderer().containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA 541f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream); 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) { 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. left of B in aDC12BAb 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* leftmostBox; 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leftmostBox = prevBox; 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (prevBox && prevBox->bidiLevel() > box->bidiLevel()); 550f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream); 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!prevBox || prevBox->bidiLevel() < box->bidiLevel()) { 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. left of D in aDC12BAb 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* rightmostBox; 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* nextBox = box; 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightmostBox = nextBox; 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (nextBox && nextBox->bidiLevel() >= box->bidiLevel()); 561f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(rightmostBox, 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream); 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 565f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream); 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((nextBox && nextBox->bidiLevel() == box->bidiLevel()) 570d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || box->renderer().containingBlock()->style()->direction() == box->direction()) 571f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream); 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // offset is on the right edge 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (nextBox && nextBox->bidiLevel() > box->bidiLevel()) { 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. right of C in aDC12BAb 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* rightmostBox; 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightmostBox = nextBox; 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (nextBox && nextBox->bidiLevel() > box->bidiLevel()); 581f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream); 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nextBox || nextBox->bidiLevel() < box->bidiLevel()) { 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. right of A in aDC12BAb 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* leftmostBox; 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* prevBox = box; 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leftmostBox = prevBox; 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (prevBox && prevBox->bidiLevel() >= box->bidiLevel()); 592f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(leftmostBox, 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream); 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 596f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream); 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 599f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)PositionWithAffinity RenderText::positionForPoint(const LayoutPoint& point) 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstTextBox() || textLength() == 0) 602f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinity(0, DOWNSTREAM); 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y(); 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x(); 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* lastBox = 0; 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak()) 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box = box->nextTextBox(); 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 613d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RootInlineBox& rootBox = box->root(); 614197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch LayoutUnit top = std::min(rootBox.selectionTop(), rootBox.lineTop()); 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirection == top)) { 616d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) LayoutUnit bottom = rootBox.selectionBottom(); 617d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (rootBox.nextRootBox()) 618197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bottom = std::min(bottom, rootBox.nextRootBox()->lineTop()); 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) { 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ShouldAffinityBeDownstream shouldAffinityBeDownstream; 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream)) 623d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection.toFloat()), shouldAffinityBeDownstream); 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastBox = box; 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastBox) { 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ShouldAffinityBeDownstream shouldAffinityBeDownstream; 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream); 632d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection.toFloat()) + lastBox->start(), shouldAffinityBeDownstream); 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 634f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinity(0, DOWNSTREAM); 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine) 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!inlineBox) 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(inlineBox->isInlineTextBox()); 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!inlineBox->isInlineTextBox()) 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* box = toInlineTextBox(inlineBox); 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 648d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) int height = box->root().selectionHeight(); 649d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) int top = box->root().selectionTop(); 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Go ahead and round left to snap it to the nearest pixel. 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float left = box->positionForOffset(caretOffset); 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Distribute the caret's width to either side of the offset. 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int caretWidthLeftOfOffset = caretWidth / 2; 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left -= caretWidthLeftOfOffset; 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset; 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left = roundf(left); 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 661d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float rootLeft = box->root().logicalLeft(); 662d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float rootRight = box->root().logicalRight(); 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: should we use the width of the root inline box or the 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // width of the containing block for this? 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (extraWidthToEndOfLine) 667d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left + 1); 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* cb = containingBlock(); 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* cbStyle = cb->style(); 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float leftEdge; 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float rightEdge; 674197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch leftEdge = std::min<float>(0, rootLeft); 675197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch rightEdge = std::max<float>(cb->logicalWidth().toFloat(), rootRight); 6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool rightAligned = false; 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (cbStyle->textAlign()) { 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case RIGHT: 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WEBKIT_RIGHT: 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightAligned = true; 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case LEFT: 6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WEBKIT_LEFT: 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CENTER: 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WEBKIT_CENTER: 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case JUSTIFY: 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TASTART: 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightAligned = !cbStyle->isLeftToRightDirection(); 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TAEND: 6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightAligned = cbStyle->isLeftToRightDirection(); 6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // for dir=auto, use inlineBoxBidiLevel() to test the correct direction for the cursor. 6987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (rightAligned && (node() && node()->selfOrAncestorHasDirAutoAttribute())) { 6997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (inlineBox->bidiLevel()%2 != 1) 7007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci rightAligned = false; 7017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 7027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rightAligned) { 704197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch left = std::max(left, leftEdge); 705197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch left = std::min(left, rootRight - caretWidth); 7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 707197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch left = std::min(left, rightEdge - caretWidthRightOfOffset); 708197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch left = std::max(left, rootLeft); 7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, height) : IntRect(top, left, height, caretWidth); 7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 71409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len, float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->hasTextCombine() && isCombineText()) { 7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const RenderCombineText* combineText = toRenderCombineText(this); 7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (combineText->isCombined()) 7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return combineText->combinedTextWidth(f); 7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 72276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) if (f.isFixedPitch() && f.fontDescription().variant() == FontVariantNormal && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) { 7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float monospaceCharacterWidth = f.spaceWidth(); 7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float w = 0; 7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isSpace; 7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = start; i < start + len; i++) { 7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) char c = text[i]; 7307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (c <= space) { 7317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (c == space || c == newlineCharacter) { 7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += monospaceCharacterWidth; 7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 7347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (c == characterTabulation) { 7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->collapseWhiteSpace()) { 7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += monospaceCharacterWidth; 7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += f.tabWidth(style()->tabSize(), xPos + w); 7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += monospaceCharacterWidth; 7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isSpace && i > start) 74909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) w += f.fontDescription().wordSpacing(); 7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return w; 7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 754c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) TextRun run = constructTextRun(const_cast<RenderText*>(this), f, this, start, len, style(), textDirection); 7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharactersLength(textLength() - start); 7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run.charactersLength() >= run.length()); 7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharacterScanForCodePath(!canUseSimpleFontCodePath()); 7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setXPos(xPos); 761323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) FontCachePurgePreventer fontCachePurgePreventer; 7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return f.width(run, fallbackFonts, glyphOverflow); 7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::trimmedPrefWidths(float leadWidth, 766591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float& firstLineMinWidth, bool& hasBreakableStart, 767591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float& lastLineMinWidth, bool& hasBreakableEnd, 768591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch bool& hasBreakableChar, bool& hasBreak, 769591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float& firstLineMaxWidth, float& lastLineMaxWidth, 77009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float& minWidth, float& maxWidth, bool& stripFrontSpaces, 77109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) TextDirection direction) 7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool collapseWhiteSpace = style()->collapseWhiteSpace(); 7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!collapseWhiteSpace) 7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stripFrontSpaces = false; 7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_hasTab || preferredLogicalWidthsDirty()) 7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computePreferredLogicalWidths(leadWidth); 7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 780591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch hasBreakableStart = !stripFrontSpaces && m_hasBreakableStart; 781591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch hasBreakableEnd = m_hasBreakableEnd; 7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int len = textLength(); 7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!len || (stripFrontSpaces && text().impl()->containsOnlyWhitespace())) { 786591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMinWidth = 0; 787591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMinWidth = 0; 788591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = 0; 789591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMaxWidth = 0; 790591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch minWidth = 0; 791591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch maxWidth = 0; 7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasBreak = false; 7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 796591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch minWidth = m_minWidth; 797591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch maxWidth = m_maxWidth; 7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 799591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMinWidth = m_firstLineMinWidth; 800591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMinWidth = m_lastLineLineMinWidth; 8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasBreakableChar = m_hasBreakableChar; 8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasBreak = m_hasBreak; 8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 8077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (text[0] == space || (text[0] == newlineCharacter && !style()->preserveNewline()) || text[0] == characterTabulation) { 8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Font& font = style()->font(); // FIXME: This ignores first-line. 8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stripFrontSpaces) { 8107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const UChar spaceChar = space; 8117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci float spaceWidth = font.width(constructTextRun(this, font, &spaceChar, 1, style(), direction)); 812591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch maxWidth -= spaceWidth; 813591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } else { 81409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) maxWidth += font.fontDescription().wordSpacing(); 815591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 818591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch stripFrontSpaces = collapseWhiteSpace && m_hasEndWhiteSpace; 8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 820591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!style()->autoWrap() || minWidth > maxWidth) 821591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch minWidth = maxWidth; 8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Compute our max widths by scanning the string for newlines. 8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasBreak) { 8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Font& f = style()->font(); // FIXME: This ignores first-line. 8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool firstLine = true; 827591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = maxWidth; 828591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMaxWidth = maxWidth; 8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < len; i++) { 8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int linelen = 0; 8317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci while (i + linelen < len && text[i + linelen] != newlineCharacter) 8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) linelen++; 8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (linelen) { 83509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + lastLineMaxWidth, direction, 0, 0); 8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstLine) { 8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLine = false; 8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leadWidth = 0; 839591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = lastLineMaxWidth; 8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) i += linelen; 8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (firstLine) { 843591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = 0; 8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLine = false; 8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leadWidth = 0; 8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 848591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (i == len - 1) { 8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // A <pre> run that ends with a newline, as in, e.g., 8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // <pre>Some text\n\n<span>More text</pre> 851591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMaxWidth = 0; 852591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::minLogicalWidth() const 8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preferredLogicalWidthsDirty()) 8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const_cast<RenderText*>(this)->computePreferredLogicalWidths(0); 86102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_minWidth; 8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::maxLogicalWidth() const 8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preferredLogicalWidthsDirty()) 8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const_cast<RenderText*>(this)->computePreferredLogicalWidths(0); 86902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_maxWidth; 8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::computePreferredLogicalWidths(float leadWidth) 8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HashSet<const SimpleFontData*> fallbackFonts; 8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GlyphOverflow glyphOverflow; 8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphOverflow); 878c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 879c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // We shouldn't change our mind once we "know". 880c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts || (fallbackFonts.isEmpty() && glyphOverflow.isZero())); 881c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts.isEmpty() && glyphOverflow.isZero(); 8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 88409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static inline float hyphenWidth(RenderText* renderer, const Font& font, TextDirection direction) 8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* style = renderer->style(); 887c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return font.width(constructTextRun(renderer, font, style->hyphenString().string(), style, direction)); 8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow) 8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts); 8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = 0; 8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_maxWidth = 0; 896591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_firstLineMinWidth = 0; 897591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_lastLineLineMinWidth = 0; 8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isBR()) 9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float currMinWidth = 0; 9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float currMaxWidth = 0; 9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreakableChar = false; 9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreak = false; 9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasTab = false; 907591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasBreakableStart = false; 908591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasBreakableEnd = false; 909591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasEndWhiteSpace = false; 9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* styleToUse = style(); 9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Font& f = styleToUse->font(); // FIXME: This ignores first-line. 9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float wordSpacing = styleToUse->wordSpacing(); 9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int len = textLength(); 9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LazyLineBreakIterator breakIterator(m_text, styleToUse->locale()); 9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needsWordSpacing = false; 9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool ignoringSpaces = false; 9185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isSpace = false; 9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool firstWord = true; 9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool firstLine = true; 9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int nextBreakable = -1; 9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int lastWordBoundary = 0; 923d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float cachedWordTrailingSpaceWidth[2] = { 0, 0 }; // LTR, RTL 9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int firstGlyphLeftOverflow = -1; 9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool breakAll = (styleToUse->wordBreak() == BreakAllWordBreak || styleToUse->wordBreak() == BreakWordBreak) && styleToUse->autoWrap(); 9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 92909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) TextRun textRun(text()); 93009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; 93143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) BidiCharacterRun* run; 93243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) TextDirection textDirection = styleToUse->direction(); 93343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (isOverride(styleToUse->unicodeBidi())) { 93443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) run = 0; 93543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) } else { 936c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) BidiStatus status(textDirection, false); 93743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) bidiResolver.setStatus(status); 93843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&textRun, 0)); 93943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) bool hardLineBreak = false; 94043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) bool reorderRuns = false; 94143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) bidiResolver.createBidiRunsForLine(TextRunIterator(&textRun, textRun.length()), NoVisualOverride, hardLineBreak, reorderRuns); 94243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs(); 94343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) run = bidiRuns.firstRun(); 94443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) } 94543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < len; i++) { 94793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) UChar c = uncheckedCharacterAt(i); 9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 94943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (run) { 95043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // Treat adjacent runs with the same resolved directionality 95143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // (TextDirection as opposed to WTF::Unicode::Direction) as belonging 95243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // to the same run to avoid breaking unnecessarily. 953c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) while (i >= run->stop() || (run->next() && run->next()->direction() == run->direction())) 95443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) run = run->next(); 9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 95643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) ASSERT(run); 95743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) ASSERT(i <= run->stop()); 95843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) textDirection = run->direction(); 95943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) } 96009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 96109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bool previousCharacterIsSpace = isSpace; 9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isNewline = false; 9637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (c == newlineCharacter) { 9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (styleToUse->preserveNewline()) { 9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreak = true; 9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isNewline = true; 9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 9707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (c == characterTabulation) { 9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!styleToUse->collapseWhiteSpace()) { 9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasTab = true; 9735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 9767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 9777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci isSpace = c == space; 9787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 980591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch bool isBreakableLocation = isNewline || (isSpace && styleToUse->autoWrap()); 981591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!i) 982591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasBreakableStart = isBreakableLocation; 983591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (i == len - 1) { 984591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasBreakableEnd = isBreakableLocation; 985591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasEndWhiteSpace = isNewline || isSpace; 986591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ignoringSpaces && styleToUse->collapseWhiteSpace() && previousCharacterIsSpace && isSpace) 9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ignoringSpaces = true; 9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ignoringSpaces && !isSpace) 9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ignoringSpaces = false; 9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ignore spaces and soft hyphens 9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ignoringSpaces) { 9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(lastWordBoundary == i); 9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary++; 9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 999f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } else if (c == softHyphen) { 100009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow); 10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstGlyphLeftOverflow < 0) 10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstGlyphLeftOverflow = glyphOverflow.left; 10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary = i + 1; 10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 100753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable); 10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool betweenWords = true; 10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int j = i; 10107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci while (c != newlineCharacter && c != space && c != characterTabulation && (c != softHyphen)) { 10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) j++; 10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (j == len) 10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 101493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) c = uncheckedCharacterAt(j); 101553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (isBreakable(breakIterator, j, nextBreakable) && characterAt(j - 1) != softHyphen) 10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (breakAll) { 10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) betweenWords = false; 10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 102309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Terminate word boundary at bidi run boundary. 102443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (run) 1025197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch j = std::min(j, run->stop() + 1); 10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int wordLen = j - i; 10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wordLen) { 10287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool isSpace = (j < len) && c == space; 1029d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 1030d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Non-zero only when kerning is enabled, in which case we measure words with their trailing 1031d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // space, then subtract its width. 1032d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float wordTrailingSpaceWidth = 0; 1033d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isSpace && (f.fontDescription().typesettingFeatures() & Kerning)) { 1034d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(textDirection >=0 && textDirection <= 1); 1035d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!cachedWordTrailingSpaceWidth[textDirection]) 1036c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) cachedWordTrailingSpaceWidth[textDirection] = f.width(constructTextRun(this, f, &space, 1, styleToUse, textDirection)) + wordSpacing; 1037d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirection]; 1038d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 1039d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float w; 10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wordTrailingSpaceWidth && isSpace) 104209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth; 10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 104409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow); 1045f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (c == softHyphen) 104609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) currMinWidth += hyphenWidth(this, f, textDirection); 10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstGlyphLeftOverflow < 0) 10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstGlyphLeftOverflow = glyphOverflow.left; 10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMinWidth += w; 10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (betweenWords) { 10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastWordBoundary == i) 10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += w; 10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 105609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow); 10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary = j; 10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isCollapsibleWhiteSpace = (j < len) && styleToUse->isCollapsibleWhiteSpace(c); 10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (j < len && styleToUse->autoWrap()) 10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreakableChar = true; 10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add in wordSpacing to our currMaxWidth, but not if this is the last word on a line or the 10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // last word in the run. 10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !containsOnlyWhitespace(j, len-j)) 10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += wordSpacing; 10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstWord) { 10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstWord = false; 10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the first character in the run is breakable, then we consider ourselves to have a beginning 10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // minimum width of 0, since a break could occur right before our run starts, preventing us from ever 10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // being appended to a previous text run when considering the total minimum width of the containing block. 10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasBreak) 10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreakableChar = true; 1076591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_firstLineMinWidth = hasBreak ? 0 : currMinWidth; 10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1078591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_lastLineLineMinWidth = currMinWidth; 10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currMinWidth > m_minWidth) 10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = currMinWidth; 10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMinWidth = 0; 10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) i += wordLen - 1; 10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Nowrap can never be broken, so don't bother setting the 10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // breakable character boolean. Pre can only be broken if we encounter a newline. 10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->autoWrap() || isNewline) 10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreakableChar = true; 10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currMinWidth > m_minWidth) 10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = currMinWidth; 10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMinWidth = 0; 10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isNewline) { // Only set if preserveNewline was true and we saw a newline. 10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstLine) { 10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLine = false; 10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leadWidth = 0; 10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!styleToUse->autoWrap()) 1100591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_firstLineMinWidth = currMaxWidth; 11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currMaxWidth > m_maxWidth) 11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_maxWidth = currMaxWidth; 11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth = 0; 11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) TextRun run = constructTextRun(this, f, this, i, 1, styleToUse, textDirection); 11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharactersLength(len - i); 11092fb29a03d7c71253319f61b77edc6c1e3a8fc8e2Torne (Richard Coles) run.setUseComplexCodePath(!canUseSimpleFontCodePath()); 11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run.charactersLength() >= run.length()); 11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setXPos(leadWidth + currMaxWidth); 11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += f.width(run); 11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) glyphOverflow.right = 0; 11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1; 11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(lastWordBoundary == i); 11195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary++; 11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 112243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (run) 112343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) bidiResolver.runs().deleteRuns(); 11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstGlyphLeftOverflow > 0) 11265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) glyphOverflow.left = firstGlyphLeftOverflow; 11275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord)) 11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += wordSpacing; 11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_minWidth = std::max(currMinWidth, m_minWidth); 1132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_maxWidth = std::max(currMaxWidth, m_maxWidth); 11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!styleToUse->autoWrap()) 11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = m_maxWidth; 11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (styleToUse->whiteSpace() == PRE) { 11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstLine) 1139591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_firstLineMinWidth = m_maxWidth; 1140591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_lastLineLineMinWidth = currMaxWidth; 11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1143c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) clearPreferredLogicalWidthsDirty(); 11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11465267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)bool RenderText::isAllCollapsibleWhitespace() const 11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned length = textLength(); 1149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (is8Bit()) { 1150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < length; ++i) { 1151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!style()->isCollapsibleWhiteSpace(characters8()[i])) 1152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 1155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < length; ++i) { 1157926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!style()->isCollapsibleWhiteSpace(characters16()[i])) 11585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 116202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const 11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 11665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned currPos; 11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (currPos = from; 11697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci currPos < from + len && (text[currPos] == newlineCharacter || text[currPos] == space || text[currPos] == characterTabulation); 11707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci currPos++) { } 11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return currPos >= (from + len); 11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatPoint RenderText::firstRunOrigin() const 11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntPoint(firstRunX(), firstRunY()); 11775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::firstRunX() const 11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_firstTextBox ? m_firstTextBox->x() : 0; 11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::firstRunY() const 11855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_firstTextBox ? m_firstTextBox->y() : 0; 11875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 118802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setSelectionState(SelectionState state) 11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject::setSelectionState(state); 11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (canUpdateSelectionOnRootLineBoxes()) { 11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) { 11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int startPos, endPos; 11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectionStartEnd(startPos, endPos); 11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionStart) { 11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endPos = textLength(); 11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to handle selection from end of text to end of line 12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startPos && startPos == endPos) 12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = endPos - 1; 12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (selectionState() == SelectionEnd) 12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = 0; 12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isSelected(startPos, endPos)) { 1208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) box->root().setHasSelectedChildren(true); 12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 1213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) box->root().setHasSelectedChildren(state == SelectionInside); 12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The containing block can be null in case of an orphaned tree. 12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* containingBlock = this->containingBlock(); 12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (containingBlock && !containingBlock->isRenderView()) 12215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) containingBlock->setSelectionState(state); 12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force) 12255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!force && equal(m_text.impl(), text.get())) 12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 12285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned oldLen = textLength(); 12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned newLen = text->length(); 12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int delta = newLen - oldLen; 12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned end = len ? offset + len - 1 : offset; 12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* firstRootBox = 0; 12355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* lastRootBox = 0; 12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool dirtiedLines = false; 12385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Dirty all text boxes that include characters in between offset and offset+len. 12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: This shouldn't rely on the end of a dirty line box. See https://bugs.webkit.org/show_bug.cgi?id=97264 12425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run is entirely before the affected range. 12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr->end() < offset) 12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run is entirely after the affected range. 12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr->start() > end) { 12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->offsetRun(delta); 1249d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RootInlineBox* root = &curr->root(); 12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstRootBox) { 12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstRootBox = root; 125293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // The affected area was in between two runs. Go ahead and mark the root box of 125393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // the run after the affected area as dirty. 125493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) firstRootBox->markDirty(); 125593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) dirtiedLines = true; 12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRootBox = root; 12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (curr->end() >= offset && curr->end() <= end) { 12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run overlaps with the left end of the affected range. 12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->dirtyLineBoxes(); 12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (curr->start() <= offset && curr->end() >= end) { 12635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run subsumes the affected range. 12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->dirtyLineBoxes(); 12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (curr->start() <= end && curr->end() >= end) { 12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run overlaps with right end of the affected range. 12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->dirtyLineBoxes(); 12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now we have to walk all of the clean lines and adjust their cached line break information 12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to reflect our updated offsets. 12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastRootBox) 12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRootBox = lastRootBox->nextRootBox(); 12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstRootBox) { 12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* prev = firstRootBox->prevRootBox(); 12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (prev) 12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstRootBox = prev; 12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (lastTextBox()) { 12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!lastRootBox); 1283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) firstRootBox = &lastTextBox()->root(); 12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstRootBox->markDirty(); 12855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) { 12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr->lineBreakObj() == this && curr->lineBreakPos() > end) 1289e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) curr->setLineBreakPos(clampToInteger(curr->lineBreakPos() + delta)); 12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the text node is empty, dirty the line where new text will be inserted. 12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstTextBox() && parent()) { 12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parent()->dirtyLinesFromChangedChild(this); 12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_linesDirty = dirtiedLines; 12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setText(text, force || dirtiedLines); 13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::transformText() 13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RefPtr<StringImpl> textToTransform = originalText()) 13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setText(textToTransform.release(), true); 13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isInlineFlowOrEmptyText(const RenderObject* o) 13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (o->isRenderInline()) 13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!o->isText()) 13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1314e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return toRenderText(o)->text().isEmpty(); 13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)UChar RenderText::previousCharacter() const 13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // find previous text renderer if one exists 1320197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const RenderObject* previousText = previousInPreOrder(); 1321197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch for (; previousText; previousText = previousText->previousInPreOrder()) 13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInlineFlowOrEmptyText(previousText)) 13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci UChar prev = space; 13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (previousText && previousText->isText()) 1326e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (StringImpl* previousString = toRenderText(previousText)->text().impl()) 13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prev = (*previousString)[previousString->length() - 1]; 13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return prev; 13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1331f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void RenderText::addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const 13327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{ 13337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Text nodes aren't event targets, so don't descend any further. 13347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch} 13357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void applyTextTransform(const RenderStyle* style, String& text, UChar previousCharacter) 13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style) 13395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (style->textTransform()) { 13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TTNONE: 13435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CAPITALIZE: 13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeCapitalized(&text, previousCharacter); 13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UPPERCASE: 13481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) text = text.upper(style->locale()); 13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case LOWERCASE: 13511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) text = text.lower(style->locale()); 13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setTextInternal(PassRefPtr<StringImpl> text) 13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(text); 13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_text = text; 13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()) { 13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) applyTextTransform(style(), m_text, previousCharacter()); 13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We use the same characters here as for list markers. 13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See the listMarkerText function in RenderListMarker.cpp. 13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (style()->textSecurity()) { 13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSNONE: 13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSCIRCLE: 13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureText(whiteBullet); 13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSDISC: 13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureText(bullet); 13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSSQUARE: 13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureText(blackSquare); 13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 13817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!isBR() || (textLength() == 1 && m_text[0] == newlineCharacter)); 13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isAllASCII = m_text.containsOnlyASCII(); 13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath(); 13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::secureText(UChar mask) 13885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_text.length()) 13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int lastTypedCharacterOffsetToReveal = -1; 13931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) UChar revealedText; 13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->get(this) : 0; 13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (secureTextTimer && secureTextTimer->isActive()) { 13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastTypedCharacterOffsetToReveal = secureTextTimer->lastTypedCharacterOffset(); 13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastTypedCharacterOffsetToReveal >= 0) 13981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) revealedText = m_text[lastTypedCharacterOffsetToReveal]; 13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_text.fill(mask); 14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastTypedCharacterOffsetToReveal >= 0) { 14031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) m_text.replace(lastTypedCharacterOffsetToReveal, 1, String(&revealedText, 1)); 14045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // m_text may be updated later before timer fires. We invalidate the lastTypedCharacterOffset to avoid inconsistency. 14055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureTextTimer->invalidate(); 14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setText(PassRefPtr<StringImpl> text, bool force) 14105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(text); 14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!force && equal(m_text.impl(), text.get())) 14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setTextInternal(text); 141709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // If preferredLogicalWidthsDirty() of an orphan child is true, RenderObjectChildList:: 141809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // insertChildNode() fails to set true to owner. To avoid that, we call 141909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // setNeedsLayoutAndPrefWidthsRecalc() only if this RenderText has parent. 142009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (parent()) 14217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci setNeedsLayoutAndPrefWidthsRecalc(); 14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = false; 142302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 14248abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (AXObjectCache* cache = document().existingAXObjectCache()) 1425926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) cache->textChanged(this); 14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::dirtyLineBoxes(bool fullLayout) 14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fullLayout) 14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) deleteTextBoxes(); 14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (!m_linesDirty) { 14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->dirtyLineBoxes(); 14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_linesDirty = false; 14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineTextBox* RenderText::createTextBox() 14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1441d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return new InlineTextBox(*this); 14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineTextBox* RenderText::createInlineTextBox() 14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* textBox = createTextBox(); 14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_firstTextBox) 14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = m_lastTextBox = textBox; 14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox->setNextTextBox(textBox); 14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) textBox->setPreviousTextBox(m_lastTextBox); 14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = textBox; 14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) textBox->setIsText(true); 14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return textBox; 14565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::positionLineBox(InlineBox* box) 14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* s = toInlineTextBox(box); 14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: should not be needed!!! 14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!s->len()) { 14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We want the box to be destroyed. 1465f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu s->remove(DontMarkLineBoxes); 14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_firstTextBox == s) 14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = s->nextTextBox(); 14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s->prevTextBox()->setNextTextBox(s->nextTextBox()); 14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_lastTextBox == s) 14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = s->prevTextBox(); 14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 14735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s->nextTextBox()->setPreviousTextBox(s->prevTextBox()); 1474f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) s->destroy(); 14755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 14765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_containsReversedText |= !s->isLeftToRightDirection(); 14795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 148109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)float RenderText::width(unsigned from, unsigned len, float xPos, TextDirection textDirection, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 14825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (from >= textLength()) 14845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (from + len > textLength()) 14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) len = textLength() - from; 14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 148909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return width(from, len, style(firstLine)->font(), xPos, textDirection, fallbackFonts, glyphOverflow); 14905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 149209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(from + len <= textLength()); 14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!textLength()) 14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float w; 14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (&f == &style()->font()) { 15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style()->preserveNewline() && !from && len == textLength() && (!glyphOverflow || !glyphOverflow->computeBounds)) { 15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fallbackFonts) { 15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(glyphOverflow); 15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts) { 15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const_cast<RenderText*>(this)->computePreferredLogicalWidths(0, *fallbackFonts, *glyphOverflow); 1505c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // We shouldn't change our mind once we "know". 1506c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts 1507c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) || (fallbackFonts->isEmpty() && glyphOverflow->isZero())); 1508c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts->isEmpty() && glyphOverflow->isZero(); 15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = m_maxWidth; 1511d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else { 15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = maxLogicalWidth(); 1513d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 151409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 151509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) w = widthFromCache(f, from, len, xPos, textDirection, fallbackFonts, glyphOverflow); 151609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1518c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) TextRun run = constructTextRun(const_cast<RenderText*>(this), f, this, from, len, style(), textDirection); 15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharactersLength(textLength() - from); 15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run.charactersLength() >= run.length()); 15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharacterScanForCodePath(!canUseSimpleFontCodePath()); 15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 15245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setXPos(xPos); 15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = f.width(run, fallbackFonts, glyphOverflow); 15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return w; 15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect RenderText::linesBoundingBox() const 15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect result; 153402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both exist. 15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstTextBox() && lastTextBox()) { 15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Return the width of the minimal left side and the maximal right side. 15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float logicalLeftSide = 0; 15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float logicalRightSide = 0; 15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide) 15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) logicalLeftSide = curr->logicalLeft(); 15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr == firstTextBox() || curr->logicalRight() > logicalRightSide) 15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) logicalRightSide = curr->logicalRight(); 15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 154602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isHorizontal = style()->isHorizontalWritingMode(); 154802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float x = isHorizontal ? logicalLeftSide : firstTextBox()->x(); 15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float y = isHorizontal ? firstTextBox()->y() : logicalLeftSide; 15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x; 15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide; 15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = enclosingIntRect(FloatRect(x, y, width, height)); 15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderText::linesVisualOverflowBoundingBox() const 15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstTextBox()) 15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Return the width of the minimal left side and the maximal right side. 15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalLeftSide = LayoutUnit::max(); 15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalRightSide = LayoutUnit::min(); 15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 1568197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch LayoutRect logicalVisualOverflow = curr->logicalOverflowRect(); 1569197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch logicalLeftSide = std::min(logicalLeftSide, logicalVisualOverflow.x()); 1570197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch logicalRightSide = std::max(logicalRightSide, logicalVisualOverflow.maxX()); 15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 157202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalTop = firstTextBox()->logicalTopVisualOverflow(); 15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide; 15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalHeight = lastTextBox()->logicalBottomVisualOverflow() - logicalTop; 157602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight); 15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style()->isHorizontalWritingMode()) 15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect = rect.transposedRect(); 15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rect; 15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1583197021e6b966cfb06891637935ef33fff06433d1Ben MurdochLayoutRect RenderText::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const 15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // This method doesn't support paintInvalidationState, but invalidateTreeIfNeeded() never reaches RenderText. 15867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!paintInvalidationState); 15877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return parent()->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer); 15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutRect RenderText::selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const 15915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsLayout()); 15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionNone) 15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* cb = containingBlock(); 15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!cb) 15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now calculate startPos and endPos for painting selection. 16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We include a selection while endPos > 0 16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int startPos, endPos; 16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionInside) { 16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We are fully selected. 16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = 0; 16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endPos = textLength(); 16075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectionStartEnd(startPos, endPos); 16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionStart) 16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endPos = textLength(); 16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (selectionState() == SelectionEnd) 16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = 0; 16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startPos == endPos) 16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect rect; 16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.unite(box->localSelectionRect(startPos, endPos)); 16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.unite(ellipsisRectForBox(box, startPos, endPos)); 16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, 0); 16255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rect; 16265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::caretMinOffset() const 16295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* box = firstTextBox(); 16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box) 16325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int minOffset = box->start(); 16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (box = box->nextTextBox(); box; box = box->nextTextBox()) 1635197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch minOffset = std::min<int>(minOffset, box->start()); 16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return minOffset; 16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::caretMaxOffset() const 16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* box = lastTextBox(); 16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!lastTextBox()) 16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return textLength(); 16445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int maxOffset = box->start() + box->len(); 16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (box = box->prevTextBox(); box; box = box->prevTextBox()) 1647197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch maxOffset = std::max<int>(maxOffset, box->start() + box->len()); 16485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return maxOffset; 16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned RenderText::renderedTextLength() const 16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int l = 0; 16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) l += box->len(); 16565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return l; 16575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::previousOffset(int current) const 16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (isAllASCII() || m_text.is8Bit()) 16625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return current - 1; 16635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 16645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) StringImpl* textImpl = m_text.impl(); 16655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) TextBreakIterator* iterator = cursorMovementIterator(textImpl->characters16(), textImpl->length()); 16665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!iterator) 16675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current - 1; 16685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) long result = iterator->preceding(current); 16705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == TextBreakDone) 16715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = current - 1; 16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 167751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#if OS(POSIX) 16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_CHOSEONG_START (0x1100) 16805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_CHOSEONG_END (0x115F) 16815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JUNGSEONG_START (0x1160) 16825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JUNGSEONG_END (0x11A2) 16835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JONGSEONG_START (0x11A8) 16845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JONGSEONG_END (0x11F9) 16855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_SYLLABLE_START (0xAC00) 16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_SYLLABLE_END (0xD7AF) 16875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JONGSEONG_COUNT (28) 16885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum HangulState { 16905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateL, 16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateV, 16925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateT, 16935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateLV, 16945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateLVT, 16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateBreak 16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool isHangulLVT(UChar32 character) 16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 17005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (character - HANGUL_SYLLABLE_START) % HANGUL_JONGSEONG_COUNT; 17015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool isMark(UChar32 c) 17045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 17055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int8_t charType = u_charType(c); 17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charType == U_NON_SPACING_MARK || charType == U_ENCLOSING_MARK || charType == U_COMBINING_SPACING_MARK; 17075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool isRegionalIndicator(UChar32 c) 17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // National flag emoji each consists of a pair of regional indicator symbols. 17125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0x1F1E6 <= c && c <= 0x1F1FF; 17135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 17165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::previousOffsetForBackwardDeletion(int current) const 17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 171951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#if OS(POSIX) 17205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 17225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar32 character; 17235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool sawRegionalIndicator = false; 17245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (current > 0) { 17255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (U16_IS_TRAIL(text[--current])) 17265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --current; 17275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current < 0) 17285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar32 character = text.characterStartingAt(current); 17315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sawRegionalIndicator) { 17335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't check if the pair of regional indicator symbols before current position can actually be combined 17345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // into a flag, and just delete it. This may not agree with how the pair is rendered in edge cases, 17355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // but is good enough in practice. 17365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isRegionalIndicator(character)) 17375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't delete a preceding character that isn't a regional indicator symbol. 17395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) U16_FWD_1_UNSAFE(text, current); 17405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't combine characters in Armenian ... Limbu range for backward deletion. 17435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((character >= 0x0530) && (character < 0x1950)) 17445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isRegionalIndicator(character)) { 17475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sawRegionalIndicator = true; 17485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 17495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isMark(character) && (character != 0xFF9E) && (character != 0xFF9F)) 17525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current <= 0) 17565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current; 17575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Hangul 17595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) character = text.characterStartingAt(current); 17605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) { 17615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulState state; 17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (character < HANGUL_JUNGSEONG_START) 17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateL; 17655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character < HANGUL_JONGSEONG_START) 17665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateV; 17675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character < HANGUL_SYLLABLE_START) 17685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateT; 17695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 17705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = isHangulLVT(character) ? HangulStateLVT : HangulStateLV; 17715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (current > 0 && ((character = text.characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) { 17735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (state) { 17745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case HangulStateV: 17755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (character <= HANGUL_CHOSEONG_END) 17765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateL; 17775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END) && !isHangulLVT(character)) 17785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateLV; 17795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character > HANGUL_JUNGSEONG_END) 17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateBreak; 17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case HangulStateT: 17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((character >= HANGUL_JUNGSEONG_START) && (character <= HANGUL_JUNGSEONG_END)) 17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateV; 17855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END)) 17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = (isHangulLVT(character) ? HangulStateLVT : HangulStateLV); 17875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character < HANGUL_JUNGSEONG_START) 17885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateBreak; 17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = (character < HANGUL_JUNGSEONG_START) ? HangulStateL : HangulStateBreak; 17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (state == HangulStateBreak) 17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --current; 17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current; 18025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else 180351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // Platforms other than Unix-like delete by one code point. 18045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (U16_IS_TRAIL(m_text[--current])) 18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --current; 18065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current < 0) 18075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = 0; 18085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current; 18095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::nextOffset(int current) const 18135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (isAllASCII() || m_text.is8Bit()) 18155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return current + 1; 18165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 18175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) StringImpl* textImpl = m_text.impl(); 18185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) TextBreakIterator* iterator = cursorMovementIterator(textImpl->characters16(), textImpl->length()); 18195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!iterator) 18205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current + 1; 18215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) long result = iterator->following(current); 18235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == TextBreakDone) 18245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = current + 1; 18255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 18275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::computeCanUseSimpleFontCodePath() const 18305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAllASCII() || m_text.is8Bit()) 18325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 183309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return Character::characterRangeCodePath(characters16(), length()) == SimplePath; 18345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1836197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 18375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::checkConsistency() const 18395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef CHECK_CONSISTENCY 18415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineTextBox* prev = 0; 18425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (const InlineTextBox* child = m_firstTextBox; child != 0; child = child->nextTextBox()) { 18435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->renderer() == this); 18445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->prevTextBox() == prev); 18455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prev = child; 18465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(prev == m_lastTextBox); 18485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 18495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 18525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset) 18545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!gSecureTextTimers) 18565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) gSecureTextTimers = new SecureTextTimerMap; 18575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SecureTextTimer* secureTextTimer = gSecureTextTimers->get(this); 18595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!secureTextTimer) { 18605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureTextTimer = new SecureTextTimer(this); 18615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) gSecureTextTimers->add(this, secureTextTimer); 18625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureTextTimer->restartWithNewText(lastTypedCharacterOffset); 18645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1866bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)PassRefPtr<AbstractInlineTextBox> RenderText::firstAbstractInlineTextBox() 1867bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 1868bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return AbstractInlineTextBox::getOrCreate(this, m_firstTextBox); 1869bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 1870bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 1871c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 1872