Commit 8f007b92 authored by danakj's avatar danakj Committed by Commit Bot

Fix theme background to always be opaque.

We introduced a mistake where if the image was not opaque, the
background color was no longer drawn behind it, so on chromeos the
chrome header ui could be seen through. This fixes the issue by
rearranging the painting some, and improving some performance corner
cases while we're here.

First, we only need to use SaveLayerWithFlags() when we are blending
together 2+ things *that are not opaque*, then want to apply alpha to
them together. This is only needed when alpha is < 255, or when we have
both |frame_image| and |frame_overlay_image|. Otherwise the background
color is opaque, so drawing it first then blending one image into it is
equivalent.

Then, in both this and the other case, we draw the background color
first, then draw the images above it, in order to ensure the bar is
opaque.

Note also that we use kPlus blending mode when alpha < 255 so that
between the active and inactive background colors, they add up to
255 alpha, giving us something opaque.

R=estade@chromium.org

Bug: 836023
Change-Id: Ibc6b7a3dbec0d9d63b0b07f70a4c17405a3eeec2
Reviewed-on: https://chromium-review.googlesource.com/1050690Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Commit-Queue: danakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557265}
parent f9a4ee47
...@@ -62,7 +62,7 @@ void PaintFrameImagesInRoundRect(gfx::Canvas* canvas, ...@@ -62,7 +62,7 @@ void PaintFrameImagesInRoundRect(gfx::Canvas* canvas,
const gfx::ImageSkia& frame_image, const gfx::ImageSkia& frame_image,
const gfx::ImageSkia& frame_overlay_image, const gfx::ImageSkia& frame_overlay_image,
int alpha, int alpha,
SkColor background_color, SkColor opaque_background_color,
const gfx::Rect& bounds, const gfx::Rect& bounds,
int corner_radius, int corner_radius,
int image_inset_x) { int image_inset_x) {
...@@ -72,31 +72,51 @@ void PaintFrameImagesInRoundRect(gfx::Canvas* canvas, ...@@ -72,31 +72,51 @@ void PaintFrameImagesInRoundRect(gfx::Canvas* canvas,
gfx::ScopedCanvas scoped_save(canvas); gfx::ScopedCanvas scoped_save(canvas);
canvas->ClipPath(frame_path, antialias); canvas->ClipPath(frame_path, antialias);
cc::PaintFlags flags; // When no images are used, just draw a color, with the animation |alpha|
flags.setBlendMode(SkBlendMode::kPlus); // applied.
flags.setAntiAlias(antialias);
if (frame_image.isNull() && frame_overlay_image.isNull()) { if (frame_image.isNull() && frame_overlay_image.isNull()) {
flags.setColor(background_color); canvas->DrawColor(SkColorSetA(opaque_background_color, alpha));
canvas->DrawRect(bounds, flags); return;
} else if (frame_overlay_image.isNull()) { }
flags.setAlpha(alpha);
canvas->TileImageInt(frame_image, image_inset_x, 0, 0, 0, bounds.width(), // This handles the case where blending is required between one or more images
bounds.height(), 1.0f, &flags); // and the background color. In this case we use a SaveLayerWithFlags() call
} else { // to draw all 2-3 components into a single layer then apply the alpha to them
// together.
if (alpha < 0xFF ||
(!frame_image.isNull() && !frame_overlay_image.isNull())) {
cc::PaintFlags flags;
// We use kPlus blending mode so that between the active and inactive
// background colors, the result is 255 alpha (i.e. opaque).
flags.setBlendMode(SkBlendMode::kPlus);
flags.setAlpha(alpha); flags.setAlpha(alpha);
canvas->SaveLayerWithFlags(flags); canvas->SaveLayerWithFlags(flags);
if (frame_image.isNull()) { // Images can be transparent and we expect the background color to be
canvas->DrawColor(background_color); // present behind them. Here the |alpha| will be applied to the background
} else { // color by the SaveLayer call, so use |opaque_background_color|.
canvas->DrawColor(opaque_background_color);
if (!frame_image.isNull()) {
canvas->TileImageInt(frame_image, image_inset_x, 0, 0, 0, bounds.width(), canvas->TileImageInt(frame_image, image_inset_x, 0, 0, 0, bounds.width(),
bounds.height()); bounds.height());
} }
canvas->DrawImageInt(frame_overlay_image, 0, 0); if (!frame_overlay_image.isNull())
canvas->DrawImageInt(frame_overlay_image, 0, 0);
canvas->Restore(); canvas->Restore();
return;
} }
// Images can be transparent and we expect the background color to be
// present behind them.
canvas->DrawColor(opaque_background_color);
if (!frame_image.isNull()) {
canvas->TileImageInt(frame_image, image_inset_x, 0, 0, 0, bounds.width(),
bounds.height());
}
if (!frame_overlay_image.isNull())
canvas->DrawImageInt(frame_overlay_image, 0, 0);
} }
} // namespace } // namespace
...@@ -262,15 +282,16 @@ void CustomFrameHeader::PaintFrameImages(gfx::Canvas* canvas, bool active) { ...@@ -262,15 +282,16 @@ void CustomFrameHeader::PaintFrameImages(gfx::Canvas* canvas, bool active) {
appearance_provider_->GetFrameHeaderImage(active); appearance_provider_->GetFrameHeaderImage(active);
gfx::ImageSkia frame_overlay_image = gfx::ImageSkia frame_overlay_image =
appearance_provider_->GetFrameHeaderOverlayImage(active); appearance_provider_->GetFrameHeaderOverlayImage(active);
SkColor background_color = // We ensure that the background color is opaque.
SkColorSetA(appearance_provider_->GetFrameHeaderColor(active), alpha); SkColor opaque_background_color =
SkColorSetA(appearance_provider_->GetFrameHeaderColor(active), 0xFF);
int corner_radius = 0; int corner_radius = 0;
if (!GetWidget()->IsMaximized() && !GetWidget()->IsFullscreen()) if (!GetWidget()->IsMaximized() && !GetWidget()->IsFullscreen())
corner_radius = FrameHeaderUtil::GetTopCornerRadiusWhenRestored(); corner_radius = FrameHeaderUtil::GetTopCornerRadiusWhenRestored();
PaintFrameImagesInRoundRect(canvas, frame_image, frame_overlay_image, alpha, PaintFrameImagesInRoundRect(canvas, frame_image, frame_overlay_image, alpha,
background_color, GetPaintedBounds(), opaque_background_color, GetPaintedBounds(),
corner_radius, corner_radius,
FrameHeaderUtil::GetThemeBackgroundXInset()); FrameHeaderUtil::GetThemeBackgroundXInset());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment