Commit cb7a6399 authored by oshima@chromium.org's avatar oshima@chromium.org

Support high dpi in menu scroll arrow, submenu arrow and drag_utils.

Created CanvasImageSource utility class to simplify the image creating using canvas.

BUG=122992
TEST=manual

Review URL: https://chromiumcodereview.appspot.com/10702136

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146290 0039d316-1c4b-4281-b951-d872f2087c98
parent 452b36f6
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gfx/image/canvas_image_source.h"
#include "base/logging.h"
#include "ui/gfx/canvas.h"
#include "ui/base/layout.h"
namespace gfx {
////////////////////////////////////////////////////////////////////////////////
// CanvasImageSource
CanvasImageSource::CanvasImageSource(const gfx::Size& size, bool is_opaque)
: size_(size),
is_opaque_(is_opaque) {
}
gfx::ImageSkiaRep CanvasImageSource::GetImageForScale(
ui::ScaleFactor scale_factor) {
gfx::Canvas canvas(size_, scale_factor, is_opaque_);
Draw(&canvas);
return canvas.ExtractImageSkiaRep();
}
} // namespace gfx
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_GFX_IMAGE_CANVAS_IMAGE_SOURCE_H_
#define UI_GFX_IMAGE_CANVAS_IMAGE_SOURCE_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "ui/base/ui_export.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/size.h"
namespace gfx {
class Canvas;
class ImageSkiaRep;
// CanvasImageSource is useful if you need to generate an image for
// a scale factor using gfx::Canvas. It creates a new Canvas
// with target scale factor and generates ImageSkiaRep when drawing is
// completed.
class UI_EXPORT CanvasImageSource : public gfx::ImageSkiaSource {
public:
CanvasImageSource(const gfx::Size& size, bool is_opaque);
// Called when a new image needs to be drawn for a scale factor.
virtual void Draw(gfx::Canvas* canvas) = 0;
// Returns the size of images in DIP that this source will generate.
const gfx::Size& size() const { return size_; };
// Overridden from gfx::ImageSkiaSource.
virtual gfx::ImageSkiaRep GetImageForScale(
ui::ScaleFactor scale_factor) OVERRIDE;
protected:
virtual ~CanvasImageSource() {}
const gfx::Size size_;
const bool is_opaque_;
DISALLOW_COPY_AND_ASSIGN(CanvasImageSource);
};
} // namespace gfx
#endif // UI_GFX_IMAGE_CANVAS_IMAGE_SOURCE_H_
...@@ -6,12 +6,13 @@ ...@@ -6,12 +6,13 @@
#define UI_GFX_IMAGE_IMAGE_SKIA_SOURCE_H_ #define UI_GFX_IMAGE_IMAGE_SKIA_SOURCE_H_
#include "ui/base/layout.h" #include "ui/base/layout.h"
#include "ui/base/ui_export.h"
namespace gfx { namespace gfx {
class ImageSkiaRep; class ImageSkiaRep;
class ImageSkiaSource { class UI_EXPORT ImageSkiaSource {
public: public:
virtual ~ImageSkiaSource() {} virtual ~ImageSkiaSource() {}
......
...@@ -346,6 +346,8 @@ ...@@ -346,6 +346,8 @@
'gfx/font_smoothing_win.h', 'gfx/font_smoothing_win.h',
'gfx/gfx_paths.cc', 'gfx/gfx_paths.cc',
'gfx/gfx_paths.h', 'gfx/gfx_paths.h',
'gfx/image/canvas_image_source.cc',
'gfx/image/canvas_image_source.h',
'gfx/image/image.cc', 'gfx/image/image.cc',
'gfx/image/image.h', 'gfx/image/image.h',
'gfx/image/image_skia.cc', 'gfx/image/image_skia.cc',
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "third_party/skia/include/effects/SkGradientShader.h" #include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_source.h" #include "ui/gfx/image/image_skia_source.h"
...@@ -32,20 +33,17 @@ const SkColor kRadioButtonIndicatorGradient0 = SkColorSetRGB(0, 0, 0); ...@@ -32,20 +33,17 @@ const SkColor kRadioButtonIndicatorGradient0 = SkColorSetRGB(0, 0, 0);
const SkColor kRadioButtonIndicatorGradient1 = SkColorSetRGB(0x83, 0x83, 0x83); const SkColor kRadioButtonIndicatorGradient1 = SkColorSetRGB(0x83, 0x83, 0x83);
const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0); const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0);
class RadioButtonImageSource : public gfx::ImageSkiaSource { class RadioButtonImageSource : public gfx::CanvasImageSource {
public: public:
explicit RadioButtonImageSource(bool selected) : selected_(selected) { explicit RadioButtonImageSource(bool selected)
: CanvasImageSource(gfx::Size(kIndicatorSize + 2, kIndicatorSize + 2),
false),
selected_(selected) {
} }
virtual ~RadioButtonImageSource() {} virtual ~RadioButtonImageSource() {}
virtual gfx::ImageSkiaRep GetImageForScale( virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
ui::ScaleFactor scale_factor) OVERRIDE { canvas->Translate(gfx::Point(1, 1));
float scale = GetScaleFactorScale(scale_factor);
// + 2 (1px on each side) to cover rounding error.
gfx::Size size(kIndicatorSize + 2, kIndicatorSize + 2);
gfx::Canvas canvas(size.Scale(scale), false);
canvas.Scale(scale, scale);
canvas.Translate(gfx::Point(1, 1));
SkPoint gradient_points[3]; SkPoint gradient_points[3];
gradient_points[0].iset(0, 0); gradient_points[0].iset(0, 0);
...@@ -62,12 +60,12 @@ class RadioButtonImageSource : public gfx::ImageSkiaSource { ...@@ -62,12 +60,12 @@ class RadioButtonImageSource : public gfx::ImageSkiaSource {
paint.setShader(shader); paint.setShader(shader);
shader->unref(); shader->unref();
int radius = kIndicatorSize / 2; int radius = kIndicatorSize / 2;
canvas.sk_canvas()->drawCircle(radius, radius, radius, paint); canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);
paint.setStrokeWidth(SkIntToScalar(0)); paint.setStrokeWidth(SkIntToScalar(0));
paint.setShader(NULL); paint.setShader(NULL);
paint.setStyle(SkPaint::kStroke_Style); paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(kBaseStroke); paint.setColor(kBaseStroke);
canvas.sk_canvas()->drawCircle(radius, radius, radius, paint); canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);
if (selected_) { if (selected_) {
SkPoint selected_gradient_points[2]; SkPoint selected_gradient_points[2];
...@@ -81,18 +79,16 @@ class RadioButtonImageSource : public gfx::ImageSkiaSource { ...@@ -81,18 +79,16 @@ class RadioButtonImageSource : public gfx::ImageSkiaSource {
paint.setShader(shader); paint.setShader(shader);
shader->unref(); shader->unref();
paint.setStyle(SkPaint::kFill_Style); paint.setStyle(SkPaint::kFill_Style);
canvas.sk_canvas()->drawCircle(radius, radius, canvas->sk_canvas()->drawCircle(radius, radius,
kSelectedIndicatorSize / 2, paint); kSelectedIndicatorSize / 2, paint);
paint.setStrokeWidth(SkIntToScalar(0)); paint.setStrokeWidth(SkIntToScalar(0));
paint.setShader(NULL); paint.setShader(NULL);
paint.setStyle(SkPaint::kStroke_Style); paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(kIndicatorStroke); paint.setColor(kIndicatorStroke);
canvas.sk_canvas()->drawCircle(radius, radius, canvas->sk_canvas()->drawCircle(radius, radius,
kSelectedIndicatorSize / 2, paint); kSelectedIndicatorSize / 2, paint);
} }
LOG(ERROR) << "Generating:" << selected_;
return gfx::ImageSkiaRep(canvas.ExtractBitmap(), scale_factor);
} }
private: private:
...@@ -102,19 +98,38 @@ class RadioButtonImageSource : public gfx::ImageSkiaSource { ...@@ -102,19 +98,38 @@ class RadioButtonImageSource : public gfx::ImageSkiaSource {
}; };
gfx::ImageSkia* CreateRadioButtonImage(bool selected) { gfx::ImageSkia* CreateRadioButtonImage(bool selected) {
return new gfx::ImageSkia(new RadioButtonImageSource(selected), RadioButtonImageSource* source = new RadioButtonImageSource(selected);
gfx::Size(kIndicatorSize + 2, kIndicatorSize + 2)); return new gfx::ImageSkia(source, source->size());
} }
class SubmenuArrowImageSource : public gfx::CanvasImageSource {
public:
SubmenuArrowImageSource()
: gfx::CanvasImageSource(GetSubmenuArrowSize(), false) {
}
virtual ~SubmenuArrowImageSource() {}
virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
const gfx::ImageSkia* r = rb.GetImageNamed(IDR_MENU_ARROW).ToImageSkia();
canvas->Scale(-1, 1);
canvas->DrawImageInt(*r, - r->width(), 0);
}
private:
static gfx::Size GetSubmenuArrowSize() {
return ui::ResourceBundle::GetSharedInstance()
.GetImageNamed(IDR_MENU_ARROW).ToImageSkia()->size();
}
DISALLOW_COPY_AND_ASSIGN(SubmenuArrowImageSource);
};
gfx::ImageSkia* GetRtlSubmenuArrowImage() { gfx::ImageSkia* GetRtlSubmenuArrowImage() {
static gfx::ImageSkia* kRtlArrow = NULL; static gfx::ImageSkia* kRtlArrow = NULL;
if (!kRtlArrow) { if (!kRtlArrow) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); SubmenuArrowImageSource* source = new SubmenuArrowImageSource();
const gfx::ImageSkia* r = rb.GetImageNamed(IDR_MENU_ARROW).ToImageSkia(); kRtlArrow = new gfx::ImageSkia(source, source->size());
gfx::Canvas canvas(gfx::Size(r->width(), r->height()), false);
canvas.Scale(-1, 1);
canvas.DrawImageInt(*r, - r->width(), 0);
kRtlArrow = new gfx::ImageSkia(canvas.ExtractBitmap());
} }
return kRtlArrow; return kRtlArrow;
} }
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <Vssym32.h> #include <Vssym32.h>
#endif #endif
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/native_theme/native_theme.h" #include "ui/base/native_theme/native_theme.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
...@@ -93,13 +95,28 @@ class MenuScrollButton : public View { ...@@ -93,13 +95,28 @@ class MenuScrollButton : public View {
// Then the arrow. // Then the arrow.
int x = width() / 2; int x = width() / 2;
int y = (height() - config.scroll_arrow_height) / 2; int y = (height() - config.scroll_arrow_height) / 2;
int delta_y = 1;
int x_left = x - config.scroll_arrow_height;
int x_right = x + config.scroll_arrow_height;
int y_bottom;
if (!is_up_) { if (!is_up_) {
delta_y = -1; y_bottom = y;
y += config.scroll_arrow_height; y = y_bottom + config.scroll_arrow_height;
} else {
y_bottom = y + config.scroll_arrow_height;
} }
for (int i = 0; i < config.scroll_arrow_height; ++i, --x, y += delta_y) SkPath path;
canvas->FillRect(gfx::Rect(x, y, (i * 2) + 1, 1), arrow_color); path.setFillType(SkPath::kWinding_FillType);
path.moveTo(SkIntToScalar(x), SkIntToScalar(y));
path.lineTo(SkIntToScalar(x_left), SkIntToScalar(y_bottom));
path.lineTo(SkIntToScalar(x_right), SkIntToScalar(y_bottom));
path.lineTo(SkIntToScalar(x), SkIntToScalar(y));
SkPaint paint;
paint.setStyle(SkPaint::kFill_Style);
paint.setAntiAlias(true);
paint.setColor(arrow_color);
canvas->DrawPath(path, paint);
} }
private: private:
......
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