void wxSVGAnimateTransformElement::ApplyAnimation() {
	wxSVGElement* targetElement = GetTargetElement();
	if (targetElement == NULL || GetDur() <= 0 || (GetTo().GetPropertyType() != wxSVG_ANIMATED_LENGTH
			&& GetTo().GetPropertyType() != wxSVG_ANIMATED_LENGTH_LIST))
		return;
	wxSVGLengthList values;
	if (GetCurrentTime() >= GetStartTime() + GetDur()) {
		if (GetTo().GetPropertyType() == wxSVG_ANIMATED_LENGTH) {
			values.push_back(GetTo().GetLength());
		} else {
			values = GetTo().GetLengthList();
		}
	} else if (GetCurrentTime() >= GetStartTime() && GetFrom().GetPropertyType() == GetTo().GetPropertyType()
			&& GetFrom().GetLengthList().size() == GetTo().GetLengthList().size()) {
		if (GetTo().GetPropertyType() == wxSVG_ANIMATED_LENGTH) {
			values.Add(wxSVGLength(GetTo().GetLength().GetUnitType(), GetFrom().GetLength().GetValue()
					+ (GetTo().GetLength().GetValue() - GetFrom().GetLength().GetValue())*
					(GetCurrentTime() - GetStartTime())/GetDur()));
		} else {
			for (unsigned int i = 0; i < GetFrom().GetLengthList().size(); i++) {
				const wxSVGLength& from = GetFrom().GetLengthList()[i];
				const wxSVGLength& to = GetTo().GetLengthList()[i];
				values.Add(wxSVGLength(to.GetUnitType(), from.GetValue()
						+ (to.GetValue() - from.GetValue())*(GetCurrentTime() - GetStartTime())/GetDur()));
			}
		}
	} else {
		return;
	}
	wxSVGTransformable* transformable = wxSVGTransformable::GetSVGTransformable(*targetElement);
	if (transformable != NULL) {
		if (m_transformIdx == -1 || m_transformIdx >= (int) transformable->GetTransformList().GetAnimVal().size()) {
			wxSVGTransformList& transforms = transformable->GetTransformList().GetAnimVal();
			if (GetAdditive() != wxSVG_ANIMATION_ADDITIVE_SUM) {
				transforms.Clear();
			}
			wxSVGTransform* transform = new wxSVGTransform();
			UpdateTransform(*transform, GetType(), values);
			transforms.Add(transform);
			m_transformIdx = transforms.size() - 1; 
		} else {
			UpdateTransform(transformable->GetTransformList().GetAnimVal()[m_transformIdx], GetType(), values);
		}
	} else {
		wxSVGTransformList transforms;
		wxSVGTransform* transform = new wxSVGTransform();
		UpdateTransform(*transform, GetType(), values);
		transforms.Add(transform);
		targetElement->SetAnimatedValue(GetAttributeName(), wxSVGAnimatedType(transforms));
	}
}
Beispiel #2
0
/** Renders SVG to bitmap image */
wxImage wxSVGDocument::Render(int width, int height, const wxSVGRect* rect, bool preserveAspectRatio, bool alpha,
		wxProgressDialog* progressDlg) {
	if (!GetRootElement())
		return wxImage();
	
	m_screenCTM = wxSVGMatrix();
	
	if (GetRootElement()->GetWidth().GetBaseVal().GetUnitType() == wxSVG_LENGTHTYPE_UNKNOWN)
		GetRootElement()->SetWidth(wxSVGLength(wxSVG_LENGTHTYPE_PERCENTAGE, 100));
	if (GetRootElement()->GetHeight().GetBaseVal().GetUnitType() == wxSVG_LENGTHTYPE_UNKNOWN)
		GetRootElement()->SetHeight(wxSVGLength(wxSVG_LENGTHTYPE_PERCENTAGE, 100));
	
	if (width == -1 || height == -1) {
		width = (int) GetRootElement()->GetWidth().GetAnimVal();
		height = (int) GetRootElement()->GetHeight().GetAnimVal();
		if (width <= 0 || height <= 0) {
			width = (int) GetRootElement()->GetViewBox().GetAnimVal().GetWidth();
			height = (int) GetRootElement()->GetViewBox().GetAnimVal().GetHeight();
		}
	}
	
	if (GetRootElement()->GetWidth().GetAnimVal().GetUnitType() == wxSVG_LENGTHTYPE_PERCENTAGE) {
		wxSVGAnimatedLength l = GetRootElement()->GetWidth();
		l.GetBaseVal().ToViewportWidth(width);
		if (l.GetBaseVal() != ((const wxSVGAnimatedLength&) l).GetAnimVal())
			l.GetAnimVal().ToViewportWidth(width);
		GetRootElement()->SetWidth(l);
	}
	if (GetRootElement()->GetHeight().GetAnimVal().GetUnitType() == wxSVG_LENGTHTYPE_PERCENTAGE) {
		wxSVGAnimatedLength l = GetRootElement()->GetHeight();
		l.GetBaseVal().ToViewportHeight(height);
		if (l.GetBaseVal() != ((const wxSVGAnimatedLength&) l).GetAnimVal())
			l.GetAnimVal().ToViewportHeight(height);
		GetRootElement()->SetHeight(l);
	}
	
	// scale it to fit in
	m_scale = 1;
	m_scaleY = -1; // == m_scale
	if (GetRootElement()->GetWidth().GetAnimVal() > 0 && GetRootElement()->GetHeight().GetAnimVal() > 0) {
		if (preserveAspectRatio) {
			m_scale = width / GetRootElement()->GetWidth().GetAnimVal();
			if (m_scale > height / GetRootElement()->GetHeight().GetAnimVal())
				m_scale = height / GetRootElement()->GetHeight().GetAnimVal();
			m_screenCTM = m_screenCTM.Scale(m_scale);

			width = (int) (m_scale * GetRootElement()->GetWidth().GetAnimVal());
			height = (int) (m_scale * GetRootElement()->GetHeight().GetAnimVal());
		} else {
			m_scale = width / GetRootElement()->GetWidth().GetAnimVal();
			m_scaleY = height / GetRootElement()->GetHeight().GetAnimVal();
			m_screenCTM = m_screenCTM.ScaleNonUniform(m_scale, m_scaleY);
		}
	}
	
	// render only rect if specified
	if (rect && !rect->IsEmpty()) {
		m_screenCTM = m_screenCTM.Translate(-rect->GetX(), -rect->GetY());
		if (rect->GetWidth() * GetScaleX() < width)
			width = (int) (rect->GetWidth() * GetScaleX());
		if (rect->GetHeight() * GetScaleY() < height)
			height = (int) (rect->GetHeight() * GetScaleY());
	}
	
	// render
	m_canvas->Init(width, height, alpha);
	if (!alpha)
		m_canvas->Clear(*wxWHITE);
	GetCanvas()->RenderElement(GetRootElement(), rect, &m_screenCTM, &GetRootElement()->GetStyle(), NULL, NULL,
			progressDlg);

	return m_canvas->GetImage();
}
Beispiel #3
0
wxSVGLength wxSVGSVGElement::CreateSVGLength() const {
    return wxSVGLength();
}
Beispiel #4
0
void wxSVGCanvas::RenderElement(wxSVGElement* elem, const wxSVGRect* rect, const wxSVGMatrix* parentMatrix,
		const wxCSSStyleDeclaration* parentStyle, wxSVGSVGElement* ownerSVGElement, wxSVGElement* viewportElement,
		wxProgressDialog* progressDlg) {
	wxSVGMatrix matrix(*parentMatrix);
	wxCSSStyleRef style(*parentStyle);
	elem->SetOwnerSVGElement(ownerSVGElement);
	elem->SetViewportElement(viewportElement);

	switch (elem->GetDtd()) {
	case wxSVG_SVG_ELEMENT: {
		wxSVGSVGElement* element = (wxSVGSVGElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		if (element->GetWidth().GetAnimVal().GetUnitType() == wxSVG_LENGTHTYPE_UNKNOWN)
			((wxSVGAnimatedLength&) element->GetWidth()).SetAnimVal( wxSVGLength(wxSVG_LENGTHTYPE_PERCENTAGE, 100));
		if (element->GetHeight().GetAnimVal().GetUnitType() == wxSVG_LENGTHTYPE_UNKNOWN)
			((wxSVGAnimatedLength&) element->GetHeight()).SetAnimVal( wxSVGLength(wxSVG_LENGTHTYPE_PERCENTAGE, 100));
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		if (rect && element->GetParent()) {
			wxSVGRect rect2 = *rect;
			wxSVGElement* parent = (wxSVGElement*) element->GetParent();
			wxSVGTransformable* transformable = wxSVGTransformable::GetSVGTransformable(*parent);
			if (transformable)
				rect2 = rect2.MatrixTransform(transformable->GetCTM().Inverse());
			RenderChilds(elem, &rect2, &matrix, &style, element, element, progressDlg);
		} else
			RenderChilds(elem, rect, &matrix, &style, element, element, progressDlg);
		break;
	}
	case wxSVG_G_ELEMENT: {
		wxSVGGElement* element = (wxSVGGElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		RenderChilds(elem, rect, &matrix, &style, ownerSVGElement, viewportElement, progressDlg);
		break;
	}
	case wxSVG_LINE_ELEMENT: {
		wxSVGLineElement* element = (wxSVGLineElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawLine(element, &matrix, &style);
		break;
	}
	case wxSVG_POLYLINE_ELEMENT: {
		wxSVGPolylineElement* element = (wxSVGPolylineElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawPolyline(element, &matrix, &style);
		break;
	}
	case wxSVG_POLYGON_ELEMENT: {
		wxSVGPolygonElement* element = (wxSVGPolygonElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawPolygon(element, &matrix, &style);
		break;
	}
	case wxSVG_RECT_ELEMENT: {
		wxSVGRectElement* element = (wxSVGRectElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawRect(element, &matrix, &style);
		break;
	}
	case wxSVG_CIRCLE_ELEMENT: {
		wxSVGCircleElement* element = (wxSVGCircleElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawCircle(element, &matrix, &style);
		break;
	}
	case wxSVG_ELLIPSE_ELEMENT: {
		wxSVGEllipseElement* element = (wxSVGEllipseElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawEllipse(element, &matrix, &style);
		break;
	}
	case wxSVG_PATH_ELEMENT: {
		wxSVGPathElement* element = (wxSVGPathElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawPath(element, &matrix, &style);
		break;
	}
	case wxSVG_TSPAN_ELEMENT:
		break;
	case wxSVG_TEXT_ELEMENT: {
		wxSVGTextElement* element = (wxSVGTextElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawText(element, &matrix, &style);
		break;
	}
	case wxSVG_IMAGE_ELEMENT: {
		wxSVGImageElement* element = (wxSVGImageElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN || element->GetOpacity() == 0)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		DrawImage(element, &matrix, &style, rect, progressDlg);
		break;
	}
	case wxSVG_VIDEO_ELEMENT: {
		wxSVGVideoElement* element = (wxSVGVideoElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN || element->GetOpacity() == 0)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
#ifdef USE_LIBAV
		DrawVideo(element, &matrix, &style);
#else
		wxSVGGElement* gElem = new wxSVGGElement();
		gElem->SetOwnerSVGElement(ownerSVGElement);
		gElem->SetViewportElement(viewportElement);
		gElem->SetStyle(element->GetStyle());
		wxSVGRectElement* rectElem = new wxSVGRectElement();
		rectElem->SetX(element->GetX().GetAnimVal());
		rectElem->SetY(element->GetY().GetAnimVal());
		rectElem->SetWidth(element->GetWidth().GetAnimVal());
		rectElem->SetHeight(element->GetHeight().GetAnimVal());
		rectElem->SetFill(wxSVGPaint(0,0,0));
		gElem->AppendChild(rectElem);
		wxSVGTextElement* textElem = new wxSVGTextElement;
		textElem->SetX((double)element->GetX().GetAnimVal());
		textElem->SetY(element->GetY().GetAnimVal()+(double)element->GetHeight().GetAnimVal()/10);
		textElem->SetFontSize((double)element->GetHeight().GetAnimVal()/15);
		textElem->SetFill(wxSVGPaint(255,255,255));
		textElem->SetStroke(wxSVGPaint(255,255,255));
		textElem->AddChild(new wxSvgXmlNode(wxSVGXML_TEXT_NODE, wxT(""), wxT(" [") + element->GetHref() + wxT("]")));
		gElem->AppendChild(textElem);

		// render
		RenderElement(gElem, rect, &matrix, &style, ownerSVGElement, viewportElement, progressDlg);
		// delete shadow tree
		delete gElem;
#endif
		break;
	}
	case wxSVG_USE_ELEMENT: {
		wxSVGUseElement* element = (wxSVGUseElement*) elem;
		if (element->GetVisibility() == wxCSS_VALUE_HIDDEN)
			break;
		element->UpdateMatrix(matrix);
		style.Add(element->GetStyle());
		style.Add(element->GetAnimStyle());
		// test if visible
		if (element->GetWidth().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN
				&& element->GetHeight().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN) {
			if (rect && !ownerSVGElement->CheckIntersection(*elem, *rect))
				break;
			wxSVGPoint point(element->GetX().GetAnimVal() + element->GetWidth().GetAnimVal(),
					element->GetY().GetAnimVal() + element->GetHeight().GetAnimVal());
			point = point.MatrixTransform(matrix);
			if (point.GetX() < 0 || point.GetY() < 0)
				break;
		}
		// get ref element
		wxString href = element->GetHref();
		if (href.length() == 0 || href.GetChar(0) != wxT('#'))
			break;
		href.Remove(0, 1);
		wxSVGElement* refElem = (wxSVGElement*) ownerSVGElement->GetElementById(href);
		if (!refElem)
			break;

		// create shadow tree
		wxSVGGElement* gElem = new wxSVGGElement();
		gElem->SetOwnerDocument(elem->GetOwnerDocument());
		gElem->SetOwnerSVGElement(ownerSVGElement);
		gElem->SetViewportElement(viewportElement);
		gElem->SetStyle(element->GetStyle());
		if (element->GetX().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN)
			gElem->Translate(element->GetX().GetAnimVal(), element->GetY().GetAnimVal());
		if (refElem->GetDtd() == wxSVG_SYMBOL_ELEMENT || refElem->GetDtd() == wxSVG_SVG_ELEMENT) {
			wxSVGSVGElement* svgElem;
			if (refElem->GetDtd() == wxSVG_SVG_ELEMENT)
				svgElem = (wxSVGSVGElement*) refElem->CloneNode();
			else {
				svgElem = new wxSVGSVGElement();
				wxSvgXmlElement* child = refElem->GetChildren();
				while (child) {
					svgElem->AddChild(child->CloneNode());
					child = child->GetNext();
				}
				svgElem->SetViewBox(((wxSVGSymbolElement*) refElem)->GetViewBox());
				svgElem->SetPreserveAspectRatio(((wxSVGSymbolElement*) refElem)->GetPreserveAspectRatio());
			}
			if (element->GetWidth().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN)
				svgElem->SetWidth(element->GetWidth().GetAnimVal());
			if (element->GetHeight().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN)
				svgElem->SetHeight(element->GetHeight().GetAnimVal());
			gElem->AddChild(svgElem);
			LoadImages(refElem, svgElem, progressDlg);
		} else
			gElem->AddChild(refElem->CloneNode());
		// render
		RenderElement(gElem, rect, &matrix, &style, ownerSVGElement, viewportElement, progressDlg);
		// delete shadow tree
		delete gElem;
		break;
	}
	default:
	  break;
  }
}