15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <cmath> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/effects/SkGradientShader.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/gfx/font_list.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/gfx/geometry/rect_conversions.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/transform.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas_skia_paint.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Canvas::Canvas(const Size& size, float image_scale, bool is_opaque) 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : image_scale_(image_scale), 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) canvas_(NULL) { 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Size pixel_size = ToCeiledSize(ScaleSize(size, image_scale)); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pixel_size.height(), 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_opaque)); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_ = owned_canvas_.get(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uninitialized on Win and Mac. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_opaque) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SkScalar scale_scalar = SkFloatToScalar(image_scale); 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) canvas_->scale(scale_scalar, scale_scalar); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Canvas::Canvas(const ImageSkiaRep& image_rep, bool is_opaque) 4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : image_scale_(image_rep.scale()), 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_(skia::AdoptRef( 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::CreatePlatformCanvas(image_rep.pixel_width(), 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_rep.pixel_height(), 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_opaque))), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_(owned_canvas_.get()) { 5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SkScalar scale_scalar = SkFloatToScalar(image_scale_); 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) canvas_->scale(scale_scalar, scale_scalar); 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DrawImageInt(ImageSkia(image_rep), 0, 0); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas::Canvas() 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : image_scale_(1.0), 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_(skia::AdoptRef(skia::CreatePlatformCanvas(0, 0, false))), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_(owned_canvas_.get()) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas::~Canvas() { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) float image_scale) { 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return new Canvas(canvas, image_scale); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::RecreateBackingCanvas(const Size& size, 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) float image_scale, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque) { 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) image_scale_ = image_scale; 7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Size pixel_size = ToFlooredSize(ScaleSize(size, image_scale)); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pixel_size.height(), 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_opaque)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_ = owned_canvas_.get(); 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SkScalar scale_scalar = SkFloatToScalar(image_scale); 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) canvas_->scale(scale_scalar, scale_scalar); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::SizeStringInt(const base::string16& text, 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FontList& font_list, 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* width, 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* height, 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int line_height, 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int flags) { 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) float fractional_width = *width; 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) float factional_height = *height; 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SizeStringFloat(text, font_list, &fractional_width, 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &factional_height, line_height, flags); 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *width = std::ceil(fractional_width); 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *height = std::ceil(factional_height); 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int Canvas::GetStringWidth(const base::string16& text, 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FontList& font_list) { 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int width = 0, height = 0; 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SizeStringInt(text, font_list, &width, &height, 0, NO_ELLIPSIS); 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return width; 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// static 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)float Canvas::GetStringWidthF(const base::string16& text, 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FontList& font_list) { 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) float width = 0, height = 0; 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SizeStringFloat(text, font_list, &width, &height, 0, NO_ELLIPSIS); 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return width; 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Canvas::DefaultCanvasTextAlignment() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::i18n::IsRTL() ? TEXT_ALIGN_RIGHT : TEXT_ALIGN_LEFT; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ImageSkiaRep Canvas::ExtractImageRep() const { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a bitmap to return, and a canvas to draw into it. We don't just want 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to call extractSubset or the copy constructor, since we want an actual copy 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the bitmap. 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const SkISize size = canvas_->getDeviceSize(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap result; 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result.allocN32Pixels(size.width(), size.height()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) canvas_->readPixels(&result, 0, 0); 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ImageSkiaRep(result, image_scale_); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawDashedRect(const Rect& rect, SkColor color) { 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (rect.IsEmpty()) 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a 2D bitmap containing alternating on/off pixels - we do this 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that you never get two pixels of the same color around the edges 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the focus rect (this may mean that opposing edges of the rect may 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have a dot pattern out of phase to each other). 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SkColor last_color; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SkBitmap* dots = NULL; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dots || last_color != color) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int col_pixels = 32; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int row_pixels = 32; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete dots; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_color = color; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dots = new SkBitmap; 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dots->allocN32Pixels(col_pixels, row_pixels); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dots->eraseARGB(0, 0, 0, 0); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* dot = dots->getAddr32(0, 0); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < row_pixels; i++) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int u = 0; u < col_pixels; u++) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((u % 2 + i % 2) % 2 != 0) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dot[i * row_pixels + u] = color; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a shader for the bitmap with an origin of the box we'll draw. This 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shader is refcounted and will have an initial refcount of 1. 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::RefPtr<SkShader> shader = skia::AdoptRef( 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkShader::CreateBitmapShader( 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *dots, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assign the shader to the paint & release our reference. The paint will 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now own the shader and the shader will be destroyed when the paint goes 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // out of scope. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint.setShader(shader.get()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DrawRect(Rect(rect.x(), rect.y(), rect.width(), 1), paint); 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DrawRect(Rect(rect.x(), rect.y() + rect.height() - 1, rect.width(), 1), 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint); 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DrawRect(Rect(rect.x(), rect.y(), 1, rect.height()), paint); 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DrawRect(Rect(rect.x() + rect.width() - 1, rect.y(), 1, rect.height()), 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Save() { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->save(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::SaveLayerAlpha(uint8 alpha) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->saveLayerAlpha(NULL, alpha); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::SaveLayerAlpha(uint8 alpha, const Rect& layer_bounds) { 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SkRect bounds(RectToSkRect(layer_bounds)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->saveLayerAlpha(&bounds, alpha); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Restore() { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->restore(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void Canvas::ClipRect(const Rect& rect) { 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) canvas_->clipRect(RectToSkRect(rect)); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Canvas::ClipPath(const SkPath& path, bool do_anti_alias) { 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canvas_->clipPath(path, SkRegion::kIntersect_Op, do_anti_alias); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool Canvas::IsClipEmpty() const { 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return canvas_->isClipEmpty(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool Canvas::GetClipBounds(Rect* bounds) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect out; 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (canvas_->getClipBounds(&out)) { 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bounds = ToEnclosingRect(SkRectToRectF(out)); 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bounds = gfx::Rect(); 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::Translate(const Vector2d& offset) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->translate(SkIntToScalar(offset.x()), SkIntToScalar(offset.y())); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Scale(int x_scale, int y_scale) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->scale(SkIntToScalar(x_scale), SkIntToScalar(y_scale)); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawColor(SkColor color) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawColor(color, SkXfermode::kSrcOver_Mode); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawColor(SkColor color, SkXfermode::Mode mode) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawColor(color, mode); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::FillRect(const Rect& rect, SkColor color) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRect(rect, color, SkXfermode::kSrcOver_Mode); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::FillRect(const Rect& rect, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkXfermode::Mode mode) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setColor(color); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStyle(SkPaint::kFill_Style); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setXfermodeMode(mode); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(rect, paint); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawRect(const Rect& rect, SkColor color) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(rect, color, SkXfermode::kSrcOver_Mode); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawRect(const Rect& rect, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkXfermode::Mode mode) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setColor(color); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStyle(SkPaint::kStroke_Style); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set a stroke width of 0, which will put us down the stroke rect path. If 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we set a stroke width of 1, for example, this will internally create a 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // path and fill it, which causes problems near the edge of the canvas. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStrokeWidth(SkIntToScalar(0)); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setXfermodeMode(mode); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(rect, paint); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawRect(const Rect& rect, const SkPaint& paint) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawIRect(RectToSkIRect(rect), paint); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawPoint(const Point& p1, const SkPaint& paint) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawPoint(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()), paint); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawLine(const Point& p1, const Point& p2, SkColor color) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setColor(color); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStrokeWidth(SkIntToScalar(1)); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawLine(p1, p2, paint); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawLine(const Point& p1, const Point& p2, const SkPaint& paint) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawLine(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()), 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(p2.x()), SkIntToScalar(p2.y()), paint); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawCircle(const Point& center_point, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int radius, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawCircle(SkIntToScalar(center_point.x()), 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(center_point.y()), SkIntToScalar(radius), paint); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawRoundRect(const Rect& rect, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int radius, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawRoundRect(RectToSkRect(rect), SkIntToScalar(radius), 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(radius), paint); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawPath(const SkPath& path, const SkPaint& paint) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawPath(path, paint); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawFocusRect(const Rect& rect) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawDashedRect(rect, SK_ColorGRAY); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void Canvas::DrawSolidFocusRect(const Rect& rect, SkColor color) { 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkPaint paint; 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) paint.setColor(color); 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) paint.setStrokeWidth(SkIntToScalar(1)); 316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Note: We cannot use DrawRect since it would create a path and fill it which 317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // would cause problems near the edge of the canvas. 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int x1 = std::min(rect.x(), rect.right()); 319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int x2 = std::max(rect.x(), rect.right()); 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int y1 = std::min(rect.y(), rect.bottom()); 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int y2 = std::max(rect.y(), rect.bottom()); 322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DrawLine(Point(x1, y1), Point(x2, y1), paint); 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DrawLine(Point(x1, y2), Point(x2, y2), paint); 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DrawLine(Point(x1, y1), Point(x1, y2), paint); 325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DrawLine(Point(x2, y1), Point(x2, y2 + 1), paint); 326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawImageInt(const ImageSkia& image, int x, int y) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawImageInt(image, x, y, paint); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawImageInt(const ImageSkia& image, int x, int y, uint8 a) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setAlpha(a); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawImageInt(image, x, y, paint); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawImageInt(const ImageSkia& image, 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int x, 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int y, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_rep.is_null()) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& bitmap = image_rep.sk_bitmap(); 34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) float bitmap_scale = image_rep.scale(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->save(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale), 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(1.0f / bitmap_scale)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawBitmap(bitmap, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(x * bitmap_scale), 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(y * bitmap_scale), 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &paint); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->restore(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawImageInt(const ImageSkia& image, 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_x, 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_y, 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_w, 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_h, 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_x, 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_y, 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_w, 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_h, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool filter) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint p; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawImageInt(image, src_x, src_y, src_w, src_h, dest_x, dest_y, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_w, dest_h, filter, p); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawImageInt(const ImageSkia& image, 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_x, 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_y, 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_w, 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_h, 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_x, 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_y, 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_w, 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_h, 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool filter, 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DrawImageIntHelper(image, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, 386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dest_h, filter, paint, image_scale_, false); 387010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void Canvas::DrawImageIntInPixel(const ImageSkia& image, 390010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_x, 391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_y, 392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_w, 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_h, 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_x, 395010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_y, 396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_w, 397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_h, 398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool filter, 399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const SkPaint& paint) { 40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // All values passed into this function are in pixels, i.e. no scaling needs 40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // be done. 402010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Logic as below:- 40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 1. Get the matrix transform from the canvas. 40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 2. Set the scale in the matrix to 1.0 while honoring the direction of the 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the scale (x/y). Example RTL layouts. 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 3. Round off the X and Y translation components in the matrix. This is to 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // reduce floating point errors during rect transformation. This is needed 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // for fractional scale factors like 1.25/1.5, etc. 40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 4. Save the current state of the canvas. 41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 5. Set the modified matrix in the canvas. This ensures that no scaling 41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // will be done for draw operations on the canvas. 41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 6. Draw the image. 41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 7. Restore the state of the canvas and the SkCanvas matrix stack. 414010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkMatrix matrix = canvas_->getTotalMatrix(); 415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Ensure that the direction of the x and y scales is preserved. This is 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // important for RTL layouts. 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) matrix.getScaleX() > 0 ? matrix.setScaleX(1.0f) : matrix.setScaleX(-1.0f); 41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) matrix.getScaleY() > 0 ? matrix.setScaleY(1.0f) : matrix.setScaleY(-1.0f); 42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) matrix.setTranslateX(SkScalarRoundToInt(matrix.getTranslateX())); 42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) matrix.setTranslateY(SkScalarRoundToInt(matrix.getTranslateY())); 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 424010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Save(); 425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 426010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) canvas_->setMatrix(matrix); 427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 428010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DrawImageIntHelper(image, 429010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) src_x, 430010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) src_y, 431010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) src_w, 432010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) src_h, 43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) dest_x, 43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) dest_y, 43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) dest_w, 43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) dest_h, 437010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) filter, 438010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) paint, 439010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) image_scale_, 440010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true); 441010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 442010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Restore the state of the canvas. 443010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Restore(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawImageInPath(const ImageSkia& image, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPath& path, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_rep.is_null()) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix matrix; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) skia::RefPtr<SkShader> shader = CreateImageRepShader( 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_rep, 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkShader::kRepeat_TileMode, 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) matrix); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint p(paint); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p.setShader(shader.get()); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawPath(path, p); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawStringRect(const base::string16& text, 4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FontList& font_list, 4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SkColor color, 4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Rect& display_rect) { 4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DrawStringRectWithFlags(text, font_list, color, display_rect, 4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DefaultCanvasTextAlignment()); 4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::DrawStringRectWithFlags(const base::string16& text, 4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FontList& font_list, 4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SkColor color, 4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Rect& display_rect, 4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int flags) { 4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DrawStringRectWithShadows(text, font_list, color, display_rect, 0, flags, 4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ShadowValues()); 4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::TileImageInt(const ImageSkia& image, 4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int x, 4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int y, 4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int w, 4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int h) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TileImageInt(image, 0, 0, x, y, w, h); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::TileImageInt(const ImageSkia& image, 4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_x, 4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_y, 4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_x, 4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_y, 4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int w, 4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int h) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TileImageInt(image, src_x, src_y, 1.0f, 1.0f, dest_x, dest_y, w, h); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void Canvas::TileImageInt(const ImageSkia& image, 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_x, 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int src_y, 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) float tile_scale_x, 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) float tile_scale_y, 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_x, 5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int dest_y, 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int w, 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int h) { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IntersectsClipRectInt(dest_x, dest_y, w, h)) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_rep.is_null()) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix shader_scale; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.setScale(SkFloatToScalar(tile_scale_x), 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(tile_scale_y)); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) skia::RefPtr<SkShader> shader = CreateImageRepShader( 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_rep, 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkShader::kRepeat_TileMode, 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shader_scale); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint.setShader(shader.get()); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect dest_rect = { SkIntToScalar(dest_x), 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_y), 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_x + w), 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_y + h) }; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawRect(dest_rect, paint); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)NativeDrawingContext Canvas::BeginPlatformPaint() { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skia::BeginPlatformPaint(canvas_); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::EndPlatformPaint() { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::EndPlatformPaint(canvas_); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Transform(const gfx::Transform& transform) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->concat(transform.matrix()); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Canvas::Canvas(SkCanvas* canvas, float image_scale) 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : image_scale_(image_scale), 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owned_canvas_(), 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_(canvas) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(canvas); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect clip; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas_->getClipBounds(&clip) && 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(y + h)); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool Canvas::IntersectsClipRect(const Rect& rect) { 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IntersectsClipRectInt(rect.x(), rect.y(), 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect.width(), rect.height()); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void Canvas::DrawImageIntHelper(const ImageSkia& image, 572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_x, 573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_y, 574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_w, 575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int src_h, 576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_x, 577010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_y, 578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_w, 579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int dest_h, 580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool filter, 581010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const SkPaint& paint, 582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) float image_scale, 583010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool pixel) { 584010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && 585010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) src_y + src_h < std::numeric_limits<int16_t>::max()); 586010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (src_w <= 0 || src_h <= 0) { 587010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; 588010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 589010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 590010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 591010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) 592010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 593010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 594010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) float user_scale_x = static_cast<float>(dest_w) / src_w; 595010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) float user_scale_y = static_cast<float>(dest_h) / src_h; 596010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale); 598010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (image_rep.is_null()) 599010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 600010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 601010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkRect dest_rect = { SkIntToScalar(dest_x), 602010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkIntToScalar(dest_y), 603010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkIntToScalar(dest_x + dest_w), 604010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkIntToScalar(dest_y + dest_h) }; 605010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 606010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (src_w == dest_w && src_h == dest_h && 607010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) user_scale_x == 1.0f && user_scale_y == 1.0f && 608010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) image_rep.scale() == 1.0f && !pixel) { 609010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Workaround for apparent bug in Skia that causes image to occasionally 610010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // shift. 611010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; 612010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const SkBitmap& bitmap = image_rep.sk_bitmap(); 613010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); 614010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 615010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 616010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 617010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Make a bitmap shader that contains the bitmap we want to draw. This is 618010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // basically what SkCanvas.drawBitmap does internally, but it gives us 619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // more control over quality and will use the mipmap in the source image if 620010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // it has one, whereas drawBitmap won't. 621010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkMatrix shader_scale; 622010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) shader_scale.setScale(SkFloatToScalar(user_scale_x), 623010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkFloatToScalar(user_scale_y)); 624010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); 625010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); 626010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 627010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) skia::RefPtr<SkShader> shader = CreateImageRepShaderForScale( 628010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) image_rep, 629010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkShader::kRepeat_TileMode, 630010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) shader_scale, 631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) pixel ? 1.0f : image_rep.scale()); 632010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 633010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Set up our paint to use the shader & release our reference (now just owned 634010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // by the paint). 635010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkPaint p(paint); 636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) p.setFilterLevel(filter ? SkPaint::kLow_FilterLevel 637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : SkPaint::kNone_FilterLevel); 638010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) p.setShader(shader.get()); 639010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 640010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The rect will be filled by the bitmap. 641010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) canvas_->drawRect(dest_rect, p); 642010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 643010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 645