• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
33 namespace WebCore {
34 
35 class InstrumentedPlatformCanvas : public SkCanvas {
36 public:
InstrumentedPlatformCanvas(int width,int height,Color initialColor)37     InstrumentedPlatformCanvas(int width, int height, Color initialColor)
38         : m_size(width, height)
39         , m_isSolidColor(true)
40         , m_solidColor(initialColor)
41     {
42     }
43 
~InstrumentedPlatformCanvas()44     virtual ~InstrumentedPlatformCanvas() { }
45 
isSolidColor()46     bool isSolidColor() const { return m_isSolidColor; }
solidColor()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 
saveLayer(const SkRect * bounds,const SkPaint * paint,SaveFlags flags)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 
restore()63     virtual void restore()
64     {
65         WRAPCANVAS_LOG_ENTRY("");
66         SkCanvas::restore();
67     }
68 
translate(SkScalar dx,SkScalar dy)69     virtual bool translate(SkScalar dx, SkScalar dy)
70     {
71         WRAPCANVAS_LOG_ENTRY("");
72         return SkCanvas::translate(dx, dy);
73     }
74 
scale(SkScalar sx,SkScalar sy)75     virtual bool scale(SkScalar sx, SkScalar sy)
76     {
77         WRAPCANVAS_LOG_ENTRY("");
78         return SkCanvas::scale(sx, sy);
79     }
80 
rotate(SkScalar degrees)81     virtual bool rotate(SkScalar degrees)
82     {
83         WRAPCANVAS_LOG_ENTRY("");
84         return SkCanvas::rotate(degrees);
85     }
86 
skew(SkScalar sx,SkScalar sy)87     virtual bool skew(SkScalar sx, SkScalar sy)
88     {
89         WRAPCANVAS_LOG_ENTRY("");
90         return SkCanvas::skew(sx, sy);
91     }
92 
concat(const SkMatrix & matrix)93     virtual bool concat(const SkMatrix& matrix)
94     {
95         WRAPCANVAS_LOG_ENTRY("");
96         return SkCanvas::concat(matrix);
97     }
98 
setMatrix(const SkMatrix & matrix)99     virtual void setMatrix(const SkMatrix& matrix)
100     {
101         WRAPCANVAS_LOG_ENTRY("");
102         SkCanvas::setMatrix(matrix);
103     }
104 
clipRect(const SkRect & rect,SkRegion::Op op)105     virtual bool clipRect(const SkRect& rect, SkRegion::Op op)
106     {
107         WRAPCANVAS_LOG_ENTRY("");
108         return SkCanvas::clipRect(rect, op);
109     }
110 
clipPath(const SkPath & path,SkRegion::Op op)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 
clipRegion(const SkRegion & region,SkRegion::Op op)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 
clear(SkColor color)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 
drawPaint(const SkPaint & paint)134     virtual void drawPaint(const SkPaint& paint)
135     {
136         WRAPCANVAS_LOG_ENTRY("");
137         m_isSolidColor = false;
138         SkCanvas::drawPaint(paint);
139     }
140 
drawPoints(PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)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 
rectFullyOverlaps(const SkRect & rect)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 
drawRect(const SkRect & rect,const SkPaint & paint)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 
drawPath(const SkPath & path,const SkPaint & paint)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 
drawBitmap(const SkBitmap & bitmap,SkScalar left,SkScalar top,const SkPaint * paint)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 
drawBitmapRectToRect(const SkBitmap & bitmap,const SkRect * src,const SkRect & dst,const SkPaint * paint)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 
drawBitmapMatrix(const SkBitmap & bitmap,const SkMatrix & matrix,const SkPaint * paint)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 
drawSprite(const SkBitmap & bitmap,int left,int top,const SkPaint * paint)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 
drawText(const void * text,size_t byteLength,SkScalar x,SkScalar y,const SkPaint & paint)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 
drawPosText(const void * text,size_t byteLength,const SkPoint pos[],const SkPaint & paint)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 
drawPosTextH(const void * text,size_t byteLength,const SkScalar xpos[],SkScalar constY,const SkPaint & paint)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 
drawTextOnPath(const void * text,size_t byteLength,const SkPath & path,const SkMatrix * matrix,const SkPaint & paint)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 
drawPicture(SkPicture & picture)262     virtual void drawPicture(SkPicture& picture)
263     {
264         WRAPCANVAS_LOG_ENTRY("");
265         m_isSolidColor = false;
266         SkCanvas::drawPicture(picture);
267     }
268 
drawVertices(VertexMode mode,int vertexCount,const SkPoint vertices[],const SkPoint texs[],const SkColor colors[],SkXfermode * xfermode,const uint16_t indices[],int indexCount,const SkPaint & paint)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 
drawData(const void * data,size_t size)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 
287 private:
solidColor(const SkPaint & paint)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