Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(559)

Side by Side Diff: sky/engine/core/rendering/RenderParagraph.cpp

Issue 1068683002: Delete RenderBlockFlow. (Closed) Base URL: https://github.com/domokit/mojo.git@block
Patch Set: Remove unused float-related code instead of moving it. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/core/rendering/RenderParagraph.h ('k') | sky/engine/core/rendering/RenderView.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sky/engine/config.h" 5 #include "sky/engine/config.h"
6 #include "sky/engine/core/rendering/RenderParagraph.h" 6 #include "sky/engine/core/rendering/RenderParagraph.h"
7 7
8 #include "sky/engine/core/rendering/BidiRunForLine.h" 8 #include "sky/engine/core/rendering/BidiRunForLine.h"
9 #include "sky/engine/core/rendering/InlineIterator.h" 9 #include "sky/engine/core/rendering/InlineIterator.h"
10 #include "sky/engine/core/rendering/RenderLayer.h" 10 #include "sky/engine/core/rendering/RenderLayer.h"
11 #include "sky/engine/core/rendering/RenderObjectInlines.h" 11 #include "sky/engine/core/rendering/RenderObjectInlines.h"
12 #include "sky/engine/core/rendering/RenderView.h" 12 #include "sky/engine/core/rendering/RenderView.h"
13 #include "sky/engine/core/rendering/TextRunConstructor.h" 13 #include "sky/engine/core/rendering/TextRunConstructor.h"
14 #include "sky/engine/core/rendering/TrailingFloatsRootInlineBox.h"
15 #include "sky/engine/core/rendering/VerticalPositionCache.h" 14 #include "sky/engine/core/rendering/VerticalPositionCache.h"
16 #include "sky/engine/core/rendering/line/BreakingContextInlineHeaders.h" 15 #include "sky/engine/core/rendering/line/BreakingContextInlineHeaders.h"
17 #include "sky/engine/core/rendering/line/LineLayoutState.h" 16 #include "sky/engine/core/rendering/line/LineLayoutState.h"
18 #include "sky/engine/core/rendering/line/LineWidth.h" 17 #include "sky/engine/core/rendering/line/LineWidth.h"
19 #include "sky/engine/core/rendering/line/RenderTextInfo.h" 18 #include "sky/engine/core/rendering/line/RenderTextInfo.h"
20 #include "sky/engine/core/rendering/line/WordMeasurement.h" 19 #include "sky/engine/core/rendering/line/WordMeasurement.h"
21 #include "sky/engine/platform/fonts/Character.h" 20 #include "sky/engine/platform/fonts/Character.h"
22 #include "sky/engine/platform/text/BidiResolver.h" 21 #include "sky/engine/platform/text/BidiResolver.h"
23 #include "sky/engine/wtf/RefCountedLeakCounter.h" 22 #include "sky/engine/wtf/RefCountedLeakCounter.h"
24 #include "sky/engine/wtf/StdLibExtras.h" 23 #include "sky/engine/wtf/StdLibExtras.h"
25 #include "sky/engine/wtf/Vector.h" 24 #include "sky/engine/wtf/Vector.h"
26 #include "sky/engine/wtf/unicode/CharacterNames.h" 25 #include "sky/engine/wtf/unicode/CharacterNames.h"
27 26
28 27
29 namespace blink { 28 namespace blink {
30 29
31 using namespace WTF::Unicode; 30 using namespace WTF::Unicode;
32 31
33 RenderParagraph::RenderParagraph(ContainerNode* node) 32 RenderParagraph::RenderParagraph(ContainerNode* node)
34 : RenderBlockFlow(node) 33 : RenderBlock(node)
35 { 34 {
36 } 35 }
37 36
38 RenderParagraph::~RenderParagraph() 37 RenderParagraph::~RenderParagraph()
39 { 38 {
40 } 39 }
41 40
42 const char* RenderParagraph::renderName() const 41 const char* RenderParagraph::renderName() const
43 { 42 {
44 if (isAnonymous()) 43 if (isAnonymous())
45 return "RenderParagraph (anonymous)"; 44 return "RenderParagraph (anonymous)";
46 return "RenderParagraph"; 45 return "RenderParagraph";
47 } 46 }
48 47
49 RenderParagraph* RenderParagraph::createAnonymous(Document& document) 48 RenderParagraph* RenderParagraph::createAnonymous(Document& document)
50 { 49 {
51 RenderParagraph* renderer = new RenderParagraph(0); 50 RenderParagraph* renderer = new RenderParagraph(0);
52 renderer->setDocumentForAnonymous(&document); 51 renderer->setDocumentForAnonymous(&document);
53 return renderer; 52 return renderer;
54 } 53 }
55 54
55 LayoutUnit RenderParagraph::logicalLeftSelectionOffset(RenderBlock* rootBlock, L ayoutUnit position)
56 {
57 LayoutUnit logicalLeft = logicalLeftOffsetForLine(false);
58 if (logicalLeft == logicalLeftOffsetForContent())
59 return RenderBlock::logicalLeftSelectionOffset(rootBlock, position);
60
61 RenderBlock* cb = this;
62 while (cb != rootBlock) {
63 logicalLeft += cb->logicalLeft();
64 cb = cb->containingBlock();
65 }
66 return logicalLeft;
67 }
68
69 LayoutUnit RenderParagraph::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
70 {
71 LayoutUnit logicalRight = logicalRightOffsetForLine(false);
72 if (logicalRight == logicalRightOffsetForContent())
73 return RenderBlock::logicalRightSelectionOffset(rootBlock, position);
74
75 RenderBlock* cb = this;
76 while (cb != rootBlock) {
77 logicalRight += cb->logicalLeft();
78 cb = cb->containingBlock();
79 }
80 return logicalRight;
81 }
82
56 RootInlineBox* RenderParagraph::lineAtIndex(int i) const 83 RootInlineBox* RenderParagraph::lineAtIndex(int i) const
57 { 84 {
58 ASSERT(i >= 0); 85 ASSERT(i >= 0);
59 86
60 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) { 87 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
61 if (!i--) 88 if (!i--)
62 return box; 89 return box;
63 } 90 }
64 91
65 return 0; 92 return 0;
66 } 93 }
67 94
68 int RenderParagraph::lineCount(const RootInlineBox* stopRootInlineBox, bool* fou nd) const 95 int RenderParagraph::lineCount(const RootInlineBox* stopRootInlineBox, bool* fou nd) const
69 { 96 {
70 int count = 0; 97 int count = 0;
71 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) { 98 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
72 count++; 99 count++;
73 if (box == stopRootInlineBox) { 100 if (box == stopRootInlineBox) {
74 if (found) 101 if (found)
75 *found = true; 102 *found = true;
76 break; 103 break;
77 } 104 }
78 } 105 }
79 106
80 return count; 107 return count;
81 } 108 }
82 109
110 void RenderParagraph::deleteLineBoxTree()
111 {
112 m_lineBoxes.deleteLineBoxTree();
113 }
114
83 GapRects RenderParagraph::inlineSelectionGaps(RenderBlock* rootBlock, const Layo utPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 115 GapRects RenderParagraph::inlineSelectionGaps(RenderBlock* rootBlock, const Layo utPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
84 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLog icalRight, const PaintInfo* paintInfo) 116 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLog icalRight, const PaintInfo* paintInfo)
85 { 117 {
86 GapRects result; 118 GapRects result;
87 119
88 bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth; 120 bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
89 121
90 if (!firstLineBox()) { 122 if (!firstLineBox()) {
91 if (containsStart) { 123 if (containsStart) {
92 // Go ahead and update our lastLogicalTop to be the bottom of the bl ock. <hr>s or empty blocks with height can trip this 124 // Go ahead and update our lastLogicalTop to be the bottom of the bl ock. <hr>s or empty blocks with height can trip this
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 afterLowest = lowestDirtyLine; 236 afterLowest = lowestDirtyLine;
205 lowestDirtyLine = lowestDirtyLine->prevRootBox(); 237 lowestDirtyLine = lowestDirtyLine->prevRootBox();
206 } 238 }
207 239
208 while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWith Leading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) { 240 while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWith Leading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
209 afterLowest->markDirty(); 241 afterLowest->markDirty();
210 afterLowest = afterLowest->prevRootBox(); 242 afterLowest = afterLowest->prevRootBox();
211 } 243 }
212 } 244 }
213 245
214 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo otLineBox, bool isOnlyRun = false) 246 static void updateLogicalWidthForLeftAlignedBlock(bool isLeftToRightDirection, B idiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float av ailableLogicalWidth)
247 {
248 // The direction of the block should determine what happens with wide lines.
249 // In particular with RTL blocks, wide lines should still spill out to the l eft.
250 if (isLeftToRightDirection) {
251 if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
252 trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailing SpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
253 return;
254 }
255
256 if (trailingSpaceRun)
257 trailingSpaceRun->m_box->setLogicalWidth(0);
258 else if (totalLogicalWidth > availableLogicalWidth)
259 logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
260 }
261
262 static void updateLogicalWidthForRightAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float a vailableLogicalWidth)
263 {
264 // Wide lines spill out of the block based off direction.
265 // So even if text-align is right, if direction is LTR, wide lines should ov erflow out of the right
266 // side of the block.
267 if (isLeftToRightDirection) {
268 if (trailingSpaceRun) {
269 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
270 trailingSpaceRun->m_box->setLogicalWidth(0);
271 }
272 if (totalLogicalWidth < availableLogicalWidth)
273 logicalLeft += availableLogicalWidth - totalLogicalWidth;
274 return;
275 }
276
277 if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
278 trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpac eRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
279 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
280 } else
281 logicalLeft += availableLogicalWidth - totalLogicalWidth;
282 }
283
284 static void updateLogicalWidthForCenterAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
285 {
286 float trailingSpaceWidth = 0;
287 if (trailingSpaceRun) {
288 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
289 trailingSpaceWidth = std::min(trailingSpaceRun->m_box->logicalWidth(), ( availableLogicalWidth - totalLogicalWidth + 1) / 2);
290 trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpac eWidth));
291 }
292 if (isLeftToRightDirection)
293 logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidt h) / 2, 0);
294 else
295 logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLog icalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
296 }
297
298 void RenderParagraph::updateLogicalWidthForAlignment(const ETextAlign& textAlign , const RootInlineBox* rootInlineBox, BidiRun* trailingSpaceRun, float& logicalL eft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionO pportunityCount)
299 {
300 TextDirection direction;
301 if (rootInlineBox && rootInlineBox->renderer().style()->unicodeBidi() == Pla intext)
302 direction = rootInlineBox->direction();
303 else
304 direction = style()->direction();
305
306 // Armed with the total width of the line (without justification),
307 // we now examine our text-align property in order to determine where to pos ition the
308 // objects horizontally. The total width of the line can be increased if we end up
309 // justifying text.
310 switch (textAlign) {
311 case LEFT:
312 updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
313 break;
314 case RIGHT:
315 updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection() , trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
316 break;
317 case CENTER:
318 updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection( ), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
319 break;
320 case JUSTIFY:
321 adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
322 if (expansionOpportunityCount) {
323 if (trailingSpaceRun) {
324 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
325 trailingSpaceRun->m_box->setLogicalWidth(0);
326 }
327 break;
328 }
329 // Fall through
330 case TASTART:
331 if (direction == LTR)
332 updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirectio n(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
333 else
334 updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirecti on(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
335 break;
336 case TAEND:
337 if (direction == LTR)
338 updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirecti on(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
339 else
340 updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirectio n(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
341 break;
342 }
343 }
344
345 RootInlineBox* RenderParagraph::createAndAppendRootInlineBox()
346 {
347 RootInlineBox* rootBox = createRootInlineBox();
348 m_lineBoxes.appendLineBox(rootBox);
349 return rootBox;
350 }
351
352 RootInlineBox* RenderParagraph::createRootInlineBox()
353 {
354 return new RootInlineBox(*this);
355 }
356
357 InlineBox* RenderParagraph::createInlineBoxForRenderer(RenderObject* obj, bool i sRootLineBox, bool isOnlyRun)
215 { 358 {
216 if (isRootLineBox) 359 if (isRootLineBox)
217 return toRenderBlockFlow(obj)->createAndAppendRootInlineBox(); 360 return toRenderParagraph(obj)->createAndAppendRootInlineBox();
218 361
219 if (obj->isText()) { 362 if (obj->isText()) {
220 InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox(); 363 InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
221 // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode 364 // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
222 // (Note the use of strict mode. In "almost strict" mode, we don't trea t the box for <br> as text.) 365 // (Note the use of strict mode. In "almost strict" mode, we don't trea t the box for <br> as text.)
223 return textBox; 366 return textBox;
224 } 367 }
225 368
226 if (obj->isBox()) 369 if (obj->isBox())
227 return toRenderBox(obj)->createInlineBox(); 370 return toRenderBox(obj)->createInlineBox();
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 920
778 WordMeasurements wordMeasurements; 921 WordMeasurements wordMeasurements;
779 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, 922 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo,
780 lastFloatFromPreviousLine, wordMeasurements); 923 lastFloatFromPreviousLine, wordMeasurements);
781 renderTextInfo.m_lineBreakIterator.resetPriorContext(); 924 renderTextInfo.m_lineBreakIterator.resetPriorContext();
782 if (resolver.position().atEnd()) { 925 if (resolver.position().atEnd()) {
783 // FIXME: We shouldn't be creating any runs in nextLineBreak to begi n with! 926 // FIXME: We shouldn't be creating any runs in nextLineBreak to begi n with!
784 // Once BidiRunList is separated from BidiResolver this will not be needed. 927 // Once BidiRunList is separated from BidiResolver this will not be needed.
785 resolver.runs().deleteRuns(); 928 resolver.runs().deleteRuns();
786 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed). 929 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed).
787 layoutState.setCheckForFloatsFromLastLine(true);
788 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0); 930 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0);
789 break; 931 break;
790 } 932 }
791 933
792 ASSERT(endOfLine != resolver.position()); 934 ASSERT(endOfLine != resolver.position());
793 935
794 // This is a short-cut for empty lines. 936 // This is a short-cut for empty lines.
795 if (layoutState.lineInfo().isEmpty()) { 937 if (layoutState.lineInfo().isEmpty()) {
796 if (lastRootBox()) 938 if (lastRootBox())
797 lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.of fset(), resolver.status()); 939 lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.of fset(), resolver.status());
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics(); 1377 const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
1236 return fontMetrics.ascent() 1378 return fontMetrics.ascent()
1237 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f ontMetrics.height()) / 2 1379 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f ontMetrics.height()) / 2
1238 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : b orderRight() + paddingRight()); 1380 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : b orderRight() + paddingRight());
1239 } 1381 }
1240 if (lastLineBox()) 1382 if (lastLineBox())
1241 return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox ())->fontMetrics().ascent(lastRootBox()->baselineType()); 1383 return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox ())->fontMetrics().ascent(lastRootBox()->baselineType());
1242 return -1; 1384 return -1;
1243 } 1385 }
1244 1386
1387 void RenderParagraph::layout()
1388 {
1389 ASSERT(needsLayout());
1390 ASSERT(isInlineBlock() || !isInline());
1391
1392 if (simplifiedLayout())
1393 return;
1394
1395 SubtreeLayoutScope layoutScope(*this);
1396
1397 LayoutUnit oldLeft = logicalLeft();
1398 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth();
1399 bool relayoutChildren = logicalWidthChanged;
1400
1401 LayoutUnit beforeEdge = borderBefore() + paddingBefore();
1402 LayoutUnit afterEdge = borderAfter() + paddingAfter();
1403 LayoutUnit previousHeight = logicalHeight();
1404 setLogicalHeight(beforeEdge);
1405
1406 layoutChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge);
1407
1408 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
1409
1410 updateLogicalHeight();
1411
1412 if (previousHeight != logicalHeight())
1413 relayoutChildren = true;
1414
1415 layoutPositionedObjects(relayoutChildren, oldLeft != logicalLeft() ? ForcedL ayoutAfterContainingBlockMoved : DefaultLayout);
1416
1417 // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1418 computeOverflow(oldClientAfterEdge);
1419
1420 updateLayerTransformAfterLayout();
1421
1422 clearNeedsLayout();
1423 }
1424
1245 void RenderParagraph::layoutChildren(bool relayoutChildren, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge) 1425 void RenderParagraph::layoutChildren(bool relayoutChildren, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge)
1246 { 1426 {
1247 // Figure out if we should clear out our line boxes. 1427 // Figure out if we should clear out our line boxes.
1248 // FIXME: Handle resize eventually! 1428 // FIXME: Handle resize eventually!
1249 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren ; 1429 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren ;
1250 LineLayoutState layoutState(isFullLayout); 1430 LineLayoutState layoutState(isFullLayout);
1251 1431
1252 if (isFullLayout) 1432 if (isFullLayout)
1253 lineBoxes()->deleteLineBoxes(); 1433 lineBoxes()->deleteLineBoxes();
1254 1434
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 1500
1321 if (!firstLineBox() && hasLineIfEmpty()) 1501 if (!firstLineBox() && hasLineIfEmpty())
1322 setLogicalHeight(logicalHeight() + lineHeight(true, HorizontalLine, Posi tionOfInteriorLineBoxes)); 1502 setLogicalHeight(logicalHeight() + lineHeight(true, HorizontalLine, Posi tionOfInteriorLineBoxes));
1323 1503
1324 // See if we have any lines that spill out of our block. If we do, then we will possibly need to 1504 // See if we have any lines that spill out of our block. If we do, then we will possibly need to
1325 // truncate text. 1505 // truncate text.
1326 if (hasTextOverflow) 1506 if (hasTextOverflow)
1327 checkLinesForTextOverflow(); 1507 checkLinesForTextOverflow();
1328 } 1508 }
1329 1509
1330 void RenderParagraph::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWi thRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByF loat)
1331 {
1332 Vector<RenderBox*>* cleanLineFloats = line->floatsPtr();
1333 if (!cleanLineFloats)
1334 return;
1335
1336 Vector<RenderBox*>::iterator end = cleanLineFloats->end();
1337 for (Vector<RenderBox*>::iterator it = cleanLineFloats->begin(); it != end; ++it) {
1338 RenderBox* floatingBox = *it;
1339 floatingBox->layoutIfNeeded();
1340 LayoutSize newSize(floatingBox->width() + floatingBox->marginWidth(), fl oatingBox->height() + floatingBox->marginHeight());
1341 if (floats[floatIndex].object != floatingBox) {
1342 encounteredNewFloat = true;
1343 return;
1344 }
1345
1346 if (floats[floatIndex].rect.size() != newSize) {
1347 LayoutUnit floatTop = floats[floatIndex].rect.y();
1348 LayoutUnit floatHeight = std::max(floats[floatIndex].rect.height(), newSize.height());
1349 floatHeight = std::min(floatHeight, LayoutUnit::max() - floatTop);
1350 line->markDirty();
1351 markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop + floatHeight, line);
1352 floats[floatIndex].rect.setSize(newSize);
1353 dirtiedByFloat = true;
1354 }
1355 floatIndex++;
1356 }
1357 }
1358
1359 RootInlineBox* RenderParagraph::determineStartPosition(LineLayoutState& layoutSt ate, InlineBidiResolver& resolver) 1510 RootInlineBox* RenderParagraph::determineStartPosition(LineLayoutState& layoutSt ate, InlineBidiResolver& resolver)
1360 { 1511 {
1361 RootInlineBox* curr = 0; 1512 RootInlineBox* curr = 0;
1362 RootInlineBox* last = 0; 1513 RootInlineBox* last = 0;
1363 1514
1364 // FIXME: This entire float-checking block needs to be broken into a new fun ction.
1365 bool dirtiedByFloat = false;
1366 if (!layoutState.isFullLayout()) {
1367 size_t floatIndex = 0;
1368 for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextR ootBox()) {
1369 // If a new float has been inserted before this line or before its l ast known float, just do a full layout.
1370 bool encounteredNewFloat = false;
1371 checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encou nteredNewFloat, dirtiedByFloat);
1372 if (encounteredNewFloat)
1373 layoutState.markForFullLayout();
1374
1375 if (dirtiedByFloat || layoutState.isFullLayout())
1376 break;
1377 }
1378 // Check if a new float has been inserted after the last known float.
1379 if (!curr && floatIndex < layoutState.floats().size())
1380 layoutState.markForFullLayout();
1381 }
1382
1383 if (layoutState.isFullLayout()) { 1515 if (layoutState.isFullLayout()) {
1384 // If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations. 1516 // If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations.
1385 if (layoutState.hasInlineChild() && !selfNeedsLayout()) { 1517 if (layoutState.hasInlineChild() && !selfNeedsLayout()) {
1386 setNeedsLayout(MarkOnlyThis); 1518 setNeedsLayout(MarkOnlyThis);
1387 } 1519 }
1388 1520
1389 // FIXME: This should just call deleteLineBoxTree, but that causes 1521 // FIXME: This should just call deleteLineBoxTree, but that causes
1390 // crashes for fast/repaint tests. 1522 // crashes for fast/repaint tests.
1391 curr = firstRootBox(); 1523 curr = firstRootBox();
1392 while (curr) { 1524 while (curr) {
1393 // Note: This uses nextRootBox() insted of nextLineBox() like delete LineBoxTree does. 1525 // Note: This uses nextRootBox() insted of nextLineBox() like delete LineBoxTree does.
1394 RootInlineBox* next = curr->nextRootBox(); 1526 RootInlineBox* next = curr->nextRootBox();
1395 curr->deleteLine(); 1527 curr->deleteLine();
1396 curr = next; 1528 curr = next;
1397 } 1529 }
1398 ASSERT(!firstLineBox() && !lastLineBox()); 1530 ASSERT(!firstLineBox() && !lastLineBox());
1399 } else { 1531 } else {
1400 if (curr) { 1532 if (curr) {
1401 // We have a dirty line. 1533 // We have a dirty line.
1402 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { 1534 if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
1403 // We have a previous line. 1535 // We have a previous line.
1404 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRo otBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox-> lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength()))) 1536 if (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj( ) || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= to RenderText(prevRootBox->lineBreakObj())->textLength()))
1405 // The previous line didn't break cleanly or broke at a newl ine 1537 // The previous line didn't break cleanly or broke at a newl ine
1406 // that has been deleted, so treat it as dirty too. 1538 // that has been deleted, so treat it as dirty too.
1407 curr = prevRootBox; 1539 curr = prevRootBox;
1408 } 1540 }
1409 } else { 1541 } else {
1410 // No dirty lines were found. 1542 // No dirty lines were found.
1411 // If the last line didn't break cleanly, treat it as dirty. 1543 // If the last line didn't break cleanly, treat it as dirty.
1412 if (lastRootBox() && !lastRootBox()->endsWithBreak()) 1544 if (lastRootBox() && !lastRootBox()->endsWithBreak())
1413 curr = lastRootBox(); 1545 curr = lastRootBox();
1414 } 1546 }
(...skipping 17 matching lines...) Expand all
1432 resolver.setStatus(BidiStatus(direction, isOverride(style()->unicodeBidi ()))); 1564 resolver.setStatus(BidiStatus(direction, isOverride(style()->unicodeBidi ())));
1433 InlineIterator iter = InlineIterator(this, bidiFirstSkippingEmptyInlines (this, resolver.runs(), &resolver), 0); 1565 InlineIterator iter = InlineIterator(this, bidiFirstSkippingEmptyInlines (this, resolver.runs(), &resolver), 0);
1434 resolver.setPosition(iter, numberOfIsolateAncestors(iter)); 1566 resolver.setPosition(iter, numberOfIsolateAncestors(iter));
1435 } 1567 }
1436 return curr; 1568 return curr;
1437 } 1569 }
1438 1570
1439 void RenderParagraph::determineEndPosition(LineLayoutState& layoutState, RootInl ineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStat us) 1571 void RenderParagraph::determineEndPosition(LineLayoutState& layoutState, RootInl ineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStat us)
1440 { 1572 {
1441 ASSERT(!layoutState.endLine()); 1573 ASSERT(!layoutState.endLine());
1442 size_t floatIndex = layoutState.floatIndex();
1443 RootInlineBox* last = 0; 1574 RootInlineBox* last = 0;
1444 for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->next RootBox()) { 1575 for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->next RootBox()) {
1445 if (!curr->isDirty()) {
1446 bool encounteredNewFloat = false;
1447 bool dirtiedByFloat = false;
1448 checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encou nteredNewFloat, dirtiedByFloat);
1449 if (encounteredNewFloat)
1450 return;
1451 }
1452 if (curr->isDirty()) 1576 if (curr->isDirty())
1453 last = 0; 1577 last = 0;
1454 else if (!last) 1578 else if (!last)
1455 last = curr; 1579 last = curr;
1456 } 1580 }
1457 1581
1458 if (!last) 1582 if (!last)
1459 return; 1583 return;
1460 1584
1461 // At this point, |last| is the first line in a run of clean lines that ends with the last line 1585 // At this point, |last| is the first line in a run of clean lines that ends with the last line
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1581 curr->adjustLogicalPosition(logicalLeft, 0); 1705 curr->adjustLogicalPosition(logicalLeft, 0);
1582 else 1706 else
1583 curr->adjustLogicalPosition(logicalLeft - (availableLogicalW idth - totalLogicalWidth), 0); 1707 curr->adjustLogicalPosition(logicalLeft - (availableLogicalW idth - totalLogicalWidth), 0);
1584 } 1708 }
1585 } 1709 }
1586 firstLine = false; 1710 firstLine = false;
1587 } 1711 }
1588 } 1712 }
1589 1713
1590 } // namespace blink 1714 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/rendering/RenderParagraph.h ('k') | sky/engine/core/rendering/RenderView.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698