1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2000 Dirk Mueller (mueller@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderText.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "AXObjectCache.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CharacterNames.h"
30d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "EllipsisBox.h"
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "FloatQuad.h"
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "FrameView.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InlineTextBox.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Range.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderArena.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderBlock.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderLayer.h"
38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderView.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextBreakIterator.h"
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "VisiblePosition.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "break_lines.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/AlwaysInline.h>
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace Unicode;
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: Move to StringImpl.h eventually.
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool charactersAreAllASCII(StringImpl* text)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return charactersAreAllASCII(text->characters(), text->length());
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderText::RenderText(Node* node, PassRefPtr<StringImpl> str)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     : RenderObject(node)
595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian     , m_minWidth(-1)
605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian     , m_text(document()->displayStringModifiedByEncoding(str))
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     , m_firstTextBox(0)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     , m_lastTextBox(0)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     , m_maxWidth(-1)
64635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     , m_beginMinWidth(0)
65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     , m_endMinWidth(0)
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     , m_hasTab(false)
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     , m_linesDirty(false)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     , m_containsReversedText(false)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     , m_isAllASCII(charactersAreAllASCII(m_text.get()))
705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian     , m_knownNotToUseFallbackFonts(false)
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_text);
735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
74635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setIsText();
75635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // FIXME: It would be better to call this only if !m_text->containsOnlyWhitespace().
775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // But that might slow things down, and maybe should only be done if visuallyNonEmpty
785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // is still false. Not making any change for now, but should consider in the future.
79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    view()->frameView()->setIsVisuallyNonEmpty();
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderText::~RenderText()
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_firstTextBox);
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_lastTextBox);
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char* RenderText::renderName() const
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return "RenderText";
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderText::isTextFragment() const
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderText::isWordBreak() const
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // There is no need to ever schedule repaints from a style change of a text run, since
110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // we already did this for the parent of the text run.
111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // We do have to schedule layouts, though, since a style change can force us to
112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // need to relayout.
1135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (diff == StyleDifferenceLayout) {
114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        setNeedsLayoutAndPrefWidthsRecalc();
1155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_knownNotToUseFallbackFonts = false;
1165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE;
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (oldTransform != style()->textTransform() || oldSecurity != style()->textSecurity()) {
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (RefPtr<StringImpl> textToTransform = originalText())
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setText(textToTransform.release(), true);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::destroy()
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!documentBeingDestroyed()) {
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstTextBox()) {
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isBR()) {
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RootInlineBox* next = firstTextBox()->root()->nextRootBox();
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (next)
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    next->markDirty();
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                box->remove();
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (parent())
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parent()->dirtyLinesFromChangedChild(this);
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deleteTextBoxes();
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject::destroy();
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::extractTextBox(InlineTextBox* box)
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkConsistency();
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lastTextBox = box->prevTextBox();
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (box == m_firstTextBox)
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstTextBox = 0;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (box->prevTextBox())
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        box->prevTextBox()->setNextLineBox(0);
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    box->setPreviousLineBox(0);
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        curr->setExtracted();
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkConsistency();
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::attachTextBox(InlineTextBox* box)
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkConsistency();
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_lastTextBox) {
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_lastTextBox->setNextLineBox(box);
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        box->setPreviousLineBox(m_lastTextBox);
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstTextBox = box;
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* last = box;
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox()) {
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        curr->setExtracted(false);
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        last = curr;
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lastTextBox = last;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkConsistency();
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::removeTextBox(InlineTextBox* box)
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkConsistency();
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (box == m_firstTextBox)
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstTextBox = box->nextTextBox();
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (box == m_lastTextBox)
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_lastTextBox = box->prevTextBox();
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (box->nextTextBox())
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        box->nextTextBox()->setPreviousLineBox(box->prevTextBox());
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (box->prevTextBox())
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        box->prevTextBox()->setNextLineBox(box->nextTextBox());
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkConsistency();
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::deleteTextBoxes()
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (firstTextBox()) {
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderArena* arena = renderArena();
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineTextBox* next;
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (InlineTextBox* curr = firstTextBox(); curr; curr = next) {
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            next = curr->nextTextBox();
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr->destroy(arena);
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstTextBox = m_lastTextBox = 0;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> RenderText::originalText() const
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* e = node();
212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return e ? static_cast<Text*>(e)->dataImpl() : 0;
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderText::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
2188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        rects.append(IntRect(tx + box->x(), ty + box->y(), box->width(), box->height()));
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight)
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // function to take ints causes various internal mismatches. But selectionRect takes ints, and
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX.
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(end == UINT_MAX || end <= INT_MAX);
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(start <= INT_MAX);
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    start = min(start, static_cast<unsigned>(INT_MAX));
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    end = min(end, static_cast<unsigned>(INT_MAX));
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    FloatPoint absPos = localToAbsolute(FloatPoint());
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Note: box->end() returns the index of the last character, not the index past it
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (start <= box->start() && box->end() < end) {
2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            IntRect r = IntRect(absPos.x() + box->x(), absPos.y() + box->y(), box->width(), box->height());
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (useSelectionHeight) {
240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                IntRect selectionRect = box->selectionRect(absPos.x(), absPos.y(), start, end);
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                r.setHeight(selectionRect.height());
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                r.setY(selectionRect.y());
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rects.append(r);
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            unsigned realEnd = min(box->end() + 1, end);
247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            IntRect r = box->selectionRect(absPos.x(), absPos.y(), start, realEnd);
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!r.isEmpty()) {
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!useSelectionHeight) {
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // change the height and y position because selectionRect uses selection-specific values
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    r.setHeight(box->height());
2528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    r.setY(absPos.y() + box->y());
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rects.append(r);
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderText::absoluteQuads(Vector<FloatQuad>& quads)
261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        quads.append(localToAbsoluteQuad(FloatRect(box->x(), box->y(), box->width(), box->height())));
264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool useSelectionHeight)
267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // function to take ints causes various internal mismatches. But selectionRect takes ints, and
271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but
272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX.
273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(end == UINT_MAX || end <= INT_MAX);
274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(start <= INT_MAX);
275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    start = min(start, static_cast<unsigned>(INT_MAX));
276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    end = min(end, static_cast<unsigned>(INT_MAX));
277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Note: box->end() returns the index of the last character, not the index past it
280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (start <= box->start() && box->end() < end) {
2818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            IntRect r = IntRect(box->x(), box->y(), box->width(), box->height());
282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (useSelectionHeight) {
283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                IntRect selectionRect = box->selectionRect(0, 0, start, end);
284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                r.setHeight(selectionRect.height());
285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                r.setY(selectionRect.y());
286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            quads.append(localToAbsoluteQuad(FloatRect(r)));
288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else {
289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            unsigned realEnd = min(box->end() + 1, end);
290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            IntRect r = box->selectionRect(0, 0, start, realEnd);
291d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (r.height()) {
292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (!useSelectionHeight) {
293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    // change the height and y position because selectionRect uses selection-specific values
294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    r.setHeight(box->height());
2958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    r.setY(box->y());
296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                }
297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                quads.append(localToAbsoluteQuad(FloatRect(r)));
298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
299635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectInlineTextBox* RenderText::findNextInlineTextBox(int offset, int& pos) const
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The text runs point to parts of the RenderText's m_text
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (they don't include '\n')
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Find the text run that includes the character at offset
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and return pos, which is the position of the char in the run.
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_firstTextBox)
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* s = m_firstTextBox;
314635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int off = s->len();
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (offset > off && s->nextTextBox()) {
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s = s->nextTextBox();
317635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        off = s->start() + s->len();
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we are now in the correct text run
320635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    pos = (offset > off ? s->len() : s->len() - (off - offset) );
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return s;
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianVisiblePosition RenderText::positionForPoint(const IntPoint& point)
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!firstTextBox() || textLength() == 0)
3278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return createVisiblePosition(0, DOWNSTREAM);
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get the offset for the position, since this will take rtl text into account.
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int offset;
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: We should be able to roll these special cases into the general cases in the loop below.
333231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (firstTextBox() && point.y() <  firstTextBox()->root()->lineBottom() && point.x() < firstTextBox()->m_x) {
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // at the y coordinate of the first line or above
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // and the x coordinate is to the left of the first text box left edge
3368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        offset = firstTextBox()->offsetForPosition(point.x());
3378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return createVisiblePosition(offset + firstTextBox()->start(), DOWNSTREAM);
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (lastTextBox() && point.y() >= lastTextBox()->root()->lineTop() && point.x() >= lastTextBox()->m_x + lastTextBox()->m_width) {
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // at the y coordinate of the last line or below
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // and the x coordinate is to the right of the last text box right edge
3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        offset = lastTextBox()->offsetForPosition(point.x());
343d0825bca7fe65beaee391d30da42e937db621564Steve Block        return createVisiblePosition(offset + lastTextBox()->start(), VP_UPSTREAM_IF_POSSIBLE);
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* lastBoxAbove = 0;
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (point.y() >= box->root()->lineTop()) {
349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            int bottom = box->root()->nextRootBox() ? box->root()->nextRootBox()->lineTop() : box->root()->lineBottom();
3508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (point.y() < bottom) {
3518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                offset = box->offsetForPosition(point.x());
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (point.x() == box->m_x)
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // the x coordinate is equal to the left edge of this box
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // the affinity must be downstream so the position doesn't jump back to the previous line
3568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    return createVisiblePosition(offset + box->start(), DOWNSTREAM);
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (point.x() < box->m_x + box->m_width)
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // and the x coordinate is to the left of the right edge of this box
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // check to see if position goes in this box
3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    return createVisiblePosition(offset + box->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (!box->prevOnLine() && point.x() < box->m_x)
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // box is first on line
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // and the x coordinate is to the left of the first text box left edge
3668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    return createVisiblePosition(offset + box->start(), DOWNSTREAM);
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!box->nextOnLine())
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // box is last on line
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // and the x coordinate is to the right of the last text box right edge
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // generate VisiblePosition, use UPSTREAM affinity if possible
3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    return createVisiblePosition(offset + box->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastBoxAbove = box;
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return createVisiblePosition(lastBoxAbove ? lastBoxAbove->start() + lastBoxAbove->len() : 0, DOWNSTREAM);
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
381635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!inlineBox)
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(inlineBox->isInlineTextBox());
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!inlineBox->isInlineTextBox())
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox);
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
392231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int height = box->root()->lineBottom() - box->root()->lineTop();
393231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int top = box->root()->lineTop();
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int left = box->positionForOffset(caretOffset);
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Distribute the caret's width to either side of the offset.
3985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int caretWidthLeftOfOffset = caretWidth / 2;
3995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    left -= caretWidthLeftOfOffset;
4005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset;
4015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int rootLeft = box->root()->x();
4035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int rootRight = rootLeft + box->root()->width();
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: should we use the width of the root inline box or the
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // width of the containing block for this?
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (extraWidthToEndOfLine)
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *extraWidthToEndOfLine = (box->root()->width() + rootLeft) - (left + 1);
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock* cb = containingBlock();
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->autoWrap()) {
4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int availableWidth = cb->lineWidth(top, false);
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (box->direction() == LTR)
4135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            left = min(left, rootLeft + availableWidth - caretWidthRightOfOffset);
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            left = max(left, cb->x());
4165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else {
4175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // If there is no wrapping, the caret can leave its containing block, but not its root line box.
4185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (cb->style()->direction() == LTR) {
4195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            int rightEdge = max(cb->width(), rootRight);
4205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            left = min(left, rightEdge - caretWidthRightOfOffset);
421635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            left = max(left, rootLeft);
4225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else {
4235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            int leftEdge = min(cb->x(), rootLeft);
4245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            left = max(left, leftEdge);
4255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            left = min(left, rootRight - caretWidth);
4265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
429635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return IntRect(left, top, caretWidth, height);
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4325f1ab04193ad0130ca8204aadaceae083aca9881Feng QianALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts) const
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII) {
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int monospaceCharacterWidth = f.spaceWidth();
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int tabWidth = allowTabs() ? monospaceCharacterWidth * 8 : 0;
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int w = 0;
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool isSpace;
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool previousCharWasSpace = true; // FIXME: Preserves historical behavior, but seems wrong for start > 0.
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = start; i < start + len; i++) {
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char c = (*m_text)[i];
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (c <= ' ') {
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (c == ' ' || c == '\n') {
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    w += monospaceCharacterWidth;
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    isSpace = true;
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (c == '\t') {
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    w += tabWidth ? tabWidth - ((xPos + w) % tabWidth) : monospaceCharacterWidth;
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    isSpace = true;
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    isSpace = false;
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                w += monospaceCharacterWidth;
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                isSpace = false;
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isSpace && !previousCharWasSpace)
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                w += f.wordSpacing();
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            previousCharWasSpace = isSpace;
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return w;
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts);
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::trimmedPrefWidths(int leadWidth,
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                   int& beginMinW, bool& beginWS,
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                   int& endMinW, bool& endWS,
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                   bool& hasBreakableChar, bool& hasBreak,
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                   int& beginMaxW, int& endMaxW,
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                   int& minW, int& maxW, bool& stripFrontSpaces)
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool collapseWhiteSpace = style()->collapseWhiteSpace();
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!collapseWhiteSpace)
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stripFrontSpaces = false;
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_hasTab || prefWidthsDirty())
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        calcPrefWidths(leadWidth);
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    beginWS = !stripFrontSpaces && m_hasBeginWS;
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endWS = m_hasEndWS;
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int len = textLength();
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!len || (stripFrontSpaces && m_text->containsOnlyWhitespace())) {
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        beginMinW = 0;
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endMinW = 0;
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        beginMaxW = 0;
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endMaxW = 0;
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        minW = 0;
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        maxW = 0;
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        hasBreak = false;
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    minW = m_minWidth;
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    maxW = m_maxWidth;
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    beginMinW = m_beginMinWidth;
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endMinW = m_endMinWidth;
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    hasBreakableChar = m_hasBreakableChar;
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    hasBreak = m_hasBreak;
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ((*m_text)[0] == ' ' || ((*m_text)[0] == '\n' && !style()->preserveNewline()) || (*m_text)[0] == '\t') {
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const Font& f = style()->font(); // FIXME: This ignores first-line.
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (stripFrontSpaces) {
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const UChar space = ' ';
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int spaceWidth = f.width(TextRun(&space, 1));
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            maxW -= spaceWidth;
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            maxW += f.wordSpacing();
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    stripFrontSpaces = collapseWhiteSpace && m_hasEndWS;
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!style()->autoWrap() || minW > maxW)
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        minW = maxW;
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Compute our max widths by scanning the string for newlines.
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasBreak) {
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const Font& f = style()->font(); // FIXME: This ignores first-line.
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool firstLine = true;
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        beginMaxW = maxW;
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endMaxW = maxW;
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = 0; i < len; i++) {
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int linelen = 0;
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (i + linelen < len && (*m_text)[i + linelen] != '\n')
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                linelen++;
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (linelen) {
5315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                endMaxW = widthFromCache(f, i, linelen, leadWidth + endMaxW, 0);
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (firstLine) {
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    firstLine = false;
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    leadWidth = 0;
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    beginMaxW = endMaxW;
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                i += linelen;
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (firstLine) {
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                beginMaxW = 0;
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                firstLine = false;
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                leadWidth = 0;
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (i == len - 1)
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // A <pre> run that ends with a newline, as in, e.g.,
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // <pre>Some text\n\n<span>More text</pre>
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                endMaxW = 0;
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool isSpaceAccordingToStyle(UChar c, RenderStyle* style)
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return c == ' ' || (c == noBreakSpace && style->nbspMode() == SPACE);
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderText::minPrefWidth() const
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (prefWidthsDirty())
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const_cast<RenderText*>(this)->calcPrefWidths(0);
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_minWidth;
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderText::maxPrefWidth() const
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (prefWidthsDirty())
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const_cast<RenderText*>(this)->calcPrefWidths(0);
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_maxWidth;
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::calcPrefWidths(int leadWidth)
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HashSet<const SimpleFontData*> fallbackFonts;
5765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    calcPrefWidths(leadWidth, fallbackFonts);
5775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (fallbackFonts.isEmpty())
5785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_knownNotToUseFallbackFonts = true;
5795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
5805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts)
5825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
5835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(m_hasTab || prefWidthsDirty() || !m_knownNotToUseFallbackFonts);
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_minWidth = 0;
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_beginMinWidth = 0;
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_endMinWidth = 0;
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_maxWidth = 0;
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isBR())
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int currMinWidth = 0;
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int currMaxWidth = 0;
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasBreakableChar = false;
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasBreak = false;
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasTab = false;
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasBeginWS = false;
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasEndWS = false;
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const Font& f = style()->font(); // FIXME: This ignores first-line.
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int wordSpacing = style()->wordSpacing();
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int len = textLength();
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* txt = characters();
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool needsWordSpacing = false;
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool ignoringSpaces = false;
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isSpace = false;
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool firstWord = true;
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool firstLine = true;
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int nextBreakable = -1;
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int lastWordBoundary = 0;
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool breakNBSP = style()->autoWrap() && style()->nbspMode() == SPACE;
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool breakAll = (style()->wordBreak() == BreakAllWordBreak || style()->wordBreak() == BreakWordBreak) && style()->autoWrap();
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < len; i++) {
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UChar c = txt[i];
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool previousCharacterIsSpace = isSpace;
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool isNewline = false;
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (c == '\n') {
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (style()->preserveNewline()) {
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_hasBreak = true;
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                isNewline = true;
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                isSpace = false;
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                isSpace = true;
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (c == '\t') {
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!style()->collapseWhiteSpace()) {
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_hasTab = true;
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                isSpace = false;
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                isSpace = true;
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            isSpace = c == ' ';
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((isSpace || isNewline) && !i)
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_hasBeginWS = true;
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((isSpace || isNewline) && i == len - 1)
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_hasEndWS = true;
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!ignoringSpaces && style()->collapseWhiteSpace() && previousCharacterIsSpace && isSpace)
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ignoringSpaces = true;
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ignoringSpaces && !isSpace)
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ignoringSpaces = false;
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Ignore spaces and soft hyphens
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ignoringSpaces) {
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(lastWordBoundary == i);
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastWordBoundary++;
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (c == softHyphen) {
6555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts);
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastWordBoundary = i + 1;
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool hasBreak = breakAll || isBreakable(txt, i, len, nextBreakable, breakNBSP);
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool betweenWords = true;
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int j = i;
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (c != '\n' && !isSpaceAccordingToStyle(c, style()) && c != '\t' && c != softHyphen) {
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            j++;
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (j == len)
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            c = txt[j];
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isBreakable(txt, j, len, nextBreakable, breakNBSP))
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (breakAll) {
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                betweenWords = false;
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int wordLen = j - i;
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (wordLen) {
6785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            int w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts);
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currMinWidth += w;
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (betweenWords) {
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (lastWordBoundary == i)
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    currMaxWidth += w;
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
6845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts);
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                lastWordBoundary = j;
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool isSpace = (j < len) && isSpaceAccordingToStyle(c, style());
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool isCollapsibleWhiteSpace = (j < len) && style()->isCollapsibleWhiteSpace(c);
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (j < len && style()->autoWrap())
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_hasBreakableChar = true;
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Add in wordSpacing to our currMaxWidth, but not if this is the last word on a line or the
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // last word in the run.
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !containsOnlyWhitespace(j, len-j))
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currMaxWidth += wordSpacing;
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (firstWord) {
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                firstWord = false;
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If the first character in the run is breakable, then we consider ourselves to have a beginning
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // minimum width of 0, since a break could occur right before our run starts, preventing us from ever
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // being appended to a previous text run when considering the total minimum width of the containing block.
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (hasBreak)
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    m_hasBreakableChar = true;
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_beginMinWidth = hasBreak ? 0 : w;
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_endMinWidth = w;
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (currMinWidth > m_minWidth)
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_minWidth = currMinWidth;
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currMinWidth = 0;
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i += wordLen - 1;
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Nowrap can never be broken, so don't bother setting the
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // breakable character boolean. Pre can only be broken if we encounter a newline.
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (style()->autoWrap() || isNewline)
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_hasBreakableChar = true;
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (currMinWidth > m_minWidth)
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_minWidth = currMinWidth;
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currMinWidth = 0;
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isNewline) { // Only set if preserveNewline was true and we saw a newline.
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (firstLine) {
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    firstLine = false;
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    leadWidth = 0;
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!style()->autoWrap())
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        m_beginMinWidth = currMaxWidth;
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (currMaxWidth > m_maxWidth)
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    m_maxWidth = currMaxWidth;
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currMaxWidth = 0;
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currMaxWidth += f.width(TextRun(txt + i, 1, allowTabs(), leadWidth + currMaxWidth));
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1;
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(lastWordBoundary == i);
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastWordBoundary++;
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord))
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currMaxWidth += wordSpacing;
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_minWidth = max(currMinWidth, m_minWidth);
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_maxWidth = max(currMaxWidth, m_maxWidth);
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!style()->autoWrap())
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_minWidth = m_maxWidth;
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->whiteSpace() == PRE) {
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLine)
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_beginMinWidth = m_maxWidth;
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_endMinWidth = currMaxWidth;
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setPrefWidthsDirty(false);
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
762643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool RenderText::isAllCollapsibleWhitespace()
763643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
764643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int length = textLength();
765643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    const UChar* text = characters();
766643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (int i = 0; i < length; i++) {
767643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!style()->isCollapsibleWhiteSpace(text[i]))
768643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return false;
769643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
770643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return true;
771643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
772643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned currPos;
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (currPos = from;
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         currPos < from + len && ((*m_text)[currPos] == '\n' || (*m_text)[currPos] == ' ' || (*m_text)[currPos] == '\t');
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         currPos++) { }
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return currPos >= (from + len);
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7825f1ab04193ad0130ca8204aadaceae083aca9881Feng QianIntPoint RenderText::firstRunOrigin() const
7835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
7845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return IntPoint(firstRunX(), firstRunY());
7855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
7865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
787635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderText::firstRunX() const
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_firstTextBox ? m_firstTextBox->m_x : 0;
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
792635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderText::firstRunY() const
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_firstTextBox ? m_firstTextBox->m_y : 0;
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
796635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::setSelectionState(SelectionState state)
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* box;
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject::setSelectionState(state);
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) {
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int startPos, endPos;
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        selectionStartEnd(startPos, endPos);
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (selectionState() == SelectionStart) {
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            endPos = textLength();
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // to handle selection from end of text to end of line
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (startPos != 0 && startPos == endPos)
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                startPos = endPos - 1;
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (selectionState() == SelectionEnd)
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            startPos = 0;
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (box = firstTextBox(); box; box = box->nextTextBox()) {
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (box->isSelected(startPos, endPos)) {
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RootInlineBox* line = box->root();
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (line)
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    line->setHasSelectedChildren(true);
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (box = firstTextBox(); box; box = box->nextTextBox()) {
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RootInlineBox* line = box->root();
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (line)
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                line->setHasSelectedChildren(state == SelectionInside);
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
829643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // The returned value can be null in case of an orphaned tree.
830643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (RenderBlock* cb = containingBlock())
831643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        cb->setSelectionState(state);
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force)
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned oldLen = textLength();
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned newLen = text->length();
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int delta = newLen - oldLen;
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned end = len ? offset + len - 1 : offset;
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* firstRootBox = 0;
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* lastRootBox = 0;
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool dirtiedLines = false;
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Dirty all text boxes that include characters in between offset and offset+len.
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Text run is entirely before the affected range.
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->end() < offset)
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Text run is entirely after the affected range.
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->start() > end) {
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr->offsetRun(delta);
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RootInlineBox* root = curr->root();
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!firstRootBox) {
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                firstRootBox = root;
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!dirtiedLines) {
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // The affected area was in between two runs. Go ahead and mark the root box of
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // the run after the affected area as dirty.
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    firstRootBox->markDirty();
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    dirtiedLines = true;
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastRootBox = root;
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (curr->end() >= offset && curr->end() <= end) {
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Text run overlaps with the left end of the affected range.
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr->dirtyLineBoxes();
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            dirtiedLines = true;
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (curr->start() <= offset && curr->end() >= end) {
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Text run subsumes the affected range.
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr->dirtyLineBoxes();
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            dirtiedLines = true;
8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (curr->start() <= end && curr->end() >= end) {
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Text run overlaps with right end of the affected range.
8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr->dirtyLineBoxes();
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            dirtiedLines = true;
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now we have to walk all of the clean lines and adjust their cached line break information
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to reflect our updated offsets.
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lastRootBox)
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastRootBox = lastRootBox->nextRootBox();
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (firstRootBox) {
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RootInlineBox* prev = firstRootBox->prevRootBox();
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prev)
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            firstRootBox = prev;
8895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else if (lastTextBox()) {
8905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT(!lastRootBox);
8915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        firstRootBox = lastTextBox()->root();
8925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        firstRootBox->markDirty();
8935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        dirtiedLines = true;
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) {
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curr->lineBreakObj() == this && curr->lineBreakPos() > end)
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr->setLineBreakPos(curr->lineBreakPos() + delta);
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the text node is empty, dirty the line where new text will be inserted.
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!firstTextBox() && parent()) {
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parent()->dirtyLinesFromChangedChild(this);
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        dirtiedLines = true;
9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_linesDirty = dirtiedLines;
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setText(text, force);
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool isInlineFlowOrEmptyText(RenderObject* o)
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
912635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (o->isRenderInline())
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!o->isText())
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
916635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    StringImpl* text = toRenderText(o)->text();
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!text)
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return !text->length();
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUChar RenderText::previousCharacter()
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // find previous text renderer if one exists
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* previousText = this;
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while ((previousText = previousText->previousInPreOrder()))
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!isInlineFlowOrEmptyText(previousText))
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar prev = ' ';
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (previousText && previousText->isText())
931635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (StringImpl* previousString = toRenderText(previousText)->text())
9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            prev = (*previousString)[previousString->length() - 1];
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return prev;
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::setTextInternal(PassRefPtr<StringImpl> text)
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(text);
9395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_text = document()->displayStringModifiedByEncoding(text);
9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_text);
9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG)
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isSVGText()) {
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style() && style()->whiteSpace() == PRE) {
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Spec: When xml:space="preserve", the SVG user agent will do the following using a
9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // copy of the original character data content. It will convert all newline and tab
9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // characters into space characters. Then, it will draw all space characters, including
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // leading, trailing and multiple contiguous space characters.
9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_text = m_text->replace('\n', ' ');
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If xml:space="preserve" is set, white-space is set to "pre", which
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // preserves leading, trailing & contiguous space character for us.
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       } else {
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Spec: When xml:space="default", the SVG user agent will do the following using a
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // copy of the original character data content. First, it will remove all newline
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // characters. Then it will convert all tab characters into space characters.
9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Then, it will strip off all leading and trailing space characters.
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Then, all contiguous space characters will be consolidated.
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           m_text = m_text->replace('\n', StringImpl::empty());
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           // If xml:space="default" is set, white-space is set to "nowrap", which handles
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           // leading, trailing & contiguous space character removal for us.
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_text = m_text->replace('\t', ' ');
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()) {
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (style()->textTransform()) {
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case TTNONE:
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case CAPITALIZE: {
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_text = m_text->capitalize(previousCharacter());
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case UPPERCASE:
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_text = m_text->upper();
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case LOWERCASE:
9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_text = m_text->lower();
9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We use the same characters here as for list markers.
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // See the listMarkerText function in RenderListMarker.cpp.
9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (style()->textSecurity()) {
9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case TSNONE:
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case TSCIRCLE:
9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_text = m_text->secure(whiteBullet);
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case TSDISC:
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_text = m_text->secure(bullet);
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case TSSQUARE:
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_text = m_text->secure(blackSquare);
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_text);
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!isBR() || (textLength() == 1 && (*m_text)[0] == '\n'));
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_isAllASCII = charactersAreAllASCII(m_text.get());
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::setText(PassRefPtr<StringImpl> text, bool force)
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(text);
10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!force && equal(m_text.get(), text.get()))
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setTextInternal(text);
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayoutAndPrefWidthsRecalc();
10185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_knownNotToUseFallbackFonts = false;
1019d0825bca7fe65beaee391d30da42e937db621564Steve Block
1020d0825bca7fe65beaee391d30da42e937db621564Steve Block    AXObjectCache* axObjectCache = document()->axObjectCache();
1021d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (axObjectCache->accessibilityEnabled())
1022d0825bca7fe65beaee391d30da42e937db621564Steve Block        axObjectCache->contentChanged(this);
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderText::lineHeight(bool firstLine, bool) const
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Always use the interior line height of the parent (e.g., if our parent is an inline block).
10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return parent()->lineHeight(firstLine, true);
10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderText::dirtyLineBoxes(bool fullLayout)
10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fullLayout)
10348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        deleteTextBoxes();
10358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (!m_linesDirty) {
10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            box->dirtyLineBoxes();
10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_linesDirty = false;
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianInlineTextBox* RenderText::createTextBox()
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return new (renderArena()) InlineTextBox(this);
10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianInlineTextBox* RenderText::createInlineTextBox()
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    InlineTextBox* textBox = createTextBox();
10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_firstTextBox)
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstTextBox = m_lastTextBox = textBox;
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_lastTextBox->setNextLineBox(textBox);
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        textBox->setPreviousLineBox(m_lastTextBox);
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_lastTextBox = textBox;
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    textBox->setIsText(true);
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return textBox;
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderText::positionLineBox(InlineBox* box)
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* s = static_cast<InlineTextBox*>(box);
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: should not be needed!!!
1066635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!s->len()) {
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We want the box to be destroyed.
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->remove();
1069d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_firstTextBox == s)
1070d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_firstTextBox = s->nextTextBox();
1071d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
1072d0825bca7fe65beaee391d30da42e937db621564Steve Block            s->prevTextBox()->setNextLineBox(s->nextTextBox());
1073d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_lastTextBox == s)
1074d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_lastTextBox = s->prevTextBox();
1075d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
1076d0825bca7fe65beaee391d30da42e937db621564Steve Block            s->nextTextBox()->setPreviousLineBox(s->prevTextBox());
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->destroy(renderArena());
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_containsReversedText |= s->direction() == RTL;
10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianunsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts) const
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (from >= textLength())
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (from + len > textLength())
10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        len = textLength() - from;
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return width(from, len, style(firstLine)->font(), xPos, fallbackFonts);
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianunsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, HashSet<const SimpleFontData*>* fallbackFonts) const
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(from + len <= textLength());
10988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!characters())
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int w;
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (&f == &style()->font()) {
11035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!style()->preserveNewline() && !from && len == textLength()) {
11045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (fallbackFonts) {
11055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                if (prefWidthsDirty() || !m_knownNotToUseFallbackFonts) {
11065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    const_cast<RenderText*>(this)->calcPrefWidths(0, *fallbackFonts);
11075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    if (fallbackFonts->isEmpty())
11085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        m_knownNotToUseFallbackFonts = true;
11095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                }
11105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                w = m_maxWidth;
11115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            } else
11125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                w = maxPrefWidth();
11135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else
11145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            w = widthFromCache(f, from, len, xPos, fallbackFonts);
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
11165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        w = f.width(TextRun(text()->characters() + from, len, allowTabs(), xPos), fallbackFonts);
11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return w;
11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect RenderText::linesBoundingBox() const
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect result;
1124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(!firstTextBox() == !lastTextBox());  // Either both are null or both exist.
1126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (firstTextBox() && lastTextBox()) {
1127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Return the width of the minimal left side and the maximal right side.
1128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int leftSide = 0;
1129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int rightSide = 0;
1130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
11318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (curr == firstTextBox() || curr->x() < leftSide)
11328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                leftSide = curr->x();
11338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (curr == firstTextBox() || curr->x() + curr->width() > rightSide)
11348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                rightSide = curr->x() + curr->width();
1135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
1136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        result.setWidth(rightSide - leftSide);
1137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        result.setX(leftSide);
11388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setHeight(lastTextBox()->y() + lastTextBox()->height() - firstTextBox()->y());
11398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result.setY(firstTextBox()->y());
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return result;
11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* cb = containingBlock();
1148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return cb->clippedOverflowRectForRepaint(repaintContainer);
11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderText::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent)
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!needsLayout());
11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (selectionState() == SelectionNone)
11568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return IntRect();
11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock* cb =  containingBlock();
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!cb)
11598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return IntRect();
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now calculate startPos and endPos for painting selection.
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We include a selection while endPos > 0
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int startPos, endPos;
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (selectionState() == SelectionInside) {
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We are fully selected.
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        startPos = 0;
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endPos = textLength();
11688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        selectionStartEnd(startPos, endPos);
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (selectionState() == SelectionStart)
11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            endPos = textLength();
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (selectionState() == SelectionEnd)
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            startPos = 0;
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (startPos == endPos)
11778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return IntRect();
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    IntRect rect;
1180d0825bca7fe65beaee391d30da42e937db621564Steve Block    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        rect.unite(box->selectionRect(0, 0, startPos, endPos));
11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1183d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Check if there are ellipsis which fall within the selection.
1184d0825bca7fe65beaee391d30da42e937db621564Steve Block        unsigned short truncation = box->truncation();
1185d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (truncation != cNoTruncation) {
1186d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (EllipsisBox* ellipsis = box->root()->ellipsisBox()) {
1187d0825bca7fe65beaee391d30da42e937db621564Steve Block                int ePos = min<int>(endPos - box->start(), box->len());
1188d0825bca7fe65beaee391d30da42e937db621564Steve Block                int sPos = max<int>(startPos - box->start(), 0);
1189d0825bca7fe65beaee391d30da42e937db621564Steve Block                // The ellipsis should be considered to be selected if the end of
1190d0825bca7fe65beaee391d30da42e937db621564Steve Block                // the selection is past the beginning of the truncation and the
1191d0825bca7fe65beaee391d30da42e937db621564Steve Block                // beginning of the selection is before or at the beginning of the
1192d0825bca7fe65beaee391d30da42e937db621564Steve Block                // truncation.
1193d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (ePos >= truncation && sPos <= truncation)
1194d0825bca7fe65beaee391d30da42e937db621564Steve Block                    rect.unite(ellipsis->selectionRect(0, 0));
1195d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
1196d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
1197d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
1198d0825bca7fe65beaee391d30da42e937db621564Steve Block
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (clipToVisibleContent)
12008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        computeRectForRepaint(repaintContainer, rect);
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cb->hasColumns())
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cb->adjustRectForColumns(rect);
12048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
12058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return rect;
12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderText::caretMinOffset() const
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* box = firstTextBox();
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box)
12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int minOffset = box->start();
12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (box = box->nextTextBox(); box; box = box->nextTextBox())
1218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        minOffset = min<int>(minOffset, box->start());
12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return minOffset;
12208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderText::caretMaxOffset() const
12238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* box = lastTextBox();
12258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!box)
12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return textLength();
1227635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int maxOffset = box->start() + box->len();
12288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (box = box->prevTextBox(); box; box = box->prevTextBox())
1229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        maxOffset = max<int>(maxOffset, box->start() + box->len());
12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return maxOffset;
12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned RenderText::caretMaxRenderedOffset() const
12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int l = 0;
12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
1237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        l += box->len();
12388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return l;
12398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderText::previousOffset(int current) const
12428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    StringImpl* si = m_text.get();
12448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!iterator)
12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return current - 1;
12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long result = textBreakPreceding(iterator, current);
12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result == TextBreakDone)
12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = current - 1;
12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#ifdef BUILDING_ON_TIGER
12538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // ICU 3.2 allows character breaks before a half-width Katakana voiced mark.
12548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (static_cast<unsigned>(result) < si->length()) {
12558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        UChar character = (*si)[result];
12568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (character == 0xFF9E || character == 0xFF9F)
12578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            --result;
12588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
12598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
12608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
12628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_CHOSEONG_START (0x1100)
12658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_CHOSEONG_END (0x115F)
12668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_JUNGSEONG_START (0x1160)
12678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_JUNGSEONG_END (0x11A2)
12688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_JONGSEONG_START (0x11A8)
12698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_JONGSEONG_END (0x11F9)
12708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_SYLLABLE_START (0xAC00)
12718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_SYLLABLE_END (0xD7AF)
12728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define HANGUL_JONGSEONG_COUNT (28)
12738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
12748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianenum HangulState {
12758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HangulStateL,
12768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HangulStateV,
12778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HangulStateT,
12788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HangulStateLV,
12798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HangulStateLVT,
12808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HangulStateBreak
12818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian};
12828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
12838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianinline bool isHangulLVT(UChar32 character)
12848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
12858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return (character - HANGUL_SYLLABLE_START) % HANGUL_JONGSEONG_COUNT;
12868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
12878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
12888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianint RenderText::previousOffsetForBackwardDeletion(int current) const
12898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
12908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if PLATFORM(MAC)
12918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UChar32 character;
12928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (current > 0) {
12938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (U16_IS_TRAIL((*m_text)[--current]))
12948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            --current;
12958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (current < 0)
12968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
12978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
12988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        UChar32 character = m_text->characterStartingAt(current);
12998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // We don't combine characters in Armenian ... Limbu range for backward deletion.
13018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if ((character >= 0x0530) && (character < 0x1950))
13028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
13038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (u_isbase(character) && (character != 0xFF9E) && (character != 0xFF9F))
13058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
13068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
13078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (current <= 0)
13098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return current;
13108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Hangul
13128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    character = m_text->characterStartingAt(current);
13138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) {
13148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        HangulState state;
13158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        HangulState initialState;
13168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (character < HANGUL_JUNGSEONG_START)
13188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            state = HangulStateL;
13198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else if (character < HANGUL_JONGSEONG_START)
13208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            state = HangulStateV;
13218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else if (character < HANGUL_SYLLABLE_START)
13228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            state = HangulStateT;
13238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else
13248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            state = isHangulLVT(character) ? HangulStateLVT : HangulStateLV;
13258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        initialState = state;
13278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        while (current > 0 && ((character = m_text->characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {
13298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            switch (state) {
13308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case HangulStateV:
13318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (character <= HANGUL_CHOSEONG_END)
13328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    state = HangulStateL;
13338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END) && !isHangulLVT(character))
13348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    state = HangulStateLV;
13358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else if (character > HANGUL_JUNGSEONG_END)
13368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    state = HangulStateBreak;
13378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
13388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case HangulStateT:
13398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if ((character >= HANGUL_JUNGSEONG_START) && (character <= HANGUL_JUNGSEONG_END))
13408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    state = HangulStateV;
13418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))
13428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    state = (isHangulLVT(character) ? HangulStateLVT : HangulStateLV);
13438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else if (character < HANGUL_JUNGSEONG_START)
13448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    state = HangulStateBreak;
13458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
13468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            default:
13478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                state = (character < HANGUL_JUNGSEONG_START) ? HangulStateL : HangulStateBreak;
13488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
13498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
13508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (state == HangulStateBreak)
13518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
13528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            --current;
13548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
13558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
13568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return current;
13588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#else
13598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Platforms other than Mac delete by one code point.
13608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return current - 1;
13618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
13628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
13638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderText::nextOffset(int current) const
13658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    StringImpl* si = m_text.get();
13678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
13688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!iterator)
13698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return current + 1;
13708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long result = textBreakFollowing(iterator, current);
13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result == TextBreakDone)
13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = current + 1;
13748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#ifdef BUILDING_ON_TIGER
13768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // ICU 3.2 allows character breaks before a half-width Katakana voiced mark.
13778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (static_cast<unsigned>(result) < si->length()) {
13788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        UChar character = (*si)[result];
13798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (character == 0xFF9E || character == 0xFF9F)
13808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ++result;
13818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
13828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
13838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
13858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
13888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderText::checkConsistency() const
13908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef CHECK_CONSISTENCY
13928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const InlineTextBox* prev = 0;
13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (const InlineTextBox* child = m_firstTextBox; child != 0; child = child->nextTextBox()) {
1394d0825bca7fe65beaee391d30da42e937db621564Steve Block        ASSERT(child->renderer() == this);
13958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(child->prevTextBox() == prev);
13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prev = child;
13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(prev == m_lastTextBox);
13998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
1405