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" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/TextResourceDecoder.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/FrameView.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Settings.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/FloatQuad.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/text/TextBreakIterator.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/text/transcoder/FontTranscoder.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/EllipsisBox.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/InlineTextBox.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderBlock.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderCombineText.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/break_lines.h" 4302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/text/StringBuffer.h" 44e6d4491e48613634a83c1957c72759da80987961Ben Murdoch#include "wtf/text/StringBuilder.h" 4502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/unicode/CharacterNames.h" 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WTF; 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace Unicode; 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct SameSizeAsRenderText : public RenderObject { 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t bitfields : 16; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float widths[4]; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String text; 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void* pointers[2]; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)COMPILE_ASSERT(sizeof(RenderText) == sizeof(SameSizeAsRenderText), RenderText_should_stay_small); 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class SecureTextTimer; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef HashMap<RenderText*, SecureTextTimer*> SecureTextTimerMap; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static SecureTextTimerMap* gSecureTextTimers = 0; 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class SecureTextTimer : public TimerBase { 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SecureTextTimer(RenderText* renderText) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_renderText(renderText) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_lastTypedCharacterOffset(-1) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void restartWithNewText(unsigned lastTypedCharacterOffset) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTypedCharacterOffset = lastTypedCharacterOffset; 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Settings* settings = m_renderText->document()->settings()) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startOneShot(settings->passwordEchoDurationInSeconds()); 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void invalidate() { m_lastTypedCharacterOffset = -1; } 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned lastTypedCharacterOffset() { return m_lastTypedCharacterOffset; } 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual void fired() 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(gSecureTextTimers->contains(m_renderText)); 87e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch m_renderText->setText(m_renderText->text().impl(), true /* forcing setting text as it may be masked later */); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderText* m_renderText; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_lastTypedCharacterOffset; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void makeCapitalized(String* string, UChar previous) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (string->isNull()) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = string->length(); 1005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) const StringImpl& input = *string->impl(); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (length >= numeric_limits<unsigned>::max()) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CRASH(); 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuffer<UChar> stringWithPrevious(length + 1); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stringWithPrevious[0] = previous == noBreakSpace ? ' ' : previous; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 1; i < length + 1; i++) { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Replace   with a real space since ICU no longer treats   as a word separator. 1095267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (input[i - 1] == noBreakSpace) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stringWithPrevious[i] = ' '; 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) stringWithPrevious[i] = input[i - 1]; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TextBreakIterator* boundary = wordBreakIterator(stringWithPrevious.characters(), length + 1); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!boundary) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) StringBuilder result; 1205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) result.reserveCapacity(length); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t endOfWord; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t startOfWord = textBreakFirst(boundary); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (endOfWord = textBreakNext(boundary); endOfWord != TextBreakDone; startOfWord = endOfWord, endOfWord = textBreakNext(boundary)) { 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startOfWord) // Ignore first char of previous string 1265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) result.append(input[startOfWord - 1] == noBreakSpace ? noBreakSpace : toTitleCase(stringWithPrevious[startOfWord])); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = startOfWord + 1; i < endOfWord; i++) 1285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) result.append(input[i - 1]); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) *string = result.toString(); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str) 135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : RenderObject(!node || node->isDocumentNode() ? 0 : node) 136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_hasTab(false) 137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_linesDirty(false) 138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_containsReversedText(false) 139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_knownToHaveNoOverflowAndNoFallbackFonts(false) 140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_needsTranscoding(false) 141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_minWidth(-1) 142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_maxWidth(-1) 143591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch , m_firstLineMinWidth(0) 144591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch , m_lastLineLineMinWidth(0) 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_text(str) 146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_firstTextBox(0) 147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_lastTextBox(0) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME: Some clients of RenderText (and subclasses) pass Document as node to create anonymous renderer. 151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // They should be switched to passing null and using setDocumentForAnonymous. 152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (node && node->isDocumentNode()) 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setDocumentForAnonymous(toDocument(node)); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isAllASCII = m_text.containsOnlyASCII(); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath(); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setIsText(); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) view()->frameView()->incrementVisuallyNonEmptyCharacterCount(m_text.length()); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderText::~RenderText() 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_firstTextBox); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_lastTextBox); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char* RenderText::renderName() const 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return "RenderText"; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::isTextFragment() const 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::isWordBreak() const 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::updateNeedsTranscoding() 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) const WTF::TextEncoding* encoding = document()->decoder() ? &document()->decoder()->encoding() : 0; 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needsTranscoding = fontTranscoder().needsTranscoding(style()->font().fontDescription(), encoding); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // There is no need to ever schedule repaints from a style change of a text run, since 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // we already did this for the parent of the text run. 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We do have to schedule layouts, though, since a style change can force us to 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // need to relayout. 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (diff == StyleDifferenceLayout) { 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setNeedsLayoutAndPrefWidthsRecalc(); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = false; 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* newStyle = style(); 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needsResetText = false; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!oldStyle) { 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateNeedsTranscoding(); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsResetText = m_needsTranscoding; 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (oldStyle->font().needsTranscoding() != newStyle->font().needsTranscoding() || (newStyle->font().needsTranscoding() && oldStyle->font().family().family() != newStyle->font().family().family())) { 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateNeedsTranscoding(); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsResetText = true; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE; 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE; 21602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch if (needsResetText || oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity()) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transformText(); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::removeAndDestroyTextBoxes() 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!documentBeingDestroyed()) { 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstTextBox()) { 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isBR()) { 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* next = firstTextBox()->root()->nextRootBox(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (next) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next->markDirty(); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->remove(); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (parent()) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parent()->dirtyLinesFromChangedChild(this); 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) deleteTextBoxes(); 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::willBeDestroyed() 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->take(this) : 0) 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete secureTextTimer; 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeAndDestroyTextBoxes(); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject::willBeDestroyed(); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::extractTextBox(InlineTextBox* box) 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = box->prevTextBox(); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box == m_firstTextBox) 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = 0; 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->prevTextBox()) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->prevTextBox()->setNextTextBox(0); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->setPreviousTextBox(0); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox()) 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->setExtracted(); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::attachTextBox(InlineTextBox* box) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_lastTextBox) { 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox->setNextTextBox(box); 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->setPreviousTextBox(m_lastTextBox); 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = box; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* last = box; 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox()) { 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->setExtracted(false); 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) last = curr; 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = last; 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::removeTextBox(InlineTextBox* box) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box == m_firstTextBox) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = box->nextTextBox(); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box == m_lastTextBox) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = box->prevTextBox(); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->nextTextBox()) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->nextTextBox()->setPreviousTextBox(box->prevTextBox()); 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->prevTextBox()) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->prevTextBox()->setNextTextBox(box->nextTextBox()); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::deleteTextBoxes() 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstTextBox()) { 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* next; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = next) { 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next = curr->nextTextBox(); 303f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) curr->destroy(); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = m_lastTextBox = 0; 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> RenderText::originalText() const 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* e = node(); 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (e && e->isTextNode()) ? toText(e)->dataImpl() : 0; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rects.append(enclosingIntRect(FloatRect(accumulatedOffset + box->topLeft(), box->size()))); 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigned end, bool useSelectionHeight) 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned realEnd = min(box->end() + 1, end); 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect r = box->localSelectionRect(start, realEnd); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (r.height()) { 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!useSelectionHeight) { 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Change the height and y position (or width and x for vertical text) 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // because selectionRect uses selection-specific values. 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isHorizontal()) { 330263e37c84f3a08c25b886ca7b5f41567730b0594Ben Murdoch r.setHeight(box->height()); 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setY(box->y()); 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 333263e37c84f3a08c25b886ca7b5f41567730b0594Ben Murdoch r.setWidth(box->width()); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setX(box->x()); 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return FloatRect(r); 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return FloatRect(); 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX 34502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 34602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // function to take ints causes various internal mismatches. But selectionRect takes ints, and 34702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX. 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(end == UINT_MAX || end <= INT_MAX); 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(start <= INT_MAX); 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) start = min(start, static_cast<unsigned>(INT_MAX)); 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) end = min(end, static_cast<unsigned>(INT_MAX)); 35302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: box->end() returns the index of the last character, not the index past it 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (start <= box->start() && box->end() < end) { 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect r = box->calculateBoundaries(); 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (useSelectionHeight) { 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect selectionRect = box->localSelectionRect(start, end); 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isHorizontal()) { 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setHeight(selectionRect.height()); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setY(selectionRect.y()); 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setWidth(selectionRect.width()); 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setX(selectionRect.x()); 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 368926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) rects.append(localToAbsoluteQuad(r, 0, wasFixed).enclosingBoundingBox()); 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rect.isZero()) 373926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) rects.append(localToAbsoluteQuad(rect, 0, wasFixed).enclosingBoundingBox()); 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigned endPos) 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box) 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 38202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned short truncation = box->truncation(); 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (truncation == cNoTruncation) 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 38602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect rect; 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (EllipsisBox* ellipsis = box->root()->ellipsisBox()) { 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int ellipsisStartPosition = max<int>(startPos - box->start(), 0); 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int ellipsisEndPosition = min<int>(endPos - box->start(), box->len()); 39102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The ellipsis should be considered to be selected if the end of 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the selection is past the beginning of the truncation and the 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // beginning of the selection is before or at the beginning of the truncation. 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= truncation) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ellipsis->selectionRect(); 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 39802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 40102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, ClippingOption option) const 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect boundaries = box->calculateBoundaries(); 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Shorten the width of this text box if it ends in an ellipsis. 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch. 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(box, 0, textLength()) : IntRect(); 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ellipsisRect.isEmpty()) { 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->isHorizontalWritingMode()) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) boundaries.setWidth(ellipsisRect.maxX() - boundaries.x()); 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) quads.append(localToAbsoluteQuad(boundaries, 0, wasFixed)); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 41902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) absoluteQuads(quads, wasFixed, NoClipping); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX 42802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 42902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // function to take ints causes various internal mismatches. But selectionRect takes ints, and 43002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX. 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(end == UINT_MAX || end <= INT_MAX); 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(start <= INT_MAX); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) start = min(start, static_cast<unsigned>(INT_MAX)); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) end = min(end, static_cast<unsigned>(INT_MAX)); 43602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: box->end() returns the index of the last character, not the index past it 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (start <= box->start() && box->end() < end) { 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect r = box->calculateBoundaries(); 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (useSelectionHeight) { 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect selectionRect = box->localSelectionRect(start, end); 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isHorizontal()) { 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setHeight(selectionRect.height()); 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setY(selectionRect.y()); 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setWidth(selectionRect.width()); 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) r.setX(selectionRect.x()); 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) quads.append(localToAbsoluteQuad(r, 0, wasFixed)); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rect.isZero()) 455926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) quads.append(localToAbsoluteQuad(rect, 0, wasFixed)); 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineTextBox* RenderText::findNextInlineTextBox(int offset, int& pos) const 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The text runs point to parts of the RenderText's m_text 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (they don't include '\n') 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Find the text run that includes the character at offset 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and return pos, which is the position of the char in the run. 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_firstTextBox) 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* s = m_firstTextBox; 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int off = s->len(); 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (offset > off && s->nextTextBox()) { 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s = s->nextTextBox(); 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) off = s->start() + s->len(); 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // we are now in the correct text run 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pos = (offset > off ? s->len() : s->len() - (off - offset) ); 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return s; 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPositionIsNotAtStart }; 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* box, ShouldAffinityBeDownstream& shouldAffinityBeDownstream) 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = AlwaysDownstream; 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the x coordinate is equal to the left edge of this box 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the affinity must be downstream so the position doesn't jump back to the previous line 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // except when box is the first box in the line 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointLineDirection <= box->logicalLeft()) { 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = !box->prevLeafChild() ? UpstreamIfPositionIsNotAtStart : AlwaysDownstream; 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and the x coordinate is to the left of the right edge of this box 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // check to see if position goes in this box 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointLineDirection < box->logicalRight()) { 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // box is first on line 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and the x coordinate is to the left of the first text box left edge 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box->prevLeafChildIgnoringLineBreak() && pointLineDirection < box->logicalLeft()) 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box->nextLeafChildIgnoringLineBreak()) { 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // box is last on line 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and the x coordinate is to the right of the last text box right edge 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // generate VisiblePosition, use UPSTREAM affinity if possible 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 518f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)static PositionWithAffinity createPositionWithAffinityForBox(const InlineBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream) 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EAffinity affinity = VP_DEFAULT_AFFINITY; 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (shouldAffinityBeDownstream) { 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AlwaysDownstream: 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) affinity = DOWNSTREAM; 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AlwaysUpstream: 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) affinity = VP_UPSTREAM_IF_POSSIBLE; 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UpstreamIfPositionIsNotAtStart: 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM; 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 532f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return box->renderer()->createPositionWithAffinity(offset, affinity); 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream) 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(box); 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(box->renderer()); 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(offset >= 0); 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (offset && static_cast<unsigned>(offset) < box->len()) 542f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->start() + offset, shouldAffinityBeDownstream); 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool positionIsAtStartOfBox = !offset; 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (positionIsAtStartOfBox == box->isLeftToRightDirection()) { 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // offset is on the left edge 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((prevBox && prevBox->bidiLevel() == box->bidiLevel()) 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || box->renderer()->containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA 551f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream); 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) { 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. left of B in aDC12BAb 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* leftmostBox; 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leftmostBox = prevBox; 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (prevBox && prevBox->bidiLevel() > box->bidiLevel()); 560f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream); 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!prevBox || prevBox->bidiLevel() < box->bidiLevel()) { 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. left of D in aDC12BAb 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* rightmostBox; 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* nextBox = box; 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightmostBox = nextBox; 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (nextBox && nextBox->bidiLevel() >= box->bidiLevel()); 571f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(rightmostBox, 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream); 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream); 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((nextBox && nextBox->bidiLevel() == box->bidiLevel()) 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || box->renderer()->containingBlock()->style()->direction() == box->direction()) 581f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream); 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // offset is on the right edge 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (nextBox && nextBox->bidiLevel() > box->bidiLevel()) { 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. right of C in aDC12BAb 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* rightmostBox; 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightmostBox = nextBox; 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (nextBox && nextBox->bidiLevel() > box->bidiLevel()); 591f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream); 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nextBox || nextBox->bidiLevel() < box->bidiLevel()) { 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // e.g. right of A in aDC12BAb 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* leftmostBox; 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineBox* prevBox = box; 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leftmostBox = prevBox; 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (prevBox && prevBox->bidiLevel() >= box->bidiLevel()); 602f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(leftmostBox, 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream); 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 606f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream); 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 609f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)PositionWithAffinity RenderText::positionForPoint(const LayoutPoint& point) 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstTextBox() || textLength() == 0) 612f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinity(0, DOWNSTREAM); 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y(); 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x(); 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* lastBox = 0; 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak()) 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box = box->nextTextBox(); 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* rootBox = box->root(); 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit top = min(rootBox->selectionTop(), rootBox->lineTop()); 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirection == top)) { 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit bottom = rootBox->selectionBottom(); 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rootBox->nextRootBox()) 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bottom = min(bottom, rootBox->nextRootBox()->lineTop()); 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) { 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ShouldAffinityBeDownstream shouldAffinityBeDownstream; 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream)) 633f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream); 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastBox = box; 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastBox) { 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ShouldAffinityBeDownstream shouldAffinityBeDownstream; 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream); 642f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream); 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 644f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return createPositionWithAffinity(0, DOWNSTREAM); 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine) 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!inlineBox) 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(inlineBox->isInlineTextBox()); 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!inlineBox->isInlineTextBox()) 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* box = toInlineTextBox(inlineBox); 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int height = box->root()->selectionHeight(); 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int top = box->root()->selectionTop(); 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Go ahead and round left to snap it to the nearest pixel. 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float left = box->positionForOffset(caretOffset); 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Distribute the caret's width to either side of the offset. 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int caretWidthLeftOfOffset = caretWidth / 2; 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left -= caretWidthLeftOfOffset; 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset; 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left = roundf(left); 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float rootLeft = box->root()->logicalLeft(); 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float rootRight = box->root()->logicalRight(); 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: should we use the width of the root inline box or the 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // width of the containing block for this? 6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (extraWidthToEndOfLine) 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *extraWidthToEndOfLine = (box->root()->logicalWidth() + rootLeft) - (left + 1); 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* cb = containingBlock(); 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* cbStyle = cb->style(); 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float leftEdge; 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float rightEdge; 6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leftEdge = min<float>(0, rootLeft); 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightEdge = max<float>(cb->logicalWidth(), rootRight); 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool rightAligned = false; 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (cbStyle->textAlign()) { 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case RIGHT: 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WEBKIT_RIGHT: 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightAligned = true; 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case LEFT: 6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WEBKIT_LEFT: 6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CENTER: 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WEBKIT_CENTER: 6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case JUSTIFY: 6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TASTART: 7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightAligned = !cbStyle->isLeftToRightDirection(); 7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TAEND: 7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightAligned = cbStyle->isLeftToRightDirection(); 7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rightAligned) { 7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left = max(left, leftEdge); 7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left = min(left, rootRight - caretWidth); 7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left = min(left, rightEdge - caretWidthRightOfOffset); 7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left = max(left, rootLeft); 7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, height) : IntRect(top, left, height, caretWidth); 7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->hasTextCombine() && isCombineText()) { 7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const RenderCombineText* combineText = toRenderCombineText(this); 7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (combineText->isCombined()) 7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return combineText->combinedTextWidth(f); 7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) { 7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float monospaceCharacterWidth = f.spaceWidth(); 7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float w = 0; 7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isSpace; 7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = start; i < start + len; i++) { 7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) char c = text[i]; 7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (c <= ' ') { 7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (c == ' ' || c == '\n') { 7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += monospaceCharacterWidth; 7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (c == '\t') { 7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->collapseWhiteSpace()) { 7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += monospaceCharacterWidth; 7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += f.tabWidth(style()->tabSize(), xPos + w); 7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += monospaceCharacterWidth; 7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isSpace && i > start) 7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w += f.wordSpacing(); 7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return w; 7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TextRun run = RenderBlock::constructTextRun(const_cast<RenderText*>(this), f, this, start, len, style()); 7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharactersLength(textLength() - start); 7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run.charactersLength() >= run.length()); 7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharacterScanForCodePath(!canUseSimpleFontCodePath()); 7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setXPos(xPos); 7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return f.width(run, fallbackFonts, glyphOverflow); 7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::trimmedPrefWidths(float leadWidth, 769591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float& firstLineMinWidth, bool& hasBreakableStart, 770591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float& lastLineMinWidth, bool& hasBreakableEnd, 771591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch bool& hasBreakableChar, bool& hasBreak, 772591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float& firstLineMaxWidth, float& lastLineMaxWidth, 773591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float& minWidth, float& maxWidth, bool& stripFrontSpaces) 7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool collapseWhiteSpace = style()->collapseWhiteSpace(); 7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!collapseWhiteSpace) 7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stripFrontSpaces = false; 7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_hasTab || preferredLogicalWidthsDirty()) 7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computePreferredLogicalWidths(leadWidth); 7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 782591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch hasBreakableStart = !stripFrontSpaces && m_hasBreakableStart; 783591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch hasBreakableEnd = m_hasBreakableEnd; 7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int len = textLength(); 7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 787e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!len || (stripFrontSpaces && text().impl()->containsOnlyWhitespace())) { 788591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMinWidth = 0; 789591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMinWidth = 0; 790591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = 0; 791591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMaxWidth = 0; 792591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch minWidth = 0; 793591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch maxWidth = 0; 7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasBreak = false; 7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 798591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch minWidth = m_minWidth; 799591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch maxWidth = m_maxWidth; 8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 801591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMinWidth = m_firstLineMinWidth; 802591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMinWidth = m_lastLineLineMinWidth; 8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasBreakableChar = m_hasBreakableChar; 8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasBreak = m_hasBreak; 8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (text[0] == ' ' || (text[0] == '\n' && !style()->preserveNewline()) || text[0] == '\t') { 8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Font& font = style()->font(); // FIXME: This ignores first-line. 8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stripFrontSpaces) { 8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const UChar space = ' '; 8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float spaceWidth = font.width(RenderBlock::constructTextRun(this, font, &space, 1, style())); 814591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch maxWidth -= spaceWidth; 815591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } else { 816591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch maxWidth += font.wordSpacing(); 817591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 820591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch stripFrontSpaces = collapseWhiteSpace && m_hasEndWhiteSpace; 8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 822591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!style()->autoWrap() || minWidth > maxWidth) 823591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch minWidth = maxWidth; 8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Compute our max widths by scanning the string for newlines. 8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasBreak) { 8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Font& f = style()->font(); // FIXME: This ignores first-line. 8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool firstLine = true; 829591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = maxWidth; 830591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMaxWidth = maxWidth; 8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < len; i++) { 8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int linelen = 0; 8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (i + linelen < len && text[i + linelen] != '\n') 8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) linelen++; 8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (linelen) { 837591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + lastLineMaxWidth, 0, 0); 8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstLine) { 8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLine = false; 8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leadWidth = 0; 841591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = lastLineMaxWidth; 8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) i += linelen; 8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (firstLine) { 845591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch firstLineMaxWidth = 0; 8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLine = false; 8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leadWidth = 0; 8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 850591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (i == len - 1) { 8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // A <pre> run that ends with a newline, as in, e.g., 8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // <pre>Some text\n\n<span>More text</pre> 853591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lastLineMaxWidth = 0; 854591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::minLogicalWidth() const 8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preferredLogicalWidthsDirty()) 8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const_cast<RenderText*>(this)->computePreferredLogicalWidths(0); 86302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_minWidth; 8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::maxLogicalWidth() const 8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preferredLogicalWidthsDirty()) 8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const_cast<RenderText*>(this)->computePreferredLogicalWidths(0); 87102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_maxWidth; 8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::computePreferredLogicalWidths(float leadWidth) 8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HashSet<const SimpleFontData*> fallbackFonts; 8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GlyphOverflow glyphOverflow; 8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphOverflow); 8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fallbackFonts.isEmpty() && !glyphOverflow.left && !glyphOverflow.right && !glyphOverflow.top && !glyphOverflow.bottom) 8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = true; 8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline float hyphenWidth(RenderText* renderer, const Font& font) 8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* style = renderer->style(); 8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return font.width(RenderBlock::constructTextRun(renderer, font, style->hyphenString().string(), style)); 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; 9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Non-zero only when kerning is enabled, in which case we measure words with their trailing 9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // space, then subtract its width. 9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(RenderBlock::constructTextRun(this, f, &space, 1, styleToUse)) + wordSpacing : 0; 9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If automatic hyphenation is allowed, we keep track of the width of the widest word (or word 9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fragment) encountered so far, and only try hyphenating words that are wider. 9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float maxWordWidth = numeric_limits<float>::max(); 9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int minimumPrefixLength = 0; 9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int minimumSuffixLength = 0; 9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int firstGlyphLeftOverflow = -1; 9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool breakAll = (styleToUse->wordBreak() == BreakAllWordBreak || styleToUse->wordBreak() == BreakWordBreak) && styleToUse->autoWrap(); 9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < len; i++) { 93893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) UChar c = uncheckedCharacterAt(i); 9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool previousCharacterIsSpace = isSpace; 9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isNewline = false; 9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (c == '\n') { 9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (styleToUse->preserveNewline()) { 9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreak = true; 9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isNewline = true; 9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (c == '\t') { 9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!styleToUse->collapseWhiteSpace()) { 9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasTab = true; 9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = false; 9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = true; 9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 9575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isSpace = c == ' '; 9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 959591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch bool isBreakableLocation = isNewline || (isSpace && styleToUse->autoWrap()); 960591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!i) 961591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasBreakableStart = isBreakableLocation; 962591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (i == len - 1) { 963591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasBreakableEnd = isBreakableLocation; 964591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_hasEndWhiteSpace = isNewline || isSpace; 965591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ignoringSpaces && styleToUse->collapseWhiteSpace() && previousCharacterIsSpace && isSpace) 9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ignoringSpaces = true; 9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ignoringSpaces && !isSpace) 9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ignoringSpaces = false; 9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ignore spaces and soft hyphens 9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ignoringSpaces) { 9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(lastWordBoundary == i); 9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary++; 9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 978f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } else if (c == softHyphen) { 9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); 9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstGlyphLeftOverflow < 0) 9815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstGlyphLeftOverflow = glyphOverflow.left; 9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary = i + 1; 9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 98653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable); 9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool betweenWords = true; 9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int j = i; 989f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) while (c != '\n' && c != ' ' && c != '\t' && (c != softHyphen)) { 9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) j++; 9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (j == len) 9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 99393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) c = uncheckedCharacterAt(j); 99453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (isBreakable(breakIterator, j, nextBreakable) && characterAt(j - 1) != softHyphen) 9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (breakAll) { 9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) betweenWords = false; 9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int wordLen = j - i; 10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wordLen) { 100453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) bool isSpace = (j < len) && c == ' '; 10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float w; 10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wordTrailingSpaceWidth && isSpace) 10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth; 10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); 1010f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (c == softHyphen) 10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMinWidth += hyphenWidth(this, f); 10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1014f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) maxWordWidth = max(maxWordWidth, w); 10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstGlyphLeftOverflow < 0) 10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstGlyphLeftOverflow = glyphOverflow.left; 10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMinWidth += w; 10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (betweenWords) { 10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastWordBoundary == i) 10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += w; 10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); 10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary = j; 10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isCollapsibleWhiteSpace = (j < len) && styleToUse->isCollapsibleWhiteSpace(c); 10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (j < len && styleToUse->autoWrap()) 10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreakableChar = true; 10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add in wordSpacing to our currMaxWidth, but not if this is the last word on a line or the 10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // last word in the run. 10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !containsOnlyWhitespace(j, len-j)) 10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += wordSpacing; 10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstWord) { 10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstWord = false; 10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the first character in the run is breakable, then we consider ourselves to have a beginning 10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // minimum width of 0, since a break could occur right before our run starts, preventing us from ever 10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // being appended to a previous text run when considering the total minimum width of the containing block. 10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasBreak) 10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreakableChar = true; 1043591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_firstLineMinWidth = hasBreak ? 0 : currMinWidth; 10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1045591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_lastLineLineMinWidth = currMinWidth; 10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currMinWidth > m_minWidth) 10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = currMinWidth; 10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMinWidth = 0; 10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) i += wordLen - 1; 10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Nowrap can never be broken, so don't bother setting the 10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // breakable character boolean. Pre can only be broken if we encounter a newline. 10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->autoWrap() || isNewline) 10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasBreakableChar = true; 10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currMinWidth > m_minWidth) 10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = currMinWidth; 10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMinWidth = 0; 10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isNewline) { // Only set if preserveNewline was true and we saw a newline. 10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstLine) { 10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLine = false; 10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leadWidth = 0; 10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!styleToUse->autoWrap()) 1067591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_firstLineMinWidth = currMaxWidth; 10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currMaxWidth > m_maxWidth) 10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_maxWidth = currMaxWidth; 10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth = 0; 10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TextRun run = RenderBlock::constructTextRun(this, f, this, i, 1, styleToUse); 10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharactersLength(len - i); 10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run.charactersLength() >= run.length()); 10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setXPos(leadWidth + currMaxWidth); 10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += f.width(run); 10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) glyphOverflow.right = 0; 10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1; 10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(lastWordBoundary == i); 10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastWordBoundary++; 10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstGlyphLeftOverflow > 0) 10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) glyphOverflow.left = firstGlyphLeftOverflow; 10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord)) 10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currMaxWidth += wordSpacing; 10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = max(currMinWidth, m_minWidth); 10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_maxWidth = max(currMaxWidth, m_maxWidth); 10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!styleToUse->autoWrap()) 10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minWidth = m_maxWidth; 11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (styleToUse->whiteSpace() == PRE) { 11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstLine) 1103591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_firstLineMinWidth = m_maxWidth; 1104591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_lastLineLineMinWidth = currMaxWidth; 11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setPreferredLogicalWidthsDirty(false); 11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)bool RenderText::isAllCollapsibleWhitespace() const 11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned length = textLength(); 1113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (is8Bit()) { 1114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < length; ++i) { 1115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!style()->isCollapsibleWhiteSpace(characters8()[i])) 1116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 1119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < length; ++i) { 1121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!style()->isCollapsibleWhiteSpace(characters16()[i])) 11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 11235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 112602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 11275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const 11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned currPos; 11325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (currPos = from; 11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currPos < from + len && (text[currPos] == '\n' || text[currPos] == ' ' || text[currPos] == '\t'); 11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currPos++) { } 11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return currPos >= (from + len); 11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatPoint RenderText::firstRunOrigin() const 11395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntPoint(firstRunX(), firstRunY()); 11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::firstRunX() const 11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_firstTextBox ? m_firstTextBox->x() : 0; 11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::firstRunY() const 11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_firstTextBox ? m_firstTextBox->y() : 0; 11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 115202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setSelectionState(SelectionState state) 11545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject::setSelectionState(state); 11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (canUpdateSelectionOnRootLineBoxes()) { 11585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) { 11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int startPos, endPos; 11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectionStartEnd(startPos, endPos); 11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionStart) { 11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endPos = textLength(); 11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to handle selection from end of text to end of line 11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startPos && startPos == endPos) 11665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = endPos - 1; 11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (selectionState() == SelectionEnd) 11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = 0; 11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (box->isSelected(startPos, endPos)) { 11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* root = box->root(); 11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (root) 11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) root->setHasSelectedChildren(true); 11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* root = box->root(); 11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (root) 11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) root->setHasSelectedChildren(state == SelectionInside); 11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The containing block can be null in case of an orphaned tree. 11875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* containingBlock = this->containingBlock(); 11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (containingBlock && !containingBlock->isRenderView()) 11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) containingBlock->setSelectionState(state); 11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force) 11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!force && equal(m_text.impl(), text.get())) 11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned oldLen = textLength(); 11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned newLen = text->length(); 11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int delta = newLen - oldLen; 12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned end = len ? offset + len - 1 : offset; 12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* firstRootBox = 0; 12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* lastRootBox = 0; 12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool dirtiedLines = false; 12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Dirty all text boxes that include characters in between offset and offset+len. 12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (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 12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run is entirely before the affected range. 12115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr->end() < offset) 12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run is entirely after the affected range. 12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr->start() > end) { 12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->offsetRun(delta); 12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* root = curr->root(); 12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstRootBox) { 12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstRootBox = root; 122093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // The affected area was in between two runs. Go ahead and mark the root box of 122193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // the run after the affected area as dirty. 122293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) firstRootBox->markDirty(); 122393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) dirtiedLines = true; 12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRootBox = root; 12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (curr->end() >= offset && curr->end() <= end) { 12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run overlaps with the left end of the affected range. 12285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->dirtyLineBoxes(); 12295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (curr->start() <= offset && curr->end() >= end) { 12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run subsumes the affected range. 12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->dirtyLineBoxes(); 12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (curr->start() <= end && curr->end() >= end) { 12355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text run overlaps with right end of the affected range. 12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curr->dirtyLineBoxes(); 12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now we have to walk all of the clean lines and adjust their cached line break information 12425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to reflect our updated offsets. 12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastRootBox) 12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRootBox = lastRootBox->nextRootBox(); 12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstRootBox) { 12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* prev = firstRootBox->prevRootBox(); 12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (prev) 12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstRootBox = prev; 12495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (lastTextBox()) { 12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!lastRootBox); 12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstRootBox = lastTextBox()->root(); 12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstRootBox->markDirty(); 12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) { 12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr->lineBreakObj() == this && curr->lineBreakPos() > end) 1257e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) curr->setLineBreakPos(clampToInteger(curr->lineBreakPos() + delta)); 12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the text node is empty, dirty the line where new text will be inserted. 12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstTextBox() && parent()) { 12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parent()->dirtyLinesFromChangedChild(this); 12635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dirtiedLines = true; 12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_linesDirty = dirtiedLines; 12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setText(text, force || dirtiedLines); 12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::transformText() 12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RefPtr<StringImpl> textToTransform = originalText()) 12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setText(textToTransform.release(), true); 12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isInlineFlowOrEmptyText(const RenderObject* o) 12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (o->isRenderInline()) 12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!o->isText()) 12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1282e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return toRenderText(o)->text().isEmpty(); 12835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)UChar RenderText::previousCharacter() const 12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // find previous text renderer if one exists 12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const RenderObject* previousText = this; 12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while ((previousText = previousText->previousInPreOrder())) 12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInlineFlowOrEmptyText(previousText)) 12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar prev = ' '; 12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (previousText && previousText->isText()) 1294e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (StringImpl* previousString = toRenderText(previousText)->text().impl()) 12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prev = (*previousString)[previousString->length() - 1]; 12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return prev; 12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1299f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void RenderText::addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const 13007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{ 13017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Text nodes aren't event targets, so don't descend any further. 13027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch} 13037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void applyTextTransform(const RenderStyle* style, String& text, UChar previousCharacter) 13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style) 13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (style->textTransform()) { 13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TTNONE: 13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CAPITALIZE: 13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeCapitalized(&text, previousCharacter); 13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UPPERCASE: 13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) text.makeUpper(); 13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case LOWERCASE: 13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) text.makeLower(); 13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setTextInternal(PassRefPtr<StringImpl> text) 13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(text); 13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_text = text; 13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_needsTranscoding) { 132981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) const WTF::TextEncoding* encoding = document()->decoder() ? &document()->decoder()->encoding() : 0; 13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fontTranscoder().convert(m_text, style()->font().fontDescription(), encoding); 13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 13335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()) { 13355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) applyTextTransform(style(), m_text, previousCharacter()); 13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We use the same characters here as for list markers. 13385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See the listMarkerText function in RenderListMarker.cpp. 13395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (style()->textSecurity()) { 13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSNONE: 13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSCIRCLE: 13435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureText(whiteBullet); 13445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSDISC: 13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureText(bullet); 13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSSQUARE: 13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureText(blackSquare); 13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!isBR() || (textLength() == 1 && m_text[0] == '\n')); 13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isAllASCII = m_text.containsOnlyASCII(); 13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath(); 13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::secureText(UChar mask) 13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_text.length()) 13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int lastTypedCharacterOffsetToReveal = -1; 13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String revealedText; 13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->get(this) : 0; 13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (secureTextTimer && secureTextTimer->isActive()) { 13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastTypedCharacterOffsetToReveal = secureTextTimer->lastTypedCharacterOffset(); 13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastTypedCharacterOffsetToReveal >= 0) 13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) revealedText.append(m_text[lastTypedCharacterOffsetToReveal]); 13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_text.fill(mask); 13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastTypedCharacterOffsetToReveal >= 0) { 13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_text.replace(lastTypedCharacterOffsetToReveal, 1, revealedText); 13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // m_text may be updated later before timer fires. We invalidate the lastTypedCharacterOffset to avoid inconsistency. 13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureTextTimer->invalidate(); 13795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::setText(PassRefPtr<StringImpl> text, bool force) 13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(text); 13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!force && equal(m_text.impl(), text.get())) 13875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setTextInternal(text); 13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setNeedsLayoutAndPrefWidthsRecalc(); 13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = false; 139202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1393926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (AXObjectCache* cache = document()->existingAXObjectCache()) 1394926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) cache->textChanged(this); 13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RenderText::textWithoutTranscoding() const 13985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If m_text isn't transcoded or is secure, we can just return the modified text. 14005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_needsTranscoding || style()->textSecurity() != TSNONE) 14015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return text(); 14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise, we should use original text. If text-transform is 14045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // specified, we should transform the text on the fly. 14055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String text = originalText(); 14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) applyTextTransform(style(), text, previousCharacter()); 14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return text; 14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::dirtyLineBoxes(bool fullLayout) 14115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fullLayout) 14135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) deleteTextBoxes(); 14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (!m_linesDirty) { 14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) box->dirtyLineBoxes(); 14175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_linesDirty = false; 14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineTextBox* RenderText::createTextBox() 14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1423f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return new InlineTextBox(this); 14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineTextBox* RenderText::createInlineTextBox() 14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* textBox = createTextBox(); 14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_firstTextBox) 14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = m_lastTextBox = textBox; 14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox->setNextTextBox(textBox); 14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) textBox->setPreviousTextBox(m_lastTextBox); 14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = textBox; 14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) textBox->setIsText(true); 14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return textBox; 14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::positionLineBox(InlineBox* box) 14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* s = toInlineTextBox(box); 14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: should not be needed!!! 14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!s->len()) { 14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We want the box to be destroyed. 14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s->remove(); 14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_firstTextBox == s) 14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstTextBox = s->nextTextBox(); 14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s->prevTextBox()->setNextTextBox(s->nextTextBox()); 14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_lastTextBox == s) 14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastTextBox = s->prevTextBox(); 14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s->nextTextBox()->setPreviousTextBox(s->prevTextBox()); 1456f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) s->destroy(); 14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 14585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_containsReversedText |= !s->isLeftToRightDirection(); 14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::width(unsigned from, unsigned len, float xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (from >= textLength()) 14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (from + len > textLength()) 14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) len = textLength() - from; 14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow); 14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 14755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(from + len <= textLength()); 14775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!textLength()) 14785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float w; 14815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (&f == &style()->font()) { 14825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style()->preserveNewline() && !from && len == textLength() && (!glyphOverflow || !glyphOverflow->computeBounds)) { 14835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fallbackFonts) { 14845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(glyphOverflow); 14855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts) { 14865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const_cast<RenderText*>(this)->computePreferredLogicalWidths(0, *fallbackFonts, *glyphOverflow); 14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fallbackFonts->isEmpty() && !glyphOverflow->left && !glyphOverflow->right && !glyphOverflow->top && !glyphOverflow->bottom) 14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_knownToHaveNoOverflowAndNoFallbackFonts = true; 14895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = m_maxWidth; 14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 14925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = maxLogicalWidth(); 14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow); 14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TextRun run = RenderBlock::constructTextRun(const_cast<RenderText*>(this), f, this, from, len, style()); 14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharactersLength(textLength() - from); 14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run.charactersLength() >= run.length()); 14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setCharacterScanForCodePath(!canUseSimpleFontCodePath()); 15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run.setXPos(xPos); 15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = f.width(run, fallbackFonts, glyphOverflow); 15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return w; 15075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect RenderText::linesBoundingBox() const 15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect result; 151202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both exist. 15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (firstTextBox() && lastTextBox()) { 15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Return the width of the minimal left side and the maximal right side. 15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float logicalLeftSide = 0; 15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float logicalRightSide = 0; 15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide) 15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) logicalLeftSide = curr->logicalLeft(); 15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curr == firstTextBox() || curr->logicalRight() > logicalRightSide) 15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) logicalRightSide = curr->logicalRight(); 15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 152402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isHorizontal = style()->isHorizontalWritingMode(); 152602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float x = isHorizontal ? logicalLeftSide : firstTextBox()->x(); 15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float y = isHorizontal ? firstTextBox()->y() : logicalLeftSide; 15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x; 15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide; 15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = enclosingIntRect(FloatRect(x, y, width, height)); 15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderText::linesVisualOverflowBoundingBox() const 15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstTextBox()) 15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Return the width of the minimal left side and the maximal right side. 15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalLeftSide = LayoutUnit::max(); 15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalRightSide = LayoutUnit::min(); 15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) logicalLeftSide = min(logicalLeftSide, curr->logicalLeftVisualOverflow()); 15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) logicalRightSide = max(logicalRightSide, curr->logicalRightVisualOverflow()); 15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 154902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalTop = firstTextBox()->logicalTopVisualOverflow(); 15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide; 15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalHeight = lastTextBox()->logicalBottomVisualOverflow() - logicalTop; 155302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight); 15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style()->isHorizontalWritingMode()) 15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect = rect.transposedRect(); 15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rect; 15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderText::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const 15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* rendererToRepaint = containingBlock(); 15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do not cross self-painting layer boundaries. 15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* enclosingLayerRenderer = enclosingLayer()->renderer(); 15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (enclosingLayerRenderer != rendererToRepaint && !rendererToRepaint->isDescendantOf(enclosingLayerRenderer)) 15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rendererToRepaint = enclosingLayerRenderer; 15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The renderer we chose to repaint may be an ancestor of repaintContainer, but we need to do a repaintContainer-relative repaint. 15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (repaintContainer && repaintContainer != rendererToRepaint && !rendererToRepaint->isDescendantOf(repaintContainer)) 15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return repaintContainer->clippedOverflowRectForRepaint(repaintContainer); 15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rendererToRepaint->clippedOverflowRectForRepaint(repaintContainer); 15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderText::selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent) 15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsLayout()); 15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionNone) 15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* cb = containingBlock(); 15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!cb) 15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(); 15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now calculate startPos and endPos for painting selection. 15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We include a selection while endPos > 0 15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int startPos, endPos; 15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionInside) { 15905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We are fully selected. 15915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = 0; 15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endPos = textLength(); 15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectionStartEnd(startPos, endPos); 15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectionState() == SelectionStart) 15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endPos = textLength(); 15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (selectionState() == SelectionEnd) 15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startPos = 0; 15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startPos == endPos) 16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect rect; 16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.unite(box->localSelectionRect(startPos, endPos)); 16075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.unite(ellipsisRectForBox(box, startPos, endPos)); 16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (clipToVisibleContent) 16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeRectForRepaint(repaintContainer, rect); 16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cb->hasColumns()) 16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cb->adjustRectForColumns(rect); 16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox(); 16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rect; 16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::caretMinOffset() const 16235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* box = firstTextBox(); 16255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!box) 16265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 16275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int minOffset = box->start(); 16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (box = box->nextTextBox(); box; box = box->nextTextBox()) 16295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) minOffset = min<int>(minOffset, box->start()); 16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return minOffset; 16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::caretMaxOffset() const 16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InlineTextBox* box = lastTextBox(); 16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!lastTextBox()) 16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return textLength(); 16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int maxOffset = box->start() + box->len(); 16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (box = box->prevTextBox(); box; box = box->prevTextBox()) 16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) maxOffset = max<int>(maxOffset, box->start() + box->len()); 16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return maxOffset; 16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned RenderText::renderedTextLength() const 16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int l = 0; 16485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) l += box->len(); 16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return l; 16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::previousOffset(int current) const 16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (isAllASCII() || m_text.is8Bit()) 16565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return current - 1; 16575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 16585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) StringImpl* textImpl = m_text.impl(); 16595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) TextBreakIterator* iterator = cursorMovementIterator(textImpl->characters16(), textImpl->length()); 16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!iterator) 16615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current - 1; 16625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) long result = textBreakPreceding(iterator, current); 16645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == TextBreakDone) 16655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = current - 1; 16665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 16695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 167153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#if OS(DARWIN) 16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_CHOSEONG_START (0x1100) 16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_CHOSEONG_END (0x115F) 16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JUNGSEONG_START (0x1160) 16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JUNGSEONG_END (0x11A2) 16775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JONGSEONG_START (0x11A8) 16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JONGSEONG_END (0x11F9) 16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_SYLLABLE_START (0xAC00) 16805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_SYLLABLE_END (0xD7AF) 16815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HANGUL_JONGSEONG_COUNT (28) 16825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum HangulState { 16845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateL, 16855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateV, 16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateT, 16875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateLV, 16885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateLVT, 16895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulStateBreak 16905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool isHangulLVT(UChar32 character) 16935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (character - HANGUL_SYLLABLE_START) % HANGUL_JONGSEONG_COUNT; 16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool isMark(UChar32 c) 16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int8_t charType = u_charType(c); 17005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charType == U_NON_SPACING_MARK || charType == U_ENCLOSING_MARK || charType == U_COMBINING_SPACING_MARK; 17015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool isRegionalIndicator(UChar32 c) 17045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 17055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // National flag emoji each consists of a pair of regional indicator symbols. 17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0x1F1E6 <= c && c <= 0x1F1FF; 17075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::previousOffsetForBackwardDeletion(int current) const 17125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 171353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#if OS(DARWIN) 17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_text); 17155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl& text = *m_text.impl(); 17165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar32 character; 17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool sawRegionalIndicator = false; 17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (current > 0) { 17195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (U16_IS_TRAIL(text[--current])) 17205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --current; 17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current < 0) 17225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar32 character = text.characterStartingAt(current); 17255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (sawRegionalIndicator) { 17275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't check if the pair of regional indicator symbols before current position can actually be combined 17285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // into a flag, and just delete it. This may not agree with how the pair is rendered in edge cases, 17295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // but is good enough in practice. 17305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isRegionalIndicator(character)) 17315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't delete a preceding character that isn't a regional indicator symbol. 17335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) U16_FWD_1_UNSAFE(text, current); 17345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't combine characters in Armenian ... Limbu range for backward deletion. 17375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((character >= 0x0530) && (character < 0x1950)) 17385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isRegionalIndicator(character)) { 17415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sawRegionalIndicator = true; 17425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 17435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isMark(character) && (character != 0xFF9E) && (character != 0xFF9F)) 17465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current <= 0) 17505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current; 17515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Hangul 17535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) character = text.characterStartingAt(current); 17545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) { 17555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulState state; 17565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HangulState initialState; 17575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (character < HANGUL_JUNGSEONG_START) 17595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateL; 17605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character < HANGUL_JONGSEONG_START) 17615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateV; 17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character < HANGUL_SYLLABLE_START) 17635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateT; 17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 17655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = isHangulLVT(character) ? HangulStateLVT : HangulStateLV; 17665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) initialState = state; 17685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (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))) { 17705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (state) { 17715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case HangulStateV: 17725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (character <= HANGUL_CHOSEONG_END) 17735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateL; 17745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END) && !isHangulLVT(character)) 17755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateLV; 17765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character > HANGUL_JUNGSEONG_END) 17775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateBreak; 17785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case HangulStateT: 17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((character >= HANGUL_JUNGSEONG_START) && (character <= HANGUL_JUNGSEONG_END)) 17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateV; 17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END)) 17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = (isHangulLVT(character) ? HangulStateLVT : HangulStateLV); 17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (character < HANGUL_JUNGSEONG_START) 17855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = HangulStateBreak; 17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 17885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = (character < HANGUL_JUNGSEONG_START) ? HangulStateL : HangulStateBreak; 17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (state == HangulStateBreak) 17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --current; 17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current; 17995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else 18005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Platforms other than Mac delete by one code point. 18015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (U16_IS_TRAIL(m_text[--current])) 18025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --current; 18035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (current < 0) 18045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current = 0; 18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current; 18065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 18075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderText::nextOffset(int current) const 18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (isAllASCII() || m_text.is8Bit()) 18125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return current + 1; 18135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 18145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) StringImpl* textImpl = m_text.impl(); 18155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) TextBreakIterator* iterator = cursorMovementIterator(textImpl->characters16(), textImpl->length()); 18165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!iterator) 18175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current + 1; 18185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) long result = textBreakFollowing(iterator, current); 18205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == TextBreakDone) 18215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = current + 1; 18225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 18245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderText::computeCanUseSimpleFontCodePath() const 18275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAllASCII() || m_text.is8Bit()) 18295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 18307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return Font::characterRangeCodePath(characters16(), length()) == Font::Simple; 18315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG 18345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::checkConsistency() const 18365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef CHECK_CONSISTENCY 18385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const InlineTextBox* prev = 0; 18395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (const InlineTextBox* child = m_firstTextBox; child != 0; child = child->nextTextBox()) { 18405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->renderer() == this); 18415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->prevTextBox() == prev); 18425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prev = child; 18435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(prev == m_lastTextBox); 18455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 18465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 18495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderText::momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset) 18515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 18525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!gSecureTextTimers) 18535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) gSecureTextTimers = new SecureTextTimerMap; 18545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SecureTextTimer* secureTextTimer = gSecureTextTimers->get(this); 18565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!secureTextTimer) { 18575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureTextTimer = new SecureTextTimer(this); 18585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) gSecureTextTimers->add(this, secureTextTimer); 18595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) secureTextTimer->restartWithNewText(lastTypedCharacterOffset); 18615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 1864