1 // Copyright 2020 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 "components/media_message_center/media_notification_background_ash_impl.h"
6 
7 #include "ui/gfx/canvas.h"
8 #include "ui/gfx/image/image_skia_operations.h"
9 #include "ui/gfx/skia_util.h"
10 #include "ui/views/view.h"
11 
12 namespace media_message_center {
13 
14 namespace {
15 
16 constexpr SkColor kBackgroundColor = SK_ColorTRANSPARENT;
17 constexpr SkColor kForegroundColor = SK_ColorWHITE;
18 
19 constexpr gfx::Size kArtworkSize(80, 80);
20 constexpr int kArtworkBottomMargin = 16;
21 constexpr int kArtworkRightMargin = 16;
22 constexpr int kArtworkCornerRadius = 4;
23 
ScaleToFitSize(const gfx::Size & image_size)24 gfx::Size ScaleToFitSize(const gfx::Size& image_size) {
25   if ((image_size.width() > kArtworkSize.width() &&
26        image_size.height() > kArtworkSize.height()) ||
27       (image_size.width() < kArtworkSize.width() ||
28        image_size.height() < kArtworkSize.height())) {
29     const float scale = std::max(
30         kArtworkSize.width() / static_cast<float>(image_size.width()),
31         kArtworkSize.height() / static_cast<float>(image_size.height()));
32     return gfx::ScaleToFlooredSize(image_size, scale);
33   }
34 
35   return image_size;
36 }
37 
38 }  // namespace
39 
GetArtworkBounds(const gfx::Rect & view_bounds) const40 gfx::Rect MediaNotificationBackgroundAshImpl::GetArtworkBounds(
41     const gfx::Rect& view_bounds) const {
42   gfx::Size target_size = ScaleToFitSize(artwork_.size());
43 
44   int vertical_offset = (target_size.height() - kArtworkSize.height()) / 2;
45   int horizontal_offset = (target_size.width() - kArtworkSize.width()) / 2;
46 
47   int bounds_x = base::i18n::IsRTL()
48                      ? view_bounds.x() + kArtworkRightMargin - horizontal_offset
49                      : view_bounds.right() - kArtworkRightMargin -
50                            kArtworkSize.width() - horizontal_offset;
51 
52   return gfx::Rect(bounds_x,
53                    view_bounds.bottom() - kArtworkBottomMargin -
54                        kArtworkSize.height() - vertical_offset,
55                    target_size.width(), target_size.height());
56 }
57 
GetArtworkClipPath(const gfx::Rect & view_bounds) const58 SkPath MediaNotificationBackgroundAshImpl::GetArtworkClipPath(
59     const gfx::Rect& view_bounds) const {
60   int x = base::i18n::IsRTL() ? view_bounds.x() + kArtworkRightMargin
61                               : view_bounds.right() - kArtworkRightMargin -
62                                     kArtworkSize.width();
63   int y = view_bounds.bottom() - kArtworkBottomMargin - kArtworkSize.height();
64 
65   SkPath path;
66   path.addRoundRect(gfx::RectToSkRect(gfx::Rect(x, y, kArtworkSize.width(),
67                                                 kArtworkSize.height())),
68                     kArtworkCornerRadius, kArtworkCornerRadius);
69   return path;
70 }
71 
Paint(gfx::Canvas * canvas,views::View * view) const72 void MediaNotificationBackgroundAshImpl::Paint(gfx::Canvas* canvas,
73                                                views::View* view) const {
74   gfx::Rect source_bounds(0, 0, artwork_.width(), artwork_.height());
75   gfx::Rect target_bounds = GetArtworkBounds(view->GetContentsBounds());
76 
77   canvas->ClipPath(GetArtworkClipPath(view->GetContentsBounds()), true);
78 
79   canvas->DrawImageInt(
80       artwork_, source_bounds.x(), source_bounds.y(), source_bounds.width(),
81       source_bounds.height(), target_bounds.x(), target_bounds.y(),
82       target_bounds.width(), target_bounds.height(), false /* filter */);
83 }
84 
UpdateArtwork(const gfx::ImageSkia & image)85 void MediaNotificationBackgroundAshImpl::UpdateArtwork(
86     const gfx::ImageSkia& image) {
87   if (artwork_.BackedBySameObjectAs(image))
88     return;
89 
90   artwork_ = image;
91 }
92 
UpdateCornerRadius(int top_radius,int bottom_radius)93 bool MediaNotificationBackgroundAshImpl::UpdateCornerRadius(int top_radius,
94                                                             int bottom_radius) {
95   return false;
96 }
97 
UpdateArtworkMaxWidthPct(double max_width_pct)98 bool MediaNotificationBackgroundAshImpl::UpdateArtworkMaxWidthPct(
99     double max_width_pct) {
100   return false;
101 }
102 
GetBackgroundColor(const views::View & owner) const103 SkColor MediaNotificationBackgroundAshImpl::GetBackgroundColor(
104     const views::View& owner) const {
105   return kBackgroundColor;
106 }
107 
GetForegroundColor(const views::View & owner) const108 SkColor MediaNotificationBackgroundAshImpl::GetForegroundColor(
109     const views::View& owner) const {
110   return kForegroundColor;
111 }
112 
113 }  // namespace media_message_center
114