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) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/effects/SkGradientShader.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size_conversions.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/transform.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas_skia_paint.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas::Canvas(const gfx::Size& size, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : scale_factor_(scale_factor), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_(NULL) { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size pixel_size = gfx::ToCeiledSize( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pixel_size.height(), 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_opaque)); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_ = owned_canvas_.get(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uninitialized on Win and Mac. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_opaque) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor)); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->scale(scale, scale); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : scale_factor_(image_rep.scale_factor()), 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_(skia::AdoptRef( 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::CreatePlatformCanvas(image_rep.pixel_width(), 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_rep.pixel_height(), 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_opaque))), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_(owned_canvas_.get()) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->scale(scale, scale); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawImageInt(gfx::ImageSkia(image_rep), 0, 0); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas::Canvas() 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : scale_factor_(ui::SCALE_FACTOR_100P), 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_(skia::AdoptRef(skia::CreatePlatformCanvas(0, 0, false))), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_(owned_canvas_.get()) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas::~Canvas() { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas* Canvas::CreateCanvasWithoutScaling(SkCanvas* canvas, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new Canvas(canvas, scale_factor); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::RecreateBackingCanvas(const gfx::Size& size, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scale_factor_ = scale_factor; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size pixel_size = gfx::ToFlooredSize( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ScaleSize(size, ui::GetScaleFactorScale(scale_factor))); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) owned_canvas_ = skia::AdoptRef(skia::CreatePlatformCanvas(pixel_size.width(), 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pixel_size.height(), 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_opaque)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_ = owned_canvas_.get(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor_)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->scale(scale, scale); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int Canvas::GetStringWidth(const base::string16& text, const gfx::Font& font) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = 0, height = 0; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Canvas::SizeStringInt(text, font, &width, &height, 0, NO_ELLIPSIS); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return width; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Canvas::DefaultCanvasTextAlignment() { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::i18n::IsRTL() ? TEXT_ALIGN_RIGHT : TEXT_ALIGN_LEFT; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkiaRep Canvas::ExtractImageRep() const { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& device_bitmap = canvas_->getDevice()->accessBitmap(false); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a bitmap to return, and a canvas to draw into it. We don't just want 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to call extractSubset or the copy constructor, since we want an actual copy 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the bitmap. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap result; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::ImageSkiaRep(result, scale_factor_); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawDashedRect(const gfx::Rect& rect, SkColor color) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a 2D bitmap containing alternating on/off pixels - we do this 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that you never get two pixels of the same color around the edges 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the focus rect (this may mean that opposing edges of the rect may 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have a dot pattern out of phase to each other). 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SkColor last_color; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SkBitmap* dots = NULL; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dots || last_color != color) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int col_pixels = 32; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int row_pixels = 32; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete dots; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_color = color; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dots = new SkBitmap; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dots->setConfig(SkBitmap::kARGB_8888_Config, col_pixels, row_pixels); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dots->allocPixels(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dots->eraseARGB(0, 0, 0, 0); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* dot = dots->getAddr32(0, 0); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < row_pixels; i++) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int u = 0; u < col_pixels; u++) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((u % 2 + i % 2) % 2 != 0) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dot[i * row_pixels + u] = color; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a shader for the bitmap with an origin of the box we'll draw. This 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shader is refcounted and will have an initial refcount of 1. 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::RefPtr<SkShader> shader = skia::AdoptRef( 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkShader::CreateBitmapShader( 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *dots, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode)); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assign the shader to the paint & release our reference. The paint will 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now own the shader and the shader will be destroyed when the paint goes 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // out of scope. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint.setShader(shader.get()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(gfx::Rect(rect.x(), rect.y(), rect.width(), 1), paint); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(gfx::Rect(rect.x(), rect.y() + rect.height() - 1, rect.width(), 1), 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(gfx::Rect(rect.x(), rect.y(), 1, rect.height()), paint); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(gfx::Rect(rect.x() + rect.width() - 1, rect.y(), 1, rect.height()), 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Save() { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->save(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::SaveLayerAlpha(uint8 alpha) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->saveLayerAlpha(NULL, alpha); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect bounds(gfx::RectToSkRect(layer_bounds)); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->saveLayerAlpha(&bounds, alpha); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Restore() { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->restore(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Canvas::ClipRect(const gfx::Rect& rect) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas_->clipRect(gfx::RectToSkRect(rect)); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Canvas::ClipPath(const SkPath& path) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas_->clipPath(path); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Canvas::GetClipBounds(gfx::Rect* bounds) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect out; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_non_empty_clip = canvas_->getClipBounds(&out); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->SetRect(out.left(), out.top(), out.width(), out.height()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return has_non_empty_clip; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Translate(const gfx::Vector2d& offset) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->translate(SkIntToScalar(offset.x()), SkIntToScalar(offset.y())); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Scale(int x_scale, int y_scale) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->scale(SkIntToScalar(x_scale), SkIntToScalar(y_scale)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawColor(SkColor color) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawColor(color, SkXfermode::kSrcOver_Mode); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawColor(SkColor color, SkXfermode::Mode mode) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawColor(color, mode); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::FillRect(const gfx::Rect& rect, SkColor color) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRect(rect, color, SkXfermode::kSrcOver_Mode); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::FillRect(const gfx::Rect& rect, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkXfermode::Mode mode) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setColor(color); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStyle(SkPaint::kFill_Style); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setXfermodeMode(mode); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(rect, paint); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawRect(const gfx::Rect& rect, SkColor color) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(rect, color, SkXfermode::kSrcOver_Mode); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawRect(const gfx::Rect& rect, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkXfermode::Mode mode) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setColor(color); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStyle(SkPaint::kStroke_Style); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set a stroke width of 0, which will put us down the stroke rect path. If 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we set a stroke width of 1, for example, this will internally create a 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // path and fill it, which causes problems near the edge of the canvas. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStrokeWidth(SkIntToScalar(0)); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setXfermodeMode(mode); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawRect(rect, paint); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawRect(const gfx::Rect& rect, const SkPaint& paint) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawIRect(RectToSkIRect(rect), paint); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawPoint(const gfx::Point& p1, const SkPaint& paint) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawPoint(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()), paint); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawLine(const gfx::Point& p1, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& p2, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setColor(color); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setStrokeWidth(SkIntToScalar(1)); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawLine(p1, p2, paint); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawLine(const gfx::Point& p1, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& p2, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawLine(SkIntToScalar(p1.x()), SkIntToScalar(p1.y()), 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(p2.x()), SkIntToScalar(p2.y()), paint); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawCircle(const gfx::Point& center_point, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int radius, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawCircle(SkIntToScalar(center_point.x()), 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(center_point.y()), SkIntToScalar(radius), paint); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawRoundRect(const gfx::Rect& rect, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int radius, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawRoundRect(RectToSkRect(rect), SkIntToScalar(radius), 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(radius), paint); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawPath(const SkPath& path, const SkPaint& paint) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawPath(path, paint); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawFocusRect(const gfx::Rect& rect) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawDashedRect(rect, SK_ColorGRAY); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawImageInt(const gfx::ImageSkia& image, int x, int y) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawImageInt(image, x, y, paint); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawImageInt(const gfx::ImageSkia& image, int x, int y, uint8 a) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setAlpha(a); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawImageInt(image, x, y, paint); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawImageInt(const gfx::ImageSkia& image, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, int y, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_rep.is_null()) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& bitmap = image_rep.sk_bitmap(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float bitmap_scale = image_rep.GetScale(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->save(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale), 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(1.0f / bitmap_scale)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawBitmap(bitmap, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(x * bitmap_scale), 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(y * bitmap_scale), 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &paint); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->restore(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawImageInt(const gfx::ImageSkia& image, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int src_x, int src_y, int src_w, int src_h, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dest_x, int dest_y, int dest_w, int dest_h, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool filter) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint p; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawImageInt(image, src_x, src_y, src_w, src_h, dest_x, dest_y, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_w, dest_h, filter, p); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawImageInt(const gfx::ImageSkia& image, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int src_x, int src_y, int src_w, int src_h, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dest_x, int dest_y, int dest_w, int dest_h, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool filter, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_y + src_h < std::numeric_limits<int16_t>::max()); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src_w <= 0 || src_h <= 0) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float user_scale_x = static_cast<float>(dest_w) / src_w; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float user_scale_y = static_cast<float>(dest_h) / src_h; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_scale_x, user_scale_y); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_rep.is_null()) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect dest_rect = { SkIntToScalar(dest_x), 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_y), 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_x + dest_w), 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_y + dest_h) }; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src_w == dest_w && src_h == dest_h && 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_scale_x == 1.0f && user_scale_y == 1.0f && 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_rep.scale_factor() == ui::SCALE_FACTOR_100P) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Workaround for apparent bug in Skia that causes image to occasionally 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shift. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& bitmap = image_rep.sk_bitmap(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a bitmap shader that contains the bitmap we want to draw. This is 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // basically what SkCanvas.drawBitmap does internally, but it gives us 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more control over quality and will use the mipmap in the source image if 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it has one, whereas drawBitmap won't. 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix shader_scale; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.setScale(SkFloatToScalar(user_scale_x), 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(user_scale_y)); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_rep, 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkShader::kRepeat_TileMode, 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shader_scale); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up our paint to use the shader & release our reference (now just owned 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the paint). 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint p(paint); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p.setFilterBitmap(filter); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p.setShader(shader.get()); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The rect will be filled by the bitmap. 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawRect(dest_rect, p); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::DrawImageInPath(const gfx::ImageSkia& image, 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y, 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPath& path, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_rep.is_null()) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix matrix; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_rep, 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkShader::kRepeat_TileMode, 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) matrix); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint p(paint); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p.setShader(shader.get()); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawPath(path, p); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Canvas::DrawStringInt(const base::string16& text, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font& font, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color, 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, int y, int w, int h) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawStringInt(text, font, color, x, y, w, h, DefaultCanvasTextAlignment()); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Canvas::DrawStringInt(const base::string16& text, 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font& font, 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color, 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& display_rect) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawStringInt(text, font, color, display_rect.x(), display_rect.y(), 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) display_rect.width(), display_rect.height()); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Canvas::DrawStringInt(const base::string16& text, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font& font, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color, 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, int y, int w, int h, 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawStringWithShadows(text, 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) font, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color, 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect(x, y, w, h), 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShadowValues()); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::TileImageInt(const gfx::ImageSkia& image, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, int y, int w, int h) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TileImageInt(image, 0, 0, x, y, w, h); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::TileImageInt(const gfx::ImageSkia& image, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int src_x, int src_y, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dest_x, int dest_y, int w, int h) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TileImageInt(image, src_x, src_y, 1.0f, 1.0f, dest_x, dest_y, w, h); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::TileImageInt(const gfx::ImageSkia& image, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int src_x, int src_y, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float tile_scale_x, float tile_scale_y, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dest_x, int dest_y, int w, int h) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IntersectsClipRectInt(dest_x, dest_y, w, h)) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkiaRep& image_rep = GetImageRepToPaint(image, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tile_scale_x, tile_scale_y); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_rep.is_null()) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix shader_scale; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.setScale(SkFloatToScalar(tile_scale_x), 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkFloatToScalar(tile_scale_y)); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skia::RefPtr<SkShader> shader = gfx::CreateImageRepShader( 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_rep, 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkShader::kRepeat_TileMode, 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shader_scale); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint.setShader(shader.get()); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect dest_rect = { SkIntToScalar(dest_x), 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_y), 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_x + w), 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(dest_y + h) }; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->drawRect(dest_rect, paint); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeDrawingContext Canvas::BeginPlatformPaint() { 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skia::BeginPlatformPaint(canvas_); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::EndPlatformPaint() { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::EndPlatformPaint(canvas_); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Canvas::Transform(const gfx::Transform& transform) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_->concat(transform.matrix()); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Canvas::Canvas(SkCanvas* canvas, ui::ScaleFactor scale_factor) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : scale_factor_(scale_factor), 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owned_canvas_(), 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas_(canvas) { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(canvas); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect clip; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas_->getClipBounds(&clip) && 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(y + h)); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Canvas::IntersectsClipRect(const gfx::Rect& rect) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IntersectsClipRectInt(rect.x(), rect.y(), 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect.width(), rect.height()); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& image) const { 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetImageRepToPaint(image, 1.0f, 1.0f); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::ImageSkiaRep& Canvas::GetImageRepToPaint( 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& image, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float user_additional_scale_x, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float user_additional_scale_y) const { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor_); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!image_rep.is_null()) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix m = canvas_->getTotalMatrix(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) * 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_additional_scale_x; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) * 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_additional_scale_y; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float bitmap_scale = image_rep.GetScale(); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scale_x < bitmap_scale || scale_y < bitmap_scale) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<SkBitmap&>(image_rep.sk_bitmap()).buildMipMap(); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image_rep; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 544