https://bugs.webkit.org/show_bug.cgi?id=134342
Reviewed by Dean Jackson.
Source/WebCore:
Tests: css3/blending/background-blend-mode-body-image.html
css3/blending/background-blend-mode-body-transparent-color-and-image.html
css3/blending/background-blend-mode-body-transparent-image.html
* rendering/RenderBox.cpp:
(WebCore::RenderBox::paintFillLayers):
If the background layers have blend modes, we paint the base background color first,
before starting a new transparency layer. After creating the transparency layer,
the base background will be skipped, and the background layers will blend on top of
a transparent backdrop.
(WebCore::RenderBox::paintFillLayer):
* rendering/RenderBox.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
This method is able to paint only the base background color (BaseBackgroundColorOnly),
skipping the background-color and background-images. This option is available only
on bottom layer of the root renderer and only if the background color is not opaque,
otherwise the method will return early.
Another option is to paint the root background without using the base background color
(BaseBackgroundColorSkip).
* rendering/RenderBoxModelObject.h:
Adding the BaseBackgroundColorUsage enum.
LayoutTests:
* css3/blending/background-blend-mode-body-image-expected.html: Added.
* css3/blending/background-blend-mode-body-image.html: Added.
* css3/blending/background-blend-mode-body-transparent-color-and-image-expected.html: Added.
* css3/blending/background-blend-mode-body-transparent-color-and-image.html: Added.
* css3/blending/background-blend-mode-body-transparent-image-expected.html: Added.
* css3/blending/background-blend-mode-body-transparent-image.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170841
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-07-07 Ion Rosca <rosca@adobe.com>
+
+ [CSS Blending]The background images set on the root element will blend on an initial white backdrop.
+ https://bugs.webkit.org/show_bug.cgi?id=134342
+
+ Reviewed by Dean Jackson.
+
+ * css3/blending/background-blend-mode-body-image-expected.html: Added.
+ * css3/blending/background-blend-mode-body-image.html: Added.
+ * css3/blending/background-blend-mode-body-transparent-color-and-image-expected.html: Added.
+ * css3/blending/background-blend-mode-body-transparent-color-and-image.html: Added.
+ * css3/blending/background-blend-mode-body-transparent-image-expected.html: Added.
+ * css3/blending/background-blend-mode-body-transparent-image.html: Added.
+
2014-07-06 Yoav Weiss <yoav@yoav.ws>
Turn on img@sizes compile flag
--- /dev/null
+<!DOCTYPE HTML>
+<style>
+body {
+ background-color: green;
+}
+</style>
+<p>This test will check that a background-image set on body does not blend with the browser's white background color.<br/>
+The test passes if the page has a green background.</p>
--- /dev/null
+<!DOCTYPE HTML>
+<style>
+body {
+ background-image: linear-gradient(green, green);
+ background-blend-mode: screen;
+}
+</style>
+<p>This test will check that a background-image set on body does not blend with the browser's white background color.<br/>
+The test passes if the page has a green background.</p>
--- /dev/null
+<!DOCTYPE HTML>
+<style>
+body, html {
+ height: 100%;
+}
+body {
+ margin: 0px;
+}
+div {
+ background-image: linear-gradient(green, green);
+ background-color: rgba(255, 0, 0, 0.2);
+ background-blend-mode: screen;
+ height: 100%;
+}
+p {
+ display: inline;
+}
+</style>
+<div>
+ <p>This test will check that a background-image set on body does not blend with the browser's white background color, it will only blend with the red transparent background-color.<br/>
+ The test passes if the page has a green background.</p>
+</div>
--- /dev/null
+<!DOCTYPE HTML>
+<style>
+body {
+ background-image: linear-gradient(green, green);
+ background-color: rgba(255, 0, 0, 0.2);
+ background-blend-mode: screen;
+ margin: 0px;
+}
+p {
+ display: inline;
+}
+</style>
+<p>This test will check that a background-image set on body does not blend with the browser's white background color, it will only blend with the red transparent background-color.<br/>
+The test passes if the page has a green background.</p>
--- /dev/null
+<!DOCTYPE HTML>
+<style>
+body {
+ background-image: linear-gradient(transparent, transparent 10%, green 10%, green 90%, transparent 90%, transparent);
+}
+</style>
+<p>This test will check that a transparent background-image set on body does not blend with the browser's white background color.<br/>
+The test passes if the page has a green background with white horizontal lines.</p>
--- /dev/null
+<!DOCTYPE HTML>
+<style>
+body {
+ background-image: linear-gradient(transparent, transparent 10%, green 10%, green 90%, transparent 90%, transparent);
+ background-blend-mode: screen;
+}
+</style>
+<p>This test will check that a transparent background-image set on body does not blend with the browser's white background color.<br/>
+The test passes if the page has a green background with white horizontal lines.</p>
+2014-07-07 Ion Rosca <rosca@adobe.com>
+
+ [CSS Blending]The background images set on the root element will blend on an initial white backdrop.
+ https://bugs.webkit.org/show_bug.cgi?id=134342
+
+ Reviewed by Dean Jackson.
+
+ Tests: css3/blending/background-blend-mode-body-image.html
+ css3/blending/background-blend-mode-body-transparent-color-and-image.html
+ css3/blending/background-blend-mode-body-transparent-image.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::paintFillLayers):
+ If the background layers have blend modes, we paint the base background color first,
+ before starting a new transparency layer. After creating the transparency layer,
+ the base background will be skipped, and the background layers will blend on top of
+ a transparent backdrop.
+ (WebCore::RenderBox::paintFillLayer):
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+ This method is able to paint only the base background color (BaseBackgroundColorOnly),
+ skipping the background-color and background-images. This option is available only
+ on bottom layer of the root renderer and only if the background color is not opaque,
+ otherwise the method will return early.
+ Another option is to paint the root background without using the base background color
+ (BaseBackgroundColorSkip).
+ * rendering/RenderBoxModelObject.h:
+ Adding the BaseBackgroundColorUsage enum.
+
2014-07-06 Yoav Weiss <yoav@yoav.ws>
Turn on img@sizes compile flag
GraphicsContext* context = paintInfo.context;
if (!context)
shouldDrawBackgroundInSeparateBuffer = false;
- if (shouldDrawBackgroundInSeparateBuffer)
+
+ BaseBackgroundColorUsage baseBgColorUsage = BaseBackgroundColorUse;
+
+ if (shouldDrawBackgroundInSeparateBuffer) {
+ paintFillLayer(paintInfo, c, *layers.rbegin(), rect, bleedAvoidance, op, backgroundObject, BaseBackgroundColorOnly);
+ baseBgColorUsage = BaseBackgroundColorSkip;
context->beginTransparencyLayer(1);
+ }
Vector<const FillLayer*>::const_reverse_iterator topLayer = layers.rend();
for (Vector<const FillLayer*>::const_reverse_iterator it = layers.rbegin(); it != topLayer; ++it)
- paintFillLayer(paintInfo, c, *it, rect, bleedAvoidance, op, backgroundObject);
+ paintFillLayer(paintInfo, c, *it, rect, bleedAvoidance, op, backgroundObject, baseBgColorUsage);
if (shouldDrawBackgroundInSeparateBuffer)
context->endTransparencyLayer();
}
void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, const LayoutRect& rect,
- BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderElement* backgroundObject)
+ BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderElement* backgroundObject, BaseBackgroundColorUsage baseBgColorUsage)
{
- paintFillLayerExtended(paintInfo, c, fillLayer, rect, bleedAvoidance, 0, LayoutSize(), op, backgroundObject);
+ paintFillLayerExtended(paintInfo, c, fillLayer, rect, bleedAvoidance, 0, LayoutSize(), op, backgroundObject, baseBgColorUsage);
}
static bool layersUseImage(WrappedImagePtr image, const FillLayer* layers)
void paintBackground(const PaintInfo&, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone);
- void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, CompositeOperator, RenderElement* backgroundObject);
+ void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, CompositeOperator, RenderElement* backgroundObject, BaseBackgroundColorUsage = BaseBackgroundColorUse);
void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone, CompositeOperator = CompositeSourceOver, RenderElement* backgroundObject = nullptr);
void paintMaskImages(const PaintInfo&, const LayoutRect&);
}
void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& color, const FillLayer* bgLayer, const LayoutRect& rect,
- BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, CompositeOperator op, RenderElement* backgroundObject)
+ BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, CompositeOperator op, RenderElement* backgroundObject, BaseBackgroundColorUsage baseBgColorUsage)
{
GraphicsContext* context = paintInfo.context;
if (context->paintingDisabled() || rect.isEmpty())
}
}
+ bool baseBgColorOnly = (baseBgColorUsage == BaseBackgroundColorOnly);
+ if (baseBgColorOnly && (!isRoot || bgLayer->next() || (bgColor.isValid() && !bgColor.hasAlpha())))
+ return;
+
bool colorVisible = bgColor.isValid() && bgColor.alpha();
float deviceScaleFactor = document().deviceScaleFactor();
FloatRect pixelSnappedRect = pixelSnappedForPainting(rect, deviceScaleFactor);
// If we have an alpha and we are painting the root element, go ahead and blend with the base background color.
Color baseColor;
bool shouldClearBackground = false;
- if (isOpaqueRoot) {
+ if ((baseBgColorUsage != BaseBackgroundColorSkip) && isOpaqueRoot) {
baseColor = view().frameView().baseBackgroundColor();
if (!baseColor.alpha())
shouldClearBackground = true;
FloatRect backgroundRectForPainting = pixelSnappedForPainting(backgroundRect, deviceScaleFactor);
if (baseColor.alpha()) {
- if (bgColor.alpha())
+ if (!baseBgColorOnly && bgColor.alpha())
baseColor = baseColor.blend(bgColor);
context->fillRect(backgroundRectForPainting, baseColor, style().colorSpace(), CompositeCopy);
- } else if (bgColor.alpha()) {
+ } else if (!baseBgColorOnly && bgColor.alpha()) {
CompositeOperator operation = shouldClearBackground ? CompositeCopy : context->compositeOperation();
context->fillRect(backgroundRectForPainting, bgColor, style().colorSpace(), operation);
} else if (shouldClearBackground)
}
// no progressive loading of the background image
- if (shouldPaintBackgroundImage) {
+ if (!baseBgColorOnly && shouldPaintBackgroundImage) {
BackgroundImageGeometry geometry;
calculateBackgroundImageGeometry(paintInfo.paintContainer, bgLayer, scrolledPaintRect, geometry, backgroundObject);
geometry.clip(LayoutRect(pixelSnappedRect));
BackgroundBleedBackgroundOverBorder
};
+enum BaseBackgroundColorUsage {
+ BaseBackgroundColorUse,
+ BaseBackgroundColorOnly,
+ BaseBackgroundColorSkip
+};
+
enum ContentChangeType {
ImageChanged,
MaskImageChanged,
void paintBorder(const PaintInfo&, const LayoutRect&, const RenderStyle&, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
bool paintNinePieceImage(GraphicsContext*, const LayoutRect&, const RenderStyle&, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
void paintBoxShadow(const PaintInfo&, const LayoutRect&, const RenderStyle&, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
- void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderElement* backgroundObject = 0);
+ void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderElement* backgroundObject = 0, BaseBackgroundColorUsage = BaseBackgroundColorUse);
virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox* = 0) const;