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
3 // found in the LICENSE file.
5 #include "chrome/browser/profiles/profile_info_util.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "third_party/skia/include/core/SkPaint.h"
9 #include "third_party/skia/include/core/SkPath.h"
10 #include "third_party/skia/include/core/SkScalar.h"
11 #include "third_party/skia/include/core/SkXfermode.h"
12 #include "ui/gfx/canvas.h"
13 #include "ui/gfx/image/canvas_image_source.h"
14 #include "ui/gfx/image/image_skia_operations.h"
18 const int kAvatarIconWidth
= 38;
19 const int kAvatarIconHeight
= 31;
20 const int kAvatarIconPadding
= 2;
24 // A CanvasImageSource that draws a sized and positioned avatar with an
25 // optional border independently of the scale factor.
26 class AvatarImageSource
: public gfx::CanvasImageSource
{
30 POSITION_BOTTOM_CENTER
,
39 AvatarImageSource(gfx::ImageSkia avatar
,
40 const gfx::Size
& canvas_size
,
42 AvatarPosition position
,
44 virtual ~AvatarImageSource();
46 // CanvasImageSource override:
47 virtual void Draw(gfx::Canvas
* canvas
) OVERRIDE
;
50 gfx::ImageSkia avatar_
;
51 const gfx::Size canvas_size_
;
53 const AvatarPosition position_
;
54 const AvatarBorder border_
;
56 DISALLOW_COPY_AND_ASSIGN(AvatarImageSource
);
59 AvatarImageSource::AvatarImageSource(gfx::ImageSkia avatar
,
60 const gfx::Size
& canvas_size
,
62 AvatarPosition position
,
64 : gfx::CanvasImageSource(canvas_size
, false),
65 canvas_size_(canvas_size
),
66 size_(size
- kAvatarIconPadding
),
69 // Resize the avatar to the desired square size.
70 avatar_
= gfx::ImageSkiaOperations::CreateResizedImage(
71 avatar
, skia::ImageOperations::RESIZE_BEST
, gfx::Size(size_
, size_
));
74 AvatarImageSource::~AvatarImageSource() {
77 void AvatarImageSource::Draw(gfx::Canvas
* canvas
) {
78 // Center the avatar horizontally.
79 int x
= (canvas_size_
.width() - size_
) / 2;
82 if (position_
== POSITION_CENTER
) {
83 // Draw the avatar centered on the canvas.
84 y
= (canvas_size_
.height() - size_
) / 2;
86 // Draw the avatar on the bottom center of the canvas, leaving 1px below.
87 y
= canvas_size_
.height() - size_
- 1;
90 canvas
->DrawImageInt(avatar_
, x
, y
);
92 if (border_
== BORDER_NORMAL
) {
93 // Draw a gray border on the inside of the avatar.
94 SkColor border_color
= SkColorSetARGB(83, 0, 0, 0);
96 // Offset the rectangle by a half pixel so the border is drawn within the
97 // appropriate pixels no matter the scale factor. Subtract 1 from the right
98 // and bottom sizes to specify the endpoints, yielding -0.5.
100 path
.addRect(SkFloatToScalar(x
+ 0.5f
), // left
101 SkFloatToScalar(y
+ 0.5f
), // top
102 SkFloatToScalar(x
+ size_
- 0.5f
), // right
103 SkFloatToScalar(y
+ size_
- 0.5f
)); // bottom
106 paint
.setColor(border_color
);
107 paint
.setStyle(SkPaint::kStroke_Style
);
108 paint
.setStrokeWidth(SkIntToScalar(1));
110 canvas
->DrawPath(path
, paint
);
111 } else if (border_
== BORDER_ETCHED
) {
112 // Give the avatar an etched look by drawing a highlight on the bottom and
114 SkColor shadow_color
= SkColorSetARGB(83, 0, 0, 0);
115 SkColor highlight_color
= SkColorSetARGB(96, 255, 255, 255);
118 paint
.setStyle(SkPaint::kStroke_Style
);
119 paint
.setStrokeWidth(SkIntToScalar(1));
123 // Left and top shadows. To support higher scale factors than 1, position
124 // the orthogonal dimension of each line on the half-pixel to separate the
125 // pixel. For a vertical line, this means adding 0.5 to the x-value.
126 path
.moveTo(SkFloatToScalar(x
+ 0.5f
), SkIntToScalar(y
+ size_
));
128 // Draw up to the top-left. Stop with the y-value at a half-pixel.
129 path
.rLineTo(SkIntToScalar(0), SkFloatToScalar(-size_
+ 0.5f
));
131 // Draw right to the top-right, stopping within the last pixel.
132 path
.rLineTo(SkFloatToScalar(size_
- 0.5f
), SkIntToScalar(0));
134 paint
.setColor(shadow_color
);
135 canvas
->DrawPath(path
, paint
);
139 // Bottom and right highlights. Note that the shadows own the shared corner
140 // pixels, so reduce the sizes accordingly.
141 path
.moveTo(SkIntToScalar(x
+ 1), SkFloatToScalar(y
+ size_
- 0.5f
));
143 // Draw right to the bottom-right.
144 path
.rLineTo(SkFloatToScalar(size_
- 1.5f
), SkIntToScalar(0));
146 // Draw up to the top-right.
147 path
.rLineTo(SkIntToScalar(0), SkFloatToScalar(-size_
+ 1.5f
));
149 paint
.setColor(highlight_color
);
150 canvas
->DrawPath(path
, paint
);
154 } // namespace internal
156 gfx::Image
GetSizedAvatarIconWithBorder(const gfx::Image
& image
,
158 int width
, int height
) {
162 gfx::Size
size(width
, height
);
164 // Source for a centered, sized icon with a border.
165 scoped_ptr
<gfx::ImageSkiaSource
> source(
166 new internal::AvatarImageSource(
167 *image
.ToImageSkia(),
169 std::min(width
, height
),
170 internal::AvatarImageSource::POSITION_CENTER
,
171 internal::AvatarImageSource::BORDER_NORMAL
));
173 return gfx::Image(gfx::ImageSkia(source
.release(), size
));
176 gfx::Image
GetAvatarIconForMenu(const gfx::Image
& image
,
178 return GetSizedAvatarIconWithBorder(
179 image
, is_rectangle
, kAvatarIconWidth
, kAvatarIconHeight
);
182 gfx::Image
GetAvatarIconForWebUI(const gfx::Image
& image
,
187 gfx::Size
size(kAvatarIconWidth
, kAvatarIconHeight
);
189 // Source for a centered, sized icon.
190 scoped_ptr
<gfx::ImageSkiaSource
> source(
191 new internal::AvatarImageSource(
192 *image
.ToImageSkia(),
194 std::min(kAvatarIconWidth
, kAvatarIconHeight
),
195 internal::AvatarImageSource::POSITION_CENTER
,
196 internal::AvatarImageSource::BORDER_NONE
));
198 return gfx::Image(gfx::ImageSkia(source
.release(), size
));
201 gfx::Image
GetAvatarIconForTitleBar(const gfx::Image
& image
,
208 int size
= std::min(std::min(kAvatarIconWidth
, kAvatarIconHeight
),
209 std::min(dst_width
, dst_height
));
210 gfx::Size
dst_size(dst_width
, dst_height
);
212 // Source for a sized icon drawn at the bottom center of the canvas,
213 // with an etched border.
214 scoped_ptr
<gfx::ImageSkiaSource
> source(
215 new internal::AvatarImageSource(
216 *image
.ToImageSkia(),
219 internal::AvatarImageSource::POSITION_BOTTOM_CENTER
,
220 internal::AvatarImageSource::BORDER_ETCHED
));
222 return gfx::Image(gfx::ImageSkia(source
.release(), dst_size
));
225 } // namespace profiles