blob: 494bcb5e17ca2852701a16ff3ee01dc65994d718 [file] [log] [blame]
/*
* Copyright (C) 2011 Research In Motion Limited. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef InstrumentedPlatformCanvas_h
#define InstrumentedPlatformCanvas_h
#include "SkCanvas.h"
#define DEBUG_SKIA_DRAWING 0
#if DEBUG_SKIA_DRAWING
#include "AndroidLog.h" // NOTE: AndroidLog.h normally shouldn't be included in a header
#include "FloatRect.h"
#define WRAPCANVAS_LOG_ENTRY(...) {ALOGD("non-rect %s, m_isSolidColor %d", __FUNCTION__, m_isSolidColor);}
#else
#define WRAPCANVAS_LOG_ENTRY(...) ((void)0)
#endif
namespace WebCore {
class InstrumentedPlatformCanvas : public SkCanvas {
public:
InstrumentedPlatformCanvas(int width, int height, Color initialColor)
: m_size(width, height)
, m_isSolidColor(true)
, m_solidColor(initialColor)
{
}
virtual ~InstrumentedPlatformCanvas() { }
bool isSolidColor() const { return m_isSolidColor; }
Color solidColor() const { return m_solidColor; }
// overrides from SkCanvas
virtual int save(SaveFlags flags = kMatrixClip_SaveFlag)
{
WRAPCANVAS_LOG_ENTRY("");
return SkCanvas::save(flags);
}
virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
return SkCanvas::saveLayer(bounds, paint, flags);
}
virtual void restore()
{
WRAPCANVAS_LOG_ENTRY("");
SkCanvas::restore();
}
virtual bool translate(SkScalar dx, SkScalar dy)
{
WRAPCANVAS_LOG_ENTRY("");
return SkCanvas::translate(dx, dy);
}
virtual bool scale(SkScalar sx, SkScalar sy)
{
WRAPCANVAS_LOG_ENTRY("");
return SkCanvas::scale(sx, sy);
}
virtual bool rotate(SkScalar degrees)
{
WRAPCANVAS_LOG_ENTRY("");
return SkCanvas::rotate(degrees);
}
virtual bool skew(SkScalar sx, SkScalar sy)
{
WRAPCANVAS_LOG_ENTRY("");
return SkCanvas::skew(sx, sy);
}
virtual bool concat(const SkMatrix& matrix)
{
WRAPCANVAS_LOG_ENTRY("");
return SkCanvas::concat(matrix);
}
virtual void setMatrix(const SkMatrix& matrix)
{
WRAPCANVAS_LOG_ENTRY("");
SkCanvas::setMatrix(matrix);
}
virtual bool clipRect(const SkRect& rect, SkRegion::Op op)
{
WRAPCANVAS_LOG_ENTRY("");
return SkCanvas::clipRect(rect, op);
}
virtual bool clipPath(const SkPath& path, SkRegion::Op op)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
return SkCanvas::clipPath(path, op);
}
virtual bool clipRegion(const SkRegion& region, SkRegion::Op op)
{
WRAPCANVAS_LOG_ENTRY("");
if (!region.isRect())
m_isSolidColor = false;
return SkCanvas::clipRegion(region, op);
}
virtual void clear(SkColor color)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = true;
m_solidColor = Color(color);
SkCanvas::clear(color);
}
virtual void drawPaint(const SkPaint& paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawPaint(paint);
}
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawPoints(mode, count, pts, paint);
}
bool rectFullyOverlaps(const SkRect& rect)
{
IntRect canvasRect(IntPoint(), m_size);
if (getTotalMatrix().rectStaysRect()
&& getTotalClip().contains(canvasRect)) {
const SkMatrix& matrix = getTotalMatrix();
SkRect mapped;
matrix.mapRect(&mapped, rect);
return mapped.contains(canvasRect);
}
return false;
}
virtual void drawRect(const SkRect& rect, const SkPaint& paint)
{
#if DEBUG_SKIA_DRAWING
FloatRect rectToDraw = rect;
ALOGD("drawrect " FLOAT_RECT_FORMAT ", is solid %d", FLOAT_RECT_ARGS(rectToDraw), m_isSolidColor);
#endif
if (m_isSolidColor) {
Color color = solidColor(paint);
if (color != m_solidColor) {
if (color.isValid() && rectFullyOverlaps(rect))
m_solidColor = color;
else
m_isSolidColor = false;
}
}
SkCanvas::drawRect(rect, paint);
}
virtual void drawPath(const SkPath& path, const SkPaint& paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawPath(path, paint);
}
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
SkScalar top, const SkPaint* paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawBitmap(bitmap, left, top, paint);
}
virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
const SkRect& dst, const SkPaint* paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawBitmapRectToRect(bitmap, src, dst, paint);
}
virtual void drawBitmapMatrix(const SkBitmap& bitmap,
const SkMatrix& matrix, const SkPaint* paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawBitmapMatrix(bitmap, matrix, paint);
}
virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint* paint = 0)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawBitmapNine(bitmap, center, dst, paint);
}
virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
const SkPaint* paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawSprite(bitmap, left, top, paint);
}
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawText(text, byteLength, x, y, paint);
}
virtual void drawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawPosText(text, byteLength, pos, paint);
}
virtual void drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY, const SkPaint& paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
}
virtual void drawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix, const SkPaint& paint)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawTextOnPath(text, byteLength, path, matrix, paint);
}
virtual void drawPicture(SkPicture& picture)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawPicture(picture);
}
virtual void 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)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawVertices(mode, vertexCount, vertices, texs,
colors, xfermode, indices, indexCount, paint);
}
virtual void drawData(const void* data, size_t size)
{
WRAPCANVAS_LOG_ENTRY("");
m_isSolidColor = false;
SkCanvas::drawData(data, size);
}
private:
Color solidColor(const SkPaint& paint)
{
if (paint.getStyle() != SkPaint::kFill_Style)
return Color();
if (paint.getLooper() || paint.getShader())
return Color();
SkXfermode::Mode mode;
SkXfermode::AsMode(paint.getXfermode(), &mode);
if (mode == SkXfermode::kClear_Mode)
return Color(0, 0, 0, 0);
if ((mode == SkXfermode::kSrcOver_Mode && paint.getAlpha() == 255)
|| mode == SkXfermode::kSrc_Mode)
return Color(paint.getColor());
return Color();
}
IntSize m_size;
bool m_isSolidColor;
Color m_solidColor;
SkPaint m_solidPaint;
};
} // namespace WebCore
#endif // InstrumentedPlatformCanvas_h