15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/badge_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/ui_resources.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkTypeface.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Different platforms need slightly different constants to look good. 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kTextSize = 9.0; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginBrowserAction = 0; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginPageAction = 2; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPadding = 2; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kTopTextPadding = 0; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kTextSize = 8.0; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginBrowserAction = 5; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginPageAction = 2; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPadding = 2; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kTopTextPadding = 1; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_MACOSX) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kTextSize = 9.0; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginBrowserAction = 5; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginPageAction = 2; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPadding = 2; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kTopTextPadding = 0; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float kTextSize = 10; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginBrowserAction = 5; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBottomMarginPageAction = 2; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPadding = 2; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The padding between the top of the badge and the top of the text. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kTopTextPadding = -1; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBadgeHeight = 11; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMaxTextWidth = 23; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The minimum width for center-aligning the badge. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kCenterAlignThreshold = 20; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace badge_util { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkPaint* GetBadgeTextPaintSingleton() { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kPreferredTypeface[] = "Helvetica Bold"; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kPreferredTypeface[] = "Arial"; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SkPaint* text_paint = NULL; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!text_paint) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_paint = new SkPaint; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_paint->setAntiAlias(true); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_paint->setTextAlign(SkPaint::kLeft_Align); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::RefPtr<SkTypeface> typeface = skia::AdoptRef( 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkTypeface::CreateFromName(kPreferredTypeface, SkTypeface::kBold)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skia doesn't do any font fallback---if the user is missing the font then 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // typeface will be NULL. If we don't do manual fallback then we'll crash. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (typeface) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_paint->setFakeBoldText(true); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall back to the system font. We don't bold it because we aren't sure 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // how it will look. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For the most part this code path will only be hit on Linux systems 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that don't have Arial. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typeface = skia::AdoptRef(SkTypeface::CreateFromName( 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base_font.GetFontName().c_str(), SkTypeface::kNormal)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(typeface); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_paint->setTypeface(typeface.get()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |text_paint| adds its own ref. Release the ref from CreateFontName. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return text_paint; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap DrawBadgeIconOverlay(const SkBitmap& icon, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float font_size, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& text, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& fallback) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMinPadding = 1; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculate the proper style/text overlay to render on the badge. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint* paint = badge_util::GetBadgeTextPaintSingleton(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint->setTextSize(SkFloatToScalar(font_size)); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint->setColor(SK_ColorWHITE); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string badge_text = UTF16ToUTF8(text); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See if the text will fit - otherwise use a default. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar text_width = paint->measureText(badge_text.c_str(), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) badge_text.size()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SkScalarRound(text_width) > (icon.width() - kMinPadding * 2)) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // String is too large - use the alternate text. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) badge_text = UTF16ToUTF8(fallback); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_width = paint->measureText(badge_text.c_str(), badge_text.size()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When centering the text, we need to make sure there are an equal number 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of pixels on each side as otherwise the text looks off-center. So if the 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // padding would be uneven, clip one pixel off the right side. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int badge_width = icon.width(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((SkScalarRound(text_width) % 1) != (badge_width % 1)) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) badge_width--; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Render the badge bitmap and overlay into a canvas. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<gfx::Canvas> canvas(new gfx::Canvas( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size(badge_width, icon.height()), ui::SCALE_FACTOR_100P, false)); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(icon), 0, 0); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Draw the text overlay centered horizontally and vertically. Skia expects 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // us to specify the lower left coordinate of the text box, which is why we 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // add 'font_size - 1' to the height. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar x = (badge_width - text_width)/2; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar y = (icon.height() - font_size)/2 + font_size - 1; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->sk_canvas()->drawText( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) badge_text.c_str(), badge_text.size(), x, y, *paint); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return the generated image. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas->ExtractImageRep().sk_bitmap(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PaintBadge(gfx::Canvas* canvas, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& bounds, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& text, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkColor& text_color_in, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkColor& background_color_in, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int icon_width, 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ActionInfo::Type action_type) { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (text.empty()) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor text_color = text_color_in; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (SkColorGetA(text_color_in) == 0x00) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_color = SK_ColorWHITE; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor background_color = background_color_in; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (SkColorGetA(background_color_in) == 0x00) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) background_color = SkColorSetARGB(255, 218, 0, 24); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->Save(); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkPaint* text_paint = badge_util::GetBadgeTextPaintSingleton(); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_paint->setTextSize(SkFloatToScalar(kTextSize)); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_paint->setColor(text_color); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Calculate text width. We clamp it to a max size. 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkScalar sk_text_width = text_paint->measureText(text.c_str(), text.size()); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int text_width = std::min(kMaxTextWidth, SkScalarFloor(sk_text_width)); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Calculate badge size. It is clamped to a min width just because it looks 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // silly if it is too skinny. 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int badge_width = text_width + kPadding * 2; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Force the pixel width of badge to be either odd (if the icon width is odd) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // or even otherwise. If there is a mismatch you get http://crbug.com/26400. 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (icon_width != 0 && (badge_width % 2 != icon_width % 2)) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) badge_width += 1; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) badge_width = std::max(kBadgeHeight, badge_width); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Paint the badge background color in the right location. It is usually 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // right-aligned, but it can also be center-aligned if it is large. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rect_height = kBadgeHeight; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom_margin = 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) action_type == extensions::ActionInfo::TYPE_BROWSER ? 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kBottomMarginBrowserAction : kBottomMarginPageAction; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rect_y = bounds.bottom() - bottom_margin - kBadgeHeight; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rect_width = badge_width; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rect_x = (badge_width >= kCenterAlignThreshold) ? 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.x() + (bounds.width() - badge_width) / 2 : 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.right() - badge_width; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect rect(rect_x, rect_y, rect_width, rect_height); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkPaint rect_paint; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect_paint.setStyle(SkPaint::kFill_Style); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect_paint.setAntiAlias(true); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect_paint.setColor(background_color); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawRoundRect(rect, 2, rect_paint); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overlay the gradient. It is stretchy, so we do this in three parts. 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::ImageSkia* gradient_left = rb.GetImageSkiaNamed( 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDR_BROWSER_ACTION_BADGE_LEFT); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::ImageSkia* gradient_right = rb.GetImageSkiaNamed( 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDR_BROWSER_ACTION_BADGE_RIGHT); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::ImageSkia* gradient_center = rb.GetImageSkiaNamed( 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDR_BROWSER_ACTION_BADGE_CENTER); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawImageInt(*gradient_left, rect.x(), rect.y()); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->TileImageInt(*gradient_center, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect.x() + gradient_left->width(), 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect.y(), 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect.width() - gradient_left->width() - gradient_right->width(), 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect.height()); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawImageInt(*gradient_right, 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect.right() - gradient_right->width(), rect.y()); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Finally, draw the text centered within the badge. We set a clip in case the 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // text was too large. 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect.Inset(kPadding, 0); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->ClipRect(rect); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->sk_canvas()->drawText( 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text.c_str(), text.size(), 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkFloatToScalar(rect.x() + 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<float>(rect.width() - text_width) / 2), 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkFloatToScalar(rect.y() + kTextSize + kTopTextPadding), 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *text_paint); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->Restore(); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace badge_util 230