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