- Revision
- 126177
- Author
- [email protected]
- Date
- 2012-08-21 11:15:39 -0700 (Tue, 21 Aug 2012)
Log Message
[New Multicolumn] Make column rules paint properly.
https://bugs.webkit.org/show_bug.cgi?id=94616
Reviewed by Simon Fraser.
Make the new multi-column code paint column rules and also prepare it for painting
the actual column contents.
* rendering/RenderMultiColumnBlock.cpp:
(WebCore::RenderMultiColumnBlock::ensureColumnSets):
Remove the addRegionToThread call, since this is now done automatically in RenderRegion::insertedIntoTree.
* rendering/RenderMultiColumnBlock.h:
(WebCore::RenderMultiColumnBlock::flowThread):
Make public so that RenderMultiColumnSet can access it.
(RenderMultiColumnBlock):
* rendering/RenderMultiColumnSet.cpp:
(WebCore::RenderMultiColumnSet::columnGap):
Add a column gap fetch method. It's identical to the one on RenderBlock (which will eventually go away
when we kill the old multi-column code).
(WebCore::RenderMultiColumnSet::columnRectAt):
Also identical to the RenderBlock version of this method. Gets the rect for the nth column.
(WebCore::RenderMultiColumnSet::paintReplaced):
Subclass paintReplaced in order to do column rules and contents painting.
(WebCore::RenderMultiColumnSet::paintColumnRules):
(WebCore::RenderMultiColumnSet::paintColumnContents):
Similar to the methods on RenderBlock. The former paints the rules and the latter paints the contents of
the flow thread into the columns.
* rendering/RenderMultiColumnSet.h:
(RenderMultiColumnSet):
Add the declarations of all the new methods.
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::installFlowThread):
Added a new virtual function for installing flow threads when they didn't exist at construction time.
This only applies to actual CSS Regions, so the subclass of the method in RenderRegionSet just does
nothing.
(WebCore::RenderRegion::attachRegion):
Get the named flow thread code out of attachRegion, since it broke multi-column. Moved it into a
virtual function, installFlowThread, that is only used by actual CSS regions. Eventually we may
want a RenderRegion subclass that represents a region for a named flow thread only, but for now
let the code sit in installFlowThread in the base class.
* rendering/RenderRegion.h:
(RenderRegion):
Add installFlowThread declaration.
* rendering/RenderRegionSet.cpp:
(WebCore::RenderRegionSet::installFlowThread):
installFlowThread for region sets just does nothing, since we don't use named flow threads.
* rendering/RenderRegionSet.h:
(RenderRegionSet):
Add the override of installFlowThread.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (126176 => 126177)
--- trunk/Source/WebCore/ChangeLog 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/ChangeLog 2012-08-21 18:15:39 UTC (rev 126177)
@@ -1,3 +1,66 @@
+2012-08-21 David Hyatt <[email protected]>
+
+ [New Multicolumn] Make column rules paint properly.
+ https://bugs.webkit.org/show_bug.cgi?id=94616
+
+ Reviewed by Simon Fraser.
+
+ Make the new multi-column code paint column rules and also prepare it for painting
+ the actual column contents.
+
+ * rendering/RenderMultiColumnBlock.cpp:
+ (WebCore::RenderMultiColumnBlock::ensureColumnSets):
+ Remove the addRegionToThread call, since this is now done automatically in RenderRegion::insertedIntoTree.
+
+ * rendering/RenderMultiColumnBlock.h:
+ (WebCore::RenderMultiColumnBlock::flowThread):
+ Make public so that RenderMultiColumnSet can access it.
+
+ (RenderMultiColumnBlock):
+ * rendering/RenderMultiColumnSet.cpp:
+ (WebCore::RenderMultiColumnSet::columnGap):
+ Add a column gap fetch method. It's identical to the one on RenderBlock (which will eventually go away
+ when we kill the old multi-column code).
+
+ (WebCore::RenderMultiColumnSet::columnRectAt):
+ Also identical to the RenderBlock version of this method. Gets the rect for the nth column.
+
+ (WebCore::RenderMultiColumnSet::paintReplaced):
+ Subclass paintReplaced in order to do column rules and contents painting.
+
+ (WebCore::RenderMultiColumnSet::paintColumnRules):
+ (WebCore::RenderMultiColumnSet::paintColumnContents):
+ Similar to the methods on RenderBlock. The former paints the rules and the latter paints the contents of
+ the flow thread into the columns.
+
+ * rendering/RenderMultiColumnSet.h:
+ (RenderMultiColumnSet):
+ Add the declarations of all the new methods.
+
+ * rendering/RenderRegion.cpp:
+ (WebCore::RenderRegion::installFlowThread):
+ Added a new virtual function for installing flow threads when they didn't exist at construction time.
+ This only applies to actual CSS Regions, so the subclass of the method in RenderRegionSet just does
+ nothing.
+
+ (WebCore::RenderRegion::attachRegion):
+ Get the named flow thread code out of attachRegion, since it broke multi-column. Moved it into a
+ virtual function, installFlowThread, that is only used by actual CSS regions. Eventually we may
+ want a RenderRegion subclass that represents a region for a named flow thread only, but for now
+ let the code sit in installFlowThread in the base class.
+
+ * rendering/RenderRegion.h:
+ (RenderRegion):
+ Add installFlowThread declaration.
+
+ * rendering/RenderRegionSet.cpp:
+ (WebCore::RenderRegionSet::installFlowThread):
+ installFlowThread for region sets just does nothing, since we don't use named flow threads.
+
+ * rendering/RenderRegionSet.h:
+ (RenderRegionSet):
+ Add the override of installFlowThread.
+
2012-08-21 Patrick Gansterer <[email protected]>
[WIN] Build fix for !ENABLE(DRAG_SUPPORT).
Modified: trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp 2012-08-21 18:15:39 UTC (rev 126177)
@@ -144,7 +144,6 @@
RenderMultiColumnSet* columnSet = new (renderArena()) RenderMultiColumnSet(document(), flowThread());
columnSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
RenderBlock::addChild(columnSet, firstChild());
- flowThread()->addRegionToThread(columnSet);
}
}
Modified: trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h 2012-08-21 18:15:39 UTC (rev 126177)
@@ -43,6 +43,8 @@
LayoutUnit columnWidth() const { return m_columnWidth; }
unsigned columnCount() const { return m_columnCount; }
+ RenderMultiColumnFlowThread* flowThread() const { return m_flowThread; }
+
private:
virtual bool isRenderMultiColumnBlock() const { return true; }
@@ -58,8 +60,6 @@
void ensureColumnSets();
- RenderMultiColumnFlowThread* flowThread() const { return m_flowThread; }
-
RenderMultiColumnFlowThread* m_flowThread;
unsigned m_columnCount; // The default column count/width that are based off our containing block width. These values represent only the default,
LayoutUnit m_columnWidth; // since a multi-column block that is split across variable width pages or regions will have different column counts and widths in each.
Modified: trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp 2012-08-21 18:15:39 UTC (rev 126177)
@@ -24,6 +24,8 @@
*/
#include "config.h"
+#include "PaintInfo.h"
+#include "RenderMultiColumnFlowThread.h"
#include "RenderMultiColumnSet.h"
#include "RenderMultiColumnBlock.h"
@@ -60,6 +62,106 @@
setLogicalHeight(columnHeight());
}
+LayoutUnit RenderMultiColumnSet::columnGap() const
+{
+ if (style()->hasNormalColumnGap())
+ return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
+ return static_cast<int>(style()->columnGap());
+}
+
+LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const
+{
+ LayoutUnit colLogicalWidth = columnWidth();
+ LayoutUnit colLogicalHeight = columnHeight();
+ LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
+ LayoutUnit colLogicalLeft = borderAndPaddingLogicalLeft();
+ int colGap = columnGap();
+ if (style()->isLeftToRightDirection())
+ colLogicalLeft += index * (colLogicalWidth + colGap);
+ else
+ colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
+
+ if (isHorizontalWritingMode())
+ return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
+ return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
+}
+
+void RenderMultiColumnSet::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+ // FIXME: RenderRegions are replaced elements right now and so they only paint in the foreground phase.
+ // Columns should technically respect phases and allow for background/float/foreground overlap etc., just like
+ // RenderBlocks do. We can't correct this, however, until RenderRegions are changed to actually be
+ // RenderBlocks. Note this is a pretty minor issue, since the old column implementation clipped columns
+ // anyway, thus making it impossible for them to overlap one another. It's also really unlikely that the columns
+ // would overlap another block.
+ setRegionObjectsRegionStyle();
+ paintColumnRules(paintInfo, paintOffset);
+ paintColumnContents(paintInfo, paintOffset);
+ restoreRegionObjectsOriginalStyle();
+}
+
+void RenderMultiColumnSet::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+ if (paintInfo.context->paintingDisabled())
+ return;
+
+ RenderStyle* blockStyle = toRenderMultiColumnBlock(parent())->style();
+ const Color& ruleColor = blockStyle->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
+ bool ruleTransparent = blockStyle->columnRuleIsTransparent();
+ EBorderStyle ruleStyle = blockStyle->columnRuleStyle();
+ LayoutUnit ruleThickness = blockStyle->columnRuleWidth();
+ LayoutUnit colGap = columnGap();
+ bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleThickness <= colGap;
+ if (!renderRule)
+ return;
+
+ unsigned colCount = columnCount();
+
+ bool antialias = shouldAntialiasLines(paintInfo.context);
+
+ bool leftToRight = style()->isLeftToRightDirection();
+ LayoutUnit currLogicalLeftOffset = leftToRight ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
+ LayoutUnit ruleAdd = borderAndPaddingLogicalLeft();
+ LayoutUnit ruleLogicalLeft = leftToRight ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
+ LayoutUnit inlineDirectionSize = columnWidth();
+ BoxSide boxSide = isHorizontalWritingMode()
+ ? leftToRight ? BSLeft : BSRight
+ : leftToRight ? BSTop : BSBottom;
+
+ for (unsigned i = 0; i < colCount; i++) {
+ // Move to the next position.
+ if (leftToRight) {
+ ruleLogicalLeft += inlineDirectionSize + colGap / 2;
+ currLogicalLeftOffset += inlineDirectionSize + colGap;
+ } else {
+ ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
+ currLogicalLeftOffset -= (inlineDirectionSize + colGap);
+ }
+
+ // Now paint the column rule.
+ if (i < colCount - 1) {
+ LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
+ LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
+ LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
+ LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
+ IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
+ drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
+ }
+
+ ruleLogicalLeft = currLogicalLeftOffset;
+ }
+}
+
+void RenderMultiColumnSet::paintColumnContents(PaintInfo& /* paintInfo */, const LayoutPoint& /* paintOffset */)
+{
+ // For each rectangle, set it as the region rectangle and then let flow thread painting do the rest.
+ // We make multiple calls to paintIntoRegion, changing the rectangles each time.
+ if (!columnCount())
+ return;
+
+ // FIXME: Implement.
+}
+
const char* RenderMultiColumnSet::renderName() const
{
return "RenderMultiColumnSet";
Modified: trunk/Source/WebCore/rendering/RenderMultiColumnSet.h (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderMultiColumnSet.h 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnSet.h 2012-08-21 18:15:39 UTC (rev 126177)
@@ -65,11 +65,19 @@
virtual void computeLogicalWidth() OVERRIDE;
virtual void computeLogicalHeight() OVERRIDE;
+ virtual void paintReplaced(PaintInfo&, const LayoutPoint& paintOffset) OVERRIDE;
+
virtual LayoutUnit logicalWidthForFlowThreadContent() const OVERRIDE { return m_columnWidth; }
virtual LayoutUnit logicalHeightForFlowThreadContent() const OVERRIDE { return m_columnHeight; } // FIXME: Will be wrong once we have multiple sets.
virtual const char* renderName() const;
+ void paintColumnRules(PaintInfo&, const LayoutPoint& paintOffset);
+ void paintColumnContents(PaintInfo&, const LayoutPoint& paintOffset);
+
+ LayoutUnit columnGap() const;
+ LayoutRect columnRectAt( unsigned index) const;
+
unsigned m_columnCount;
LayoutUnit m_columnWidth;
LayoutUnit m_columnHeight;
Modified: trunk/Source/WebCore/rendering/RenderRegion.cpp (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderRegion.cpp 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderRegion.cpp 2012-08-21 18:15:39 UTC (rev 126177)
@@ -191,19 +191,12 @@
// We'll need to expand RenderBoxRegionInfo to also hold left and right overflow values.
}
-void RenderRegion::attachRegion()
+void RenderRegion::installFlowThread()
{
ASSERT(view());
- ASSERT(!m_flowThread);
- // Initialize the flow thread reference and create the flow thread object if needed.
- // The flow thread lifetime is influenced by the number of regions attached to it,
- // and we are attaching the region to the flow thread.
+
m_flowThread = view()->flowThreadController()->ensureRenderFlowThreadWithName(style()->regionThread());
- // A region is valid if it is not part of a circular reference, which is checked below
- // and in RenderNamedFlowThread::addRegionToThread.
- setIsValid(false);
-
// By now the flow thread should already be added to the rendering tree,
// so we go up the rendering parents and check that this region is not part of the same
// flow that it actually needs to display. It would create a circular reference.
@@ -214,16 +207,29 @@
m_parentNamedFlowThread = toRenderNamedFlowThread(parentObject);
// Do not take into account a region that links a flow with itself. The dependency
// cannot change, so it is not worth adding it to the list.
- if (m_flowThread == m_parentNamedFlowThread) {
+ if (m_flowThread == m_parentNamedFlowThread)
m_flowThread = 0;
- // This region is not valid for this flow thread (as being part of a circular dependency).
- setIsValid(false);
- return;
- }
break;
}
}
+}
+void RenderRegion::attachRegion()
+{
+ if (documentBeingDestroyed())
+ return;
+
+ // A region starts off invalid.
+ setIsValid(false);
+
+ // Initialize the flow thread reference and create the flow thread object if needed.
+ // The flow thread lifetime is influenced by the number of regions attached to it,
+ // and we are attaching the region to the flow thread.
+ installFlowThread();
+
+ if (!m_flowThread)
+ return;
+
m_flowThread->addRegionToThread(this);
// The region just got attached to the flow thread, lets check whether
Modified: trunk/Source/WebCore/rendering/RenderRegion.h (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderRegion.h 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderRegion.h 2012-08-21 18:15:39 UTC (rev 126177)
@@ -97,23 +97,29 @@
virtual LayoutUnit logicalWidthForFlowThreadContent() const;
virtual LayoutUnit logicalHeightForFlowThreadContent() const;
+protected:
+ void setRegionObjectsRegionStyle();
+ void restoreRegionObjectsOriginalStyle();
+
private:
virtual const char* renderName() const { return "RenderRegion"; }
virtual void insertedIntoTree() OVERRIDE;
virtual void willBeRemovedFromTree() OVERRIDE;
+ virtual void installFlowThread();
+
PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*);
void computeChildrenStyleInRegion(const RenderObject*);
- void setRegionObjectsRegionStyle();
- void restoreRegionObjectsOriginalStyle();
void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached);
void printRegionObjectsStyles();
void checkRegionStyle();
+protected:
RenderFlowThread* m_flowThread;
+private:
// If this RenderRegion is displayed as part of another named flow,
// we need to create a dependency tree, so that layout of the
// regions is always done before the regions themselves.
Modified: trunk/Source/WebCore/rendering/RenderRegionSet.cpp (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderRegionSet.cpp 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderRegionSet.cpp 2012-08-21 18:15:39 UTC (rev 126177)
@@ -33,4 +33,10 @@
{
}
+void RenderRegionSet::installFlowThread()
+{
+ // We don't have to do anything, since we were able to connect the flow thread
+ // in the constructor.
}
+
+}
Modified: trunk/Source/WebCore/rendering/RenderRegionSet.h (126176 => 126177)
--- trunk/Source/WebCore/rendering/RenderRegionSet.h 2012-08-21 18:10:22 UTC (rev 126176)
+++ trunk/Source/WebCore/rendering/RenderRegionSet.h 2012-08-21 18:15:39 UTC (rev 126177)
@@ -50,6 +50,8 @@
RenderRegionSet(Node*, RenderFlowThread*);
private:
+ virtual void installFlowThread() OVERRIDE;
+
virtual const char* renderName() const = 0;
};