+ string token("");
+ while (GetToken(d, token, i, delims) == ",");
+ x = RealFromStr(token);
+ if (GetToken(d, token, i, delims) != ",")
+ {
+ Fatal("Expected \",\" seperating x,y pair");
+ }
+ y = RealFromStr(GetToken(d,token,i,delims));
+}
+
+static bool GetKeyValuePair(const string & d, string & key, string & value, unsigned & i, const string & delims = "()[],{}<>;:=")
+{
+ key = "";
+ string token;
+ while (GetToken(d, token, i, delims) == ":" || token == ";");
+ key = token;
+ if (GetToken(d, token, i, delims) != ":")
+ {
+ Error("Expected \":\" seperating key:value pair");
+ return false;
+ }
+ value = "";
+ GetToken(d, value, i, delims);
+ return true;
+}
+
+static void TransformXYPair(Real & x, Real & y, const SVGMatrix & transform)
+{
+ Real x0(x);
+ x = transform.a * x + transform.c * y + transform.e;
+ y = transform.b * x0 + transform.d * y + transform.f;
+}
+
+void Document::ParseSVGTransform(const string & s, SVGMatrix & transform)
+{
+ //Debug("Parsing transform %s", s.c_str());
+ string token;
+ string command;
+ unsigned i = 0;
+
+ while (i < s.size())
+ {
+ GetToken(s, command, i);
+ if (command == "," || command == "" || command == ":")
+ {
+ if (i < s.size())
+ GetToken(s, command, i);
+ else
+ return;
+ }
+ //Debug("Token is \"%s\"", command.c_str());
+
+ SVGMatrix delta = {1,0,0,0,1,0};
+
+
+ assert(GetToken(s,token, i) == "(");
+ if (command == "translate")
+ {
+ GetXYPair(s, delta.e, delta.f, i);
+ assert(GetToken(s,token, i) == ")");
+ }
+ else if (command == "matrix")
+ {
+ GetXYPair(s, delta.a, delta.b,i);
+ GetXYPair(s, delta.c, delta.d,i);
+ GetXYPair(s, delta.e, delta.f,i);
+ assert(GetToken(s,token, i) == ")");
+ }
+ else if (command == "scale")
+ {
+ delta.a = RealFromStr(GetToken(s,token,i));
+ GetToken(s, token, i);
+ if (token == ",")
+ {
+ delta.d = RealFromStr(GetToken(s,token,i));
+ assert(GetToken(s, token, i) == ")");
+ }
+ else
+ {
+ delta.d = delta.a;
+ assert(token == ")");
+ }