Chromium Code Reviews| Index: Source/core/layout/LayoutBlockFlowLine.cpp |
| diff --git a/Source/core/layout/LayoutBlockFlowLine.cpp b/Source/core/layout/LayoutBlockFlowLine.cpp |
| index ec91c14250785e1970d3db3c59bddc7b833fa4aa..80c56cef31e30ac4cf8a4032efc55ee696dadcd6 100644 |
| --- a/Source/core/layout/LayoutBlockFlowLine.cpp |
| +++ b/Source/core/layout/LayoutBlockFlowLine.cpp |
| @@ -52,6 +52,9 @@ namespace blink { |
| using namespace WTF::Unicode; |
| +typedef WTF::HashMap<LayoutBlockFlow*, HashSet<LayoutInline*>> InlinesWithOutlineAndContinuationMap; |
| +static InlinesWithOutlineAndContinuationMap* gInlinesWithOutlineAndContinuationMap = nullptr; |
| + |
| static inline InlineBox* createInlineBoxForLayoutObject(LayoutObject* obj, bool isRootLineBox, bool isOnlyRun = false) |
| { |
| // Callers should handle text themselves. |
| @@ -1489,6 +1492,19 @@ void LayoutBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical |
| maxLogicalWidth = std::max(maxLogicalWidth, inlineMax); |
| } |
| +void LayoutBlockFlow::removeInlinesWithOutlineAndContinuation() |
| +{ |
| + if (gInlinesWithOutlineAndContinuationMap) |
| + gInlinesWithOutlineAndContinuationMap->remove(this); |
| +} |
| + |
| +void LayoutBlockFlow::addInlineWithOutlineAndContinuation(LayoutInline* layoutInline) |
| +{ |
| + if (!gInlinesWithOutlineAndContinuationMap) |
| + gInlinesWithOutlineAndContinuationMap = new InlinesWithOutlineAndContinuationMap; |
| + gInlinesWithOutlineAndContinuationMap->add(this, HashSet<LayoutInline*>()).storedValue->value.add(layoutInline); |
| +} |
| + |
| void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& paintInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUnit afterEdge) |
| { |
| LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| @@ -1522,6 +1538,8 @@ void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& pa |
| if (hasTextOverflow) |
| deleteEllipsisLineBoxes(); |
| + removeInlinesWithOutlineAndContinuation(); |
|
leviw_travelin_and_unemployed
2015/08/10 20:13:14
It's a bit unfortunate that we incur a hash lookup
Xianzhu
2015/08/11 17:57:50
Ran top-10k web sites, 7986 of them succeeded, and
|
| + |
| if (firstChild()) { |
| // In full layout mode, clear the line boxes of children upfront. Otherwise, |
| // siblings can run into stale root lineboxes during layout. Then layout |
| @@ -1566,6 +1584,9 @@ void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& pa |
| } |
| if (!o->isText() || !toLayoutText(o)->isAllCollapsibleWhitespace()) |
| lastChild = o; |
| + |
| + if (o->isLayoutInline() && o->styleRef().hasOutline() && !o->isElementContinuation() && toLayoutInline(o)->continuation()) |
| + addInlineWithOutlineAndContinuation(toLayoutInline(o)); |
| } |
| // If there is a trailing float on the line that will possibly occur after a natural line break |
| // then dirty its adjacent lineboxes to ensure it gets placed. |
| @@ -1863,6 +1884,23 @@ void LayoutBlockFlow::addOverflowFromInlineChildren() |
| LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), curr->lineBottom()); |
| addContentsVisualOverflow(visualOverflow); |
| } |
| + |
| + if (!gInlinesWithOutlineAndContinuationMap) |
| + return; |
| + InlinesWithOutlineAndContinuationMap::const_iterator it = gInlinesWithOutlineAndContinuationMap->find(this); |
| + if (it == gInlinesWithOutlineAndContinuationMap->end() || it->value.isEmpty()) |
| + return; |
| + |
| + // Add outline rects of continuations of descendant inlines into visual overflow of this block. |
| + LayoutRect outlineBoundsOfAllContinuations; |
| + for (LayoutInline* flow : it->value) { |
| + Vector<LayoutRect> outlineRects; |
| + flow->addOutlineRectsForContinuations(outlineRects, LayoutPoint()); |
|
chrishtr
2015/08/10 23:45:33
Is this cache really so important for performance?
Xianzhu
2015/08/11 17:57:50
They are in different document stages. The code fr
chrishtr
2015/08/13 20:04:13
You're saying that the layout data necessary to lo
Xianzhu
2015/08/13 20:26:00
I see. That would cause we always traverse the who
|
| + LayoutRect outlineBounds = unionRect(outlineRects); |
| + outlineBounds.inflate(flow->styleRef().outlineOutsetExtent()); |
| + outlineBoundsOfAllContinuations.unite(outlineBounds); |
| + } |
| + addContentsVisualOverflow(outlineBoundsOfAllContinuations); |
| } |
| void LayoutBlockFlow::deleteEllipsisLineBoxes() |