make RRect and Oval first-class drawing primitives in SkCanvas.
add RRect as a first-class clip primitive.
Review URL: https://codereview.appspot.com/6923058
git-svn-id: http://skia.googlecode.com/svn/trunk@6762 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 5bbfc74..3b3dbc4 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -27,6 +27,7 @@
class SkDrawFilter;
class SkMetaData;
class SkPicture;
+class SkRRect;
class SkSurface_Base;
/** \class SkCanvas
@@ -339,20 +340,35 @@
*/
void resetMatrix();
- /** Modify the current clip with the specified rectangle.
- @param rect The rect to intersect with the current clip
- @param op The region op to apply to the current clip
- @return true if the canvas' clip is non-empty
- */
+ /**
+ * Modify the current clip with the specified rectangle.
+ * @param rect The rect to combine with the current clip
+ * @param op The region op to apply to the current clip
+ * @param doAntiAlias true if the clip should be antialiased
+ * @return true if the canvas' clip is non-empty
+ */
virtual bool clipRect(const SkRect& rect,
SkRegion::Op op = SkRegion::kIntersect_Op,
bool doAntiAlias = false);
- /** Modify the current clip with the specified path.
- @param path The path to apply to the current clip
- @param op The region op to apply to the current clip
- @return true if the canvas' new clip is non-empty
- */
+ /**
+ * Modify the current clip with the specified SkRRect.
+ * @param rrect The rrect to combine with the current clip
+ * @param op The region op to apply to the current clip
+ * @param doAntiAlias true if the clip should be antialiased
+ * @return true if the canvas' clip is non-empty
+ */
+ virtual bool clipRRect(const SkRRect& rrect,
+ SkRegion::Op op = SkRegion::kIntersect_Op,
+ bool doAntiAlias = false);
+
+ /**
+ * Modify the current clip with the specified path.
+ * @param path The path to combine with the current clip
+ * @param op The region op to apply to the current clip
+ * @param doAntiAlias true if the clip should be antialiased
+ * @return true if the canvas' new clip is non-empty
+ */
virtual bool clipPath(const SkPath& path,
SkRegion::Op op = SkRegion::kIntersect_Op,
bool doAntiAlias = false);
@@ -577,7 +593,16 @@
@param oval The rectangle bounds of the oval to be drawn
@param paint The paint used to draw the oval
*/
- void drawOval(const SkRect& oval, const SkPaint&);
+ virtual void drawOval(const SkRect& oval, const SkPaint&);
+
+ /**
+ * Draw the specified RRect using the specified paint The rrect will be filled or stroked
+ * based on the Style in the paint.
+ *
+ * @param rrect The round-rect to draw
+ * @param paint The paint used to draw the round-rect
+ */
+ virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint);
/** Draw the specified circle using the specified paint. If radius is <= 0,
then nothing will be drawn. The circle will be filled
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index b85e827..98d7752 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -28,6 +28,7 @@
class SkAutoPathBoundsUpdate;
class SkString;
class SkPathRef;
+class SkRRect;
#ifndef SK_DEBUG_PATH_REF
#define SK_DEBUG_PATH_REF 0
@@ -656,6 +657,11 @@
Direction dir = kCW_Direction);
/**
+ * Add a SkRRect contour to the path
+ */
+ void addRRect(const SkRRect&, Direction dir = kCW_Direction);
+
+ /**
* Add a new contour made of just lines. This is just a fast version of
* the following:
* this->moveTo(pts[0]);
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index b51b6aa..3525695 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -158,7 +158,8 @@
// V8 : Add an option for encoding bitmaps
// V9 : Allow the reader and writer of an SKP disagree on whether to support
// SK_SUPPORT_HINTING_SCALE_FACTOR
- static const uint32_t PICTURE_VERSION = 9;
+ // V10: add drawRRect, drawOval, clipRRect
+ static const uint32_t PICTURE_VERSION = 10;
// fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
// install their own SkPicturePlayback-derived players,SkPictureRecord-derived
diff --git a/include/core/SkRRect.h b/include/core/SkRRect.h
index 1b52da9..a900d4a 100644
--- a/include/core/SkRRect.h
+++ b/include/core/SkRRect.h
@@ -11,6 +11,8 @@
#include "SkRect.h"
#include "SkPoint.h"
+class SkPath;
+
// Path forward:
// core work
// add validate method (all radii positive, all radii sums < rect size, etc.)
@@ -83,7 +85,7 @@
/**
* Returns the RR's sub type.
*/
- Type type() const {
+ Type getType() const {
SkDEBUGCODE(this->validate();)
if (kUnknown_Type == fType) {
@@ -93,6 +95,14 @@
return fType;
}
+ Type type() const { return this->getType(); }
+
+ inline bool isEmpty() const { return kEmpty_Type == this->getType(); }
+ inline bool isRect() const { return kRect_Type == this->getType(); }
+ inline bool isOval() const { return kOval_Type == this->getType(); }
+ inline bool isSimple() const { return kSimple_Type == this->getType(); }
+ inline bool isComplex() const { return kComplex_Type == this->getType(); }
+
/**
* Set this RR to the empty rectangle (0,0,0,0) with 0 x & y radii.
*/
@@ -162,6 +172,16 @@
const SkRect& rect() const { return fRect; }
const SkVector& radii(Corner corner) const { return fRadii[corner]; }
+ const SkRect& getBounds() const { return fRect; }
+
+ /**
+ * When a rrect is simple, all of its radii are equal. This returns one
+ * of those radii. This call requires the rrect to be non-complex.
+ */
+ const SkVector& getSimpleRadii() const {
+ SkASSERT(!this->isComplex());
+ return fRadii[0];
+ }
friend bool operator==(const SkRRect& a, const SkRRect& b) {
return a.fRect == b.fRect &&
@@ -199,6 +219,24 @@
SkDEBUGCODE(void validate() const;)
+ enum {
+ kSizeInMemory = 12 * sizeof(SkScalar)
+ };
+
+ /**
+ * Write the rrect into the specified buffer. This is guaranteed to always
+ * write kSizeInMemory bytes, and that value is guaranteed to always be
+ * a multiple of 4. Return kSizeInMemory.
+ */
+ uint32_t writeToMemory(void* buffer) const;
+
+ /**
+ * Read the rrect from the specified buffer. This is guaranteed to always
+ * read kSizeInMemory bytes, and that value is guaranteed to always be
+ * a multiple of 4. Return kSizeInMemory.
+ */
+ uint32_t readFromMemory(const void* buffer);
+
private:
SkRect fRect;
// Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[]
@@ -208,6 +246,9 @@
// uninitialized data
void computeType() const;
+
+ // to access fRadii directly
+ friend class SkPath;
};
#endif
diff --git a/include/utils/SkDeferredCanvas.h b/include/utils/SkDeferredCanvas.h
index 4686d00..716ec3e 100644
--- a/include/utils/SkDeferredCanvas.h
+++ b/include/utils/SkDeferredCanvas.h
@@ -140,6 +140,8 @@
virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
bool doAntiAlias) SK_OVERRIDE;
+ virtual bool clipRRect(const SkRRect& rect, SkRegion::Op op,
+ bool doAntiAlias) SK_OVERRIDE;
virtual bool clipPath(const SkPath& path, SkRegion::Op op,
bool doAntiAlias) SK_OVERRIDE;
virtual bool clipRegion(const SkRegion& deviceRgn,
@@ -148,8 +150,9 @@
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) SK_OVERRIDE;
- virtual void drawRect(const SkRect& rect, const SkPaint& paint)
- SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
virtual void drawPath(const SkPath& path, const SkPaint& paint)
SK_OVERRIDE;
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h
index 4eb1f25..608ab01 100644
--- a/include/utils/SkDumpCanvas.h
+++ b/include/utils/SkDumpCanvas.h
@@ -35,7 +35,9 @@
kDrawPaint_Verb,
kDrawPoints_Verb,
+ kDrawOval_Verb,
kDrawRect_Verb,
+ kDrawRRect_Verb,
kDrawPath_Verb,
kDrawBitmap_Verb,
kDrawText_Verb,
@@ -76,6 +78,7 @@
virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE;
+ virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipRegion(const SkRegion& deviceRgn,
SkRegion::Op) SK_OVERRIDE;
@@ -83,7 +86,9 @@
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) SK_OVERRIDE;
- virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
virtual void drawPath(const SkPath& path, const SkPaint& paint) SK_OVERRIDE;
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
const SkPaint* paint) SK_OVERRIDE;
diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h
index 065adf0..fcd0ccf 100644
--- a/include/utils/SkNWayCanvas.h
+++ b/include/utils/SkNWayCanvas.h
@@ -34,6 +34,7 @@
virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE;
+ virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipRegion(const SkRegion& deviceRgn,
SkRegion::Op) SK_OVERRIDE;
@@ -41,7 +42,9 @@
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint&) SK_OVERRIDE;
- virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE;
virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
const SkPaint*) SK_OVERRIDE;
diff --git a/include/utils/SkProxyCanvas.h b/include/utils/SkProxyCanvas.h
index aa47085..bd260c7 100644
--- a/include/utils/SkProxyCanvas.h
+++ b/include/utils/SkProxyCanvas.h
@@ -39,6 +39,7 @@
virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE;
+ virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipRegion(const SkRegion& deviceRgn,
SkRegion::Op op = SkRegion::kIntersect_Op) SK_OVERRIDE;
@@ -46,7 +47,9 @@
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) SK_OVERRIDE;
- virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
virtual void drawPath(const SkPath& path, const SkPaint& paint) SK_OVERRIDE;
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
const SkPaint* paint = NULL) SK_OVERRIDE;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 34310c8..3efdd22 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -17,6 +17,7 @@
#include "SkMetaData.h"
#include "SkPicture.h"
#include "SkRasterClip.h"
+#include "SkRRect.h"
#include "SkScalarCompare.h"
#include "SkSurface_Base.h"
#include "SkTemplates.h"
@@ -1125,6 +1126,18 @@
}
}
+bool SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ if (rrect.isRect()) {
+ // call the non-virtual version
+ return this->SkCanvas::clipRect(rrect.getBounds(), op, doAA);
+ } else {
+ SkPath path;
+ path.addRRect(rrect);
+ // call the non-virtual version
+ return this->SkCanvas::clipPath(path, op, doAA);
+ }
+}
+
bool SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
#ifdef SK_ENABLE_CLIP_QUICKREJECT
if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) {
@@ -1466,6 +1479,40 @@
LOOPER_END
}
+void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
+ if (paint.canComputeFastBounds()) {
+ SkRect storage;
+ if (this->quickReject(paint.computeFastBounds(oval, &storage))) {
+ return;
+ }
+ }
+
+ SkPath path;
+ path.addOval(oval);
+ // call the non-virtual version
+ this->SkCanvas::drawPath(path, paint);
+}
+
+void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ if (paint.canComputeFastBounds()) {
+ SkRect storage;
+ if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) {
+ return;
+ }
+ }
+
+ if (rrect.isRect()) {
+ // call the non-virtual version
+ this->SkCanvas::drawRect(rrect.getBounds(), paint);
+ } else {
+ SkPath path;
+ path.addRRect(rrect);
+ // call the non-virtual version
+ this->SkCanvas::drawPath(path, paint);
+ }
+}
+
+
void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
if (!path.isFinite()) {
return;
@@ -1898,17 +1945,7 @@
SkRect r;
r.set(cx - radius, cy - radius, cx + radius, cy + radius);
-
- if (paint.canComputeFastBounds()) {
- SkRect storage;
- if (this->quickReject(paint.computeFastBounds(r, &storage))) {
- return;
- }
- }
-
- SkPath path;
- path.addOval(r);
- this->drawPath(path, paint);
+ this->drawOval(r, paint);
}
void SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry,
@@ -1920,28 +1957,14 @@
return;
}
}
-
- SkPath path;
- path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
- this->drawPath(path, paint);
+ SkRRect rrect;
+ rrect.setRectXY(r, rx, ry);
+ this->drawRRect(rrect, paint);
} else {
this->drawRect(r, paint);
}
}
-void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
- if (paint.canComputeFastBounds()) {
- SkRect storage;
- if (this->quickReject(paint.computeFastBounds(oval, &storage))) {
- return;
- }
- }
-
- SkPath path;
- path.addOval(oval);
- this->drawPath(path, paint);
-}
-
void SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle,
SkScalar sweepAngle, bool useCenter,
const SkPaint& paint) {
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index fe95514..ae1d187 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -11,9 +11,9 @@
#include "SkBuffer.h"
#include "SkMath.h"
#include "SkPathRef.h"
+#include "SkRRect.h"
#include "SkThread.h"
-
////////////////////////////////////////////////////////////////////////////
#if SK_DEBUG_PATH_REF
@@ -1088,6 +1088,21 @@
this->close();
}
+void SkPath::addRRect(const SkRRect& rrect, Direction dir) {
+ const SkRect& bounds = rrect.getBounds();
+
+ if (rrect.isRect()) {
+ this->addRect(bounds, dir);
+ } else if (rrect.isOval()) {
+ this->addOval(bounds, dir);
+ } else if (rrect.isSimple()) {
+ const SkVector& rad = rrect.getSimpleRadii();
+ this->addRoundRect(bounds, rad.x(), rad.y(), dir);
+ } else {
+ this->addRoundRect(bounds, (const SkScalar*)&rrect.fRadii[0], dir);
+ }
+}
+
bool SkPath::hasOnlyMoveTos() const {
int count = fPathRef->countVerbs();
const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbsMemBegin();
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 4292361..9594a59 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -29,6 +29,7 @@
CLIP_PATH,
CLIP_REGION,
CLIP_RECT,
+ CLIP_RRECT,
CONCAT,
DRAW_BITMAP,
DRAW_BITMAP_MATRIX,
@@ -36,6 +37,7 @@
DRAW_BITMAP_RECT_TO_RECT,
DRAW_CLEAR,
DRAW_DATA,
+ DRAW_OVAL,
DRAW_PAINT,
DRAW_PATH,
DRAW_PICTURE,
@@ -45,6 +47,7 @@
DRAW_POS_TEXT_H,
DRAW_POS_TEXT_H_TOP_BOTTOM, // fast variant of DRAW_POS_TEXT_H
DRAW_RECT,
+ DRAW_RRECT,
DRAW_SPRITE,
DRAW_TEXT,
DRAW_TEXT_ON_PATH,
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 9a8f133..31ee3ec 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -634,7 +634,7 @@
#endif
#ifdef SPEW_CLIP_SKIPPING
- SkipClipRec skipRect, skipRegion, skipPath;
+ SkipClipRec skipRect, skipRRect, skipRegion, skipPath;
#endif
#ifdef SK_BUILD_FOR_ANDROID
@@ -731,7 +731,7 @@
bool doAA = ClipParams_unpackDoAA(packed);
size_t offsetToRestore = reader.readInt();
SkASSERT(!offsetToRestore || \
- offsetToRestore >= reader.offset());
+ offsetToRestore >= reader.offset());
if (!canvas.clipRect(rect, op, doAA) && offsetToRestore) {
#ifdef SPEW_CLIP_SKIPPING
skipRect.recordSkip(offsetToRestore - reader.offset());
@@ -739,6 +739,22 @@
reader.setOffset(offsetToRestore);
}
} break;
+ case CLIP_RRECT: {
+ SkRRect rrect;
+ reader.readRRect(&rrect);
+ uint32_t packed = reader.readInt();
+ SkRegion::Op op = ClipParams_unpackRegionOp(packed);
+ bool doAA = ClipParams_unpackDoAA(packed);
+ size_t offsetToRestore = reader.readInt();
+ SkASSERT(!offsetToRestore || \
+ offsetToRestore >= reader.offset());
+ if (!canvas.clipRRect(rrect, op, doAA) && offsetToRestore) {
+#ifdef SPEW_CLIP_SKIPPING
+ skipRRect.recordSkip(offsetToRestore - reader.offset());
+#endif
+ reader.setOffset(offsetToRestore);
+ }
+ } break;
case CONCAT:
canvas.concat(*getMatrix(reader));
break;
@@ -776,6 +792,10 @@
canvas.drawData(reader.skip(length), length);
// skip handles padding the read out to a multiple of 4
} break;
+ case DRAW_OVAL: {
+ const SkPaint& paint = *getPaint(reader);
+ canvas.drawOval(reader.skipT<SkRect>(), paint);
+ } break;
case DRAW_PAINT:
canvas.drawPaint(*getPaint(reader));
break;
@@ -837,6 +857,11 @@
const SkPaint& paint = *getPaint(reader);
canvas.drawRect(reader.skipT<SkRect>(), paint);
} break;
+ case DRAW_RRECT: {
+ const SkPaint& paint = *getPaint(reader);
+ SkRRect rrect;
+ canvas.drawRRect(*reader.readRRect(&rrect), paint);
+ } break;
case DRAW_SPRITE: {
const SkPaint* paint = getPaint(reader);
const SkBitmap& bitmap = getBitmap(reader);
@@ -952,10 +977,10 @@
#ifdef SPEW_CLIP_SKIPPING
{
- size_t size = skipRect.fSize + skipPath.fSize + skipRegion.fSize;
- SkDebugf("--- Clip skips %d%% rect:%d path:%d rgn:%d\n",
- size * 100 / reader.offset(), skipRect.fCount, skipPath.fCount,
- skipRegion.fCount);
+ size_t size = skipRect.fSize + skipRRect.fSize + skipPath.fSize + skipRegion.fSize;
+ SkDebugf("--- Clip skips %d%% rect:%d rrect:%d path:%d rgn:%d\n",
+ size * 100 / reader.offset(), skipRect.fCount, skipRRect.fCount,
+ skipPath.fCount, skipRegion.fCount);
}
#endif
// this->dumpSize();
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index 8f52b19..13a685f 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -19,6 +19,7 @@
#include "SkPath.h"
#include "SkPathHeap.h"
#include "SkRegion.h"
+#include "SkRRect.h"
#include "SkPictureFlat.h"
#include "SkSerializationHelpers.h"
@@ -147,7 +148,7 @@
int index = reader.readInt();
return (*fRegions)[index - 1];
}
-
+
void getText(SkReader32& reader, TextContainer* text) {
size_t length = text->fByteLength = reader.readInt();
text->fText = (const char*)reader.skip(length);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 3c4df53..82257c8 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -8,6 +8,7 @@
#include "SkPictureRecord.h"
#include "SkTSearch.h"
#include "SkPixelRef.h"
+#include "SkRRect.h"
#include "SkBBoxHierarchy.h"
#include "SkPictureStateTree.h"
@@ -111,6 +112,7 @@
4, // CLIP_PATH,
4, // CLIP_REGION,
7, // CLIP_RECT,
+ 15, // CLIP_RRECT,
2, // CONCAT,
0, // DRAW_BITMAP,
0, // DRAW_BITMAP_MATRIX,
@@ -118,6 +120,7 @@
0, // DRAW_BITMAP_RECT,
0, // DRAW_CLEAR,
0, // DRAW_DATA,
+ 0, // DRAW_OVAL,
0, // DRAW_PAINT,
0, // DRAW_PATH,
0, // DRAW_PICTURE,
@@ -127,6 +130,7 @@
0, // DRAW_POS_TEXT_H,
0, // DRAW_POS_TEXT_H_TOP_BOTTOM, // fast variant of DRAW_POS_TEXT_H
0, // DRAW_RECT,
+ 0, // DRAW_RRECT,
0, // DRAW_SPRITE,
0, // DRAW_TEXT,
0, // DRAW_TEXT_ON_PATH,
@@ -352,11 +356,30 @@
addRect(rect);
addInt(ClipParams_pack(op, doAA));
recordRestoreOffsetPlaceholder(op);
-
+
validate();
return this->INHERITED::clipRect(rect, op, doAA);
}
+bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ if (rrect.isRect()) {
+ return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA);
+ }
+
+ addDraw(CLIP_RRECT);
+ addRRect(rrect);
+ addInt(ClipParams_pack(op, doAA));
+ recordRestoreOffsetPlaceholder(op);
+
+ validate();
+
+ if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
+ return this->INHERITED::clipRect(rrect.getBounds(), op, doAA);
+ } else {
+ return this->INHERITED::clipRRect(rrect, op, doAA);
+ }
+}
+
bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
SkRect r;
@@ -410,6 +433,13 @@
validate();
}
+void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) {
+ addDraw(DRAW_OVAL);
+ addPaint(paint);
+ addRect(oval);
+ validate();
+}
+
void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
addDraw(DRAW_RECT);
addPaint(paint);
@@ -417,6 +447,23 @@
validate();
}
+void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ if (rrect.isRect()) {
+ addDraw(DRAW_RECT);
+ addPaint(paint);
+ addRect(rrect.getBounds());
+ } else if (rrect.isOval()) {
+ addDraw(DRAW_OVAL);
+ addPaint(paint);
+ addRect(rrect.getBounds());
+ } else {
+ addDraw(DRAW_RRECT);
+ addPaint(paint);
+ addRRect(rrect);
+ }
+ validate();
+}
+
void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
addDraw(DRAW_PATH);
addPaint(paint);
@@ -754,6 +801,10 @@
}
}
+void SkPictureRecord::addRRect(const SkRRect& rrect) {
+ fWriter.writeRRect(rrect);
+}
+
void SkPictureRecord::addRegion(const SkRegion& region) {
addInt(fRegions.find(region));
}
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 77a6b04..abaa22d 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -36,13 +36,16 @@
virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE;
+ virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE;
virtual void clear(SkColor) SK_OVERRIDE;
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
const SkPaint&) SK_OVERRIDE;
- virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE;
virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
const SkPaint*) SK_OVERRIDE;
@@ -129,6 +132,7 @@
void addRectPtr(const SkRect* rect);
void addIRect(const SkIRect& rect);
void addIRectPtr(const SkIRect* rect);
+ void addRRect(const SkRRect&);
void addRegion(const SkRegion& region);
void addText(const void* text, size_t byteLength);
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index 5740a19..c409cd6 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -227,6 +227,30 @@
fType = kComplex_Type;
}
+///////////////////////////////////////////////////////////////////////////////
+
+uint32_t SkRRect::writeToMemory(void* buffer) const {
+ SkASSERT(kSizeInMemory == sizeof(SkRect) + sizeof(fRadii));
+
+ memcpy(buffer, &fRect, sizeof(SkRect));
+ memcpy((char*)buffer + sizeof(SkRect), fRadii, sizeof(fRadii));
+ return kSizeInMemory;
+}
+
+uint32_t SkRRect::readFromMemory(const void* buffer) {
+ SkScalar storage[12];
+ SkASSERT(sizeof(storage) == kSizeInMemory);
+
+ // we make a local copy, to ensure alignment before we cast
+ memcpy(storage, buffer, kSizeInMemory);
+
+ this->setRectRadii(*(const SkRect*)&storage[0],
+ (const SkVector*)&storage[4]);
+ return kSizeInMemory;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
#ifdef SK_DEBUG
void SkRRect::validate() const {
bool allRadiiZero = (0 == fRadii[0].fX && 0 == fRadii[0].fY);
diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h
index 31803ea..b563652 100644
--- a/src/pipe/SkGPipePriv.h
+++ b/src/pipe/SkGPipePriv.h
@@ -37,6 +37,7 @@
kClipPath_DrawOp,
kClipRegion_DrawOp,
kClipRect_DrawOp,
+ kClipRRect_DrawOp,
kConcat_DrawOp,
kDrawBitmap_DrawOp,
kDrawBitmapMatrix_DrawOp,
@@ -44,6 +45,7 @@
kDrawBitmapRectToRect_DrawOp,
kDrawClear_DrawOp,
kDrawData_DrawOp,
+ kDrawOval_DrawOp,
kDrawPaint_DrawOp,
kDrawPath_DrawOp,
kDrawPicture_DrawOp,
@@ -51,6 +53,7 @@
kDrawPosText_DrawOp,
kDrawPosTextH_DrawOp,
kDrawRect_DrawOp,
+ kDrawRRect_DrawOp,
kDrawSprite_DrawOp,
kDrawText_DrawOp,
kDrawTextOnPath_DrawOp,
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 1f13daf..8a86c58 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -21,6 +21,7 @@
#include "SkOrderedReadBuffer.h"
#include "SkPathEffect.h"
#include "SkRasterizer.h"
+#include "SkRRect.h"
#include "SkShader.h"
#include "SkTypeface.h"
#include "SkXfermode.h"
@@ -237,6 +238,14 @@
canvas->clipRect(*rect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
}
+static void clipRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+ SkGPipeState* state) {
+ SkRRect rrect;
+ reader->readRRect(&rrect);
+ bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
+ canvas->clipRRect(rrect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
+}
+
///////////////////////////////////////////////////////////////////////////////
static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -332,6 +341,14 @@
}
}
+static void drawOval_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+ SkGPipeState* state) {
+ const SkRect* rect = skip<SkRect>(reader);
+ if (state->shouldDraw()) {
+ canvas->drawOval(*rect, state->paint());
+ }
+}
+
static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
const SkRect* rect = skip<SkRect>(reader);
@@ -340,6 +357,15 @@
}
}
+static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+ SkGPipeState* state) {
+ SkRRect rrect;
+ reader->readRRect(&rrect);
+ if (state->shouldDraw()) {
+ canvas->drawRRect(rrect, state->paint());
+ }
+}
+
static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
SkPath path;
@@ -677,6 +703,7 @@
clipPath_rp,
clipRegion_rp,
clipRect_rp,
+ clipRRect_rp,
concat_rp,
drawBitmap_rp,
drawBitmapMatrix_rp,
@@ -684,6 +711,7 @@
drawBitmapRect_rp,
drawClear_rp,
drawData_rp,
+ drawOval_rp,
drawPaint_rp,
drawPath_rp,
drawPicture_rp,
@@ -691,6 +719,7 @@
drawPosText_rp,
drawPosTextH_rp,
drawRect_rp,
+ drawRRect_rp,
drawSprite_rp,
drawText_rp,
drawTextOnPath_rp,
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index f0b4e0a..cfd1e7c 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -21,12 +21,17 @@
#include "SkPathEffect.h"
#include "SkPictureFlat.h"
#include "SkRasterizer.h"
+#include "SkRRect.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkTSearch.h"
#include "SkTypeface.h"
#include "SkWriter32.h"
+enum {
+ kSizeOfFlatRRect = sizeof(SkRect) + 4 * sizeof(SkVector)
+};
+
static bool isCrossProcess(uint32_t flags) {
return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag);
}
@@ -208,8 +213,8 @@
virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
- virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
- bool doAntiAlias = false) SK_OVERRIDE;
+ virtual bool clipRect(const SkRect&, SkRegion::Op op, bool doAntiAlias = false) SK_OVERRIDE;
+ virtual bool clipRRect(const SkRRect&, SkRegion::Op op, bool doAntiAlias = false) SK_OVERRIDE;
virtual bool clipPath(const SkPath& path, SkRegion::Op op,
bool doAntiAlias = false) SK_OVERRIDE;
virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE;
@@ -217,7 +222,9 @@
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
const SkPaint&) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE;
virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE;
virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
const SkPaint*) SK_OVERRIDE;
@@ -625,6 +632,17 @@
return this->INHERITED::clipRect(rect, rgnOp, doAntiAlias);
}
+bool SkGPipeCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op rgnOp,
+ bool doAntiAlias) {
+ NOTIFY_SETUP(this);
+ if (this->needOpBytes(kSizeOfFlatRRect)) {
+ unsigned flags = doAntiAlias & kClip_HasAntiAlias_DrawOpFlag;
+ this->writeOp(kClipRRect_DrawOp, flags, rgnOp);
+ fWriter.writeRRect(rrect);
+ }
+ return this->INHERITED::clipRRect(rrect, rgnOp, doAntiAlias);
+}
+
bool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp,
bool doAntiAlias) {
NOTIFY_SETUP(this);
@@ -683,6 +701,15 @@
}
}
+void SkGPipeCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+ NOTIFY_SETUP(this);
+ this->writePaint(paint);
+ if (this->needOpBytes(sizeof(SkRect))) {
+ this->writeOp(kDrawOval_DrawOp);
+ fWriter.writeRect(rect);
+ }
+}
+
void SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
NOTIFY_SETUP(this);
this->writePaint(paint);
@@ -692,6 +719,15 @@
}
}
+void SkGPipeCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ NOTIFY_SETUP(this);
+ this->writePaint(paint);
+ if (this->needOpBytes(kSizeOfFlatRRect)) {
+ this->writeOp(kDrawRRect_DrawOp);
+ fWriter.writeRRect(rrect);
+ }
+}
+
void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
NOTIFY_SETUP(this);
this->writePaint(paint);
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index 7ea3bbb..c827be6 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -14,6 +14,7 @@
#include "SkDrawFilter.h"
#include "SkGPipe.h"
#include "SkPaint.h"
+#include "SkRRect.h"
#include "SkShader.h"
enum {
@@ -782,6 +783,15 @@
return val;
}
+bool SkDeferredCanvas::clipRRect(const SkRRect& rrect,
+ SkRegion::Op op,
+ bool doAntiAlias) {
+ this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias);
+ bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias);
+ this->recordedDrawCommand();
+ return val;
+}
+
bool SkDeferredCanvas::clipPath(const SkPath& path,
SkRegion::Op op,
bool doAntiAlias) {
@@ -826,17 +836,35 @@
this->recordedDrawCommand();
}
+void SkDeferredCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
+ this->drawingCanvas()->drawOval(rect, paint);
+ this->recordedDrawCommand();
+}
+
void SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
if (fDeferredDrawing && this->isFullFrame(&rect, &paint) &&
isPaintOpaque(&paint)) {
this->getDeferredDevice()->skipPendingCommands();
}
-
+
AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
this->drawingCanvas()->drawRect(rect, paint);
this->recordedDrawCommand();
}
+void SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ if (rrect.isRect()) {
+ this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
+ } else if (rrect.isOval()) {
+ this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
+ } else {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
+ this->drawingCanvas()->drawRRect(rrect, paint);
+ this->recordedDrawCommand();
+ }
+}
+
void SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
this->drawingCanvas()->drawPath(path, paint);
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 9135849..2722fb4 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -8,6 +8,7 @@
#include "SkDumpCanvas.h"
#include "SkPicture.h"
#include "SkPixelRef.h"
+#include "SkRRect.h"
#include "SkString.h"
#include <stdarg.h>
@@ -31,6 +32,31 @@
str->appendf("[%d,%d %d:%d]", r.fLeft, r.fTop, r.width(), r.height());
}
+static void toString(const SkRRect& rrect, SkString* str) {
+ SkRect r = rrect.getBounds();
+ str->appendf("[%g,%g %g:%g]",
+ SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop),
+ SkScalarToFloat(r.width()), SkScalarToFloat(r.height()));
+ if (rrect.isOval()) {
+ str->append("()");
+ } else if (rrect.isSimple()) {
+ const SkVector& rad = rrect.getSimpleRadii();
+ str->appendf("(%g,%g)", rad.x(), rad.y());
+ } else if (rrect.isComplex()) {
+ SkVector radii[4] = {
+ rrect.radii(SkRRect::kUpperLeft_Corner),
+ rrect.radii(SkRRect::kUpperRight_Corner),
+ rrect.radii(SkRRect::kLowerRight_Corner),
+ rrect.radii(SkRRect::kLowerLeft_Corner),
+ };
+ str->appendf("(%g,%g %g,%g %g,%g %g,%g)",
+ radii[0].x(), radii[0].y(),
+ radii[1].x(), radii[1].y(),
+ radii[2].x(), radii[2].y(),
+ radii[3].x(), radii[3].y());
+ }
+}
+
static void dumpVerbs(const SkPath& path, SkString* str) {
SkPath::Iter iter(path, false);
SkPoint pts[4];
@@ -273,6 +299,14 @@
return this->INHERITED::clipRect(rect, op, doAA);
}
+bool SkDumpCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ SkString str;
+ toString(rrect, &str);
+ this->dump(kClip_Verb, NULL, "clipRRect(%s %s %s)", str.c_str(), toString(op),
+ bool_to_aastring(doAA));
+ return this->INHERITED::clipRRect(rrect, op, doAA);
+}
+
bool SkDumpCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
SkString str;
toString(path, &str);
@@ -301,12 +335,24 @@
count);
}
+void SkDumpCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+ SkString str;
+ toString(rect, &str);
+ this->dump(kDrawOval_Verb, &paint, "drawOval(%s)", str.c_str());
+}
+
void SkDumpCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
SkString str;
toString(rect, &str);
this->dump(kDrawRect_Verb, &paint, "drawRect(%s)", str.c_str());
}
+void SkDumpCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ SkString str;
+ toString(rrect, &str);
+ this->dump(kDrawRRect_Verb, &paint, "drawRRect(%s)", str.c_str());
+}
+
void SkDumpCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
SkString str;
toString(path, &str);
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 3b78163..d59d559 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -144,6 +144,14 @@
return this->INHERITED::clipRect(rect, op, doAA);
}
+bool SkNWayCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ Iter iter(fList);
+ while (iter.next()) {
+ iter->clipRRect(rrect, op, doAA);
+ }
+ return this->INHERITED::clipRRect(rrect, op, doAA);
+}
+
bool SkNWayCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
Iter iter(fList);
while (iter.next()) {
@@ -175,6 +183,13 @@
}
}
+void SkNWayCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+ Iter iter(fList);
+ while (iter.next()) {
+ iter->drawOval(rect, paint);
+ }
+}
+
void SkNWayCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
Iter iter(fList);
while (iter.next()) {
@@ -182,6 +197,13 @@
}
}
+void SkNWayCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ Iter iter(fList);
+ while (iter.next()) {
+ iter->drawRRect(rrect, paint);
+ }
+}
+
void SkNWayCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
Iter iter(fList);
while (iter.next()) {
diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp
index e245c73..4af509d 100644
--- a/src/utils/SkProxyCanvas.cpp
+++ b/src/utils/SkProxyCanvas.cpp
@@ -62,6 +62,10 @@
return fProxy->clipRect(rect, op, doAA);
}
+bool SkProxyCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ return fProxy->clipRRect(rrect, op, doAA);
+}
+
bool SkProxyCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
return fProxy->clipPath(path, op, doAA);
}
@@ -79,10 +83,18 @@
fProxy->drawPoints(mode, count, pts, paint);
}
+void SkProxyCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+ fProxy->drawOval(rect, paint);
+}
+
void SkProxyCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
fProxy->drawRect(rect, paint);
}
+void SkProxyCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ fProxy->drawRRect(rrect, paint);
+}
+
void SkProxyCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
fProxy->drawPath(path, paint);
}