bool SVGTransformable::parseTransformValue(SVGTransform::SVGTransformType type, const UChar*& ptr, const UChar* end, SVGTransform& transform) { if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN) return false; int valueCount = 0; float values[] = {0, 0, 0, 0, 0, 0}; if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0) return false; switch (type) { case SVGTransform::SVG_TRANSFORM_UNKNOWN: ASSERT_NOT_REACHED(); break; case SVGTransform::SVG_TRANSFORM_SKEWX: transform.setSkewX(values[0]); break; case SVGTransform::SVG_TRANSFORM_SKEWY: transform.setSkewY(values[0]); break; case SVGTransform::SVG_TRANSFORM_SCALE: if (valueCount == 1) // Spec: if only one param given, assume uniform scaling transform.setScale(values[0], values[0]); else transform.setScale(values[0], values[1]); break; case SVGTransform::SVG_TRANSFORM_TRANSLATE: if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0 transform.setTranslate(values[0], 0); else transform.setTranslate(values[0], values[1]); break; case SVGTransform::SVG_TRANSFORM_ROTATE: if (valueCount == 1) transform.setRotate(values[0], 0, 0); else transform.setRotate(values[0], values[1], values[2]); break; case SVGTransform::SVG_TRANSFORM_MATRIX: transform.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5])); break; } return true; }
SVGTransform SVGTransformDistance::addSVGTransforms(const SVGTransform& first, const SVGTransform& second) { ASSERT(first.type() == second.type()); SVGTransform transform; switch (first.type()) { case SVGTransform::SVG_TRANSFORM_UNKNOWN: return SVGTransform(); case SVGTransform::SVG_TRANSFORM_ROTATE: { transform.setRotate(first.angle() + second.angle(), first.rotationCenter().x() + second.rotationCenter().x(), first.rotationCenter().y() + second.rotationCenter().y()); return transform; } case SVGTransform::SVG_TRANSFORM_MATRIX: transform.setMatrix(first.matrix() * second.matrix()); return transform; case SVGTransform::SVG_TRANSFORM_TRANSLATE: { float dx = first.translate().x() + second.translate().x(); float dy = first.translate().y() + second.translate().y(); transform.setTranslate(dx, dy); return transform; } case SVGTransform::SVG_TRANSFORM_SCALE: { FloatSize scale = first.scale() + second.scale(); transform.setScale(scale.width(), scale.height()); return transform; } case SVGTransform::SVG_TRANSFORM_SKEWX: transform.setSkewX(first.angle() + second.angle()); return transform; case SVGTransform::SVG_TRANSFORM_SKEWY: transform.setSkewY(first.angle() + second.angle()); return transform; } ASSERT_NOT_REACHED(); return SVGTransform(); }
SVGTransform *SVGSVGElement::createSVGTransformFromMatrix(SVGMatrix *matrix) { SVGTransform *obj = SVGSVGElement::createSVGTransform(); obj->setMatrix(matrix); return obj; }
bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const AtomicString& transform) { double x[] = {0, 0, 0, 0, 0, 0}; int nr = 0, required = 0, optional = 0; const UChar* currTransform = transform.characters(); const UChar* end = currTransform + transform.length(); bool delimParsed = false; while (currTransform < end) { delimParsed = false; unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN; skipOptionalSpaces(currTransform, end); if (currTransform >= end) return false; if (*currTransform == 's') { if (skipString(currTransform, end, skewXDesc, sizeof(skewXDesc) / sizeof(UChar))) { required = 1; optional = 0; type = SVGTransform::SVG_TRANSFORM_SKEWX; } else if (skipString(currTransform, end, skewYDesc, sizeof(skewYDesc) / sizeof(UChar))) { required = 1; optional = 0; type = SVGTransform::SVG_TRANSFORM_SKEWY; } else if (skipString(currTransform, end, scaleDesc, sizeof(scaleDesc) / sizeof(UChar))) { required = 1; optional = 1; type = SVGTransform::SVG_TRANSFORM_SCALE; } else return false; } else if (skipString(currTransform, end, translateDesc, sizeof(translateDesc) / sizeof(UChar))) { required = 1; optional = 1; type = SVGTransform::SVG_TRANSFORM_TRANSLATE; } else if (skipString(currTransform, end, rotateDesc, sizeof(rotateDesc) / sizeof(UChar))) { required = 1; optional = 2; type = SVGTransform::SVG_TRANSFORM_ROTATE; } else if (skipString(currTransform, end, matrixDesc, sizeof(matrixDesc) / sizeof(UChar))) { required = 6; optional = 0; type = SVGTransform::SVG_TRANSFORM_MATRIX; } else return false; if ((nr = parseTransformParamList(currTransform, end, x, required, optional)) < 0) return false; SVGTransform t; switch (type) { case SVGTransform::SVG_TRANSFORM_SKEWX: t.setSkewX(narrowPrecisionToFloat(x[0])); break; case SVGTransform::SVG_TRANSFORM_SKEWY: t.setSkewY(narrowPrecisionToFloat(x[0])); break; case SVGTransform::SVG_TRANSFORM_SCALE: if (nr == 1) // Spec: if only one param given, assume uniform scaling t.setScale(narrowPrecisionToFloat(x[0]), narrowPrecisionToFloat(x[0])); else t.setScale(narrowPrecisionToFloat(x[0]), narrowPrecisionToFloat(x[1])); break; case SVGTransform::SVG_TRANSFORM_TRANSLATE: if (nr == 1) // Spec: if only one param given, assume 2nd param to be 0 t.setTranslate(narrowPrecisionToFloat(x[0]), 0); else t.setTranslate(narrowPrecisionToFloat(x[0]), narrowPrecisionToFloat(x[1])); break; case SVGTransform::SVG_TRANSFORM_ROTATE: if (nr == 1) t.setRotate(narrowPrecisionToFloat(x[0]), 0, 0); else t.setRotate(narrowPrecisionToFloat(x[0]), narrowPrecisionToFloat(x[1]), narrowPrecisionToFloat(x[2])); break; case SVGTransform::SVG_TRANSFORM_MATRIX: t.setMatrix(AffineTransform(x[0], x[1], x[2], x[3], x[4], x[5])); break; } ExceptionCode ec = 0; list->appendItem(t, ec); skipOptionalSpaces(currTransform, end); if (currTransform < end && *currTransform == ',') { delimParsed = true; currTransform++; } skipOptionalSpaces(currTransform, end); } return !delimParsed; }