summaryrefslogtreecommitdiffstats
path: root/ui/views/painter.cc
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-16 19:41:56 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-16 19:41:56 +0000
commit871f053a4f6ef28dbf0a8db9572d44b305edea69 (patch)
tree4206f4fa077eee15d2371229663a445ab5595823 /ui/views/painter.cc
parent96f503fe17b392b85cdca0212a82f8d3b7bb6845 (diff)
downloadchromium_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.cc207
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