| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/canvas.h" | 5 #include "ui/gfx/canvas.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "third_party/skia/include/core/SkBitmap.h" | 11 #include "third_party/skia/include/core/SkBitmap.h" |
| 12 #include "third_party/skia/include/effects/SkGradientShader.h" | 12 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 13 #include "ui/gfx/canvas.h" | 13 #include "ui/gfx/canvas.h" |
| 14 #include "ui/gfx/font.h" | 14 #include "ui/gfx/font.h" |
| 15 #include "ui/gfx/rect.h" | 15 #include "ui/gfx/rect.h" |
| 16 #include "ui/gfx/size_conversions.h" | 16 #include "ui/gfx/size_conversions.h" |
| 17 #include "ui/gfx/skia_util.h" | 17 #include "ui/gfx/skia_util.h" |
| 18 #include "ui/gfx/transform.h" | 18 #include "ui/gfx/transform.h" |
| 19 | 19 |
| 20 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
| 21 #include "ui/gfx/canvas_skia_paint.h" | 21 #include "ui/gfx/canvas_skia_paint.h" |
| 22 #endif | 22 #endif |
| 23 | 23 |
| 24 namespace gfx { | 24 namespace gfx { |
| 25 | 25 |
| 26 Canvas::Canvas(const gfx::Size& size, | 26 Canvas::Canvas(const gfx::Size& size, |
| 27 ui::ScaleFactor scale_factor, | 27 ui::ScaleFactor scale_factor, |
| 28 bool is_opaque) | 28 bool is_opaque) |
| 29 : scale_factor_(scale_factor), | 29 : scale_factor_(scale_factor), |
| 30 owned_canvas_(NULL), | |
| 31 canvas_(NULL) { | 30 canvas_(NULL) { |
| 32 gfx::Size pixel_size = gfx::ToFlooredSize( | 31 gfx::Size pixel_size = gfx::ToFlooredSize( |
| 33 gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); | 32 gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); |
| 34 owned_canvas_.reset(skia::CreatePlatformCanvas(pixel_size.width(), | 33 owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), |
| 35 pixel_size.height(), | 34 pixel_size.height(), |
| 36 is_opaque)); | 35 is_opaque)); |
| 37 canvas_ = owned_canvas_.get(); | 36 canvas_ = owned_canvas_.get(); |
| 38 #if defined(OS_WIN) || defined(OS_MACOSX) | 37 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 39 // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but | 38 // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but |
| 40 // uninitialized on Win and Mac. | 39 // uninitialized on Win and Mac. |
| 41 if (!is_opaque) | 40 if (!is_opaque) |
| 42 owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); | 41 owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); |
| 43 #endif | 42 #endif |
| 44 | 43 |
| 45 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor)); | 44 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor)); |
| 46 canvas_->scale(scale, scale); | 45 canvas_->scale(scale, scale); |
| 47 } | 46 } |
| 48 | 47 |
| 49 Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque) | 48 Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque) |
| 50 : scale_factor_(image_rep.scale_factor()), | 49 : scale_factor_(image_rep.scale_factor()), |
| 51 owned_canvas_(skia::CreatePlatformCanvas(image_rep.pixel_width(), | 50 owned_canvas_(skia::AdoptRef( |
| 52 image_rep.pixel_height(), | 51 skia::CreatePlatformCanvas(image_rep.pixel_width(), |
| 53 is_opaque)), | 52 image_rep.pixel_height(), |
| 53 is_opaque))), |
| 54 canvas_(owned_canvas_.get()) { | 54 canvas_(owned_canvas_.get()) { |
| 55 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); | 55 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); |
| 56 canvas_->scale(scale, scale); | 56 canvas_->scale(scale, scale); |
| 57 DrawImageInt(gfx::ImageSkia(image_rep), 0, 0); | 57 DrawImageInt(gfx::ImageSkia(image_rep), 0, 0); |
| 58 } | 58 } |
| 59 | 59 |
| 60 Canvas::Canvas() | 60 Canvas::Canvas() |
| 61 : scale_factor_(ui::SCALE_FACTOR_100P), | 61 : scale_factor_(ui::SCALE_FACTOR_100P), |
| 62 owned_canvas_(skia::CreatePlatformCanvas(0, 0, false)), | 62 owned_canvas_(skia::AdoptRef(skia::CreatePlatformCanvas(0, 0, false))), |
| 63 canvas_(owned_canvas_.get()) { | 63 canvas_(owned_canvas_.get()) { |
| 64 } | 64 } |
| 65 | 65 |
| 66 Canvas::~Canvas() { | 66 Canvas::~Canvas() { |
| 67 } | 67 } |
| 68 | 68 |
| 69 // static | 69 // static |
| 70 Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, | 70 Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, |
| 71 ui::ScaleFactor scale_factor) { | 71 ui::ScaleFactor scale_factor) { |
| 72 return new Canvas(canvas, scale_factor); | 72 return new Canvas(canvas, scale_factor); |
| 73 } | 73 } |
| 74 | 74 |
| 75 void Canvas::RecreateBackingCanvas(const gfx::Size& size, | 75 void Canvas::RecreateBackingCanvas(const gfx::Size& size, |
| 76 ui::ScaleFactor scale_factor, | 76 ui::ScaleFactor scale_factor, |
| 77 bool is_opaque) { | 77 bool is_opaque) { |
| 78 scale_factor_ = scale_factor; | 78 scale_factor_ = scale_factor; |
| 79 gfx::Size pixel_size = gfx::ToFlooredSize( | 79 gfx::Size pixel_size = gfx::ToFlooredSize( |
| 80 gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); | 80 gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); |
| 81 owned_canvas_.reset(skia::CreatePlatformCanvas(pixel_size.width(), | 81 owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), |
| 82 pixel_size.height(), | 82 pixel_size.height(), |
| 83 is_opaque)); | 83 is_opaque)); |
| 84 canvas_ = owned_canvas_.get(); | 84 canvas_ = owned_canvas_.get(); |
| 85 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); | 85 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); |
| 86 canvas_->scale(scale, scale); | 86 canvas_->scale(scale, scale); |
| 87 } | 87 } |
| 88 | 88 |
| 89 // static | 89 // static |
| 90 int Canvas::GetStringWidth(const string16& text, const gfx::Font& font) { | 90 int Canvas::GetStringWidth(const string16& text, const gfx::Font& font) { |
| 91 int width = 0, height = 0; | 91 int width = 0, height = 0; |
| 92 Canvas::SizeStringInt(text, font, &width, &height, NO_ELLIPSIS); | 92 Canvas::SizeStringInt(text, font, &width, &height, NO_ELLIPSIS); |
| 93 return width; | 93 return width; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 for (int u = 0; u < col_pixels; u++) { | 133 for (int u = 0; u < col_pixels; u++) { |
| 134 if ((u % 2 + i % 2) % 2 != 0) { | 134 if ((u % 2 + i % 2) % 2 != 0) { |
| 135 dot[i * row_pixels + u] = color; | 135 dot[i * row_pixels + u] = color; |
| 136 } | 136 } |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 } | 139 } |
| 140 | 140 |
| 141 // Make a shader for the bitmap with an origin of the box we'll draw. This | 141 // Make a shader for the bitmap with an origin of the box we'll draw. This |
| 142 // shader is refcounted and will have an initial refcount of 1. | 142 // shader is refcounted and will have an initial refcount of 1. |
| 143 SkShader* shader = SkShader::CreateBitmapShader( | 143 skia::RefPtr<SkShader> shader = skia::AdoptRef( |
| 144 *dots, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); | 144 SkShader::CreateBitmapShader( |
| 145 *dots, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode)); |
| 145 // Assign the shader to the paint & release our reference. The paint will | 146 // Assign the shader to the paint & release our reference. The paint will |
| 146 // now own the shader and the shader will be destroyed when the paint goes | 147 // now own the shader and the shader will be destroyed when the paint goes |
| 147 // out of scope. | 148 // out of scope. |
| 148 SkPaint paint; | 149 SkPaint paint; |
| 149 paint.setShader(shader); | 150 paint.setShader(shader.get()); |
| 150 shader->unref(); | |
| 151 | 151 |
| 152 DrawRect(gfx::Rect(rect.x(), rect.y(), rect.width(), 1), paint); | 152 DrawRect(gfx::Rect(rect.x(), rect.y(), rect.width(), 1), paint); |
| 153 DrawRect(gfx::Rect(rect.x(), rect.y() + rect.height() - 1, rect.width(), 1), | 153 DrawRect(gfx::Rect(rect.x(), rect.y() + rect.height() - 1, rect.width(), 1), |
| 154 paint); | 154 paint); |
| 155 DrawRect(gfx::Rect(rect.x(), rect.y(), 1, rect.height()), paint); | 155 DrawRect(gfx::Rect(rect.x(), rect.y(), 1, rect.height()), paint); |
| 156 DrawRect(gfx::Rect(rect.x() + rect.width() - 1, rect.y(), 1, rect.height()), | 156 DrawRect(gfx::Rect(rect.x() + rect.width() - 1, rect.y(), 1, rect.height()), |
| 157 paint); | 157 paint); |
| 158 } | 158 } |
| 159 | 159 |
| 160 void Canvas::Save() { | 160 void Canvas::Save() { |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 // Make a bitmap shader that contains the bitmap we want to draw. This is | 366 // Make a bitmap shader that contains the bitmap we want to draw. This is |
| 367 // basically what SkCanvas.drawBitmap does internally, but it gives us | 367 // basically what SkCanvas.drawBitmap does internally, but it gives us |
| 368 // more control over quality and will use the mipmap in the source image if | 368 // more control over quality and will use the mipmap in the source image if |
| 369 // it has one, whereas drawBitmap won't. | 369 // it has one, whereas drawBitmap won't. |
| 370 SkMatrix shader_scale; | 370 SkMatrix shader_scale; |
| 371 shader_scale.setScale(SkFloatToScalar(user_scale_x), | 371 shader_scale.setScale(SkFloatToScalar(user_scale_x), |
| 372 SkFloatToScalar(user_scale_y)); | 372 SkFloatToScalar(user_scale_y)); |
| 373 shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); | 373 shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); |
| 374 shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); | 374 shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); |
| 375 | 375 |
| 376 SkShader* shader = gfx::CreateImageRepShader(image_rep, | 376 skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( |
| 377 SkShader::kRepeat_TileMode, | 377 image_rep, |
| 378 shader_scale); | 378 SkShader::kRepeat_TileMode, |
| 379 shader_scale); |
| 379 | 380 |
| 380 // Set up our paint to use the shader & release our reference (now just owned | 381 // Set up our paint to use the shader & release our reference (now just owned |
| 381 // by the paint). | 382 // by the paint). |
| 382 SkPaint p(paint); | 383 SkPaint p(paint); |
| 383 p.setFilterBitmap(filter); | 384 p.setFilterBitmap(filter); |
| 384 p.setShader(shader); | 385 p.setShader(shader.get()); |
| 385 shader->unref(); | |
| 386 | 386 |
| 387 // The rect will be filled by the bitmap. | 387 // The rect will be filled by the bitmap. |
| 388 canvas_->drawRect(dest_rect, p); | 388 canvas_->drawRect(dest_rect, p); |
| 389 } | 389 } |
| 390 | 390 |
| 391 void Canvas::DrawImageInPath(const gfx::ImageSkia& image, | 391 void Canvas::DrawImageInPath(const gfx::ImageSkia& image, |
| 392 int x, | 392 int x, |
| 393 int y, | 393 int y, |
| 394 const SkPath& path, | 394 const SkPath& path, |
| 395 const SkPaint& paint) { | 395 const SkPaint& paint) { |
| 396 const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image); | 396 const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image); |
| 397 if (image_rep.is_null()) | 397 if (image_rep.is_null()) |
| 398 return; | 398 return; |
| 399 | 399 |
| 400 SkMatrix matrix; | 400 SkMatrix matrix; |
| 401 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); | 401 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); |
| 402 SkShader* shader = gfx::CreateImageRepShader(image_rep, | 402 skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( |
| 403 SkShader::kRepeat_TileMode, matrix); | 403 image_rep, |
| 404 SkShader::kRepeat_TileMode, |
| 405 matrix); |
| 404 | 406 |
| 405 SkPaint p(paint); | 407 SkPaint p(paint); |
| 406 p.setShader(shader); | 408 p.setShader(shader.get()); |
| 407 shader->unref(); | |
| 408 canvas_->drawPath(path, p); | 409 canvas_->drawPath(path, p); |
| 409 } | 410 } |
| 410 | 411 |
| 411 void Canvas::DrawStringInt(const string16& text, | 412 void Canvas::DrawStringInt(const string16& text, |
| 412 const gfx::Font& font, | 413 const gfx::Font& font, |
| 413 SkColor color, | 414 SkColor color, |
| 414 int x, int y, int w, int h) { | 415 int x, int y, int w, int h) { |
| 415 DrawStringInt(text, font, color, x, y, w, h, DefaultCanvasTextAlignment()); | 416 DrawStringInt(text, font, color, x, y, w, h, DefaultCanvasTextAlignment()); |
| 416 } | 417 } |
| 417 | 418 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 tile_scale_x, tile_scale_y); | 459 tile_scale_x, tile_scale_y); |
| 459 if (image_rep.is_null()) | 460 if (image_rep.is_null()) |
| 460 return; | 461 return; |
| 461 | 462 |
| 462 SkMatrix shader_scale; | 463 SkMatrix shader_scale; |
| 463 shader_scale.setScale(SkFloatToScalar(tile_scale_x), | 464 shader_scale.setScale(SkFloatToScalar(tile_scale_x), |
| 464 SkFloatToScalar(tile_scale_y)); | 465 SkFloatToScalar(tile_scale_y)); |
| 465 shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); | 466 shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); |
| 466 shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); | 467 shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); |
| 467 | 468 |
| 468 SkShader* shader = gfx::CreateImageRepShader(image_rep, | 469 skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( |
| 469 SkShader::kRepeat_TileMode, | 470 image_rep, |
| 470 shader_scale); | 471 SkShader::kRepeat_TileMode, |
| 472 shader_scale); |
| 471 | 473 |
| 472 SkPaint paint; | 474 SkPaint paint; |
| 473 paint.setShader(shader); | 475 paint.setShader(shader.get()); |
| 474 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | 476 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); |
| 475 shader->unref(); | |
| 476 | 477 |
| 477 SkRect dest_rect = { SkIntToScalar(dest_x), | 478 SkRect dest_rect = { SkIntToScalar(dest_x), |
| 478 SkIntToScalar(dest_y), | 479 SkIntToScalar(dest_y), |
| 479 SkIntToScalar(dest_x + w), | 480 SkIntToScalar(dest_x + w), |
| 480 SkIntToScalar(dest_y + h) }; | 481 SkIntToScalar(dest_y + h) }; |
| 481 canvas_->drawRect(dest_rect, paint); | 482 canvas_->drawRect(dest_rect, paint); |
| 482 } | 483 } |
| 483 | 484 |
| 484 gfx::NativeDrawingContext Canvas::BeginPlatformPaint() { | 485 gfx::NativeDrawingContext Canvas::BeginPlatformPaint() { |
| 485 return skia::BeginPlatformPaint(canvas_); | 486 return skia::BeginPlatformPaint(canvas_); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 | 533 |
| 533 float bitmap_scale = image_rep.GetScale(); | 534 float bitmap_scale = image_rep.GetScale(); |
| 534 if (scale_x < bitmap_scale || scale_y < bitmap_scale) | 535 if (scale_x < bitmap_scale || scale_y < bitmap_scale) |
| 535 const_cast<SkBitmap&>(image_rep.sk_bitmap()).buildMipMap(); | 536 const_cast<SkBitmap&>(image_rep.sk_bitmap()).buildMipMap(); |
| 536 } | 537 } |
| 537 | 538 |
| 538 return image_rep; | 539 return image_rep; |
| 539 } | 540 } |
| 540 | 541 |
| 541 } // namespace gfx | 542 } // namespace gfx |
| OLD | NEW |