b=306088, simplify nssvgtransformlist::setvaluestring, r=tor

This commit is contained in:
vladimir%pobox.com 2005-09-02 20:24:24 +00:00
parent 132ddbe43e
commit 1aed554cfa
2 changed files with 89 additions and 82 deletions

View File

@ -140,7 +140,6 @@ nsSVGTransformList::SetValueString(const nsAString& aValue)
char* args;
const char* delimiters1 = "\x20\x9\xD\xA,(";
const char* delimiters2 = "()";
const char* delimiters3 = "\x20\x9\xD\xA,";
nsCOMArray<nsIDOMSVGTransform> xforms;
while ((keyword = nsCRT::strtok(rest, delimiters1, &rest))) {
@ -162,123 +161,82 @@ nsSVGTransformList::SetValueString(const nsAString& aValue)
nsCOMPtr<nsIAtom> keyatom = do_GetAtom(keyword);
if (keyatom == nsSVGAtoms::translate) {
char* arg1 = nsCRT::strtok(args, delimiters3, &args);
if (!arg1) {
// tx [ty=0]
float t[2] = { 0.f };
PRInt32 num_parsed = ParseParameterList(args, t, 2);
if (num_parsed != 1 && num_parsed != 2) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
char* arg2 = nsCRT::strtok(args, delimiters3, &args);
char* end;
float tx = (float) PR_strtod(arg1, &end);
float ty = arg2 ? (float) PR_strtod(arg2, &end) : 0.0f;
transform->SetTranslate(tx, ty);
transform->SetTranslate(t[0], t[1]);
}
else if (keyatom == nsSVGAtoms::scale) {
char* arg1 = nsCRT::strtok(args, delimiters3, &args);
if (!arg1) {
// sx [sy=sx]
float s[2] = { 0.f };
PRInt32 num_parsed = ParseParameterList(args, s, 2);
if (num_parsed != 1 && num_parsed != 2) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
char* arg2 = nsCRT::strtok(args, delimiters3, &args);
char* end;
float sx = (float) PR_strtod(arg1, &end);
float sy = arg2 ? (float) PR_strtod(arg2, &end) : sx;
transform->SetScale(sx, sy);
}
if (num_parsed == 1)
s[1] = s[0];
transform->SetScale(s[0], s[1]);
}
else if (keyatom == nsSVGAtoms::rotate) {
char* arg1 = nsCRT::strtok(args, delimiters3, &args);
if (!arg1) {
// r [x0=0 y0=0]
float r[3] = { 0.f };
PRInt32 num_parsed = ParseParameterList(args, r, 3);
if (num_parsed != 1 && num_parsed != 3) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
char* arg2 = nsCRT::strtok(args, delimiters3, &args);
char* arg3 = arg2 ? nsCRT::strtok(args, delimiters3, &args) : nsnull;
if (arg2 && !arg3) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
char* end;
float angle = (float) PR_strtod(arg1, &end);
float cx = arg2 ? (float) PR_strtod(arg2, &end) : 0.0f;
float cy = arg3 ? (float) PR_strtod(arg3, &end) : 0.0f;
transform->SetRotate(angle, cx, cy);
}
transform->SetRotate(r[0], r[1], r[2]);
}
else if (keyatom == nsSVGAtoms::skewX) {
char* arg1 = nsCRT::strtok(args, delimiters3, &args);
if (!arg1) {
// x-angle
float angle;
PRInt32 num_parsed = ParseParameterList(args, &angle, 1);
if (num_parsed != 1) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
char* end;
float angle = (float) PR_strtod(arg1, &end);
transform->SetSkewX(angle);
}
}
else if (keyatom == nsSVGAtoms::skewY) {
char* arg1 = nsCRT::strtok(args, delimiters3, &args);
if (!arg1) {
// y-angle
float angle;
PRInt32 num_parsed = ParseParameterList(args, &angle, 1);
if (num_parsed != 1) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
char* end;
float angle = (float) PR_strtod(arg1, &end);
transform->SetSkewY(angle);
}
else if (keyatom == nsSVGAtoms::matrix) {
char *arg, *end;
arg = nsCRT::strtok(args, delimiters3, &args);
if (!arg) {
// a b c d e f
float m[6];
PRInt32 num_parsed = ParseParameterList(args, m, 6);
if (num_parsed != 6) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
float a = (float) PR_strtod(arg, &end);
arg = nsCRT::strtok(args, delimiters3, &args);
if (!arg) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
float b = (float) PR_strtod(arg, &end);
arg = nsCRT::strtok(args, delimiters3, &args);
if (!arg) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
float c = (float) PR_strtod(arg, &end);
arg = nsCRT::strtok(args, delimiters3, &args);
if (!arg) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
float d = (float) PR_strtod(arg, &end);
arg = nsCRT::strtok(args, delimiters3, &args);
if (!arg) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
float e = (float) PR_strtod(arg, &end);
arg = nsCRT::strtok(args, delimiters3, &args);
if (!arg) {
rv = NS_ERROR_FAILURE;
break; // parse error
}
float f = (float) PR_strtod(arg, &end);
nsCOMPtr<nsIDOMSVGMatrix> matrix;
NS_NewSVGMatrix(getter_AddRefs(matrix),
a, b, c, d, e, f);
m[0], m[1], m[2], m[3], m[4], m[5]);
NS_ASSERTION(matrix, "couldn't create matrix");
transform->SetMatrix(matrix);
}
else { // parse error
rv = NS_ERROR_FAILURE;
break;
}
}
xforms.AppendObject(transform);
}
@ -302,6 +260,54 @@ nsSVGTransformList::SetValueString(const nsAString& aValue)
return rv;
}
// helper for SetValueString
// parse up to nvars comma-separated parameters into vars, returning
// the number of variables actually provided.
//
// -1 will be returned if any of the arguments can't be converted to a
// float. The return value may be higher than nvars, if more
// arguments were provided; no attempt is made to actually parse any
// more arguments than nvars.
//
// note that this would accept ",,," and will just return 0
// arguments found, instead of -1. This is because the numeric
// values can have spaces surrounding them, but the spaces can also
// be used as delimiters. strtok doesn't tell us what the
// delimiter is, so we have no way to distinguish
// ' 20,20 ' from ',,20,20,,' (or from ',,20 20,,', for that matter).
//
// XXX If someone knows for sure that it's not ok to mix commas and
// spaces as delimiters, then we can scan the string for a comma,
// and if found use a delimiter of just ",", otherwise use a set of
// spaces (without a comma).
PRInt32
nsSVGTransformList::ParseParameterList(char *paramstr, float *vars, PRInt32 nvars)
{
if (!paramstr)
return 0;
char *arg, *argend, *argrest = paramstr;
int num_args_found = 0;
float f;
const char* arg_delimiters = "\x20\x09\x0d\x0a,";
while ((arg = nsCRT::strtok(argrest, arg_delimiters, &argrest))) {
if (num_args_found < nvars) {
f = (float) PR_strtod(arg, &argend);
if (arg == argend)
return -1;
vars[num_args_found] = f;
}
arg = argrest;
num_args_found++;
}
return num_args_found;
}
NS_IMETHODIMP
nsSVGTransformList::GetValueString(nsAString& aValue)
{

View File

@ -83,6 +83,7 @@ public:
PRBool AppendElement(nsIDOMSVGTransform* aElement);
protected:
PRInt32 ParseParameterList(char *paramstr, float *vars, PRInt32 nvars);
void ReleaseTransforms();
nsAutoVoidArray mTransforms;