1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/paint/MultiColumnSetPainter.h"
7
8 #include "core/paint/BlockPainter.h"
9 #include "core/paint/BoxPainter.h"
10 #include "core/rendering/PaintInfo.h"
11 #include "core/rendering/RenderMultiColumnSet.h"
12 #include "platform/geometry/LayoutPoint.h"
13
14 namespace blink {
15
paintObject(PaintInfo & paintInfo,const LayoutPoint & paintOffset)16 void MultiColumnSetPainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
17 {
18 if (m_renderMultiColumnSet.style()->visibility() != VISIBLE)
19 return;
20
21 BlockPainter(m_renderMultiColumnSet).paintObject(paintInfo, paintOffset);
22
23 // FIXME: Right now we're only painting in the foreground phase.
24 // Columns should technically respect phases and allow for background/float/foreground overlap etc., just like
25 // RenderBlocks do. Note this is a pretty minor issue, since the old column implementation clipped columns
26 // anyway, thus making it impossible for them to overlap one another. It's also really unlikely that the columns
27 // would overlap another block.
28 if (!m_renderMultiColumnSet.flowThread() || !m_renderMultiColumnSet.isValid() || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
29 return;
30
31 paintColumnRules(paintInfo, paintOffset);
32 }
33
paintColumnRules(PaintInfo & paintInfo,const LayoutPoint & paintOffset)34 void MultiColumnSetPainter::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
35 {
36 if (m_renderMultiColumnSet.flowThread()->isRenderPagedFlowThread())
37 return;
38
39 RenderStyle* blockStyle = m_renderMultiColumnSet.multiColumnBlockFlow()->style();
40 const Color& ruleColor = m_renderMultiColumnSet.resolveColor(blockStyle, CSSPropertyWebkitColumnRuleColor);
41 bool ruleTransparent = blockStyle->columnRuleIsTransparent();
42 EBorderStyle ruleStyle = blockStyle->columnRuleStyle();
43 LayoutUnit ruleThickness = blockStyle->columnRuleWidth();
44 LayoutUnit colGap = m_renderMultiColumnSet.columnGap();
45 bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
46 if (!renderRule)
47 return;
48
49 unsigned colCount = m_renderMultiColumnSet.actualColumnCount();
50 if (colCount <= 1)
51 return;
52
53 bool antialias = BoxPainter::shouldAntialiasLines(paintInfo.context);
54
55 bool leftToRight = m_renderMultiColumnSet.style()->isLeftToRightDirection();
56 LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : m_renderMultiColumnSet.contentLogicalWidth();
57 LayoutUnit ruleAdd = m_renderMultiColumnSet.borderAndPaddingLogicalLeft();
58 LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : m_renderMultiColumnSet.contentLogicalWidth();
59 LayoutUnit inlineDirectionSize = m_renderMultiColumnSet.pageLogicalWidth();
60 BoxSide boxSide = m_renderMultiColumnSet.isHorizontalWritingMode()
61 ? leftToRight ? BSLeft : BSRight
62 : leftToRight ? BSTop : BSBottom;
63
64 for (unsigned i = 0; i < colCount; i++) {
65 // Move to the next position.
66 if (leftToRight) {
67 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
68 currLogicalLeftOffset += inlineDirectionSize + colGap;
69 } else {
70 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
71 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
72 }
73
74 // Now paint the column rule.
75 if (i < colCount - 1) {
76 LayoutUnit ruleLeft = m_renderMultiColumnSet.isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + m_renderMultiColumnSet.borderLeft() + m_renderMultiColumnSet.paddingLeft();
77 LayoutUnit ruleRight = m_renderMultiColumnSet.isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + m_renderMultiColumnSet.contentWidth();
78 LayoutUnit ruleTop = m_renderMultiColumnSet.isHorizontalWritingMode() ? paintOffset.y() + m_renderMultiColumnSet.borderTop() + m_renderMultiColumnSet.paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
79 LayoutUnit ruleBottom = m_renderMultiColumnSet.isHorizontalWritingMode() ? ruleTop + m_renderMultiColumnSet.contentHeight() : ruleTop + ruleThickness;
80 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
81 ObjectPainter::drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
82 }
83
84 ruleLogicalLeft = currLogicalLeftOffset;
85 }
86 }
87
88 } // namespace blink
89