summaryrefslogtreecommitdiffstats
path: root/gfx
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-29 23:07:21 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-29 23:07:21 +0000
commit80cdb9fef61dc06c379027ad37fe40f45e061792 (patch)
treef11f6db1acae8645b94c279aef9d92e4832d9cd2 /gfx
parentfaa7929a4a690be40fb28598725085fdec8dbc96 (diff)
downloadchromium_src-80cdb9fef61dc06c379027ad37fe40f45e061792.zip
chromium_src-80cdb9fef61dc06c379027ad37fe40f45e061792.tar.gz
chromium_src-80cdb9fef61dc06c379027ad37fe40f45e061792.tar.bz2
Implement more rendering methods on Canvas.
Translation in TileImageInt is still wonky. BUG=none TEST=see unittests Review URL: http://codereview.chromium.org/3014043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54220 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gfx')
-rw-r--r--gfx/DEPS2
-rw-r--r--gfx/canvas.h3
-rw-r--r--gfx/canvas_direct2d.cc118
-rw-r--r--gfx/canvas_direct2d_unittest.cc52
4 files changed, 143 insertions, 32 deletions
diff --git a/gfx/DEPS b/gfx/DEPS
index 38b52d1..548fe15 100644
--- a/gfx/DEPS
+++ b/gfx/DEPS
@@ -1,5 +1,5 @@
include_rules = [
"+base",
- "+skia",
"+grit/gfx_resources.h",
+ "+skia",
]
diff --git a/gfx/canvas.h b/gfx/canvas.h
index 6b59c6d..de06e73 100644
--- a/gfx/canvas.h
+++ b/gfx/canvas.h
@@ -210,6 +210,7 @@ class Canvas {
// |tile_mode| specifies how the gradient brush repeats outside its natural
// bounds.
// Returns an encapsulated platform brush object which the caller must delete.
+ // Returns NULL if the system is unable to create the brush for some reason.
virtual Brush* CreateLinearGradientBrush(
const gfx::Point& start_point,
const gfx::Point& end_point,
@@ -228,6 +229,7 @@ class Canvas {
// |tile_mode| specifies how the gradient brush repeats outside its natural
// bounds.
// Returns an encapsulated platform brush object which the caller must delete.
+ // Returns NULL if the system is unable to create the brush for some reason.
virtual Brush* CreateRadialGradientBrush(
const gfx::Point& center_point,
float radius,
@@ -241,6 +243,7 @@ class Canvas {
// |tile_mode_x,y| - specifies how the brush tiles the areas beyond those
// filled by its bitmap along each axis.
// Returns an encapsulated platform brush object which the caller must delete.
+ // Returns NULL if the system is unable to create the brush for some reason.
virtual Brush* CreateBitmapBrush(
const SkBitmap& bitmap,
TileMode tile_mode_x,
diff --git a/gfx/canvas_direct2d.cc b/gfx/canvas_direct2d.cc
index 406078d..633ea9f 100644
--- a/gfx/canvas_direct2d.cc
+++ b/gfx/canvas_direct2d.cc
@@ -31,6 +31,10 @@ D2D1_POINT_2F PointToPoint2F(const gfx::Point& point) {
static_cast<float>(point.y()));
}
+D2D1_POINT_2F PointToPoint2F(int x, int y) {
+ return D2D1::Point2F(static_cast<float>(x), static_cast<float>(y));
+}
+
D2D1_EXTEND_MODE TileModeToExtendMode(gfx::Canvas::TileMode tile_mode) {
switch (tile_mode) {
case gfx::Canvas::TileMode_Clamp:
@@ -45,6 +49,13 @@ D2D1_EXTEND_MODE TileModeToExtendMode(gfx::Canvas::TileMode tile_mode) {
return D2D1_EXTEND_MODE_CLAMP;
}
+D2D1_BITMAP_INTERPOLATION_MODE FilterToInterpolationMode(bool filter) {
+ return filter ? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
+ : D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
+}
+
+// Creates a Direct2D gradient stop collection for the specified colors and
+// positions. The caller is responsible for releasing this object.
ID2D1GradientStopCollection* CreateGradientStopCollection(
ID2D1RenderTarget* render_target,
const SkColor colors[],
@@ -67,6 +78,46 @@ ID2D1GradientStopCollection* CreateGradientStopCollection(
return SUCCEEDED(hr) ? gradient_stop_collection : NULL;
}
+// Creates a Direct2D bitmap object from the contents of a SkBitmap. The caller
+// is responsible for releasing this object.
+ID2D1Bitmap* CreateD2D1BitmapFromSkBitmap(ID2D1RenderTarget* render_target,
+ const SkBitmap& bitmap) {
+ ID2D1Bitmap* d2d1_bitmap = NULL;
+ HRESULT hr = render_target->CreateBitmap(
+ D2D1::SizeU(bitmap.width(), bitmap.height()),
+ NULL,
+ NULL,
+ D2D1::BitmapProperties(
+ D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
+ D2D1_ALPHA_MODE_IGNORE)),
+ &d2d1_bitmap);
+ if (FAILED(hr))
+ return NULL;
+ bitmap.lockPixels();
+ d2d1_bitmap->CopyFromMemory(NULL, bitmap.getPixels(), bitmap.rowBytes());
+ bitmap.unlockPixels();
+ return d2d1_bitmap;
+}
+
+// Creates a Direct2D bitmap brush from the contents of a SkBitmap. The caller
+// is responsible for releasing this object.
+ID2D1Brush* CreateD2D1BrushFromSkBitmap(ID2D1RenderTarget* render_target,
+ const SkBitmap& bitmap,
+ gfx::Canvas::TileMode tile_mode_x,
+ gfx::Canvas::TileMode tile_mode_y) {
+ ScopedComPtr<ID2D1Bitmap> d2d1_bitmap(
+ CreateD2D1BitmapFromSkBitmap(render_target, bitmap));
+
+ ID2D1BitmapBrush* brush = NULL;
+ render_target->CreateBitmapBrush(
+ d2d1_bitmap,
+ D2D1::BitmapBrushProperties(TileModeToExtendMode(tile_mode_x),
+ TileModeToExtendMode(tile_mode_y)),
+ D2D1::BrushProperties(),
+ &brush);
+ return brush;
+}
+
// A platform wrapper for a Direct2D brush that makes sure the underlying
// ID2D1Brush COM object is released when this object is destroyed.
class Direct2DBrush : public gfx::Brush {
@@ -196,6 +247,7 @@ void CanvasDirect2D::ScaleInt(int x, int y) {
void CanvasDirect2D::FillRectInt(int x, int y, int w, int h,
const SkPaint& paint) {
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::FillRectInt(const SkColor& color, int x, int y, int w,
@@ -213,52 +265,69 @@ void CanvasDirect2D::FillRectInt(const gfx::Brush* brush, int x, int y, int w,
void CanvasDirect2D::DrawRectInt(const SkColor& color, int x, int y, int w,
int h) {
-
+ ScopedComPtr<ID2D1SolidColorBrush> solid_brush;
+ rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive());
+ rt_->DrawRectangle(RectToRectF(x, y, w, h), solid_brush);
}
void CanvasDirect2D::DrawRectInt(const SkColor& color, int x, int y, int w,
int h, SkXfermode::Mode mode) {
-
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::DrawLineInt(const SkColor& color, int x1, int y1, int x2,
int y2) {
-
+ ScopedComPtr<ID2D1SolidColorBrush> solid_brush;
+ rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive());
+ rt_->DrawLine(PointToPoint2F(x1, y1), PointToPoint2F(x2, y2), solid_brush);
}
void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, int x, int y) {
+ ScopedComPtr<ID2D1Bitmap> d2d1_bitmap(
+ CreateD2D1BitmapFromSkBitmap(rt_, bitmap));
+ rt_->DrawBitmap(d2d1_bitmap,
+ RectToRectF(x, y, bitmap.width(), bitmap.height()),
+ 1.0f,
+ D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
+ RectToRectF(0, 0, bitmap.width(), bitmap.height()));
}
void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, int x, int y,
const SkPaint& paint) {
-
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, int src_x, int src_y,
int src_w, int src_h, int dest_x, int dest_y,
int dest_w, int dest_h, bool filter) {
-
+ ScopedComPtr<ID2D1Bitmap> d2d1_bitmap(
+ CreateD2D1BitmapFromSkBitmap(rt_, bitmap));
+ rt_->DrawBitmap(d2d1_bitmap,
+ RectToRectF(dest_x, dest_y, dest_w, dest_h),
+ 1.0f,
+ FilterToInterpolationMode(filter),
+ RectToRectF(src_x, src_y, src_w, src_h));
}
void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, int src_x, int src_y,
int src_w, int src_h, int dest_x, int dest_y,
int dest_w, int dest_h, bool filter,
const SkPaint& paint) {
-
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::DrawStringInt(const std::wstring& text,
const gfx::Font& font,
const SkColor& color, int x, int y, int w,
int h) {
-
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::DrawStringInt(const std::wstring& text,
const gfx::Font& font,
const SkColor& color,
const gfx::Rect& display_rect) {
-
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::DrawStringInt(const std::wstring& text,
@@ -266,19 +335,24 @@ void CanvasDirect2D::DrawStringInt(const std::wstring& text,
const SkColor& color,
int x, int y, int w, int h,
int flags) {
-
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::DrawFocusRect(int x, int y, int width, int height) {
+ NOTIMPLEMENTED();
}
void CanvasDirect2D::TileImageInt(const SkBitmap& bitmap, int x, int y, int w,
int h) {
+ ScopedComPtr<ID2D1Brush> brush(
+ CreateD2D1BrushFromSkBitmap(rt_, bitmap, TileMode_Repeat,
+ TileMode_Repeat));
+ rt_->FillRectangle(RectToRectF(x, y, w, h), brush);
}
void CanvasDirect2D::TileImageInt(const SkBitmap& bitmap, int src_x, int src_y,
int dest_x, int dest_y, int w, int h) {
-
+ NOTIMPLEMENTED();
}
gfx::NativeDrawingContext CanvasDirect2D::BeginPlatformPaint() {
@@ -346,27 +420,9 @@ Brush* CanvasDirect2D::CreateBitmapBrush(
const SkBitmap& bitmap,
TileMode tile_mode_x,
TileMode tile_mode_y) {
- ScopedComPtr<ID2D1Bitmap> d2d1_bitmap;
- HRESULT hr = rt_->CreateBitmap(
- D2D1::SizeU(bitmap.width(), bitmap.height()),
- NULL,
- NULL,
- D2D1::BitmapProperties(
- D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
- D2D1_ALPHA_MODE_IGNORE)),
- d2d1_bitmap.Receive());
- bitmap.lockPixels();
- d2d1_bitmap->CopyFromMemory(NULL, bitmap.getPixels(), bitmap.rowBytes());
- bitmap.unlockPixels();
-
- ID2D1BitmapBrush* brush = NULL;
- hr = rt_->CreateBitmapBrush(
- d2d1_bitmap,
- D2D1::BitmapBrushProperties(TileModeToExtendMode(tile_mode_x),
- TileModeToExtendMode(tile_mode_y)),
- D2D1::BrushProperties(),
- &brush);
- return SUCCEEDED(hr) ? new Direct2DBrush(brush) : NULL;
+ ID2D1Brush* brush =
+ CreateD2D1BrushFromSkBitmap(rt_, bitmap, tile_mode_x, tile_mode_y);
+ return brush ? new Direct2DBrush(brush) : NULL;
}
CanvasSkia* CanvasDirect2D::AsCanvasSkia() {
diff --git a/gfx/canvas_direct2d_unittest.cc b/gfx/canvas_direct2d_unittest.cc
index ff63302..6595a4c 100644
--- a/gfx/canvas_direct2d_unittest.cc
+++ b/gfx/canvas_direct2d_unittest.cc
@@ -281,3 +281,55 @@ TEST(CanvasDirect2D, CreateBitmapBrush) {
canvas.Restore();
}
+TEST(CanvasDirect2D, DrawRectInt) {
+ TestWindow window;
+ gfx::CanvasDirect2D canvas(window.rt());
+
+ canvas.Save();
+ canvas.DrawRectInt(SK_ColorRED, 10, 10, 200, 200);
+ canvas.Restore();
+}
+
+TEST(CanvasDirect2D, DrawLineInt) {
+ TestWindow window;
+ gfx::CanvasDirect2D canvas(window.rt());
+
+ canvas.Save();
+ canvas.DrawLineInt(SK_ColorRED, 10, 10, 210, 210);
+ canvas.Restore();
+}
+
+TEST(CanvasDirect2D, DrawBitmapInt) {
+ TestWindow window;
+ gfx::CanvasDirect2D canvas(window.rt());
+
+ SkBitmap bitmap = LoadBitmapFromResources(IDR_BITMAP_BRUSH_IMAGE);
+
+ canvas.Save();
+ canvas.DrawBitmapInt(bitmap, 100, 100);
+ canvas.Restore();
+}
+
+TEST(CanvasDirect2D, DrawBitmapInt2) {
+ TestWindow window;
+ gfx::CanvasDirect2D canvas(window.rt());
+
+ SkBitmap bitmap = LoadBitmapFromResources(IDR_BITMAP_BRUSH_IMAGE);
+
+ canvas.Save();
+ canvas.DrawBitmapInt(bitmap, 5, 5, 30, 30, 10, 10, 30, 30, false);
+ canvas.DrawBitmapInt(bitmap, 5, 5, 30, 30, 110, 110, 100, 100, true);
+ canvas.DrawBitmapInt(bitmap, 5, 5, 30, 30, 220, 220, 100, 100, false);
+ canvas.Restore();
+}
+
+TEST(CanvasDirect2D, TileImageInt) {
+ TestWindow window;
+ gfx::CanvasDirect2D canvas(window.rt());
+
+ SkBitmap bitmap = LoadBitmapFromResources(IDR_BITMAP_BRUSH_IMAGE);
+
+ canvas.Save();
+ canvas.TileImageInt(bitmap, 10, 10, 300, 300);
+ canvas.Restore();
+}