Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: ui/gfx/canvas.cc

Issue 1424983005: ui: Fix NinePatchPainter to work in physical pixels. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ninepatchscale: testreview Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/canvas.h ('k') | ui/gfx/nine_image_painter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 return canvas_->getClipBounds(&clip) && 509 return canvas_->getClipBounds(&clip) &&
548 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), 510 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w),
549 SkIntToScalar(y + h)); 511 SkIntToScalar(y + h));
550 } 512 }
551 513
552 bool Canvas::IntersectsClipRect(const Rect& rect) { 514 bool Canvas::IntersectsClipRect(const Rect& rect) {
553 return IntersectsClipRectInt(rect.x(), rect.y(), 515 return IntersectsClipRectInt(rect.x(), rect.y(),
554 rect.width(), rect.height()); 516 rect.width(), rect.height());
555 } 517 }
556 518
557 void Canvas::DrawImageIntHelper(const ImageSkia& image, 519 void Canvas::DrawImageIntHelper(const ImageSkiaRep& image_rep,
558 int src_x, 520 int src_x,
559 int src_y, 521 int src_y,
560 int src_w, 522 int src_w,
561 int src_h, 523 int src_h,
562 int dest_x, 524 int dest_x,
563 int dest_y, 525 int dest_y,
564 int dest_w, 526 int dest_w,
565 int dest_h, 527 int dest_h,
566 bool filter, 528 bool filter,
567 const SkPaint& paint, 529 const SkPaint& paint,
568 float image_scale,
569 bool pixel) { 530 bool pixel) {
570 DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && 531 DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() &&
571 src_y + src_h < std::numeric_limits<int16_t>::max()); 532 src_y + src_h < std::numeric_limits<int16_t>::max());
572 if (src_w <= 0 || src_h <= 0) { 533 if (src_w <= 0 || src_h <= 0) {
573 NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; 534 NOTREACHED() << "Attempting to draw bitmap from an empty rect!";
574 return; 535 return;
575 } 536 }
576 537
577 if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) 538 if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h))
578 return; 539 return;
579 540
580 float user_scale_x = static_cast<float>(dest_w) / src_w; 541 float user_scale_x = static_cast<float>(dest_w) / src_w;
581 float user_scale_y = static_cast<float>(dest_h) / src_h; 542 float user_scale_y = static_cast<float>(dest_h) / src_h;
582 543
583 const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale);
584 if (image_rep.is_null())
585 return;
586
587 SkRect dest_rect = { SkIntToScalar(dest_x), 544 SkRect dest_rect = { SkIntToScalar(dest_x),
588 SkIntToScalar(dest_y), 545 SkIntToScalar(dest_y),
589 SkIntToScalar(dest_x + dest_w), 546 SkIntToScalar(dest_x + dest_w),
590 SkIntToScalar(dest_y + dest_h) }; 547 SkIntToScalar(dest_y + dest_h) };
591 548
592 if (src_w == dest_w && src_h == dest_h && 549 if (src_w == dest_w && src_h == dest_h &&
593 user_scale_x == 1.0f && user_scale_y == 1.0f && 550 user_scale_x == 1.0f && user_scale_y == 1.0f &&
594 image_rep.scale() == 1.0f && !pixel) { 551 image_rep.scale() == 1.0f && !pixel) {
595 // Workaround for apparent bug in Skia that causes image to occasionally 552 // Workaround for apparent bug in Skia that causes image to occasionally
596 // shift. 553 // shift.
(...skipping 23 matching lines...) Expand all
620 // by the paint). 577 // by the paint).
621 SkPaint p(paint); 578 SkPaint p(paint);
622 p.setFilterQuality(filter ? kLow_SkFilterQuality : kNone_SkFilterQuality); 579 p.setFilterQuality(filter ? kLow_SkFilterQuality : kNone_SkFilterQuality);
623 p.setShader(shader.get()); 580 p.setShader(shader.get());
624 581
625 // The rect will be filled by the bitmap. 582 // The rect will be filled by the bitmap.
626 canvas_->drawRect(dest_rect, p); 583 canvas_->drawRect(dest_rect, p);
627 } 584 }
628 585
629 } // namespace gfx 586 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/canvas.h ('k') | ui/gfx/nine_image_painter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698