diff --git a/engine/core/rendering/RenderBlock.cpp b/engine/core/rendering/RenderBlock.cpp index 76eb36b7381..92913c00e0d 100644 --- a/engine/core/rendering/RenderBlock.cpp +++ b/engine/core/rendering/RenderBlock.cpp @@ -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 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::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; diff --git a/engine/core/rendering/RenderBlock.h b/engine/core/rendering/RenderBlock.h index 2a33359c637..3dab0c761a4 100644 --- a/engine/core/rendering/RenderBlock.h +++ b/engine/core/rendering/RenderBlock.h @@ -266,7 +266,6 @@ public: protected: virtual void addOverflowFromChildren(); void addOverflowFromPositionedObjects(); - void addOverflowFromBlockChildren(); virtual void addFocusRingRects(Vector&, 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 diff --git a/engine/core/rendering/RenderBlockFlow.h b/engine/core/rendering/RenderBlockFlow.h index 34806d1d657..008a2b5c252 100644 --- a/engine/core/rendering/RenderBlockFlow.h +++ b/engine/core/rendering/RenderBlockFlow.h @@ -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); diff --git a/engine/core/rendering/RenderBlockLineLayout.cpp b/engine/core/rendering/RenderBlockLineLayout.cpp index 3a19e7bedea..3ce73cb0039 100644 --- a/engine/core/rendering/RenderBlockLineLayout.cpp +++ b/engine/core/rendering/RenderBlockLineLayout.cpp @@ -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(); diff --git a/engine/core/rendering/RenderParagraph.cpp b/engine/core/rendering/RenderParagraph.cpp index f8c9e0790df..202db7f0d6c 100644 --- a/engine/core/rendering/RenderParagraph.cpp +++ b/engine/core/rendering/RenderParagraph.cpp @@ -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 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::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 diff --git a/engine/core/rendering/RenderParagraph.h b/engine/core/rendering/RenderParagraph.h index 92d63bba50f..bbf56efcef7 100644 --- a/engine/core/rendering/RenderParagraph.h +++ b/engine/core/rendering/RenderParagraph.h @@ -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());