diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-22 15:21:18 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-22 15:21:18 +0000 |
commit | aec143824c9be4e4af6e2cb7cce3d2d2268c0b15 (patch) | |
tree | 72b17b11f32c788da1e114ebd6305f470b94acf3 | |
parent | fd4ee4dea13f083c81cc80180fa09ee0127158a1 (diff) |
Add asADash entry point into SkPathEffect to allow extracting Dash info from PathEffects
BUG=skia:
R=bsalomon@google.com, reed@google.com
Author: egdaniel@google.com
Review URL: https://codereview.chromium.org/212103010
git-svn-id: http://skia.googlecode.com/svn/trunk@14297 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | gyp/tests.gypi | 1 | ||||
-rw-r--r-- | include/core/SkPathEffect.h | 27 | ||||
-rw-r--r-- | include/core/SkPicture.h | 3 | ||||
-rw-r--r-- | include/effects/SkDashPathEffect.h | 5 | ||||
-rw-r--r-- | src/core/SkPathEffect.cpp | 4 | ||||
-rw-r--r-- | src/effects/SkDashPathEffect.cpp | 76 | ||||
-rw-r--r-- | tests/AsADashTest.cpp | 57 |
7 files changed, 149 insertions, 24 deletions
diff --git a/gyp/tests.gypi b/gyp/tests.gypi index e6c6bb0e32..f27b144dea 100644 --- a/gyp/tests.gypi +++ b/gyp/tests.gypi @@ -34,6 +34,7 @@ '../tests/ARGBImageEncoderTest.cpp', '../tests/AndroidPaintTest.cpp', '../tests/AnnotationTest.cpp', + '../tests/AsADashTest.cpp', '../tests/AtomicTest.cpp', '../tests/BBoxHierarchyTest.cpp', '../tests/BitSetTest.cpp', diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h index 86ccf86a92..638287d07c 100644 --- a/include/core/SkPathEffect.h +++ b/include/core/SkPathEffect.h @@ -104,6 +104,33 @@ public: const SkStrokeRec&, const SkMatrix&, const SkRect* cullR) const; + /** + * If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType + * and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled + * in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or + * greater to that of the effect, it will memcpy the values of the dash intervals into the + * info. Thus the general approach will be call asADash once with default info to get DashType + * and fCount. If effect can be represented as a dash pattern, allocate space for the intervals + * in info, then call asADash again with the same info and the intervals will get copied in. + */ + + enum DashType { + kNone_DashType, //!< ignores the info parameter + kDash_DashType, //!< fills in all of the info parameter + }; + + struct DashInfo { + DashInfo() : fIntervals(NULL), fCount(0), fPhase(0) {} + + SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines + // Even values represent ons, and odds offs + int32_t fCount; //!< Number of intervals in the dash. Should be even number + SkScalar fPhase; //!< Offset into the dashed interval pattern + // mod the sum of all intervals + }; + + virtual DashType asADash(DashInfo* info) const; + SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect) protected: diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index bf9ec4f8bb..996d85716e 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -324,13 +324,14 @@ protected: // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes // V23: SkPaint::FilterLevel became a real enum // V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping + // V25: SkDashPathEffect now only writes phase and interval array when flattening // Note: If the picture version needs to be increased then please follow the // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw // Only SKPs within the min/current picture version range (inclusive) can be read. static const uint32_t MIN_PICTURE_VERSION = 19; - static const uint32_t CURRENT_PICTURE_VERSION = 24; + static const uint32_t CURRENT_PICTURE_VERSION = 25; mutable uint32_t fUniqueID; diff --git a/include/effects/SkDashPathEffect.h b/include/effects/SkDashPathEffect.h index 41f8f5a43e..f69e90586a 100644 --- a/include/effects/SkDashPathEffect.h +++ b/include/effects/SkDashPathEffect.h @@ -49,6 +49,8 @@ public: const SkStrokeRec&, const SkMatrix&, const SkRect*) const SK_OVERRIDE; + virtual DashType asADash(DashInfo* info) const SK_OVERRIDE; + virtual Factory getFactory() const SK_OVERRIDE; static SkFlattenable* CreateProc(SkReadBuffer&); @@ -63,8 +65,11 @@ public: SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase); private: + void setInternalMembers(SkScalar phase); + SkScalar* fIntervals; int32_t fCount; + SkScalar fPhase; // computed from phase SkScalar fInitialDashLength; int32_t fInitialDashIndex; diff --git a/src/core/SkPathEffect.cpp b/src/core/SkPathEffect.cpp index e181320356..01d5d6f961 100644 --- a/src/core/SkPathEffect.cpp +++ b/src/core/SkPathEffect.cpp @@ -22,6 +22,10 @@ bool SkPathEffect::asPoints(PointData* results, const SkPath& src, return false; } +SkPathEffect::DashType SkPathEffect::asADash(DashInfo* info) const { + return kNone_DashType; +} + /////////////////////////////////////////////////////////////////////////////// SkPairPathEffect::SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1) diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp index 15276b684c..6f132e0be5 100644 --- a/src/effects/SkDashPathEffect.cpp +++ b/src/effects/SkDashPathEffect.cpp @@ -34,19 +34,10 @@ static SkScalar FindFirstInterval(const SkScalar intervals[], SkScalar phase, return intervals[0]; } -SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, - SkScalar phase) { - SkASSERT(intervals); - SkASSERT(count > 1 && SkAlign2(count) == count); - - fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count); - fCount = count; - +void SkDashPathEffect::setInternalMembers(SkScalar phase) { SkScalar len = 0; - for (int i = 0; i < count; i++) { - SkASSERT(intervals[i] >= 0); - fIntervals[i] = intervals[i]; - len += intervals[i]; + for (int i = 0; i < fCount; i++) { + len += fIntervals[i]; } fIntervalLength = len; @@ -74,8 +65,10 @@ SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, } SkASSERT(phase >= 0 && phase < len); - fInitialDashLength = FindFirstInterval(intervals, phase, - &fInitialDashIndex, count); + fPhase = phase; + + fInitialDashLength = FindFirstInterval(fIntervals, fPhase, + &fInitialDashIndex, fCount); SkASSERT(fInitialDashLength >= 0); SkASSERT(fInitialDashIndex >= 0 && fInitialDashIndex < fCount); @@ -84,6 +77,21 @@ SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, } } +SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, + SkScalar phase) { + SkASSERT(intervals); + SkASSERT(count > 1 && SkAlign2(count) == count); + + fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count); + fCount = count; + for (int i = 0; i < count; i++) { + SkASSERT(intervals[i] >= 0); + fIntervals[i] = intervals[i]; + } + + this->setInternalMembers(phase); +} + SkDashPathEffect::~SkDashPathEffect() { sk_free(fIntervals); } @@ -510,17 +518,24 @@ bool SkDashPathEffect::asPoints(PointData* results, return true; } +SkPathEffect::DashType SkDashPathEffect::asADash(DashInfo* info) const { + if (info) { + if (info->fCount >= fCount && NULL != info->fIntervals) { + memcpy(info->fIntervals, fIntervals, fCount * sizeof(SkScalar)); + } + info->fCount = fCount; + info->fPhase = fPhase; + } + return kDash_DashType; +} + SkFlattenable::Factory SkDashPathEffect::getFactory() const { return CreateProc; } void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); - buffer.writeInt(fInitialDashIndex); - buffer.writeScalar(fInitialDashLength); - buffer.writeScalar(fIntervalLength); - // Dummy write to stay compatible with old skps. Write will be removed in follow up patch. - buffer.writeBool(false); + buffer.writeScalar(fPhase); buffer.writeScalarArray(fIntervals, fCount); } @@ -529,10 +544,15 @@ SkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) { } SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { - fInitialDashIndex = buffer.readInt(); - fInitialDashLength = buffer.readScalar(); - fIntervalLength = buffer.readScalar(); - buffer.readBool(); // dummy read to stay compatible with old skps + bool useOldPic = buffer.pictureVersion() < 25 && 0 != buffer.pictureVersion(); + if (useOldPic) { + fInitialDashIndex = buffer.readInt(); + fInitialDashLength = buffer.readScalar(); + fIntervalLength = buffer.readScalar(); + buffer.readBool(); // Dummy for old ScalarToFit field + } else { + fPhase = buffer.readScalar(); + } fCount = buffer.getArrayCount(); size_t allocSize = sizeof(SkScalar) * fCount; @@ -542,4 +562,14 @@ SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { } else { fIntervals = NULL; } + + if (useOldPic) { + fPhase = 0; + for (int i = 0; i < fInitialDashIndex; ++i) { + fPhase += fIntervals[i]; + } + fPhase += fInitialDashLength; + } else { + this->setInternalMembers(fPhase); + } } diff --git a/tests/AsADashTest.cpp b/tests/AsADashTest.cpp new file mode 100644 index 0000000000..47f19717a4 --- /dev/null +++ b/tests/AsADashTest.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Test.h" + +#include "SkPathEffect.h" +#include "SkDashPathEffect.h" +#include "SkCornerPathEffect.h" + +DEF_TEST(AsADashTest_noneDash, reporter) { + SkAutoTUnref<SkCornerPathEffect> pe(SkCornerPathEffect::Create(1.0)); + SkPathEffect::DashInfo info; + + SkPathEffect::DashType dashType = pe->asADash(&info); + REPORTER_ASSERT(reporter, SkPathEffect::kNone_DashType == dashType); +} + +DEF_TEST(AsADashTest_nullInfo, reporter) { + SkScalar inIntervals[] = { 4.0, 2.0, 1.0, 3.0 }; + const SkScalar phase = 2.0; + SkAutoTUnref<SkDashPathEffect> pe(SkDashPathEffect::Create(inIntervals, 4, phase)); + + SkPathEffect::DashType dashType = pe->asADash(NULL); + REPORTER_ASSERT(reporter, SkPathEffect::kDash_DashType == dashType); +} + +DEF_TEST(AsADashTest_usingDash, reporter) { + SkScalar inIntervals[] = { 4.0, 2.0, 1.0, 3.0 }; + SkScalar totalIntSum = 10.0; + const SkScalar phase = 2.0; + + SkAutoTUnref<SkDashPathEffect> pe(SkDashPathEffect::Create(inIntervals, 4, phase)); + + SkPathEffect::DashInfo info; + + SkPathEffect::DashType dashType = pe->asADash(&info); + REPORTER_ASSERT(reporter, SkPathEffect::kDash_DashType == dashType); + REPORTER_ASSERT(reporter, 4 == info.fCount); + REPORTER_ASSERT(reporter, SkScalarMod(phase, totalIntSum) == info.fPhase); + + // Since it is a kDash_DashType, allocate space for the intervals and recall asADash + SkAutoTArray<SkScalar> intervals(info.fCount); + info.fIntervals = intervals.get(); + pe->asADash(&info); + REPORTER_ASSERT(reporter, inIntervals[0] == info.fIntervals[0]); + REPORTER_ASSERT(reporter, inIntervals[1] == info.fIntervals[1]); + REPORTER_ASSERT(reporter, inIntervals[2] == info.fIntervals[2]); + REPORTER_ASSERT(reporter, inIntervals[3] == info.fIntervals[3]); + + // Make sure nothing else has changed on us + REPORTER_ASSERT(reporter, 4 == info.fCount); + REPORTER_ASSERT(reporter, SkScalarMod(phase, totalIntSum) == info.fPhase); +} |