OLD | NEW |
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 "ui/wm/core/image_grid.h" | 5 #include "ui/wm/core/image_grid.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "third_party/skia/include/core/SkColor.h" | 9 #include "third_party/skia/include/core/SkColor.h" |
10 #include "third_party/skia/include/core/SkXfermode.h" | 10 #include "third_party/skia/include/core/SkXfermode.h" |
11 #include "ui/compositor/dip_util.h" | 11 #include "ui/compositor/dip_util.h" |
12 #include "ui/gfx/canvas.h" | 12 #include "ui/gfx/canvas.h" |
13 #include "ui/gfx/image/image.h" | 13 #include "ui/gfx/image/image.h" |
| 14 #include "ui/gfx/image/image_skia_operations.h" |
14 #include "ui/gfx/rect.h" | 15 #include "ui/gfx/rect.h" |
15 #include "ui/gfx/rect_conversions.h" | 16 #include "ui/gfx/rect_conversions.h" |
16 #include "ui/gfx/size.h" | 17 #include "ui/gfx/size.h" |
17 #include "ui/gfx/size_conversions.h" | 18 #include "ui/gfx/size_conversions.h" |
18 #include "ui/gfx/transform.h" | 19 #include "ui/gfx/transform.h" |
19 | 20 |
20 using std::max; | 21 using std::max; |
21 using std::min; | 22 using std::min; |
22 | 23 |
23 namespace wm { | 24 namespace wm { |
| 25 namespace { |
| 26 |
| 27 // Sets the scaling for the transform applied to a layer. The left, top, |
| 28 // right and bottom layers are stretched to the height or width of the |
| 29 // center image. |
| 30 |
| 31 void ScaleWidth(gfx::Size center, ui::Layer* layer, gfx::Transform& transform) { |
| 32 float layer_width = layer->bounds().width() * layer->device_scale_factor(); |
| 33 float scale = static_cast<float>(center.width()) / layer_width; |
| 34 transform.Scale(scale, 1.0); |
| 35 } |
| 36 |
| 37 void ScaleHeight(gfx::Size center, |
| 38 ui::Layer* layer, |
| 39 gfx::Transform& transform) { |
| 40 float layer_height = layer->bounds().height() * layer->device_scale_factor(); |
| 41 float scale = static_cast<float>(center.height()) / layer_height; |
| 42 transform.Scale(1.0, scale); |
| 43 } |
| 44 |
| 45 // Returns the dimensions of |image| if non-NULL or gfx::Size(0, 0) otherwise. |
| 46 gfx::Size GetImageSize(const gfx::Image* image) { |
| 47 return image ? gfx::Size(image->ToImageSkia()->width(), |
| 48 image->ToImageSkia()->height()) |
| 49 : gfx::Size(); |
| 50 } |
| 51 |
| 52 // Returns true if |layer|'s bounds don't fit within |size|. |
| 53 bool LayerExceedsSize(const ui::Layer* layer, const gfx::Size& size) { |
| 54 return layer->bounds().width() > size.width() || |
| 55 layer->bounds().height() > size.height(); |
| 56 } |
| 57 |
| 58 } // namespace |
24 | 59 |
25 gfx::RectF ImageGrid::TestAPI::GetTransformedLayerBounds( | 60 gfx::RectF ImageGrid::TestAPI::GetTransformedLayerBounds( |
26 const ui::Layer& layer) { | 61 const ui::Layer& layer) { |
27 gfx::RectF bounds = layer.bounds(); | 62 gfx::RectF bounds = layer.bounds(); |
28 layer.transform().TransformRect(&bounds); | 63 layer.transform().TransformRect(&bounds); |
29 return bounds; | 64 return bounds; |
30 } | 65 } |
31 | 66 |
32 ImageGrid::ImageGrid() | 67 ImageGrid::ImageGrid() |
33 : layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)), | 68 : layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)), |
(...skipping 12 matching lines...) Expand all Loading... |
46 | 81 |
47 void ImageGrid::SetImages(const gfx::Image* top_left_image, | 82 void ImageGrid::SetImages(const gfx::Image* top_left_image, |
48 const gfx::Image* top_image, | 83 const gfx::Image* top_image, |
49 const gfx::Image* top_right_image, | 84 const gfx::Image* top_right_image, |
50 const gfx::Image* left_image, | 85 const gfx::Image* left_image, |
51 const gfx::Image* center_image, | 86 const gfx::Image* center_image, |
52 const gfx::Image* right_image, | 87 const gfx::Image* right_image, |
53 const gfx::Image* bottom_left_image, | 88 const gfx::Image* bottom_left_image, |
54 const gfx::Image* bottom_image, | 89 const gfx::Image* bottom_image, |
55 const gfx::Image* bottom_right_image) { | 90 const gfx::Image* bottom_right_image) { |
56 SetImage(top_left_image, &top_left_layer_, &top_left_painter_); | 91 SetImage(top_left_image, &top_left_layer_, &top_left_painter_, NONE); |
57 SetImage(top_image, &top_layer_, &top_painter_); | 92 SetImage(top_image, &top_layer_, &top_painter_, HORIZONTAL); |
58 SetImage(top_right_image, &top_right_layer_, &top_right_painter_); | 93 SetImage(top_right_image, &top_right_layer_, &top_right_painter_, NONE); |
59 SetImage(left_image, &left_layer_, &left_painter_); | 94 SetImage(left_image, &left_layer_, &left_painter_, VERTICAL); |
60 SetImage(center_image, ¢er_layer_, ¢er_painter_); | 95 SetImage(center_image, ¢er_layer_, ¢er_painter_, NONE); |
61 SetImage(right_image, &right_layer_, &right_painter_); | 96 SetImage(right_image, &right_layer_, &right_painter_, VERTICAL); |
62 SetImage(bottom_left_image, &bottom_left_layer_, &bottom_left_painter_); | 97 SetImage(bottom_left_image, &bottom_left_layer_, &bottom_left_painter_, NONE); |
63 SetImage(bottom_image, &bottom_layer_, &bottom_painter_); | 98 SetImage(bottom_image, &bottom_layer_, &bottom_painter_, HORIZONTAL); |
64 SetImage(bottom_right_image, &bottom_right_layer_, &bottom_right_painter_); | 99 SetImage( |
| 100 bottom_right_image, &bottom_right_layer_, &bottom_right_painter_, NONE); |
65 | 101 |
66 top_image_height_ = GetImageSize(top_image).height(); | 102 top_image_height_ = GetImageSize(top_image).height(); |
67 bottom_image_height_ = GetImageSize(bottom_image).height(); | 103 bottom_image_height_ = GetImageSize(bottom_image).height(); |
68 left_image_width_ = GetImageSize(left_image).width(); | 104 left_image_width_ = GetImageSize(left_image).width(); |
69 right_image_width_ = GetImageSize(right_image).width(); | 105 right_image_width_ = GetImageSize(right_image).width(); |
70 | 106 |
71 base_top_row_height_ = max(GetImageSize(top_left_image).height(), | 107 base_top_row_height_ = max(GetImageSize(top_left_image).height(), |
72 max(GetImageSize(top_image).height(), | 108 max(GetImageSize(top_image).height(), |
73 GetImageSize(top_right_image).height())); | 109 GetImageSize(top_right_image).height())); |
74 base_bottom_row_height_ = max(GetImageSize(bottom_left_image).height(), | 110 base_bottom_row_height_ = max(GetImageSize(bottom_left_image).height(), |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 ui::Layer* layer) { | 262 ui::Layer* layer) { |
227 if (clip_rect != clip_rect_) { | 263 if (clip_rect != clip_rect_) { |
228 clip_rect_ = clip_rect; | 264 clip_rect_ = clip_rect; |
229 layer->SchedulePaint(layer->bounds()); | 265 layer->SchedulePaint(layer->bounds()); |
230 } | 266 } |
231 } | 267 } |
232 | 268 |
233 void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) { | 269 void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) { |
234 if (!clip_rect_.IsEmpty()) | 270 if (!clip_rect_.IsEmpty()) |
235 canvas->ClipRect(clip_rect_); | 271 canvas->ClipRect(clip_rect_); |
236 canvas->DrawImageInt(*(image_->ToImageSkia()), 0, 0); | 272 canvas->DrawImageInt(image_, 0, 0); |
237 } | 273 } |
238 | 274 |
239 void ImageGrid::ImagePainter::OnDeviceScaleFactorChanged( | 275 void ImageGrid::ImagePainter::OnDeviceScaleFactorChanged( |
240 float device_scale_factor) { | 276 float device_scale_factor) { |
241 // Redrawing will take care of scale factor change. | 277 // Redrawing will take care of scale factor change. |
242 } | 278 } |
243 | 279 |
244 base::Closure ImageGrid::ImagePainter::PrepareForLayerBoundsChange() { | 280 base::Closure ImageGrid::ImagePainter::PrepareForLayerBoundsChange() { |
245 return base::Closure(); | 281 return base::Closure(); |
246 } | 282 } |
247 | 283 |
248 // static | |
249 gfx::Size ImageGrid::GetImageSize(const gfx::Image* image) { | |
250 return image ? | |
251 gfx::Size(image->ToImageSkia()->width(), image->ToImageSkia()->height()) : | |
252 gfx::Size(); | |
253 } | |
254 | |
255 // static | |
256 bool ImageGrid::LayerExceedsSize(const ui::Layer* layer, | |
257 const gfx::Size& size) { | |
258 return layer->bounds().width() > size.width() || | |
259 layer->bounds().height() > size.height(); | |
260 } | |
261 | |
262 void ImageGrid::SetImage(const gfx::Image* image, | 284 void ImageGrid::SetImage(const gfx::Image* image, |
263 scoped_ptr<ui::Layer>* layer_ptr, | 285 scoped_ptr<ui::Layer>* layer_ptr, |
264 scoped_ptr<ImagePainter>* painter_ptr) { | 286 scoped_ptr<ImagePainter>* painter_ptr, |
| 287 ImageType type) { |
| 288 // Minimum width (for HORIZONTAL) or height (for VERTICAL) of the |
| 289 // |image| so that layers are scaled property if the device scale |
| 290 // factor is non integral. |
| 291 const int kMinimumSize = 20; |
| 292 |
265 // Clean out old layers and painters. | 293 // Clean out old layers and painters. |
266 if (layer_ptr->get()) | 294 if (layer_ptr->get()) |
267 layer_->Remove(layer_ptr->get()); | 295 layer_->Remove(layer_ptr->get()); |
268 layer_ptr->reset(); | 296 layer_ptr->reset(); |
269 painter_ptr->reset(); | 297 painter_ptr->reset(); |
270 | 298 |
271 // If we're not using an image, we're done. | 299 // If we're not using an image, we're done. |
272 if (!image) | 300 if (!image) |
273 return; | 301 return; |
274 | 302 |
| 303 gfx::ImageSkia image_skia = image->AsImageSkia(); |
| 304 switch (type) { |
| 305 case HORIZONTAL: |
| 306 if (image_skia.width() < kMinimumSize) { |
| 307 image_skia = gfx::ImageSkiaOperations::CreateResizedImage( |
| 308 image_skia, |
| 309 skia::ImageOperations::RESIZE_GOOD, |
| 310 gfx::Size(kMinimumSize, image_skia.height())); |
| 311 } |
| 312 break; |
| 313 case VERTICAL: |
| 314 if (image_skia.height() < kMinimumSize) { |
| 315 image_skia = gfx::ImageSkiaOperations::CreateResizedImage( |
| 316 image_skia, |
| 317 skia::ImageOperations::RESIZE_GOOD, |
| 318 gfx::Size(image_skia.width(), kMinimumSize)); |
| 319 } |
| 320 break; |
| 321 case NONE: |
| 322 break; |
| 323 } |
| 324 |
275 // Set up the new layer and painter. | 325 // Set up the new layer and painter. |
276 layer_ptr->reset(new ui::Layer(ui::LAYER_TEXTURED)); | 326 layer_ptr->reset(new ui::Layer(ui::LAYER_TEXTURED)); |
277 | 327 |
278 const gfx::Size size = GetImageSize(image); | 328 const gfx::Size size = image_skia.size(); |
279 layer_ptr->get()->SetBounds(gfx::Rect(0, 0, size.width(), size.height())); | 329 layer_ptr->get()->SetBounds(gfx::Rect(0, 0, size.width(), size.height())); |
280 | 330 |
281 painter_ptr->reset(new ImagePainter(image)); | 331 painter_ptr->reset(new ImagePainter(image_skia)); |
282 layer_ptr->get()->set_delegate(painter_ptr->get()); | 332 layer_ptr->get()->set_delegate(painter_ptr->get()); |
283 layer_ptr->get()->SetFillsBoundsOpaquely(false); | 333 layer_ptr->get()->SetFillsBoundsOpaquely(false); |
284 layer_ptr->get()->SetVisible(true); | 334 layer_ptr->get()->SetVisible(true); |
285 layer_->Add(layer_ptr->get()); | 335 layer_->Add(layer_ptr->get()); |
286 } | 336 } |
287 | 337 |
288 void ImageGrid::ScaleWidth(gfx::Size center, | |
289 ui::Layer* layer, | |
290 gfx::Transform& transform) { | |
291 int layer_width = ConvertSizeToPixel(layer, | |
292 layer->bounds().size()).width(); | |
293 float scale = static_cast<float>(center.width()) / layer_width; | |
294 transform.Scale(scale, 1.0); | |
295 } | |
296 | |
297 void ImageGrid::ScaleHeight(gfx::Size center, | |
298 ui::Layer* layer, | |
299 gfx::Transform& transform) { | |
300 int layer_height = ConvertSizeToPixel(layer, | |
301 layer->bounds().size()).height(); | |
302 float scale = static_cast<float>(center.height()) / layer_height; | |
303 transform.Scale(1.0, scale); | |
304 } | |
305 | |
306 } // namespace wm | 338 } // namespace wm |
OLD | NEW |