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