File: BoxDecorationData.cpp

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (91 lines) | stat: -rw-r--r-- 3,915 bytes parent folder | download
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
89
90
91
// 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/BoxDecorationData.h"

#include "core/rendering/RenderBox.h"
#include "core/rendering/style/BorderEdge.h"
#include "core/rendering/style/RenderStyle.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/GraphicsContext.h"

namespace blink {

BoxDecorationData::BoxDecorationData(const RenderBox& renderBox, GraphicsContext* context)
{
    backgroundColor = renderBox.style()->visitedDependentColor(CSSPropertyBackgroundColor);
    hasBackground = backgroundColor.alpha() || renderBox.style()->hasBackgroundImage();
    ASSERT(hasBackground == renderBox.style()->hasBackground());
    hasBorder = renderBox.style()->hasBorder();
    hasAppearance = renderBox.style()->hasAppearance();

    m_bleedAvoidance = determineBackgroundBleedAvoidance(renderBox, context);
}

BackgroundBleedAvoidance BoxDecorationData::determineBackgroundBleedAvoidance(const RenderBox& renderBox, GraphicsContext* context)
{
    if (renderBox.isDocumentElement())
        return BackgroundBleedNone;

    if (!hasBackground)
        return BackgroundBleedNone;

    if (!hasBorder || !renderBox.style()->hasBorderRadius() || renderBox.canRenderBorderImage()) {
        if (renderBox.backgroundShouldAlwaysBeClipped())
            return BackgroundBleedClipBackground;
        return BackgroundBleedNone;
    }

    // If display lists are enabled (via Slimming Paint), then simply clip the background and do not
    // perform advanced bleed-avoidance heuristics. These heuristics are not correct in the presence
    // of impl-side rasterization or layerization, since the actual pixel-relative scaling and rotation
    // of the content is not known to Blink.
    if (RuntimeEnabledFeatures::slimmingPaintEnabled())
        return BackgroundBleedClipBackground;

    // FIXME: See crbug.com/382491. getCTM does not accurately reflect the scale at the time content is
    // rasterized, and should not be relied on to make decisions about bleeding.
    AffineTransform ctm = context->getCTM();
    FloatSize contextScaling(static_cast<float>(ctm.xScale()), static_cast<float>(ctm.yScale()));

    // Because RoundedRect uses IntRect internally the inset applied by the
    // BackgroundBleedShrinkBackground strategy cannot be less than one integer
    // layout coordinate, even with subpixel layout enabled. To take that into
    // account, we clamp the contextScaling to 1.0 for the following test so
    // that borderObscuresBackgroundEdge can only return true if the border
    // widths are greater than 2 in both layout coordinates and screen
    // coordinates.
    // This precaution will become obsolete if RoundedRect is ever promoted to
    // a sub-pixel representation.
    if (contextScaling.width() > 1)
        contextScaling.setWidth(1);
    if (contextScaling.height() > 1)
        contextScaling.setHeight(1);

    if (borderObscuresBackgroundEdge(*renderBox.style(), contextScaling))
        return BackgroundBleedShrinkBackground;
    if (!hasAppearance && renderBox.style()->borderObscuresBackground() && renderBox.backgroundHasOpaqueTopLayer())
        return BackgroundBleedBackgroundOverBorder;

    return BackgroundBleedClipBackground;
}

bool BoxDecorationData::borderObscuresBackgroundEdge(const RenderStyle& style, const FloatSize& contextScale) const
{
    BorderEdge edges[4];
    style.getBorderEdgeInfo(edges);

    for (int i = BSTop; i <= BSLeft; ++i) {
        const BorderEdge& currEdge = edges[i];
        // FIXME: for vertical text
        float axisScale = (i == BSTop || i == BSBottom) ? contextScale.height() : contextScale.width();
        if (!currEdge.obscuresBackgroundEdge(axisScale))
            return false;
    }

    return true;
}

} // namespace blink