mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Delete RenderBlockFlow.
We only ever create RenderParagraphs now. The only non-trivial change here is making RenderView a RenderFlexibleBox. This required changing custom.sky. That test was written in a fragile way that behaved differently if we did multiple layouts. Instead, having it be less racy and only change values during the test itself. This also throws a wrench in moving all the layout code to dart because we can't set the layout manager on the RenderView. Maybe we need to explicitly let you do so. R=eseidel@chromium.org Review URL: https://codereview.chromium.org/1068683002
This commit is contained in:
parent
cb473bbf48
commit
b9df2edb7d
@ -892,8 +892,6 @@ sky_core_files = [
|
||||
"rendering/PointerEventsHitRules.h",
|
||||
"rendering/RenderBlock.cpp",
|
||||
"rendering/RenderBlock.h",
|
||||
"rendering/RenderBlockFlow.cpp",
|
||||
"rendering/RenderBlockFlow.h",
|
||||
"rendering/RenderBox.cpp",
|
||||
"rendering/RenderBox.h",
|
||||
"rendering/RenderBoxModelObject.cpp",
|
||||
@ -1013,7 +1011,6 @@ sky_core_files = [
|
||||
"rendering/SubtreeLayoutScope.h",
|
||||
"rendering/TextRunConstructor.cpp",
|
||||
"rendering/TextRunConstructor.h",
|
||||
"rendering/TrailingFloatsRootInlineBox.h",
|
||||
"rendering/VerticalPositionCache.h",
|
||||
"script/dart_controller.cc",
|
||||
"script/dart_controller.h",
|
||||
|
||||
@ -172,7 +172,6 @@ void StyleResolver::matchRules(Element& element, ElementRuleCollector& collector
|
||||
PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document)
|
||||
{
|
||||
RefPtr<RenderStyle> documentStyle = RenderStyle::create();
|
||||
documentStyle->setDisplay(FLEX);
|
||||
documentStyle->setRTLOrdering(LogicalOrder);
|
||||
documentStyle->setLocale(document.contentLanguage());
|
||||
documentStyle->setZIndex(0);
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
#include "sky/engine/core/rendering/InlineTextBox.h"
|
||||
#include "sky/engine/core/rendering/RenderBlock.h"
|
||||
#include "sky/engine/core/rendering/RenderInline.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
#include "sky/engine/core/rendering/RenderText.h"
|
||||
#include "sky/engine/platform/Logging.h"
|
||||
#include "sky/engine/wtf/text/CString.h"
|
||||
@ -802,8 +803,8 @@ bool Position::isCandidate() const
|
||||
if (editingIgnoresContent(deprecatedNode()))
|
||||
return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
|
||||
|
||||
if (renderer->isRenderBlockFlow()) {
|
||||
if (toRenderBlock(renderer)->logicalHeight()) {
|
||||
if (renderer->isRenderParagraph()) {
|
||||
if (toRenderParagraph(renderer)->logicalHeight()) {
|
||||
if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
|
||||
return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
|
||||
return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
|
||||
@ -1003,7 +1004,7 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi
|
||||
|
||||
if (!renderer->isText()) {
|
||||
inlineBox = 0;
|
||||
if (canHaveChildrenForEditing(deprecatedNode()) && renderer->isRenderBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
|
||||
if (canHaveChildrenForEditing(deprecatedNode()) && renderer->isRenderParagraph() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
|
||||
// Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
|
||||
// an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
|
||||
// of RenderObject::createVisiblePosition().
|
||||
@ -1151,7 +1152,7 @@ TextDirection Position::primaryDirection() const
|
||||
{
|
||||
TextDirection primaryDirection = LTR;
|
||||
for (const RenderObject* r = m_anchorNode->renderer(); r; r = r->parent()) {
|
||||
if (r->isRenderBlockFlow()) {
|
||||
if (r->isRenderParagraph()) {
|
||||
primaryDirection = r->style()->direction();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
#include "sky/engine/core/editing/htmlediting.h"
|
||||
#include "sky/engine/core/rendering/RenderBlock.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@ -149,8 +150,8 @@ bool PositionIterator::isCandidate() const
|
||||
if (editingIgnoresContent(m_anchorNode))
|
||||
return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
|
||||
|
||||
if (renderer->isRenderBlockFlow()) {
|
||||
if (toRenderBlock(renderer)->logicalHeight()) {
|
||||
if (renderer->isRenderParagraph()) {
|
||||
if (toRenderParagraph(renderer)->logicalHeight()) {
|
||||
if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
|
||||
return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
|
||||
return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).atEditingBoundary();
|
||||
|
||||
@ -789,7 +789,7 @@ bool TextIterator::shouldRepresentNodeOffsetZero()
|
||||
// If this node is unrendered or invisible the VisiblePosition checks below won't have much meaning.
|
||||
// Additionally, if the range we are iterating over contains huge sections of unrendered content,
|
||||
// we would create VisiblePositions on every call to this function without this check.
|
||||
if (!m_node->renderer() || (m_node->renderer()->isRenderBlockFlow() && !toRenderBlock(m_node->renderer())->height()))
|
||||
if (!m_node->renderer() || (m_node->renderer()->isRenderParagraph() && !toRenderBlock(m_node->renderer())->height()))
|
||||
return false;
|
||||
|
||||
// The startPos.isNotNull() check is needed because the start could be before the body,
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
#include "sky/engine/core/editing/VisiblePosition.h"
|
||||
#include "sky/engine/core/editing/htmlediting.h"
|
||||
#include "sky/engine/core/rendering/InlineTextBox.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
#include "sky/engine/core/rendering/RenderObject.h"
|
||||
#include "sky/engine/platform/heap/Handle.h"
|
||||
#include "sky/engine/platform/text/TextBoundaries.h"
|
||||
@ -881,7 +881,7 @@ bool isLogicalEndOfLine(const VisiblePosition &p)
|
||||
static inline IntPoint absoluteLineDirectionPointToLocalPointInBlock(RootInlineBox* root, int lineDirectionPoint)
|
||||
{
|
||||
ASSERT(root);
|
||||
RenderBlockFlow& containingBlock = root->block();
|
||||
RenderParagraph& containingBlock = root->block();
|
||||
FloatPoint absoluteBlockPoint = containingBlock.localToAbsolute(FloatPoint());
|
||||
return IntPoint(lineDirectionPoint - absoluteBlockPoint.x(), root->blockDirectionPointInLine());
|
||||
}
|
||||
@ -907,7 +907,8 @@ VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
|
||||
if (box) {
|
||||
root = box->root().prevRootBox();
|
||||
// We want to skip zero height boxes.
|
||||
// This could happen in case it is a TrailingFloatsRootInlineBox.
|
||||
// This use to happen in case it is a TrailingFloatsRootInlineBox.
|
||||
// TODO(ojan): Can this still happen in sky?
|
||||
if (!root || !root->logicalHeight() || !root->firstLeafChild())
|
||||
root = 0;
|
||||
}
|
||||
@ -964,7 +965,8 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lin
|
||||
if (box) {
|
||||
root = box->root().nextRootBox();
|
||||
// We want to skip zero height boxes.
|
||||
// This could happen in case it is a TrailingFloatsRootInlineBox.
|
||||
// This use to happen in case it is a TrailingFloatsRootInlineBox.
|
||||
// TODO(ojan): Can this still happen in sky?
|
||||
if (!root || !root->logicalHeight() || !root->firstLeafChild())
|
||||
root = 0;
|
||||
}
|
||||
|
||||
@ -893,7 +893,7 @@ bool areIdenticalElements(const Node* first, const Node* second)
|
||||
bool isBlockFlowElement(const Node& node)
|
||||
{
|
||||
RenderObject* renderer = node.renderer();
|
||||
return node.isElementNode() && renderer && renderer->isRenderBlockFlow();
|
||||
return node.isElementNode() && renderer && renderer->isRenderParagraph();
|
||||
}
|
||||
|
||||
Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selection)
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sky/engine/core/rendering/InlineFlowBox.h"
|
||||
#include "sky/engine/core/rendering/PaintInfo.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
#include "sky/engine/core/rendering/RenderObjectInlines.h"
|
||||
#include "sky/engine/core/rendering/RootInlineBox.h"
|
||||
#include "sky/engine/platform/Partitions.h"
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "sky/engine/core/rendering/RenderInline.h"
|
||||
#include "sky/engine/core/rendering/RenderLayer.h"
|
||||
#include "sky/engine/core/rendering/RenderObjectInlines.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
#include "sky/engine/core/rendering/RenderView.h"
|
||||
#include "sky/engine/core/rendering/RootInlineBox.h"
|
||||
#include "sky/engine/platform/fonts/Font.h"
|
||||
|
||||
@ -24,9 +24,10 @@
|
||||
#define SKY_ENGINE_CORE_RENDERING_INLINEITERATOR_H_
|
||||
|
||||
#include "sky/engine/core/rendering/BidiRun.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderInline.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
#include "sky/engine/core/rendering/RenderText.h"
|
||||
#include "sky/engine/core/rendering/line/TrailingObjects.h"
|
||||
#include "sky/engine/wtf/StdLibExtras.h"
|
||||
|
||||
namespace blink {
|
||||
@ -283,7 +284,7 @@ static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re
|
||||
return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInlinePtr);
|
||||
}
|
||||
|
||||
static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, BidiRunList<BidiRun>& runs, InlineBidiResolver* resolver = 0)
|
||||
static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderParagraph* root, BidiRunList<BidiRun>& runs, InlineBidiResolver* resolver = 0)
|
||||
{
|
||||
RenderObject* o = root->firstChild();
|
||||
if (!o)
|
||||
@ -331,7 +332,7 @@ inline void InlineIterator::fastIncrementInTextNode()
|
||||
m_pos++;
|
||||
}
|
||||
|
||||
// FIXME: This is used by RenderBlockFlow for simplified layout, and has nothing to do with bidi
|
||||
// FIXME: This is used by RenderParagraph for simplified layout, and has nothing to do with bidi
|
||||
// it shouldn't use functions called bidiFirst and bidiNext.
|
||||
class InlineWalker {
|
||||
public:
|
||||
@ -600,7 +601,7 @@ public:
|
||||
// We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine.
|
||||
// We'll be called for every span inside the isolated span so we just ignore subsequent calls.
|
||||
// We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats.
|
||||
if (RenderBlockFlow::shouldSkipCreatingRunsForObject(obj))
|
||||
if (RenderParagraph::shouldSkipCreatingRunsForObject(obj))
|
||||
return;
|
||||
if (!m_haveAddedFakeRunForRootIsolate) {
|
||||
BidiRun* run = addPlaceholderRunForIsolatedInline(resolver, obj, pos);
|
||||
@ -629,7 +630,7 @@ static void inline appendRunObjectIfNecessary(RenderObject* obj, unsigned start,
|
||||
|
||||
static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, IsolateTracker& tracker)
|
||||
{
|
||||
if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj))
|
||||
if (start > end || RenderParagraph::shouldSkipCreatingRunsForObject(obj))
|
||||
return;
|
||||
|
||||
LineMidpointState& lineMidpointState = resolver.midpointState();
|
||||
|
||||
@ -585,7 +585,7 @@ GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& r
|
||||
// FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is
|
||||
// fixed).
|
||||
GapRects result;
|
||||
if (!isRenderBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
|
||||
if (!isRenderParagraph()) // FIXME: Make multi-column selection gap filling work someday.
|
||||
return result;
|
||||
|
||||
if (hasTransform()) {
|
||||
@ -1444,10 +1444,10 @@ RenderBlock* RenderBlock::firstLineBlock() const
|
||||
RenderObject* parentBlock = firstLineBlock->parent();
|
||||
if (firstLineBlock->isReplaced()
|
||||
|| !parentBlock
|
||||
|| !parentBlock->isRenderBlockFlow())
|
||||
|| !parentBlock->isRenderParagraph())
|
||||
break;
|
||||
ASSERT_WITH_SECURITY_IMPLICATION(parentBlock->isRenderBlock());
|
||||
if (toRenderBlock(parentBlock)->firstChild() != firstLineBlock)
|
||||
if (toRenderParagraph(parentBlock)->firstChild() != firstLineBlock)
|
||||
break;
|
||||
firstLineBlock = toRenderBlock(parentBlock);
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ protected:
|
||||
RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
|
||||
|
||||
public:
|
||||
// FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
|
||||
// FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderParagraph
|
||||
virtual void deleteLineBoxTree();
|
||||
|
||||
virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
|
||||
@ -308,8 +308,7 @@ protected:
|
||||
friend class LineBreaker;
|
||||
|
||||
// FIXME: This is temporary as we move code that accesses block flow
|
||||
// member variables out of RenderBlock and into RenderBlockFlow.
|
||||
friend class RenderBlockFlow;
|
||||
// member variables out of RenderBlock and into RenderParagraph.
|
||||
friend class RenderParagraph;
|
||||
};
|
||||
|
||||
|
||||
@ -1,328 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Google Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "sky/engine/config.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
|
||||
#include "sky/engine/core/frame/FrameView.h"
|
||||
#include "sky/engine/core/frame/LocalFrame.h"
|
||||
#include "sky/engine/core/frame/Settings.h"
|
||||
#include "sky/engine/core/rendering/BidiRun.h"
|
||||
#include "sky/engine/core/rendering/HitTestLocation.h"
|
||||
#include "sky/engine/core/rendering/RenderLayer.h"
|
||||
#include "sky/engine/core/rendering/RenderText.h"
|
||||
#include "sky/engine/core/rendering/RenderView.h"
|
||||
#include "sky/engine/core/rendering/line/LineWidth.h"
|
||||
#include "sky/engine/platform/text/BidiTextRun.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
RenderBlockFlow::RenderBlockFlow(ContainerNode* node)
|
||||
: RenderBlock(node)
|
||||
{
|
||||
}
|
||||
|
||||
RenderBlockFlow::~RenderBlockFlow()
|
||||
{
|
||||
}
|
||||
|
||||
RenderBlockFlow* RenderBlockFlow::createAnonymous(Document* document)
|
||||
{
|
||||
RenderBlockFlow* renderer = new RenderBlockFlow(0);
|
||||
renderer->setDocumentForAnonymous(document);
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void RenderBlockFlow::layout()
|
||||
{
|
||||
ASSERT(needsLayout());
|
||||
ASSERT(isInlineBlock() || !isInline());
|
||||
|
||||
if (simplifiedLayout())
|
||||
return;
|
||||
|
||||
SubtreeLayoutScope layoutScope(*this);
|
||||
|
||||
layoutBlockFlow(layoutScope);
|
||||
|
||||
updateLayerTransformAfterLayout();
|
||||
|
||||
clearNeedsLayout();
|
||||
}
|
||||
|
||||
inline void RenderBlockFlow::layoutBlockFlow(SubtreeLayoutScope& layoutScope)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox* child)
|
||||
{
|
||||
LayoutUnit startPosition = borderStart() + paddingStart();
|
||||
LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
|
||||
|
||||
LayoutUnit childMarginStart = marginStartForChild(child);
|
||||
LayoutUnit newPosition = startPosition + childMarginStart;
|
||||
|
||||
// If the child has an offset from the content edge to avoid floats then use that, otherwise let any negative
|
||||
// margin pull it back over the content edge or any positive margin push it out.
|
||||
if (child->style()->marginStartUsing(style()).isAuto())
|
||||
newPosition = std::max(newPosition, childMarginStart);
|
||||
|
||||
child->setX(style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child));
|
||||
}
|
||||
|
||||
void RenderBlockFlow::layoutBlockChild(RenderBox* child)
|
||||
{
|
||||
child->computeAndSetBlockDirectionMargins(this);
|
||||
LayoutUnit marginBefore = marginBeforeForChild(child);
|
||||
child->setY(logicalHeight() + marginBefore);
|
||||
child->layoutIfNeeded();
|
||||
determineLogicalLeftPositionForChild(child);
|
||||
setLogicalHeight(logicalHeight() + marginBefore + logicalHeightForChild(child) + marginAfterForChild(child));
|
||||
}
|
||||
|
||||
void RenderBlockFlow::layoutChildren(bool relayoutChildren, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge)
|
||||
{
|
||||
dirtyForLayoutFromPercentageHeightDescendants(layoutScope);
|
||||
|
||||
RenderBox* next = firstChildBox();
|
||||
RenderBox* lastNormalFlowChild = 0;
|
||||
|
||||
while (next) {
|
||||
RenderBox* child = next;
|
||||
next = child->nextSiblingBox();
|
||||
|
||||
updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
|
||||
|
||||
if (child->isOutOfFlowPositioned()) {
|
||||
child->containingBlock()->insertPositionedObject(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Lay out the child.
|
||||
layoutBlockChild(child);
|
||||
lastNormalFlowChild = child;
|
||||
}
|
||||
|
||||
// Negative margins can cause our height to shrink below our minimal height (border/padding).
|
||||
// If this happens, ensure that the computed height is increased to the minimal height.
|
||||
setLogicalHeight(std::max(logicalHeight() + afterEdge, beforeEdge + afterEdge));
|
||||
}
|
||||
|
||||
RootInlineBox* RenderBlockFlow::createAndAppendRootInlineBox()
|
||||
{
|
||||
RootInlineBox* rootBox = createRootInlineBox();
|
||||
m_lineBoxes.appendLineBox(rootBox);
|
||||
|
||||
return rootBox;
|
||||
}
|
||||
|
||||
void RenderBlockFlow::deleteLineBoxTree()
|
||||
{
|
||||
m_lineBoxes.deleteLineBoxTree();
|
||||
}
|
||||
|
||||
void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild)
|
||||
{
|
||||
RenderBlock::addChild(newChild, beforeChild);
|
||||
}
|
||||
|
||||
LayoutUnit RenderBlockFlow::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 RenderBlockFlow::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* RenderBlockFlow::createRootInlineBox()
|
||||
{
|
||||
return new RootInlineBox(*this);
|
||||
}
|
||||
|
||||
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 RenderBlockFlow::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;
|
||||
}
|
||||
}
|
||||
|
||||
LayoutUnit RenderBlockFlow::startAlignedOffsetForLine(bool firstLine)
|
||||
{
|
||||
ETextAlign textAlign = style()->textAlign();
|
||||
|
||||
if (textAlign == TASTART) // FIXME: Handle TAEND here
|
||||
return startOffsetForLine(firstLine);
|
||||
|
||||
// updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
|
||||
float totalLogicalWidth = 0;
|
||||
float logicalLeft = logicalLeftOffsetForLine(false).toFloat();
|
||||
float availableLogicalWidth = logicalRightOffsetForLine(false) - logicalLeft;
|
||||
updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
|
||||
|
||||
if (!style()->isLeftToRightDirection())
|
||||
return logicalWidth() - logicalLeft;
|
||||
return logicalLeft;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
|
||||
* (C) 1999 Antti Koivisto (koivisto@kde.org)
|
||||
* (C) 2007 David Smith (catfish.man@gmail.com)
|
||||
* Copyright (C) 2003-2013 Apple Inc. All rights reserved.
|
||||
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
|
||||
* Copyright (C) 2013 Google Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SKY_ENGINE_CORE_RENDERING_RENDERBLOCKFLOW_H_
|
||||
#define SKY_ENGINE_CORE_RENDERING_RENDERBLOCKFLOW_H_
|
||||
|
||||
#include "sky/engine/core/rendering/RenderBlock.h"
|
||||
#include "sky/engine/core/rendering/line/TrailingObjects.h"
|
||||
#include "sky/engine/core/rendering/style/RenderStyleConstants.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class LineBreaker;
|
||||
class LineWidth;
|
||||
class FloatingObject;
|
||||
|
||||
class RenderBlockFlow : public RenderBlock {
|
||||
public:
|
||||
explicit RenderBlockFlow(ContainerNode*);
|
||||
virtual ~RenderBlockFlow();
|
||||
|
||||
static RenderBlockFlow* createAnonymous(Document*);
|
||||
|
||||
virtual bool isRenderBlockFlow() const override final { return true; }
|
||||
|
||||
void layout() override;
|
||||
|
||||
virtual void deleteLineBoxTree() override final;
|
||||
|
||||
LayoutUnit availableLogicalWidthForLine(bool shouldIndentText) const
|
||||
{
|
||||
return max<LayoutUnit>(0, logicalRightOffsetForLine(shouldIndentText) - logicalLeftOffsetForLine(shouldIndentText));
|
||||
}
|
||||
LayoutUnit logicalRightOffsetForLine(bool shouldIndentText) const
|
||||
{
|
||||
LayoutUnit right = logicalRightOffsetForContent();
|
||||
if (shouldIndentText && !style()->isLeftToRightDirection())
|
||||
right -= textIndentOffset();
|
||||
return right;
|
||||
}
|
||||
LayoutUnit logicalLeftOffsetForLine(bool shouldIndentText) const
|
||||
{
|
||||
LayoutUnit left = logicalLeftOffsetForContent();
|
||||
if (shouldIndentText && style()->isLeftToRightDirection())
|
||||
left += textIndentOffset();
|
||||
return left;
|
||||
}
|
||||
LayoutUnit startOffsetForLine(bool shouldIndentText) const
|
||||
{
|
||||
return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(shouldIndentText)
|
||||
: logicalWidth() - logicalRightOffsetForLine(shouldIndentText);
|
||||
}
|
||||
LayoutUnit endOffsetForLine(bool shouldIndentText) const
|
||||
{
|
||||
return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(shouldIndentText)
|
||||
: logicalWidth() - logicalRightOffsetForLine(shouldIndentText);
|
||||
}
|
||||
|
||||
// FIXME-BLOCKFLOW: Move this into RenderBlockFlow once there are no calls
|
||||
// in RenderBlock. http://crbug.com/393945, http://crbug.com/302024
|
||||
using RenderBlock::lineBoxes;
|
||||
using RenderBlock::firstLineBox;
|
||||
using RenderBlock::lastLineBox;
|
||||
using RenderBlock::firstRootBox;
|
||||
using RenderBlock::lastRootBox;
|
||||
|
||||
virtual LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) override;
|
||||
virtual LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) override;
|
||||
|
||||
RootInlineBox* createAndAppendRootInlineBox();
|
||||
|
||||
virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
|
||||
|
||||
LayoutUnit startAlignedOffsetForLine(bool shouldIndentText);
|
||||
void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount);
|
||||
|
||||
static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
|
||||
{
|
||||
return obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void layoutChildren(bool relayoutChildren, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge);
|
||||
|
||||
void determineLogicalLeftPositionForChild(RenderBox* child);
|
||||
|
||||
private:
|
||||
void layoutBlockFlow(SubtreeLayoutScope&);
|
||||
void layoutBlockChild(RenderBox* child);
|
||||
|
||||
RootInlineBox* createRootInlineBox();
|
||||
|
||||
public:
|
||||
struct FloatWithRect {
|
||||
FloatWithRect(RenderBox* f)
|
||||
: object(f)
|
||||
, rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
|
||||
, everHadLayout(f->everHadLayout())
|
||||
{
|
||||
}
|
||||
|
||||
RenderBox* object;
|
||||
LayoutRect rect;
|
||||
bool everHadLayout;
|
||||
};
|
||||
|
||||
protected:
|
||||
friend class BreakingContext; // FIXME: It uses insertFloatingObject and positionNewFloatOnLine, if we move those out from the private scope/add a helper to LineBreaker, we can remove this friend
|
||||
friend class LineBreaker;
|
||||
};
|
||||
|
||||
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBlockFlow, isRenderBlockFlow());
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_CORE_RENDERING_RENDERBLOCKFLOW_H_
|
||||
@ -2763,7 +2763,7 @@ PositionWithAffinity RenderBox::positionForPoint(const LayoutPoint& point)
|
||||
LayoutPoint adjustedPoint = point;
|
||||
|
||||
for (RenderObject* renderObject = firstChild; renderObject; renderObject = renderObject->nextSibling()) {
|
||||
if (!renderObject->slowFirstChild() && !renderObject->isInline() && !renderObject->isRenderBlockFlow())
|
||||
if (!renderObject->slowFirstChild() && !renderObject->isInline() && !renderObject->isRenderParagraph())
|
||||
continue;
|
||||
|
||||
if (!renderObject->isBox())
|
||||
|
||||
@ -32,7 +32,6 @@ namespace blink {
|
||||
struct LayerPaintingInfo;
|
||||
struct PaintInfo;
|
||||
class HitTestingTransformState;
|
||||
class RenderBlockFlow;
|
||||
class TransformationMatrix;
|
||||
|
||||
enum SizeType { MainOrPreferredSize, MinSize, MaxSize };
|
||||
|
||||
@ -66,8 +66,8 @@ struct RenderFlexibleBox::Violation {
|
||||
};
|
||||
|
||||
|
||||
RenderFlexibleBox::RenderFlexibleBox(Element* element)
|
||||
: RenderBlock(element)
|
||||
RenderFlexibleBox::RenderFlexibleBox(ContainerNode* node)
|
||||
: RenderBlock(node)
|
||||
, m_orderIterator(this)
|
||||
, m_numberOfInFlowChildrenOnFirstLine(-1)
|
||||
{
|
||||
|
||||
@ -38,7 +38,7 @@ namespace blink {
|
||||
|
||||
class RenderFlexibleBox : public RenderBlock {
|
||||
public:
|
||||
RenderFlexibleBox(Element*);
|
||||
RenderFlexibleBox(ContainerNode*);
|
||||
virtual ~RenderFlexibleBox();
|
||||
|
||||
static RenderFlexibleBox* createAnonymous(Document*);
|
||||
@ -46,7 +46,7 @@ public:
|
||||
virtual const char* renderName() const override;
|
||||
|
||||
virtual bool isFlexibleBox() const override final { return true; }
|
||||
void layout() final;
|
||||
void layout();
|
||||
|
||||
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
|
||||
virtual int firstLineBoxBaseline() const override;
|
||||
|
||||
@ -242,7 +242,7 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq
|
||||
|
||||
void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, RenderObject* child)
|
||||
{
|
||||
if (!container->parent() || (container->isRenderBlock() && (container->selfNeedsLayout() || !container->isRenderBlockFlow())))
|
||||
if (!container->parent() || (container->isRenderBlock() && (container->selfNeedsLayout() || !container->isRenderParagraph())))
|
||||
return;
|
||||
|
||||
RenderInline* inlineContainer = container->isRenderInline() ? toRenderInline(container) : 0;
|
||||
|
||||
@ -440,7 +440,7 @@ bool RenderObject::skipInvalidationWhenLaidOutChildren() const
|
||||
|
||||
// SVG renderers need to be invalidated when their children are laid out.
|
||||
// RenderBlocks with line boxes are responsible to invalidate them so we can't ignore them.
|
||||
if (isRenderBlockFlow() && toRenderBlockFlow(this)->firstLineBox())
|
||||
if (isRenderParagraph() && toRenderParagraph(this)->firstLineBox())
|
||||
return false;
|
||||
|
||||
return rendererHasNoBoxEffect();
|
||||
@ -1239,7 +1239,7 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle& newS
|
||||
|
||||
s_affectsParentBlock = isFloatingOrOutOfFlowPositioned()
|
||||
&& !newStyle.hasOutOfFlowPosition()
|
||||
&& parent() && (parent()->isRenderBlockFlow() || parent()->isRenderInline());
|
||||
&& parent() && (parent()->isRenderParagraph() || parent()->isRenderInline());
|
||||
|
||||
// Clearing these bits is required to avoid leaving stale renderers.
|
||||
// FIXME: We shouldn't need that hack if our logic was totally correct.
|
||||
|
||||
@ -111,7 +111,6 @@ const int showTreeCharacterOffset = 39;
|
||||
// Base class for all rendering tree objects.
|
||||
class RenderObject : public ImageResourceClient {
|
||||
friend class RenderBlock;
|
||||
friend class RenderBlockFlow;
|
||||
friend class RenderObjectChildList;
|
||||
WTF_MAKE_NONCOPYABLE(RenderObject);
|
||||
public:
|
||||
@ -260,7 +259,6 @@ public:
|
||||
virtual bool isImage() const { return false; }
|
||||
virtual bool isInlineBlock() const { return false; }
|
||||
virtual bool isRenderBlock() const { return false; }
|
||||
virtual bool isRenderBlockFlow() const { return false; }
|
||||
virtual bool isRenderCustomLayout() const { return false; }
|
||||
virtual bool isRenderParagraph() const { return false; }
|
||||
virtual bool isRenderImage() const { return false; }
|
||||
|
||||
@ -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();
|
||||
@ -784,7 +927,6 @@ void RenderParagraph::layoutRunsAndFloatsInRange(LineLayoutState& layoutState,
|
||||
// Once BidiRunList is separated from BidiResolver this will not be needed.
|
||||
resolver.runs().deleteRuns();
|
||||
resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
|
||||
layoutState.setCheckForFloatsFromLastLine(true);
|
||||
resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
|
||||
break;
|
||||
}
|
||||
@ -1242,6 +1384,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.
|
||||
@ -1327,59 +1507,11 @@ void RenderParagraph::layoutChildren(bool relayoutChildren, SubtreeLayoutScope&
|
||||
checkLinesForTextOverflow();
|
||||
}
|
||||
|
||||
void RenderParagraph::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat)
|
||||
{
|
||||
Vector<RenderBox*>* cleanLineFloats = line->floatsPtr();
|
||||
if (!cleanLineFloats)
|
||||
return;
|
||||
|
||||
Vector<RenderBox*>::iterator end = cleanLineFloats->end();
|
||||
for (Vector<RenderBox*>::iterator it = cleanLineFloats->begin(); it != end; ++it) {
|
||||
RenderBox* floatingBox = *it;
|
||||
floatingBox->layoutIfNeeded();
|
||||
LayoutSize newSize(floatingBox->width() + floatingBox->marginWidth(), floatingBox->height() + floatingBox->marginHeight());
|
||||
if (floats[floatIndex].object != floatingBox) {
|
||||
encounteredNewFloat = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (floats[floatIndex].rect.size() != newSize) {
|
||||
LayoutUnit floatTop = floats[floatIndex].rect.y();
|
||||
LayoutUnit floatHeight = std::max(floats[floatIndex].rect.height(), newSize.height());
|
||||
floatHeight = std::min(floatHeight, LayoutUnit::max() - floatTop);
|
||||
line->markDirty();
|
||||
markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop + floatHeight, line);
|
||||
floats[floatIndex].rect.setSize(newSize);
|
||||
dirtiedByFloat = true;
|
||||
}
|
||||
floatIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
RootInlineBox* RenderParagraph::determineStartPosition(LineLayoutState& layoutState, InlineBidiResolver& resolver)
|
||||
{
|
||||
RootInlineBox* curr = 0;
|
||||
RootInlineBox* last = 0;
|
||||
|
||||
// FIXME: This entire float-checking block needs to be broken into a new function.
|
||||
bool dirtiedByFloat = false;
|
||||
if (!layoutState.isFullLayout()) {
|
||||
size_t floatIndex = 0;
|
||||
for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
|
||||
// If a new float has been inserted before this line or before its last known float, just do a full layout.
|
||||
bool encounteredNewFloat = false;
|
||||
checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
|
||||
if (encounteredNewFloat)
|
||||
layoutState.markForFullLayout();
|
||||
|
||||
if (dirtiedByFloat || layoutState.isFullLayout())
|
||||
break;
|
||||
}
|
||||
// Check if a new float has been inserted after the last known float.
|
||||
if (!curr && floatIndex < layoutState.floats().size())
|
||||
layoutState.markForFullLayout();
|
||||
}
|
||||
|
||||
if (layoutState.isFullLayout()) {
|
||||
// If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations.
|
||||
if (layoutState.hasInlineChild() && !selfNeedsLayout()) {
|
||||
@ -1401,7 +1533,7 @@ RootInlineBox* RenderParagraph::determineStartPosition(LineLayoutState& layoutSt
|
||||
// We have a dirty line.
|
||||
if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
|
||||
// We have a previous line.
|
||||
if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
|
||||
if (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength()))
|
||||
// The previous line didn't break cleanly or broke at a newline
|
||||
// that has been deleted, so treat it as dirty too.
|
||||
curr = prevRootBox;
|
||||
@ -1439,16 +1571,8 @@ RootInlineBox* RenderParagraph::determineStartPosition(LineLayoutState& layoutSt
|
||||
void RenderParagraph::determineEndPosition(LineLayoutState& layoutState, RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus)
|
||||
{
|
||||
ASSERT(!layoutState.endLine());
|
||||
size_t floatIndex = layoutState.floatIndex();
|
||||
RootInlineBox* last = 0;
|
||||
for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {
|
||||
if (!curr->isDirty()) {
|
||||
bool encounteredNewFloat = false;
|
||||
bool dirtiedByFloat = false;
|
||||
checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
|
||||
if (encounteredNewFloat)
|
||||
return;
|
||||
}
|
||||
if (curr->isDirty())
|
||||
last = 0;
|
||||
else if (!last)
|
||||
|
||||
@ -6,30 +6,64 @@
|
||||
#define SKY_ENGINE_CORE_RENDERING_RENDERPARAGRAPH_H_
|
||||
|
||||
#include "sky/engine/core/dom/ContainerNode.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderBlock.h"
|
||||
#include "sky/engine/core/rendering/line/TrailingObjects.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
struct BidiRun;
|
||||
class ContainerNode;
|
||||
// class InlineBidiResolver;
|
||||
class InlineIterator;
|
||||
|
||||
class RenderParagraph final : public RenderBlockFlow {
|
||||
class RenderParagraph final : public RenderBlock {
|
||||
public:
|
||||
explicit RenderParagraph(ContainerNode*);
|
||||
virtual ~RenderParagraph();
|
||||
|
||||
static RenderParagraph* createAnonymous(Document&);
|
||||
|
||||
bool isRenderParagraph() const override { return true; }
|
||||
bool isRenderParagraph() const final { return true; }
|
||||
|
||||
void layout() final;
|
||||
|
||||
LayoutUnit logicalRightOffsetForLine(bool shouldIndentText) const
|
||||
{
|
||||
LayoutUnit right = logicalRightOffsetForContent();
|
||||
if (shouldIndentText && !style()->isLeftToRightDirection())
|
||||
right -= textIndentOffset();
|
||||
return right;
|
||||
}
|
||||
LayoutUnit logicalLeftOffsetForLine(bool shouldIndentText) const
|
||||
{
|
||||
LayoutUnit left = logicalLeftOffsetForContent();
|
||||
if (shouldIndentText && style()->isLeftToRightDirection())
|
||||
left += textIndentOffset();
|
||||
return left;
|
||||
}
|
||||
|
||||
LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) final;
|
||||
LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) final;
|
||||
|
||||
virtual RootInlineBox* lineAtIndex(int) const;
|
||||
virtual int lineCount(const RootInlineBox* = 0, bool* = 0) const;
|
||||
|
||||
void deleteLineBoxTree() final;
|
||||
|
||||
GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
|
||||
LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
|
||||
|
||||
protected:
|
||||
void layoutChildren(bool relayoutChildren, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge) final;
|
||||
static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
|
||||
{
|
||||
return obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline();
|
||||
}
|
||||
|
||||
// TODO(ojan): Remove the need for these.
|
||||
using RenderBlock::lineBoxes;
|
||||
using RenderBlock::firstLineBox;
|
||||
using RenderBlock::lastRootBox;
|
||||
|
||||
protected:
|
||||
void addOverflowFromChildren() final;
|
||||
|
||||
void simplifiedNormalFlowLayout() final;
|
||||
@ -48,9 +82,16 @@ protected:
|
||||
private:
|
||||
virtual const char* renderName() const override;
|
||||
|
||||
void layoutChildren(bool relayoutChildren, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge);
|
||||
|
||||
void markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest = 0);
|
||||
|
||||
void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount);
|
||||
|
||||
RootInlineBox* createAndAppendRootInlineBox();
|
||||
RootInlineBox* createRootInlineBox();
|
||||
InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox);
|
||||
InlineBox* createInlineBoxForRenderer(RenderObject*, bool isRootLineBox, bool isOnlyRun = false);
|
||||
RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
|
||||
void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
|
||||
BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
|
||||
@ -62,7 +103,6 @@ private:
|
||||
void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&,
|
||||
const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus);
|
||||
void linkToEndLineIfNeeded(LineLayoutState&);
|
||||
void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
|
||||
RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
|
||||
void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
|
||||
bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
namespace blink {
|
||||
|
||||
RenderView::RenderView(Document* document)
|
||||
: RenderBlockFlow(document)
|
||||
: RenderFlexibleBox(document)
|
||||
, m_frameView(document->view())
|
||||
, m_selectionStart(nullptr)
|
||||
, m_selectionEnd(nullptr)
|
||||
@ -116,11 +116,6 @@ void RenderView::updateLogicalWidth()
|
||||
setLogicalWidth(viewLogicalWidth());
|
||||
}
|
||||
|
||||
LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType heightType) const
|
||||
{
|
||||
return RenderBlockFlow::availableLogicalHeight(heightType);
|
||||
}
|
||||
|
||||
bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
|
||||
{
|
||||
return child->isBox();
|
||||
@ -145,7 +140,7 @@ void RenderView::layout()
|
||||
if (!needsLayout())
|
||||
return;
|
||||
|
||||
RenderBlockFlow::layout();
|
||||
RenderFlexibleBox::layout();
|
||||
clearNeedsLayout();
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
#define SKY_ENGINE_CORE_RENDERING_RENDERVIEW_H_
|
||||
|
||||
#include "sky/engine/core/frame/FrameView.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderFlexibleBox.h"
|
||||
#include "sky/engine/core/rendering/RenderIFrame.h"
|
||||
#include "sky/engine/wtf/OwnPtr.h"
|
||||
|
||||
@ -33,7 +33,7 @@ namespace blink {
|
||||
// It's dimensions match that of the logical viewport (which may be different from
|
||||
// the visible viewport in fixed-layout mode), and it is always at position (0,0)
|
||||
// relative to the document (and so isn't necessarily in view).
|
||||
class RenderView final : public RenderBlockFlow {
|
||||
class RenderView final : public RenderFlexibleBox {
|
||||
public:
|
||||
explicit RenderView(Document*);
|
||||
virtual ~RenderView();
|
||||
@ -56,8 +56,6 @@ public:
|
||||
virtual void updateLogicalWidth() override;
|
||||
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override;
|
||||
|
||||
virtual LayoutUnit availableLogicalHeight(AvailableLogicalHeightType) const override;
|
||||
|
||||
// The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
|
||||
int viewHeight() const;
|
||||
int viewWidth() const;
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
#include "sky/engine/core/rendering/HitTestResult.h"
|
||||
#include "sky/engine/core/rendering/InlineTextBox.h"
|
||||
#include "sky/engine/core/rendering/PaintInfo.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
#include "sky/engine/core/rendering/RenderInline.h"
|
||||
#include "sky/engine/core/rendering/RenderView.h"
|
||||
#include "sky/engine/core/rendering/VerticalPositionCache.h"
|
||||
@ -37,7 +37,7 @@ namespace blink {
|
||||
|
||||
struct SameSizeAsRootInlineBox : public InlineFlowBox {
|
||||
unsigned unsignedVariable;
|
||||
void* pointers[4];
|
||||
void* pointers[3];
|
||||
LayoutUnit layoutVariables[5];
|
||||
};
|
||||
|
||||
@ -46,7 +46,7 @@ COMPILE_ASSERT(sizeof(RootInlineBox) == sizeof(SameSizeAsRootInlineBox), RootInl
|
||||
typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap;
|
||||
static EllipsisBoxMap* gEllipsisBoxMap = 0;
|
||||
|
||||
RootInlineBox::RootInlineBox(RenderBlockFlow& block)
|
||||
RootInlineBox::RootInlineBox(RenderParagraph& block)
|
||||
: InlineFlowBox(block)
|
||||
, m_lineBreakPos(0)
|
||||
, m_lineBreakObj(0)
|
||||
@ -392,8 +392,8 @@ LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const
|
||||
|
||||
LayoutSize offsetToBlockBefore;
|
||||
if (RenderBlock* block = root().block().blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
|
||||
if (block->isRenderBlockFlow()) {
|
||||
if (RootInlineBox* lastLine = toRenderBlockFlow(block)->lastRootBox()) {
|
||||
if (block->isRenderParagraph()) {
|
||||
if (RootInlineBox* lastLine = toRenderParagraph(block)->lastRootBox()) {
|
||||
RenderObject::SelectionState lastLineSelectionState = lastLine->selectionState();
|
||||
if (lastLineSelectionState != RenderObject::SelectionInside && lastLineSelectionState != RenderObject::SelectionStart)
|
||||
return top;
|
||||
@ -420,9 +420,9 @@ int RootInlineBox::blockDirectionPointInLine() const
|
||||
return std::max(lineTop(), selectionTop());
|
||||
}
|
||||
|
||||
RenderBlockFlow& RootInlineBox::block() const
|
||||
RenderParagraph& RootInlineBox::block() const
|
||||
{
|
||||
return toRenderBlockFlow(renderer());
|
||||
return toRenderParagraph(renderer());
|
||||
}
|
||||
|
||||
static bool isEditableLeaf(InlineBox* leaf)
|
||||
|
||||
@ -28,14 +28,14 @@ namespace blink {
|
||||
|
||||
class EllipsisBox;
|
||||
class HitTestResult;
|
||||
class RenderBlockFlow;
|
||||
class RenderParagraph;
|
||||
|
||||
struct BidiStatus;
|
||||
struct GapRects;
|
||||
|
||||
class RootInlineBox : public InlineFlowBox {
|
||||
public:
|
||||
explicit RootInlineBox(RenderBlockFlow&);
|
||||
explicit RootInlineBox(RenderParagraph&);
|
||||
|
||||
virtual void destroy() override final;
|
||||
|
||||
@ -121,22 +121,11 @@ public:
|
||||
|
||||
GapRects lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo*);
|
||||
|
||||
RenderBlockFlow& block() const;
|
||||
RenderParagraph& block() const;
|
||||
|
||||
InlineBox* closestLeafChildForPoint(const IntPoint&, bool onlyEditableLeaves);
|
||||
InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
|
||||
|
||||
void appendFloat(RenderBox* floatingBox)
|
||||
{
|
||||
ASSERT(!isDirty());
|
||||
if (m_floats)
|
||||
m_floats->append(floatingBox);
|
||||
else
|
||||
m_floats= adoptPtr(new Vector<RenderBox*>(1, floatingBox));
|
||||
}
|
||||
|
||||
Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); }
|
||||
|
||||
virtual void extractLineBoxFromRenderObject() override final;
|
||||
virtual void attachLineBoxToRenderObject() override final;
|
||||
virtual void removeLineBoxFromRenderObject() override final;
|
||||
@ -219,10 +208,6 @@ private:
|
||||
|
||||
OwnPtr<LineFragmentationData> m_fragmentationData;
|
||||
|
||||
// Floats hanging off the line are pushed into this vector during layout. It is only
|
||||
// good for as long as the line has not been marked dirty.
|
||||
OwnPtr<Vector<RenderBox*> > m_floats;
|
||||
|
||||
LayoutUnit m_lineTop;
|
||||
LayoutUnit m_lineBottom;
|
||||
LayoutUnit m_lineTopWithLeading;
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SKY_ENGINE_CORE_RENDERING_TRAILINGFLOATSROOTINLINEBOX_H_
|
||||
#define SKY_ENGINE_CORE_RENDERING_TRAILINGFLOATSROOTINLINEBOX_H_
|
||||
|
||||
#include "sky/engine/core/rendering/RootInlineBox.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class TrailingFloatsRootInlineBox final : public RootInlineBox {
|
||||
public:
|
||||
TrailingFloatsRootInlineBox(RenderBlockFlow& block)
|
||||
: RootInlineBox(block)
|
||||
{
|
||||
setHasVirtualLogicalHeight();
|
||||
}
|
||||
|
||||
private:
|
||||
virtual float virtualLogicalHeight() const override { return 0; }
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_CORE_RENDERING_TRAILINGFLOATSROOTINLINEBOX_H_
|
||||
@ -45,7 +45,7 @@ const unsigned cMaxLineDepth = 200;
|
||||
|
||||
class BreakingContext {
|
||||
public:
|
||||
BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidth& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderBlockFlow* block)
|
||||
BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidth& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderParagraph* block)
|
||||
: m_resolver(resolver)
|
||||
, m_current(resolver.position())
|
||||
, m_lineBreak(resolver.position())
|
||||
@ -105,7 +105,7 @@ private:
|
||||
InlineIterator m_lineBreak;
|
||||
InlineIterator m_startOfIgnoredSpaces;
|
||||
|
||||
RenderBlockFlow* m_block;
|
||||
RenderParagraph* m_block;
|
||||
RenderObject* m_lastObject;
|
||||
RenderObject* m_nextObject;
|
||||
|
||||
@ -292,7 +292,7 @@ inline void BreakingContext::handleOutOfFlowPositioned(Vector<RenderBox*>& posit
|
||||
|
||||
// This is currently just used for list markers and inline flows that have line boxes. Neither should
|
||||
// have an effect on whitespace at the start of the line.
|
||||
inline bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow* block, RenderObject* o, LineMidpointState& lineMidpointState)
|
||||
inline bool shouldSkipWhitespaceAfterStartObject(RenderParagraph* block, RenderObject* o, LineMidpointState& lineMidpointState)
|
||||
{
|
||||
RenderObject* next = bidiNextSkippingEmptyInlines(block, o);
|
||||
while (next && next->isFloatingOrOutOfFlowPositioned())
|
||||
|
||||
@ -36,7 +36,7 @@ struct RenderTextInfo;
|
||||
class LineBreaker {
|
||||
public:
|
||||
friend class BreakingContext;
|
||||
LineBreaker(RenderBlockFlow* block)
|
||||
LineBreaker(RenderParagraph* block)
|
||||
: m_block(block)
|
||||
{
|
||||
reset();
|
||||
@ -52,7 +52,7 @@ private:
|
||||
|
||||
void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
|
||||
|
||||
RenderBlockFlow* m_block;
|
||||
RenderParagraph* m_block;
|
||||
bool m_hyphenated;
|
||||
Vector<RenderBox*> m_positionedObjects;
|
||||
};
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#ifndef SKY_ENGINE_CORE_RENDERING_LINE_LINELAYOUTSTATE_H_
|
||||
#define SKY_ENGINE_CORE_RENDERING_LINE_LINELAYOUTSTATE_H_
|
||||
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
#include "sky/engine/platform/geometry/LayoutRect.h"
|
||||
|
||||
namespace blink {
|
||||
@ -34,12 +34,9 @@ namespace blink {
|
||||
class LineLayoutState {
|
||||
public:
|
||||
LineLayoutState(bool fullLayout)
|
||||
: m_lastFloat(0)
|
||||
, m_endLine(0)
|
||||
, m_floatIndex(0)
|
||||
: m_endLine(0)
|
||||
, m_endLineLogicalTop(0)
|
||||
, m_endLineMatched(false)
|
||||
, m_checkForFloatsFromLastLine(false)
|
||||
, m_hasInlineChild(false)
|
||||
, m_isFullLayout(fullLayout)
|
||||
, m_adjustedLogicalLineTop(0)
|
||||
@ -51,9 +48,6 @@ public:
|
||||
bool endLineMatched() const { return m_endLineMatched; }
|
||||
void setEndLineMatched(bool endLineMatched) { m_endLineMatched = endLineMatched; }
|
||||
|
||||
bool checkForFloatsFromLastLine() const { return m_checkForFloatsFromLastLine; }
|
||||
void setCheckForFloatsFromLastLine(bool check) { m_checkForFloatsFromLastLine = check; }
|
||||
|
||||
bool hasInlineChild() const { return m_hasInlineChild; }
|
||||
void setHasInlineChild(bool hasInlineChild) { m_hasInlineChild = hasInlineChild; }
|
||||
|
||||
@ -66,26 +60,15 @@ public:
|
||||
RootInlineBox* endLine() const { return m_endLine; }
|
||||
void setEndLine(RootInlineBox* line) { m_endLine = line; }
|
||||
|
||||
FloatingObject* lastFloat() const { return m_lastFloat; }
|
||||
void setLastFloat(FloatingObject* lastFloat) { m_lastFloat = lastFloat; }
|
||||
|
||||
Vector<RenderBlockFlow::FloatWithRect>& floats() { return m_floats; }
|
||||
|
||||
unsigned floatIndex() const { return m_floatIndex; }
|
||||
void setFloatIndex(unsigned floatIndex) { m_floatIndex = floatIndex; }
|
||||
|
||||
LayoutUnit adjustedLogicalLineTop() const { return m_adjustedLogicalLineTop; }
|
||||
void setAdjustedLogicalLineTop(LayoutUnit value) { m_adjustedLogicalLineTop = value; }
|
||||
|
||||
private:
|
||||
Vector<RenderBlockFlow::FloatWithRect> m_floats;
|
||||
FloatingObject* m_lastFloat;
|
||||
RootInlineBox* m_endLine;
|
||||
LineInfo m_lineInfo;
|
||||
unsigned m_floatIndex;
|
||||
LayoutUnit m_endLineLogicalTop;
|
||||
bool m_endLineMatched;
|
||||
bool m_checkForFloatsFromLastLine;
|
||||
// FIXME(sky): Do we still need this?
|
||||
// Used as a performance optimization to avoid doing a full paint invalidation when our floats
|
||||
// change but we don't have any inline children.
|
||||
bool m_hasInlineChild;
|
||||
|
||||
@ -31,11 +31,11 @@
|
||||
#include "sky/engine/core/rendering/line/LineWidth.h"
|
||||
|
||||
#include "sky/engine/core/rendering/RenderBlock.h"
|
||||
#include "sky/engine/core/rendering/RenderBlockFlow.h"
|
||||
#include "sky/engine/core/rendering/RenderParagraph.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
LineWidth::LineWidth(RenderBlockFlow& block, bool isFirstLine, IndentTextOrNot shouldIndentText)
|
||||
LineWidth::LineWidth(RenderParagraph& block, bool isFirstLine, IndentTextOrNot shouldIndentText)
|
||||
: m_block(block)
|
||||
, m_uncommittedWidth(0)
|
||||
, m_committedWidth(0)
|
||||
|
||||
@ -36,14 +36,14 @@ namespace blink {
|
||||
|
||||
class FloatingObject;
|
||||
class RenderObject;
|
||||
class RenderBlockFlow;
|
||||
class RenderParagraph;
|
||||
|
||||
enum IndentTextOrNot { DoNotIndentText, IndentText };
|
||||
enum WhitespaceTreatment { ExcludeWhitespace, IncludeWhitespace };
|
||||
|
||||
class LineWidth {
|
||||
public:
|
||||
LineWidth(RenderBlockFlow&, bool isFirstLine, IndentTextOrNot shouldIndentText);
|
||||
LineWidth(RenderParagraph&, bool isFirstLine, IndentTextOrNot shouldIndentText);
|
||||
|
||||
bool fitsOnLine() const { return currentWidth() <= (m_availableWidth + LayoutUnit::epsilon()); }
|
||||
bool fitsOnLine(float extra) const { return currentWidth() + extra <= (m_availableWidth + LayoutUnit::epsilon()); }
|
||||
@ -71,7 +71,7 @@ private:
|
||||
void computeAvailableWidthFromLeftAndRight();
|
||||
void updateLineDimension(LayoutUnit newLineTop, LayoutUnit newLineWidth, const float& newLineLeft, const float& newLineRight);
|
||||
|
||||
RenderBlockFlow& m_block;
|
||||
RenderParagraph& m_block;
|
||||
float m_uncommittedWidth;
|
||||
float m_committedWidth;
|
||||
float m_trailingWhitespaceWidth;
|
||||
|
||||
@ -23,7 +23,6 @@ void main() {
|
||||
|
||||
parent.setLayoutManager(() {
|
||||
if (first) {
|
||||
first = false;
|
||||
parent.width = 200.0;
|
||||
} else {
|
||||
parent.width = 150.0;
|
||||
@ -69,6 +68,7 @@ void main() {
|
||||
expect(secondChild.offsetWidth, equals(200));
|
||||
assertNonChangingValues();
|
||||
|
||||
first = false;
|
||||
parent.setNeedsLayout();
|
||||
|
||||
window.requestAnimationFrame((_) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user