| Index: sky/engine/core/rendering/RenderParagraph.cpp
|
| diff --git a/sky/engine/core/rendering/RenderParagraph.cpp b/sky/engine/core/rendering/RenderParagraph.cpp
|
| index a427e45631aaf1f12c7142ba732c404d628a7607..7fe459ebf8f16b0c3418ba427a4a945fc5246824 100644
|
| --- a/sky/engine/core/rendering/RenderParagraph.cpp
|
| +++ b/sky/engine/core/rendering/RenderParagraph.cpp
|
| @@ -11,7 +11,6 @@
|
| #include "sky/engine/core/rendering/RenderObjectInlines.h"
|
| #include "sky/engine/core/rendering/RenderView.h"
|
| #include "sky/engine/core/rendering/TextRunConstructor.h"
|
| -#include "sky/engine/core/rendering/TrailingFloatsRootInlineBox.h"
|
| #include "sky/engine/core/rendering/VerticalPositionCache.h"
|
| #include "sky/engine/core/rendering/line/BreakingContextInlineHeaders.h"
|
| #include "sky/engine/core/rendering/line/LineLayoutState.h"
|
| @@ -31,7 +30,7 @@ namespace blink {
|
| using namespace WTF::Unicode;
|
|
|
| RenderParagraph::RenderParagraph(ContainerNode* node)
|
| - : RenderBlockFlow(node)
|
| + : RenderBlock(node)
|
| {
|
| }
|
|
|
| @@ -53,6 +52,34 @@ RenderParagraph* RenderParagraph::createAnonymous(Document& document)
|
| return renderer;
|
| }
|
|
|
| +LayoutUnit RenderParagraph::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
|
| +{
|
| + LayoutUnit logicalLeft = logicalLeftOffsetForLine(false);
|
| + if (logicalLeft == logicalLeftOffsetForContent())
|
| + return RenderBlock::logicalLeftSelectionOffset(rootBlock, position);
|
| +
|
| + RenderBlock* cb = this;
|
| + while (cb != rootBlock) {
|
| + logicalLeft += cb->logicalLeft();
|
| + cb = cb->containingBlock();
|
| + }
|
| + return logicalLeft;
|
| +}
|
| +
|
| +LayoutUnit RenderParagraph::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
|
| +{
|
| + LayoutUnit logicalRight = logicalRightOffsetForLine(false);
|
| + if (logicalRight == logicalRightOffsetForContent())
|
| + return RenderBlock::logicalRightSelectionOffset(rootBlock, position);
|
| +
|
| + RenderBlock* cb = this;
|
| + while (cb != rootBlock) {
|
| + logicalRight += cb->logicalLeft();
|
| + cb = cb->containingBlock();
|
| + }
|
| + return logicalRight;
|
| +}
|
| +
|
| RootInlineBox* RenderParagraph::lineAtIndex(int i) const
|
| {
|
| ASSERT(i >= 0);
|
| @@ -80,6 +107,11 @@ int RenderParagraph::lineCount(const RootInlineBox* stopRootInlineBox, bool* fou
|
| return count;
|
| }
|
|
|
| +void RenderParagraph::deleteLineBoxTree()
|
| +{
|
| + m_lineBoxes.deleteLineBoxTree();
|
| +}
|
| +
|
| GapRects RenderParagraph::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
|
| LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
|
| {
|
| @@ -211,10 +243,121 @@ void RenderParagraph::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUn
|
| }
|
| }
|
|
|
| -static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
|
| +static void updateLogicalWidthForLeftAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
|
| +{
|
| + // The direction of the block should determine what happens with wide lines.
|
| + // In particular with RTL blocks, wide lines should still spill out to the left.
|
| + if (isLeftToRightDirection) {
|
| + if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
|
| + trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
|
| + return;
|
| + }
|
| +
|
| + if (trailingSpaceRun)
|
| + trailingSpaceRun->m_box->setLogicalWidth(0);
|
| + else if (totalLogicalWidth > availableLogicalWidth)
|
| + logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
|
| +}
|
| +
|
| +static void updateLogicalWidthForRightAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
|
| +{
|
| + // Wide lines spill out of the block based off direction.
|
| + // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right
|
| + // side of the block.
|
| + if (isLeftToRightDirection) {
|
| + if (trailingSpaceRun) {
|
| + totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
|
| + trailingSpaceRun->m_box->setLogicalWidth(0);
|
| + }
|
| + if (totalLogicalWidth < availableLogicalWidth)
|
| + logicalLeft += availableLogicalWidth - totalLogicalWidth;
|
| + return;
|
| + }
|
| +
|
| + if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
|
| + trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
|
| + totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
|
| + } else
|
| + logicalLeft += availableLogicalWidth - totalLogicalWidth;
|
| +}
|
| +
|
| +static void updateLogicalWidthForCenterAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
|
| +{
|
| + float trailingSpaceWidth = 0;
|
| + if (trailingSpaceRun) {
|
| + totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
|
| + trailingSpaceWidth = std::min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
|
| + trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpaceWidth));
|
| + }
|
| + if (isLeftToRightDirection)
|
| + logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0);
|
| + else
|
| + logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
|
| +}
|
| +
|
| +void RenderParagraph::updateLogicalWidthForAlignment(const ETextAlign& textAlign, const RootInlineBox* rootInlineBox, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount)
|
| +{
|
| + TextDirection direction;
|
| + if (rootInlineBox && rootInlineBox->renderer().style()->unicodeBidi() == Plaintext)
|
| + direction = rootInlineBox->direction();
|
| + else
|
| + direction = style()->direction();
|
| +
|
| + // Armed with the total width of the line (without justification),
|
| + // we now examine our text-align property in order to determine where to position the
|
| + // objects horizontally. The total width of the line can be increased if we end up
|
| + // justifying text.
|
| + switch (textAlign) {
|
| + case LEFT:
|
| + updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
|
| + break;
|
| + case RIGHT:
|
| + updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
|
| + break;
|
| + case CENTER:
|
| + updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
|
| + break;
|
| + case JUSTIFY:
|
| + adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
|
| + if (expansionOpportunityCount) {
|
| + if (trailingSpaceRun) {
|
| + totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
|
| + trailingSpaceRun->m_box->setLogicalWidth(0);
|
| + }
|
| + break;
|
| + }
|
| + // Fall through
|
| + case TASTART:
|
| + if (direction == LTR)
|
| + updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
|
| + else
|
| + updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
|
| + break;
|
| + case TAEND:
|
| + if (direction == LTR)
|
| + updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
|
| + else
|
| + updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
|
| + break;
|
| + }
|
| +}
|
| +
|
| +RootInlineBox* RenderParagraph::createAndAppendRootInlineBox()
|
| +{
|
| + RootInlineBox* rootBox = createRootInlineBox();
|
| + m_lineBoxes.appendLineBox(rootBox);
|
| + return rootBox;
|
| +}
|
| +
|
| +RootInlineBox* RenderParagraph::createRootInlineBox()
|
| +{
|
| + return new RootInlineBox(*this);
|
| +}
|
| +
|
| +InlineBox* RenderParagraph::createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun)
|
| {
|
| if (isRootLineBox)
|
| - return toRenderBlockFlow(obj)->createAndAppendRootInlineBox();
|
| + return toRenderParagraph(obj)->createAndAppendRootInlineBox();
|
|
|
| if (obj->isText()) {
|
| InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
|
| @@ -1242,6 +1385,44 @@ int RenderParagraph::lastLineBoxBaseline(LineDirectionMode lineDirection) const
|
| return -1;
|
| }
|
|
|
| +void RenderParagraph::layout()
|
| +{
|
| + ASSERT(needsLayout());
|
| + ASSERT(isInlineBlock() || !isInline());
|
| +
|
| + if (simplifiedLayout())
|
| + return;
|
| +
|
| + SubtreeLayoutScope layoutScope(*this);
|
| +
|
| + LayoutUnit oldLeft = logicalLeft();
|
| + bool logicalWidthChanged = updateLogicalWidthAndColumnWidth();
|
| + bool relayoutChildren = logicalWidthChanged;
|
| +
|
| + LayoutUnit beforeEdge = borderBefore() + paddingBefore();
|
| + LayoutUnit afterEdge = borderAfter() + paddingAfter();
|
| + LayoutUnit previousHeight = logicalHeight();
|
| + setLogicalHeight(beforeEdge);
|
| +
|
| + layoutChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge);
|
| +
|
| + LayoutUnit oldClientAfterEdge = clientLogicalBottom();
|
| +
|
| + updateLogicalHeight();
|
| +
|
| + if (previousHeight != logicalHeight())
|
| + relayoutChildren = true;
|
| +
|
| + layoutPositionedObjects(relayoutChildren, oldLeft != logicalLeft() ? ForcedLayoutAfterContainingBlockMoved : DefaultLayout);
|
| +
|
| + // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
|
| + computeOverflow(oldClientAfterEdge);
|
| +
|
| + updateLayerTransformAfterLayout();
|
| +
|
| + clearNeedsLayout();
|
| +}
|
| +
|
| void RenderParagraph::layoutChildren(bool relayoutChildren, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge)
|
| {
|
| // Figure out if we should clear out our line boxes.
|
|
|