Add the ability to specifiy which SVG path to use via command line and change the default to the last path found.

This commit is contained in:
Christopher Kohnert 2017-06-01 11:30:43 -07:00
parent 52e020ada8
commit 5bdcc88474
3 changed files with 40 additions and 10 deletions

View File

@ -151,7 +151,7 @@ static bool buildFromPath(Shape &shape, const char *pathDef) {
return true;
}
bool loadSvgShape(Shape &output, const char *filename, Vector2 *dimensions) {
bool loadSvgShape(Shape &output, const char *filename, int pathIndex, Vector2 *dimensions) {
tinyxml2::XMLDocument doc;
if (doc.LoadFile(filename))
return false;
@ -159,11 +159,29 @@ bool loadSvgShape(Shape &output, const char *filename, Vector2 *dimensions) {
if (!root)
return false;
tinyxml2::XMLElement *path = root->FirstChildElement("path");
if (!path) {
tinyxml2::XMLElement *g = root->FirstChildElement("g");
if (g)
path = g->FirstChildElement("path");
tinyxml2::XMLElement *path = NULL;
if( pathIndex > 0 ) {
path = root->FirstChildElement("path");
if (!path) {
tinyxml2::XMLElement *g = root->FirstChildElement("g");
if (g)
path = g->FirstChildElement("path");
}
while (path && --pathIndex > 0)
path = path->NextSiblingElement("path");
}
else {
// A pathIndex of 0 means "default", which is the same as specifying a -1 (i.e. last).
path = root->LastChildElement("path");
if (!path) {
tinyxml2::XMLElement *g = root->LastChildElement("g");
if (g)
path = g->LastChildElement("path");
}
while (path && ++pathIndex < 0) {
path = path->PreviousSiblingElement("path");
}
}
if (!path)
return false;

View File

@ -7,6 +7,6 @@
namespace msdfgen {
/// Reads the first path found in the specified SVG file and stores it as a Shape in output.
bool loadSvgShape(Shape &output, const char *filename, Vector2 *dimensions = NULL);
bool loadSvgShape(Shape &output, const char *filename, int pathIndex, Vector2 *dimensions = NULL);
}

View File

@ -44,6 +44,11 @@ static bool parseUnsigned(unsigned &value, const char *arg) {
return sscanf(arg, "%u%c", &value, &c) == 1;
}
static bool parseInteger(int &value, const char *arg) {
static char c;
return sscanf(arg, "%d%c", &value, &c) == 1;
}
static bool parseUnsignedLL(unsigned long long &value, const char *arg) {
static char c;
return sscanf(arg, "%llu%c", &value, &c) == 1;
@ -280,8 +285,10 @@ static const char *helpText =
"\tLoads text shape description from a file.\n"
" -stdin\n"
"\tReads text shape description from the standard input.\n"
" -svg <filename.svg>\n"
"\tLoads the first vector path encountered in the specified SVG file.\n"
" -svg <filename.svg> [<pathIndex>]\n"
"\tLoads a vector <path> element from the specified SVG file. The optional index specifies a sibling\n"
"\tto use. E.g. 1 = first element, 2 = second element, -1 = last element, -2 = second to last, etc.\n"
"\tDefault: -1 (i.e. last path element).\n"
"\n"
"OPTIONS\n"
" -angle <angle>\n"
@ -359,6 +366,7 @@ int main(int argc, const char * const *argv) {
const char *testRenderMulti = NULL;
bool outputSpecified = false;
int unicode = 0;
int svgPathIndex = 0;
int width = 64, height = 64;
int testWidth = 0, testHeight = 0;
@ -404,6 +412,10 @@ int main(int argc, const char * const *argv) {
inputType = SVG;
input = argv[argPos+1];
argPos += 2;
// Optional path specifier
if( argPos+1 < argc && parseInteger(svgPathIndex, argv[argPos]) ) {
argPos += 1;
}
continue;
}
ARG_CASE("-font", 2) {
@ -618,7 +630,7 @@ int main(int argc, const char * const *argv) {
Shape shape;
switch (inputType) {
case SVG: {
if (!loadSvgShape(shape, input, &svgDims))
if (!loadSvgShape(shape, input, svgPathIndex, &svgDims))
ABORT("Failed to load shape from SVG file.");
break;
}