diff options
author | Chris Dalton <csmartdalton@google.com> | 2017-11-06 14:10:54 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-07 01:51:31 +0000 |
commit | 7c02cc7934d08da3217ff9a0baae72cb93b09c6b (patch) | |
tree | 8f6ff7a992a2bddbfd0c28bfad74572aa17feb90 | |
parent | 61ffd53a906524836e2704b89637cceb487da76c (diff) |
Add clipping options to path text bench and samples
Bug: skia:
Change-Id: I632a2fa5627ef1438d9ab451318a42d12c61b802
Reviewed-on: https://skia-review.googlesource.com/67683
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
-rw-r--r-- | bench/PathTextBench.cpp | 32 | ||||
-rw-r--r-- | samplecode/SamplePathText.cpp | 33 | ||||
-rw-r--r-- | tools/sk_tool_utils.cpp | 15 | ||||
-rw-r--r-- | tools/sk_tool_utils.h | 12 |
4 files changed, 82 insertions, 10 deletions
diff --git a/bench/PathTextBench.cpp b/bench/PathTextBench.cpp index 6551fa5f27..8920223c35 100644 --- a/bench/PathTextBench.cpp +++ b/bench/PathTextBench.cpp @@ -11,6 +11,7 @@ #include "SkPaint.h" #include "SkPath.h" #include "SkRandom.h" +#include "sk_tool_utils.h" static constexpr int kScreenWidth = 1500; static constexpr int kScreenHeight = 1500; @@ -27,12 +28,19 @@ static_assert(52 == kNumGlyphs, "expected 52 glyphs"); */ class PathTextBench : public Benchmark { public: - PathTextBench(bool cached) : fCached(cached) {} + PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {} bool isVisual() override { return true; } private: const char* onGetName() override { - return fCached ? "path_text" : "path_text_uncached"; + fName = "path_text"; + if (fClipped) { + fName.append("_clipped"); + } + if (fUncached) { + fName.append("_uncached"); + } + return fName.c_str(); } SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); } @@ -43,7 +51,7 @@ private: for (int i = 0; i < kNumGlyphs; ++i) { SkGlyphID id = cache->unicharToGlyph(kGlyphs[i]); cache->getScalerContext()->getPath(SkPackedGlyphID(id), &fGlyphs[i]); - fGlyphs[i].setIsVolatile(!fCached); + fGlyphs[i].setIsVolatile(fUncached); } SkRandom rand; @@ -67,10 +75,18 @@ private: fPaints[i].setAntiAlias(true); fPaints[i].setColor(rand.nextU() | 0x80808080); } + + if (fClipped) { + fClipPath = sk_tool_utils::make_star(SkRect::MakeIWH(kScreenWidth,kScreenHeight), 11,3); + fClipPath.setIsVolatile(fUncached); + } } void onDraw(int loops, SkCanvas* canvas) override { SkAutoCanvasRestore acr(canvas, true); + if (fClipped) { + canvas->clipPath(fClipPath, SkClipOp::kIntersect, true); + } for (int i = 0; i < kNumDraws; ++i) { const SkPath& glyph = fGlyphs[i % kNumGlyphs]; canvas->setMatrix(fXforms[i]); @@ -78,13 +94,17 @@ private: } } - const bool fCached; + const bool fClipped; + const bool fUncached; + SkString fName; SkPath fGlyphs[kNumGlyphs]; SkPaint fPaints[kNumDraws]; SkMatrix fXforms[kNumDraws]; + SkPath fClipPath; typedef Benchmark INHERITED; }; -DEF_BENCH(return new PathTextBench(false);) -DEF_BENCH(return new PathTextBench(true);) +DEF_BENCH(return new PathTextBench(false, false);) +DEF_BENCH(return new PathTextBench(false, true);) +DEF_BENCH(return new PathTextBench(true, true);) diff --git a/samplecode/SamplePathText.cpp b/samplecode/SamplePathText.cpp index 5df223b32d..12bb282a74 100644 --- a/samplecode/SamplePathText.cpp +++ b/samplecode/SamplePathText.cpp @@ -13,6 +13,7 @@ #include "SkPath.h" #include "SkRandom.h" #include "SkTaskGroup.h" +#include "sk_tool_utils.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Static text from paths. @@ -21,7 +22,7 @@ public: constexpr static int kNumPaths = 1500; virtual const char* getName() const { return "PathText"; } - PathText() : fRand(25) { + PathText() { SkPaint defaultPaint; SkAutoGlyphCache agc(defaultPaint, nullptr, &SkMatrix::I()); SkGlyphCache* cache = agc.getCache(); @@ -53,10 +54,32 @@ public: SampleCode::TitleR(evt, this->getName()); return true; } + SkUnichar unichar; + if (SampleCode::CharQ(*evt, &unichar)) { + if (unichar == 'X') { + fDoClip = !fDoClip; + this->inval(nullptr); + return true; + } + } return this->INHERITED::onQuery(evt); } void onDrawContent(SkCanvas* canvas) override { + if (fDoClip) { + SkMatrix oldMatrix = canvas->getTotalMatrix(); + canvas->setMatrix(SkMatrix::MakeScale(this->width(), this->height())); + canvas->save(); + canvas->clipPath(fClipPath, SkClipOp::kDifference, true); + canvas->clear(SK_ColorBLACK); + canvas->restore(); + canvas->clipPath(fClipPath, SkClipOp::kIntersect, true); + canvas->setMatrix(oldMatrix); + } + this->drawGlyphs(canvas); + } + + virtual void drawGlyphs(SkCanvas* canvas) { for (Glyph& glyph : fGlyphs) { SkAutoCanvasRestore acr(canvas, true); canvas->translate(glyph.fPosition.x(), glyph.fPosition.y()); @@ -81,7 +104,9 @@ protected: }; Glyph fGlyphs[kNumPaths]; - SkRandom fRand; + SkRandom fRand{25}; + SkPath fClipPath = sk_tool_utils::make_star(SkRect{0,0,1,1}, 11, 3); + bool fDoClip = false; typedef SampleView INHERITED; }; @@ -193,7 +218,7 @@ public: std::swap(fFrontMatrices, fBackMatrices); } - void onDrawContent(SkCanvas* canvas) override { + void drawGlyphs(SkCanvas* canvas) override { for (int i = 0; i < kNumPaths; ++i) { SkAutoCanvasRestore acr(canvas, true); canvas->concat(fFrontMatrices[i]); @@ -299,7 +324,7 @@ public: fFrontPaths.swap(fBackPaths); } - void onDrawContent(SkCanvas* canvas) override { + void drawGlyphs(SkCanvas* canvas) override { for (int i = 0; i < kNumPaths; ++i) { canvas->drawPath(fFrontPaths[i], fGlyphs[i].fPaint); } diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp index 0a93db4239..56c1f48ed9 100644 --- a/tools/sk_tool_utils.cpp +++ b/tools/sk_tool_utils.cpp @@ -263,6 +263,21 @@ void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, add_to_text_blob_w_len(builder, text, strlen(text), origPaint, x, y); } +SkPath make_star(const SkRect& bounds, int numPts, int step) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(0,-1); + for (int i = 1; i < numPts; ++i) { + int idx = i*step; + SkScalar theta = idx * 2*SK_ScalarPI/numPts + SK_ScalarPI/2; + SkScalar x = SkScalarCos(theta); + SkScalar y = -SkScalarSin(theta); + path.lineTo(x, y); + } + path.transform(SkMatrix::MakeRectToRect(path.getBounds(), bounds, SkMatrix::kFill_ScaleToFit)); + return path; +} + #if !defined(__clang__) && defined(_MSC_VER) // MSVC takes ~2 minutes to compile this function with optimization. // We don't really care to wait that long for this function. diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h index b1bde770ea..2931243b9b 100644 --- a/tools/sk_tool_utils.h +++ b/tools/sk_tool_utils.h @@ -135,6 +135,18 @@ namespace sk_tool_utils { void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPaint& origPaint, SkScalar x, SkScalar y); + // Constructs a star by walking a 'numPts'-sided regular polygon with even/odd fill: + // + // moveTo(pts[0]); + // lineTo(pts[step % numPts]); + // ... + // lineTo(pts[(step * (N - 1)) % numPts]); + // + // numPts=5, step=2 will produce a classic five-point star. + // + // numPts and step must be co-prime. + SkPath make_star(const SkRect& bounds, int numPts = 5, int step = 2); + void make_big_path(SkPath& path); // Return a blurred version of 'src'. This doesn't use a separable filter |