18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2000 Lars Knoll (knoll@kde.org) 32fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved. 4d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2010 Google Inc. All rights reserved. 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "BidiResolver.h" 2606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "Hyphenation.h" 278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "InlineIterator.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InlineTextBox.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Logging.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderArena.h" 312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "RenderCombineText.h" 328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderInline.h" 33545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "RenderLayer.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderListMarker.h" 352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "RenderRubyRun.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h" 3768513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "Settings.h" 3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "TextBreakIterator.h" 39ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h" 40d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "TrailingFloatsRootInlineBox.h" 416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "VerticalPositionCache.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "break_lines.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/AlwaysInline.h> 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/RefCountedLeakCounter.h> 45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h> 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h> 4709b60ab8488b362c96df8f268613aafaeebfcfa1Steve Block#include <wtf/unicode/CharacterNames.h> 4809b60ab8488b362c96df8f268613aafaeebfcfa1Steve Block 4909b60ab8488b362c96df8f268613aafaeebfcfa1Steve Block#if ENABLE(SVG) 5009b60ab8488b362c96df8f268613aafaeebfcfa1Steve Block#include "RenderSVGInlineText.h" 5109b60ab8488b362c96df8f268613aafaeebfcfa1Steve Block#include "SVGRootInlineBox.h" 5209b60ab8488b362c96df8f268613aafaeebfcfa1Steve Block#endif 5309b60ab8488b362c96df8f268613aafaeebfcfa1Steve Block 547cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#ifdef ANDROID_LAYOUT 557cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#include "Frame.h" 567cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#include "FrameTree.h" 577cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#include "Settings.h" 587cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#include "Text.h" 597cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#include "HTMLNames.h" 607cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#endif // ANDROID_LAYOUT 6106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF; 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace Unicode; 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// We don't let our line box tree for a single line get any deeper than this. 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst unsigned cMaxLineDepth = 200; 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic inline int borderPaddingMarginStart(RenderInline* child) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return child->marginStart() + child->paddingStart() + child->borderStart(); 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic inline int borderPaddingMarginEnd(RenderInline* child) 772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return child->marginEnd() + child->paddingEnd() + child->borderEnd(); 792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 81a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic int inlineLogicalWidth(RenderObject* child, bool start = true, bool end = true) 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned lineDepth = 1; 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int extraWidth = 0; 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* parent = child->parent(); 862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (parent->isRenderInline() && lineDepth++ < cMaxLineDepth) { 872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderInline* parentAsRenderInline = toRenderInline(parent); 888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (start && !child->previousSibling()) 892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch extraWidth += borderPaddingMarginStart(parentAsRenderInline); 908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (end && !child->nextSibling()) 912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch extraWidth += borderPaddingMarginEnd(parentAsRenderInline); 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project child = parent; 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parent = child->parent(); 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return extraWidth; 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void checkMidpoints(LineMidpointState& lineMidpointState, InlineIterator& lBreak) 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check to see if our last midpoint is a start point beyond the line break. If so, 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // shave it off the list, and shave off a trailing space if the previous end point doesn't 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // preserve whitespace. 1032bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lBreak.m_obj && lineMidpointState.numMidpoints && !(lineMidpointState.numMidpoints % 2)) { 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch InlineIterator* midpoints = lineMidpointState.midpoints.data(); 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2]; 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoints - 1]; 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator currpoint = endpoint; 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak) 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currpoint.increment(); 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (currpoint == lBreak) { 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We hit the line break before the start point. Shave off the start point. 1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.numMidpoints--; 1132bde8e466a4451c7319e3a072d118917957d6554Steve Block if (endpoint.m_obj->style()->collapseWhiteSpace()) 1142bde8e466a4451c7319e3a072d118917957d6554Steve Block endpoint.m_pos--; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void addMidpoint(LineMidpointState& lineMidpointState, const InlineIterator& midpoint) 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (lineMidpointState.midpoints.size() <= lineMidpointState.numMidpoints) 1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.midpoints.grow(lineMidpointState.numMidpoints + 10); 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch InlineIterator* midpoints = lineMidpointState.midpoints.data(); 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch midpoints[lineMidpointState.numMidpoints++] = midpoint; 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBidiResolver& resolver) 1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return new (obj->renderArena()) BidiRun(start, end, obj, resolver.context(), resolver.dir()); 1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid RenderBlock::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int end, RenderObject* obj, InlineBidiResolver& resolver) 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (start > end || obj->isFloating() || 1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch (obj->isPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline())) 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LineMidpointState& lineMidpointState = resolver.midpointState(); 1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints); 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator nextMidpoint; 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (haveNextMidpoint) 1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint]; 1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (lineMidpointState.betweenMidpoints) { 1452bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!(haveNextMidpoint && nextMidpoint.m_obj == obj)) 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This is a new start point. Stop ignoring objects and 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // adjust our start. 1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.betweenMidpoints = false; 1502bde8e466a4451c7319e3a072d118917957d6554Steve Block start = nextMidpoint.m_pos; 1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.currentMidpoint++; 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (start < end) 1532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return appendRunsForObject(runs, start, end, obj, resolver); 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 1552bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) { 1562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch runs.addRun(createRun(start, end, obj, resolver)); 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // An end midpoint has been encountered within our object. We 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // need to go ahead and append a run with our endpoint. 1622bde8e466a4451c7319e3a072d118917957d6554Steve Block if (static_cast<int>(nextMidpoint.m_pos + 1) <= end) { 1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.betweenMidpoints = true; 1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.currentMidpoint++; 1652bde8e466a4451c7319e3a072d118917957d6554Steve Block if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it. 1662bde8e466a4451c7319e3a072d118917957d6554Steve Block if (static_cast<int>(nextMidpoint.m_pos + 1) > start) 1672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch runs.addRun(createRun(start, nextMidpoint.m_pos + 1, obj, resolver)); 1682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return appendRunsForObject(runs, nextMidpoint.m_pos + 1, end, obj, resolver); 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 1712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch runs.addRun(createRun(start, end, obj, resolver)); 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false) 1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isRootLineBox) 1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return toRenderBlock(obj)->createAndAppendRootInlineBox(); 1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (obj->isText()) { 1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox(); 1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode 1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // (Note the use of strict mode. In "almost strict" mode, we don't treat the box for <br> as text.) 1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (obj->isBR()) 1855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen textBox->setIsText(isOnlyRun || obj->document()->inNoQuirksMode()); 1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return textBox; 1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (obj->isBox()) 1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return toRenderBox(obj)->createInlineBox(); 1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return toRenderInline(obj)->createAndAppendInlineFlowBox(); 1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout) 1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (o->isText()) { 19881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (o->preferredLogicalWidthsDirty() && (o->isCounter() || o->isQuote())) 199bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen toRenderText(o)->computePreferredLogicalWidths(0); // FIXME: Counters depend on this hack. No clue why. Should be investigated and removed. 2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderText(o)->dirtyLineBoxes(fullLayout); 2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else 2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderInline(o)->dirtyLineBoxes(fullLayout); 2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 2048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2052fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) 2062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 2072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block do { 2082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (parentBox->isConstructed() || parentBox->nextOnLine()) 2092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return true; 2102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block parentBox = parentBox->parent(); 2112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } while (parentBox); 2122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return false; 2132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 2142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2152bde8e466a4451c7319e3a072d118917957d6554Steve BlockInlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj, bool firstLine, InlineBox* childBox) 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if we have an unconstructed line box for this object that is also 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the last item on the line. 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned lineDepth = 1; 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineFlowBox* parentBox = 0; 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineFlowBox* result = 0; 2222bde8e466a4451c7319e3a072d118917957d6554Steve Block bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::initialLineBoxContain(); 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(obj->isRenderInline() || obj == this); 2258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0; 2272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get the last box we made for this render object. 2292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch parentBox = inlineFlow ? inlineFlow->lastLineBox() : toRenderBlock(obj)->lastLineBox(); 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // If this box or its ancestor is constructed then it is from a previous line, and we need 2322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // to make a new box for our line. If this box or its ancestor is unconstructed but it has 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // something following it on the line, then we know we have to make a new box 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // as well. In this situation our inline has actually been split in two on 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the same line (this can happen with very fancy language mixtures). 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool constructedNewBox = false; 2372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes(); 2382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox); 2392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (allowedToConstructNewBox && !canUseExistingParentBox) { 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to make a new box for this render object. Once 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // made, we need to place it at the end of the current line. 2428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this); 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(newBox->isInlineFlowBox()); 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parentBox = static_cast<InlineFlowBox*>(newBox); 2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian parentBox->setFirstLineStyleBit(firstLine); 2462bde8e466a4451c7319e3a072d118917957d6554Steve Block parentBox->setIsHorizontal(isHorizontalWritingMode()); 2472bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!hasDefaultLineBoxContain) 2482bde8e466a4451c7319e3a072d118917957d6554Steve Block parentBox->clearDescendantsHaveSameLineHeightAndBaseline(); 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructedNewBox = true; 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (constructedNewBox || canUseExistingParentBox) { 2532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!result) 2542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result = parentBox; 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // If we have hit the block itself, then |box| represents the root 2572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // inline box for the line, and it doesn't have to be appended to any parent 2582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // inline. 2592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (childBox) 2602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch parentBox->addToLine(childBox); 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!constructedNewBox || obj == this) 2632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch childBox = parentBox; 2662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we've exceeded our line depth, then jump straight to the root and skip all the remaining 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // intermediate inline flows. 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project obj = (++lineDepth >= cMaxLineDepth) ? this : obj->parent(); 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (true); 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) 2782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch BidiRun* run = bidiRuns.logicallyLastRun(); 2802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!run) 2812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 2822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned int pos = run->stop(); 2832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderObject* r = run->m_object; 2842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!r->isText() || r->isBR()) 2852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 2862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderText* renderText = toRenderText(r); 2872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (pos >= renderText->textLength()) 2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 2892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (isASCIISpace(renderText->characters()[pos])) { 2912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch pos++; 2922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (pos >= renderText->textLength()) 2932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 2942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 2952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 2962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochRootInlineBox* RenderBlock::constructLine(BidiRunList<BidiRun>& bidiRuns, bool firstLine, bool lastLine) 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(bidiRuns.firstRun()); 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool rootHasSelectedChildren = false; 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineFlowBox* parentBox = 0; 3042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) { 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create a box for our object. 3062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool isOnlyRun = (bidiRuns.runCount() == 1); 3072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (bidiRuns.runCount() == 2 && !r->m_object->isListMarker()) 3082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun() : bidiRuns.firstRun())->m_object->isListMarker(); 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun); 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r->m_box = box; 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(box); 3145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!box) 3155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian continue; 3165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!rootHasSelectedChildren && box->renderer()->selectionState() != RenderObject::SelectionNone) 318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch rootHasSelectedChildren = true; 319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If we have no parent box yet, or if the run is not simply a sibling, 3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // then we need to construct inline boxes as necessary to properly enclose the 3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // run's inline box. 3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!parentBox || parentBox->renderer() != r->m_object->parent()) 3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Create new inline boxes all the way back to the appropriate insertion point. 3252bde8e466a4451c7319e3a072d118917957d6554Steve Block parentBox = createLineBoxes(r->m_object->parent(), firstLine, box); 3262bde8e466a4451c7319e3a072d118917957d6554Steve Block else { 3272bde8e466a4451c7319e3a072d118917957d6554Steve Block // Append the inline box to this line. 3282bde8e466a4451c7319e3a072d118917957d6554Steve Block parentBox->addToLine(box); 3292bde8e466a4451c7319e3a072d118917957d6554Steve Block } 3305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool visuallyOrdered = r->m_object->style()->visuallyOrdered(); 33281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch box->setBidiLevel(r->level()); 3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (box->isInlineTextBox()) { 3355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian InlineTextBox* text = static_cast<InlineTextBox*>(box); 3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian text->setStart(r->m_start); 3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian text->setLen(r->m_stop - r->m_start); 3385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian text->m_dirOverride = r->dirOverride(visuallyOrdered); 33906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (r->m_hasHyphen) 34006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen text->setHasHyphen(true); 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We should have a root inline box. It should be unconstructed and 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // be the last continuation of our line list. 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(lastLineBox() && !lastLineBox()->isConstructed()); 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 348a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Set the m_selectedChildren flag on the root inline box if one of the leaf inline box 349a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // from the bidi runs walk above has a selection state. 350a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (rootHasSelectedChildren) 351a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch lastLineBox()->root()->setHasSelectedChildren(true); 352a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Set bits on our inline flow boxes that indicate which sides should 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // paint borders/margins/padding. This knowledge will ultimately be used when 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we determine the horizontal positions and widths of all the inline boxes on 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the line. 3572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool isLogicallyLastRunWrapped = bidiRuns.logicallyLastRun()->m_object && bidiRuns.logicallyLastRun()->m_object->isText() ? !reachedEndOfTextRenderer(bidiRuns) : true; 3582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lastLineBox()->determineSpacingForFlowBoxes(lastLine, isLogicallyLastRunWrapped, bidiRuns.logicallyLastRun()->m_object); 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now mark the line boxes as being constructed. 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastLineBox()->setConstructed(); 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return the last line. 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return lastRootBox(); 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochETextAlign RenderBlock::textAlignmentForLine(bool endsWithSoftBreak) const 36881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 36981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ETextAlign alignment = style()->textAlign(); 37081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!endsWithSoftBreak && alignment == JUSTIFY) 37181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch alignment = TAAUTO; 37281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 37381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return alignment; 37481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 37581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 3762bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic void updateLogicalWidthForLeftAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth) 3772bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 3782bde8e466a4451c7319e3a072d118917957d6554Steve Block // The direction of the block should determine what happens with wide lines. 3792bde8e466a4451c7319e3a072d118917957d6554Steve Block // In particular with RTL blocks, wide lines should still spill out to the left. 3802bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isLeftToRightDirection) { 3812bde8e466a4451c7319e3a072d118917957d6554Steve Block if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) 3822bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth)); 3832bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 3842bde8e466a4451c7319e3a072d118917957d6554Steve Block } 3852bde8e466a4451c7319e3a072d118917957d6554Steve Block 3862bde8e466a4451c7319e3a072d118917957d6554Steve Block if (trailingSpaceRun) 3872bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingSpaceRun->m_box->setLogicalWidth(0); 3882bde8e466a4451c7319e3a072d118917957d6554Steve Block else if (totalLogicalWidth > availableLogicalWidth) 3892bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalLeft -= (totalLogicalWidth - availableLogicalWidth); 3902bde8e466a4451c7319e3a072d118917957d6554Steve Block} 3912bde8e466a4451c7319e3a072d118917957d6554Steve Block 3922bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic void updateLogicalWidthForRightAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth) 3932bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 3942bde8e466a4451c7319e3a072d118917957d6554Steve Block // Wide lines spill out of the block based off direction. 3952bde8e466a4451c7319e3a072d118917957d6554Steve Block // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right 3962bde8e466a4451c7319e3a072d118917957d6554Steve Block // side of the block. 3972bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isLeftToRightDirection) { 3982bde8e466a4451c7319e3a072d118917957d6554Steve Block if (trailingSpaceRun) { 3992bde8e466a4451c7319e3a072d118917957d6554Steve Block totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); 4002bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingSpaceRun->m_box->setLogicalWidth(0); 4012bde8e466a4451c7319e3a072d118917957d6554Steve Block } 4022bde8e466a4451c7319e3a072d118917957d6554Steve Block if (totalLogicalWidth < availableLogicalWidth) 4032bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalLeft += availableLogicalWidth - totalLogicalWidth; 4042bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 4052bde8e466a4451c7319e3a072d118917957d6554Steve Block } 4062bde8e466a4451c7319e3a072d118917957d6554Steve Block 4072bde8e466a4451c7319e3a072d118917957d6554Steve Block if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) { 4082bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth)); 4092bde8e466a4451c7319e3a072d118917957d6554Steve Block totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); 4102bde8e466a4451c7319e3a072d118917957d6554Steve Block } else 4112bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalLeft += availableLogicalWidth - totalLogicalWidth; 4122bde8e466a4451c7319e3a072d118917957d6554Steve Block} 4132bde8e466a4451c7319e3a072d118917957d6554Steve Block 4142bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic void updateLogicalWidthForCenterAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth) 4152bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 4162bde8e466a4451c7319e3a072d118917957d6554Steve Block float trailingSpaceWidth = 0; 4172bde8e466a4451c7319e3a072d118917957d6554Steve Block if (trailingSpaceRun) { 4182bde8e466a4451c7319e3a072d118917957d6554Steve Block totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); 4192bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingSpaceWidth = min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2); 4202bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceWidth)); 4212bde8e466a4451c7319e3a072d118917957d6554Steve Block } 4222bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isLeftToRightDirection) 4232bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalLeft += max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0); 4242bde8e466a4451c7319e3a072d118917957d6554Steve Block else 4252bde8e466a4451c7319e3a072d118917957d6554Steve Block logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth; 4262bde8e466a4451c7319e3a072d118917957d6554Steve Block} 4272bde8e466a4451c7319e3a072d118917957d6554Steve Block 4282bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, 4292bde8e466a4451c7319e3a072d118917957d6554Steve Block GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache) 4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 43181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak()); 43281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), firstLine); 43381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), firstLine) - logicalLeft; 43481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool needsWordSpacing = false; 43681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth(); 4372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned expansionOpportunityCount = 0; 4382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool isAfterExpansion = true; 4392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Vector<unsigned, 16> expansionOpportunities; 4402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderObject* previousObject = 0; 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (BidiRun* r = firstRun; r; r = r->next()) { 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!r->m_box || r->m_object->isPositioned() || r->m_box->isLineBreak()) 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; // Positioned objects are only participating to figure out their 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // correct static x position. They have no effect on the width. 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Similarly, line break boxes have no effect on the width. 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r->m_object->isText()) { 448635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderText* rt = toRenderText(r->m_object); 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (textAlign == JUSTIFY && r != trailingSpaceRun) { 4512bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!isAfterExpansion) 4522bde8e466a4451c7319e3a072d118917957d6554Steve Block static_cast<InlineTextBox*>(r->m_box)->setCanHaveLeadingExpansion(true); 4532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned opportunitiesInRun = Font::expansionOpportunityCount(rt->characters() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion); 4542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block expansionOpportunities.append(opportunitiesInRun); 4552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block expansionOpportunityCount += opportunitiesInRun; 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (int length = rt->textLength()) { 459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characters()[r->m_start])) 460a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch totalLogicalWidth += rt->style(firstLine)->font().wordSpacing(); 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length; 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian HashSet<const SimpleFontData*> fallbackFonts; 464dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GlyphOverflow glyphOverflow; 4652bde8e466a4451c7319e3a072d118917957d6554Steve Block 4662bde8e466a4451c7319e3a072d118917957d6554Steve Block // Always compute glyph overflow if the block's line-box-contain value is "glyphs". 4672bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lineBox->fitsToGlyphs()) { 4682bde8e466a4451c7319e3a072d118917957d6554Steve Block // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization 4692bde8e466a4451c7319e3a072d118917957d6554Steve Block // will keep us from computing glyph bounds in nearly all cases. 4702bde8e466a4451c7319e3a072d118917957d6554Steve Block bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); 4712bde8e466a4451c7319e3a072d118917957d6554Steve Block int baselineShift = lineBox->verticalPositionForBox(r->m_box, verticalPositionCache); 4722bde8e466a4451c7319e3a072d118917957d6554Steve Block int rootDescent = includeRootLine ? lineBox->renderer()->style(firstLine)->font().fontMetrics().descent() : 0; 4732bde8e466a4451c7319e3a072d118917957d6554Steve Block int rootAscent = includeRootLine ? lineBox->renderer()->style(firstLine)->font().fontMetrics().ascent() : 0; 4742bde8e466a4451c7319e3a072d118917957d6554Steve Block int boxAscent = rt->style(firstLine)->font().fontMetrics().ascent() - baselineShift; 4752bde8e466a4451c7319e3a072d118917957d6554Steve Block int boxDescent = rt->style(firstLine)->font().fontMetrics().descent() + baselineShift; 4762bde8e466a4451c7319e3a072d118917957d6554Steve Block if (boxAscent > rootDescent || boxDescent > rootAscent) 4772bde8e466a4451c7319e3a072d118917957d6554Steve Block glyphOverflow.computeBounds = true; 4782bde8e466a4451c7319e3a072d118917957d6554Steve Block } 4792bde8e466a4451c7319e3a072d118917957d6554Steve Block 48006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen int hyphenWidth = 0; 48106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (static_cast<InlineTextBox*>(r->m_box)->hasHyphen()) { 48206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen const AtomicString& hyphenString = rt->style()->hyphenString(); 48306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen hyphenWidth = rt->style(firstLine)->font().width(TextRun(hyphenString.characters(), hyphenString.length())); 48406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 485a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch r->m_box->setLogicalWidth(rt->width(r->m_start, r->m_stop - r->m_start, totalLogicalWidth, firstLine, &fallbackFonts, &glyphOverflow) + hyphenWidth); 48606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!fallbackFonts.isEmpty()) { 4875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(r->m_box->isText()); 4886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first; 4896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ASSERT(it->second.first.isEmpty()); 4906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen copyToVector(fallbackFonts, it->second.first); 4912bde8e466a4451c7319e3a072d118917957d6554Steve Block r->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); 4925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 49306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) { 494dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(r->m_box->isText()); 4956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first; 4966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen it->second.second = glyphOverflow; 4972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch r->m_box->clearKnownToHaveNoOverflow(); 498dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 4992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else { 5002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block isAfterExpansion = false; 5012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!r->m_object->isRenderInline()) { 5022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RenderBox* renderBox = toRenderBox(r->m_object); 5032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (renderBox->isRubyRun()) { 5042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int startOverhang; 5052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int endOverhang; 5062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderObject* nextObject = 0; 5072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (BidiRun* runWithNextObject = r->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) { 5082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!runWithNextObject->m_object->isPositioned() && !runWithNextObject->m_box->isLineBreak()) { 5092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch nextObject = runWithNextObject->m_object; 5102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 5112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch toRenderRubyRun(renderBox)->getOverhang(firstLine, renderBox->style()->isLeftToRightDirection() ? previousObject : nextObject, renderBox->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang); 5142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setMarginStartForChild(renderBox, -startOverhang); 5152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setMarginEndForChild(renderBox, -endOverhang); 5162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block r->m_box->setLogicalWidth(logicalWidthForChild(renderBox)); 5182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox); 5192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 522a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch totalLogicalWidth += r->m_box->logicalWidth(); 5232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch previousObject = r->m_object; 5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (isAfterExpansion && !expansionOpportunities.isEmpty()) { 5272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block expansionOpportunities.last()--; 5282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block expansionOpportunityCount--; 5292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 5302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Armed with the total width of the line (without justification), 5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we now examine our text-align property in order to determine where to position the 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // objects horizontally. The total width of the line can be increased if we end up 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // justifying text. 5350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch switch (textAlign) { 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case LEFT: 5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WEBKIT_LEFT: 5382bde8e466a4451c7319e3a072d118917957d6554Steve Block updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); 5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case JUSTIFY: 54181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth); 54281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (expansionOpportunityCount) { 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (trailingSpaceRun) { 544a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); 545bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen trailingSpaceRun->m_box->setLogicalWidth(0); 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // fall through 5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case TAAUTO: 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // for right to left fall through to right aligned 552a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) { 553a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) 55481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth)); 5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case RIGHT: 5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WEBKIT_RIGHT: 5592bde8e466a4451c7319e3a072d118917957d6554Steve Block updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); 5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case CENTER: 5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WEBKIT_CENTER: 5632bde8e466a4451c7319e3a072d118917957d6554Steve Block updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); 5642bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 5652bde8e466a4451c7319e3a072d118917957d6554Steve Block case TASTART: 566a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (style()->isLeftToRightDirection()) 5672bde8e466a4451c7319e3a072d118917957d6554Steve Block updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 5692bde8e466a4451c7319e3a072d118917957d6554Steve Block updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); 5702bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 5712bde8e466a4451c7319e3a072d118917957d6554Steve Block case TAEND: 5722bde8e466a4451c7319e3a072d118917957d6554Steve Block if (style()->isLeftToRightDirection()) 5732bde8e466a4451c7319e3a072d118917957d6554Steve Block updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); 5742bde8e466a4451c7319e3a072d118917957d6554Steve Block else 5752bde8e466a4451c7319e3a072d118917957d6554Steve Block updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); 5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (expansionOpportunityCount && availableLogicalWidth > totalLogicalWidth) { 5802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block size_t i = 0; 5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (BidiRun* r = firstRun; r; r = r->next()) { 5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!r->m_box || r == trailingSpaceRun) 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 585635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (r->m_object->isText()) { 5862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned opportunitiesInRun = expansionOpportunities[i++]; 5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(opportunitiesInRun <= expansionOpportunityCount); 5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Only justify text if whitespace is collapsed. 5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r->m_object->style()->collapseWhiteSpace()) { 5922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box); 59381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount; 5942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block textBox->setExpansion(expansion); 5952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block totalLogicalWidth += expansion; 5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block expansionOpportunityCount -= opportunitiesInRun; 5982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!expansionOpportunityCount) 5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The widths of all runs are now known. We can now place every inline box (and 6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // compute accurate widths for the inline flow boxes). 6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project needsWordSpacing = false; 607a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch lineBox->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing, textBoxDataMap); 6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid RenderBlock::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, 6116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner VerticalPositionCache& verticalPositionCache) 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache)); 614a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch lineBox->setBlockLogicalHeight(logicalHeight()); 6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now make sure we place replaced render objects correctly. 6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (BidiRun* r = firstRun; r; r = r->next()) { 6185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(r->m_box); 6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!r->m_box) 6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; // Skip runs with no line boxes. 6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Align positioned boxes with the top of the line box. This is 6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a reasonable approximation of an appropriate y position. 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (r->m_object->isPositioned()) 625a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch r->m_box->setLogicalTop(logicalHeight()); 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Position is used to properly position both replaced elements and 6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to update the static normal flow x/y of positioned elements. 6298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (r->m_object->isText()) 6308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderText(r->m_object)->positionLineBox(r->m_box); 6318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else if (r->m_object->isBox()) 6328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderBox(r->m_object)->positionLineBox(r->m_box); 6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Positioned objects and zero-length text nodes destroy their boxes in 6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // position(), which unnecessarily dirties the line. 6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lineBox->markDirty(false); 6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool isCollapsibleSpace(UChar character, RenderText* renderer) 6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (character == ' ' || character == '\t' || character == softHyphen) 6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (character == '\n') 6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !renderer->style()->preserveNewline(); 6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (character == noBreakSpace) 6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return renderer->style()->nbspMode() == SPACE; 6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6502bde8e466a4451c7319e3a072d118917957d6554Steve Block 6512bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic void setStaticPositions(RenderBlock* block, RenderBox* child) 6522bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 6532bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: The math here is actually not really right. It's a best-guess approximation that 6542bde8e466a4451c7319e3a072d118917957d6554Steve Block // will work for the common cases 6552bde8e466a4451c7319e3a072d118917957d6554Steve Block RenderObject* containerBlock = child->container(); 6562bde8e466a4451c7319e3a072d118917957d6554Steve Block int blockHeight = block->logicalHeight(); 6572bde8e466a4451c7319e3a072d118917957d6554Steve Block if (containerBlock->isRenderInline()) { 6582bde8e466a4451c7319e3a072d118917957d6554Steve Block // A relative positioned inline encloses us. In this case, we also have to determine our 6592bde8e466a4451c7319e3a072d118917957d6554Steve Block // position as though we were an inline. Set |staticInlinePosition| and |staticBlockPosition| on the relative positioned 6602bde8e466a4451c7319e3a072d118917957d6554Steve Block // inline so that we can obtain the value later. 6612bde8e466a4451c7319e3a072d118917957d6554Steve Block toRenderInline(containerBlock)->layer()->setStaticInlinePosition(block->startOffsetForLine(blockHeight, false)); 6622bde8e466a4451c7319e3a072d118917957d6554Steve Block toRenderInline(containerBlock)->layer()->setStaticBlockPosition(blockHeight); 6632bde8e466a4451c7319e3a072d118917957d6554Steve Block } 6642bde8e466a4451c7319e3a072d118917957d6554Steve Block 6652bde8e466a4451c7319e3a072d118917957d6554Steve Block if (child->style()->isOriginalDisplayInlineType()) 6662bde8e466a4451c7319e3a072d118917957d6554Steve Block child->layer()->setStaticInlinePosition(block->startOffsetForLine(blockHeight, false)); 6672bde8e466a4451c7319e3a072d118917957d6554Steve Block else 6682bde8e466a4451c7319e3a072d118917957d6554Steve Block child->layer()->setStaticInlinePosition(block->borderAndPaddingStart()); 6692bde8e466a4451c7319e3a072d118917957d6554Steve Block child->layer()->setStaticBlockPosition(blockHeight); 6702bde8e466a4451c7319e3a072d118917957d6554Steve Block} 6712bde8e466a4451c7319e3a072d118917957d6554Steve Block 6722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline BidiRun* RenderBlock::handleTrailingSpaces(BidiRunList<BidiRun>& bidiRuns, BidiContext* currentContext) 6732bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 6742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!bidiRuns.runCount() 6752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch || !bidiRuns.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace() 6762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch || !bidiRuns.logicallyLastRun()->m_object->style()->autoWrap()) 6772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 6782bde8e466a4451c7319e3a072d118917957d6554Steve Block 6792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch BidiRun* trailingSpaceRun = bidiRuns.logicallyLastRun(); 6802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderObject* lastObject = trailingSpaceRun->m_object; 6812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!lastObject->isText()) 6822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 6832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderText* lastText = toRenderText(lastObject); 6852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const UChar* characters = lastText->characters(); 6862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int firstSpace = trailingSpaceRun->stop(); 6872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (firstSpace > trailingSpaceRun->start()) { 6882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch UChar current = characters[firstSpace - 1]; 6892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!isCollapsibleSpace(current, lastText)) 6902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 6912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch firstSpace--; 6922bde8e466a4451c7319e3a072d118917957d6554Steve Block } 6932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (firstSpace == trailingSpaceRun->stop()) 6942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 6952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch TextDirection direction = style()->direction(); 6972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool shouldReorder = trailingSpaceRun != (direction == LTR ? bidiRuns.lastRun() : bidiRuns.firstRun()); 6982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (firstSpace != trailingSpaceRun->start()) { 6992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch BidiContext* baseContext = currentContext; 7002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (BidiContext* parent = baseContext->parent()) 7012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch baseContext = parent; 7022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch BidiRun* newTrailingRun = new (renderArena()) BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral); 7042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch trailingSpaceRun->m_stop = firstSpace; 7052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (direction == LTR) 7062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bidiRuns.addRun(newTrailingRun); 7072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch else 7082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bidiRuns.prependRun(newTrailingRun); 7092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch trailingSpaceRun = newTrailingRun; 7102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return trailingSpaceRun; 7112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!shouldReorder) 7132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return trailingSpaceRun; 7142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (direction == LTR) { 7162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bidiRuns.moveRunToEnd(trailingSpaceRun); 7172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch trailingSpaceRun->m_level = 0; 7182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 7192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bidiRuns.moveRunToBeginning(trailingSpaceRun); 7202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch trailingSpaceRun->m_level = 1; 7212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return trailingSpaceRun; 7232bde8e466a4451c7319e3a072d118917957d6554Steve Block} 7242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid RenderBlock::appendFloatingObjectToLastLine(FloatingObject* floatingObject) 7262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 72754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block ASSERT(!floatingObject->m_originatingLine); 72854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block floatingObject->m_originatingLine = lastRootBox(); 7292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lastRootBox()->appendFloat(floatingObject->renderer()); 7302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 7312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 732a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogicalTop, int& repaintLogicalBottom) 7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool useRepaintBounds = false; 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 736231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_overflow.clear(); 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 738a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(borderBefore() + paddingBefore()); 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Figure out if we should clear out our line boxes. 7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Handle resize eventually! 742d0825bca7fe65beaee391d30da42e937db621564Steve Block bool fullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren; 7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fullLayout) 7448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian lineBoxes()->deleteLineBoxes(renderArena()); 7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Text truncation only kicks in if your overflow isn't visible and your text-overflow-mode isn't 7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // clip. 7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: CSS3 says that descendants that are clipped must also know how to truncate. This is insanely 7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // difficult to figure out (especially in the middle of doing layout), and is really an esoteric pile of nonsense 7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // anyway, so we won't worry about following the draft here. 7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool hasTextOverflow = style()->textOverflow() && hasOverflowClip(); 7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Walk all the lines and delete our ellipsis line boxes if they exist. 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasTextOverflow) 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project deleteEllipsisLineBoxes(); 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (firstChild()) { 7587cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#ifdef ANDROID_LAYOUT 7598e7024d69d9885dc2d064817dae1acd41badc23fGrace Kloba // if we are in fitColumnToScreen mode 7607cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // and the current object is not float:right in LTR or not float:left in RTL, 7617cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // and text align is auto, or justify or left in LTR, or right in RTL, we 7627cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // will wrap text around screen width so that it doesn't need to scroll 7637cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // horizontally when reading a paragraph. 764ef5ff0dbc68f344b819b75af5dc5bcc7bda8f411Shimeng (Simon) Wang // In case the line height is less than the font size, we skip 765ef5ff0dbc68f344b819b75af5dc5bcc7bda8f411Shimeng (Simon) Wang // the text wrapping since this will cause text overlapping. 766c2af0ea11e14d459b597600184bf0e2a805a29aeShimeng (Simon) Wang // If a text has background image, we ignore text wrapping, 767c2af0ea11e14d459b597600184bf0e2a805a29aeShimeng (Simon) Wang // otherwise the background will be potentially messed up. 7687cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba const Settings* settings = document()->settings(); 7698e7024d69d9885dc2d064817dae1acd41badc23fGrace Kloba bool doTextWrap = settings && settings->layoutAlgorithm() == Settings::kLayoutFitColumnToScreen; 7707cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (doTextWrap) { 7717cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba int ta = style()->textAlign(); 7727cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba int dir = style()->direction(); 7737cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba bool autowrap = style()->autoWrap(); 7747cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // if the RenderBlock is positioned, don't wrap text around screen 7757cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // width as it may cause text to overlap. 7767cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba bool positioned = isPositioned(); 7777cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba EFloat cssfloat = style()->floating(); 778ef5ff0dbc68f344b819b75af5dc5bcc7bda8f411Shimeng (Simon) Wang const int lineHeight = style()->computedLineHeight(); 779ef5ff0dbc68f344b819b75af5dc5bcc7bda8f411Shimeng (Simon) Wang const int fontSize = style()->fontSize(); 780d5c8fc35c6fd034d37978ad6c4df7e0afdbb0e1bShimeng (Simon) Wang doTextWrap = autowrap && !positioned && 78121d8d81a756ca7e60b5131e5f1006f52799179b0Shimeng (Simon) Wang (fontSize <= lineHeight) && !style()->hasBackground() && 7827cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba (((dir == LTR && cssfloat != FRIGHT) || 783b62826266ccf1d6f2ede3e9735e2279e6dee5a5bShimeng (Simon) Wang (dir == RTL && cssfloat != FNONE)) && 7847cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba ((ta == TAAUTO) || (ta == JUSTIFY) || 7857cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba ((ta == LEFT || ta == WEBKIT_LEFT) && (dir == LTR)) || 7867cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba ((ta == RIGHT || ta == WEBKIT_RIGHT) && (dir == RTL)))); 7877cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 7887cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba bool hasTextToWrap = false; 7897cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#endif 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // layout replaced elements 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool endOfInline = false; 7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* o = bidiFirst(this, 0, false); 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Vector<FloatWithRect> floats; 794d0825bca7fe65beaee391d30da42e937db621564Steve Block bool hasInlineChild = false; 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (o) { 79668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!hasInlineChild && o->isInline()) 79768513a70bcd92384395513322f1b801e7bf9c729Steve Block hasInlineChild = true; 79868513a70bcd92384395513322f1b801e7bf9c729Steve Block 7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->isReplaced() || o->isFloating() || o->isPositioned()) { 800635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* box = toRenderBox(o); 801635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent()) 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project o->setChildNeedsLayout(true, false); 8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths. 806a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (relayoutChildren && (o->style()->paddingStart().isPercent() || o->style()->paddingEnd().isPercent())) 807bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen o->setPreferredLogicalWidthsDirty(true, false); 8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->isPositioned()) 810635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project o->containingBlock()->insertPositionedObject(box); 8118de7ac488df2f39f82e56811541f4847b3f2e952Steve Block#if PLATFORM(ANDROID) 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 8137cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#ifdef ANDROID_LAYOUT 8147cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // ignore text wrap for textField or menuList 8158ffb902ab85b3eb5e2fad95e38034d67e7e2e463Mangesh Ghiware if (doTextWrap && (o->isTextField() || o->isMenuList())) 8168de7ac488df2f39f82e56811541f4847b3f2e952Steve Block doTextWrap = false; 8177cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#endif 8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->isFloating()) 819635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project floats.append(FloatWithRect(box)); 8208de7ac488df2f39f82e56811541f4847b3f2e952Steve Block else if (fullLayout || o->needsLayout()) { 8218de7ac488df2f39f82e56811541f4847b3f2e952Steve Block // Replaced elements 8228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian toRenderBox(o)->dirtyLineBoxes(fullLayout); 8238de7ac488df2f39f82e56811541f4847b3f2e952Steve Block o->layoutIfNeeded(); 8248de7ac488df2f39f82e56811541f4847b3f2e952Steve Block } 8258de7ac488df2f39f82e56811541f4847b3f2e952Steve Block } 8268de7ac488df2f39f82e56811541f4847b3f2e952Steve Block#else 82768513a70bcd92384395513322f1b801e7bf9c729Steve Block else if (o->isFloating()) 82868513a70bcd92384395513322f1b801e7bf9c729Steve Block floats.append(FloatWithRect(box)); 82968513a70bcd92384395513322f1b801e7bf9c729Steve Block else if (fullLayout || o->needsLayout()) { 83068513a70bcd92384395513322f1b801e7bf9c729Steve Block // Replaced elements 83168513a70bcd92384395513322f1b801e7bf9c729Steve Block toRenderBox(o)->dirtyLineBoxes(fullLayout); 8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project o->layoutIfNeeded(); 8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8348de7ac488df2f39f82e56811541f4847b3f2e952Steve Block#endif // PLATFORM(ANDROID) 835635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (o->isText() || (o->isRenderInline() && !endOfInline)) { 8362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!o->isText()) 8372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch toRenderInline(o)->updateAlwaysCreateLineBoxes(); 8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fullLayout || o->selfNeedsLayout()) 8398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian dirtyLineBoxesForRenderer(o, fullLayout); 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project o->setNeedsLayout(false); 8417cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#ifdef ANDROID_LAYOUT 8427cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (doTextWrap && !hasTextToWrap && o->isText()) { 8437cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba Node* node = o->node(); 8447cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // as it is very common for sites to use a serial of <a> or 8457cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // <li> as tabs, we don't force text to wrap if all the text 8467cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // are short and within an <a> or <li> tag, and only separated 8477cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // by short word like "|" or ";". 8487cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (node && node->isTextNode() && 8497cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba !static_cast<Text*>(node)->containsOnlyWhitespace()) { 8507cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba int length = static_cast<Text*>(node)->length(); 8517cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // FIXME, need a magic number to decide it is too long to 8527cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // be a tab. Pick 25 for now as it covers around 160px 8537cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // (half of 320px) with the default font. 8547cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (length > 25 || (length > 3 && 855bfce793ad58f0a43e19e55c8ce237cb43a977c42Ben Murdoch (!node->parentOrHostNode()->hasTagName(HTMLNames::aTag) && 856bfce793ad58f0a43e19e55c8ce237cb43a977c42Ben Murdoch !node->parentOrHostNode()->hasTagName(HTMLNames::liTag)))) 8577cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba hasTextToWrap = true; 8587cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 8597cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 8607cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#endif 8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project o = bidiNext(this, o, 0, false, &endOfInline); 8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8657cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#ifdef ANDROID_LAYOUT 8667cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // try to make sure that inline text will not span wider than the 8677cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // screen size unless the container has a fixed height, 8687cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (doTextWrap && hasTextToWrap) { 8697cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // check all the nested containing blocks, unless it is table or 8707cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // table-cell, to make sure there is no fixed height as it implies 8717cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // fixed layout. If we constrain the text to fit screen, we may 8727cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // cause text overlap with the block after. 8737cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba bool isConstrained = false; 8747cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba RenderObject* obj = this; 8757cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba while (obj) { 8767cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (obj->style()->height().isFixed() && (!obj->isTable() && !obj->isTableCell())) { 8777cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba isConstrained = true; 8787cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba break; 8797cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 8807cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (obj->isFloating() || obj->isPositioned()) { 881bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block // floating and absolute or fixed positioning are done out 8827cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba // of normal flow. Don't need to worry about height any more. 8837cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba break; 8847cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 8857cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba obj = obj->container(); 8867cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 8877cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba if (!isConstrained) { 888c05b3a990126a5a1de357c025e25e6acd4e4e185Grace Kloba int textWrapWidth = view()->frameView()->textWrapWidth(); 889a56054997e46fcd04621cc67d650b6daf85f7b59Grace Kloba int padding = paddingLeft() + paddingRight(); 890c05b3a990126a5a1de357c025e25e6acd4e4e185Grace Kloba if (textWrapWidth > 0 && width() > (textWrapWidth + padding)) { 891a56054997e46fcd04621cc67d650b6daf85f7b59Grace Kloba // limit the content width (width excluding padding) to be 892c05b3a990126a5a1de357c025e25e6acd4e4e185Grace Kloba // (textWrapWidth - 2 * ANDROID_FCTS_MARGIN_PADDING) 893c05b3a990126a5a1de357c025e25e6acd4e4e185Grace Kloba int maxWidth = textWrapWidth - 2 * ANDROID_FCTS_MARGIN_PADDING + padding; 8947cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba setWidth(min(width(), maxWidth)); 89515196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, maxWidth); 89615196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, maxWidth); 897e0d453637f1bc58e518a60882c1bdd04ae41d353Steve Block 898ef70308a818da13f513c6e3b640d8228c99abbd0Mangesh Ghiware // if overflow isn't visible, block elements may get clipped 899ef70308a818da13f513c6e3b640d8228c99abbd0Mangesh Ghiware // due to the limited content width. disable overflow clipping. 900ef70308a818da13f513c6e3b640d8228c99abbd0Mangesh Ghiware setHasOverflowClip(false); 901ef70308a818da13f513c6e3b640d8228c99abbd0Mangesh Ghiware 902e0d453637f1bc58e518a60882c1bdd04ae41d353Steve Block IntRect overflow = layoutOverflowRect(); 903e0d453637f1bc58e518a60882c1bdd04ae41d353Steve Block if (overflow.width() > maxWidth) { 904e0d453637f1bc58e518a60882c1bdd04ae41d353Steve Block overflow.setWidth(maxWidth); 905e0d453637f1bc58e518a60882c1bdd04ae41d353Steve Block clearLayoutOverflow(); 906e0d453637f1bc58e518a60882c1bdd04ae41d353Steve Block addLayoutOverflow(overflow); 907e0d453637f1bc58e518a60882c1bdd04ae41d353Steve Block } 9087cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 9097cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 9107cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba } 9117cc8cd1a39eab64760ba9f012efd77e0ce048053Grace Kloba#endif 9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We want to skip ahead to the first dirty line 9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineBidiResolver resolver; 9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned floatIndex; 9158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool firstLine = true; 9160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool previousLineBrokeCleanly = true; 91768513a70bcd92384395513322f1b801e7bf9c729Steve Block RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, previousLineBrokeCleanly, resolver, floats, floatIndex, 918a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch useRepaintBounds, repaintLogicalTop, repaintLogicalBottom); 9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 920d0825bca7fe65beaee391d30da42e937db621564Steve Block if (fullLayout && hasInlineChild && !selfNeedsLayout()) { 9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setNeedsLayout(true, false); // Mark ourselves as needing a full layout. This way we'll repaint like 9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we're supposed to. 923635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderView* v = view(); 9248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (v && !v->doingFullRepaint() && hasLayer()) { 9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Because we waited until we were already inside layout to discover 9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // that the block really needed a full layout, we missed our chance to repaint the layer 9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // before layout started. Luckily the layer has cached the repaint rect for its original 9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // position and size, and so we can use that to make a repaint happen now. 9298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian repaintUsingContainer(containerForRepaint(), layer()->repaintRect()); 9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 93381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* lastFloat = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0; 9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LineMidpointState& lineMidpointState = resolver.midpointState(); 9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We also find the first clean line and extract these lines. We will add them back 9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if we determine that we're able to synchronize after handling all our dirty lines. 9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator cleanLineStart; 9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BidiStatus cleanLineBidiStatus; 941a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int endLineLogicalTop = 0; 9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* endLine = (fullLayout || !startLine) ? 9432bde8e466a4451c7319e3a072d118917957d6554Steve Block 0 : determineEndPosition(startLine, floats, floatIndex, cleanLineStart, cleanLineBidiStatus, endLineLogicalTop); 9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (startLine) { 94668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!useRepaintBounds) { 94768513a70bcd92384395513322f1b801e7bf9c729Steve Block useRepaintBounds = true; 948a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch repaintLogicalTop = logicalHeight(); 949a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch repaintLogicalBottom = logicalHeight(); 95068513a70bcd92384395513322f1b801e7bf9c729Steve Block } 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderArena* arena = renderArena(); 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* box = startLine; 9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (box) { 9542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalTop = min(repaintLogicalTop, box->logicalTopVisualOverflow()); 9552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalBottom = max(repaintLogicalBottom, box->logicalBottomVisualOverflow()); 9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* next = box->nextRootBox(); 9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box->deleteLine(arena); 9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project box = next; 9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator end = resolver.position(); 9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!fullLayout && lastRootBox() && lastRootBox()->endsWithBreak()) { 9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the last line before the start line ends with a line break that clear floats, 9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // adjust the height accordingly. 9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // A line break can be either the first or the last object on a line, depending on its direction. 9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) { 9698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderObject* lastObject = lastLeafChild->renderer(); 9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!lastObject->isBR()) 9718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian lastObject = lastRootBox()->firstLeafChild()->renderer(); 9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lastObject->isBR()) { 9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EClear clear = lastObject->style()->clear(); 9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (clear != CNONE) 9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newLine(clear); 9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool endLineMatched = false; 9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool checkForEndLineMatch = endLine; 9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool checkForFloatsFromLastLine = false; 9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool isLineEmpty = true; 98568513a70bcd92384395513322f1b801e7bf9c729Steve Block bool paginated = view()->layoutState() && view()->layoutState()->isPaginated(); 9860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 98781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch LineBreakIteratorInfo lineBreakIteratorInfo; 9886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner VerticalPositionCache verticalPositionCache; 9896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (!end.atEnd()) { 9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Is this check necessary before the first iteration or can it be moved to the end? 992a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop, repaintLogicalBottom, repaintLogicalTop))) 9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.reset(); 9960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isLineEmpty = true; 998635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EClear clear = CNONE; 100006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bool hyphenated; 10012bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<RenderBox*> positionedObjects; 100268513a70bcd92384395513322f1b801e7bf9c729Steve Block 100368513a70bcd92384395513322f1b801e7bf9c729Steve Block InlineIterator oldEnd = end; 100481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* lastFloatFromPreviousLine = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0; 10052bde8e466a4451c7319e3a072d118917957d6554Steve Block end = findNextLineBreak(resolver, firstLine, isLineEmpty, lineBreakIteratorInfo, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine, positionedObjects); 10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (resolver.position().atEnd()) { 10072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: We shouldn't be creating any runs in findNextLineBreak to begin with! 10082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Once BidiRunList is separated from BidiResolver this will not be needed. 10092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch resolver.runs().deleteRuns(); 10102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed). 10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkForFloatsFromLastLine = true; 10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(end != resolver.position()); 10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10162bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isLineEmpty) { 10172bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lastRootBox()) 10182bde8e466a4451c7319e3a072d118917957d6554Steve Block lastRootBox()->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status()); 10192bde8e466a4451c7319e3a072d118917957d6554Steve Block } else { 102081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch VisualDirectionOverride override = (style()->visuallyOrdered() ? (style()->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride); 10212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine. 10222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch BidiRunList<BidiRun>& bidiRuns = resolver.runs(); 102381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch resolver.createBidiRunsForLine(end, override, previousLineBrokeCleanly); 10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(resolver.position() == end); 10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch BidiRun* trailingSpaceRun = !previousLineBrokeCleanly ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0; 10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now that the runs have been ordered, we create the line boxes. 10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // At the same time we figure out where border/padding/margin should be applied for 10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // inline flow boxes. 10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* lineBox = 0; 1033a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldLogicalHeight = logicalHeight(); 10342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (bidiRuns.runCount()) { 103506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (hyphenated) 10362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bidiRuns.logicallyLastRun()->m_hasHyphen = true; 10372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lineBox = constructLine(bidiRuns, firstLine, !end.m_obj); 10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lineBox) { 10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lineBox->setEndsWithBreak(previousLineBrokeCleanly); 10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 104106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#if ENABLE(SVG) 104206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bool isSVGRootInlineBox = lineBox->isSVGRootInlineBox(); 104306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#else 104406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bool isSVGRootInlineBox = false; 104506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#endif 104606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 10476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen GlyphOverflowAndFallbackFontsMap textBoxDataMap; 10482bde8e466a4451c7319e3a072d118917957d6554Steve Block 104906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Now we position all of our text runs horizontally. 105006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!isSVGRootInlineBox) 10512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch computeInlineDirectionPositionsForLine(lineBox, firstLine, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache); 10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now position our text runs vertically. 10542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache); 10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG) 105706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // SVG text layout code computes vertical & horizontal positions on its own. 105806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Note that we still need to execute computeVerticalPositionsForLine() as 105906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // it calls InlineTextBox::positionLineBox(), which tracks whether the box 106006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // contains reversed text or not. If we wouldn't do that editing and thus 106106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // text selection in RTL boxes would not work as expected. 106206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (isSVGRootInlineBox) { 106306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen ASSERT(isSVGText()); 106406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen static_cast<SVGRootInlineBox*>(lineBox)->computePerCharacterLayoutInformation(); 106506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1068f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Compute our overflow now. 10692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxDataMap); 1070f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(MAC) 10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Highlight acts as an overflow inflation. 10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->highlight() != nullAtom) 10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lineBox->addHighlightOverflow(); 10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bidiRuns.deleteRuns(); 10802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed). 10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lineBox) { 10832bde8e466a4451c7319e3a072d118917957d6554Steve Block lineBox->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status()); 10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (useRepaintBounds) { 10852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalTop = min(repaintLogicalTop, lineBox->logicalTopVisualOverflow()); 10862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow()); 10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 108868513a70bcd92384395513322f1b801e7bf9c729Steve Block 108968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginated) { 109068513a70bcd92384395513322f1b801e7bf9c729Steve Block int adjustment = 0; 109168513a70bcd92384395513322f1b801e7bf9c729Steve Block adjustLinePositionForPagination(lineBox, adjustment); 109268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (adjustment) { 1093a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, firstLine); 10942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block lineBox->adjustBlockDirectionPosition(adjustment); 109568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (useRepaintBounds) // This can only be a positive adjustment, so no need to update repaintTop. 10962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow()); 109768513a70bcd92384395513322f1b801e7bf9c729Steve Block 1098a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, firstLine) != oldLineWidth) { 109968513a70bcd92384395513322f1b801e7bf9c729Steve Block // We have to delete this line, remove all floats that got added, and let line layout re-run. 110068513a70bcd92384395513322f1b801e7bf9c729Steve Block lineBox->deleteLine(renderArena()); 1101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); 1102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(oldLogicalHeight + adjustment); 110368513a70bcd92384395513322f1b801e7bf9c729Steve Block resolver.setPosition(oldEnd); 110468513a70bcd92384395513322f1b801e7bf9c729Steve Block end = oldEnd; 110568513a70bcd92384395513322f1b801e7bf9c729Steve Block continue; 110668513a70bcd92384395513322f1b801e7bf9c729Steve Block } 110768513a70bcd92384395513322f1b801e7bf9c729Steve Block 1108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(lineBox->blockLogicalHeight()); 110968513a70bcd92384395513322f1b801e7bf9c729Steve Block } 111068513a70bcd92384395513322f1b801e7bf9c729Steve Block } 11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11132bde8e466a4451c7319e3a072d118917957d6554Steve Block for (size_t i = 0; i < positionedObjects.size(); ++i) 11142bde8e466a4451c7319e3a072d118917957d6554Steve Block setStaticPositions(this, positionedObjects[i]); 11152bde8e466a4451c7319e3a072d118917957d6554Steve Block 11168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian firstLine = false; 11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newLine(clear); 11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_floatingObjects && lastRootBox()) { 112181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 112281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator it = floatingObjectSet.begin(); 112381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lastFloat) { 112581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat); 112681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(lastFloatIterator != end); 112781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ++lastFloatIterator; 112881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch it = lastFloatIterator; 112981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 113081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (; it != end; ++it) { 113181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* f = *it; 11322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch appendFloatingObjectToLastLine(f); 11338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(f->m_renderer == floats[floatIndex].object); 11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If a float's geometry has changed, give up on syncing with clean lines. 1135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (floats[floatIndex].rect != f->frameRect()) 11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkForEndLineMatch = false; 11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatIndex++; 11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 113981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0; 11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lineMidpointState.reset(); 11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolver.setPosition(end); 11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (endLine) { 11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (endLineMatched) { 11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Attach all the remaining lines, and then adjust their y-positions as needed. 1149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int delta = logicalHeight() - endLineLogicalTop; 11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) { 11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project line->attachLine(); 115268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginated) { 115368513a70bcd92384395513322f1b801e7bf9c729Steve Block delta -= line->paginationStrut(); 115468513a70bcd92384395513322f1b801e7bf9c729Steve Block adjustLinePositionForPagination(line, delta); 115568513a70bcd92384395513322f1b801e7bf9c729Steve Block } 11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (delta) { 11572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalTop = min(repaintLogicalTop, line->logicalTopVisualOverflow() + min(delta, 0)); 11582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalBottom = max(repaintLogicalBottom, line->logicalBottomVisualOverflow() + max(delta, 0)); 11592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block line->adjustBlockDirectionPosition(delta); 11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) { 1162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Vector<RenderBox*>::iterator end = cleanLineFloats->end(); 1163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) { 116454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block FloatingObject* floatingObject = insertFloatingObject(*f); 116554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block ASSERT(!floatingObject->m_originatingLine); 116654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block floatingObject->m_originatingLine = line; 1167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f) + delta); 11688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project positionNewFloats(); 11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(lastRootBox()->blockLogicalHeight()); 11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Delete all the remaining lines. 1175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RootInlineBox* line = endLine; 11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderArena* arena = renderArena(); 11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (line) { 11782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalTop = min(repaintLogicalTop, line->logicalTopVisualOverflow()); 11792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalBottom = max(repaintLogicalBottom, line->logicalBottomVisualOverflow()); 1180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RootInlineBox* next = line->nextRootBox(); 11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project line->deleteLine(arena); 11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project line = next; 11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_floatingObjects && (checkForFloatsFromLastLine || positionNewFloats()) && lastRootBox()) { 11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // In case we have a float on the last line, it might not be positioned up to now. 11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This has to be done before adding in the bottom border/padding, or the float will 11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // include the padding incorrectly. -dwh 1190d0825bca7fe65beaee391d30da42e937db621564Steve Block if (checkForFloatsFromLastLine) { 11912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow(); 11922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow(); 1193d0825bca7fe65beaee391d30da42e937db621564Steve Block TrailingFloatsRootInlineBox* trailingFloatsLineBox = new (renderArena()) TrailingFloatsRootInlineBox(this); 1194d0825bca7fe65beaee391d30da42e937db621564Steve Block m_lineBoxes.appendLineBox(trailingFloatsLineBox); 1195d0825bca7fe65beaee391d30da42e937db621564Steve Block trailingFloatsLineBox->setConstructed(); 11966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen GlyphOverflowAndFallbackFontsMap textBoxDataMap; 11976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner VerticalPositionCache verticalPositionCache; 11986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner trailingFloatsLineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache); 11992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int blockLogicalHeight = logicalHeight(); 12002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IntRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight); 12012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IntRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight); 12022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom()); 1203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch trailingFloatsLineBox->setBlockLogicalHeight(logicalHeight()); 1204d0825bca7fe65beaee391d30da42e937db621564Steve Block } 120581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 120681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 120781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator it = floatingObjectSet.begin(); 120881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lastFloat) { 121081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat); 121181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(lastFloatIterator != end); 121281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ++lastFloatIterator; 121381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch it = lastFloatIterator; 121481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 121581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (; it != end; ++it) 12162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch appendFloatingObjectToLastLine(*it); 121781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0; 12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch size_t floatCount = floats.size(); 12200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Floats that did not have layout did not repaint when we laid them out. They would have 12210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // painted by now if they had moved, but if they stayed at (0, 0), they still need to be 12220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // painted. 12230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (size_t i = 0; i < floatCount; ++i) { 12240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!floats[i].everHadLayout) { 12250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RenderBox* f = floats[i].object; 12260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!f->x() && !f->y() && f->checkForRepaintDuringLayout()) 12270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch f->repaint(); 12280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 12290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1232f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Expand the last line to accommodate Ruby and emphasis marks. 1233f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int lastLineAnnotationsAdjustment = 0; 1234f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (lastRootBox()) { 12354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang int lowestAllowedPosition = max(lastRootBox()->lineBottom(), logicalHeight() + paddingAfter()); 1236f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!style()->isFlippedLinesWritingMode()) 1237f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch lastLineAnnotationsAdjustment = lastRootBox()->computeUnderAnnotationAdjustment(lowestAllowedPosition); 1238f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else 1239f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotationAdjustment(lowestAllowedPosition); 12404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 1241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 12428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now add in the bottom border/padding. 1243f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + borderAfter() + paddingAfter() + scrollbarLogicalHeight()); 12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!firstLineBox() && hasLineIfEmpty()) 12462bde8e466a4451c7319e3a072d118917957d6554Steve Block setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); 12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if we have any lines that spill out of our block. If we do, then we will possibly need to 12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // truncate text. 12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasTextOverflow) 12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkLinesForTextOverflow(); 12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12542bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderBlock::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat) 12552bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 12562bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<RenderBox*>* cleanLineFloats = line->floatsPtr(); 12572bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!cleanLineFloats) 12582bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 12592bde8e466a4451c7319e3a072d118917957d6554Steve Block 12602bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<RenderBox*>::iterator end = cleanLineFloats->end(); 12612bde8e466a4451c7319e3a072d118917957d6554Steve Block for (Vector<RenderBox*>::iterator it = cleanLineFloats->begin(); it != end; ++it) { 12622bde8e466a4451c7319e3a072d118917957d6554Steve Block RenderBox* floatingBox = *it; 12632bde8e466a4451c7319e3a072d118917957d6554Steve Block floatingBox->layoutIfNeeded(); 12642bde8e466a4451c7319e3a072d118917957d6554Steve Block IntSize newSize(floatingBox->width() + floatingBox->marginLeft() + floatingBox->marginRight(), floatingBox->height() + floatingBox->marginTop() + floatingBox->marginBottom()); 12652bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(floatIndex < floats.size()); 12662bde8e466a4451c7319e3a072d118917957d6554Steve Block if (floats[floatIndex].object != floatingBox) { 12672bde8e466a4451c7319e3a072d118917957d6554Steve Block encounteredNewFloat = true; 12682bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 12692bde8e466a4451c7319e3a072d118917957d6554Steve Block } 12702bde8e466a4451c7319e3a072d118917957d6554Steve Block if (floats[floatIndex].rect.size() != newSize) { 12712bde8e466a4451c7319e3a072d118917957d6554Steve Block int floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x(); 12722bde8e466a4451c7319e3a072d118917957d6554Steve Block int floatHeight = isHorizontalWritingMode() ? max(floats[floatIndex].rect.height(), newSize.height()) 12732bde8e466a4451c7319e3a072d118917957d6554Steve Block : max(floats[floatIndex].rect.width(), newSize.width()); 12742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch floatHeight = min(floatHeight, numeric_limits<int>::max() - floatTop); 12752bde8e466a4451c7319e3a072d118917957d6554Steve Block line->markDirty(); 12762bde8e466a4451c7319e3a072d118917957d6554Steve Block markLinesDirtyInBlockRange(line->blockLogicalHeight(), floatTop + floatHeight, line); 12772bde8e466a4451c7319e3a072d118917957d6554Steve Block floats[floatIndex].rect.setSize(newSize); 12782bde8e466a4451c7319e3a072d118917957d6554Steve Block dirtiedByFloat = true; 12792bde8e466a4451c7319e3a072d118917957d6554Steve Block } 12802bde8e466a4451c7319e3a072d118917957d6554Steve Block floatIndex++; 12812bde8e466a4451c7319e3a072d118917957d6554Steve Block } 12822bde8e466a4451c7319e3a072d118917957d6554Steve Block} 12832bde8e466a4451c7319e3a072d118917957d6554Steve Block 12840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly, 128568513a70bcd92384395513322f1b801e7bf9c729Steve Block InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats, 1286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool& useRepaintBounds, int& repaintLogicalTop, int& repaintLogicalBottom) 12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* curr = 0; 12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* last = 0; 12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool dirtiedByFloat = false; 12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!fullLayout) { 129368513a70bcd92384395513322f1b801e7bf9c729Steve Block // Paginate all of the clean lines. 129468513a70bcd92384395513322f1b801e7bf9c729Steve Block bool paginated = view()->layoutState() && view()->layoutState()->isPaginated(); 129568513a70bcd92384395513322f1b801e7bf9c729Steve Block int paginationDelta = 0; 12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t floatIndex = 0; 12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) { 129868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginated) { 129968513a70bcd92384395513322f1b801e7bf9c729Steve Block paginationDelta -= curr->paginationStrut(); 130068513a70bcd92384395513322f1b801e7bf9c729Steve Block adjustLinePositionForPagination(curr, paginationDelta); 130168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (paginationDelta) { 130268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (containsFloats() || !floats.isEmpty()) { 130368513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: Do better eventually. For now if we ever shift because of pagination and floats are present just go to a full layout. 130468513a70bcd92384395513322f1b801e7bf9c729Steve Block fullLayout = true; 130568513a70bcd92384395513322f1b801e7bf9c729Steve Block break; 130668513a70bcd92384395513322f1b801e7bf9c729Steve Block } 130768513a70bcd92384395513322f1b801e7bf9c729Steve Block 130868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!useRepaintBounds) 130968513a70bcd92384395513322f1b801e7bf9c729Steve Block useRepaintBounds = true; 131068513a70bcd92384395513322f1b801e7bf9c729Steve Block 13112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalTop = min(repaintLogicalTop, curr->logicalTopVisualOverflow() + min(paginationDelta, 0)); 13122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalBottom = max(repaintLogicalBottom, curr->logicalBottomVisualOverflow() + max(paginationDelta, 0)); 13132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block curr->adjustBlockDirectionPosition(paginationDelta); 131468513a70bcd92384395513322f1b801e7bf9c729Steve Block } 131568513a70bcd92384395513322f1b801e7bf9c729Steve Block } 13162bde8e466a4451c7319e3a072d118917957d6554Steve Block 13172bde8e466a4451c7319e3a072d118917957d6554Steve Block // If a new float has been inserted before this line or before its last known float,just do a full layout. 13182bde8e466a4451c7319e3a072d118917957d6554Steve Block checkFloatsInCleanLine(curr, floats, floatIndex, fullLayout, dirtiedByFloat); 13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (dirtiedByFloat || fullLayout) 13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 13218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if a new float has been inserted after the last known float. 13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!curr && floatIndex < floats.size()) 13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fullLayout = true; 13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fullLayout) { 13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Nuke all our lines. 13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (firstRootBox()) { 13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderArena* arena = renderArena(); 13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = firstRootBox(); 13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (curr) { 13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* next = curr->nextRootBox(); 13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr->deleteLine(arena); 13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = next; 13368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!firstLineBox() && !lastLineBox()); 13388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (curr) { 13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have a dirty line. 13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (RootInlineBox* prevRootBox = curr->prevRootBox()) { 13438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have a previous line. 13448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength()))) 13458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The previous line didn't break cleanly or broke at a newline 13468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // that has been deleted, so treat it as dirty too. 13478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = prevRootBox; 13488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 13508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // No dirty lines were found. 13518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the last line didn't break cleanly, treat it as dirty. 13528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lastRootBox() && !lastRootBox()->endsWithBreak()) 13538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = lastRootBox(); 13548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we have no dirty lines, then last is just the last root box. 13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project last = curr ? curr->prevRootBox() : lastRootBox(); 13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project numCleanFloats = 0; 13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!floats.isEmpty()) { 1362a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int savedLogicalHeight = logicalHeight(); 13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Restore floats from clean lines. 13648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* line = firstRootBox(); 13658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (line != curr) { 1366635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) { 1367635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Vector<RenderBox*>::iterator end = cleanLineFloats->end(); 1368635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) { 136954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block FloatingObject* floatingObject = insertFloatingObject(*f); 137054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block ASSERT(!floatingObject->m_originatingLine); 137154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block floatingObject->m_originatingLine = line; 1372a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f)); 13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project positionNewFloats(); 13748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(floats[numCleanFloats].object == *f); 13758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project numCleanFloats++; 13768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project line = line->nextRootBox(); 13798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(savedLogicalHeight); 13818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian firstLine = !last; 13848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project previousLineBrokeCleanly = !last || last->endsWithBreak(); 13858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* startObj; 13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int pos = 0; 13888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (last) { 1389a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch setLogicalHeight(last->blockLogicalHeight()); 13908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project startObj = last->lineBreakObj(); 13918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pos = last->lineBreakPos(); 13928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolver.setStatus(last->lineBreakBidiStatus()); 13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 13942bde8e466a4451c7319e3a072d118917957d6554Steve Block bool ltr = style()->isLeftToRightDirection(); 13955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Direction direction = ltr ? LeftToRight : RightToLeft; 13965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian resolver.setLastStrongDir(direction); 13975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian resolver.setLastDir(direction); 13985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian resolver.setEorDir(direction); 13992bde8e466a4451c7319e3a072d118917957d6554Steve Block resolver.setContext(BidiContext::create(ltr ? 0 : 1, direction, style()->unicodeBidi() == Override, FromStyleOrDOM)); 14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project startObj = bidiFirst(this, &resolver); 14028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolver.setPosition(InlineIterator(this, startObj, pos)); 14058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return curr; 14078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14092bde8e466a4451c7319e3a072d118917957d6554Steve BlockRootInlineBox* RenderBlock::determineEndPosition(RootInlineBox* startLine, Vector<FloatWithRect>& floats, size_t floatIndex, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus, int& logicalTop) 14108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* last = 0; 14122bde8e466a4451c7319e3a072d118917957d6554Steve Block for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) { 14132bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!curr->isDirty()) { 14142bde8e466a4451c7319e3a072d118917957d6554Steve Block bool encounteredNewFloat = false; 14152bde8e466a4451c7319e3a072d118917957d6554Steve Block bool dirtiedByFloat = false; 14162bde8e466a4451c7319e3a072d118917957d6554Steve Block checkFloatsInCleanLine(curr, floats, floatIndex, encounteredNewFloat, dirtiedByFloat); 14172bde8e466a4451c7319e3a072d118917957d6554Steve Block if (encounteredNewFloat) 14182bde8e466a4451c7319e3a072d118917957d6554Steve Block return 0; 14198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14202bde8e466a4451c7319e3a072d118917957d6554Steve Block if (curr->isDirty()) 14212bde8e466a4451c7319e3a072d118917957d6554Steve Block last = 0; 14222bde8e466a4451c7319e3a072d118917957d6554Steve Block else if (!last) 14232bde8e466a4451c7319e3a072d118917957d6554Steve Block last = curr; 14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!last) 14278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 14288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14292bde8e466a4451c7319e3a072d118917957d6554Steve Block // At this point, |last| is the first line in a run of clean lines that ends with the last line 14302bde8e466a4451c7319e3a072d118917957d6554Steve Block // in the block. 14312bde8e466a4451c7319e3a072d118917957d6554Steve Block 14328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* prev = last->prevRootBox(); 14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos()); 14348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cleanLineBidiStatus = prev->lineBreakBidiStatus(); 1435a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch logicalTop = prev->blockLogicalHeight(); 14368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* line = last; line; line = line->nextRootBox()) 14388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project line->extractLine(); // Disconnect all line boxes from their render objects while preserving 14398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // their connections to one another. 14408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return last; 14428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1444a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool RenderBlock::matchedEndLine(const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, RootInlineBox*& endLine, 1445a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int& endLogicalTop, int& repaintLogicalBottom, int& repaintLogicalTop) 14468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (resolver.position() == endLineStart) { 14488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (resolver.status() != endLineStatus) 14498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 14508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1451a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int delta = logicalHeight() - endLogicalTop; 14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!delta || !m_floatingObjects) 14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 14548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if any floats end in the range along which we want to shift the lines vertically. 1456a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTop = min(logicalHeight(), endLogicalTop); 14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* lastLine = endLine; 14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (RootInlineBox* nextLine = lastLine->nextRootBox()) 14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastLine = nextLine; 14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1462a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalBottom = lastLine->blockLogicalHeight() + abs(delta); 14638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 146481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 146581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 146681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 146781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* f = *it; 1468a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalBottomForFloat(f) >= logicalTop && logicalBottomForFloat(f) < logicalBottom) 14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 14708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 14738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The first clean line doesn't match, but we can check a handful of following lines to try 14768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to match back up. 14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static int numLines = 8; // The # of lines we're willing to match against. 14788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* line = endLine; 14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) { 14802bde8e466a4451c7319e3a072d118917957d6554Steve Block if (line->lineBreakObj() == resolver.position().m_obj && line->lineBreakPos() == resolver.position().m_pos) { 14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have a match. 14828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (line->lineBreakBidiStatus() != resolver.status()) 14838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; // ...but the bidi state doesn't match. 14848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* result = line->nextRootBox(); 14858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1486a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Set our logical top to be the block height of endLine. 14878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result) 1488a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch endLogicalTop = line->blockLogicalHeight(); 14898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1490a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int delta = logicalHeight() - endLogicalTop; 14918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (delta && m_floatingObjects) { 14928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // See if any floats end in the range along which we want to shift the lines vertically. 1493a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalTop = min(logicalHeight(), endLogicalTop); 14948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* lastLine = endLine; 14968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (RootInlineBox* nextLine = lastLine->nextRootBox()) 14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastLine = nextLine; 14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1499a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int logicalBottom = lastLine->blockLogicalHeight() + abs(delta); 15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 150181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 150281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObjectSetIterator end = floatingObjectSet.end(); 150381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { 150481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch FloatingObject* f = *it; 1505a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (logicalBottomForFloat(f) >= logicalTop && logicalBottomForFloat(f) < logicalBottom) 15068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now delete the lines that we failed to sync. 15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* boxToDelete = endLine; 15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderArena* arena = renderArena(); 15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (boxToDelete && boxToDelete != result) { 15142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalTop = min(repaintLogicalTop, boxToDelete->logicalTopVisualOverflow()); 15152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch repaintLogicalBottom = max(repaintLogicalBottom, boxToDelete->logicalBottomVisualOverflow()); 15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RootInlineBox* next = boxToDelete->nextRootBox(); 15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boxToDelete->deleteLine(arena); 15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boxToDelete = next; 15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project endLine = result; 15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic inline bool skipNonBreakingSpace(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly) 15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15312bde8e466a4451c7319e3a072d118917957d6554Steve Block if (it.m_obj->style()->nbspMode() != SPACE || it.current() != noBreakSpace) 15328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: This is bad. It makes nbsp inconsistent with space and won't work correctly 15358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // with m_minWidth/m_maxWidth. 15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do not skip a non-breaking space if it is the first character 15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // on a line after a clean line break (or on the first line, since previousLineBrokeCleanly starts off 15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // |true|). 15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isLineEmpty && previousLineBrokeCleanly) 15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 15418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic inline bool shouldCollapseWhiteSpace(const RenderStyle* style, bool isLineEmpty, bool previousLineBrokeCleanly) 15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return style->collapseWhiteSpace() || (style->whiteSpace() == PRE_WRAP && (!isLineEmpty || !previousLineBrokeCleanly)); 15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool inlineFlowRequiresLineBox(RenderInline* flow) 15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Right now, we only allow line boxes for inlines that are truly empty. 15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to fix this, though, because at the very least, inlines containing only 15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ignorable whitespace should should also have line boxes. 1555a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return !flow->firstChild() && flow->hasInlineDirectionBordersPaddingOrMargin(); 15568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockbool RenderBlock::requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly) 15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15602bde8e466a4451c7319e3a072d118917957d6554Steve Block if (it.m_obj->isFloatingOrPositioned()) 15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15632bde8e466a4451c7319e3a072d118917957d6554Steve Block if (it.m_obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderInline(it.m_obj))) 15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15662bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!shouldCollapseWhiteSpace(it.m_obj->style(), isLineEmpty, previousLineBrokeCleanly) || it.m_obj->isBR()) 15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar current = it.current(); 15702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || it.m_obj->preservesNewline()) 15710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch && !skipNonBreakingSpace(it, isLineEmpty, previousLineBrokeCleanly); 15728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj, bool isLineEmpty, bool previousLineBrokeCleanly) 15758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(inlineObj->parent() == this); 15778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator it(this, inlineObj, 0); 15790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while (!it.atEnd() && !requiresLineBox(it, isLineEmpty, previousLineBrokeCleanly)) 15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project it.increment(); 15818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !it.atEnd(); 15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: The entire concept of the skipTrailingWhitespace function is flawed, since we really need to be building 15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// line boxes even for containers that may ultimately collapse away. Otherwise we'll never get positioned 15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// elements quite right. In other words, we need to build this function's work into the normal line 15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// object iteration process. 15898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// NB. this function will insert any floating elements that would otherwise 15908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// be skipped but it will not position them. 15910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBlock::skipTrailingWhitespace(InlineIterator& iterator, bool isLineEmpty, bool previousLineBrokeCleanly) 15928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while (!iterator.atEnd() && !requiresLineBox(iterator, isLineEmpty, previousLineBrokeCleanly)) { 15942bde8e466a4451c7319e3a072d118917957d6554Steve Block RenderObject* object = iterator.m_obj; 15958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (object->isFloating()) { 1596635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project insertFloatingObject(toRenderBox(object)); 159781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } else if (object->isPositioned()) 159881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch setStaticPositions(this, toRenderBox(object)); 15998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project iterator.increment(); 16008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool isLineEmpty, bool previousLineBrokeCleanly, 16042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch FloatingObject* lastFloatFromPreviousLine, LineWidth& width) 16058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 16060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), isLineEmpty, previousLineBrokeCleanly)) { 16072bde8e466a4451c7319e3a072d118917957d6554Steve Block RenderObject* object = resolver.position().m_obj; 16082bde8e466a4451c7319e3a072d118917957d6554Steve Block if (object->isFloating()) 16092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch positionNewFloatOnLine(insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, width); 16102bde8e466a4451c7319e3a072d118917957d6554Steve Block else if (object->isPositioned()) 161181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch setStaticPositions(this, toRenderBox(object)); 16128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolver.increment(); 16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolver.commitExplicitEmbedding(); 16158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This is currently just used for list markers and inline flows that have line boxes. Neither should 16188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// have an effect on whitespace at the start of the line. 16190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o, LineMidpointState& lineMidpointState) 16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* next = bidiNext(block, o); 1622635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (next && !next->isBR() && next->isText() && toRenderText(next)->textLength() > 0) { 1623635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderText* nextText = toRenderText(next); 16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar nextChar = nextText->characters()[0]; 16258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) { 16260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); 16278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 16288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 16328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 163481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace) 16358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 16362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (isFixedPitch || (!from && len == text->textLength()) || text->style()->hasTextCombine()) 16378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return text->width(from, len, font, xPos); 16388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return font.width(TextRun(text->characters() + from, len, !collapseWhiteSpace, xPos)); 16398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 16408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 164181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, int minimumPrefixLength, int minimumSuffixLength, int lastSpace, int pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated) 164206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 164381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // Map 'hyphenate-limit-{before,after}: auto;' to 2. 164481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (minimumPrefixLength < 0) 164581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch minimumPrefixLength = 2; 164681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 164781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (minimumSuffixLength < 0) 164881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch minimumSuffixLength = 2; 164981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 165081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (pos - lastSpace <= minimumSuffixLength) 165181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return; 165281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 165306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen const AtomicString& hyphenString = text->style()->hyphenString(); 165406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen int hyphenWidth = font.width(TextRun(hyphenString.characters(), hyphenString.length())); 165506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 165681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing; 165768513a70bcd92384395513322f1b801e7bf9c729Steve Block // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely 165868513a70bcd92384395513322f1b801e7bf9c729Steve Block // that an hyphenation opportunity exists, so do not bother to look for it. 165968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (maxPrefixWidth <= font.pixelSize() * 5 / 4) 166068513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 166168513a70bcd92384395513322f1b801e7bf9c729Steve Block 166268513a70bcd92384395513322f1b801e7bf9c729Steve Block unsigned prefixLength = font.offsetForPosition(TextRun(text->characters() + lastSpace, pos - lastSpace, !collapseWhiteSpace, xPos + lastSpaceWordSpacing), maxPrefixWidth, false); 166381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (prefixLength < static_cast<unsigned>(minimumPrefixLength)) 166406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen return; 166506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 166681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch prefixLength = lastHyphenLocation(text->characters() + lastSpace, pos - lastSpace, min(prefixLength, static_cast<unsigned>(pos - lastSpace - minimumSuffixLength)) + 1, localeIdentifier); 166781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // FIXME: The following assumes that the character at lastSpace is a space (and therefore should not factor 166881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // into hyphenate-limit-before) unless lastSpace is 0. This is wrong in the rare case of hyphenating 166981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // the first word in a text node which has leading whitespace. 16702bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!prefixLength || prefixLength - (lastSpace ? 1 : 0) < static_cast<unsigned>(minimumPrefixLength)) 167106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen return; 167206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 167381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(pos - lastSpace - prefixLength >= static_cast<unsigned>(minimumSuffixLength)); 167481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 167506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#if !ASSERT_DISABLED 167681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing; 167706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen ASSERT(xPos + prefixWidth <= availableWidth); 167806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#else 167906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen UNUSED_PARAM(isFixedPitch); 168006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#endif 168106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 16822bde8e466a4451c7319e3a072d118917957d6554Steve Block lineBreak.moveTo(text, lastSpace + prefixLength, nextBreakable); 168306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen hyphenated = true; 168406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 168506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 16862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass LineWidth { 16872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 16882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LineWidth(RenderBlock* block, bool isFirstLine) 16892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_block(block) 16902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_uncommittedWidth(0) 16912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_committedWidth(0) 16922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_overhangWidth(0) 16932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_left(0) 16942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_right(0) 16952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_availableWidth(0) 16962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_isFirstLine(isFirstLine) 16972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 16982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(block); 16992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch updateAvailableWidth(); 17002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool fitsOnLine() const { return currentWidth() <= m_availableWidth; } 17022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool fitsOnLine(float extra) const { return currentWidth() + extra <= m_availableWidth; } 17032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float currentWidth() const { return m_committedWidth + m_uncommittedWidth; } 17042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction. 17062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float uncommittedWidth() const { return m_uncommittedWidth; } 17072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float committedWidth() const { return m_committedWidth; } 17082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float availableWidth() const { return m_availableWidth; } 17092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void updateAvailableWidth(); 17112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void shrinkAvailableWidthForNewFloatIfNeeded(RenderBlock::FloatingObject*); 17122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; } 17132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void commit() 17142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 17152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_committedWidth += m_uncommittedWidth; 17162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_uncommittedWidth = 0; 17172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer); 17192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void fitBelowFloats(); 17202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 17222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void computeAvailableWidthFromLeftAndRight() 17232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 17242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_availableWidth = max(0, m_right - m_left) + m_overhangWidth; 17252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 17282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderBlock* m_block; 17292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float m_uncommittedWidth; 17302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float m_committedWidth; 17312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang. 17322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int m_left; 17332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int m_right; 17342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float m_availableWidth; 17352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool m_isFirstLine; 17362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 17372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline void LineWidth::updateAvailableWidth() 17392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int height = m_block->logicalHeight(); 17412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_left = m_block->logicalLeftOffsetForLine(height, m_isFirstLine); 17422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_right = m_block->logicalRightOffsetForLine(height, m_isFirstLine); 17432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch computeAvailableWidthFromLeftAndRight(); 17452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(RenderBlock::FloatingObject* newFloat) 17482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int height = m_block->logicalHeight(); 17502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (height < m_block->logicalTopForFloat(newFloat) || height >= m_block->logicalBottomForFloat(newFloat)) 17512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 17522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (newFloat->type() == RenderBlock::FloatingObject::FloatLeft) 17542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_left = m_block->logicalRightForFloat(newFloat); 17552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch else 17562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_right = m_block->logicalLeftForFloat(newFloat); 17572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch computeAvailableWidthFromLeftAndRight(); 17592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid LineWidth::applyOverhang(RenderRubyRun* rubyRun, RenderObject* startRenderer, RenderObject* endRenderer) 17622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int startOverhang; 17642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int endOverhang; 17652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch rubyRun->getOverhang(m_isFirstLine, startRenderer, endRenderer, startOverhang, endOverhang); 17662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch startOverhang = min<int>(startOverhang, m_committedWidth); 17682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_availableWidth += startOverhang; 17692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch endOverhang = max(min<int>(endOverhang, m_availableWidth - currentWidth()), 0); 17712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_availableWidth += endOverhang; 17722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_overhangWidth += startOverhang + endOverhang; 17732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid LineWidth::fitBelowFloats() 17762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!m_committedWidth); 17782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!fitsOnLine()); 17792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int floatLogicalBottom; 17812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int lastFloatLogicalBottom = m_block->logicalHeight(); 17822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float newLineWidth = m_availableWidth; 17832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (true) { 17842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch floatLogicalBottom = m_block->nextFloatLogicalBottomBelow(lastFloatLogicalBottom); 17852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!floatLogicalBottom) 17862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 17872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch newLineWidth = m_block->availableLogicalWidthForLine(floatLogicalBottom, m_isFirstLine); 17892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lastFloatLogicalBottom = floatLogicalBottom; 17902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (newLineWidth >= m_uncommittedWidth) 17912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 17922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (newLineWidth > m_availableWidth) { 17952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_block->setLogicalHeight(lastFloatLogicalBottom); 17962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_availableWidth = newLineWidth + m_overhangWidth; 17972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 180081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochInlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, LineBreakIteratorInfo& lineBreakIteratorInfo, bool& previousLineBrokeCleanly, 18012bde8e466a4451c7319e3a072d118917957d6554Steve Block bool& hyphenated, EClear* clear, FloatingObject* lastFloatFromPreviousLine, Vector<RenderBox*>& positionedBoxes) 18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 18032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(resolver.position().root() == this); 18048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18052bde8e466a4451c7319e3a072d118917957d6554Steve Block bool appliedStartWidth = resolver.position().m_pos > 0; 18060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LineMidpointState& lineMidpointState = resolver.midpointState(); 18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LineWidth width(this, firstLine); 18092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch skipLeadingWhitespace(resolver, isLineEmpty, previousLineBrokeCleanly, lastFloatFromPreviousLine, width); 18118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (resolver.position().atEnd()) 18138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return resolver.position(); 18148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This variable is used only if whitespace isn't set to PRE, and it tells us whether 18168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // or not we are currently ignoring whitespace. 18178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool ignoringSpaces = false; 18188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator ignoreStart; 18198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This variable tracks whether the very last character we saw was a space. We use 18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // this to detect when we encounter a second space so we know we have to terminate 18228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a run. 18238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool currentCharacterIsSpace = false; 18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool currentCharacterIsWS = false; 18258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderObject* trailingSpaceObject = 0; 18262bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<RenderBox*, 4> trailingPositionedBoxes; 18278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator lBreak = resolver.position(); 18298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18302bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: It is error-prone to split the position object out like this. 18312bde8e466a4451c7319e3a072d118917957d6554Steve Block // Teach this code to work with objects instead of this split tuple. 18322bde8e466a4451c7319e3a072d118917957d6554Steve Block RenderObject* o = resolver.position().m_obj; 183381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RenderObject* last = o; 18342bde8e466a4451c7319e3a072d118917957d6554Steve Block unsigned pos = resolver.position().m_pos; 18352bde8e466a4451c7319e3a072d118917957d6554Steve Block int nextBreakable = resolver.position().m_nextBreakablePosition; 18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool atStart = true; 18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool prevLineBrokeCleanly = previousLineBrokeCleanly; 18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project previousLineBrokeCleanly = false; 18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 184106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen hyphenated = false; 184206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 18438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool autoWrapWasEverTrueOnLine = false; 18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool floatsFitOnLine = true; 18458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Firefox and Opera will allow a table cell to grow to fit an image inside it under 18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // very specific circumstances (in order to match common WinIE renderings). 18488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.) 1849a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto(); 18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EWhiteSpace currWS = style()->whiteSpace(); 18528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EWhiteSpace lastWS = currWS; 18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (o) { 18542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderObject* next = bidiNext(this, o); 18552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currWS = o->isReplaced() ? o->parent()->style()->whiteSpace() : o->style()->whiteSpace(); 18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastWS = last->isReplaced() ? last->parent()->style()->whiteSpace() : last->style()->whiteSpace(); 18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool autoWrap = RenderStyle::autoWrap(currWS); 18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project autoWrapWasEverTrueOnLine = autoWrapWasEverTrueOnLine || autoWrap; 18618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG) 186306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bool preserveNewline = o->isSVGInlineText() ? false : RenderStyle::preserveNewline(currWS); 18648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 18658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool preserveNewline = RenderStyle::preserveNewline(currWS); 18668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 18678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool collapseWhiteSpace = RenderStyle::collapseWhiteSpace(currWS); 18698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->isBR()) { 18712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (width.fitsOnLine()) { 18722bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveToStartOf(o); 18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lBreak.increment(); 18748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // A <br> always breaks a line, so don't let the line be collapsed 18768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // away. Also, the space at the end of a line with a <br> does not 18778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // get collapsed away. It only does this if the previous line broke 18788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // cleanly. Otherwise the <br> has no effect on whether the line is 18798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // empty or not. 18808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (prevLineBrokeCleanly) 18818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isLineEmpty = false; 18828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceObject = 0; 18838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project previousLineBrokeCleanly = true; 18848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isLineEmpty && clear) 18868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *clear = o->style()->clear(); 18878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto end; 18898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->isFloatingOrPositioned()) { 18928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // add to special objects... 18938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->isFloating()) { 1894635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* floatBox = toRenderBox(o); 189568513a70bcd92384395513322f1b801e7bf9c729Steve Block FloatingObject* f = insertFloatingObject(floatBox); 18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // check if it fits in the current line. 18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If it does, position it now, otherwise, position 18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // it after moving to next line (in newLine() func) 18992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (floatsFitOnLine && width.fitsOnLine(logicalWidthForFloat(f))) { 19002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch positionNewFloatOnLine(f, lastFloatFromPreviousLine, width); 19012bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lBreak.m_obj == o) { 19022bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(!lBreak.m_pos); 19032bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.increment(); 19042bde8e466a4451c7319e3a072d118917957d6554Steve Block } 19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 19068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project floatsFitOnLine = false; 19078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (o->isPositioned()) { 19088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If our original display wasn't an inline type, then we can 190981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // go ahead and determine our static inline position now. 19108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox* box = toRenderBox(o); 19118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isInlineType = box->style()->isOriginalDisplayInlineType(); 19122bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!isInlineType) 191381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch box->layer()->setStaticInlinePosition(borderAndPaddingStart()); 19142bde8e466a4451c7319e3a072d118917957d6554Steve Block else { 19152bde8e466a4451c7319e3a072d118917957d6554Steve Block // If our original display was an INLINE type, then we can go ahead 19162bde8e466a4451c7319e3a072d118917957d6554Steve Block // and determine our static y position now. 191781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch box->layer()->setStaticBlockPosition(logicalHeight()); 19188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we're ignoring spaces, we have to stop and include this object and 19218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // then start ignoring spaces again. 19222bde8e466a4451c7319e3a072d118917957d6554Steve Block if (isInlineType || o->container()->isRenderInline()) { 19238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ignoringSpaces) { 19242bde8e466a4451c7319e3a072d118917957d6554Steve Block ignoreStart.m_obj = o; 19252bde8e466a4451c7319e3a072d118917957d6554Steve Block ignoreStart.m_pos = 0; 19260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, ignoreStart); // Stop ignoring spaces. 19270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, ignoreStart); // Start ignoring again. 19288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19292bde8e466a4451c7319e3a072d118917957d6554Steve Block if (trailingSpaceObject) 19302bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingPositionedBoxes.append(box); 19312bde8e466a4451c7319e3a072d118917957d6554Steve Block } else 19322bde8e466a4451c7319e3a072d118917957d6554Steve Block positionedBoxes.append(box); 19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1934635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (o->isRenderInline()) { 19358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Right now, we should only encounter empty inlines here. 19368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!o->firstChild()); 19378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderInline* flowBox = toRenderInline(o); 1939635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 19408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now that some inline flows have line boxes, if we are already ignoring spaces, we need 19418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to make sure that we stop to include this object and then start ignoring spaces again. 19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If this object is at the start of the line, we need to behave like list markers and 19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // start ignoring spaces. 1944635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (inlineFlowRequiresLineBox(flowBox)) { 19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isLineEmpty = false; 19468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ignoringSpaces) { 19478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceObject = 0; 19482bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingPositionedBoxes.clear(); 19490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); // Stop ignoring spaces. 19500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); // Start ignoring again. 19512bde8e466a4451c7319e3a072d118917957d6554Steve Block } else if (style()->collapseWhiteSpace() && resolver.position().m_obj == o 19520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) { 19538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Like with list markers, we start ignoring spaces to make sure that any 19548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // additional spaces we see will be discarded. 19558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsSpace = true; 19568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsWS = true; 19578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ignoringSpaces = true; 19588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox)); 19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (o->isReplaced()) { 1963635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderBox* replacedBox = toRenderBox(o); 1964635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Break on replaced elements if either has normal white-space. 19668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((autoWrap || RenderStyle::autoWrap(lastWS)) && (!o->isImage() || allowImagesToBreak)) { 19672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.commit(); 19682bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveToStartOf(o); 19698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ignoringSpaces) 19720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); 19738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isLineEmpty = false; 19758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ignoringSpaces = false; 19768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsSpace = false; 19778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsWS = false; 19788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceObject = 0; 19792bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingPositionedBoxes.clear(); 1980643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 19818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Optimize for a common case. If we can't find whitespace after the list 1982a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // item, then this is all moot. 1983a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int replacedLogicalWidth = logicalWidthForChild(replacedBox) + marginStartForChild(replacedBox) + marginEndForChild(replacedBox) + inlineLogicalWidth(o); 1984643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (o->isListMarker()) { 19850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) { 19868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Like with inline flows, we start ignoring spaces to make sure that any 19878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // additional spaces we see will be discarded. 19888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsSpace = true; 19898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsWS = true; 19908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ignoringSpaces = true; 19918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1992643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (toRenderListMarker(o)->isInside()) 19932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(replacedLogicalWidth); 19948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 19952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(replacedLogicalWidth); 19962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (o->isRubyRun()) 19972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.applyOverhang(toRenderRubyRun(o), last, next); 19988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (o->isText()) { 19998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!pos) 20008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project appliedStartWidth = false; 20018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2002635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderText* t = toRenderText(o); 20038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 200468513a70bcd92384395513322f1b801e7bf9c729Steve Block#if ENABLE(SVG) 200568513a70bcd92384395513322f1b801e7bf9c729Steve Block bool isSVGText = t->isSVGInlineText(); 200668513a70bcd92384395513322f1b801e7bf9c729Steve Block#endif 200768513a70bcd92384395513322f1b801e7bf9c729Steve Block 20082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RenderStyle* style = t->style(firstLine); 20092bde8e466a4451c7319e3a072d118917957d6554Steve Block if (style->hasTextCombine() && o->isCombineText()) 20102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block toRenderCombineText(o)->combineText(); 20112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 20128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int strlen = t->textLength(); 20138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int len = strlen - pos; 20148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* str = t->characters(); 20158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 201606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen const Font& f = style->font(); 20178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isFixedPitch = f.isFixedPitch(); 201881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch bool canHyphenate = style->hyphens() == HyphensAuto && WebCore::canHyphenate(style->locale()); 20198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int lastSpace = pos; 202181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float wordSpacing = o->style()->wordSpacing(); 202281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float lastSpaceWordSpacing = 0; 20238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2024d0825bca7fe65beaee391d30da42e937db621564Steve Block // Non-zero only when kerning is enabled, in which case we measure words with their trailing 2025d0825bca7fe65beaee391d30da42e937db621564Steve Block // space, then subtract its width. 202681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(TextRun(&space, 1)) + wordSpacing : 0; 2027d0825bca7fe65beaee391d30da42e937db621564Steve Block 20282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float wrapW = width.uncommittedWidth() + inlineLogicalWidth(o, !appliedStartWidth, true); 202981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float charWidth = 0; 20308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE; 20318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word, 20328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // which is only possible if the word is the first thing on the line, that is, if |w| is zero. 20332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool breakWords = o->style()->breakWords() && ((autoWrap && !width.committedWidth()) || currWS == PRE); 20348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool midWordBreak = false; 20358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool breakAll = o->style()->wordBreak() == BreakAllWordBreak && autoWrap; 203681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float hyphenWidth = 0; 20378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (t->isWordBreak()) { 20392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.commit(); 20402bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveToStartOf(o); 20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!len); 20428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (len) { 20458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool previousCharacterIsSpace = currentCharacterIsSpace; 20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool previousCharacterIsWS = currentCharacterIsWS; 20478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar c = str[pos]; 20488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsSpace = c == ' ' || c == '\t' || (!preserveNewline && (c == '\n')); 20498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!collapseWhiteSpace || !currentCharacterIsSpace) 20518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isLineEmpty = false; 20528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2053bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphens() != HyphensNone) { 2054bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen const AtomicString& hyphenString = style->hyphenString(); 2055bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen hyphenWidth = f.width(TextRun(hyphenString.characters(), hyphenString.length())); 20562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(hyphenWidth); 20578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2058bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 20598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool applyWordSpacing = false; 20608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsWS = currentCharacterIsSpace || (breakNBSP && c == noBreakSpace); 20628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((breakAll || breakWords) && !midWordBreak) { 20648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project wrapW += charWidth; 20652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch charWidth = textWidth(t, pos, 1, f, width.committedWidth() + wrapW, isFixedPitch, collapseWhiteSpace); 20662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch midWordBreak = width.committedWidth() + wrapW + charWidth > width.availableWidth(); 20678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 206981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (lineBreakIteratorInfo.first != t) { 207081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch lineBreakIteratorInfo.first = t; 207181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch lineBreakIteratorInfo.second.reset(str, strlen); 207281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 207381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 207481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(lineBreakIteratorInfo.second, pos, nextBreakable, breakNBSP) && (style->hyphens() != HyphensNone || (pos && str[pos - 1] != softHyphen))); 2075bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 20768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (betweenWords || midWordBreak) { 20778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool stoppedIgnoringSpaces = false; 20788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ignoringSpaces) { 20798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!currentCharacterIsSpace) { 20808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Stop ignoring spaces and begin at this 20818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // new point. 20828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ignoringSpaces = false; 20838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSpaceWordSpacing = 0; 20848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSpace = pos; // e.g., "Foo goo", don't add in any of the ignored spaces. 20850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); 20868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stoppedIgnoringSpaces = true; 20878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Just keep ignoring these spaces. 20898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pos++; 20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project len--; 20918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 20928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 209581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float additionalTmpW; 2096d0825bca7fe65beaee391d30da42e937db621564Steve Block if (wordTrailingSpaceWidth && currentCharacterIsSpace) 20972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch additionalTmpW = textWidth(t, lastSpace, pos + 1 - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace) - wordTrailingSpaceWidth + lastSpaceWordSpacing; 2098d0825bca7fe65beaee391d30da42e937db621564Steve Block else 20992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch additionalTmpW = textWidth(t, lastSpace, pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing; 21002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(additionalTmpW); 21018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!appliedStartWidth) { 21022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(inlineLogicalWidth(o, true, false)); 21038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project appliedStartWidth = true; 21048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project applyWordSpacing = wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace; 21078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!width.committedWidth() && autoWrap && !width.fitsOnLine()) 21092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.fitBelowFloats(); 21108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (autoWrap || breakWords) { 21128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we break only after white-space, consider the current character 21138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // as candidate width for this line. 21148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool lineWasTooWide = false; 21152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (width.fitsOnLine() && currentCharacterIsWS && o->style()->breakOnlyAfterWhiteSpace() && !midWordBreak) { 21162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int charWidth = textWidth(t, pos, 1, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace) + (applyWordSpacing ? wordSpacing : 0); 21178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if line is too big even without the extra space 21188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // at the end of the line. If it is not, do nothing. 21198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the line needs the extra whitespace to be too long, 21208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // then move the line break to the space and skip all 21218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // additional whitespace. 21222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!width.fitsOnLine(charWidth)) { 21238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lineWasTooWide = true; 21242bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveTo(o, pos, nextBreakable); 21250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch skipTrailingWhitespace(lBreak, isLineEmpty, previousLineBrokeCleanly); 21268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (lineWasTooWide || !width.fitsOnLine()) { 21292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (canHyphenate && !width.fitsOnLine()) { 21302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, nextBreakable, hyphenated); 213106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (hyphenated) 213206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto end; 213306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 21342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (lBreak.atTextParagraphSeparator()) { 21358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stoppedIgnoringSpaces && pos > 0) { 21368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to stop right before the newline and then start up again. 21370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop 21380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); // Start 21398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lBreak.increment(); 21418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project previousLineBrokeCleanly = true; 21428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21432bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characters()[lBreak.m_pos - 1] == softHyphen && style->hyphens() != HyphensNone) 2144bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen hyphenated = true; 21458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto end; // Didn't fit. Jump to the end. 21468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 21478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!betweenWords || (midWordBreak && !autoWrap)) 21482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(-additionalTmpW); 2149bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (hyphenWidth) { 21508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Subtract the width of the soft hyphen out since we fit on a line. 21512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(-hyphenWidth); 2152bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen hyphenWidth = 0; 2153bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 21548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (c == '\n' && preserveNewline) { 21588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stoppedIgnoringSpaces && pos > 0) { 21598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to stop right before the newline and then start up again. 21600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop 21610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); // Start 21628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21632bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveTo(o, pos, nextBreakable); 21648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lBreak.increment(); 21658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project previousLineBrokeCleanly = true; 21668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return lBreak; 21678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (autoWrap && betweenWords) { 21702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.commit(); 21718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project wrapW = 0; 21722bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveTo(o, pos, nextBreakable); 21738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Auto-wrapping text should not wrap in the middle of a word once it has had an 21748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // opportunity to break after a word. 21758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project breakWords = false; 21768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (midWordBreak) { 21798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Remember this as a breakable position in case 21808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // adding the end width forces a break. 21812bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveTo(o, pos, nextBreakable); 21828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project midWordBreak &= (breakWords || breakAll); 21838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (betweenWords) { 21868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; 21878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSpace = pos; 21888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!ignoringSpaces && o->style()->collapseWhiteSpace()) { 21918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we encounter a newline, or if we encounter a 21928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // second space, we need to go ahead and break up this 21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // run and enter a mode where we start collapsing spaces. 21948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (currentCharacterIsSpace && previousCharacterIsSpace) { 21958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ignoringSpaces = true; 21968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We just entered a mode where we are ignoring 21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // spaces. Create a midpoint to terminate the run 21998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // before the second space. 22000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, ignoreStart); 22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (ignoringSpaces) { 22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Stop ignoring spaces and begin at this 22058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // new point. 22068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ignoringSpaces = false; 22078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; 22088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastSpace = pos; // e.g., "Foo goo", don't add in any of the ignored spaces. 22090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); 22108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(SVG) 22132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (isSVGText && pos > 0) { 22142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Force creation of new InlineBoxes for each absolute positioned character (those that start new text chunks). 22152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (static_cast<RenderSVGInlineText*>(t)->characterStartsNewTextChunk(pos)) { 22162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); 22172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); 22182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 22212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (currentCharacterIsSpace && !previousCharacterIsSpace) { 22232bde8e466a4451c7319e3a072d118917957d6554Steve Block ignoreStart.m_obj = o; 22242bde8e466a4451c7319e3a072d118917957d6554Steve Block ignoreStart.m_pos = pos; 22258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!currentCharacterIsWS && previousCharacterIsWS) { 22282bde8e466a4451c7319e3a072d118917957d6554Steve Block if (autoWrap && o->style()->breakOnlyAfterWhiteSpace()) 22292bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveTo(o, pos, nextBreakable); 22308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (collapseWhiteSpace && currentCharacterIsSpace && !ignoringSpaces) 22338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceObject = o; 22342bde8e466a4451c7319e3a072d118917957d6554Steve Block else if (!o->style()->collapseWhiteSpace() || !currentCharacterIsSpace) { 22358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceObject = 0; 22362bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingPositionedBoxes.clear(); 22372bde8e466a4451c7319e3a072d118917957d6554Steve Block } 22388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pos++; 22408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project len--; 22418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project atStart = false; 22428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // IMPORTANT: pos is > length here! 22452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing; 22462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(o, !appliedStartWidth, true)); 224706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 22482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!width.fitsOnLine()) { 22492bde8e466a4451c7319e3a072d118917957d6554Steve Block if (canHyphenate) 22502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, nextBreakable, hyphenated); 22512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22522bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!hyphenated && lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characters()[lBreak.m_pos - 1] == softHyphen && style->hyphens() != HyphensNone) 22532bde8e466a4451c7319e3a072d118917957d6554Steve Block hyphenated = true; 22542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 225506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (hyphenated) 225606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto end; 225706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 22588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 22598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_NOT_REACHED(); 22608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool checkForBreak = autoWrap; 22622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (width.committedWidth() && !width.fitsOnLine() && lBreak.m_obj && currWS == NOWRAP) 22638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkForBreak = true; 22648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (next && o->isText() && next->isText() && !next->isBR()) { 22658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (autoWrap || (next->style()->autoWrap())) { 22668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (currentCharacterIsSpace) 22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkForBreak = true; 22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 22698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkForBreak = false; 2270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderText* nextText = toRenderText(next); 22718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nextText->textLength()) { 22728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar c = nextText->characters()[0]; 22732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (c == ' ' || c == '\t' || (c == '\n' && !next->preservesNewline())) 22748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the next item on the line is text, and if we did not end with 22758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // a space, then the next text run continues our word (and so it needs to 22768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // keep adding to |tmpW|. Just update and continue. 22778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkForBreak = true; 22788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (nextText->isWordBreak()) 22798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkForBreak = true; 22802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!width.fitsOnLine() && !width.committedWidth()) 22822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.fitBelowFloats(); 22832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool canPlaceOnLine = width.fitsOnLine() || !autoWrapWasEverTrueOnLine; 22858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (canPlaceOnLine && checkForBreak) { 22862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.commit(); 22872bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveToStartOf(next); 22888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (checkForBreak && !width.fitsOnLine()) { 22948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if we have floats, try to get below them. 22952bde8e466a4451c7319e3a072d118917957d6554Steve Block if (currentCharacterIsSpace && !ignoringSpaces && o->style()->collapseWhiteSpace()) { 22968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project trailingSpaceObject = 0; 22972bde8e466a4451c7319e3a072d118917957d6554Steve Block trailingPositionedBoxes.clear(); 22982bde8e466a4451c7319e3a072d118917957d6554Steve Block } 22998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (width.committedWidth()) 23018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto end; 23028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.fitBelowFloats(); 23048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // |width| may have been adjusted because we got shoved down past a float (thus 23068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // giving us more room), so we need to retest, and only jump to 23078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the end label if we still don't fit on the line. -dwh 23082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!width.fitsOnLine()) 23098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto end; 23108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!o->isFloatingOrPositioned()) { 23138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project last = o; 23140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (last->isReplaced() && autoWrap && (!last->isImage() || allowImagesToBreak) && (!last->isListMarker() || toRenderListMarker(last)->isInside())) { 23152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.commit(); 23162bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveToStartOf(next); 23178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project o = next; 23218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project nextBreakable = -1; 23228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Clear out our character space bool, since inline <pre>s don't collapse whitespace 23248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // with adjacent inline normal/nowrap spans. 23258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!collapseWhiteSpace) 23268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currentCharacterIsSpace = false; 23278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pos = 0; 23298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project atStart = false; 23308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (width.fitsOnLine() || lastWS == NOWRAP) 23332bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.clear(); 23348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project end: 23362bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lBreak == resolver.position() && (!lBreak.m_obj || !lBreak.m_obj->isBR())) { 23378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // we just add as much as possible 23388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (style()->whiteSpace() == PRE) { 23398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Don't really understand this case. 23408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pos != 0) { 23412bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: This should call moveTo which would clear m_nextBreakablePosition 23422bde8e466a4451c7319e3a072d118917957d6554Steve Block // this code as-is is likely wrong. 23432bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.m_obj = o; 23442bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.m_pos = pos - 1; 23452bde8e466a4451c7319e3a072d118917957d6554Steve Block } else 23462bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveTo(last, last->isText() ? last->length() : 0); 23472bde8e466a4451c7319e3a072d118917957d6554Steve Block } else if (lBreak.m_obj) { 23488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // Don't ever break in the middle of a word if we can help it. 23498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // There's no room at all. We just have to be on this line, 23508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // even though we'll spill out. 23512bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.moveTo(o, pos); 23528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // make sure we consume at least one char/object. 23568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (lBreak == resolver.position()) 23578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lBreak.increment(); 23588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Sanity check our midpoints. 23600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch checkMidpoints(lineMidpointState, lBreak); 23618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (trailingSpaceObject) { 23638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This object is either going to be part of the last midpoint, or it is going 23648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to be the actual endpoint. In both cases we just decrease our pos by 1 level to 23658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // exclude the space, allowing it to - in effect - collapse into the newline. 23660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (lineMidpointState.numMidpoints % 2) { 23672bde8e466a4451c7319e3a072d118917957d6554Steve Block // Find the trailing space object's midpoint. 23682bde8e466a4451c7319e3a072d118917957d6554Steve Block int trailingSpaceMidpoint = lineMidpointState.numMidpoints - 1; 23692bde8e466a4451c7319e3a072d118917957d6554Steve Block for ( ; trailingSpaceMidpoint >= 0 && lineMidpointState.midpoints[trailingSpaceMidpoint].m_obj != trailingSpaceObject; --trailingSpaceMidpoint) { } 23702bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(trailingSpaceMidpoint >= 0); 23712bde8e466a4451c7319e3a072d118917957d6554Steve Block lineMidpointState.midpoints[trailingSpaceMidpoint].m_pos--; 23722bde8e466a4451c7319e3a072d118917957d6554Steve Block 23732bde8e466a4451c7319e3a072d118917957d6554Steve Block // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts 23742bde8e466a4451c7319e3a072d118917957d6554Steve Block // ignoring spaces. 23752bde8e466a4451c7319e3a072d118917957d6554Steve Block size_t currentMidpoint = trailingSpaceMidpoint + 1; 23762bde8e466a4451c7319e3a072d118917957d6554Steve Block for (size_t i = 0; i < trailingPositionedBoxes.size(); ++i) { 23772bde8e466a4451c7319e3a072d118917957d6554Steve Block if (currentMidpoint >= lineMidpointState.numMidpoints) { 23782bde8e466a4451c7319e3a072d118917957d6554Steve Block // We don't have a midpoint for this box yet. 23792bde8e466a4451c7319e3a072d118917957d6554Steve Block InlineIterator ignoreStart(this, trailingPositionedBoxes[i], 0); 23802bde8e466a4451c7319e3a072d118917957d6554Steve Block addMidpoint(lineMidpointState, ignoreStart); // Stop ignoring. 23812bde8e466a4451c7319e3a072d118917957d6554Steve Block addMidpoint(lineMidpointState, ignoreStart); // Start ignoring again. 23822bde8e466a4451c7319e3a072d118917957d6554Steve Block } else { 23832bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(lineMidpointState.midpoints[currentMidpoint].m_obj == trailingPositionedBoxes[i]); 23842bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(lineMidpointState.midpoints[currentMidpoint + 1].m_obj == trailingPositionedBoxes[i]); 23852bde8e466a4451c7319e3a072d118917957d6554Steve Block } 23862bde8e466a4451c7319e3a072d118917957d6554Steve Block currentMidpoint += 2; 23872bde8e466a4451c7319e3a072d118917957d6554Steve Block } 23882bde8e466a4451c7319e3a072d118917957d6554Steve Block } else if (!lBreak.m_obj && trailingSpaceObject->isText()) { 23898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add a new end midpoint that stops right at the very end. 2390635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RenderText* text = toRenderText(trailingSpaceObject); 23918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = text->textLength(); 23928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned pos = length >= 2 ? length - 2 : UINT_MAX; 23938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project InlineIterator endMid(0, trailingSpaceObject, pos); 23940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch addMidpoint(lineMidpointState, endMid); 23952bde8e466a4451c7319e3a072d118917957d6554Steve Block for (size_t i = 0; i < trailingPositionedBoxes.size(); ++i) { 23962bde8e466a4451c7319e3a072d118917957d6554Steve Block ignoreStart.m_obj = trailingPositionedBoxes[i]; 23972bde8e466a4451c7319e3a072d118917957d6554Steve Block ignoreStart.m_pos = 0; 23982bde8e466a4451c7319e3a072d118917957d6554Steve Block addMidpoint(lineMidpointState, ignoreStart); // Stop ignoring spaces. 23992bde8e466a4451c7319e3a072d118917957d6554Steve Block addMidpoint(lineMidpointState, ignoreStart); // Start ignoring again. 24002bde8e466a4451c7319e3a072d118917957d6554Steve Block } 24018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We might have made lBreak an iterator that points past the end 24058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // of the object. Do this adjustment to make it point to the start 24068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // of the next object instead to avoid confusing the rest of the 24078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // code. 24082bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lBreak.m_pos > 0) { 24092bde8e466a4451c7319e3a072d118917957d6554Steve Block lBreak.m_pos--; 24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lBreak.increment(); 24118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return lBreak; 24148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 24158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2416231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBlock::addOverflowFromInlineChildren() 24178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2418f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int endPadding = hasOverflowClip() ? paddingEnd() : 0; 2419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to. 24202bde8e466a4451c7319e3a072d118917957d6554Steve Block if (hasOverflowClip() && !endPadding && node() && node()->rendererIsEditable() && node() == node()->rootEditableElement() && style()->isLeftToRightDirection()) 2421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch endPadding = 1; 24228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 2423f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding)); 2424231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!hasOverflowClip()) 24252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch addVisualOverflow(curr->visualOverflowRect(curr->lineTop(), curr->lineBottom())); 24268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 24288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::deleteEllipsisLineBoxes() 24308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 24318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) 24328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr->clearTruncation(); 24338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 24348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBlock::checkLinesForTextOverflow() 24368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 24378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Determine the width of the ellipsis using the current font. 24388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: CSS3 says this is configurable, also need to use 0x002E (FULL STOP) if horizontal ellipsis is "not renderable" 24398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project TextRun ellipsisRun(&horizontalEllipsis, 1); 2440635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1)); 24418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const Font& firstLineFont = firstLineStyle()->font(); 24428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const Font& font = style()->font(); 24438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int firstLineEllipsisWidth = firstLineFont.width(ellipsisRun); 24448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(ellipsisRun); 24458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For LTR text truncation, we want to get the right edge of our padding box, and then we want to see 24478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if the right edge of a line box exceeds that. For RTL, we use the left edge of the padding box and 24488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // check the left edge of the line box to see if it is less 24498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Include the scrollbar for overflow blocks, which means we want to use "contentWidth()" 2450a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool ltr = style()->isLeftToRightDirection(); 24518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 2452bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int blockRightEdge = logicalRightOffsetForLine(curr->y(), curr == firstRootBox()); 2453bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int blockLeftEdge = logicalLeftOffsetForLine(curr->y(), curr == firstRootBox()); 2454bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int lineBoxEdge = ltr ? curr->x() + curr->logicalWidth() : curr->x(); 24555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((ltr && lineBoxEdge > blockRightEdge) || (!ltr && lineBoxEdge < blockLeftEdge)) { 24568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This line spills out of our box in the appropriate direction. Now we need to see if the line 24578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // can be truncated. In order for truncation to be possible, the line must have sufficient space to 24588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // accommodate our truncation string, and no replaced elements (images, tables) can overlap the ellipsis 24598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // space. 24608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int width = curr == firstRootBox() ? firstLineEllipsisWidth : ellipsisWidth; 24615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int blockEdge = ltr ? blockRightEdge : blockLeftEdge; 246281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (curr->lineCanAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)) 24635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge, blockRightEdge, width); 24648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 24678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineWidth& width) 24692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 24702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!positionNewFloats()) 24712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 24722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.shrinkAvailableWidthForNewFloatIfNeeded(newFloat); 24742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!newFloat->m_paginationStrut) 24762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 24772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 24792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(floatingObjectSet.last() == newFloat); 24802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int floatLogicalTop = logicalTopForFloat(newFloat); 24822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int paginationStrut = newFloat->m_paginationStrut; 24832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (floatLogicalTop - paginationStrut != logicalHeight()) 24852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 24862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch FloatingObjectSetIterator it = floatingObjectSet.end(); 24882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch --it; // Last float is newFloat, skip that one. 24892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch FloatingObjectSetIterator begin = floatingObjectSet.begin(); 24902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (it != begin) { 24912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch --it; 24922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch FloatingObject* f = *it; 24932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (f == lastFloatFromPreviousLine) 24942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 24952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (logicalTopForFloat(f) == logicalHeight()) { 24962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!f->m_paginationStrut); 24972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch f->m_paginationStrut = paginationStrut; 24982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RenderBox* o = f->m_renderer; 24992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setLogicalTopForChild(o, logicalTopForChild(o) + marginBeforeForChild(o) + paginationStrut); 25002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (o->isRenderBlock()) 25012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch toRenderBlock(o)->setChildNeedsLayout(true, false); 25022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch o->layoutIfNeeded(); 25032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setLogicalTopForFloat(f, logicalTopForFloat(f) + f->m_paginationStrut); 25042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setLogicalHeight(logicalHeight() + paginationStrut); 25082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch width.updateAvailableWidth(); 25092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 25112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 25122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2514