aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-11-06 14:10:54 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-11-07 01:51:31 +0000
commit7c02cc7934d08da3217ff9a0baae72cb93b09c6b (patch)
tree8f6ff7a992a2bddbfd0c28bfad74572aa17feb90
parent61ffd53a906524836e2704b89637cceb487da76c (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.cpp32
-rw-r--r--samplecode/SamplePathText.cpp33
-rw-r--r--tools/sk_tool_utils.cpp15
-rw-r--r--tools/sk_tool_utils.h12
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