Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: chrome/browser/ui/extensions/icon_with_badge_image_source.cc

Issue 2401363005: Remove sundry IsModeMaterial checks. (Closed)
Patch Set: resolve merge conflict Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/ui/libgtk2ui/gtk2_ui.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/extensions/icon_with_badge_image_source.h" 5 #include "chrome/browser/ui/extensions/icon_with_badge_image_source.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/logging.h"
12 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
13 #include "build/build_config.h" 12 #include "build/build_config.h"
14 #include "chrome/browser/extensions/extension_action.h" 13 #include "chrome/browser/extensions/extension_action.h"
15 #include "chrome/grit/theme_resources.h" 14 #include "chrome/grit/theme_resources.h"
16 #include "third_party/skia/include/core/SkPaint.h" 15 #include "third_party/skia/include/core/SkPaint.h"
17 #include "third_party/skia/include/core/SkRefCnt.h"
18 #include "third_party/skia/include/core/SkTypeface.h"
19 #include "ui/base/material_design/material_design_controller.h"
20 #include "ui/base/resource/resource_bundle.h" 16 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/canvas.h" 17 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/color_palette.h" 18 #include "ui/gfx/color_palette.h"
23 #include "ui/gfx/font.h" 19 #include "ui/gfx/font.h"
24 #include "ui/gfx/geometry/rect.h" 20 #include "ui/gfx/geometry/rect.h"
25 #include "ui/gfx/geometry/size.h" 21 #include "ui/gfx/geometry/size.h"
26 #include "ui/gfx/image/image_skia_operations.h" 22 #include "ui/gfx/image/image_skia_operations.h"
27 #include "ui/resources/grit/ui_resources.h"
28 23
29 namespace { 24 namespace {
30 25
31 // Different platforms need slightly different constants to look good.
32 // TODO(devlin): Comb through these and see if they are all still needed/
33 // appropriate.
34 #if defined(OS_WIN)
35 const float kTextSize = 10;
36 // The padding between the top of the badge and the top of the text.
37 const int kTopTextPadding = -1;
38 #elif defined(OS_MACOSX)
39 const float kTextSize = 9.0;
40 const int kTopTextPadding = 0;
41 #elif defined(OS_CHROMEOS)
42 const float kTextSize = 8.0;
43 const int kTopTextPadding = 1;
44 #elif defined(OS_POSIX)
45 const float kTextSize = 9.0;
46 const int kTopTextPadding = 0;
47 #endif
48
49 const int kPadding = 2; 26 const int kPadding = 2;
50 const int kBadgeHeight = 11; 27 const int kBadgeHeight = 11;
51 const int kMaxTextWidth = 23; 28 const int kMaxTextWidth = 23;
52 29
53 // The minimum width for center-aligning the badge. 30 // The minimum width for center-aligning the badge.
54 const int kCenterAlignThreshold = 20; 31 const int kCenterAlignThreshold = 20;
55 32
56 // Helper routine that returns a singleton SkPaint object configured for
57 // rendering badge overlay text (correct font, typeface, etc).
58 SkPaint* GetBadgeTextPaintSingleton() {
59 #if defined(OS_MACOSX)
60 const char kPreferredTypeface[] = "Helvetica Bold";
61 #else
62 const char kPreferredTypeface[] = "Arial";
63 #endif
64
65 static SkPaint* text_paint = NULL;
66 if (!text_paint) {
67 text_paint = new SkPaint;
68 text_paint->setAntiAlias(true);
69 text_paint->setTextAlign(SkPaint::kLeft_Align);
70
71 sk_sp<SkTypeface> typeface(
72 SkTypeface::MakeFromName(kPreferredTypeface,
73 SkFontStyle::FromOldStyle(SkTypeface::kBold)));
74 // Skia doesn't do any font fallback---if the user is missing the font then
75 // typeface will be NULL. If we don't do manual fallback then we'll crash.
76 if (typeface) {
77 text_paint->setFakeBoldText(true);
78 } else {
79 // Fall back to the system font. We don't bold it because we aren't sure
80 // how it will look.
81 // For the most part this code path will only be hit on Linux systems
82 // that don't have Arial.
83 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
84 const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont);
85 typeface = SkTypeface::MakeFromName(base_font.GetFontName().c_str(),
86 SkFontStyle());
87 DCHECK(typeface);
88 }
89
90 text_paint->setTypeface(std::move(typeface));
91 }
92 return text_paint;
93 }
94
95 gfx::ImageSkiaRep ScaleImageSkiaRep(const gfx::ImageSkiaRep& rep, 33 gfx::ImageSkiaRep ScaleImageSkiaRep(const gfx::ImageSkiaRep& rep,
96 int target_width_dp, 34 int target_width_dp,
97 float target_scale) { 35 float target_scale) {
98 int width_px = target_width_dp * target_scale; 36 int width_px = target_width_dp * target_scale;
99 return gfx::ImageSkiaRep( 37 return gfx::ImageSkiaRep(
100 skia::ImageOperations::Resize(rep.sk_bitmap(), 38 skia::ImageOperations::Resize(rep.sk_bitmap(),
101 skia::ImageOperations::RESIZE_BEST, 39 skia::ImageOperations::RESIZE_BEST,
102 width_px, width_px), 40 width_px, width_px),
103 target_scale); 41 target_scale);
104 } 42 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 97
160 // Paints badge with specified parameters to |canvas|. 98 // Paints badge with specified parameters to |canvas|.
161 void IconWithBadgeImageSource::PaintBadge(gfx::Canvas* canvas) { 99 void IconWithBadgeImageSource::PaintBadge(gfx::Canvas* canvas) {
162 if (!badge_ || badge_->text.empty()) 100 if (!badge_ || badge_->text.empty())
163 return; 101 return;
164 102
165 SkColor text_color = SkColorGetA(badge_->text_color) == SK_AlphaTRANSPARENT 103 SkColor text_color = SkColorGetA(badge_->text_color) == SK_AlphaTRANSPARENT
166 ? SK_ColorWHITE 104 ? SK_ColorWHITE
167 : badge_->text_color; 105 : badge_->text_color;
168 106
169 SkColor background_color = ui::MaterialDesignController::IsModeMaterial()
170 ? gfx::kGoogleBlue500
171 : SkColorSetRGB(218, 0, 24);
172 if (SkColorGetA(badge_->background_color) != SK_AlphaTRANSPARENT)
173 background_color = badge_->background_color;
174 // Make sure the background color is opaque. See http://crbug.com/619499 107 // Make sure the background color is opaque. See http://crbug.com/619499
175 if (ui::MaterialDesignController::IsModeMaterial()) 108 SkColor background_color =
176 background_color = SkColorSetA(background_color, SK_AlphaOPAQUE); 109 SkColorGetA(badge_->background_color) == SK_AlphaTRANSPARENT
110 ? gfx::kGoogleBlue500
111 : SkColorSetA(badge_->background_color, SK_AlphaOPAQUE);
177 112
178 canvas->Save();
179
180 SkPaint* text_paint = nullptr;
181 int text_width = 0;
182 ResourceBundle* rb = &ResourceBundle::GetSharedInstance(); 113 ResourceBundle* rb = &ResourceBundle::GetSharedInstance();
183 gfx::FontList base_font = rb->GetFontList(ResourceBundle::BaseFont) 114 gfx::FontList base_font = rb->GetFontList(ResourceBundle::BaseFont)
184 .DeriveWithHeightUpperBound(kBadgeHeight); 115 .DeriveWithHeightUpperBound(kBadgeHeight);
185 base::string16 utf16_text = base::UTF8ToUTF16(badge_->text); 116 base::string16 utf16_text = base::UTF8ToUTF16(badge_->text);
186 117
187 // See if we can squeeze a slightly larger font into the badge given the 118 // See if we can squeeze a slightly larger font into the badge given the
188 // actual string that is to be displayed. 119 // actual string that is to be displayed.
189 const int kMaxIncrementAttempts = 5; 120 const int kMaxIncrementAttempts = 5;
190 for (size_t i = 0; i < kMaxIncrementAttempts; ++i) { 121 for (size_t i = 0; i < kMaxIncrementAttempts; ++i) {
191 int w = 0; 122 int w = 0;
192 int h = 0; 123 int h = 0;
193 gfx::FontList bigger_font = 124 gfx::FontList bigger_font =
194 base_font.Derive(1, 0, gfx::Font::Weight::NORMAL); 125 base_font.Derive(1, 0, gfx::Font::Weight::NORMAL);
195 gfx::Canvas::SizeStringInt(utf16_text, bigger_font, &w, &h, 0, 126 gfx::Canvas::SizeStringInt(utf16_text, bigger_font, &w, &h, 0,
196 gfx::Canvas::NO_ELLIPSIS); 127 gfx::Canvas::NO_ELLIPSIS);
197 if (h > kBadgeHeight) 128 if (h > kBadgeHeight)
198 break; 129 break;
199 base_font = bigger_font; 130 base_font = bigger_font;
200 } 131 }
201 132
202 if (ui::MaterialDesignController::IsModeMaterial()) { 133 const int text_width =
203 text_width =
204 std::min(kMaxTextWidth, canvas->GetStringWidth(utf16_text, base_font)); 134 std::min(kMaxTextWidth, canvas->GetStringWidth(utf16_text, base_font));
205 } else {
206 text_paint = GetBadgeTextPaintSingleton();
207 text_paint->setColor(text_color);
208 float scale = canvas->image_scale();
209
210 // Calculate text width. Font width may not be linear with respect to the
211 // scale factor (e.g. when hinting is applied), so we need to use the font
212 // size that canvas actually uses when drawing a text.
213 text_paint->setTextSize(SkFloatToScalar(kTextSize) * scale);
214 SkScalar sk_text_width_in_pixel =
215 text_paint->measureText(badge_->text.c_str(), badge_->text.size());
216 text_paint->setTextSize(SkFloatToScalar(kTextSize));
217
218 // We clamp the width to a max size. SkPaint::measureText returns the width
219 // in pixel (as a result of scale multiplier), so convert
220 // sk_text_width_in_pixel back to DIP (density independent pixel) first.
221 text_width = std::min(
222 kMaxTextWidth, static_cast<int>(std::ceil(
223 SkScalarToFloat(sk_text_width_in_pixel) / scale)));
224 }
225
226 // Calculate badge size. It is clamped to a min width just because it looks 135 // Calculate badge size. It is clamped to a min width just because it looks
227 // silly if it is too skinny. 136 // silly if it is too skinny.
228 int badge_width = text_width + kPadding * 2; 137 int badge_width = text_width + kPadding * 2;
229 // Force the pixel width of badge to be either odd (if the icon width is odd) 138 // Force the pixel width of badge to be either odd (if the icon width is odd)
230 // or even otherwise. If there is a mismatch you get http://crbug.com/26400. 139 // or even otherwise. If there is a mismatch you get http://crbug.com/26400.
231 if (size().width() != 0 && (badge_width % 2 != size().width() % 2)) 140 if (size().width() != 0 && (badge_width % 2 != size().width() % 2))
232 badge_width += 1; 141 badge_width += 1;
233 badge_width = std::max(kBadgeHeight, badge_width); 142 badge_width = std::max(kBadgeHeight, badge_width);
234 143
235 // Calculate the badge background rect. It is usually right-aligned, but it 144 // Calculate the badge background rect. It is usually right-aligned, but it
236 // can also be center-aligned if it is large. 145 // can also be center-aligned if it is large.
237 gfx::Rect rect(badge_width >= kCenterAlignThreshold 146 gfx::Rect rect(badge_width >= kCenterAlignThreshold
238 ? (size().width() - badge_width) / 2 147 ? (size().width() - badge_width) / 2
239 : size().width() - badge_width, 148 : size().width() - badge_width,
240 size().height() - kBadgeHeight, badge_width, kBadgeHeight); 149 size().height() - kBadgeHeight, badge_width, kBadgeHeight);
241 SkPaint rect_paint; 150 SkPaint rect_paint;
242 rect_paint.setStyle(SkPaint::kFill_Style); 151 rect_paint.setStyle(SkPaint::kFill_Style);
243 rect_paint.setAntiAlias(true); 152 rect_paint.setAntiAlias(true);
244 rect_paint.setColor(background_color); 153 rect_paint.setColor(background_color);
245 154
246 if (ui::MaterialDesignController::IsModeMaterial()) { 155 // Clear part of the background icon.
247 // Clear part of the background icon. 156 gfx::Rect cutout_rect(rect);
248 gfx::Rect cutout_rect(rect); 157 cutout_rect.Inset(-1, -1);
249 cutout_rect.Inset(-1, -1); 158 SkPaint cutout_paint = rect_paint;
250 SkPaint cutout_paint = rect_paint; 159 cutout_paint.setBlendMode(SkBlendMode::kClear);
251 cutout_paint.setBlendMode(SkBlendMode::kClear); 160 canvas->DrawRoundRect(cutout_rect, 2, cutout_paint);
252 canvas->DrawRoundRect(cutout_rect, 2, cutout_paint);
253 161
254 // Paint the backdrop. 162 // Paint the backdrop.
255 canvas->DrawRoundRect(rect, 1, rect_paint); 163 canvas->DrawRoundRect(rect, 1, rect_paint);
256 164
257 // Paint the text. 165 // Paint the text.
258 rect.Inset(std::max(kPadding, (rect.width() - text_width) / 2), 166 rect.Inset(std::max(kPadding, (rect.width() - text_width) / 2),
259 kBadgeHeight - base_font.GetHeight(), kPadding, 0); 167 kBadgeHeight - base_font.GetHeight(), kPadding, 0);
260 canvas->DrawStringRect(utf16_text, base_font, text_color, rect); 168 canvas->DrawStringRect(utf16_text, base_font, text_color, rect);
261 } else {
262 // Paint the backdrop.
263 canvas->DrawRoundRect(rect, 2, rect_paint);
264
265 // Overlay the gradient. It is stretchy, so we do this in three parts.
266 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
267 gfx::ImageSkia* gradient_left =
268 rb.GetImageSkiaNamed(IDR_BROWSER_ACTION_BADGE_LEFT);
269 gfx::ImageSkia* gradient_right =
270 rb.GetImageSkiaNamed(IDR_BROWSER_ACTION_BADGE_RIGHT);
271 gfx::ImageSkia* gradient_center =
272 rb.GetImageSkiaNamed(IDR_BROWSER_ACTION_BADGE_CENTER);
273
274 canvas->DrawImageInt(*gradient_left, rect.x(), rect.y());
275 canvas->TileImageInt(
276 *gradient_center, rect.x() + gradient_left->width(), rect.y(),
277 rect.width() - gradient_left->width() - gradient_right->width(),
278 rect.height());
279 canvas->DrawImageInt(*gradient_right,
280 rect.right() - gradient_right->width(), rect.y());
281
282 // Finally, draw the text centered within the badge. We set a clip in case
283 // the text was too large.
284 rect.Inset(kPadding, 0);
285 canvas->ClipRect(rect);
286 canvas->sk_canvas()->drawText(
287 badge_->text.c_str(), badge_->text.size(),
288 SkFloatToScalar(rect.x() +
289 static_cast<float>(rect.width() - text_width) / 2),
290 SkFloatToScalar(rect.y() + kTextSize + kTopTextPadding), *text_paint);
291 }
292 canvas->Restore();
293 } 169 }
294 170
295 void IconWithBadgeImageSource::PaintPageActionDecoration(gfx::Canvas* canvas) { 171 void IconWithBadgeImageSource::PaintPageActionDecoration(gfx::Canvas* canvas) {
296 static const SkColor decoration_color = SkColorSetARGB(255, 70, 142, 226); 172 static const SkColor decoration_color = SkColorSetARGB(255, 70, 142, 226);
297 173
298 int major_radius = std::ceil(size().width() / 5.0); 174 int major_radius = std::ceil(size().width() / 5.0);
299 int minor_radius = std::ceil(major_radius / 2.0); 175 int minor_radius = std::ceil(major_radius / 2.0);
300 gfx::Point center_point(major_radius + 1, size().height() - (major_radius)-1); 176 gfx::Point center_point(major_radius + 1, size().height() - (major_radius)-1);
301 SkPaint paint; 177 SkPaint paint;
302 paint.setAntiAlias(true); 178 paint.setAntiAlias(true);
303 paint.setStyle(SkPaint::kFill_Style); 179 paint.setStyle(SkPaint::kFill_Style);
304 paint.setColor(SK_ColorTRANSPARENT); 180 paint.setColor(SK_ColorTRANSPARENT);
305 paint.setBlendMode(SkBlendMode::kSrc); 181 paint.setBlendMode(SkBlendMode::kSrc);
306 canvas->DrawCircle(center_point, major_radius, paint); 182 canvas->DrawCircle(center_point, major_radius, paint);
307 paint.setColor(decoration_color); 183 paint.setColor(decoration_color);
308 canvas->DrawCircle(center_point, minor_radius, paint); 184 canvas->DrawCircle(center_point, minor_radius, paint);
309 } 185 }
310 186
311 void IconWithBadgeImageSource::PaintBlockedActionDecoration( 187 void IconWithBadgeImageSource::PaintBlockedActionDecoration(
312 gfx::Canvas* canvas) { 188 gfx::Canvas* canvas) {
313 canvas->Save(); 189 canvas->Save();
314 gfx::ImageSkia img = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 190 gfx::ImageSkia img = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
315 IDR_BLOCKED_EXTENSION_SCRIPT); 191 IDR_BLOCKED_EXTENSION_SCRIPT);
316 canvas->DrawImageInt(img, size().width() - img.width(), 0); 192 canvas->DrawImageInt(img, size().width() - img.width(), 0);
317 canvas->Restore(); 193 canvas->Restore();
318 } 194 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/libgtk2ui/gtk2_ui.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698