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(SVGTransform* first, SVGTransform* second, unsigned repeatCount) { ASSERT(first->transformType() == second->transformType()); SVGTransform* transform = SVGTransform::create(); switch (first->transformType()) { case kSvgTransformMatrix: ASSERT_NOT_REACHED(); case kSvgTransformUnknown: return transform; case kSvgTransformRotate: { transform->setRotate(first->angle() + second->angle() * repeatCount, first->rotationCenter().x() + second->rotationCenter().x() * repeatCount, first->rotationCenter().y() + second->rotationCenter().y() * repeatCount); return transform; } case kSvgTransformTranslate: { float dx = first->translate().x() + second->translate().x() * repeatCount; float dy = first->translate().y() + second->translate().y() * repeatCount; transform->setTranslate(dx, dy); return transform; } case kSvgTransformScale: { FloatSize scale = second->scale(); scale.scale(repeatCount); scale += first->scale(); transform->setScale(scale.width(), scale.height()); return transform; } case kSvgTransformSkewx: transform->setSkewX(first->angle() + second->angle() * repeatCount); return transform; case kSvgTransformSkewy: transform->setSkewY(first->angle() + second->angle() * repeatCount); return transform; } ASSERT_NOT_REACHED(); return transform; }
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* SVGTransformDistance::addToSVGTransform( SVGTransform* transform) const { DCHECK(m_transformType == transform->transformType() || m_transformType == kSvgTransformUnknown); SVGTransform* newTransform = transform->clone(); switch (m_transformType) { case kSvgTransformMatrix: ASSERT_NOT_REACHED(); case kSvgTransformUnknown: return SVGTransform::create(); case kSvgTransformTranslate: { FloatPoint translation = transform->translate(); translation += FloatSize::narrowPrecision(m_transform.e(), m_transform.f()); newTransform->setTranslate(translation.x(), translation.y()); return newTransform; } case kSvgTransformScale: { FloatSize scale = transform->scale(); scale += FloatSize::narrowPrecision(m_transform.a(), m_transform.d()); newTransform->setScale(scale.width(), scale.height()); return newTransform; } case kSvgTransformRotate: { FloatPoint center = transform->rotationCenter(); newTransform->setRotate(transform->angle() + m_angle, center.x() + m_cx, center.y() + m_cy); return newTransform; } case kSvgTransformSkewx: newTransform->setSkewX(transform->angle() + m_angle); return newTransform; case kSvgTransformSkewy: newTransform->setSkewY(transform->angle() + m_angle); return newTransform; } ASSERT_NOT_REACHED(); return newTransform; }
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; }