From: reed@google.com Date: Wed, 12 Dec 2012 19:02:53 +0000 (+0000) Subject: make RRect and Oval first-class drawing primitives in SkCanvas. X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~14084 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=68d61ed83ec7b6e98e9623c2f5c9e7b1a32d25bb;p=platform%2Fupstream%2FlibSkiaSharp.git 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 SkDraw; class SkDrawFilter; class SkMetaData; class SkPicture; +class SkRRect; class SkSurface_Base; /** \class SkCanvas @@ -339,20 +340,35 @@ public: */ 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 @@ public: @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 SkWriter32; class SkAutoPathBoundsUpdate; class SkString; class SkPathRef; +class SkRRect; #ifndef SK_DEBUG_PATH_REF #define SK_DEBUG_PATH_REF 0 @@ -656,6 +657,11 @@ public: 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 @@ protected: // 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 @@ public: /** * Returns the RR's sub type. */ - Type type() const { + Type getType() const { SkDEBUGCODE(this->validate();) if (kUnknown_Type == fType) { @@ -93,6 +95,14 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: // 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 @@ public: 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 @@ public: 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 @@ public: kDrawPaint_Verb, kDrawPoints_Verb, + kDrawOval_Verb, kDrawRect_Verb, + kDrawRRect_Verb, kDrawPath_Verb, kDrawBitmap_Verb, kDrawText_Verb, @@ -76,6 +78,7 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ static bool clipPathHelper(const SkCanvas* canvas, SkRasterClip* currClip, } } +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 @@ void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 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 @@ void SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 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 @@ void SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 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 @@ void SkPath::addRoundRect(const SkRect& rect, const SkScalar rad[], 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(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 @@ enum DrawType { CLIP_PATH, CLIP_REGION, CLIP_RECT, + CLIP_RRECT, CONCAT, DRAW_BITMAP, DRAW_BITMAP_MATRIX, @@ -36,6 +37,7 @@ enum DrawType { DRAW_BITMAP_RECT_TO_RECT, DRAW_CLEAR, DRAW_DATA, + DRAW_OVAL, DRAW_PAINT, DRAW_PATH, DRAW_PICTURE, @@ -45,6 +47,7 @@ enum DrawType { 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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { #endif #ifdef SPEW_CLIP_SKIPPING - SkipClipRec skipRect, skipRegion, skipPath; + SkipClipRec skipRect, skipRRect, skipRegion, skipPath; #endif #ifdef SK_BUILD_FOR_ANDROID @@ -731,7 +731,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { 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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { 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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { 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(), paint); + } break; case DRAW_PAINT: canvas.drawPaint(*getPaint(reader)); break; @@ -837,6 +857,11 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { const SkPaint& paint = *getPaint(reader); canvas.drawRect(reader.skipT(), 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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { #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 @@ private: 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 @@ static inline uint32_t getSkipableSize(unsigned drawType) { 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 @@ static inline uint32_t getSkipableSize(unsigned drawType) { 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 @@ static inline uint32_t getSkipableSize(unsigned drawType) { 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 @@ bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 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 @@ void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts 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 @@ void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { 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::addIRectPtr(const SkIRect* rect) { } } +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 @@ public: 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 @@ private: 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 @@ void SkRRect::computeType() const { 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 @@ enum DrawOps { kClipPath_DrawOp, kClipRegion_DrawOp, kClipRect_DrawOp, + kClipRRect_DrawOp, kConcat_DrawOp, kDrawBitmap_DrawOp, kDrawBitmapMatrix_DrawOp, @@ -44,6 +45,7 @@ enum DrawOps { kDrawBitmapRectToRect_DrawOp, kDrawClear_DrawOp, kDrawData_DrawOp, + kDrawOval_DrawOp, kDrawPaint_DrawOp, kDrawPath_DrawOp, kDrawPicture_DrawOp, @@ -51,6 +53,7 @@ enum DrawOps { 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 @@ static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 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 drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, } } +static void drawOval_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, + SkGPipeState* state) { + const SkRect* rect = skip(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(reader); @@ -340,6 +357,15 @@ static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, } } +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 @@ static const ReadProc gReadTable[] = { clipPath_rp, clipRegion_rp, clipRect_rp, + clipRRect_rp, concat_rp, drawBitmap_rp, drawBitmapMatrix_rp, @@ -684,6 +711,7 @@ static const ReadProc gReadTable[] = { drawBitmapRect_rp, drawClear_rp, drawData_rp, + drawOval_rp, drawPaint_rp, drawPath_rp, drawPicture_rp, @@ -691,6 +719,7 @@ static const ReadProc gReadTable[] = { 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 @@ public: 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 @@ public: 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 @@ bool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp, 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::drawPoints(PointMode mode, size_t count, } } +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::drawRect(const SkRect& rect, const SkPaint& paint) { } } +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 @@ bool SkDeferredCanvas::clipRect(const SkRect& rect, 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 @@ void SkDeferredCanvas::drawPoints(PointMode mode, size_t count, 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 @@ -31,6 +32,31 @@ static void toString(const SkIRect& r, SkString* str) { 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 @@ bool SkDumpCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 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 @@ void SkDumpCanvas::drawPoints(PointMode mode, size_t count, 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 @@ bool SkNWayCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 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::drawPoints(PointMode mode, size_t count, const SkPoint pts[], } } +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::drawRect(const SkRect& rect, const SkPaint& paint) { } } +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 @@ bool SkProxyCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 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 @@ void SkProxyCanvas::drawPoints(PointMode mode, size_t count, 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); }