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