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