1/* 2 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#ifndef InstrumentedPlatformCanvas_h 20#define InstrumentedPlatformCanvas_h 21 22#include "SkCanvas.h" 23 24#define DEBUG_SKIA_DRAWING 0 25#if DEBUG_SKIA_DRAWING 26#include "AndroidLog.h" // NOTE: AndroidLog.h normally shouldn't be included in a header 27#include "FloatRect.h" 28#define WRAPCANVAS_LOG_ENTRY(...) {ALOGD("non-rect %s, m_isSolidColor %d", __FUNCTION__, m_isSolidColor);} 29#else 30#define WRAPCANVAS_LOG_ENTRY(...) ((void)0) 31#endif 32 33namespace WebCore { 34 35class InstrumentedPlatformCanvas : public SkCanvas { 36public: 37 InstrumentedPlatformCanvas(int width, int height, Color initialColor) 38 : m_size(width, height) 39 , m_isSolidColor(true) 40 , m_solidColor(initialColor) 41 { 42 } 43 44 virtual ~InstrumentedPlatformCanvas() { } 45 46 bool isSolidColor() const { return m_isSolidColor; } 47 Color solidColor() const { return m_solidColor; } 48 49 // overrides from SkCanvas 50 virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) 51 { 52 WRAPCANVAS_LOG_ENTRY(""); 53 return SkCanvas::save(flags); 54 } 55 56 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) 57 { 58 WRAPCANVAS_LOG_ENTRY(""); 59 m_isSolidColor = false; 60 return SkCanvas::saveLayer(bounds, paint, flags); 61 } 62 63 virtual void restore() 64 { 65 WRAPCANVAS_LOG_ENTRY(""); 66 SkCanvas::restore(); 67 } 68 69 virtual bool translate(SkScalar dx, SkScalar dy) 70 { 71 WRAPCANVAS_LOG_ENTRY(""); 72 return SkCanvas::translate(dx, dy); 73 } 74 75 virtual bool scale(SkScalar sx, SkScalar sy) 76 { 77 WRAPCANVAS_LOG_ENTRY(""); 78 return SkCanvas::scale(sx, sy); 79 } 80 81 virtual bool rotate(SkScalar degrees) 82 { 83 WRAPCANVAS_LOG_ENTRY(""); 84 return SkCanvas::rotate(degrees); 85 } 86 87 virtual bool skew(SkScalar sx, SkScalar sy) 88 { 89 WRAPCANVAS_LOG_ENTRY(""); 90 return SkCanvas::skew(sx, sy); 91 } 92 93 virtual bool concat(const SkMatrix& matrix) 94 { 95 WRAPCANVAS_LOG_ENTRY(""); 96 return SkCanvas::concat(matrix); 97 } 98 99 virtual void setMatrix(const SkMatrix& matrix) 100 { 101 WRAPCANVAS_LOG_ENTRY(""); 102 SkCanvas::setMatrix(matrix); 103 } 104 105 virtual bool clipRect(const SkRect& rect, SkRegion::Op op) 106 { 107 WRAPCANVAS_LOG_ENTRY(""); 108 return SkCanvas::clipRect(rect, op); 109 } 110 111 virtual bool clipPath(const SkPath& path, SkRegion::Op op) 112 { 113 WRAPCANVAS_LOG_ENTRY(""); 114 m_isSolidColor = false; 115 return SkCanvas::clipPath(path, op); 116 } 117 118 virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) 119 { 120 WRAPCANVAS_LOG_ENTRY(""); 121 if (!region.isRect()) 122 m_isSolidColor = false; 123 return SkCanvas::clipRegion(region, op); 124 } 125 126 virtual void clear(SkColor color) 127 { 128 WRAPCANVAS_LOG_ENTRY(""); 129 m_isSolidColor = true; 130 m_solidColor = Color(color); 131 SkCanvas::clear(color); 132 } 133 134 virtual void drawPaint(const SkPaint& paint) 135 { 136 WRAPCANVAS_LOG_ENTRY(""); 137 m_isSolidColor = false; 138 SkCanvas::drawPaint(paint); 139 } 140 141 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], 142 const SkPaint& paint) 143 { 144 WRAPCANVAS_LOG_ENTRY(""); 145 m_isSolidColor = false; 146 SkCanvas::drawPoints(mode, count, pts, paint); 147 } 148 149 bool rectFullyOverlaps(const SkRect& rect) 150 { 151 IntRect canvasRect(IntPoint(), m_size); 152 if (getTotalMatrix().rectStaysRect() 153 && getTotalClip().contains(canvasRect)) { 154 const SkMatrix& matrix = getTotalMatrix(); 155 SkRect mapped; 156 matrix.mapRect(&mapped, rect); 157 return mapped.contains(canvasRect); 158 } 159 return false; 160 } 161 162 virtual void drawRect(const SkRect& rect, const SkPaint& paint) 163 { 164 165#if DEBUG_SKIA_DRAWING 166 FloatRect rectToDraw = rect; 167 ALOGD("drawrect " FLOAT_RECT_FORMAT ", is solid %d", FLOAT_RECT_ARGS(rectToDraw), m_isSolidColor); 168#endif 169 170 if (m_isSolidColor) { 171 Color color = solidColor(paint); 172 if (color != m_solidColor) { 173 if (color.isValid() && rectFullyOverlaps(rect)) 174 m_solidColor = color; 175 else 176 m_isSolidColor = false; 177 } 178 } 179 180 SkCanvas::drawRect(rect, paint); 181 } 182 183 virtual void drawPath(const SkPath& path, const SkPaint& paint) 184 { 185 WRAPCANVAS_LOG_ENTRY(""); 186 m_isSolidColor = false; 187 SkCanvas::drawPath(path, paint); 188 } 189 190 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, 191 SkScalar top, const SkPaint* paint) 192 { 193 WRAPCANVAS_LOG_ENTRY(""); 194 m_isSolidColor = false; 195 SkCanvas::drawBitmap(bitmap, left, top, paint); 196 } 197 198 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 199 const SkRect& dst, const SkPaint* paint) 200 { 201 WRAPCANVAS_LOG_ENTRY(""); 202 m_isSolidColor = false; 203 SkCanvas::drawBitmapRectToRect(bitmap, src, dst, paint); 204 } 205 206 virtual void drawBitmapMatrix(const SkBitmap& bitmap, 207 const SkMatrix& matrix, const SkPaint* paint) 208 { 209 WRAPCANVAS_LOG_ENTRY(""); 210 m_isSolidColor = false; 211 SkCanvas::drawBitmapMatrix(bitmap, matrix, paint); 212 } 213 214 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 215 const SkRect& dst, const SkPaint* paint = 0) 216 { 217 WRAPCANVAS_LOG_ENTRY(""); 218 m_isSolidColor = false; 219 SkCanvas::drawBitmapNine(bitmap, center, dst, paint); 220 } 221 222 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, 223 const SkPaint* paint) 224 { 225 WRAPCANVAS_LOG_ENTRY(""); 226 m_isSolidColor = false; 227 SkCanvas::drawSprite(bitmap, left, top, paint); 228 } 229 230 virtual void drawText(const void* text, size_t byteLength, SkScalar x, 231 SkScalar y, const SkPaint& paint) 232 { 233 WRAPCANVAS_LOG_ENTRY(""); 234 m_isSolidColor = false; 235 SkCanvas::drawText(text, byteLength, x, y, paint); 236 } 237 238 virtual void drawPosText(const void* text, size_t byteLength, 239 const SkPoint pos[], const SkPaint& paint) 240 { 241 WRAPCANVAS_LOG_ENTRY(""); 242 m_isSolidColor = false; 243 SkCanvas::drawPosText(text, byteLength, pos, paint); 244 } 245 246 virtual void drawPosTextH(const void* text, size_t byteLength, 247 const SkScalar xpos[], SkScalar constY, const SkPaint& paint) 248 { 249 WRAPCANVAS_LOG_ENTRY(""); 250 m_isSolidColor = false; 251 SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint); 252 } 253 254 virtual void drawTextOnPath(const void* text, size_t byteLength, 255 const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) 256 { 257 WRAPCANVAS_LOG_ENTRY(""); 258 m_isSolidColor = false; 259 SkCanvas::drawTextOnPath(text, byteLength, path, matrix, paint); 260 } 261 262 virtual void drawPicture(SkPicture& picture) 263 { 264 WRAPCANVAS_LOG_ENTRY(""); 265 m_isSolidColor = false; 266 SkCanvas::drawPicture(picture); 267 } 268 269 virtual void drawVertices(VertexMode mode, int vertexCount, 270 const SkPoint vertices[], const SkPoint texs[], 271 const SkColor colors[], SkXfermode* xfermode, 272 const uint16_t indices[], int indexCount, const SkPaint& paint) 273 { 274 WRAPCANVAS_LOG_ENTRY(""); 275 m_isSolidColor = false; 276 SkCanvas::drawVertices(mode, vertexCount, vertices, texs, 277 colors, xfermode, indices, indexCount, paint); 278 } 279 280 virtual void drawData(const void* data, size_t size) 281 { 282 WRAPCANVAS_LOG_ENTRY(""); 283 m_isSolidColor = false; 284 SkCanvas::drawData(data, size); 285 } 286 287private: 288 Color solidColor(const SkPaint& paint) 289 { 290 if (paint.getStyle() != SkPaint::kFill_Style) 291 return Color(); 292 if (paint.getLooper() || paint.getShader()) 293 return Color(); 294 295 SkXfermode::Mode mode; 296 SkXfermode::AsMode(paint.getXfermode(), &mode); 297 if (mode == SkXfermode::kClear_Mode) 298 return Color(0, 0, 0, 0); 299 300 if ((mode == SkXfermode::kSrcOver_Mode && paint.getAlpha() == 255) 301 || mode == SkXfermode::kSrc_Mode) 302 return Color(paint.getColor()); 303 return Color(); 304 } 305 306 IntSize m_size; 307 bool m_isSolidColor; 308 Color m_solidColor; 309 SkPaint m_solidPaint; 310}; 311 312} // namespace WebCore 313 314#endif // InstrumentedPlatformCanvas_h 315