Add alt path dumper that outputs for SkPath::Make()

Change-Id: I85f285c32229d0999d187777436c3875e9884fef
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/341724
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-12-08 12:49:11 -05:00 committed by Skia Commit-Bot
parent b87975c133
commit e5d9bbfa5b
2 changed files with 74 additions and 0 deletions

View File

@ -1697,6 +1697,10 @@ public:
void dump() const { this->dump(nullptr, false); }
void dumpHex() const { this->dump(nullptr, true); }
// Like dump(), but outputs for the SkPath::Make() factory
void dumpArrays(SkWStream* stream, bool dumpAsHex) const;
void dumpArrays() const { this->dumpArrays(nullptr, false); }
/** Writes SkPath to buffer, returning the number of bytes written.
Pass nullptr to obtain the storage size.

View File

@ -1939,6 +1939,76 @@ void SkPath::dump(SkWStream* wStream, bool dumpAsHex) const {
}
}
void SkPath::dumpArrays(SkWStream* wStream, bool dumpAsHex) const {
SkString builder;
auto bool_str = [](bool v) { return v ? "true" : "false"; };
builder.appendf("// fBoundsIsDirty = %s\n", bool_str(fPathRef->fBoundsIsDirty));
builder.appendf("// fGenerationID = %d\n", fPathRef->fGenerationID);
builder.appendf("// fSegmentMask = %d\n", fPathRef->fSegmentMask);
builder.appendf("// fIsOval = %s\n", bool_str(fPathRef->fIsOval));
builder.appendf("// fIsRRect = %s\n", bool_str(fPathRef->fIsRRect));
auto append_scalar = [&](SkScalar v) {
if (dumpAsHex) {
builder.appendf("SkBits2Float(0x%08X) /* %g */", SkFloat2Bits(v), v);
} else {
builder.appendf("%g", v);
}
};
builder.append("const SkPoint path_points[] = {\n");
for (int i = 0; i < this->countPoints(); ++i) {
SkPoint p = this->getPoint(i);
builder.append(" { ");
append_scalar(p.fX);
builder.append(", ");
append_scalar(p.fY);
builder.append(" },\n");
}
builder.append("};\n");
const char* gVerbStrs[] = {
"Move", "Line", "Quad", "Conic", "Cubic", "Close"
};
builder.append("const uint8_t path_verbs[] = {\n ");
for (auto v = fPathRef->verbsBegin(); v != fPathRef->verbsEnd(); ++v) {
builder.appendf("(uint8_t)SkPathVerb::k%s, ", gVerbStrs[*v]);
}
builder.append("\n};\n");
const int nConics = fPathRef->conicWeightsEnd() - fPathRef->conicWeights();
if (nConics) {
builder.append("const SkScalar path_conics[] = {\n ");
for (auto c = fPathRef->conicWeights(); c != fPathRef->conicWeightsEnd(); ++c) {
append_scalar(*c);
builder.append(", ");
}
builder.append("\n};\n");
}
char const * const gFillTypeStrs[] = {
"Winding",
"EvenOdd",
"InverseWinding",
"InverseEvenOdd",
};
builder.appendf("SkPath path = SkPath::Make(path_points, %d, path_verbs, %d, %s, %d,\n",
this->countPoints(), this->countVerbs(),
nConics ? "path_conics" : "nullptr", nConics);
builder.appendf(" SkPathFillType::k%s, %s);\n",
gFillTypeStrs[(int)this->getFillType()],
bool_str(fIsVolatile));
if (wStream) {
wStream->writeText(builder.c_str());
} else {
SkDebugf("%s\n", builder.c_str());
}
}
bool SkPath::isValidImpl() const {
if ((fFillType & ~3) != 0) {
return false;