17242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
27242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Use of this source code is governed by a BSD-style license that can be
37242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// found in the LICENSE file.
47242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
57242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "config.h"
67242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/MultiColumnSetPainter.h"
77242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
87242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/BlockPainter.h"
97242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/BoxPainter.h"
107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/PaintInfo.h"
117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/RenderMultiColumnSet.h"
127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/geometry/LayoutPoint.h"
137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccinamespace blink {
157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid MultiColumnSetPainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (m_renderMultiColumnSet.style()->visibility() != VISIBLE)
197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    BlockPainter(m_renderMultiColumnSet).paintObject(paintInfo, paintOffset);
227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // FIXME: Right now we're only painting in the foreground phase.
247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Columns should technically respect phases and allow for background/float/foreground overlap etc., just like
257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // RenderBlocks do. Note this is a pretty minor issue, since the old column implementation clipped columns
267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // anyway, thus making it impossible for them to overlap one another. It's also really unlikely that the columns
277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // would overlap another block.
287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!m_renderMultiColumnSet.flowThread() || !m_renderMultiColumnSet.isValid() || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    paintColumnRules(paintInfo, paintOffset);
327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid MultiColumnSetPainter::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (m_renderMultiColumnSet.flowThread()->isRenderPagedFlowThread())
377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RenderStyle* blockStyle = m_renderMultiColumnSet.multiColumnBlockFlow()->style();
407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const Color& ruleColor = m_renderMultiColumnSet.resolveColor(blockStyle, CSSPropertyWebkitColumnRuleColor);
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool ruleTransparent = blockStyle->columnRuleIsTransparent();
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    EBorderStyle ruleStyle = blockStyle->columnRuleStyle();
437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    LayoutUnit ruleThickness = blockStyle->columnRuleWidth();
447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    LayoutUnit colGap = m_renderMultiColumnSet.columnGap();
457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!renderRule)
477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    unsigned colCount = m_renderMultiColumnSet.actualColumnCount();
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (colCount <= 1)
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool antialias = BoxPainter::shouldAntialiasLines(paintInfo.context);
547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool leftToRight = m_renderMultiColumnSet.style()->isLeftToRightDirection();
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : m_renderMultiColumnSet.contentLogicalWidth();
577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    LayoutUnit ruleAdd = m_renderMultiColumnSet.borderAndPaddingLogicalLeft();
587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : m_renderMultiColumnSet.contentLogicalWidth();
597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    LayoutUnit inlineDirectionSize = m_renderMultiColumnSet.pageLogicalWidth();
607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    BoxSide boxSide = m_renderMultiColumnSet.isHorizontalWritingMode()
617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ? leftToRight ? BSLeft : BSRight
627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        : leftToRight ? BSTop : BSBottom;
637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for (unsigned i = 0; i < colCount; i++) {
657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Move to the next position.
667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (leftToRight) {
677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ruleLogicalLeft += inlineDirectionSize + colGap / 2;
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            currLogicalLeftOffset += inlineDirectionSize + colGap;
697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        } else {
707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            currLogicalLeftOffset -= (inlineDirectionSize + colGap);
727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Now paint the column rule.
757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (i < colCount - 1) {
767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            LayoutUnit ruleLeft = m_renderMultiColumnSet.isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + m_renderMultiColumnSet.borderLeft() + m_renderMultiColumnSet.paddingLeft();
777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            LayoutUnit ruleRight = m_renderMultiColumnSet.isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + m_renderMultiColumnSet.contentWidth();
787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            LayoutUnit ruleTop = m_renderMultiColumnSet.isHorizontalWritingMode() ? paintOffset.y() + m_renderMultiColumnSet.borderTop() + m_renderMultiColumnSet.paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            LayoutUnit ruleBottom = m_renderMultiColumnSet.isHorizontalWritingMode() ? ruleTop + m_renderMultiColumnSet.contentHeight() : ruleTop + ruleThickness;
807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ObjectPainter::drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ruleLogicalLeft = currLogicalLeftOffset;
857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // namespace blink
89