1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/paint/BoxClipper.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderBox.h"
#include "core/rendering/RenderLayer.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/paint/ClipDisplayItem.h"
#include "platform/graphics/paint/DisplayItemList.h"
namespace blink {
BoxClipper::BoxClipper(RenderBox& box, const PaintInfo& paintInfo, const LayoutPoint& accumulatedOffset, ContentsClipBehavior contentsClipBehavior)
: m_pushedClip(false)
, m_accumulatedOffset(accumulatedOffset)
, m_paintInfo(paintInfo)
, m_box(box)
{
if (m_paintInfo.phase == PaintPhaseBlockBackground || m_paintInfo.phase == PaintPhaseSelfOutline || m_paintInfo.phase == PaintPhaseMask)
return;
bool isControlClip = m_box.hasControlClip();
bool isOverflowClip = m_box.hasOverflowClip() && !m_box.layer()->isSelfPaintingLayer();
if (!isControlClip && !isOverflowClip)
return;
LayoutRect clipRect = isControlClip ? m_box.controlClipRect(m_accumulatedOffset) : m_box.overflowClipRect(m_accumulatedOffset);
FloatRoundedRect clipRoundedRect(0, 0, 0, 0);
bool hasBorderRadius = m_box.style()->hasBorderRadius();
if (hasBorderRadius)
clipRoundedRect = m_box.style()->getRoundedInnerBorderFor(LayoutRect(m_accumulatedOffset, m_box.size()));
if (contentsClipBehavior == SkipContentsClipIfPossible) {
LayoutRect contentsVisualOverflow = m_box.contentsVisualOverflowRect();
if (contentsVisualOverflow.isEmpty())
return;
LayoutRect conservativeClipRect = clipRect;
if (hasBorderRadius)
conservativeClipRect.intersect(LayoutRect(clipRoundedRect.radiusCenterRect()));
conservativeClipRect.moveBy(-m_accumulatedOffset);
if (m_box.hasLayer())
conservativeClipRect.move(m_box.scrolledContentOffset());
if (conservativeClipRect.contains(contentsVisualOverflow))
return;
}
DisplayItem::Type clipType = DisplayItem::ClipBoxForeground;
if (RuntimeEnabledFeatures::slimmingPaintEnabled())
clipType = m_paintInfo.displayItemTypeForClipping();
OwnPtr<ClipDisplayItem> clipDisplayItem = ClipDisplayItem::create(m_box.displayItemClient(), clipType, pixelSnappedIntRect(clipRect));
if (hasBorderRadius)
clipDisplayItem->roundedRectClips().append(clipRoundedRect);
if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
ASSERT(m_paintInfo.context->displayItemList());
m_paintInfo.context->displayItemList()->add(clipDisplayItem.release());
} else
clipDisplayItem->replay(paintInfo.context);
m_pushedClip = true;
}
BoxClipper::~BoxClipper()
{
if (!m_pushedClip)
return;
ASSERT(m_box.hasControlClip() || (m_box.hasOverflowClip() && !m_box.layer()->isSelfPaintingLayer()));
OwnPtr<EndClipDisplayItem> endClipDisplayItem = EndClipDisplayItem::create(m_box.displayItemClient());
if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
ASSERT(m_paintInfo.context->displayItemList());
m_paintInfo.context->displayItemList()->add(endClipDisplayItem.release());
} else {
endClipDisplayItem->replay(m_paintInfo.context);
}
}
} // namespace blink
|