| Index: ui/gfx/canvas.cc
|
| diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
|
| index 288d19256652b4f53ed2a00a3f1e8ffc76ea2a09..4e9b31179f887cba5bcf15aea6dfb20e987f931b 100644
|
| --- a/ui/gfx/canvas.cc
|
| +++ b/ui/gfx/canvas.cc
|
| @@ -254,42 +254,42 @@ 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;
|
| + float bitmap_scale;
|
| + if (!GetBitmapToPaint(image, &bitmap, &bitmap_scale))
|
| + return;
|
| +
|
| + canvas_->save();
|
| + canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale),
|
| + SkFloatToScalar(1.0f / bitmap_scale));
|
| + canvas_->drawBitmap(*bitmap,
|
| + SkFloatToScalar(x * bitmap_scale),
|
| + SkFloatToScalar(y * bitmap_scale));
|
| + 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 +300,26 @@ 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) };
|
| + float user_scale_x = static_cast<float>(dest_w) / src_w;
|
| + float user_scale_y = static_cast<float>(dest_h) / src_h;
|
|
|
| - if (src_w == dest_w && src_h == dest_h) {
|
| + const SkBitmap* bitmap;
|
| + float bitmap_scale;
|
| + if (!GetBitmapToPaint(image, user_scale_x, user_scale_y, &bitmap,
|
| + &bitmap_scale))
|
| + return;
|
| +
|
| + 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 == 1.0f && bitmap_scale == 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 +327,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(user_scale_x),
|
| + SkFloatToScalar(user_scale_y));
|
| + shader_scale.preTranslate(SkFloatToScalar(-src_x * bitmap_scale),
|
| + SkFloatToScalar(-src_y * bitmap_scale));
|
| + shader_scale.postTranslate(SkFloatToScalar(dest_x * bitmap_scale),
|
| + SkFloatToScalar(dest_y * bitmap_scale));
|
| + shader_scale.postScale(1.0f / bitmap_scale, 1.0f / bitmap_scale);
|
| shader->setLocalMatrix(shader_scale);
|
|
|
| // Set up our paint to use the shader & release our reference (now just owned
|
| @@ -366,20 +379,25 @@ 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;
|
| + float bitmap_scale;
|
| + if (!GetBitmapToPaint(image, &bitmap, &bitmap_scale))
|
| + return;
|
| +
|
| SkPaint paint;
|
|
|
| - SkShader* shader = SkShader::CreateBitmapShader(bitmap,
|
| + SkShader* shader = SkShader::CreateBitmapShader(*bitmap,
|
| SkShader::kRepeat_TileMode,
|
| SkShader::kRepeat_TileMode);
|
| paint.setShader(shader);
|
| @@ -392,6 +410,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),
|
| + SkFloatToScalar(1.0f / bitmap_scale));
|
| canvas_->drawPaint(paint);
|
| canvas_->restore();
|
| }
|
| @@ -420,4 +440,34 @@ bool Canvas::IntersectsClipRect(const gfx::Rect& rect) {
|
| rect.width(), rect.height());
|
| }
|
|
|
| +
|
| +bool Canvas::GetBitmapToPaint(const gfx::ImageSkia& image,
|
| + const SkBitmap** bitmap,
|
| + float* bitmap_scale_factor) const {
|
| + return GetBitmapToPaint(image, 1.0f, 1.0f, bitmap, bitmap_scale_factor);
|
| +}
|
| +
|
| +bool Canvas::GetBitmapToPaint(const gfx::ImageSkia& image,
|
| + float user_additional_scale_x,
|
| + float user_additional_scale_y,
|
| + const SkBitmap** bitmap,
|
| + float* bitmap_scale_factor) const {
|
| + SkMatrix m = canvas_->getTotalMatrix();
|
| + float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) *
|
| + user_additional_scale_x;
|
| + float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) *
|
| + user_additional_scale_y;
|
| +
|
| + bool success = image.GetBitmapForScale(scale_x, scale_y,
|
| + bitmap, bitmap_scale_factor);
|
| + if (!success) {
|
| + return false;
|
| + }
|
| +
|
| + if (scale_x < *bitmap_scale_factor || scale_y < *bitmap_scale_factor)
|
| + const_cast<SkBitmap*>(*bitmap)->buildMipMap();
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace gfx
|
|
|