diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-16 19:41:56 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-16 19:41:56 +0000 |
commit | 871f053a4f6ef28dbf0a8db9572d44b305edea69 (patch) | |
tree | 4206f4fa077eee15d2371229663a445ab5595823 /ui/views/painter.cc | |
parent | 96f503fe17b392b85cdca0212a82f8d3b7bb6845 (diff) | |
download | chromium_src-871f053a4f6ef28dbf0a8db9572d44b305edea69.zip chromium_src-871f053a4f6ef28dbf0a8db9572d44b305edea69.tar.gz chromium_src-871f053a4f6ef28dbf0a8db9572d44b305edea69.tar.bz2 |
Make ImagePainter support image grids where not all the sizes match up. This
will be useful with the upcoming omnibox size change.
Also de-inline various functions and some misc. other cleanup, e.g. adding
DISALLOW_COPY_AND_ASSIGN or fixing spelling errors.
BUG=231005
TEST=none
R=sky@chromium.org
Review URL: https://codereview.chromium.org/14688021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200609 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/painter.cc')
-rw-r--r-- | ui/views/painter.cc | 207 |
1 files changed, 133 insertions, 74 deletions
diff --git a/ui/views/painter.cc b/ui/views/painter.cc index 12d4c44..9f8d220 100644 --- a/ui/views/painter.cc +++ b/ui/views/painter.cc @@ -16,52 +16,26 @@ #include "ui/gfx/point.h" #include "ui/gfx/rect.h" + namespace views { namespace { +// GradientPainter ------------------------------------------------------------ + class GradientPainter : public Painter { public: GradientPainter(bool horizontal, SkColor* colors, SkScalar* pos, - size_t count) - : horizontal_(horizontal), - count_(count) { - pos_.reset(new SkScalar[count_]); - colors_.reset(new SkColor[count_]); - - for (size_t i = 0; i < count_; ++i) { - pos_[i] = pos[i]; - colors_[i] = colors[i]; - } - } + size_t count); + virtual ~GradientPainter(); - virtual ~GradientPainter() {} - - // Overridden from Painter: - virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE { - SkPaint paint; - SkPoint p[2]; - p[0].iset(0, 0); - if (horizontal_) - p[1].iset(size.width(), 0); - else - p[1].iset(0, size.height()); - - skia::RefPtr<SkShader> s = skia::AdoptRef(SkGradientShader::CreateLinear( - p, colors_.get(), pos_.get(), count_, SkShader::kClamp_TileMode, NULL)); - paint.setStyle(SkPaint::kFill_Style); - paint.setShader(s.get()); - // Need to unref shader, otherwise never deleted. - - canvas->sk_canvas()->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0), - SkIntToScalar(size.width()), - SkIntToScalar(size.height()), paint); - } + // Painter: + virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE; private: - // If |horizontal_| is true then the gradiant is painted horizontally. + // If |horizontal_| is true then the gradient is painted horizontally. bool horizontal_; // The gradient colors. scoped_ptr<SkColor[]> colors_; @@ -73,18 +47,53 @@ class GradientPainter : public Painter { DISALLOW_COPY_AND_ASSIGN(GradientPainter); }; -// A helper fuction to stretch the given image over the specified canvas area. -void Fill(gfx::Canvas* c, const gfx::ImageSkia& i, int x, int y, int w, int h) { - c->DrawImageInt(i, 0, 0, i.width(), i.height(), x, y, w, h, false); +GradientPainter::GradientPainter(bool horizontal, + SkColor* colors, + SkScalar* pos, + size_t count) + : horizontal_(horizontal), + colors_(new SkColor[count]), + pos_(new SkScalar[count]), + count_(count) { + for (size_t i = 0; i < count_; ++i) { + pos_[i] = pos[i]; + colors_[i] = colors[i]; + } } +GradientPainter::~GradientPainter() { +} + +void GradientPainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) { + SkPaint paint; + SkPoint p[2]; + p[0].iset(0, 0); + if (horizontal_) + p[1].iset(size.width(), 0); + else + p[1].iset(0, size.height()); + + skia::RefPtr<SkShader> s = skia::AdoptRef(SkGradientShader::CreateLinear( + p, colors_.get(), pos_.get(), count_, SkShader::kClamp_TileMode, NULL)); + paint.setStyle(SkPaint::kFill_Style); + paint.setShader(s.get()); + + canvas->sk_canvas()->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0), + SkIntToScalar(size.width()), + SkIntToScalar(size.height()), paint); +} + + +// ImagePainter --------------------------------------------------------------- + // ImagePainter stores and paints nine images as a scalable grid. class VIEWS_EXPORT ImagePainter : public Painter { public: - // Construct an ImagePainter with the specified image resource ids. + // Constructs an ImagePainter with the specified image resource ids. // See CreateImageGridPainter()'s comment regarding image ID count and order. explicit ImagePainter(const int image_ids[]); - // Construct an ImagePainter with the specified image and insets. + + // Constructs an ImagePainter with the specified image and insets. ImagePainter(const gfx::ImageSkia& image, const gfx::Insets& insets); virtual ~ImagePainter(); @@ -92,17 +101,23 @@ class VIEWS_EXPORT ImagePainter : public Painter { // Returns true if the images are empty. bool IsEmpty() const; - // Overridden from Painter: + // Painter: virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE; private: - // Images must share widths by column and heights by row as depicted below. - // Coordinates along the X and Y axes are used for construction and painting. - // x0 x1 x2 x3 - // y0__|______|______|______| - // y1__|__i0__|__i1__|__i2__| - // y2__|__i3__|__i4__|__i5__| - // y3__|__i6__|__i7__|__i8__| + // Stretches the given image over the specified canvas area. + static void Fill(gfx::Canvas* c, + const gfx::ImageSkia& i, + int x, + int y, + int w, + int h); + + // Images are numbered as depicted below. + // ____________________ + // |__i0__|__i1__|__i2__| + // |__i3__|__i4__|__i5__| + // |__i6__|__i7__|__i8__| gfx::ImageSkia images_[9]; DISALLOW_COPY_AND_ASSIGN(ImagePainter); @@ -145,27 +160,61 @@ void ImagePainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) { if (IsEmpty()) return; - // Paint image subsets in accordance with the |images_| format. - const gfx::Rect rect(size); - const int x[] = { rect.x(), rect.x() + images_[0].width(), - rect.right() - images_[2].width(), rect.right() }; - const int y[] = { rect.y(), rect.y() + images_[0].height(), - rect.bottom() - images_[6].height(), rect.bottom() }; - - canvas->DrawImageInt(images_[0], x[0], y[0]); - Fill(canvas, images_[1], x[1], y[0], x[2] - x[1], y[1] - y[0]); - canvas->DrawImageInt(images_[2], x[2], y[0]); - Fill(canvas, images_[3], x[0], y[1], x[1] - x[0], y[2] - y[1]); + // In case the corners and edges don't all have the same width/height, we draw + // the center first, and extend it out in all directions to the edges of the + // images with the smallest widths/heights. This way there will be no + // unpainted areas, though some corners or edges might overlap the center. + int w = size.width(); + int i0w = images_[0].width(); + int i2w = images_[2].width(); + int i3w = images_[3].width(); + int i5w = images_[5].width(); + int i6w = images_[6].width(); + int i8w = images_[8].width(); + int i4x = std::min(std::min(i0w, i3w), i6w); + int i4w = w - i4x - std::min(std::min(i2w, i5w), i8w); + int h = size.height(); + int i0h = images_[0].height(); + int i1h = images_[1].height(); + int i2h = images_[2].height(); + int i6h = images_[6].height(); + int i7h = images_[7].height(); + int i8h = images_[8].height(); + int i4y = std::min(std::min(i0h, i1h), i2h); + int i4h = h - i4y - std::min(std::min(i6h, i7h), i8h); if (!images_[4].isNull()) - Fill(canvas, images_[4], x[1], y[1], x[2] - x[1], y[2] - y[1]); - Fill(canvas, images_[5], x[2], y[1], x[3] - x[2], y[2] - y[1]); - canvas->DrawImageInt(images_[6], 0, y[2]); - Fill(canvas, images_[7], x[1], y[2], x[2] - x[1], y[3] - y[2]); - canvas->DrawImageInt(images_[8], x[2], y[2]); + Fill(canvas, images_[4], i4x, i4y, i4w, i4h); + canvas->DrawImageInt(images_[0], 0, 0); + Fill(canvas, images_[1], i0w, 0, w - i0w - i2w, i1h); + canvas->DrawImageInt(images_[2], w - i2w, 0); + Fill(canvas, images_[3], 0, i0h, i3w, h - i0h - i6h); + Fill(canvas, images_[5], w - i5w, i2h, i5w, h - i2h - i8h); + canvas->DrawImageInt(images_[6], 0, h - i6h); + Fill(canvas, images_[7], i6w, h - i7h, w - i6w - i8w, i7h); + canvas->DrawImageInt(images_[8], w - i8w, h - i8h); +} + +// static +void ImagePainter::Fill(gfx::Canvas* c, + const gfx::ImageSkia& i, + int x, + int y, + int w, + int h) { + c->DrawImageInt(i, 0, 0, i.width(), i.height(), x, y, w, h, false); } } // namespace + +// Painter -------------------------------------------------------------------- + +Painter::Painter() { +} + +Painter::~Painter() { +} + // static void Painter::PaintPainterAt(gfx::Canvas* canvas, Painter* painter, @@ -213,26 +262,36 @@ Painter* Painter::CreateImageGridPainter(const int image_ids[]) { return new ImagePainter(image_ids); } + +// HorizontalPainter ---------------------------------------------------------- + HorizontalPainter::HorizontalPainter(const int image_resource_names[]) { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); for (int i = 0; i < 3; ++i) images_[i] = rb.GetImageNamed(image_resource_names[i]).ToImageSkia(); - height_ = images_[LEFT]->height(); - DCHECK(images_[LEFT]->height() == images_[RIGHT]->height() && - images_[LEFT]->height() == images_[CENTER]->height()); + DCHECK_EQ(images_[LEFT]->height(), images_[CENTER]->height()); + DCHECK_EQ(images_[LEFT]->height(), images_[RIGHT]->height()); +} + +HorizontalPainter::~HorizontalPainter() { } void HorizontalPainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) { if (size.width() < (images_[LEFT]->width() + images_[CENTER]->width() + - images_[RIGHT]->width())) { - // No room to paint. - return; - } + images_[RIGHT]->width())) + return; // No room to paint. + canvas->DrawImageInt(*images_[LEFT], 0, 0); - canvas->DrawImageInt(*images_[RIGHT], - size.width() - images_[RIGHT]->width(), 0); - canvas->TileImageInt(*images_[CENTER], images_[LEFT]->width(), 0, - size.width() - images_[LEFT]->width() - images_[RIGHT]->width(), height_); + canvas->DrawImageInt(*images_[RIGHT], size.width() - images_[RIGHT]->width(), + 0); + canvas->TileImageInt( + *images_[CENTER], images_[LEFT]->width(), 0, + size.width() - images_[LEFT]->width() - images_[RIGHT]->width(), + images_[LEFT]->height()); +} + +int HorizontalPainter::height() const { + return images_[LEFT]->height(); } } // namespace views |