1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 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) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/profiles/profile_avatar_icon_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/format_macros.h" 98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/path_service.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/strings/string_number_conversions.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/strings/stringprintf.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/common/chrome_paths.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "grit/theme_resources.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "skia/ext/image_operations.h" 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h" 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "third_party/skia/include/core/SkPath.h" 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "third_party/skia/include/core/SkScalar.h" 198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "third_party/skia/include/core/SkXfermode.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ui/gfx/image/canvas_image_source.h" 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/gfx/image/image.h" 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/rect.h" 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/skia_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Helper methods for transforming and drawing avatar icons. 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Determine what the scaled height of the avatar icon should be for a 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// specified width, to preserve the aspect ratio. 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)int GetScaledAvatarHeightForWidth(int width, const gfx::ImageSkia& avatar) { 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Multiply the width by the inverted aspect ratio (height over 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // width), and then add 0.5 to ensure the int truncation rounds nicely. 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int scaled_height = width * 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ((float) avatar.height() / (float) avatar.width()) + 0.5f; 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return scaled_height; 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A CanvasImageSource that draws a sized and positioned avatar with an 418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// optional border independently of the scale factor. 428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class AvatarImageSource : public gfx::CanvasImageSource { 438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public: 448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) enum AvatarPosition { 458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) POSITION_CENTER, 468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) POSITION_BOTTOM_CENTER, 478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) }; 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) enum AvatarBorder { 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BORDER_NONE, 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BORDER_NORMAL, 528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BORDER_ETCHED, 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) }; 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AvatarImageSource(gfx::ImageSkia avatar, 568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Size& canvas_size, 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int width, 588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AvatarPosition position, 598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AvatarBorder border); 608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual ~AvatarImageSource(); 618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // CanvasImageSource override: 638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void Draw(gfx::Canvas* canvas) OVERRIDE; 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private: 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::ImageSkia avatar_; 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Size canvas_size_; 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int width_; 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int height_; 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const AvatarPosition position_; 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const AvatarBorder border_; 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AvatarImageSource); 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AvatarImageSource::AvatarImageSource(gfx::ImageSkia avatar, 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Size& canvas_size, 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int width, 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AvatarPosition position, 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AvatarBorder border) 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : gfx::CanvasImageSource(canvas_size, false), 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) canvas_size_(canvas_size), 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) width_(width), 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) height_(GetScaledAvatarHeightForWidth(width, avatar)), 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) position_(position), 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) border_(border) { 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) avatar_ = gfx::ImageSkiaOperations::CreateResizedImage( 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) avatar, skia::ImageOperations::RESIZE_BEST, 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Size(width_, height_)); 908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AvatarImageSource::~AvatarImageSource() { 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void AvatarImageSource::Draw(gfx::Canvas* canvas) { 968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Center the avatar horizontally. 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int x = (canvas_size_.width() - width_) / 2; 988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int y; 998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (position_ == POSITION_CENTER) { 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Draw the avatar centered on the canvas. 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) y = (canvas_size_.height() - height_) / 2; 1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Draw the avatar on the bottom center of the canvas, leaving 1px below. 10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) y = canvas_size_.height() - height_ - 1; 1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) canvas->DrawImageInt(avatar_, x, y); 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The border should be square. 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int border_size = std::max(width_, height_); 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Reset the x and y for the square border. 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) x = (canvas_size_.width() - border_size) / 2; 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) y = (canvas_size_.height() - border_size) / 2; 1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (border_ == BORDER_NORMAL) { 1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Draw a gray border on the inside of the avatar. 1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkColor border_color = SkColorSetARGB(83, 0, 0, 0); 1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Offset the rectangle by a half pixel so the border is drawn within the 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // appropriate pixels no matter the scale factor. Subtract 1 from the right 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // and bottom sizes to specify the endpoints, yielding -0.5. 1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkPath path; 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) path.addRect(SkFloatToScalar(x + 0.5f), // left 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkFloatToScalar(y + 0.5f), // top 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SkFloatToScalar(x + border_size - 0.5f), // right 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SkFloatToScalar(y + border_size - 0.5f)); // bottom 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkPaint paint; 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint.setColor(border_color); 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint.setStyle(SkPaint::kStroke_Style); 1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint.setStrokeWidth(SkIntToScalar(1)); 1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) canvas->DrawPath(path, paint); 1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else if (border_ == BORDER_ETCHED) { 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Give the avatar an etched look by drawing a highlight on the bottom and 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // right edges. 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkColor shadow_color = SkColorSetARGB(83, 0, 0, 0); 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkColor highlight_color = SkColorSetARGB(96, 255, 255, 255); 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkPaint paint; 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint.setStyle(SkPaint::kStroke_Style); 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint.setStrokeWidth(SkIntToScalar(1)); 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkPath path; 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Left and top shadows. To support higher scale factors than 1, position 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // the orthogonal dimension of each line on the half-pixel to separate the 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // pixel. For a vertical line, this means adding 0.5 to the x-value. 15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path.moveTo(SkFloatToScalar(x + 0.5f), SkIntToScalar(y + height_)); 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Draw up to the top-left. Stop with the y-value at a half-pixel. 15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path.rLineTo(SkIntToScalar(0), SkFloatToScalar(-height_ + 0.5f)); 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Draw right to the top-right, stopping within the last pixel. 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path.rLineTo(SkFloatToScalar(width_ - 0.5f), SkIntToScalar(0)); 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint.setColor(shadow_color); 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) canvas->DrawPath(path, paint); 1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) path.reset(); 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Bottom and right highlights. Note that the shadows own the shared corner 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // pixels, so reduce the sizes accordingly. 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path.moveTo(SkIntToScalar(x + 1), SkFloatToScalar(y + height_ - 0.5f)); 1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Draw right to the bottom-right. 16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path.rLineTo(SkFloatToScalar(width_ - 1.5f), SkIntToScalar(0)); 1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Draw up to the top-right. 17123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path.rLineTo(SkIntToScalar(0), SkFloatToScalar(-height_ + 1.5f)); 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint.setColor(highlight_color); 1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) canvas->DrawPath(path, paint); 1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace profiles { 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstruct IconResourceInfo { 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int resource_id; 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const char* filename; 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kAvatarIconWidth = 38; 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kAvatarIconHeight = 31; 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst SkColor kAvatarTutorialBackgroundColor = SkColorSetRGB(0x42, 0x85, 0xf4); 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst SkColor kAvatarTutorialContentTextColor = SkColorSetRGB(0xc6, 0xda, 0xfc); 1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst SkColor kAvatarBubbleAccountsBackgroundColor = 1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SkColorSetRGB(0xf3, 0xf3, 0xf3); 193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_"; 195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kGAIAPictureFileName[] = "Google Profile Picture.png"; 196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kHighResAvatarFolderName[] = "Avatars"; 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This avatar does not exist on the server, the high res copy is in the build. 1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char kNoHighResAvatar[] = "NothingToDownload"; 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// The size of the function-static kDefaultAvatarIconResources array below. 2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst size_t kDefaultAvatarIconsCount = 27; 203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// The first 8 icons are generic. 205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst size_t kGenericAvatarIconsCount = 8; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// The avatar used as a placeholder (grey silhouette). 2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst int kPlaceholderAvatarIcon = 26; 2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochgfx::Image GetSizedAvatarIcon(const gfx::Image& image, 2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool is_rectangle, 2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int width, int height) { 2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!is_rectangle && image.Height() <= height) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Size size(width, height); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Source for a centered, sized icon. GAIA images get a border. 2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<gfx::ImageSkiaSource> source( 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new AvatarImageSource( 2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) *image.ToImageSkia(), 2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) size, 2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::min(width, height), 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AvatarImageSource::POSITION_CENTER, 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu AvatarImageSource::BORDER_NONE)); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return gfx::Image(gfx::ImageSkia(source.release(), size)); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)gfx::Image GetAvatarIconForMenu(const gfx::Image& image, 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_rectangle) { 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return GetSizedAvatarIcon( 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) image, is_rectangle, kAvatarIconWidth, kAvatarIconHeight); 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image GetAvatarIconForWebUI(const gfx::Image& image, 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_rectangle) { 2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return GetSizedAvatarIcon(image, is_rectangle, 2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch kAvatarIconWidth, kAvatarIconHeight); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image GetAvatarIconForTitleBar(const gfx::Image& image, 2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool is_gaia_image, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dst_width, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dst_height) { 2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The image requires no border or resizing. 2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!is_gaia_image && image.Height() <= kAvatarIconHeight) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int size = std::min(std::min(kAvatarIconWidth, kAvatarIconHeight), 2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::min(dst_width, dst_height)); 2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Size dst_size(dst_width, dst_height); 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Source for a sized icon drawn at the bottom center of the canvas, 2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // with an etched border (for GAIA images). 2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<gfx::ImageSkiaSource> source( 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new AvatarImageSource( 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) *image.ToImageSkia(), 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) dst_size, 2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) size, 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AvatarImageSource::POSITION_BOTTOM_CENTER, 2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch is_gaia_image ? AvatarImageSource::BORDER_ETCHED : 2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AvatarImageSource::BORDER_NONE)); 2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return gfx::Image(gfx::ImageSkia(source.release(), dst_size)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SkBitmap GetAvatarIconAsSquare(const SkBitmap& source_bitmap, 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int scale_factor) { 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SkBitmap square_bitmap; 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if ((source_bitmap.width() == scale_factor * profiles::kAvatarIconWidth) && 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (source_bitmap.height() == scale_factor * profiles::kAvatarIconHeight)) { 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Shave a couple of columns so the |source_bitmap| is more square. So when 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // resized to a square aspect ratio it looks pretty. 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Rect frame(scale_factor * profiles::kAvatarIconWidth, 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scale_factor * profiles::kAvatarIconHeight); 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) frame.Inset(scale_factor * 2, 0, scale_factor * 2, 0); 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) source_bitmap.extractSubset(&square_bitmap, gfx::RectToSkIRect(frame)); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If not the avatar icon's aspect ratio, the image should be square. 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(source_bitmap.width() == source_bitmap.height()); 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) square_bitmap = source_bitmap; 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return square_bitmap; 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Helper methods for accessing, transforming and drawing avatar icons. 288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochsize_t GetDefaultAvatarIconCount() { 289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return kDefaultAvatarIconsCount; 290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochsize_t GetGenericAvatarIconCount() { 293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return kGenericAvatarIconsCount; 294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint GetPlaceholderAvatarIndex() { 2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return kPlaceholderAvatarIcon; 2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint GetPlaceholderAvatarIconResourceID() { 3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return IDR_PROFILE_AVATAR_26; 3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst IconResourceInfo* GetDefaultAvatarIconResourceInfo(size_t index) { 3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch static const IconResourceInfo resource_info[kDefaultAvatarIconsCount] = { 3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_0, "avatar_generic.png"}, 3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_1, "avatar_generic_aqua.png"}, 3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_2, "avatar_generic_blue.png"}, 3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_3, "avatar_generic_green.png"}, 3100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_4, "avatar_generic_orange.png"}, 3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_5, "avatar_generic_purple.png"}, 3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_6, "avatar_generic_red.png"}, 3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_7, "avatar_generic_yellow.png"}, 3140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_8, "avatar_secret_agent.png"}, 3150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_9, "avatar_superhero.png"}, 3160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_10, "avatar_volley_ball.png"}, 3170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_11, "avatar_businessman.png"}, 3180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_12, "avatar_ninja.png"}, 3190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_13, "avatar_alien.png"}, 3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_14, "avatar_smiley.png"}, 3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_15, "avatar_flower.png"}, 3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_16, "avatar_pizza.png"}, 3230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_17, "avatar_soccer.png"}, 3240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_18, "avatar_burger.png"}, 3250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_19, "avatar_cat.png"}, 3260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_20, "avatar_cupcake.png"}, 3270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_21, "avatar_dog.png"}, 3280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_22, "avatar_horse.png"}, 3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_23, "avatar_margarita.png"}, 3300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_24, "avatar_note.png"}, 3310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_25, "avatar_sun_cloud.png"}, 3320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { IDR_PROFILE_AVATAR_26, kNoHighResAvatar}, 3330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch }; 3340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return &resource_info[index]; 3350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint GetDefaultAvatarIconResourceIDAtIndex(size_t index) { 338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(IsDefaultAvatarIconIndex(index)); 3390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return GetDefaultAvatarIconResourceInfo(index)->resource_id; 340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 341c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 342c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char* GetDefaultAvatarIconFileNameAtIndex(size_t index) { 3430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(index < kDefaultAvatarIconsCount); 3440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return GetDefaultAvatarIconResourceInfo(index)->filename; 3450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char* GetNoHighResAvatarFileName() { 3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return kNoHighResAvatar; 349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 350c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::FilePath GetPathOfHighResAvatarAtIndex(size_t index) { 352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string file_name = GetDefaultAvatarIconResourceInfo(index)->filename; 353010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::FilePath user_data_dir; 354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return user_data_dir.AppendASCII( 356010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kHighResAvatarFolderName).AppendASCII(file_name); 357010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 358010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 359c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstd::string GetDefaultAvatarIconUrl(size_t index) { 360c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(IsDefaultAvatarIconIndex(index)); 361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return base::StringPrintf("%s%" PRIuS, kDefaultUrlPrefix, index); 362c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 363c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 364c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool IsDefaultAvatarIconIndex(size_t index) { 365c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return index < kDefaultAvatarIconsCount; 366c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool IsDefaultAvatarIconUrl(const std::string& url, size_t* icon_index) { 369c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(icon_index); 370c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (url.find(kDefaultUrlPrefix) != 0) 371c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 372c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 373c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int int_value = -1; 374c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (base::StringToInt(base::StringPiece(url.begin() + 375c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch strlen(kDefaultUrlPrefix), 376c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch url.end()), 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &int_value)) { 378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (int_value < 0 || 379c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int_value >= static_cast<int>(kDefaultAvatarIconsCount)) 380c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 381c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *icon_index = int_value; 382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return true; 383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 38868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace profiles 389