Start splitting RenderParagraph logic out of RenderBlock.

In particular, move RenderParagraph-specific code from
hitTestContents, paintContents, simplifiedNormalFlowLayout & addOverflowFromChildren.

R=ojan@chromium.org

Review URL: https://codereview.chromium.org/754493002
This commit is contained in:
Rafael Weinstein 2014-11-26 11:15:01 -08:00
parent 253b5bed74
commit 9e43ce3605
6 changed files with 91 additions and 89 deletions

View File

@ -400,10 +400,10 @@ void RenderBlock::layoutBlock(bool)
void RenderBlock::addOverflowFromChildren()
{
if (isRenderParagraph())
toRenderBlockFlow(this)->addOverflowFromInlineChildren();
else
addOverflowFromBlockChildren();
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
if (!child->isFloatingOrOutOfFlowPositioned())
addOverflowFromChild(child);
}
}
void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
@ -431,14 +431,6 @@ void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
addVisualEffectOverflow();
}
void RenderBlock::addOverflowFromBlockChildren()
{
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
if (!child->isFloatingOrOutOfFlowPositioned())
addOverflowFromChild(child);
}
}
void RenderBlock::addOverflowFromPositionedObjects()
{
TrackedRendererListHashSet* positionedDescendants = positionedObjects();
@ -472,32 +464,9 @@ void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, R
void RenderBlock::simplifiedNormalFlowLayout()
{
if (isRenderParagraph()) {
ListHashSet<RootInlineBox*> lineBoxes;
for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
RenderObject* o = walker.current();
if (!o->isOutOfFlowPositioned() && o->isReplaced()) {
o->layoutIfNeeded();
if (toRenderBox(o)->inlineBoxWrapper()) {
RootInlineBox& box = toRenderBox(o)->inlineBoxWrapper()->root();
lineBoxes.add(&box);
}
} else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
o->clearNeedsLayout();
}
}
// FIXME: Glyph overflow will get lost in this case, but not really a big deal.
GlyphOverflowAndFallbackFontsMap textBoxDataMap;
for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
RootInlineBox* box = *it;
box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
}
} else {
for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
if (!box->isOutOfFlowPositioned())
box->layoutIfNeeded();
}
for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
if (!box->isOutOfFlowPositioned())
box->layoutIfNeeded();
}
}
@ -651,24 +620,14 @@ void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// Avoid painting descendants of the root element when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
// will do a full paint invalidation.
if (document().didLayoutWithPendingStylesheets() && !isRenderView())
return;
PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
if (isRenderParagraph())
m_lineBoxes.paint(this, paintInfo, paintOffset);
else {
PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
// We don't paint our own background, but we do let the kids paint their backgrounds.
PaintInfo paintInfoForChild(paintInfo);
paintInfoForChild.phase = newPhase;
paintInfoForChild.updatePaintingRootForChildren(this);
paintChildren(paintInfoForChild, paintOffset);
}
// We don't paint our own background, but we do let the kids paint their backgrounds.
PaintInfo paintInfoForChild(paintInfo);
paintInfoForChild.phase = newPhase;
paintInfoForChild.updatePaintingRootForChildren(this);
paintChildren(paintInfoForChild, paintOffset);
}
void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@ -771,8 +730,13 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
return;
// 2. paint contents
if (paintPhase != PaintPhaseSelfOutline)
paintContents(paintInfo, scrolledOffset);
if (paintPhase != PaintPhaseSelfOutline) {
// Avoid painting descendants of the root element when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
// will do a full paint invalidation.
if (!document().didLayoutWithPendingStylesheets() || isRenderView())
paintContents(paintInfo, scrolledOffset);
}
// 3. paint selection
// FIXME: Make this work with multi column layouts. For now don't fill gaps.
@ -1419,19 +1383,13 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
{
if (isRenderParagraph()) {
// We have to hit-test our line boxes.
if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction))
// Hit test our children.
HitTestAction childHitTest = hitTestAction;
if (hitTestAction == HitTestChildBlockBackgrounds)
childHitTest = HitTestChildBlockBackground;
for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
if (!child->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, childHitTest))
return true;
} else {
// Hit test our children.
HitTestAction childHitTest = hitTestAction;
if (hitTestAction == HitTestChildBlockBackgrounds)
childHitTest = HitTestChildBlockBackground;
for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
if (!child->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, childHitTest))
return true;
}
}
return false;

