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