Skip to content

Instantly share code, notes, and snippets.

@HalCanary
Last active August 16, 2018 15:50
Show Gist options
  • Save HalCanary/0310ea8efe4ba8cbad9774e759f130a0 to your computer and use it in GitHub Desktop.
Save HalCanary/0310ea8efe4ba8cbad9774e759f130a0 to your computer and use it in GitHub Desktop.
/*
Here's a proposal for an addition to SkPath's public API. This allows a client
to build a SkPath from two arrays with a single function call. The
implementation shown here can probably be optimized if I looked at Path's
implementation details.
This can now be done with SkParsePath::FromSVGString, but that is a far less
elegant API.
*/
////////////////////////////////////////////////////////////////////////////////
class SkPath {
public:
enum Verb : unsigned char {
kMove_Verb,
kLine_Verb,
kQuad_Verb,
kConic_Verb,
kCubic_Verb,
kClose_Verb,
kDone_Verb,
};
static int VerbCount(SkPath::Verb verb) {
switch (verb) {
case SkPath::kMove_Verb: return 2;
case SkPath::kLine_Verb: return 2;
case SkPath::kQuad_Verb: return 4;
case SkPath::kConic_Verb: return 5;
case SkPath::kCubic_Verb: return 6;
case SkPath::kClose_Verb: return 0;
case SkPath::kDone_Verb: return -1;
default: return -1;
}
}
// Consumes VerbCount(verb) SkScalars from the values array.
SkPath& doVerb(SkPath::Verb verb, const SkScalar* values);
// A path can now be build directly from two arrays:
SkPath& doVerbs(const SkPath::Verb* verbs, size_t verbCount,
const SkScalar* values, size_t valueCount);
};
////////////////////////////////////////////////////////////////////////////////
SkPath& SkPath::doVerb(SkPath::Verb verb, const SkScalar* x) {
SkASSERT(x);
switch (verb) {
case SkPath::kMove_Verb: this->moveTo(x[0], x[1]); break;
case SkPath::kLine_Verb: this->lineTo(x[0], x[1]); break;
case SkPath::kQuad_Verb: this->quadTo(x[0], x[1], x[2], x[3]); break;
case SkPath::kConic_Verb: this->conicTo(x[0], x[1], x[2], x[3], x[4]); break;
case SkPath::kCubic_Verb: this->cubicTo(x[0], x[1], x[2], x[3], x[4], x[5]); break;
case SkPath::kClose_Verb: this->close(); break;
case SkPath::kDone_Verb:
default:
break;
}
return *this;
}
SkPath& SkPath::doVerbs(const SkPath::Verb* verbs, size_t verbCount,
const SkScalar* values, size_t valueCount) {
const SkPath::Verb* verbStop = verbs + verbCount;
const SkScalar* valueStop = values + valueCount;
while (verbs < verbStop) {
int count = SkPath::VerbCount(*verbs);
if (count < 0 || values + count > valueStop) {
break;
}
this->doVerb(*verbs++, values);
values += count;
}
return *this;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment