FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, const SVGLength& x, const SVGLength& y, const SVGLength& width, const SVGLength& height) { DCHECK_NE(SVGUnitTypes::kSvgUnitTypeUnknown, type); if (type != SVGUnitTypes::kSvgUnitTypeUserspaceonuse) { const FloatSize& viewportSize = viewport.size(); return FloatRect( convertValueFromPercentageToUserUnits(x, viewportSize) + viewport.x(), convertValueFromPercentageToUserUnits(y, viewportSize) + viewport.y(), convertValueFromPercentageToUserUnits(width, viewportSize), convertValueFromPercentageToUserUnits(height, viewportSize)); } SVGLengthContext lengthContext(context); return FloatRect(x.value(lengthContext), y.value(lengthContext), width.value(lengthContext), height.value(lengthContext)); }
IntSize SVGImage::size() const { if (!m_page) return IntSize(); Frame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); if (!rootElement) return IntSize(); SVGLength width = rootElement->width(); SVGLength height = rootElement->height(); IntSize svgSize; if (width.unitType() == LengthTypePercentage) svgSize.setWidth(rootElement->relativeWidthValue()); else svgSize.setWidth(static_cast<int>(width.value(rootElement))); if (height.unitType() == LengthTypePercentage) svgSize.setHeight(rootElement->relativeHeightValue()); else svgSize.setHeight(static_cast<int>(height.value(rootElement))); return svgSize; }
PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& length) { CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN; switch (length.unitType()) { case LengthTypeUnknown: break; case LengthTypeNumber: cssType = CSSPrimitiveValue::CSS_NUMBER; break; case LengthTypePercentage: cssType = CSSPrimitiveValue::CSS_PERCENTAGE; break; case LengthTypeEMS: cssType = CSSPrimitiveValue::CSS_EMS; break; case LengthTypeEXS: cssType = CSSPrimitiveValue::CSS_EXS; break; case LengthTypePX: cssType = CSSPrimitiveValue::CSS_PX; break; case LengthTypeCM: cssType = CSSPrimitiveValue::CSS_CM; break; case LengthTypeMM: cssType = CSSPrimitiveValue::CSS_MM; break; case LengthTypeIN: cssType = CSSPrimitiveValue::CSS_IN; break; case LengthTypePT: cssType = CSSPrimitiveValue::CSS_PT; break; case LengthTypePC: cssType = CSSPrimitiveValue::CSS_PC; break; }; return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType); }
float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle* style, SVGElement* lengthContext) const { if (style->baselineShift() == BS_LENGTH) { SVGLength baselineShiftValueLength = style->baselineShiftValue(); if (baselineShiftValueLength.unitType() == LengthTypePercentage) return baselineShiftValueLength.valueAsPercentage() * m_font.pixelSize(); return baselineShiftValueLength.value(lengthContext); } switch (style->baselineShift()) { case BS_BASELINE: return 0; case BS_SUB: return -m_font.height() / 2; case BS_SUPER: return m_font.height() / 2; default: ASSERT_NOT_REACHED(); return 0; } }
float SVGTextLayoutEngineSpacing::calculateCSSKerningAndSpacing(const SVGRenderStyle* style, SVGElement* lengthContext, const UChar* currentCharacter) { float kerning = 0; SVGLength kerningLength = style->kerning(); if (kerningLength.unitType() == LengthTypePercentage) kerning = kerningLength.valueAsPercentage() * m_font.pixelSize(); else kerning = kerningLength.value(lengthContext); const UChar* lastCharacter = m_lastCharacter; m_lastCharacter = currentCharacter; if (!kerning && !m_font.letterSpacing() && !m_font.wordSpacing()) return 0; float spacing = m_font.letterSpacing() + kerning; if (currentCharacter && lastCharacter && m_font.wordSpacing()) { if (Font::treatAsSpace(*currentCharacter) && !Font::treatAsSpace(*lastCharacter)) spacing += m_font.wordSpacing(); } return spacing; }
SVGParsingError SVGLengthList::parseInternal(const CharType*& ptr, const CharType* end) { const CharType* listStart = ptr; while (ptr < end) { const CharType* start = ptr; // TODO(shanmuga.m): Enable calc for SVGLengthList while (ptr < end && *ptr != ',' && !isHTMLSpace<CharType>(*ptr)) ptr++; if (ptr == start) break; String valueString(start, ptr - start); if (valueString.isEmpty()) break; SVGLength* length = SVGLength::create(m_mode); SVGParsingError lengthParseStatus = length->setValueAsString(valueString); if (lengthParseStatus != SVGParseStatus::NoError) return lengthParseStatus.offsetWith(start - listStart); append(length); skipOptionalSVGSpacesOrDelimiter(ptr, end); } return SVGParseStatus::NoError; }
// Helper function static float calculateBaselineShift(RenderObject* item) { ASSERT(item); ASSERT(item->style()); ASSERT(item->node()); ASSERT(item->node()->isSVGElement()); const Font& font = item->style()->font(); const SVGRenderStyle* svgStyle = item->style()->svgStyle(); float baselineShift = 0.0f; if (svgStyle->baselineShift() == BS_LENGTH) { SVGLength baselineShiftValueLength = svgStyle->baselineShiftValue(); if (baselineShiftValueLength.unitType() == LengthTypePercentage) baselineShift = baselineShiftValueLength.valueAsPercentage() * font.pixelSize(); else baselineShift = baselineShiftValueLength.value(static_cast<SVGElement*>(item->node())); } else { float baselineAscent = font.ascent() + font.descent(); switch (svgStyle->baselineShift()) { case BS_BASELINE: break; case BS_SUB: baselineShift = -baselineAscent / 2.0f; break; case BS_SUPER: baselineShift = baselineAscent / 2.0f; break; default: ASSERT_NOT_REACHED(); } } return baselineShift; }
nsresult SVGLengthList::SetValueFromString(const nsAString& aValue) { SVGLengthList temp; nsCharSeparatedTokenizerTemplate<IsSVGWhitespace> tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL); nsCAutoString str; // outside loop to minimize memory churn while (tokenizer.hasMoreTokens()) { SVGLength length; if (!length.SetValueFromString(tokenizer.nextToken())) { return NS_ERROR_DOM_SYNTAX_ERR; } if (!temp.AppendItem(length)) { return NS_ERROR_OUT_OF_MEMORY; } } if (tokenizer.lastTokenEndedWithSeparator()) { return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma } return CopyFrom(temp); }
FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, const SVGLength& x, const SVGLength& y, const SVGLength& width, const SVGLength& height) { ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { SVGLengthContext lengthContext(context); return FloatRect(x.value(lengthContext), y.value(lengthContext), width.value(lengthContext), height.value(lengthContext)); } SVGLengthContext lengthContext(context, viewport); return FloatRect(x.value(lengthContext) + viewport.x(), y.value(lengthContext) + viewport.y(), width.value(lengthContext), height.value(lengthContext)); }
void SPGenericEllipse::set(unsigned int key, gchar const *value) { // There are multiple ways to set internal cx, cy, rx, and ry (via SVG attributes or Sodipodi // attributes) thus we don't want to unset them if a read fails (e.g., when we explicitly clear // an attribute by setting it to NULL). SVGLength t; switch (key) { case SP_ATTR_CX: case SP_ATTR_SODIPODI_CX: if( t.read(value) ) cx = t; this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_CY: case SP_ATTR_SODIPODI_CY: if( t.read(value) ) cy = t; this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_RX: case SP_ATTR_SODIPODI_RX: if( t.read(value) && t.value > 0.0 ) this->rx = t; this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_RY: case SP_ATTR_SODIPODI_RY: if( t.read(value) && t.value > 0.0 ) this->ry = t; this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_R: if( t.read(value) && t.value > 0.0 ) { this->ry = this->rx = t; } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_SODIPODI_START: if (value) { sp_svg_number_read_d(value, &this->start); } else { this->start = 0; } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_SODIPODI_END: if (value) { sp_svg_number_read_d(value, &this->end); } else { this->end = 2 * M_PI; } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_SODIPODI_OPEN: this->_closed = (!value); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; default: SPShape::set(key, value); break; } }
static float convertValueFromPercentageToUserUnits(const SVGLength& value, const FloatSize& viewportSize) { return CSSPrimitiveValue::clampToCSSLengthRange(value.scaleByPercentage(dimensionForLengthMode(value.unitMode(), viewportSize))); }
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 }
STDMETHODIMP CESVGRectElement::Move(ISVGView* view, double dx, double dy) { ATLASSERT(0); #if 0 CComQIPtr<ILSVGRectElement> rect = m_domElement; CComPtr<ILHTMLWindow> window; view->GetHTMLWindow(&window); CComPtr<ILSVGElement> viewportElement; rect->get_viewportElement(&viewportElement); // TODO, this can't be correct CComPtr<ILSVGRect> _rect; window->svgGetRBBox(viewportElement, &_rect); SVGRect viewBox = _rect; // x { CComPtr<ILSVGAnimatedLength> alength; rect->get_x(&alength); SVGLength length; alength->get_baseVal(&length); if (length.GetUnitType() == SVG_LENGTHTYPE_PERCENTAGE) { double dx_pcnt = dx*100/viewBox.Width; double value; length->get_valueInSpecifiedUnits(&value); length->put_valueInSpecifiedUnits(value+dx_pcnt); } else { double value; length->get_value(&value); length->put_value(value + dx); } } // y { CComPtr<ILSVGAnimatedLength> alength; rect->get_y(&alength); SVGLength length; alength->get_baseVal(&length); if (length.GetUnitType() == SVG_LENGTHTYPE_PERCENTAGE) { double dy_pcnt = dy*100/viewBox.Height; double value; length->get_valueInSpecifiedUnits(&value); length->put_valueInSpecifiedUnits(value+dy_pcnt); } else { double value; length->get_value(&value); length->put_value(value + dy); } } #endif return S_OK; }
STDMETHODIMP CESVGRectElement::Resize(ISVGView* view, double x, double y, double width, double height) { ATLASSERT(0); #if 0 CComQIPtr<ILSVGRectElement> rect = m_domElement; CComPtr<ILHTMLWindow> window; view->GetHTMLWindow(&window); CComPtr<ILSVGElement> viewportElement; rect->get_viewportElement(&viewportElement); // TODO, this can't be correct CComPtr<ILSVGRect> _rect; window->svgGetRBBox(viewportElement, &_rect); SVGRect viewBox = _rect; // x { CComQIPtr<ILSVGAnimatedLength> alength; rect->get_x(&alength); SVGLength length; alength->get_baseVal(&length); if (length.GetUnitType() == SVG_LENGTHTYPE_PERCENTAGE) { double x_pcnt = x*100/viewBox.Width; length->set_valueInSpecifiedUnits(x_pcnt); } else { length->put_value(x); } } // y { CComQIPtr<ILSVGAnimatedLength> alength; rect->get_y(&alength); SVGLength length; alength->get_baseVal(&length); if (length.GetUnitType() == SVG_LENGTHTYPE_PERCENTAGE) { double y_pcnt = y*100/viewBox.Height; length->set_valueInSpecifiedUnits(y_pcnt); } else { length->put_value(y); } } // width { CComQIPtr<ILSVGAnimatedLength> alength; rect->get_width(&alength); SVGLength length; alength->get_baseVal(&length); if (length.GetUnitType() == SVG_LENGTHTYPE_PERCENTAGE) { double width_pcnt = width*100/viewBox.Width; length->set_valueInSpecifiedUnits(width_pcnt); } else { length->put_value(width); } } // height { CComQIPtr<ILSVGAnimatedLength> alength; rect->get_height(&alength); SVGLength length; alength->get_baseVal(&length); if (length.GetUnitType() == SVG_LENGTHTYPE_PERCENTAGE) { double height_pcnt = height*100/viewBox.Height; length->set_valueInSpecifiedUnits(height_pcnt); } else { length->put_value(height); } } #endif return S_OK; }
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); }