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