From ac3aa245acc7b469aa2f0d0078e53401d78ac8b9 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Fri, 19 Aug 2016 11:25:19 -0700 Subject: Plumb drawArc to SkDevice. Plumbs the drawArc canvas method down to SkDevice without converting to a path. Plumbs through the various recording canvas classes. BUG=skia:5227 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2257023003 Review-Url: https://codereview.chromium.org/2257023003 --- include/core/SkCanvas.h | 6 ++-- include/core/SkDevice.h | 3 ++ include/private/SkRecords.h | 7 ++++ include/utils/SkDumpCanvas.h | 2 ++ include/utils/SkLuaCanvas.h | 1 + include/utils/SkNWayCanvas.h | 1 + include/utils/SkPaintFilterCanvas.h | 2 ++ src/core/SkCanvas.cpp | 33 +++++++++++++----- src/core/SkDevice.cpp | 14 ++++++++ src/core/SkLiteDL.cpp | 23 ++++++++++-- src/core/SkLiteDL.h | 1 + src/core/SkLiteRecorder.cpp | 6 +++- src/core/SkLiteRecorder.h | 1 + src/core/SkPictureFlat.h | 3 +- src/core/SkPicturePlayback.cpp | 11 ++++++ src/core/SkPictureRecord.cpp | 14 ++++++++ src/core/SkPictureRecord.h | 1 + src/core/SkRecordDraw.cpp | 3 ++ src/core/SkRecorder.cpp | 5 +++ src/core/SkRecorder.h | 1 + src/utils/SkDeferredCanvas.cpp | 7 ++++ src/utils/SkDeferredCanvas.h | 1 + src/utils/SkDumpCanvas.cpp | 8 +++++ src/utils/SkLuaCanvas.cpp | 10 ++++++ src/utils/SkNWayCanvas.cpp | 8 +++++ src/utils/SkPaintFilterCanvas.cpp | 8 +++++ src/utils/SkShadowPaintFilterCanvas.cpp | 8 +++++ src/utils/SkShadowPaintFilterCanvas.h | 2 ++ tools/android/SkAndroidSDKCanvas.cpp | 5 +++ tools/android/SkAndroidSDKCanvas.h | 2 ++ tools/debugger/SkDebugCanvas.cpp | 5 +++ tools/debugger/SkDebugCanvas.h | 1 + tools/debugger/SkDrawCommand.cpp | 62 ++++++++++++++++++++++++++++++++- tools/debugger/SkDrawCommand.h | 19 ++++++++++ 34 files changed, 268 insertions(+), 16 deletions(-) diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 52a322576e..1e0301179a 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -739,9 +739,9 @@ public: specified oval. If the sweep angle is >= 360, then the oval is drawn completely. Note that this differs slightly from SkPath::arcTo, which treats the sweep angle mod 360. - @param oval The bounds of oval used to define the shape of the arc + @param oval The bounds of oval used to define the shape of the arc. @param startAngle Starting angle (in degrees) where the arc begins - @param sweepAngle Sweep angle (in degrees) measured clockwise + @param sweepAngle Sweep angle (in degrees) measured clockwise. @param useCenter true means include the center of the oval. For filling this will draw a wedge. False means just use the arc. @param paint The paint used to draw the arc @@ -1390,6 +1390,8 @@ protected: virtual void onDrawPaint(const SkPaint&); virtual void onDrawRect(const SkRect&, const SkPaint&); virtual void onDrawOval(const SkRect&, const SkPaint&); + virtual void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, + const SkPaint&); virtual void onDrawRRect(const SkRRect&, const SkPaint&); virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&); virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[], diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 4a08b75d09..76549ca5d0 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -161,6 +161,9 @@ protected: const SkPaint& paint) = 0; virtual void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) = 0; + /** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */ + virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle, + SkScalar sweepAngle, bool useCenter, const SkPaint& paint); virtual void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) = 0; diff --git a/include/private/SkRecords.h b/include/private/SkRecords.h index 90a82ee04d..14b653190a 100644 --- a/include/private/SkRecords.h +++ b/include/private/SkRecords.h @@ -54,6 +54,7 @@ namespace SkRecords { M(ClipRRect) \ M(ClipRect) \ M(ClipRegion) \ + M(DrawArc) \ M(DrawDrawable) \ M(DrawImage) \ M(DrawImageLattice) \ @@ -214,6 +215,12 @@ RECORD(ClipRegion, 0, SkRegion::Op op); // While not strictly required, if you have an SkPaint, it's fastest to put it first. +RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkRect oval; + SkScalar startAngle; + SkScalar sweepAngle; + unsigned useCenter); RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag, SkPaint paint; SkRRect outer; diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h index fc058be657..baf509fb19 100644 --- a/include/utils/SkDumpCanvas.h +++ b/include/utils/SkDumpCanvas.h @@ -36,6 +36,7 @@ public: kDrawPaint_Verb, kDrawPoints_Verb, kDrawOval_Verb, + kDrawArc_Verb, kDrawRect_Verb, kDrawRRect_Verb, kDrawDRRect_Verb, @@ -99,6 +100,7 @@ protected: void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; diff --git a/include/utils/SkLuaCanvas.h b/include/utils/SkLuaCanvas.h index 64f285b26c..a823a47aa8 100644 --- a/include/utils/SkLuaCanvas.h +++ b/include/utils/SkLuaCanvas.h @@ -46,6 +46,7 @@ protected: void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h index a4b9c59412..2c93df9aa2 100644 --- a/include/utils/SkNWayCanvas.h +++ b/include/utils/SkNWayCanvas.h @@ -59,6 +59,7 @@ protected: void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h index 037bac6f73..63eaaa2fbc 100644 --- a/include/utils/SkPaintFilterCanvas.h +++ b/include/utils/SkPaintFilterCanvas.h @@ -31,6 +31,7 @@ public: enum Type { kPaint_Type, kPoint_Type, + kArc_Type, kBitmap_Type, kRect_Type, kRRect_Type, @@ -66,6 +67,7 @@ protected: void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index e039c60e0a..bc5e030430 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -2265,6 +2265,29 @@ void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { LOOPER_END } +void SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, + SkScalar sweepAngle, bool useCenter, + const SkPaint& paint) { + TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); + const SkRect* bounds = nullptr; + if (paint.canComputeFastBounds()) { + SkRect storage; + // Note we're using the entire oval as the bounds. + if (this->quickReject(paint.computeFastBounds(oval, &storage))) { + return; + } + bounds = &oval; + } + + LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) + + while (iter.next()) { + iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint()); + } + + LOOPER_END +} + void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); SkRect storage; @@ -3073,15 +3096,7 @@ void SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { this->drawOval(oval, paint); } else { - SkPath path; - if (useCenter) { - path.moveTo(oval.centerX(), oval.centerY()); - } - path.arcTo(oval, startAngle, sweepAngle, !useCenter); - if (useCenter) { - path.close(); - } - this->drawPath(path, paint); + this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint); } } diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 74e86dc9f0..5eaf44d419 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -73,6 +73,20 @@ SkPixelGeometry SkBaseDevice::CreateInfo::AdjustGeometry(const SkImageInfo& info return geo; } +void SkBaseDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle, + SkScalar sweepAngle, bool useCenter, const SkPaint& paint) { + SkASSERT(SkScalarAbs(sweepAngle) >= 0.f && SkScalarAbs(sweepAngle) < 360.f); + SkPath path; + if (useCenter) { + path.moveTo(oval.centerX(), oval.centerY()); + } + path.arcTo(oval, startAngle, sweepAngle, !useCenter); + if (useCenter) { + path.close(); + } + this->drawPath(draw, path, paint); +} + void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { SkPath path; diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp index c3bf976a88..f7fe578c4e 100644 --- a/src/core/SkLiteDL.cpp +++ b/src/core/SkLiteDL.cpp @@ -54,8 +54,9 @@ namespace { M(Save) M(Restore) M(SaveLayer) \ M(Concat) M(SetMatrix) M(Translate) M(TranslateZ) \ M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion) \ - M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawOval) M(DrawRRect) M(DrawDRRect) \ - M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) M(DrawShadowedPicture) \ + M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawOval) M(DrawArc) M(DrawRRect) \ + M(DrawDRRect) M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) \ + M(DrawShadowedPicture) \ M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) \ M(DrawText) M(DrawPosText) M(DrawPosTextH) \ M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob) \ @@ -195,6 +196,20 @@ namespace { SkPaint paint; void draw(SkCanvas* c, const SkMatrix&) { c->drawOval(oval, paint); } }; + struct DrawArc final : Op { + static const auto kType = Type::DrawArc; + DrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, + const SkPaint& paint) + : oval(oval), startAngle(startAngle), sweepAngle(sweepAngle), useCenter(useCenter) + , paint(paint) {} + SkRect oval; + SkScalar startAngle; + SkScalar sweepAngle; + bool useCenter; + SkPaint paint; + void draw(SkCanvas* c, const SkMatrix&) { c->drawArc(oval, startAngle, sweepAngle, + useCenter, paint); } + }; struct DrawRRect final : Op { static const auto kType = Type::DrawRRect; DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), paint(paint) {} @@ -577,6 +592,10 @@ void SkLiteDL::drawRect(const SkRect& rect, const SkPaint& paint) { void SkLiteDL::drawOval(const SkRect& oval, const SkPaint& paint) { this->push(0, oval, paint); } +void SkLiteDL::drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, + const SkPaint& paint) { + this->push(0, oval, startAngle, sweepAngle, useCenter, paint); +} void SkLiteDL::drawRRect(const SkRRect& rrect, const SkPaint& paint) { this->push(0, rrect, paint); } diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h index e80548cecd..400b242322 100644 --- a/src/core/SkLiteDL.h +++ b/src/core/SkLiteDL.h @@ -41,6 +41,7 @@ public: void drawPath (const SkPath&, const SkPaint&); void drawRect (const SkRect&, const SkPaint&); void drawOval (const SkRect&, const SkPaint&); + void drawArc (const SkRect&, SkScalar, SkScalar, bool, const SkPaint&); void drawRRect (const SkRRect&, const SkPaint&); void drawDRRect(const SkRRect&, const SkRRect&, const SkPaint&); diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp index 049ccd1afe..3b3c24cf5c 100644 --- a/src/core/SkLiteRecorder.cpp +++ b/src/core/SkLiteRecorder.cpp @@ -55,9 +55,13 @@ void SkLiteRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) { void SkLiteRecorder::onDrawRect(const SkRect& rect, const SkPaint& paint) { fDL->drawRect(rect, paint); } -void SkLiteRecorder::onDrawOval(const SkRect& oval, const SkPaint& paint) { +void SkLiteRecorder::onDrawOval(const SkRect& oval, const SkPaint& paint) { fDL->drawOval(oval, paint); } +void SkLiteRecorder::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + fDL->drawArc(oval, startAngle, sweepAngle, useCenter, paint); +} void SkLiteRecorder::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { fDL->drawRRect(rrect, paint); } diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h index 6ca03cd46c..e2d754d30d 100644 --- a/src/core/SkLiteRecorder.h +++ b/src/core/SkLiteRecorder.h @@ -36,6 +36,7 @@ public: void onDrawPath (const SkPath&, const SkPaint&) override; void onDrawRect (const SkRect&, const SkPaint&) override; void onDrawOval (const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect (const SkRRect&, const SkPaint&) override; void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index c704f29e58..a5c607dbf6 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -92,8 +92,9 @@ enum DrawType { DRAW_SHADOWED_PICTURE_LIGHTS, DRAW_IMAGE_LATTICE, + DRAW_ARC, - LAST_DRAWTYPE_ENUM = DRAW_IMAGE_LATTICE + LAST_DRAWTYPE_ENUM = DRAW_ARC }; // In the 'match' method, this constant will match any flavor of DRAW_BITMAP* diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 0ae4d058be..611b556cc0 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -188,6 +188,17 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, reader->readString(&key); canvas->drawAnnotation(rect, key.c_str(), reader->readByteArrayAsData().get()); } break; + case DRAW_ARC: { + const SkPaint* paint = fPictureData->getPaint(reader); + SkRect rect; + reader->readRect(&rect); + SkScalar startAngle = reader->readScalar(); + SkScalar sweepAngle = reader->readScalar(); + int useCenter = reader->readInt(); + if (paint) { + canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), *paint); + } + } break; case DRAW_ATLAS: { const SkPaint* paint = fPictureData->getPaint(reader); const SkImage* atlas = fPictureData->getImage(reader); diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 520451cb61..2140795b3d 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -428,6 +428,20 @@ void SkPictureRecord::onDrawOval(const SkRect& oval, const SkPaint& paint) { this->validate(initialOffset, size); } +void SkPictureRecord::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + // op + paint index + rect + start + sweep + bool (as int) + size_t size = 2 * kUInt32Size + sizeof(oval) + sizeof(startAngle) + sizeof(sweepAngle) + + sizeof(int); + size_t initialOffset = this->addDraw(DRAW_ARC, &size); + this->addPaint(paint); + this->addRect(oval); + this->addScalar(startAngle); + this->addScalar(sweepAngle); + this->addInt(useCenter); + this->validate(initialOffset, size); +} + void SkPictureRecord::onDrawRect(const SkRect& rect, const SkPaint& paint) { // op + paint index + rect size_t size = 2 * kUInt32Size + sizeof(rect); diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index ecdb368d3b..610e6d1c4c 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -187,6 +187,7 @@ protected: void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override; diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 4d27fb6968..2b7b9726bd 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -96,6 +96,7 @@ DRAW(TranslateZ, SkCanvas::translateZ(r.z)); template <> void Draw::draw(const TranslateZ& r) { } #endif +DRAW(DrawArc, drawArc(r.oval, r.startAngle, r.sweepAngle, r.useCenter, r.paint)); DRAW(DrawDRRect, drawDRRect(r.outer, r.inner, r.paint)); DRAW(DrawImage, drawImage(r.image.get(), r.left, r.top, r.paint)); @@ -413,6 +414,8 @@ private: Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); } Bounds bounds(const DrawOval& op) const { return this->adjustAndMap(op.oval, &op.paint); } + // Tighter arc bounds? + Bounds bounds(const DrawArc& op) const { return this->adjustAndMap(op.oval, &op.paint); } Bounds bounds(const DrawRRect& op) const { return this->adjustAndMap(op.rrect.rect(), &op.paint); } diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 92bb6aee5d..caa9bb58c3 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -149,6 +149,11 @@ void SkRecorder::onDrawOval(const SkRect& oval, const SkPaint& paint) { APPEND(DrawOval, paint, oval); } +void SkRecorder::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + APPEND(DrawArc, paint, oval, startAngle, sweepAngle, useCenter); +} + void SkRecorder::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { APPEND(DrawRRect, paint, rrect); } diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index d039e20e29..9f8824f85a 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -106,6 +106,7 @@ public: void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp index 14220209cc..d2f95d9317 100644 --- a/src/utils/SkDeferredCanvas.cpp +++ b/src/utils/SkDeferredCanvas.cpp @@ -324,6 +324,13 @@ void SkDeferredCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { fCanvas->drawOval(modRect, paint); } +void SkDeferredCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + SkRect modRect = rect; + this->flush_check(&modRect, &paint, kNoClip_Flag); + fCanvas->drawArc(modRect, startAngle, sweepAngle, useCenter, paint); +} + static SkRRect make_offset(const SkRRect& src, SkScalar dx, SkScalar dy) { SkRRect dst = src; dst.offset(dx, dy); diff --git a/src/utils/SkDeferredCanvas.h b/src/utils/SkDeferredCanvas.h index 6400734def..faa3d66e2c 100644 --- a/src/utils/SkDeferredCanvas.h +++ b/src/utils/SkDeferredCanvas.h @@ -63,6 +63,7 @@ protected: void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp index 5166640ca6..ca18864b7b 100644 --- a/src/utils/SkDumpCanvas.cpp +++ b/src/utils/SkDumpCanvas.cpp @@ -308,6 +308,14 @@ void SkDumpCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { this->dump(kDrawOval_Verb, &paint, "drawOval(%s)", str.c_str()); } +void SkDumpCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + SkString str; + toString(rect, &str); + this->dump(kDrawArc_Verb, &paint, "drawArc(%s, %g, %g, %d)", str.c_str(), startAngle, + sweepAngle, useCenter); +} + void SkDumpCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { SkString str; toString(rect, &str); diff --git a/src/utils/SkLuaCanvas.cpp b/src/utils/SkLuaCanvas.cpp index a3160af800..3883924c0d 100644 --- a/src/utils/SkLuaCanvas.cpp +++ b/src/utils/SkLuaCanvas.cpp @@ -179,6 +179,16 @@ void SkLuaCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { lua.pushPaint(paint, "paint"); } +void SkLuaCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + AUTO_LUA("drawArc"); + lua.pushRect(rect, "rect"); + lua.pushScalar(startAngle, "startAngle"); + lua.pushScalar(sweepAngle, "sweepAngle"); + lua.pushBool(useCenter, "useCenter"); + lua.pushPaint(paint, "paint"); +} + void SkLuaCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { AUTO_LUA("drawRect"); lua.pushRect(rect, "rect"); diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp index dc9437c404..1cd3dc4b4a 100644 --- a/src/utils/SkNWayCanvas.cpp +++ b/src/utils/SkNWayCanvas.cpp @@ -161,6 +161,14 @@ void SkNWayCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { } } +void SkNWayCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + Iter iter(fList); + while (iter.next()) { + iter->drawArc(rect, startAngle, sweepAngle, useCenter, paint); + } +} + void SkNWayCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { Iter iter(fList); while (iter.next()) { diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp index 75a7930500..15d76d6127 100644 --- a/src/utils/SkPaintFilterCanvas.cpp +++ b/src/utils/SkPaintFilterCanvas.cpp @@ -87,6 +87,14 @@ void SkPaintFilterCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { } } +void SkPaintFilterCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + AutoPaintFilter apf(this, kArc_Type, paint); + if (apf.shouldDraw()) { + this->INHERITED::onDrawArc(rect, startAngle, sweepAngle, useCenter, *apf.paint()); + } +} + void SkPaintFilterCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { AutoPaintFilter apf(this, kPath_Type, paint); if (apf.shouldDraw()) { diff --git a/src/utils/SkShadowPaintFilterCanvas.cpp b/src/utils/SkShadowPaintFilterCanvas.cpp index 31b7661296..f59facb17c 100644 --- a/src/utils/SkShadowPaintFilterCanvas.cpp +++ b/src/utils/SkShadowPaintFilterCanvas.cpp @@ -103,6 +103,14 @@ void SkShadowPaintFilterCanvas::onDrawOval(const SkRect &rect, const SkPaint &pa this->restore(); } +void SkShadowPaintFilterCanvas::onDrawArc(const SkRect &rect, SkScalar startAngle, + SkScalar sweepAngle, bool useCenter, + const SkPaint &paint) { + this->updateMatrix(); + this->INHERITED::onDrawArc(rect, startAngle, sweepAngle, useCenter, paint); + this->restore(); +} + void SkShadowPaintFilterCanvas::onDrawPath(const SkPath &path, const SkPaint &paint) { this->updateMatrix(); this->INHERITED::onDrawPath(path, paint); diff --git a/src/utils/SkShadowPaintFilterCanvas.h b/src/utils/SkShadowPaintFilterCanvas.h index ae449d64f9..892ec556e5 100644 --- a/src/utils/SkShadowPaintFilterCanvas.h +++ b/src/utils/SkShadowPaintFilterCanvas.h @@ -55,6 +55,8 @@ protected: void onDrawOval(const SkRect &rect, const SkPaint &paint) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; + void onDrawPath(const SkPath &path, const SkPaint &paint) override; void onDrawBitmap(const SkBitmap &bm, SkScalar left, SkScalar top, diff --git a/tools/android/SkAndroidSDKCanvas.cpp b/tools/android/SkAndroidSDKCanvas.cpp index 8d95d8a1b0..44ceccb15c 100644 --- a/tools/android/SkAndroidSDKCanvas.cpp +++ b/tools/android/SkAndroidSDKCanvas.cpp @@ -124,6 +124,11 @@ void SkAndroidSDKCanvas::onDrawOval(const SkRect& r, const SkPaint& paint) { FILTER(paint); fProxyTarget->drawOval(r, filteredPaint); } +void SkAndroidSDKCanvas::onDrawArc(const SkRect& r, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + FILTER(paint); + fProxyTarget->drawArc(r, startAngle, sweepAngle, useCenter, filteredPaint); +} void SkAndroidSDKCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { FILTER(paint); fProxyTarget->drawRect(r, filteredPaint); diff --git a/tools/android/SkAndroidSDKCanvas.h b/tools/android/SkAndroidSDKCanvas.h index b7be797b84..766860be2d 100644 --- a/tools/android/SkAndroidSDKCanvas.h +++ b/tools/android/SkAndroidSDKCanvas.h @@ -37,6 +37,8 @@ protected: void onDrawPoints(PointMode pMode, size_t count, const SkPoint pts[], const SkPaint& paint) override; void onDrawOval(const SkRect& r, const SkPaint& paint) override; + void onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, + const SkPaint& paint) override; void onDrawRect(const SkRect& r, const SkPaint& paint) override; void onDrawRRect(const SkRRect& r, const SkPaint& paint) override; void onDrawPath(const SkPath& path, const SkPaint& paint) override; diff --git a/tools/debugger/SkDebugCanvas.cpp b/tools/debugger/SkDebugCanvas.cpp index d5297ed980..3816ca4978 100644 --- a/tools/debugger/SkDebugCanvas.cpp +++ b/tools/debugger/SkDebugCanvas.cpp @@ -596,6 +596,11 @@ void SkDebugCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { this->addDrawCommand(new SkDrawOvalCommand(oval, paint)); } +void SkDebugCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) { + this->addDrawCommand(new SkDrawArcCommand(oval, startAngle, sweepAngle, useCenter, paint)); +} + void SkDebugCanvas::onDrawPaint(const SkPaint& paint) { this->addDrawCommand(new SkDrawPaintCommand(paint)); } diff --git a/tools/debugger/SkDebugCanvas.h b/tools/debugger/SkDebugCanvas.h index 851dfe1bd4..fd71f6921c 100644 --- a/tools/debugger/SkDebugCanvas.h +++ b/tools/debugger/SkDebugCanvas.h @@ -231,6 +231,7 @@ protected: void onDrawRect(const SkRect&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; + void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawVertices(VertexMode vmode, int vertexCount, diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp index 362325085c..65de258ed2 100644 --- a/tools/debugger/SkDrawCommand.cpp +++ b/tools/debugger/SkDrawCommand.cpp @@ -92,7 +92,9 @@ #define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors" #define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords" #define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality" - +#define SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle" +#define SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle" +#define SKDEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter" #define SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc" #define SKDEBUGCANVAS_VERB_MOVE "move" @@ -2260,6 +2262,64 @@ SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command, return new SkDrawOvalCommand(coords, paint); } +SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, + bool useCenter, const SkPaint& paint) + : INHERITED(kDrawOval_OpType) { + fOval = oval; + fStartAngle = startAngle; + fSweepAngle = sweepAngle; + fUseCenter = useCenter; + fPaint = paint; + + fInfo.push(SkObjectParser::RectToString(oval)); + fInfo.push(SkObjectParser::ScalarToString(startAngle, "StartAngle: ")); + fInfo.push(SkObjectParser::ScalarToString(sweepAngle, "SweepAngle: ")); + fInfo.push(SkObjectParser::BoolToString(useCenter)); + fInfo.push(SkObjectParser::PaintToString(paint)); +} + +void SkDrawArcCommand::execute(SkCanvas* canvas) const { + canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint); +} + +bool SkDrawArcCommand::render(SkCanvas* canvas) const { + canvas->clear(0xFFFFFFFF); + canvas->save(); + + xlate_and_scale_to_bounds(canvas, fOval); + + SkPaint p; + p.setColor(SK_ColorBLACK); + p.setStyle(SkPaint::kStroke_Style); + + canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p); + canvas->restore(); + + return true; +} + +Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const { + Json::Value result = INHERITED::toJSON(urlDataManager); + result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval); + result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle); + result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle); + result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter; + result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager); + return result; +} + +SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command, + UrlDataManager& urlDataManager) { + SkRect coords; + extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords); + SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat(); + SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat(); + bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool(); + SkPaint paint; + extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint); + return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint); +} + SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) { fPaint = paint; diff --git a/tools/debugger/SkDrawCommand.h b/tools/debugger/SkDrawCommand.h index 14a7af5882..d3f2908ee6 100644 --- a/tools/debugger/SkDrawCommand.h +++ b/tools/debugger/SkDrawCommand.h @@ -399,6 +399,25 @@ private: typedef SkDrawCommand INHERITED; }; +class SkDrawArcCommand : public SkDrawCommand { +public: + SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, + const SkPaint& paint); + void execute(SkCanvas* canvas) const override; + bool render(SkCanvas* canvas) const override; + Json::Value toJSON(UrlDataManager& urlDataManager) const override; + static SkDrawArcCommand* fromJSON(Json::Value& command, UrlDataManager& urlDataManager); + +private: + SkRect fOval; + SkScalar fStartAngle; + SkScalar fSweepAngle; + bool fUseCenter; + SkPaint fPaint; + + typedef SkDrawCommand INHERITED; +}; + class SkDrawPaintCommand : public SkDrawCommand { public: SkDrawPaintCommand(const SkPaint& paint); -- cgit v1.2.3