add dumpHex() option to SkPath

This provides exact precision
to help debugging when the float
representation of a SkScalar may
introduce error.

R=reed@google.com

Author: caryclark@google.com

Review URL: https://codereview.chromium.org/571973003
This commit is contained in:
caryclark 2014-09-15 09:26:09 -07:00 committed by Commit bot
parent a63d5df455
commit e956259c5a
4 changed files with 48 additions and 29 deletions

View File

@ -931,8 +931,9 @@ public:
*/
bool contains(SkScalar x, SkScalar y) const;
void dump(SkWStream* , bool forceClose) const;
void dump(SkWStream* , bool forceClose, bool dumpAsHex) const;
void dump() const;
void dumpHex() const;
/**
* Write the path to the buffer, and return the number of bytes written.

View File

@ -891,7 +891,7 @@ void SkClipStack::Element::dump() const {
SkDebugf("\n");
break;
case kPath_Type:
this->getPath().dump(NULL, true);
this->getPath().dump(NULL, true, false);
break;
}
}

View File

@ -2019,7 +2019,11 @@ size_t SkPath::readFromMemory(const void* storage, size_t length) {
#include "SkString.h"
#include "SkStream.h"
static void append_scalar(SkString* str, SkScalar value) {
static void append_scalar(SkString* str, SkScalar value, bool dumpAsHex) {
if (dumpAsHex) {
str->appendf("SkBits2Float(0x%08x)", SkFloat2Bits(value));
return;
}
SkString tmp;
tmp.printf("%g", value);
if (tmp.contains('.')) {
@ -2029,7 +2033,7 @@ static void append_scalar(SkString* str, SkScalar value) {
}
static void append_params(SkString* str, const char label[], const SkPoint pts[],
int count, SkScalar conicWeight = -1) {
int count, bool dumpAsHex, SkScalar conicWeight = -1) {
str->append(label);
str->append("(");
@ -2037,19 +2041,19 @@ static void append_params(SkString* str, const char label[], const SkPoint pts[]
count *= 2;
for (int i = 0; i < count; ++i) {
append_scalar(str, values[i]);
append_scalar(str, values[i], dumpAsHex);
if (i < count - 1) {
str->append(", ");
}
}
if (conicWeight >= 0) {
str->append(", ");
append_scalar(str, conicWeight);
append_scalar(str, conicWeight, dumpAsHex);
}
str->append(");\n");
}
void SkPath::dump(SkWStream* wStream, bool forceClose) const {
void SkPath::dump(SkWStream* wStream, bool forceClose, bool dumpAsHex) const {
Iter iter(*this, forceClose);
SkPoint pts[4];
Verb verb;
@ -2062,19 +2066,19 @@ void SkPath::dump(SkWStream* wStream, bool forceClose) const {
while ((verb = iter.next(pts, false)) != kDone_Verb) {
switch (verb) {
case kMove_Verb:
append_params(&builder, "path.moveTo", &pts[0], 1);
append_params(&builder, "path.moveTo", &pts[0], 1, dumpAsHex);
break;
case kLine_Verb:
append_params(&builder, "path.lineTo", &pts[1], 1);
append_params(&builder, "path.lineTo", &pts[1], 1, dumpAsHex);
break;
case kQuad_Verb:
append_params(&builder, "path.quadTo", &pts[1], 2);
append_params(&builder, "path.quadTo", &pts[1], 2, dumpAsHex);
break;
case kConic_Verb:
append_params(&builder, "path.conicTo", &pts[1], 2, iter.conicWeight());
append_params(&builder, "path.conicTo", &pts[1], 2, dumpAsHex, iter.conicWeight());
break;
case kCubic_Verb:
append_params(&builder, "path.cubicTo", &pts[1], 3);
append_params(&builder, "path.cubicTo", &pts[1], 3, dumpAsHex);
break;
case kClose_Verb:
builder.append("path.close();\n");
@ -2093,7 +2097,11 @@ void SkPath::dump(SkWStream* wStream, bool forceClose) const {
}
void SkPath::dump() const {
this->dump(NULL, false);
this->dump(NULL, false, false);
}
void SkPath::dumpHex() const {
this->dump(NULL, false, true);
}
#ifdef SK_DEBUG

View File

@ -3419,9 +3419,9 @@ static void test_operatorEqual(skiatest::Reporter* reporter) {
}
static void compare_dump(skiatest::Reporter* reporter, const SkPath& path, bool force,
const char* str) {
bool dumpAsHex, const char* str) {
SkDynamicMemoryWStream wStream;
path.dump(&wStream, force);
path.dump(&wStream, force, dumpAsHex);
SkAutoDataUnref data(wStream.copyToData());
REPORTER_ASSERT(reporter, data->size() == strlen(str));
REPORTER_ASSERT(reporter, !memcmp(data->data(), str, strlen(str)));
@ -3429,31 +3429,41 @@ static void compare_dump(skiatest::Reporter* reporter, const SkPath& path, bool
static void test_dump(skiatest::Reporter* reporter) {
SkPath p;
compare_dump(reporter, p, false, "");
compare_dump(reporter, p, true, "");
compare_dump(reporter, p, false, false, "");
compare_dump(reporter, p, true, false, "");
p.moveTo(1, 2);
p.lineTo(3, 4);
compare_dump(reporter, p, false, "path.moveTo(1, 2);\n"
"path.lineTo(3, 4);\n");
compare_dump(reporter, p, true, "path.moveTo(1, 2);\n"
"path.lineTo(3, 4);\n"
"path.lineTo(1, 2);\n"
"path.close();\n");
compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
"path.lineTo(3, 4);\n");
compare_dump(reporter, p, true, false, "path.moveTo(1, 2);\n"
"path.lineTo(3, 4);\n"
"path.lineTo(1, 2);\n"
"path.close();\n");
p.reset();
p.moveTo(1, 2);
p.quadTo(3, 4, 5, 6);
compare_dump(reporter, p, false, "path.moveTo(1, 2);\n"
"path.quadTo(3, 4, 5, 6);\n");
compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
"path.quadTo(3, 4, 5, 6);\n");
p.reset();
p.moveTo(1, 2);
p.conicTo(3, 4, 5, 6, 0.5f);
compare_dump(reporter, p, false, "path.moveTo(1, 2);\n"
"path.conicTo(3, 4, 5, 6, 0.5f);\n");
compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
"path.conicTo(3, 4, 5, 6, 0.5f);\n");
p.reset();
p.moveTo(1, 2);
p.cubicTo(3, 4, 5, 6, 7, 8);
compare_dump(reporter, p, false, "path.moveTo(1, 2);\n"
"path.cubicTo(3, 4, 5, 6, 7, 8);\n");
compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
"path.cubicTo(3, 4, 5, 6, 7, 8);\n");
p.reset();
p.moveTo(1, 2);
p.lineTo(3, 4);
compare_dump(reporter, p, false, true, "path.moveTo(SkBits2Float(0x3f800000), SkBits2Float(0x40000000));\n"
"path.lineTo(SkBits2Float(0x40400000), SkBits2Float(0x40800000));\n");
p.reset();
p.moveTo(SkBits2Float(0x3f800000), SkBits2Float(0x40000000));
p.lineTo(SkBits2Float(0x40400000), SkBits2Float(0x40800000));
compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
"path.lineTo(3, 4);\n");
}
class PathTest_Private {