void SVGAnimateMotionElement::animationTraverse(svgl::AnimationInfo* animinfo) { _elementToAnimate = animinfo->element; _translateToAnimate = 0; SVGTransformable* toAnimate = dynamic_cast<SVGTransformable*>(_elementToAnimate); if(!toAnimate) { std::cerr << "element refered by 'animateMotion' is not a SVGTransformable" << __FL__; return; } Attribute< SVGAnimatedTransformList >& transform = toAnimate->transform; { std::vector <float> v; v.push_back(0); v.push_back(0); _translateToAnimate = new SVGTranslateTransform(v); } MYGET_ANIMATED_VAL(transform).insertItemBefore(_translateToAnimate, 0); _doBezierAnim=false; _doRotateAnim = rotate_no; _rotateToAnimate=0; const SVGNumberList& keytimes = GET_SIMPLE_VAL(KeyTimes); const SVGPathSegList* pl=0; dom::Node *n = getFirstChild(); if(n) { SVGMPathElement* mpath = 0; for(;n;n=n->getNextSibling()) { mpath = dynamic_cast<SVGMPathElement*>(n); if(mpath) break; } if(mpath) { unicode::String* href = mpath->GET_SIMPLE_VAL(Href); if(href->getLength()) { dom::Element* de = animinfo->externalEntityManager->get(href, getOwnerDocument()); //dom::Element* de = GET_SIMPLE_VAL(OwnerSVGElement)->getElementById(href->substring(1)); SVGPathElement* path = dynamic_cast<SVGPathElement*>(de); if(de) pl = &(path->GET_SIMPLE_VAL(PathSegList)); } } } else pl = &(GET_SIMPLE_VAL(Path)); if (pl && pl->numberOfItems()>=2) { BezierPath bezier; for(unsigned int i=0; i<pl->numberOfItems(); ++i) { const SVGPathSeg* p = pl->getItem(i); p->updateBezier(bezier); } _distanceIter = new svgl::BezierPathDistanceIterator(bezier,.1); _bezierLength = svgl::length(bezier); unicode::String* rotate_ptr = GET_SIMPLE_VAL(Rotate); unicode::String& rotate = *rotate_ptr; if (rotate_ptr && rotate.getLength()) { static unicode::String &auto_string = *unicode::String::internString("auto"), &auto_reverse_string = *unicode::String::internString("auto-reverse"); float rot=0; if(rotate==auto_string) { _doRotateAnim=rotate_auto; } else if(rotate==auto_reverse_string) { _doRotateAnim=rotate_auto_reverse; } else { if (unicode::get_float(rotate, &rot)) { _doRotateAnim=rotate_angle; } } if(_doRotateAnim!=rotate_no) { std::vector<float> v; v.push_back(rot); v.push_back(0); v.push_back(0); _rotateToAnimate = new SVGRotateTransform(v); MYGET_ANIMATED_VAL(transform).insertItemBefore(_rotateToAnimate, 1); } } _doBezierAnim = true; } else { const SVGLengthList& values = GET_SIMPLE_VAL(Values); unsigned int valuesSize = values.numberOfItems(); if(valuesSize) { if(valuesSize % 2) { std::cerr << "'values' for 'animateMotion' must be a list of pair of length" << __FL__; return; } if(keytimes.numberOfItems()) { if(keytimes.numberOfItems()!=values.numberOfItems()) { std::cerr << "'keyTimes' and 'values' have different size" << __FL__; return; } for(unsigned int i=0; i<values.numberOfItems(); ++++i) { SVGLength l = values.getItem(i); float v1 = l.computeValue(); l = values.getItem(i+1); float v2 = l.computeValue(); //_keyFrames.push_back(KeyFrame(KeyFrame::ValueType<float,float>(v1,v2), keytimes.getItem(i).getValue().getValue())); _keyFrames.push_back(KeyFrame(KeyFrame::ValueType(v1,v2), keytimes.getItem(i).GET_SIMPLE_VAL(Value))); } } else { unsigned int num = values.numberOfItems(); float t=0; float dt=1./((num>>1)-1); for(unsigned int i=0; i<num; ++++i) { SVGLength l = values.getItem(i); float v1 = l.computeValue(); l = values.getItem(i+1); float v2 = l.computeValue(); _keyFrames.push_back(KeyFrame(KeyFrame::ValueType(v1,v2), t)); t+=dt; } } } else { unicode::String* fromstr = GET_SIMPLE_VAL(From); unicode::String* tostr = GET_SIMPLE_VAL(To); unicode::String* bystr = GET_SIMPLE_VAL(By); //std::cerr << DBGVAR(attrName) << DBGVAR(attrType) << DBGVAR(fromstr) << DBGVAR(tostr) << __FL__; SVGList<SVGLength> from, to, by; bool fromb=false, tob=false, byb=false; svgl::read(fromstr,from); svgl::read(tostr,to); svgl::read(bystr,by); fromb = (from.numberOfItems()>0); tob = (to.numberOfItems()>0); byb = (by.numberOfItems()>0); // std::cerr << DBGVAR(fromb) << DBGVAR(tob) << DBGVAR(byb) << __FL__; if( !(fromb||tob||byb) ) { std::cerr << "'from', 'to' and 'by' are unset" << __FL__; return; } if(fromb && from.numberOfItems()!=2) { std::cerr << "'from' for 'animateMotion' must be a pair of length" << __FL__; return; } if(tob && to.numberOfItems()!=2) { std::cerr << "'to' for 'animateMotion' must be a pair of length" << __FL__; return; } if(byb && by.numberOfItems()!=2) { std::cerr << "'by' for 'animateMotion' must be a pair of length" << __FL__; return; } // FIXME // from is not computed with right dpi... if(!fromb) { static unicode::String *x_string = unicode::String::internString("x"), *y_string = unicode::String::internString("y"); svgl::AnimateAdapter* x = _elementToAnimate->getAttributeByName(x_string); if(x==0 || !x->canBeSetAsDouble()) { std::cerr << "attribute 'x' of the element referenced by 'animateMotion' can not be set as double" << __FL__; return; } svgl::AnimateAdapter* y = _elementToAnimate->getAttributeByName(y_string); if(y==0 || !y->canBeSetAsDouble()) { std::cerr << "attribute 'y' of the element referenced by 'animateMotion' can not be set as double" << __FL__; return; } SVGLength l; l.newValueSpecifiedUnits(SVGLength::SVG_LENGTHTYPE_NUMBER, x->getBaseVal()); from.replaceItem(l,0); l.newValueSpecifiedUnits(SVGLength::SVG_LENGTHTYPE_NUMBER, y->getBaseVal()); from.replaceItem(l,1); fromb=true; } if(!tob) { if(byb) { to.replaceItem(from.getItem(0)+by.getItem(0), 0); to.replaceItem(from.getItem(1)+by.getItem(1), 1); } #if 0 else { STDDBG; return; } #endif } if(fromb) _keyFrames.push_back(KeyFrame( KeyFrame::ValueType(from.getItem(0).GET_SIMPLE_VAL(Value), from.getItem(1).GET_SIMPLE_VAL(Value)), 0)); _keyFrames.push_back(KeyFrame( KeyFrame::ValueType(to.getItem(0).GET_SIMPLE_VAL(Value), to.getItem(1).GET_SIMPLE_VAL(Value)), 1)); } #if 0 STDDBG; for(unsigned int j=0; j<_keyFrames.size(); ++j) { std::cerr << "( <" << _keyFrames[j].value.first << "," << _keyFrames[j].value.second << ">, " << _keyFrames[j].time << ")"; } std::cerr << std::endl; #endif }
void SVGAnimateElement::animationTraverse(svgl::AnimationInfo* animinfo) { unicode::String* attrName = GET_SIMPLE_VAL(AttributeName); SVG_ANIMATION_ATTRIBUTE_TYPE attrType = GET_SIMPLE_VAL(AttributeType); _elementToAnimate = animinfo->element; _attributeToAnimate=0; switch (attrType) { case SVG_ANIMATION_ATTRIBUTE_TYPE_CSS: std::cerr << "CSS animation not supported" << __FL__; return; break; default: attributeType.setValue(SVG_ANIMATION_ATTRIBUTE_TYPE_AUTO); case SVG_ANIMATION_ATTRIBUTE_TYPE_AUTO: case SVG_ANIMATION_ATTRIBUTE_TYPE_XML: { _attributeToAnimate = _elementToAnimate->getAttributeByName(attrName); } break; #if 0 default: std::cerr << "SVG_ANIMATION_ATTRIBUTE is set to UNKNOWN" << __FL__; break; #endif } if(_attributeToAnimate==0) { if(css::CSSStyleDeclaration::isStyleAttribute(attrName)) { std::cerr << "attribute '" << attrName << "' for element '" << _elementToAnimate->getDtdElement() << "' is a style attribute and is not yet supported yet '<animate>'" << __FL__; } else { std::cerr << "attribute '" << attrName << "' does not exist for element " << _elementToAnimate->getDtdElement() << __FL__; } return; } if(!_attributeToAnimate->canBeSetAsDouble()) { _attributeToAnimate=0; std::cerr << "attribute '" << attrName << "' in element '" << _elementToAnimate->getDtdElement() << "' can not be set as double" << __FL__; return; } const SVGLengthList& values = GET_SIMPLE_VAL(Values); #if 0 std::cerr << "-- values" << __FL__; for(unsigned int t=0; t<values.size(); ++t) std::cerr << values[t] << " "; std::cerr << std::endl; #endif if(values.numberOfItems()) { const SVGNumberList& keytimes = GET_SIMPLE_VAL(KeyTimes); #if 0 std::cerr << "** keytimes " << __FL__; #endif if(keytimes.numberOfItems()) { if(keytimes.numberOfItems()!=values.numberOfItems()) { std::cerr << "'keyTimes' and 'values' have different size" << __FL__; return; } for(std::vector<float>::size_type i=0; i<values.numberOfItems(); ++i) { SVGLength l = values.getItem(i); float v = l.computeValue(); _keyFrames.push_back(KeyFrame(v, keytimes.getItem(i).GET_SIMPLE_VAL(Value))); // std::cerr << values[i] << " " << keytimes[i]; } // std::cerr << std::endl; } else { for(std::vector<float>::size_type i=0; i<values.numberOfItems(); ++i) { float t=i/((float)values.numberOfItems()-1); SVGLength l = values.getItem(i); float v = l.computeValue(); _keyFrames.push_back(KeyFrame(v, t)); } } } else { unicode::String* fromstr = GET_SIMPLE_VAL(From); unicode::String* tostr = GET_SIMPLE_VAL(To); unicode::String* bystr = GET_SIMPLE_VAL(By); //std::cerr << DBGVAR(attrName) << DBGVAR(attrType) << DBGVAR(fromstr) << DBGVAR(tostr) << __FL__; SVGLength froml, tol, byl; bool fromb=false, tob=false, byb=false; froml.dom_setValueAsString(fromstr); tol.dom_setValueAsString(tostr); byl.dom_setValueAsString(bystr); fromb = (froml.GET_SIMPLE_VAL(UnitType) != SVGLength::SVG_LENGTHTYPE_UNKNOWN); tob = (tol.GET_SIMPLE_VAL(UnitType) != SVGLength::SVG_LENGTHTYPE_UNKNOWN); byb = (byl.GET_SIMPLE_VAL(UnitType) != SVGLength::SVG_LENGTHTYPE_UNKNOWN); float from = froml.GET_SIMPLE_VAL(Value); float to = tol.GET_SIMPLE_VAL(Value); float by = byl.GET_SIMPLE_VAL(Value); // std::cerr << DBGVAR(fromb) << DBGVAR(tob) << DBGVAR(byb) << __FL__; if( !(fromb||tob||byb) ) { std::cerr << "'from', 'to' and 'by' are unset" << __FL__; return; } // FIXME // from is not computed with right dpi... if(!fromb) { fromb=true; from = _attributeToAnimate->getBaseVal(); } if(!tob) { if(byb) { to=from+by; } else { STDDBG; return; } } if(fromb) _keyFrames.push_back(KeyFrame(from, 0)); _keyFrames.push_back(KeyFrame(to, 1)); } #if 0 DBG; for(unsigned int j=0; j<_keyFrames.numberOfItems(); ++j) { std::cerr << "(" << _keyFrames[j].value << "," << _keyFrames[j].time << ")"; } std::cerr << std::endl; #endif SVGAnimationElement::animationTraverse(animinfo); }