| 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 <cmath> | 7 #include <cmath> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 skia::CreatePlatformCanvas(image_rep.pixel_width(), | 47 skia::CreatePlatformCanvas(image_rep.pixel_width(), |
| 48 image_rep.pixel_height(), | 48 image_rep.pixel_height(), |
| 49 is_opaque))), | 49 is_opaque))), |
| 50 canvas_(owned_canvas_.get()) { | 50 canvas_(owned_canvas_.get()) { |
| 51 SkScalar scale_scalar = SkFloatToScalar(image_scale_); | 51 SkScalar scale_scalar = SkFloatToScalar(image_scale_); |
| 52 canvas_->scale(scale_scalar, scale_scalar); | 52 canvas_->scale(scale_scalar, scale_scalar); |
| 53 DrawImageInt(ImageSkia(image_rep), 0, 0); | 53 DrawImageInt(ImageSkia(image_rep), 0, 0); |
| 54 } | 54 } |
| 55 | 55 |
| 56 Canvas::Canvas() | 56 Canvas::Canvas() |
| 57 : image_scale_(1.0), | 57 : image_scale_(1.f), |
| 58 owned_canvas_(skia::AdoptRef(skia::CreatePlatformCanvas(0, 0, false))), | 58 owned_canvas_(skia::AdoptRef(skia::CreatePlatformCanvas(0, 0, false))), |
| 59 canvas_(owned_canvas_.get()) { | 59 canvas_(owned_canvas_.get()) {} |
| 60 } | |
| 61 | 60 |
| 62 Canvas::Canvas(SkCanvas* canvas, float image_scale) | 61 Canvas::Canvas(SkCanvas* canvas, float image_scale) |
| 63 : image_scale_(image_scale), owned_canvas_(), canvas_(canvas) { | 62 : image_scale_(image_scale), owned_canvas_(), canvas_(canvas) { |
| 64 DCHECK(canvas); | 63 DCHECK(canvas); |
| 65 } | 64 } |
| 66 | 65 |
| 67 Canvas::~Canvas() { | 66 Canvas::~Canvas() { |
| 68 } | 67 } |
| 69 | 68 |
| 70 void Canvas::RecreateBackingCanvas(const Size& size, | 69 void Canvas::RecreateBackingCanvas(const Size& size, |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 int src_x, | 377 int src_x, |
| 379 int src_y, | 378 int src_y, |
| 380 int src_w, | 379 int src_w, |
| 381 int src_h, | 380 int src_h, |
| 382 int dest_x, | 381 int dest_x, |
| 383 int dest_y, | 382 int dest_y, |
| 384 int dest_w, | 383 int dest_w, |
| 385 int dest_h, | 384 int dest_h, |
| 386 bool filter, | 385 bool filter, |
| 387 const SkPaint& paint) { | 386 const SkPaint& paint) { |
| 388 DrawImageIntHelper(image, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, | 387 const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); |
| 389 dest_h, filter, paint, image_scale_, false); | 388 if (image_rep.is_null()) |
| 389 return; |
| 390 DrawImageIntHelper(image_rep, src_x, src_y, src_w, src_h, dest_x, dest_y, |
| 391 dest_w, dest_h, filter, paint, false); |
| 390 } | 392 } |
| 391 | 393 |
| 392 void Canvas::DrawImageIntInPixel(const ImageSkia& image, | 394 void Canvas::DrawImageIntInPixel(const ImageSkiaRep& image_rep, |
| 393 int src_x, | |
| 394 int src_y, | |
| 395 int src_w, | |
| 396 int src_h, | |
| 397 int dest_x, | 395 int dest_x, |
| 398 int dest_y, | 396 int dest_y, |
| 399 int dest_w, | 397 int dest_w, |
| 400 int dest_h, | 398 int dest_h, |
| 401 bool filter, | 399 bool filter, |
| 402 const SkPaint& paint) { | 400 const SkPaint& paint) { |
| 403 // All values passed into this function are in pixels, i.e. no scaling needs | 401 int src_x = 0; |
| 404 // be done. | 402 int src_y = 0; |
| 405 // Logic as below:- | 403 int src_w = image_rep.pixel_width(); |
| 406 // 1. Get the matrix transform from the canvas. | 404 int src_h = image_rep.pixel_height(); |
| 407 // 2. Set the scale in the matrix to 1.0 while honoring the direction of the | 405 DrawImageIntHelper(image_rep, src_x, src_y, src_w, src_h, dest_x, dest_y, |
| 408 // the scale (x/y). Example RTL layouts. | 406 dest_w, dest_h, filter, paint, true); |
| 409 // 3. Round off the X and Y translation components in the matrix. This is to | |
| 410 // reduce floating point errors during rect transformation. This is needed | |
| 411 // for fractional scale factors like 1.25/1.5, etc. | |
| 412 // 4. Save the current state of the canvas and restore the state when going | |
| 413 // out of scope with ScopedCanvas. | |
| 414 // 5. Set the modified matrix in the canvas. This ensures that no scaling | |
| 415 // will be done for draw operations on the canvas. | |
| 416 // 6. Draw the image. | |
| 417 SkMatrix matrix = canvas_->getTotalMatrix(); | |
| 418 | |
| 419 // Ensure that the direction of the x and y scales is preserved. This is | |
| 420 // important for RTL layouts. | |
| 421 matrix.setScaleX(matrix.getScaleX() > 0 ? 1.0f : -1.0f); | |
| 422 matrix.setScaleY(matrix.getScaleY() > 0 ? 1.0f : -1.0f); | |
| 423 | |
| 424 // Floor so that we get consistent rounding. | |
| 425 matrix.setTranslateX(SkScalarFloorToScalar(matrix.getTranslateX())); | |
| 426 matrix.setTranslateY(SkScalarFloorToScalar(matrix.getTranslateY())); | |
| 427 | |
| 428 ScopedCanvas scoper(this); | |
| 429 | |
| 430 canvas_->setMatrix(matrix); | |
| 431 | |
| 432 DrawImageIntHelper(image, | |
| 433 src_x, | |
| 434 src_y, | |
| 435 src_w, | |
| 436 src_h, | |
| 437 dest_x, | |
| 438 dest_y, | |
| 439 dest_w, | |
| 440 dest_h, | |
| 441 filter, | |
| 442 paint, | |
| 443 image_scale_, | |
| 444 true); | |
| 445 } | 407 } |
| 446 | 408 |
| 447 void Canvas::DrawImageInPath(const ImageSkia& image, | 409 void Canvas::DrawImageInPath(const ImageSkia& image, |
| 448 int x, | 410 int x, |
| 449 int y, | 411 int y, |
| 450 const SkPath& path, | 412 const SkPath& path, |
| 451 const SkPaint& paint) { | 413 const SkPaint& paint) { |
| 452 const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); | 414 const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); |
| 453 if (image_rep.is_null()) | 415 if (image_rep.is_null()) |
| 454 return; | 416 return; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 return canvas_->getClipBounds(&clip) && | 517 return canvas_->getClipBounds(&clip) && |
| 556 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), | 518 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), |
| 557 SkIntToScalar(y + h)); | 519 SkIntToScalar(y + h)); |
| 558 } | 520 } |
| 559 | 521 |
| 560 bool Canvas::IntersectsClipRect(const Rect& rect) { | 522 bool Canvas::IntersectsClipRect(const Rect& rect) { |
| 561 return IntersectsClipRectInt(rect.x(), rect.y(), | 523 return IntersectsClipRectInt(rect.x(), rect.y(), |
| 562 rect.width(), rect.height()); | 524 rect.width(), rect.height()); |
| 563 } | 525 } |
| 564 | 526 |
| 565 void Canvas::DrawImageIntHelper(const ImageSkia& image, | 527 void Canvas::DrawImageIntHelper(const ImageSkiaRep& image_rep, |
| 566 int src_x, | 528 int src_x, |
| 567 int src_y, | 529 int src_y, |
| 568 int src_w, | 530 int src_w, |
| 569 int src_h, | 531 int src_h, |
| 570 int dest_x, | 532 int dest_x, |
| 571 int dest_y, | 533 int dest_y, |
| 572 int dest_w, | 534 int dest_w, |
| 573 int dest_h, | 535 int dest_h, |
| 574 bool filter, | 536 bool filter, |
| 575 const SkPaint& paint, | 537 const SkPaint& paint, |
| 576 float image_scale, | |
| 577 bool pixel) { | 538 bool pixel) { |
| 578 DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && | 539 DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && |
| 579 src_y + src_h < std::numeric_limits<int16_t>::max()); | 540 src_y + src_h < std::numeric_limits<int16_t>::max()); |
| 580 if (src_w <= 0 || src_h <= 0) { | 541 if (src_w <= 0 || src_h <= 0) { |
| 581 NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; | 542 NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; |
| 582 return; | 543 return; |
| 583 } | 544 } |
| 584 | 545 |
| 585 if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) | 546 if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) |
| 586 return; | 547 return; |
| 587 | 548 |
| 588 float user_scale_x = static_cast<float>(dest_w) / src_w; | 549 float user_scale_x = static_cast<float>(dest_w) / src_w; |
| 589 float user_scale_y = static_cast<float>(dest_h) / src_h; | 550 float user_scale_y = static_cast<float>(dest_h) / src_h; |
| 590 | 551 |
| 591 const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale); | |
| 592 if (image_rep.is_null()) | |
| 593 return; | |
| 594 | |
| 595 SkRect dest_rect = { SkIntToScalar(dest_x), | 552 SkRect dest_rect = { SkIntToScalar(dest_x), |
| 596 SkIntToScalar(dest_y), | 553 SkIntToScalar(dest_y), |
| 597 SkIntToScalar(dest_x + dest_w), | 554 SkIntToScalar(dest_x + dest_w), |
| 598 SkIntToScalar(dest_y + dest_h) }; | 555 SkIntToScalar(dest_y + dest_h) }; |
| 599 | 556 |
| 600 if (src_w == dest_w && src_h == dest_h && | 557 if (src_w == dest_w && src_h == dest_h && |
| 601 user_scale_x == 1.0f && user_scale_y == 1.0f && | 558 user_scale_x == 1.0f && user_scale_y == 1.0f && |
| 602 image_rep.scale() == 1.0f && !pixel) { | 559 image_rep.scale() == 1.0f && !pixel) { |
| 603 // Workaround for apparent bug in Skia that causes image to occasionally | 560 // Workaround for apparent bug in Skia that causes image to occasionally |
| 604 // shift. | 561 // shift. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 628 // by the paint). | 585 // by the paint). |
| 629 SkPaint p(paint); | 586 SkPaint p(paint); |
| 630 p.setFilterQuality(filter ? kLow_SkFilterQuality : kNone_SkFilterQuality); | 587 p.setFilterQuality(filter ? kLow_SkFilterQuality : kNone_SkFilterQuality); |
| 631 p.setShader(shader.get()); | 588 p.setShader(shader.get()); |
| 632 | 589 |
| 633 // The rect will be filled by the bitmap. | 590 // The rect will be filled by the bitmap. |
| 634 canvas_->drawRect(dest_rect, p); | 591 canvas_->drawRect(dest_rect, p); |
| 635 } | 592 } |
| 636 | 593 |
| 637 } // namespace gfx | 594 } // namespace gfx |
| OLD | NEW |