Index: ui/gfx/canvas.cc |
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc |
index 0b7819582031a757b168523c1ca4ef0e42254813..458a0b261804e94a4dbf6a9d6e0969a43ca40492 100644 |
--- a/ui/gfx/canvas.cc |
+++ b/ui/gfx/canvas.cc |
@@ -377,63 +377,59 @@ void Canvas::DrawImageInt(const ImageSkia& image, |
int 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) { |
- NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; |
- return; |
- } |
- |
- if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) |
- return; |
- |
- float user_scale_x = static_cast<float>(dest_w) / src_w; |
- float user_scale_y = static_cast<float>(dest_h) / src_h; |
- |
- const ImageSkiaRep& image_rep = GetImageRepToPaint(image, |
- user_scale_x, user_scale_y); |
- if (image_rep.is_null()) |
- 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 && |
- user_scale_x == 1.0f && user_scale_y == 1.0f && |
- image_rep.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 }; |
- const SkBitmap& bitmap = image_rep.sk_bitmap(); |
- canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); |
- return; |
- } |
- |
- // Make a bitmap shader that contains the bitmap we want to draw. This is |
- // 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. |
- SkMatrix shader_scale; |
- shader_scale.setScale(SkFloatToScalar(user_scale_x), |
- SkFloatToScalar(user_scale_y)); |
- shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); |
- shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); |
- |
- skia::RefPtr<SkShader> shader = CreateImageRepShader( |
- image_rep, |
- SkShader::kRepeat_TileMode, |
- shader_scale); |
- |
- // Set up our paint to use the shader & release our reference (now just owned |
- // by the paint). |
- SkPaint p(paint); |
- p.setFilterBitmap(filter); |
- p.setShader(shader.get()); |
- |
- // The rect will be filled by the bitmap. |
- canvas_->drawRect(dest_rect, p); |
+ DrawImageIntHelper(image, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, |
+ dest_h, filter, paint, image_scale_, false); |
+} |
+ |
+void Canvas::DrawImageIntInPixel(const 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) { |
+ // Logic as below:- |
+ // 1. Translate the destination rectangle with using the current translation |
sky
2014/05/05 14:08:16
nit: remove with.
ananta
2014/05/05 18:53:28
Done.
|
+ // values from the SkCanvas matrix stack. |
+ // 2. Save the current state of the canvas. |
+ // 3. Reset the scales and the translation values in the SkCanvas matrix |
+ // stack top. |
+ // 4. Set the scale in gfx::Canvas instance to 1.0, 1.0. Ideally this should |
sky
2014/05/05 14:08:16
I don't get the 'ideally this sould have been enou
ananta
2014/05/05 18:53:28
I assumed that setting the scale to 1.0 in the SkC
|
+ // have been enough. But is not the case. |
+ // 5. Draw the image. |
+ // 6. Restore the state of the canvas and the SkCanvas matrix stack. |
+ float image_scale = image_scale_; |
+ SkMatrix saved_matrix = canvas_->getTotalMatrix(); |
+ SkMatrix new_matrix = saved_matrix; |
+ |
+ SkRect destination_rect; |
+ destination_rect.set(dest_x, dest_y, dest_x + dest_w, dest_y + dest_h); |
sky
2014/05/05 14:08:16
These should all be SkIntToScalar I bleieve.
ananta
2014/05/05 18:53:28
Done.
|
+ new_matrix.setScaleX(1.0f); |
+ new_matrix.setScaleY(1.0f); |
+ new_matrix.mapRect(&destination_rect, destination_rect); |
+ |
+ Save(); |
+ |
+ // The destination is now in pixel values. No need for further translation. |
+ new_matrix.setTranslate(0, 0); |
+ canvas_->setMatrix(new_matrix); |
+ |
+ Scale(1.0f, 1.0f); |
+ |
+ DrawImageIntHelper(image, src_x, src_y, src_w, src_h, destination_rect.x(), |
sky
2014/05/05 14:08:16
SkScalarToInt I believe.
ananta
2014/05/05 18:53:28
No function by that name. Replaced with SkScalarRo
|
+ destination_rect.y(), destination_rect.width(), |
+ destination_rect.height(), filter, paint, image_scale, |
+ true); |
+ |
+ // Restore the scale factor and the old state in the canvas. |
+ Scale(image_scale, image_scale); |
sky
2014/05/05 14:08:16
Doesn't the save save the matrix and scale so that
ananta
2014/05/05 18:53:28
Left the Restore call as is. Removed the rest.
|
+ Restore(); |
+ canvas_->setMatrix(saved_matrix); |
+ image_scale_ = image_scale; |
} |
void Canvas::DrawImageInPath(const ImageSkia& image, |
@@ -505,7 +501,7 @@ void Canvas::TileImageInt(const ImageSkia& image, |
return; |
const ImageSkiaRep& image_rep = GetImageRepToPaint( |
- image, tile_scale_x, tile_scale_y); |
+ image, image_scale_, tile_scale_x, tile_scale_y); |
if (image_rep.is_null()) |
return; |
@@ -563,14 +559,15 @@ bool Canvas::IntersectsClipRect(const Rect& rect) { |
} |
const ImageSkiaRep& Canvas::GetImageRepToPaint(const ImageSkia& image) const { |
- return GetImageRepToPaint(image, 1.0f, 1.0f); |
+ return GetImageRepToPaint(image, image_scale_, 1.0f, 1.0f); |
} |
const ImageSkiaRep& Canvas::GetImageRepToPaint( |
const ImageSkia& image, |
+ float image_scale, |
float user_additional_scale_x, |
float user_additional_scale_y) const { |
- const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); |
+ const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale); |
if (!image_rep.is_null()) { |
SkMatrix m = canvas_->getTotalMatrix(); |
@@ -587,4 +584,77 @@ const ImageSkiaRep& Canvas::GetImageRepToPaint( |
return image_rep; |
} |
+void Canvas::DrawImageIntHelper(const 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, |
+ float image_scale, |
+ bool pixel) { |
+ 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) { |
+ NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; |
+ return; |
+ } |
+ |
+ if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) |
+ return; |
+ |
+ float user_scale_x = static_cast<float>(dest_w) / src_w; |
+ float user_scale_y = static_cast<float>(dest_h) / src_h; |
+ |
+ const ImageSkiaRep& image_rep = GetImageRepToPaint(image, |
+ image_scale, user_scale_x, user_scale_y); |
+ if (image_rep.is_null()) |
+ 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 && |
+ user_scale_x == 1.0f && user_scale_y == 1.0f && |
+ image_rep.scale() == 1.0f && !pixel) { |
+ // 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 }; |
+ const SkBitmap& bitmap = image_rep.sk_bitmap(); |
+ canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); |
+ return; |
+ } |
+ |
+ // Make a bitmap shader that contains the bitmap we want to draw. This is |
+ // 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. |
+ SkMatrix shader_scale; |
+ shader_scale.setScale(SkFloatToScalar(user_scale_x), |
+ SkFloatToScalar(user_scale_y)); |
+ shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); |
+ shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); |
+ |
+ skia::RefPtr<SkShader> shader = CreateImageRepShaderForScale( |
+ image_rep, |
+ SkShader::kRepeat_TileMode, |
+ shader_scale, |
+ pixel ? 1.0f : image_scale); |
+ |
+ // Set up our paint to use the shader & release our reference (now just owned |
+ // by the paint). |
+ SkPaint p(paint); |
+ p.setFilterBitmap(filter); |
+ p.setShader(shader.get()); |
+ |
+ // The rect will be filled by the bitmap. |
+ canvas_->drawRect(dest_rect, p); |
+} |
+ |
} // namespace gfx |