• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/BoxDecorationData.h"
7 
8 #include "core/rendering/style/BorderEdge.h"
9 #include "core/rendering/style/RenderStyle.h"
10 #include "platform/graphics/GraphicsContext.h"
11 
12 namespace blink {
13 
BoxDecorationData(const RenderStyle & style,bool canRenderBorderImage,bool backgroundHasOpaqueTopLayer,GraphicsContext * context)14 BoxDecorationData::BoxDecorationData(const RenderStyle& style, bool canRenderBorderImage, bool backgroundHasOpaqueTopLayer, GraphicsContext* context)
15 {
16     backgroundColor = style.visitedDependentColor(CSSPropertyBackgroundColor);
17     hasBackground = backgroundColor.alpha() || style.hasBackgroundImage();
18     ASSERT(hasBackground == style.hasBackground());
19     hasBorder = style.hasBorder();
20     hasAppearance = style.hasAppearance();
21 
22     m_bleedAvoidance = determineBackgroundBleedAvoidance(style, canRenderBorderImage, backgroundHasOpaqueTopLayer, context);
23 }
24 
determineBackgroundBleedAvoidance(const RenderStyle & style,bool canRenderBorderImage,bool backgroundHasOpaqueTopLayer,GraphicsContext * context)25 BackgroundBleedAvoidance BoxDecorationData::determineBackgroundBleedAvoidance(const RenderStyle& style, bool canRenderBorderImage, bool backgroundHasOpaqueTopLayer, GraphicsContext* context)
26 {
27     if (!hasBackground || !hasBorder || !style.hasBorderRadius() || canRenderBorderImage)
28         return BackgroundBleedNone;
29 
30     // FIXME: See crbug.com/382491. getCTM does not accurately reflect the scale at the time content is
31     // rasterized, and should not be relied on to make decisions about bleeding.
32     AffineTransform ctm = context->getCTM();
33     FloatSize contextScaling(static_cast<float>(ctm.xScale()), static_cast<float>(ctm.yScale()));
34 
35     // Because RoundedRect uses IntRect internally the inset applied by the
36     // BackgroundBleedShrinkBackground strategy cannot be less than one integer
37     // layout coordinate, even with subpixel layout enabled. To take that into
38     // account, we clamp the contextScaling to 1.0 for the following test so
39     // that borderObscuresBackgroundEdge can only return true if the border
40     // widths are greater than 2 in both layout coordinates and screen
41     // coordinates.
42     // This precaution will become obsolete if RoundedRect is ever promoted to
43     // a sub-pixel representation.
44     if (contextScaling.width() > 1)
45         contextScaling.setWidth(1);
46     if (contextScaling.height() > 1)
47         contextScaling.setHeight(1);
48 
49     if (borderObscuresBackgroundEdge(style, contextScaling))
50         return BackgroundBleedShrinkBackground;
51     if (!hasAppearance && style.borderObscuresBackground() && backgroundHasOpaqueTopLayer)
52         return BackgroundBleedBackgroundOverBorder;
53 
54     return BackgroundBleedClipBackground;
55 }
56 
borderObscuresBackgroundEdge(const RenderStyle & style,const FloatSize & contextScale) const57 bool BoxDecorationData::borderObscuresBackgroundEdge(const RenderStyle& style, const FloatSize& contextScale) const
58 {
59     BorderEdge edges[4];
60     style.getBorderEdgeInfo(edges);
61 
62     for (int i = BSTop; i <= BSLeft; ++i) {
63         const BorderEdge& currEdge = edges[i];
64         // FIXME: for vertical text
65         float axisScale = (i == BSTop || i == BSBottom) ? contextScale.height() : contextScale.width();
66         if (!currEdge.obscuresBackgroundEdge(axisScale))
67             return false;
68     }
69 
70     return true;
71 }
72 
73 } // namespace blink
74