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_list.h" | 14 #include "ui/gfx/font_list.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 Size& size, float image_scale, bool is_opaque) | 26 Canvas::Canvas(const Size& size, ui::ScaleFactor scale_factor, bool is_opaque) |
27 : image_scale_(image_scale), | 27 : scale_factor_(scale_factor), |
28 canvas_(NULL) { | 28 canvas_(NULL) { |
29 Size pixel_size = ToCeiledSize(ScaleSize(size, image_scale)); | 29 Size pixel_size = ToCeiledSize( |
| 30 ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); |
30 owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), | 31 owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), |
31 pixel_size.height(), | 32 pixel_size.height(), |
32 is_opaque)); | 33 is_opaque)); |
33 canvas_ = owned_canvas_.get(); | 34 canvas_ = owned_canvas_.get(); |
34 #if defined(OS_WIN) || defined(OS_MACOSX) | 35 #if defined(OS_WIN) || defined(OS_MACOSX) |
35 // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but | 36 // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but |
36 // uninitialized on Win and Mac. | 37 // uninitialized on Win and Mac. |
37 if (!is_opaque) | 38 if (!is_opaque) |
38 owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); | 39 owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); |
39 #endif | 40 #endif |
40 | 41 |
41 SkScalar scale_scalar = SkFloatToScalar(image_scale); | 42 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor)); |
42 canvas_->scale(scale_scalar, scale_scalar); | 43 canvas_->scale(scale, scale); |
43 } | 44 } |
44 | 45 |
45 Canvas::Canvas(const ImageSkiaRep& image_rep, bool is_opaque) | 46 Canvas::Canvas(const ImageSkiaRep& image_rep, bool is_opaque) |
46 : image_scale_(image_rep.scale()), | 47 : scale_factor_(image_rep.scale_factor()), |
47 owned_canvas_(skia::AdoptRef( | 48 owned_canvas_(skia::AdoptRef( |
48 skia::CreatePlatformCanvas(image_rep.pixel_width(), | 49 skia::CreatePlatformCanvas(image_rep.pixel_width(), |
49 image_rep.pixel_height(), | 50 image_rep.pixel_height(), |
50 is_opaque))), | 51 is_opaque))), |
51 canvas_(owned_canvas_.get()) { | 52 canvas_(owned_canvas_.get()) { |
52 SkScalar scale_scalar = SkFloatToScalar(image_scale_); | 53 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); |
53 canvas_->scale(scale_scalar, scale_scalar); | 54 canvas_->scale(scale, scale); |
54 DrawImageInt(ImageSkia(image_rep), 0, 0); | 55 DrawImageInt(ImageSkia(image_rep), 0, 0); |
55 } | 56 } |
56 | 57 |
57 Canvas::Canvas() | 58 Canvas::Canvas() |
58 : image_scale_(1.0), | 59 : scale_factor_(ui::SCALE_FACTOR_100P), |
59 owned_canvas_(skia::AdoptRef(skia::CreatePlatformCanvas(0, 0, false))), | 60 owned_canvas_(skia::AdoptRef(skia::CreatePlatformCanvas(0, 0, false))), |
60 canvas_(owned_canvas_.get()) { | 61 canvas_(owned_canvas_.get()) { |
61 } | 62 } |
62 | 63 |
63 Canvas::~Canvas() { | 64 Canvas::~Canvas() { |
64 } | 65 } |
65 | 66 |
66 // static | 67 // static |
67 Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, | 68 Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, |
68 float image_scale) { | 69 ui::ScaleFactor scale_factor) { |
69 return new Canvas(canvas, image_scale); | 70 return new Canvas(canvas, scale_factor); |
70 } | 71 } |
71 | 72 |
72 void Canvas::RecreateBackingCanvas(const Size& size, | 73 void Canvas::RecreateBackingCanvas(const Size& size, |
73 float image_scale, | 74 ui::ScaleFactor scale_factor, |
74 bool is_opaque) { | 75 bool is_opaque) { |
75 image_scale_ = image_scale; | 76 scale_factor_ = scale_factor; |
76 Size pixel_size = ToFlooredSize(ScaleSize(size, image_scale)); | 77 Size pixel_size = ToFlooredSize( |
| 78 ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); |
77 owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), | 79 owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), |
78 pixel_size.height(), | 80 pixel_size.height(), |
79 is_opaque)); | 81 is_opaque)); |
80 canvas_ = owned_canvas_.get(); | 82 canvas_ = owned_canvas_.get(); |
81 SkScalar scale_scalar = SkFloatToScalar(image_scale); | 83 SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); |
82 canvas_->scale(scale_scalar, scale_scalar); | 84 canvas_->scale(scale, scale); |
83 } | 85 } |
84 | 86 |
85 // static | 87 // static |
86 void Canvas::SizeStringInt(const base::string16& text, | 88 void Canvas::SizeStringInt(const base::string16& text, |
87 const Font& font, | 89 const Font& font, |
88 int* width, | 90 int* width, |
89 int* height, | 91 int* height, |
90 int line_height, | 92 int line_height, |
91 int flags) { | 93 int flags) { |
92 SizeStringInt(text, FontList(font), width, height, line_height, flags); | 94 SizeStringInt(text, FontList(font), width, height, line_height, flags); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 | 129 |
128 ImageSkiaRep Canvas::ExtractImageRep() const { | 130 ImageSkiaRep Canvas::ExtractImageRep() const { |
129 const SkBitmap& device_bitmap = canvas_->getDevice()->accessBitmap(false); | 131 const SkBitmap& device_bitmap = canvas_->getDevice()->accessBitmap(false); |
130 | 132 |
131 // Make a bitmap to return, and a canvas to draw into it. We don't just want | 133 // Make a bitmap to return, and a canvas to draw into it. We don't just want |
132 // to call extractSubset or the copy constructor, since we want an actual copy | 134 // to call extractSubset or the copy constructor, since we want an actual copy |
133 // of the bitmap. | 135 // of the bitmap. |
134 SkBitmap result; | 136 SkBitmap result; |
135 device_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); | 137 device_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); |
136 | 138 |
137 return ImageSkiaRep(result, image_scale_); | 139 return ImageSkiaRep(result, scale_factor_); |
138 } | 140 } |
139 | 141 |
140 void Canvas::DrawDashedRect(const Rect& rect, SkColor color) { | 142 void Canvas::DrawDashedRect(const Rect& rect, SkColor color) { |
141 // Create a 2D bitmap containing alternating on/off pixels - we do this | 143 // Create a 2D bitmap containing alternating on/off pixels - we do this |
142 // so that you never get two pixels of the same color around the edges | 144 // so that you never get two pixels of the same color around the edges |
143 // of the focus rect (this may mean that opposing edges of the rect may | 145 // of the focus rect (this may mean that opposing edges of the rect may |
144 // have a dot pattern out of phase to each other). | 146 // have a dot pattern out of phase to each other). |
145 static SkColor last_color; | 147 static SkColor last_color; |
146 static SkBitmap* dots = NULL; | 148 static SkBitmap* dots = NULL; |
147 if (!dots || last_color != color) { | 149 if (!dots || last_color != color) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 } | 322 } |
321 | 323 |
322 void Canvas::DrawImageInt(const ImageSkia& image, | 324 void Canvas::DrawImageInt(const ImageSkia& image, |
323 int x, | 325 int x, |
324 int y, | 326 int y, |
325 const SkPaint& paint) { | 327 const SkPaint& paint) { |
326 const ImageSkiaRep& image_rep = GetImageRepToPaint(image); | 328 const ImageSkiaRep& image_rep = GetImageRepToPaint(image); |
327 if (image_rep.is_null()) | 329 if (image_rep.is_null()) |
328 return; | 330 return; |
329 const SkBitmap& bitmap = image_rep.sk_bitmap(); | 331 const SkBitmap& bitmap = image_rep.sk_bitmap(); |
330 float bitmap_scale = image_rep.scale(); | 332 float bitmap_scale = image_rep.GetScale(); |
331 | 333 |
332 canvas_->save(); | 334 canvas_->save(); |
333 canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale), | 335 canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale), |
334 SkFloatToScalar(1.0f / bitmap_scale)); | 336 SkFloatToScalar(1.0f / bitmap_scale)); |
335 canvas_->drawBitmap(bitmap, | 337 canvas_->drawBitmap(bitmap, |
336 SkFloatToScalar(x * bitmap_scale), | 338 SkFloatToScalar(x * bitmap_scale), |
337 SkFloatToScalar(y * bitmap_scale), | 339 SkFloatToScalar(y * bitmap_scale), |
338 &paint); | 340 &paint); |
339 canvas_->restore(); | 341 canvas_->restore(); |
340 } | 342 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 if (image_rep.is_null()) | 385 if (image_rep.is_null()) |
384 return; | 386 return; |
385 | 387 |
386 SkRect dest_rect = { SkIntToScalar(dest_x), | 388 SkRect dest_rect = { SkIntToScalar(dest_x), |
387 SkIntToScalar(dest_y), | 389 SkIntToScalar(dest_y), |
388 SkIntToScalar(dest_x + dest_w), | 390 SkIntToScalar(dest_x + dest_w), |
389 SkIntToScalar(dest_y + dest_h) }; | 391 SkIntToScalar(dest_y + dest_h) }; |
390 | 392 |
391 if (src_w == dest_w && src_h == dest_h && | 393 if (src_w == dest_w && src_h == dest_h && |
392 user_scale_x == 1.0f && user_scale_y == 1.0f && | 394 user_scale_x == 1.0f && user_scale_y == 1.0f && |
393 image_rep.scale() == 1.0f) { | 395 image_rep.scale_factor() == ui::SCALE_FACTOR_100P) { |
394 // Workaround for apparent bug in Skia that causes image to occasionally | 396 // Workaround for apparent bug in Skia that causes image to occasionally |
395 // shift. | 397 // shift. |
396 SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; | 398 SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; |
397 const SkBitmap& bitmap = image_rep.sk_bitmap(); | 399 const SkBitmap& bitmap = image_rep.sk_bitmap(); |
398 canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); | 400 canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); |
399 return; | 401 return; |
400 } | 402 } |
401 | 403 |
402 // Make a bitmap shader that contains the bitmap we want to draw. This is | 404 // Make a bitmap shader that contains the bitmap we want to draw. This is |
403 // basically what SkCanvas.drawBitmap does internally, but it gives us | 405 // basically what SkCanvas.drawBitmap does internally, but it gives us |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 } | 567 } |
566 | 568 |
567 void Canvas::EndPlatformPaint() { | 569 void Canvas::EndPlatformPaint() { |
568 skia::EndPlatformPaint(canvas_); | 570 skia::EndPlatformPaint(canvas_); |
569 } | 571 } |
570 | 572 |
571 void Canvas::Transform(const gfx::Transform& transform) { | 573 void Canvas::Transform(const gfx::Transform& transform) { |
572 canvas_->concat(transform.matrix()); | 574 canvas_->concat(transform.matrix()); |
573 } | 575 } |
574 | 576 |
575 Canvas::Canvas(SkCanvas* canvas, float image_scale) | 577 Canvas::Canvas(SkCanvas* canvas, ui::ScaleFactor scale_factor) |
576 : image_scale_(image_scale), | 578 : scale_factor_(scale_factor), |
577 owned_canvas_(), | 579 owned_canvas_(), |
578 canvas_(canvas) { | 580 canvas_(canvas) { |
579 DCHECK(canvas); | 581 DCHECK(canvas); |
580 } | 582 } |
581 | 583 |
582 bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { | 584 bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { |
583 SkRect clip; | 585 SkRect clip; |
584 return canvas_->getClipBounds(&clip) && | 586 return canvas_->getClipBounds(&clip) && |
585 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), | 587 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), |
586 SkIntToScalar(y + h)); | 588 SkIntToScalar(y + h)); |
587 } | 589 } |
588 | 590 |
589 bool Canvas::IntersectsClipRect(const Rect& rect) { | 591 bool Canvas::IntersectsClipRect(const Rect& rect) { |
590 return IntersectsClipRectInt(rect.x(), rect.y(), | 592 return IntersectsClipRectInt(rect.x(), rect.y(), |
591 rect.width(), rect.height()); | 593 rect.width(), rect.height()); |
592 } | 594 } |
593 | 595 |
594 const ImageSkiaRep& Canvas::GetImageRepToPaint(const ImageSkia& image) const { | 596 const ImageSkiaRep& Canvas::GetImageRepToPaint(const ImageSkia& image) const { |
595 return GetImageRepToPaint(image, 1.0f, 1.0f); | 597 return GetImageRepToPaint(image, 1.0f, 1.0f); |
596 } | 598 } |
597 | 599 |
598 const ImageSkiaRep& Canvas::GetImageRepToPaint( | 600 const ImageSkiaRep& Canvas::GetImageRepToPaint( |
599 const ImageSkia& image, | 601 const ImageSkia& image, |
600 float user_additional_scale_x, | 602 float user_additional_scale_x, |
601 float user_additional_scale_y) const { | 603 float user_additional_scale_y) const { |
602 const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); | 604 const ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor_); |
603 | 605 |
604 if (!image_rep.is_null()) { | 606 if (!image_rep.is_null()) { |
605 SkMatrix m = canvas_->getTotalMatrix(); | 607 SkMatrix m = canvas_->getTotalMatrix(); |
606 float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) * | 608 float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) * |
607 user_additional_scale_x; | 609 user_additional_scale_x; |
608 float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) * | 610 float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) * |
609 user_additional_scale_y; | 611 user_additional_scale_y; |
610 | 612 |
611 float bitmap_scale = image_rep.scale(); | 613 float bitmap_scale = image_rep.GetScale(); |
612 if (scale_x < bitmap_scale || scale_y < bitmap_scale) | 614 if (scale_x < bitmap_scale || scale_y < bitmap_scale) |
613 const_cast<SkBitmap&>(image_rep.sk_bitmap()).buildMipMap(); | 615 const_cast<SkBitmap&>(image_rep.sk_bitmap()).buildMipMap(); |
614 } | 616 } |
615 | 617 |
616 return image_rep; | 618 return image_rep; |
617 } | 619 } |
618 | 620 |
619 } // namespace gfx | 621 } // namespace gfx |
OLD | NEW |