| 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 |