OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/chromeos/login/username_view.h" | 5 #include "chrome/browser/chromeos/login/username_view.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "chrome/browser/chromeos/login/rounded_view.h" |
9 #include "gfx/canvas.h" | 10 #include "gfx/canvas.h" |
10 #include "gfx/canvas_skia.h" | 11 #include "gfx/canvas_skia.h" |
11 #include "gfx/rect.h" | 12 #include "gfx/rect.h" |
| 13 #include "third_party/skia/include/core/SkColorShader.h" |
12 #include "third_party/skia/include/core/SkComposeShader.h" | 14 #include "third_party/skia/include/core/SkComposeShader.h" |
13 #include "third_party/skia/include/effects/SkGradientShader.h" | 15 #include "third_party/skia/include/effects/SkGradientShader.h" |
14 | 16 |
| 17 namespace chromeos { |
| 18 |
15 namespace { | 19 namespace { |
16 // Username label background color. | 20 // Username label background color. |
17 const SkColor kLabelBackgoundColor = 0x55000000; | 21 const SkColor kLabelBackgoundColor = 0x55000000; |
18 // Holds margin to height ratio. | 22 // Holds margin to height ratio. |
19 const double kMarginRatio = 1.0 / 3.0; | 23 const double kMarginRatio = 1.0 / 3.0; |
| 24 // Holds the frame width for the small shaped username view. |
| 25 const SkScalar kSmallShapeFrameWidth = SkIntToScalar(1); |
| 26 |
| 27 // Class that sets up half rounded rectangle (only the bottom corners are |
| 28 // rounded) as a clip region of the view. |
| 29 // For more info see the file "chrome/browser/chromeos/login/rounded_view.h". |
| 30 template<typename C> |
| 31 class HalfRoundedView : public RoundedView<C> { |
| 32 public: |
| 33 HalfRoundedView(const std::wstring &text, bool use_small_shape) |
| 34 : RoundedView<C>(text), use_small_shape_(use_small_shape) { |
| 35 } |
| 36 |
| 37 protected: |
| 38 // Overrides ViewFilter. |
| 39 virtual SkPath GetClipPath() const { |
| 40 if (!use_small_shape_) { |
| 41 return RoundedView<C>::GetClipPath(); |
| 42 } else { |
| 43 SkPath path; |
| 44 gfx::Rect bounds = C::GetLocalBounds(false); |
| 45 bounds.Inset(kSmallShapeFrameWidth, kSmallShapeFrameWidth, |
| 46 kSmallShapeFrameWidth, kSmallShapeFrameWidth); |
| 47 path.addRect(SkIntToScalar(bounds.x()), |
| 48 SkIntToScalar(bounds.y()), |
| 49 SkIntToScalar(bounds.x() + bounds.width()), |
| 50 SkIntToScalar(bounds.y() + bounds.height())); |
| 51 return path; |
| 52 } |
| 53 } |
| 54 |
| 55 virtual void DrawFrame(gfx::Canvas* canvas) { |
| 56 // No frame is needed. |
| 57 } |
| 58 |
| 59 virtual SkRect GetViewRect() const { |
| 60 gfx::Rect bounds = C::GetLocalBounds(false); |
| 61 SkRect view_rect; |
| 62 // The rectangle will be intersected with the bounds, so the correct half |
| 63 // of the round rectangle will be obtained. |
| 64 view_rect.iset(bounds.x(), bounds.y() - bounds.width(), |
| 65 bounds.x() + bounds.width(), |
| 66 bounds.y() + bounds.height()); |
| 67 return view_rect; |
| 68 } |
| 69 |
| 70 private: |
| 71 // Whether the shape for the smaller view should be used. |
| 72 bool use_small_shape_; |
| 73 }; |
| 74 |
20 } // namespace | 75 } // namespace |
21 | |
22 namespace chromeos { | |
23 | |
24 UsernameView::UsernameView(const std::wstring& username) | 76 UsernameView::UsernameView(const std::wstring& username) |
25 : views::Label(username) { | 77 : views::Label(username) { |
26 } | 78 } |
27 | 79 |
28 void UsernameView::Paint(gfx::Canvas* canvas) { | 80 void UsernameView::Paint(gfx::Canvas* canvas) { |
29 gfx::Rect bounds = GetLocalBounds(false); | 81 gfx::Rect bounds = GetLocalBounds(false); |
30 if (!text_image_.get()) | 82 if (!text_image_.get()) |
31 PaintUsername(bounds); | 83 PaintUsername(bounds); |
32 | 84 |
33 DCHECK(bounds.size() == | 85 DCHECK(bounds.size() == |
34 gfx::Size(text_image_->width(), text_image_->height())); | 86 gfx::Size(text_image_->width(), text_image_->height())); |
35 | 87 |
| 88 canvas->DrawBitmapInt(*text_image_, bounds.x(), bounds.y()); |
| 89 } |
| 90 |
| 91 // static |
| 92 UsernameView* UsernameView::CreateShapedUsernameView( |
| 93 const std::wstring& username, |
| 94 bool use_small_shape) { |
| 95 return new HalfRoundedView<UsernameView>(username, use_small_shape); |
| 96 } |
| 97 |
| 98 void UsernameView::PaintUsername(const gfx::Rect& bounds) { |
| 99 margin_width_ = bounds.height() * kMarginRatio; |
| 100 gfx::CanvasSkia canvas(bounds.width(), bounds.height(), false); |
| 101 // Draw transparent background. |
| 102 canvas.drawColor(0); |
| 103 |
| 104 // Calculate needed space. |
| 105 int flags = gfx::Canvas::TEXT_ALIGN_LEFT | |
| 106 gfx::Canvas::TEXT_VALIGN_MIDDLE | |
| 107 gfx::Canvas::NO_ELLIPSIS; |
| 108 int text_height, text_width; |
| 109 gfx::CanvasSkia::SizeStringInt(WideToUTF16Hack(GetText()), font(), |
| 110 &text_width, &text_height, |
| 111 flags); |
| 112 text_width += margin_width_; |
| 113 |
| 114 // Also leave the right margin. |
| 115 bool use_fading_for_text = text_width + margin_width_ >= bounds.width(); |
| 116 |
36 // Only alpha channel counts. | 117 // Only alpha channel counts. |
37 SkColor gradient_colors[2]; | 118 SkColor gradient_colors[2]; |
38 gradient_colors[0] = 0xFFFFFFFF; | 119 gradient_colors[0] = 0xFFFFFFFF; |
39 gradient_colors[1] = 0x00FFFFFF; | 120 gradient_colors[1] = 0x00FFFFFF; |
40 | 121 |
41 int gradient_start = std::min(margin_width_ + text_width_, | 122 int gradient_start = use_fading_for_text ? |
42 bounds.width() - bounds.height()); | 123 bounds.width() - bounds.height() - margin_width_ : |
| 124 text_width; |
| 125 int gradient_end = std::min(gradient_start + bounds.height(), |
| 126 bounds.width() - margin_width_); |
43 | 127 |
44 SkPoint gradient_borders[2]; | 128 SkPoint gradient_borders[2]; |
45 gradient_borders[0].set(SkIntToScalar(gradient_start), SkIntToScalar(0)); | 129 gradient_borders[0].set(SkIntToScalar(gradient_start), SkIntToScalar(0)); |
46 gradient_borders[1].set(SkIntToScalar( | 130 gradient_borders[1].set(SkIntToScalar(gradient_end), SkIntToScalar(0)); |
47 gradient_start + bounds.height()), SkIntToScalar(0)); | |
48 | 131 |
49 SkShader* gradient_shader = | 132 SkShader* gradient_shader = |
50 SkGradientShader::CreateLinear(gradient_borders, gradient_colors, NULL, 2, | 133 SkGradientShader::CreateLinear(gradient_borders, gradient_colors, NULL, 2, |
51 SkShader::kClamp_TileMode, NULL); | 134 SkShader::kClamp_TileMode, NULL); |
52 SkShader* image_shader = SkShader::CreateBitmapShader( | |
53 *text_image_, | |
54 SkShader::kRepeat_TileMode, | |
55 SkShader::kRepeat_TileMode); | |
56 | 135 |
57 SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrcIn_Mode); | 136 if (!use_fading_for_text) { |
58 SkShader* composite_shader = new SkComposeShader(gradient_shader, | 137 // Draw the final background with the fading in the end. |
59 image_shader, mode); | 138 SkShader* solid_shader = new SkColorShader(kLabelBackgoundColor); |
60 gradient_shader->unref(); | 139 SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrcIn_Mode); |
61 image_shader->unref(); | 140 SkShader* composite_shader = new SkComposeShader(gradient_shader, |
| 141 solid_shader, mode); |
| 142 gradient_shader->unref(); |
| 143 solid_shader->unref(); |
62 | 144 |
63 SkPaint paint; | 145 SkPaint paint; |
64 paint.setAntiAlias(true); | 146 paint.setShader(composite_shader)->unref(); |
65 paint.setFilterBitmap(true); | 147 canvas.drawPaint(paint); |
66 paint.setShader(composite_shader)->unref(); | 148 } |
67 canvas->DrawRectInt(bounds.x(), bounds.y(), | |
68 bounds.width(), bounds.height(), paint); | |
69 } | |
70 | 149 |
71 void UsernameView::PaintUsername(const gfx::Rect& bounds) { | |
72 margin_width_ = bounds.height() * kMarginRatio; | |
73 gfx::CanvasSkia canvas(bounds.width(), bounds.height(), false); | |
74 // Draw background. | |
75 canvas.drawColor(kLabelBackgoundColor); | |
76 // Calculate needed space. | |
77 int flags = gfx::Canvas::TEXT_ALIGN_LEFT | | |
78 gfx::Canvas::TEXT_VALIGN_MIDDLE | | |
79 gfx::Canvas::NO_ELLIPSIS; | |
80 int text_height; | |
81 gfx::CanvasSkia::SizeStringInt(WideToUTF16Hack(GetText()), font(), | |
82 &text_width_, &text_height, | |
83 flags); | |
84 text_width_ = std::min(text_width_, bounds.width() - margin_width_); | |
85 // Draw the text. | 150 // Draw the text. |
86 // Note, direct call of the DrawStringInt method produces the green dots | 151 // Note, direct call of the DrawStringInt method produces the green dots |
87 // along the text perimeter (when the label is place on the white background). | 152 // along the text perimeter (when the label is place on the white background). |
88 SkColor kInvisibleHaloColor = 0x00000000; | 153 SkColor kInvisibleHaloColor = 0x00000000; |
89 canvas.DrawStringWithHalo(GetText(), font(), GetColor(), kInvisibleHaloColor, | 154 canvas.DrawStringWithHalo(GetText(), font(), GetColor(), kInvisibleHaloColor, |
90 bounds.x() + margin_width_, bounds.y(), | 155 bounds.x() + margin_width_, bounds.y(), |
91 bounds.width() - margin_width_, bounds.height(), | 156 bounds.width() - 2 * margin_width_, bounds.height(), |
92 flags); | 157 flags); |
93 | 158 |
94 text_image_.reset(new SkBitmap(canvas.ExtractBitmap())); | 159 text_image_.reset(new SkBitmap(canvas.ExtractBitmap())); |
95 text_image_->buildMipMap(false); | 160 |
| 161 if (use_fading_for_text) { |
| 162 // Fade out only the text in the end. Use regualar background. |
| 163 canvas.drawColor(kLabelBackgoundColor, SkXfermode::kSrc_Mode); |
| 164 SkShader* image_shader = SkShader::CreateBitmapShader( |
| 165 *text_image_, |
| 166 SkShader::kRepeat_TileMode, |
| 167 SkShader::kRepeat_TileMode); |
| 168 SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrcIn_Mode); |
| 169 SkShader* composite_shader = new SkComposeShader(gradient_shader, |
| 170 image_shader, mode); |
| 171 gradient_shader->unref(); |
| 172 image_shader->unref(); |
| 173 |
| 174 SkPaint paint; |
| 175 paint.setShader(composite_shader)->unref(); |
| 176 canvas.drawPaint(paint); |
| 177 text_image_.reset(new SkBitmap(canvas.ExtractBitmap())); |
| 178 } |
96 } | 179 } |
97 | 180 |
98 } // namespace chromeos | 181 } // namespace chromeos |
OLD | NEW |