Commit 13a16eb5 authored by oshima@chromium.org's avatar oshima@chromium.org

Ensure min size for images used in ImageGrid

A workaround until ImageGrid switches to cc::NinePatchLayer.

BUG=376519

Review URL: https://codereview.chromium.org/302513002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273046 0039d316-1c4b-4281-b951-d872f2087c98
parent 968644f4
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ui/compositor/dip_util.h" #include "ui/compositor/dip_util.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "ui/gfx/rect_conversions.h" #include "ui/gfx/rect_conversions.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
...@@ -21,6 +22,40 @@ using std::max; ...@@ -21,6 +22,40 @@ using std::max;
using std::min; using std::min;
namespace wm { namespace wm {
namespace {
// Sets the scaling for the transform applied to a layer. The left, top,
// right and bottom layers are stretched to the height or width of the
// center image.
void ScaleWidth(gfx::Size center, ui::Layer* layer, gfx::Transform& transform) {
float layer_width = layer->bounds().width() * layer->device_scale_factor();
float scale = static_cast<float>(center.width()) / layer_width;
transform.Scale(scale, 1.0);
}
void ScaleHeight(gfx::Size center,
ui::Layer* layer,
gfx::Transform& transform) {
float layer_height = layer->bounds().height() * layer->device_scale_factor();
float scale = static_cast<float>(center.height()) / layer_height;
transform.Scale(1.0, scale);
}
// Returns the dimensions of |image| if non-NULL or gfx::Size(0, 0) otherwise.
gfx::Size GetImageSize(const gfx::Image* image) {
return image ? gfx::Size(image->ToImageSkia()->width(),
image->ToImageSkia()->height())
: gfx::Size();
}
// Returns true if |layer|'s bounds don't fit within |size|.
bool LayerExceedsSize(const ui::Layer* layer, const gfx::Size& size) {
return layer->bounds().width() > size.width() ||
layer->bounds().height() > size.height();
}
} // namespace
gfx::RectF ImageGrid::TestAPI::GetTransformedLayerBounds( gfx::RectF ImageGrid::TestAPI::GetTransformedLayerBounds(
const ui::Layer& layer) { const ui::Layer& layer) {
...@@ -53,15 +88,16 @@ void ImageGrid::SetImages(const gfx::Image* top_left_image, ...@@ -53,15 +88,16 @@ void ImageGrid::SetImages(const gfx::Image* top_left_image,
const gfx::Image* bottom_left_image, const gfx::Image* bottom_left_image,
const gfx::Image* bottom_image, const gfx::Image* bottom_image,
const gfx::Image* bottom_right_image) { const gfx::Image* bottom_right_image) {
SetImage(top_left_image, &top_left_layer_, &top_left_painter_); SetImage(top_left_image, &top_left_layer_, &top_left_painter_, NONE);
SetImage(top_image, &top_layer_, &top_painter_); SetImage(top_image, &top_layer_, &top_painter_, HORIZONTAL);
SetImage(top_right_image, &top_right_layer_, &top_right_painter_); SetImage(top_right_image, &top_right_layer_, &top_right_painter_, NONE);
SetImage(left_image, &left_layer_, &left_painter_); SetImage(left_image, &left_layer_, &left_painter_, VERTICAL);
SetImage(center_image, &center_layer_, &center_painter_); SetImage(center_image, &center_layer_, &center_painter_, NONE);
SetImage(right_image, &right_layer_, &right_painter_); SetImage(right_image, &right_layer_, &right_painter_, VERTICAL);
SetImage(bottom_left_image, &bottom_left_layer_, &bottom_left_painter_); SetImage(bottom_left_image, &bottom_left_layer_, &bottom_left_painter_, NONE);
SetImage(bottom_image, &bottom_layer_, &bottom_painter_); SetImage(bottom_image, &bottom_layer_, &bottom_painter_, HORIZONTAL);
SetImage(bottom_right_image, &bottom_right_layer_, &bottom_right_painter_); SetImage(
bottom_right_image, &bottom_right_layer_, &bottom_right_painter_, NONE);
top_image_height_ = GetImageSize(top_image).height(); top_image_height_ = GetImageSize(top_image).height();
bottom_image_height_ = GetImageSize(bottom_image).height(); bottom_image_height_ = GetImageSize(bottom_image).height();
...@@ -233,7 +269,7 @@ void ImageGrid::ImagePainter::SetClipRect(const gfx::Rect& clip_rect, ...@@ -233,7 +269,7 @@ void ImageGrid::ImagePainter::SetClipRect(const gfx::Rect& clip_rect,
void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) { void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) {
if (!clip_rect_.IsEmpty()) if (!clip_rect_.IsEmpty())
canvas->ClipRect(clip_rect_); canvas->ClipRect(clip_rect_);
canvas->DrawImageInt(*(image_->ToImageSkia()), 0, 0); canvas->DrawImageInt(image_, 0, 0);
} }
void ImageGrid::ImagePainter::OnDeviceScaleFactorChanged( void ImageGrid::ImagePainter::OnDeviceScaleFactorChanged(
...@@ -245,23 +281,15 @@ base::Closure ImageGrid::ImagePainter::PrepareForLayerBoundsChange() { ...@@ -245,23 +281,15 @@ base::Closure ImageGrid::ImagePainter::PrepareForLayerBoundsChange() {
return base::Closure(); return base::Closure();
} }
// static
gfx::Size ImageGrid::GetImageSize(const gfx::Image* image) {
return image ?
gfx::Size(image->ToImageSkia()->width(), image->ToImageSkia()->height()) :
gfx::Size();
}
// static
bool ImageGrid::LayerExceedsSize(const ui::Layer* layer,
const gfx::Size& size) {
return layer->bounds().width() > size.width() ||
layer->bounds().height() > size.height();
}
void ImageGrid::SetImage(const gfx::Image* image, void ImageGrid::SetImage(const gfx::Image* image,
scoped_ptr<ui::Layer>* layer_ptr, scoped_ptr<ui::Layer>* layer_ptr,
scoped_ptr<ImagePainter>* painter_ptr) { scoped_ptr<ImagePainter>* painter_ptr,
ImageType type) {
// Minimum width (for HORIZONTAL) or height (for VERTICAL) of the
// |image| so that layers are scaled property if the device scale
// factor is non integral.
const int kMinimumSize = 20;
// Clean out old layers and painters. // Clean out old layers and painters.
if (layer_ptr->get()) if (layer_ptr->get())
layer_->Remove(layer_ptr->get()); layer_->Remove(layer_ptr->get());
...@@ -272,35 +300,39 @@ void ImageGrid::SetImage(const gfx::Image* image, ...@@ -272,35 +300,39 @@ void ImageGrid::SetImage(const gfx::Image* image,
if (!image) if (!image)
return; return;
gfx::ImageSkia image_skia = image->AsImageSkia();
switch (type) {
case HORIZONTAL:
if (image_skia.width() < kMinimumSize) {
image_skia = gfx::ImageSkiaOperations::CreateResizedImage(
image_skia,
skia::ImageOperations::RESIZE_GOOD,
gfx::Size(kMinimumSize, image_skia.height()));
}
break;
case VERTICAL:
if (image_skia.height() < kMinimumSize) {
image_skia = gfx::ImageSkiaOperations::CreateResizedImage(
image_skia,
skia::ImageOperations::RESIZE_GOOD,
gfx::Size(image_skia.width(), kMinimumSize));
}
break;
case NONE:
break;
}
// Set up the new layer and painter. // Set up the new layer and painter.
layer_ptr->reset(new ui::Layer(ui::LAYER_TEXTURED)); layer_ptr->reset(new ui::Layer(ui::LAYER_TEXTURED));
const gfx::Size size = GetImageSize(image); const gfx::Size size = image_skia.size();
layer_ptr->get()->SetBounds(gfx::Rect(0, 0, size.width(), size.height())); layer_ptr->get()->SetBounds(gfx::Rect(0, 0, size.width(), size.height()));
painter_ptr->reset(new ImagePainter(image)); painter_ptr->reset(new ImagePainter(image_skia));
layer_ptr->get()->set_delegate(painter_ptr->get()); layer_ptr->get()->set_delegate(painter_ptr->get());
layer_ptr->get()->SetFillsBoundsOpaquely(false); layer_ptr->get()->SetFillsBoundsOpaquely(false);
layer_ptr->get()->SetVisible(true); layer_ptr->get()->SetVisible(true);
layer_->Add(layer_ptr->get()); layer_->Add(layer_ptr->get());
} }
void ImageGrid::ScaleWidth(gfx::Size center,
ui::Layer* layer,
gfx::Transform& transform) {
int layer_width = ConvertSizeToPixel(layer,
layer->bounds().size()).width();
float scale = static_cast<float>(center.width()) / layer_width;
transform.Scale(scale, 1.0);
}
void ImageGrid::ScaleHeight(gfx::Size center,
ui::Layer* layer,
gfx::Transform& transform) {
int layer_height = ConvertSizeToPixel(layer,
layer->bounds().size()).height();
float scale = static_cast<float>(center.height()) / layer_height;
transform.Scale(1.0, scale);
}
} // namespace wm } // namespace wm
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "ui/compositor/layer.h" #include "ui/compositor/layer.h"
#include "ui/compositor/layer_delegate.h" #include "ui/compositor/layer_delegate.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
#include "ui/wm/wm_export.h" #include "ui/wm/wm_export.h"
...@@ -128,7 +129,7 @@ class WM_EXPORT ImageGrid { ...@@ -128,7 +129,7 @@ class WM_EXPORT ImageGrid {
// Delegate responsible for painting a specific image on a layer. // Delegate responsible for painting a specific image on a layer.
class ImagePainter : public ui::LayerDelegate { class ImagePainter : public ui::LayerDelegate {
public: public:
ImagePainter(const gfx::Image* image) : image_(image) {} ImagePainter(const gfx::ImageSkia& image) : image_(image) {}
virtual ~ImagePainter() {} virtual ~ImagePainter() {}
// Clips |layer| to |clip_rect|. Triggers a repaint if the clipping // Clips |layer| to |clip_rect|. Triggers a repaint if the clipping
...@@ -143,35 +144,29 @@ class WM_EXPORT ImageGrid { ...@@ -143,35 +144,29 @@ class WM_EXPORT ImageGrid {
private: private:
friend class TestAPI; friend class TestAPI;
const gfx::Image* image_; // not owned const gfx::ImageSkia image_;
gfx::Rect clip_rect_; gfx::Rect clip_rect_;
DISALLOW_COPY_AND_ASSIGN(ImagePainter); DISALLOW_COPY_AND_ASSIGN(ImagePainter);
}; };
// Returns the dimensions of |image| if non-NULL or gfx::Size(0, 0) otherwise. enum ImageType {
static gfx::Size GetImageSize(const gfx::Image* image); HORIZONTAL,
VERTICAL,
// Returns true if |layer|'s bounds don't fit within |size|. NONE,
static bool LayerExceedsSize(const ui::Layer* layer, const gfx::Size& size); };
// Sets |layer_ptr| and |painter_ptr| to display |image| and adds the // Sets |layer_ptr| and |painter_ptr| to display |image| and adds the
// passed-in layer to |layer_|. If image is NULL resets |layer_ptr| and // passed-in layer to |layer_|. If image is NULL resets |layer_ptr| and
// |painter_ptr| and removes any existing layer from |layer_|. // |painter_ptr| and removes any existing layer from |layer_|.
// If |type| is either HORIZONTAL or VERTICAL, it may resize the image to
// guarantee that it has minimum size in order for scaling work properly
// with fractional device scale factors. crbug.com/376519.
void SetImage(const gfx::Image* image, void SetImage(const gfx::Image* image,
scoped_ptr<ui::Layer>* layer_ptr, scoped_ptr<ui::Layer>* layer_ptr,
scoped_ptr<ImagePainter>* painter_ptr); scoped_ptr<ImagePainter>* painter_ptr,
ImageType type);
// Sets the scaling for the transform applied to a layer. The left, top,
// right and bottom layers are stretched to the height or width of the
// center image.
void ScaleWidth(gfx::Size center,
ui::Layer* layer,
gfx::Transform& transform);
void ScaleHeight(gfx::Size center,
ui::Layer* layer,
gfx::Transform& transform);
// Layer that contains all of the image layers. // Layer that contains all of the image layers.
scoped_ptr<ui::Layer> layer_; scoped_ptr<ui::Layer> layer_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment