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; |
Xianzhu
2015/08/06 18:12:45
Note: This map will replace the continuationOutlin
|
+ |
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(); |
+ |
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()); |
+ LayoutRect outlineBounds = unionRect(outlineRects); |
+ outlineBounds.inflate(flow->styleRef().outlineOutsetExtent()); |
+ outlineBoundsOfAllContinuations.unite(outlineBounds); |
+ } |
+ addContentsVisualOverflow(outlineBoundsOfAllContinuations); |
} |
void LayoutBlockFlow::deleteEllipsisLineBoxes() |