Update filter tool to write out paths to .cpp file

https://codereview.appspot.com/6843125/



git-svn-id: http://skia.googlecode.com/svn/trunk@6714 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
robertphillips@google.com 2012-12-07 20:56:13 +00:00
Родитель 5f97114fd2
Коммит d3d377f1d6
4 изменённых файлов: 246 добавлений и 9 удалений

Просмотреть файл

@ -199,6 +199,8 @@
],
'sources': [
'../tools/filtermain.cpp',
'../tools/path_utils.cpp',
'../tools/path_utils.h',
],
'dependencies': [
'skia_base_libs.gyp:skia_base_libs',

Просмотреть файл

@ -15,14 +15,16 @@
#include "SkPictureRecord.h"
#include "SkStream.h"
#include "picture_utils.h"
#include "path_utils.h"
static void usage() {
SkDebugf("Usage: filter -i inFile [-o outFile] [-t textureDir] [-h|--help]");
SkDebugf("\n\n");
SkDebugf("Usage: filter -i inFile [-o outFile] [--input-dir path] [--output-dir path]\n");
SkDebugf(" [-p pathFile] [-t textureDir] [-h|--help]\n\n");
SkDebugf(" -i inFile : file to file.\n");
SkDebugf(" -o outFile : result of filtering.\n");
SkDebugf(" --input-dir : process all files in dir with .skp extension.\n");
SkDebugf(" --output-dir : results of filtering the input dir.\n");
SkDebugf(" -p pathFile : file in which to place compileable path data.\n");
SkDebugf(" -t textureDir : directory in which to place textures. (only available w/ single file)\n");
SkDebugf(" -h|--help : Show this help message.\n");
}
@ -30,12 +32,30 @@ static void usage() {
// SkFilterRecord allows the filter to manipulate the read in SkPicture
class SkFilterRecord : public SkPictureRecord {
public:
SkFilterRecord(uint32_t recordFlags, SkDevice* device)
SkFilterRecord(uint32_t recordFlags, SkDevice* device, SkFILEWStream* pathStream)
: INHERITED(recordFlags, device)
, fTransSkipped(0)
, fTransTot(0)
, fScalesSkipped(0)
, fScalesTot(0) {
, fScalesTot(0)
, fPathStream(pathStream) {
}
virtual ~SkFilterRecord() {
}
virtual bool clipPath(const SkPath& path, SkRegion::Op op, bool doAntiAlias) SK_OVERRIDE {
if (!path.isRect(NULL) && 4 < path.countPoints()) {
sk_tools::dump_path(fPathStream, path);
}
return INHERITED::clipPath(path, op, doAntiAlias);
}
virtual void drawPath(const SkPath& path, const SkPaint& p) SK_OVERRIDE {
if (!path.isRect(NULL) && 4 < path.countPoints()) {
sk_tools::dump_path(fPathStream, path);
}
INHERITED::drawPath(path, p);
}
virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE {
@ -97,6 +117,7 @@ protected:
int fScalesSkipped;
int fScalesTot;
SkFILEWStream* fPathStream;
private:
typedef SkPictureRecord INHERITED;
};
@ -119,7 +140,8 @@ static bool PNGEncodeBitmapToStream(SkWStream* stream, const SkBitmap& bitmap) {
return SkImageEncoder::EncodeStream(stream, bitmap, SkImageEncoder::kPNG_Type, 100);
}
int filter_picture(const SkString& inFile, const SkString& outFile, const SkString& textureDir) {
int filter_picture(const SkString& inFile, const SkString& outFile,
const SkString& textureDir, SkFILEWStream *pathStream) {
SkPicture* inPicture = NULL;
SkFILEStream inStream(inFile.c_str());
@ -136,7 +158,7 @@ int filter_picture(const SkString& inFile, const SkString& outFile, const SkStri
bm.setConfig(SkBitmap::kNo_Config, inPicture->width(), inPicture->height());
SkAutoTUnref<SkDevice> dev(SkNEW_ARGS(SkDevice, (bm)));
SkAutoTUnref<SkFilterRecord> filterRecord(SkNEW_ARGS(SkFilterRecord, (0, dev)));
SkAutoTUnref<SkFilterRecord> filterRecord(SkNEW_ARGS(SkFilterRecord, (0, dev, pathStream)));
// Playback the read in picture to the SkFilterRecorder to allow filtering
filterRecord->beginRecording();
@ -169,7 +191,7 @@ int tool_main(int argc, char** argv) {
return -1;
}
SkString inFile, outFile, inDir, outDir, textureDir;
SkString inFile, outFile, inDir, outDir, textureDir, pathFile;
char* const* stop = argv + argc;
for (++argv; argv < stop; ++argv) {
@ -209,6 +231,15 @@ int tool_main(int argc, char** argv) {
usage();
return -1;
}
} else if (strcmp(*argv, "-p") == 0) {
argv++;
if (argv < stop && **argv) {
pathFile.set(*argv);
} else {
SkDebugf("missing arg for -p\n");
usage();
return -1;
}
} else if (strcmp(*argv, "-t") == 0) {
argv++;
if (argv < stop && **argv) {
@ -234,6 +265,19 @@ int tool_main(int argc, char** argv) {
return -1;
}
SkFILEWStream *pathStream = NULL;
if (!pathFile.isEmpty()) {
pathStream = new SkFILEWStream(pathFile.c_str());
if (!pathStream->isValid()) {
SkDebugf("Could open path file %s\n", pathFile.c_str());
delete pathStream;
return -1;
}
sk_tools::dump_path_prefix(pathStream);
}
SkOSFile::Iter iter(inDir.c_str(), "skp");
int failures = 0;
SkString inputFilename, outputFilename;
@ -245,16 +289,26 @@ int tool_main(int argc, char** argv) {
sk_tools::make_filepath(&outFile, outDir, inputFilename);
}
SkDebugf("Executing %s\n", inputFilename.c_str());
filter_picture(inFile, outFile, textureDir);
filter_picture(inFile, outFile, textureDir, pathStream);
} while(iter.next(&inputFilename));
} else if (!inFile.isEmpty()) {
filter_picture(inFile, outFile, textureDir);
filter_picture(inFile, outFile, textureDir, pathStream);
} else {
usage();
if (NULL != pathStream) {
delete pathStream;
pathStream = NULL;
}
return -1;
}
if (NULL != pathStream) {
sk_tools::dump_path_suffix(pathStream);
delete pathStream;
pathStream = NULL;
}
SkGraphics::Term();
return 0;
}

134
tools/path_utils.cpp Normal file
Просмотреть файл

@ -0,0 +1,134 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "path_utils.h"
#include "SkPath.h"
#include "SkStream.h"
namespace sk_tools {
static int gCurPathID = 0;
void dump_path_prefix(SkFILEWStream* pathStream) {
if (NULL == pathStream) {
return;
}
pathStream->writeText("#include \"SkScalar.h\"\n");
pathStream->writeText("#include \"SkPoint.h\"\n");
pathStream->writeText("#include \"SkBitmap.h\"\n");
pathStream->writeText("#include \"SkDevice.h\"\n");
pathStream->writeText("#include \"SkString.h\"\n");
pathStream->writeText("#include \"SkImageEncoder.h\"\n");
}
void dump_path(SkFILEWStream* pathStream, const SkPath& path) {
if (NULL == pathStream) {
return;
}
static const int kMaxPts = 200;
static const int kMaxVerbs = 200;
int numPts = path.countPoints();
int numVerbs = path.countVerbs();
SkASSERT(numPts <= kMaxPts);
SkASSERT(numVerbs <= kMaxVerbs);
SkPoint pts[kMaxPts];
uint8_t verbs[kMaxVerbs];
path.getPoints(pts, kMaxPts);
path.getVerbs(verbs, kMaxVerbs);
const char* gStrs[] = {
"kMove_Verb",
"kLine_Verb",
"kQuad_Verb",
"kCubic_Verb",
"kClose_Verb",
"kDone_Verb"
};
pathStream->writeText("static const int numPts");
pathStream->writeDecAsText(gCurPathID);
pathStream->writeText(" = ");
pathStream->writeDecAsText(numPts);
pathStream->writeText(";\n");
pathStream->writeText("SkPoint pts");
pathStream->writeDecAsText(gCurPathID);
pathStream->writeText("[] = {\n");
for (int i = 0; i < numPts; ++i) {
SkString temp;
pathStream->writeText(" { ");
temp.appendScalar(pts[i].fX);
temp.append("f, ");
temp.appendScalar(pts[i].fY);
temp.append("f },\n");
pathStream->writeText(temp.c_str());
}
pathStream->writeText("};\n");
pathStream->writeText("static const int numVerbs");
pathStream->writeDecAsText(gCurPathID);
pathStream->writeText(" = ");
pathStream->writeDecAsText(numVerbs);
pathStream->writeText(";\n");
pathStream->writeText("uint8_t verbs");
pathStream->writeDecAsText(gCurPathID);
pathStream->writeText("[] = {\n");
for (int i = 0; i < numVerbs; ++i) {
pathStream->writeText("\tSkPath::");
pathStream->writeText(gStrs[verbs[i]]);
pathStream->writeText(",\n");
}
pathStream->writeText("};\n");
gCurPathID++;
}
void dump_path_suffix(SkFILEWStream* pathStream) {
if (NULL == pathStream) {
return;
}
pathStream->writeText("int numPaths = ");
pathStream->writeDecAsText(gCurPathID);
pathStream->writeText(";\n");
pathStream->writeText("int sizes[] = {\n");
for (int i = 0; i < gCurPathID; ++i) {
pathStream->writeText("\t numPts");
pathStream->writeDecAsText(i);
pathStream->writeText(", numVerbs");
pathStream->writeDecAsText(i);
pathStream->writeText(",\n");
}
pathStream->writeText("};\n");
pathStream->writeText("const SkPoint* points[] = {\n");
for (int i = 0; i < gCurPathID; ++i) {
pathStream->writeText("\tpts");
pathStream->writeDecAsText(i);
pathStream->writeText(",\n");
}
pathStream->writeText("};\n");
pathStream->writeText("const uint8_t* verbs[] = {\n");
for (int i = 0; i < gCurPathID; ++i) {
pathStream->writeText("\t(const uint8_t*)verbs");
pathStream->writeDecAsText(i);
pathStream->writeText(",\n");
}
pathStream->writeText("};\n");
}
}

47
tools/path_utils.h Normal file
Просмотреть файл

@ -0,0 +1,47 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef path_utils_DEFINED
#define path_utils_DEFINED
class SkFILEWStream;
class SkPath;
namespace sk_tools {
// These utilities help write paths to a .cpp file in a compileable form.
// To use call them in the order:
// dump_path_prefix - once per program invocation
// dump_path - once for each path of interest
// dump_path_suffix - once per program invocation
//
// The output system relies on a global current path ID and assumes that
// only one set of aggregation arrays will be written per program
// invocation. These utilities are not thread safe.
// Write of the headers needed to compile the resulting .cpp file
void dump_path_prefix(SkFILEWStream* pathStream);
// Write out a single path in the form:
// static const int numPts# = ...;
// SkPoint pts#[] = { ... };
// static const int numVerbs# = ...;
// uint8_t verbs#[] = { ... };
// Where # is a globally unique identifier
void dump_path(SkFILEWStream* pathStream, const SkPath& path);
// Write out structures to aggregate info about the written paths:
// int numPaths = ...;
// int sizes[] = {
// numPts#, numVerbs#,
// ...
// };
// const SkPoint* points[] = { pts#, ... };
// const uint8_t* verbs[] = { verbs#, ... };
void dump_path_suffix(SkFILEWStream* pathStream);
}
#endif