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/skia_util.h" | 16 #include "ui/gfx/skia_util.h" |
17 #include "ui/gfx/transform.h" | 17 #include "ui/gfx/transform.h" |
18 | 18 |
19 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
20 #include "ui/gfx/canvas_skia_paint.h" | 20 #include "ui/gfx/canvas_skia_paint.h" |
21 #endif | 21 #endif |
22 | 22 |
23 namespace gfx { | 23 namespace gfx { |
24 | 24 |
| 25 Canvas::Canvas(const gfx::Size& size, bool is_opaque) |
| 26 : owned_canvas_(new skia::PlatformCanvas(size.width(), size.height(), |
| 27 is_opaque)), |
| 28 canvas_(owned_canvas_.get()) { |
| 29 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 30 // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but |
| 31 // uninitialized on Win and Mac. |
| 32 if (!is_opaque) |
| 33 owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); |
| 34 #endif |
| 35 |
| 36 ApplyScaleFactor(ui::SCALE_FACTOR_100P, false); |
| 37 } |
| 38 |
25 Canvas::Canvas(const gfx::Size& size, | 39 Canvas::Canvas(const gfx::Size& size, |
26 ui::ScaleFactor scale_factor, | 40 ui::ScaleFactor scale_factor, |
27 bool is_opaque) | 41 bool is_opaque) { |
28 : scale_factor_(scale_factor), | |
29 owned_canvas_(NULL), | |
30 canvas_(NULL) { | |
31 gfx::Size pixel_size = size.Scale(ui::GetScaleFactorScale(scale_factor)); | 42 gfx::Size pixel_size = size.Scale(ui::GetScaleFactorScale(scale_factor)); |
32 owned_canvas_.reset(new skia::PlatformCanvas(pixel_size.width(), | 43 owned_canvas_.reset(new skia::PlatformCanvas(pixel_size.width(), |
33 pixel_size.height(), | 44 pixel_size.height(), |
34 is_opaque)); | 45 is_opaque)); |
35 canvas_ = owned_canvas_.get(); | 46 canvas_ = owned_canvas_.get(); |
36 #if defined(OS_WIN) || defined(OS_MACOSX) | 47 #if defined(OS_WIN) || defined(OS_MACOSX) |
37 // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but | 48 // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but |
38 // uninitialized on Win and Mac. | 49 // uninitialized on Win and Mac. |
39 if (!is_opaque) | 50 if (!is_opaque) |
40 owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); | 51 owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); |
41 #endif | 52 #endif |
42 | 53 |
43 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor)); | 54 ApplyScaleFactor(scale_factor, true); |
44 canvas_->scale(scale, scale); | |
45 } | 55 } |
46 | 56 |
47 Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque) | 57 Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque) |
48 : scale_factor_(image_rep.scale_factor()), | 58 : owned_canvas_(new skia::PlatformCanvas(image_rep.pixel_width(), |
49 owned_canvas_(new skia::PlatformCanvas(image_rep.pixel_width(), | |
50 image_rep.pixel_height(), | 59 image_rep.pixel_height(), |
51 is_opaque)), | 60 is_opaque)), |
52 canvas_(owned_canvas_.get()) { | 61 canvas_(owned_canvas_.get()) { |
53 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); | 62 ApplyScaleFactor(image_rep.scale_factor(), true); |
54 canvas_->scale(scale, scale); | |
55 DrawImageInt(gfx::ImageSkia(image_rep), 0, 0); | 63 DrawImageInt(gfx::ImageSkia(image_rep), 0, 0); |
56 } | 64 } |
57 | 65 |
58 Canvas::Canvas() | 66 Canvas::Canvas() |
59 : scale_factor_(ui::SCALE_FACTOR_100P), | 67 : owned_canvas_(new skia::PlatformCanvas()), |
60 owned_canvas_(new skia::PlatformCanvas()), | |
61 canvas_(owned_canvas_.get()) { | 68 canvas_(owned_canvas_.get()) { |
| 69 ApplyScaleFactor(ui::SCALE_FACTOR_100P, false); |
| 70 } |
| 71 |
| 72 Canvas::Canvas(SkCanvas* canvas, |
| 73 ui::ScaleFactor scale_factor, |
| 74 bool scale_canvas) |
| 75 : owned_canvas_(), |
| 76 canvas_(canvas) { |
| 77 DCHECK(canvas); |
| 78 ApplyScaleFactor(scale_factor, scale_canvas); |
62 } | 79 } |
63 | 80 |
64 Canvas::~Canvas() { | 81 Canvas::~Canvas() { |
65 } | 82 if (scale_factor_scales_canvas_) { |
66 | 83 SkScalar scale = 1.0f / ui::GetScaleFactorScale(scale_factor_); |
67 // static | 84 canvas_->scale(scale, scale); |
68 Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, | 85 } |
69 ui::ScaleFactor scale_factor) { | |
70 return new Canvas(canvas, scale_factor); | |
71 } | 86 } |
72 | 87 |
73 void Canvas::RecreateBackingCanvas(const gfx::Size& size, | 88 void Canvas::RecreateBackingCanvas(const gfx::Size& size, |
74 ui::ScaleFactor scale_factor, | 89 ui::ScaleFactor scale_factor, |
75 bool is_opaque) { | 90 bool is_opaque) { |
76 scale_factor_ = scale_factor; | |
77 gfx::Size pixel_size = size.Scale(ui::GetScaleFactorScale(scale_factor)); | 91 gfx::Size pixel_size = size.Scale(ui::GetScaleFactorScale(scale_factor)); |
78 owned_canvas_.reset(new skia::PlatformCanvas(pixel_size.width(), | 92 owned_canvas_.reset(new skia::PlatformCanvas(pixel_size.width(), |
79 pixel_size.height(), | 93 pixel_size.height(), |
80 is_opaque)); | 94 is_opaque)); |
81 canvas_ = owned_canvas_.get(); | 95 canvas_ = owned_canvas_.get(); |
82 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); | 96 |
83 canvas_->scale(scale, scale); | 97 ApplyScaleFactor(scale_factor, true); |
84 } | 98 } |
85 | 99 |
86 // static | 100 // static |
87 int Canvas::GetStringWidth(const string16& text, const gfx::Font& font) { | 101 int Canvas::GetStringWidth(const string16& text, const gfx::Font& font) { |
88 int width = 0, height = 0; | 102 int width = 0, height = 0; |
89 Canvas::SizeStringInt(text, font, &width, &height, NO_ELLIPSIS); | 103 Canvas::SizeStringInt(text, font, &width, &height, NO_ELLIPSIS); |
90 return width; | 104 return width; |
91 } | 105 } |
92 | 106 |
93 // static | 107 // static |
94 int Canvas::DefaultCanvasTextAlignment() { | 108 int Canvas::DefaultCanvasTextAlignment() { |
95 return base::i18n::IsRTL() ? TEXT_ALIGN_RIGHT : TEXT_ALIGN_LEFT; | 109 return base::i18n::IsRTL() ? TEXT_ALIGN_RIGHT : TEXT_ALIGN_LEFT; |
96 } | 110 } |
97 | 111 |
98 gfx::ImageSkiaRep Canvas::ExtractImageRep() const { | 112 SkBitmap Canvas::ExtractBitmap() const { |
99 const SkBitmap& device_bitmap = canvas_->getDevice()->accessBitmap(false); | 113 const SkBitmap& device_bitmap = canvas_->getDevice()->accessBitmap(false); |
100 | 114 |
101 // Make a bitmap to return, and a canvas to draw into it. We don't just want | 115 // Make a bitmap to return, and a canvas to draw into it. We don't just want |
102 // to call extractSubset or the copy constructor, since we want an actual copy | 116 // to call extractSubset or the copy constructor, since we want an actual copy |
103 // of the bitmap. | 117 // of the bitmap. |
104 SkBitmap result; | 118 SkBitmap result; |
105 device_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); | 119 device_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); |
| 120 return result; |
| 121 } |
106 | 122 |
107 return gfx::ImageSkiaRep(result, scale_factor_); | 123 gfx::ImageSkiaRep Canvas::ExtractImageSkiaRep() const { |
| 124 return gfx::ImageSkiaRep(ExtractBitmap(), scale_factor_); |
108 } | 125 } |
109 | 126 |
110 void Canvas::DrawDashedRect(const gfx::Rect& rect, SkColor color) { | 127 void Canvas::DrawDashedRect(const gfx::Rect& rect, SkColor color) { |
111 // Create a 2D bitmap containing alternating on/off pixels - we do this | 128 // Create a 2D bitmap containing alternating on/off pixels - we do this |
112 // so that you never get two pixels of the same color around the edges | 129 // so that you never get two pixels of the same color around the edges |
113 // of the focus rect (this may mean that opposing edges of the rect may | 130 // of the focus rect (this may mean that opposing edges of the rect may |
114 // have a dot pattern out of phase to each other). | 131 // have a dot pattern out of phase to each other). |
115 static SkColor last_color; | 132 static SkColor last_color; |
116 static SkBitmap* dots = NULL; | 133 static SkBitmap* dots = NULL; |
117 if (!dots || last_color != color) { | 134 if (!dots || last_color != color) { |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 } | 494 } |
478 | 495 |
479 void Canvas::EndPlatformPaint() { | 496 void Canvas::EndPlatformPaint() { |
480 skia::EndPlatformPaint(canvas_); | 497 skia::EndPlatformPaint(canvas_); |
481 } | 498 } |
482 | 499 |
483 void Canvas::Transform(const ui::Transform& transform) { | 500 void Canvas::Transform(const ui::Transform& transform) { |
484 canvas_->concat(transform.matrix()); | 501 canvas_->concat(transform.matrix()); |
485 } | 502 } |
486 | 503 |
487 Canvas::Canvas(SkCanvas* canvas, ui::ScaleFactor scale_factor) | |
488 : scale_factor_(scale_factor), | |
489 owned_canvas_(), | |
490 canvas_(canvas) { | |
491 DCHECK(canvas); | |
492 } | |
493 | |
494 bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { | 504 bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { |
495 SkRect clip; | 505 SkRect clip; |
496 return canvas_->getClipBounds(&clip) && | 506 return canvas_->getClipBounds(&clip) && |
497 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), | 507 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), |
498 SkIntToScalar(y + h)); | 508 SkIntToScalar(y + h)); |
499 } | 509 } |
500 | 510 |
501 bool Canvas::IntersectsClipRect(const gfx::Rect& rect) { | 511 bool Canvas::IntersectsClipRect(const gfx::Rect& rect) { |
502 return IntersectsClipRectInt(rect.x(), rect.y(), | 512 return IntersectsClipRectInt(rect.x(), rect.y(), |
503 rect.width(), rect.height()); | 513 rect.width(), rect.height()); |
504 } | 514 } |
505 | 515 |
| 516 void Canvas::ApplyScaleFactor(ui::ScaleFactor scale_factor, |
| 517 bool scale_canvas) { |
| 518 scale_factor_scales_canvas_ = scale_canvas; |
| 519 scale_factor_ = scale_factor; |
| 520 if (scale_canvas) { |
| 521 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor)); |
| 522 canvas_->scale(scale, scale); |
| 523 } |
| 524 } |
| 525 |
506 const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( | 526 const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( |
507 const gfx::ImageSkia& image) const { | 527 const gfx::ImageSkia& image) const { |
508 return GetImageRepToPaint(image, 1.0f, 1.0f); | 528 return GetImageRepToPaint(image, 1.0f, 1.0f); |
509 } | 529 } |
510 | 530 |
511 const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( | 531 const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( |
512 const gfx::ImageSkia& image, | 532 const gfx::ImageSkia& image, |
513 float user_additional_scale_x, | 533 float user_additional_scale_x, |
514 float user_additional_scale_y) const { | 534 float user_additional_scale_y) const { |
515 const gfx::ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor_); | 535 const gfx::ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor_); |
516 | 536 |
517 if (!image_rep.is_null()) { | 537 if (!image_rep.is_null()) { |
518 SkMatrix m = canvas_->getTotalMatrix(); | 538 SkMatrix m = canvas_->getTotalMatrix(); |
519 float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) * | 539 float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) * |
520 user_additional_scale_x; | 540 user_additional_scale_x; |
521 float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) * | 541 float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) * |
522 user_additional_scale_y; | 542 user_additional_scale_y; |
523 | 543 |
524 float bitmap_scale = image_rep.GetScale(); | 544 float bitmap_scale = image_rep.GetScale(); |
525 if (scale_x < bitmap_scale || scale_y < bitmap_scale) | 545 if (scale_x < bitmap_scale || scale_y < bitmap_scale) |
526 const_cast<SkBitmap&>(image_rep.sk_bitmap()).buildMipMap(); | 546 const_cast<SkBitmap&>(image_rep.sk_bitmap()).buildMipMap(); |
527 } | 547 } |
528 | 548 |
529 return image_rep; | 549 return image_rep; |
530 } | 550 } |
531 | 551 |
532 } // namespace gfx | 552 } // namespace gfx |
OLD | NEW |