View File

@ -266,7 +266,6 @@ public:
protected:
virtual void addOverflowFromChildren();
void addOverflowFromPositionedObjects();
void addOverflowFromBlockChildren();
virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) const override;
@ -276,6 +275,10 @@ protected:
virtual void invalidateTreeIfNeeded(const PaintInvalidationState&) override;
virtual void paintContents(PaintInfo&, const LayoutPoint&);
virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
private:
virtual RenderObjectChildList* virtualChildren() override final { return children(); }
virtual const RenderObjectChildList* virtualChildren() const override final { return children(); }
@ -291,14 +294,11 @@ private:
void insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
static void removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
void paintContents(PaintInfo&, const LayoutPoint&);
void paintSelection(PaintInfo&, const LayoutPoint&);
void paintCarets(PaintInfo&, const LayoutPoint&);
bool hasCaret() const;
bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
// Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline

View File

@ -115,8 +115,6 @@ public:
return obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline();
}
void addOverflowFromInlineChildren();
// FIXME: This should be const to avoid a const_cast, but can modify child dirty bits
void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);

View File

@ -1487,20 +1487,6 @@ bool RenderBlockFlow::generatesLineBoxesForInlineChild(RenderObject* inlineObj)
return !it.atEnd();
}
void RenderBlockFlow::addOverflowFromInlineChildren()
{
LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit();
// FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElement() && style()->isLeftToRightDirection())
endPadding = 1;
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding));
LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), curr->lineBottom());
addContentsVisualOverflow(visualOverflow);
}
}
void RenderBlockFlow::deleteEllipsisLineBoxes()
{
ETextAlign textAlign = style()->textAlign();

View File

@ -5,6 +5,8 @@
#include "sky/engine/config.h"
#include "sky/engine/core/rendering/RenderParagraph.h"
#include "sky/engine/core/rendering/InlineIterator.h"
namespace blink {
RenderParagraph::RenderParagraph(ContainerNode* node)
@ -23,4 +25,52 @@ RenderParagraph* RenderParagraph::createAnonymous(Document& document)
return renderer;
}
void RenderParagraph::addOverflowFromChildren()
{
LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit();
// FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElement() && style()->isLeftToRightDirection())
endPadding = 1;
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding));
LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), curr->lineBottom());
addContentsVisualOverflow(visualOverflow);
}
}
void RenderParagraph::simplifiedNormalFlowLayout()
{
ListHashSet<RootInlineBox*> lineBoxes;
for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
RenderObject* o = walker.current();
if (!o->isOutOfFlowPositioned() && o->isReplaced()) {
o->layoutIfNeeded();
if (toRenderBox(o)->inlineBoxWrapper()) {
RootInlineBox& box = toRenderBox(o)->inlineBoxWrapper()->root();
lineBoxes.add(&box);
}
} else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
o->clearNeedsLayout();
}
}
// FIXME: Glyph overflow will get lost in this case, but not really a big deal.
GlyphOverflowAndFallbackFontsMap textBoxDataMap;
for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
RootInlineBox* box = *it;
box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
}
}
void RenderParagraph::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
m_lineBoxes.paint(this, paintInfo, paintOffset);
}
bool RenderParagraph::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
{
return m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
}
} // namespace blink

View File

@ -20,6 +20,16 @@ public:
static RenderParagraph* createAnonymous(Document&);
bool isRenderParagraph() const override { return true; }
protected:
void addOverflowFromChildren() final;
void simplifiedNormalFlowLayout() final;
void paintContents(PaintInfo&, const LayoutPoint&) final;
bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) final;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderParagraph, isRenderParagraph());