mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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:
parent
253b5bed74
commit
9e43ce3605
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user