diff options
Diffstat (limited to 'WebCore/rendering/RenderBlockLineLayout.cpp')
-rw-r--r-- | WebCore/rendering/RenderBlockLineLayout.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp index e0d712c..c76d963 100644 --- a/WebCore/rendering/RenderBlockLineLayout.cpp +++ b/WebCore/rendering/RenderBlockLineLayout.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2000 Lars Knoll (knoll@kde.org) - * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009 Apple Inc. All right reserved. + * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,6 +30,7 @@ #include "RenderInline.h" #include "RenderListMarker.h" #include "RenderView.h" +#include "TrailingFloatsRootInlineBox.h" #include "break_lines.h" #include <wtf/AlwaysInline.h> #include <wtf/RefCountedLeakCounter.h> @@ -830,7 +832,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i // Figure out if we should clear out our line boxes. // FIXME: Handle resize eventually! - bool fullLayout = !firstLineBox() || !firstChild() || selfNeedsLayout() || relayoutChildren; + bool fullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren; if (fullLayout) lineBoxes()->deleteLineBoxes(renderArena()); @@ -882,6 +884,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i bool endOfInline = false; RenderObject* o = bidiFirst(this, 0, false); Vector<FloatWithRect> floats; + bool hasInlineChild = false; while (o) { if (o->isReplaced() || o->isFloating() || o->isPositioned()) { RenderBox* box = toRenderBox(o); @@ -909,6 +912,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i o->layoutIfNeeded(); } } else if (o->isText() || (o->isRenderInline() && !endOfInline)) { + hasInlineChild = true; if (fullLayout || o->selfNeedsLayout()) dirtyLineBoxesForRenderer(o, fullLayout); o->setNeedsLayout(false); @@ -988,7 +992,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i bool previousLineBrokeCleanly = true; RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, previousLineBrokeCleanly, resolver, floats, floatIndex); - if (fullLayout && !selfNeedsLayout()) { + if (fullLayout && hasInlineChild && !selfNeedsLayout()) { setNeedsLayout(true, false); // Mark ourselves as needing a full layout. This way we'll repaint like // we're supposed to. RenderView* v = view(); @@ -1229,6 +1233,16 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i // In case we have a float on the last line, it might not be positioned up to now. // This has to be done before adding in the bottom border/padding, or the float will // include the padding incorrectly. -dwh + if (checkForFloatsFromLastLine) { + int bottomVisualOverflow = lastRootBox()->bottomVisualOverflow(); + int bottomLayoutOverflow = lastRootBox()->bottomLayoutOverflow(); + TrailingFloatsRootInlineBox* trailingFloatsLineBox = new (renderArena()) TrailingFloatsRootInlineBox(this); + m_lineBoxes.appendLineBox(trailingFloatsLineBox); + trailingFloatsLineBox->setConstructed(); + trailingFloatsLineBox->verticallyAlignBoxes(height()); + trailingFloatsLineBox->setVerticalOverflowPositions(height(), bottomLayoutOverflow, height(), bottomVisualOverflow, 0); + trailingFloatsLineBox->setBlockHeight(height()); + } if (lastFloat) { for (FloatingObject* f = m_floatingObjects->last(); f != lastFloat; f = m_floatingObjects->prev()) { } @@ -1291,7 +1305,7 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLa if (floats[floatIndex].rect.size() != newSize) { int floatTop = floats[floatIndex].rect.y(); curr->markDirty(); - markLinesDirtyInVerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height())); + markLinesDirtyInVerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()), curr); floats[floatIndex].rect.setSize(newSize); dirtiedByFloat = true; } @@ -1908,6 +1922,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool int wordSpacing = o->style()->wordSpacing(); int lastSpaceWordSpacing = 0; + // Non-zero only when kerning is enabled, in which case we measure words with their trailing + // space, then subtract its width. + int wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.spaceWidth() + wordSpacing : 0; + int wrapW = tmpW + inlineWidth(o, !appliedStartWidth, true); int charWidth = 0; bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE; @@ -2002,7 +2020,11 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool } } - int additionalTmpW = textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing; + int additionalTmpW; + if (wordTrailingSpaceWidth && currentCharacterIsSpace) + additionalTmpW = textWidth(t, lastSpace, pos + 1 - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) - wordTrailingSpaceWidth + lastSpaceWordSpacing; + else + additionalTmpW = textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing; tmpW += additionalTmpW; if (!appliedStartWidth) { tmpW += inlineWidth(o, true, false); @@ -2034,7 +2056,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool } } if (lineWasTooWide || w + tmpW > width) { - if (lBreak.obj && shouldPreserveNewline(lBreak.obj) && lBreak.obj->isText() && !toRenderText(lBreak.obj)->isWordBreak() && toRenderText(lBreak.obj)->characters()[lBreak.pos] == '\n') { + if (lBreak.obj && shouldPreserveNewline(lBreak.obj) && lBreak.obj->isText() && toRenderText(lBreak.obj)->textLength() && !toRenderText(lBreak.obj)->isWordBreak() && toRenderText(lBreak.obj)->characters()[lBreak.pos] == '\n') { if (!stoppedIgnoringSpaces && pos > 0) { // We need to stop right before the newline and then start up again. addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop |