mirror of https://github.com/Chlumsky/msdfgen.git
Merge pull request #32 from ccbrown/master
SVG import fixes and support
This commit is contained in:
commit
0215653a8a
|
|
@ -52,6 +52,15 @@ static bool readDouble(double &output, const char *&pathDef) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void consumeOptionalComma(const char *&pathDef) {
|
||||||
|
while (*pathDef == ' ') {
|
||||||
|
++pathDef;
|
||||||
|
}
|
||||||
|
if (*pathDef == ',') {
|
||||||
|
++pathDef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool buildFromPath(Shape &shape, const char *pathDef) {
|
static bool buildFromPath(Shape &shape, const char *pathDef) {
|
||||||
char nodeType;
|
char nodeType;
|
||||||
Point2 prevNode(0, 0);
|
Point2 prevNode(0, 0);
|
||||||
|
|
@ -66,79 +75,83 @@ static bool buildFromPath(Shape &shape, const char *pathDef) {
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (nodeType) {
|
switch (nodeType) {
|
||||||
case 'M':
|
case 'M':
|
||||||
REQUIRE(contourStart);
|
|
||||||
REQUIRE(readCoord(node, pathDef));
|
|
||||||
startPoint = node;
|
|
||||||
nodeType = 'L';
|
|
||||||
break;
|
|
||||||
case 'm':
|
case 'm':
|
||||||
REQUIRE(contourStart);
|
REQUIRE(contourStart);
|
||||||
REQUIRE(readCoord(node, pathDef));
|
REQUIRE(readCoord(node, pathDef));
|
||||||
node += prevNode;
|
if (nodeType == 'm') {
|
||||||
|
node += prevNode;
|
||||||
|
}
|
||||||
startPoint = node;
|
startPoint = node;
|
||||||
nodeType = 'l';
|
--nodeType; // to 'L' or 'l'
|
||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
case 'z':
|
case 'z':
|
||||||
if (prevNode != startPoint)
|
if (prevNode != startPoint)
|
||||||
contour.addEdge(new LinearSegment(prevNode, startPoint));
|
contour.addEdge(new LinearSegment(prevNode, startPoint));
|
||||||
|
prevNode = startPoint;
|
||||||
goto NEXT_CONTOUR;
|
goto NEXT_CONTOUR;
|
||||||
case 'L':
|
case 'L':
|
||||||
REQUIRE(readCoord(node, pathDef));
|
|
||||||
contour.addEdge(new LinearSegment(prevNode, node));
|
|
||||||
break;
|
|
||||||
case 'l':
|
case 'l':
|
||||||
REQUIRE(readCoord(node, pathDef));
|
REQUIRE(readCoord(node, pathDef));
|
||||||
node += prevNode;
|
if (nodeType == 'l') {
|
||||||
|
node += prevNode;
|
||||||
|
}
|
||||||
contour.addEdge(new LinearSegment(prevNode, node));
|
contour.addEdge(new LinearSegment(prevNode, node));
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
REQUIRE(readDouble(node.x, pathDef));
|
|
||||||
contour.addEdge(new LinearSegment(prevNode, node));
|
|
||||||
break;
|
|
||||||
case 'h':
|
case 'h':
|
||||||
REQUIRE(readDouble(node.x, pathDef));
|
REQUIRE(readDouble(node.x, pathDef));
|
||||||
node.x += prevNode.x;
|
if (nodeType == 'h') {
|
||||||
|
node.x += prevNode.x;
|
||||||
|
}
|
||||||
contour.addEdge(new LinearSegment(prevNode, node));
|
contour.addEdge(new LinearSegment(prevNode, node));
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
REQUIRE(readDouble(node.y, pathDef));
|
|
||||||
contour.addEdge(new LinearSegment(prevNode, node));
|
|
||||||
break;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
REQUIRE(readDouble(node.y, pathDef));
|
REQUIRE(readDouble(node.y, pathDef));
|
||||||
node.y += prevNode.y;
|
if (nodeType == 'v') {
|
||||||
|
node.y += prevNode.y;
|
||||||
|
}
|
||||||
contour.addEdge(new LinearSegment(prevNode, node));
|
contour.addEdge(new LinearSegment(prevNode, node));
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
REQUIRE(readCoord(controlPoint[0], pathDef));
|
|
||||||
REQUIRE(readCoord(node, pathDef));
|
|
||||||
contour.addEdge(new QuadraticSegment(prevNode, controlPoint[0], node));
|
|
||||||
break;
|
|
||||||
case 'q':
|
case 'q':
|
||||||
REQUIRE(readCoord(controlPoint[0], pathDef));
|
REQUIRE(readCoord(controlPoint[0], pathDef));
|
||||||
|
consumeOptionalComma(pathDef);
|
||||||
REQUIRE(readCoord(node, pathDef));
|
REQUIRE(readCoord(node, pathDef));
|
||||||
controlPoint[0] += prevNode;
|
if (nodeType == 'q') {
|
||||||
node += prevNode;
|
controlPoint[0] += prevNode;
|
||||||
|
node += prevNode;
|
||||||
|
}
|
||||||
contour.addEdge(new QuadraticSegment(prevNode, controlPoint[0], node));
|
contour.addEdge(new QuadraticSegment(prevNode, controlPoint[0], node));
|
||||||
break;
|
break;
|
||||||
// TODO T, t
|
// TODO T, t
|
||||||
case 'C':
|
case 'C':
|
||||||
REQUIRE(readCoord(controlPoint[0], pathDef));
|
|
||||||
REQUIRE(readCoord(controlPoint[1], pathDef));
|
|
||||||
REQUIRE(readCoord(node, pathDef));
|
|
||||||
contour.addEdge(new CubicSegment(prevNode, controlPoint[0], controlPoint[1], node));
|
|
||||||
break;
|
|
||||||
case 'c':
|
case 'c':
|
||||||
REQUIRE(readCoord(controlPoint[0], pathDef));
|
REQUIRE(readCoord(controlPoint[0], pathDef));
|
||||||
|
consumeOptionalComma(pathDef);
|
||||||
REQUIRE(readCoord(controlPoint[1], pathDef));
|
REQUIRE(readCoord(controlPoint[1], pathDef));
|
||||||
|
consumeOptionalComma(pathDef);
|
||||||
REQUIRE(readCoord(node, pathDef));
|
REQUIRE(readCoord(node, pathDef));
|
||||||
controlPoint[0] += prevNode;
|
if (nodeType == 'c') {
|
||||||
controlPoint[1] += prevNode;
|
controlPoint[0] += prevNode;
|
||||||
node += prevNode;
|
controlPoint[1] += prevNode;
|
||||||
|
node += prevNode;
|
||||||
|
}
|
||||||
|
contour.addEdge(new CubicSegment(prevNode, controlPoint[0], controlPoint[1], node));
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
case 's':
|
||||||
|
controlPoint[0] = node * 2 - controlPoint[1];
|
||||||
|
REQUIRE(readCoord(controlPoint[1], pathDef));
|
||||||
|
consumeOptionalComma(pathDef);
|
||||||
|
REQUIRE(readCoord(node, pathDef));
|
||||||
|
if (nodeType == 's') {
|
||||||
|
controlPoint[1] += prevNode;
|
||||||
|
node += prevNode;
|
||||||
|
}
|
||||||
contour.addEdge(new CubicSegment(prevNode, controlPoint[0], controlPoint[1], node));
|
contour.addEdge(new CubicSegment(prevNode, controlPoint[0], controlPoint[1], node));
|
||||||
break;
|
break;
|
||||||
// TODO S, s
|
|
||||||
// TODO A, a
|
// TODO A, a
|
||||||
default:
|
default:
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue