Chromium Code Reviews| Index: ui/gfx/canvas.cc |
| diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc |
| index 288d19256652b4f53ed2a00a3f1e8ffc76ea2a09..0225e97a4bc52292eb604c2c33ec7b4412043f40 100644 |
| --- a/ui/gfx/canvas.cc |
| +++ b/ui/gfx/canvas.cc |
| @@ -254,42 +254,47 @@ void Canvas::DrawFocusRect(const gfx::Rect& rect) { |
| DrawDashedRect(rect, SK_ColorGRAY); |
| } |
| -void Canvas::DrawBitmapInt(const SkBitmap& bitmap, int x, int y) { |
| - canvas_->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y)); |
| +void Canvas::DrawBitmapInt(const gfx::ImageSkia& image, int x, int y) { |
| + SkPaint paint; |
| + DrawBitmapInt(image, x, y, paint); |
| } |
| -void Canvas::DrawBitmapInt(const SkBitmap& bitmap, |
| +void Canvas::DrawBitmapInt(const gfx::ImageSkia& image, |
| int x, int y, |
| const SkPaint& paint) { |
| - canvas_->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), &paint); |
| + const SkBitmap* bitmap = GetBitmapToPaint(image); |
| + if (bitmap == NULL) |
| + return; |
| + |
| + if (image.ShouldBuildMipMap()) |
|
sky
2012/04/27 23:33:58
Can we hide this in ImageSkia? By that I mean coul
|
| + const_cast<SkBitmap*>(bitmap)->buildMipMap(); |
| + |
| + float bitmap_scale_x = static_cast<float>(bitmap->width()) / image.width(); |
| + float bitmap_scale_y = static_cast<float>(bitmap->height()) / image.height(); |
| + |
| + canvas_->save(); |
| + canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale_x), |
| + SkFloatToScalar(1.0f / bitmap_scale_y)); |
| + canvas_->drawBitmap(*bitmap, |
| + SkFloatToScalar(x * bitmap_scale_x), |
| + SkFloatToScalar(y * bitmap_scale_y)); |
| + canvas_->restore(); |
| } |
| -void Canvas::DrawBitmapInt(const SkBitmap& bitmap, |
| +void Canvas::DrawBitmapInt(const gfx::ImageSkia& image, |
| 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) { |
| SkPaint p; |
| - DrawBitmapInt(bitmap, src_x, src_y, src_w, src_h, dest_x, dest_y, |
| + DrawBitmapInt(image, src_x, src_y, src_w, src_h, dest_x, dest_y, |
| dest_w, dest_h, filter, p); |
| } |
| -void Canvas::DrawBitmapInt(const SkBitmap& bitmap, |
| +void Canvas::DrawBitmapInt(const gfx::ImageSkia& image, |
| 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) { |
| - DrawBitmapFloat(bitmap, static_cast<float>(src_x), static_cast<float>(src_y), |
| - static_cast<float>(src_w), static_cast<float>(src_h), |
| - static_cast<float>(dest_x), static_cast<float>(dest_y), |
| - static_cast<float>(dest_w), static_cast<float>(dest_h), |
| - filter, paint); |
| -} |
| - |
| -void Canvas::DrawBitmapFloat(const SkBitmap& bitmap, |
| - float src_x, float src_y, float src_w, float src_h, |
| - float dest_x, float dest_y, float dest_w, float dest_h, |
| - bool filter, |
| - const SkPaint& paint) { |
| DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && |
| src_y + src_h < std::numeric_limits<int16_t>::max()); |
| if (src_w <= 0 || src_h <= 0) { |
| @@ -300,16 +305,28 @@ void Canvas::DrawBitmapFloat(const SkBitmap& bitmap, |
| if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) |
| return; |
| - SkRect dest_rect = { SkFloatToScalar(dest_x), |
| - SkFloatToScalar(dest_y), |
| - SkFloatToScalar(dest_x + dest_w), |
| - SkFloatToScalar(dest_y + dest_h) }; |
| + const SkBitmap* bitmap = GetBitmapToPaint(image); |
| + if (bitmap == NULL) { |
| + return; |
| + } |
| + |
| + if (image.ShouldBuildMipMap()) |
| + const_cast<SkBitmap*>(bitmap)->buildMipMap(); |
| - if (src_w == dest_w && src_h == dest_h) { |
| + float bitmap_scale_x = static_cast<float>(bitmap->width()) / image.width(); |
| + float bitmap_scale_y = static_cast<float>(bitmap->height()) / image.height(); |
| + |
| + SkRect dest_rect = { SkIntToScalar(dest_x), |
| + SkIntToScalar(dest_y), |
| + SkIntToScalar(dest_x + dest_w), |
| + SkIntToScalar(dest_y + dest_h) }; |
| + |
| + if (src_w == dest_w && src_h == dest_h && |
| + bitmap_scale_x == 1.0f && bitmap_scale_y == 1.0f) { |
| // Workaround for apparent bug in Skia that causes image to occasionally |
| // shift. |
| SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; |
| - canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); |
| + canvas_->drawBitmapRect(*bitmap, &src_rect, dest_rect, &paint); |
| return; |
| } |
| @@ -317,14 +334,17 @@ void Canvas::DrawBitmapFloat(const SkBitmap& bitmap, |
| // basically what SkCanvas.drawBitmap does internally, but it gives us |
| // more control over quality and will use the mipmap in the source image if |
| // it has one, whereas drawBitmap won't. |
| - SkShader* shader = SkShader::CreateBitmapShader(bitmap, |
| + SkShader* shader = SkShader::CreateBitmapShader(*bitmap, |
| SkShader::kRepeat_TileMode, |
| SkShader::kRepeat_TileMode); |
| SkMatrix shader_scale; |
| - shader_scale.setScale(SkFloatToScalar(dest_w / src_w), |
| - SkFloatToScalar(dest_h / src_h)); |
| - shader_scale.preTranslate(SkFloatToScalar(-src_x), SkFloatToScalar(-src_y)); |
| - shader_scale.postTranslate(SkFloatToScalar(dest_x), SkFloatToScalar(dest_y)); |
| + shader_scale.setScale(SkFloatToScalar(static_cast<float>(dest_w) / src_w), |
| + SkFloatToScalar(static_cast<float>(dest_h) / src_h)); |
| + shader_scale.preTranslate(SkFloatToScalar(-src_x * bitmap_scale_x), |
| + SkFloatToScalar(-src_y * bitmap_scale_y)); |
| + shader_scale.postTranslate(SkFloatToScalar(dest_x * bitmap_scale_x), |
| + SkFloatToScalar(dest_y * bitmap_scale_y)); |
| + shader_scale.postScale(1.0f / bitmap_scale_x, 1.0f / bitmap_scale_y); |
| shader->setLocalMatrix(shader_scale); |
| // Set up our paint to use the shader & release our reference (now just owned |
| @@ -366,20 +386,30 @@ void Canvas::DrawStringInt(const string16& text, |
| std::vector<ShadowValue>()); |
| } |
| -void Canvas::TileImageInt(const SkBitmap& bitmap, |
| +void Canvas::TileImageInt(const gfx::ImageSkia& image, |
| int x, int y, int w, int h) { |
| - TileImageInt(bitmap, 0, 0, x, y, w, h); |
| + TileImageInt(image, 0, 0, x, y, w, h); |
| } |
| -void Canvas::TileImageInt(const SkBitmap& bitmap, |
| +void Canvas::TileImageInt(const gfx::ImageSkia& image, |
| int src_x, int src_y, |
| int dest_x, int dest_y, int w, int h) { |
| if (!IntersectsClipRectInt(dest_x, dest_y, w, h)) |
| return; |
| + const SkBitmap* bitmap = GetBitmapToPaint(image); |
| + if (bitmap == NULL) |
| + return; |
| + |
| + if (image.ShouldBuildMipMap()) |
| + const_cast<SkBitmap*>(bitmap)->buildMipMap(); |
| + |
| + float bitmap_scale_x = static_cast<float>(bitmap->width()) / image.width(); |
| + float bitmap_scale_y = static_cast<float>(bitmap->height()) / image.height(); |
| + |
| SkPaint paint; |
| - SkShader* shader = SkShader::CreateBitmapShader(bitmap, |
| + SkShader* shader = SkShader::CreateBitmapShader(*bitmap, |
| SkShader::kRepeat_TileMode, |
| SkShader::kRepeat_TileMode); |
| paint.setShader(shader); |
| @@ -392,6 +422,8 @@ void Canvas::TileImageInt(const SkBitmap& bitmap, |
| canvas_->translate(SkIntToScalar(dest_x - src_x), |
| SkIntToScalar(dest_y - src_y)); |
| ClipRect(gfx::Rect(src_x, src_y, w, h)); |
| + canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale_x), |
| + SkFloatToScalar(1.0f / bitmap_scale_y)); |
| canvas_->drawPaint(paint); |
| canvas_->restore(); |
| } |
| @@ -420,4 +452,12 @@ bool Canvas::IntersectsClipRect(const gfx::Rect& rect) { |
| rect.width(), rect.height()); |
| } |
| +const SkBitmap* Canvas::GetBitmapToPaint(const gfx::ImageSkia& image) const { |
| + SkMatrix m = canvas_->getTotalMatrix(); |
| + float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())); |
| + float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())); |
| + |
| + return image.GetBitmapForScale(scale_x, scale_y); |
| +} |
| + |
| } // namespace gfx |