void wxSVGCtrlBase::MoveElement(wxSVGElement* elem, double Xposition, double Yposition) { if (elem->GetDtd() == wxSVG_RECT_ELEMENT) { double stroke_width = 0; if (((wxSVGRectElement*)elem)->GetStroke().GetPaintType() != wxSVG_PAINTTYPE_NONE) stroke_width = ((wxSVGRectElement*)elem)->GetStrokeWidth(); wxSVGMatrix CTM = ((wxSVGRectElement*)elem)->GetCTM(); double denom = CTM.GetB()*CTM.GetC() - CTM.GetA()*CTM.GetD(); double x = (CTM.GetC()*(Yposition-CTM.GetF()) - CTM.GetD()*(Xposition-CTM.GetE())) / denom; double y = (CTM.GetB()*(Xposition-CTM.GetE()) - CTM.GetA()*(Yposition-CTM.GetF())) / denom; wxSVGLength Xvalue(x + stroke_width / 2); wxSVGLength Yvalue(y + stroke_width / 2); ((wxSVGRectElement*)elem)->SetX(Xvalue); ((wxSVGRectElement*)elem)->SetY(Yvalue); } else { wxSVGTransformable* element = wxSVGTransformable::GetSVGTransformable(*elem); wxSVGMatrix CTM = element->GetCTM(); wxSVGTransformList transforms = element->GetTransform().GetBaseVal(); wxSVGMatrix matrix = transforms[(int)transforms.Count()-1].GetMatrix(); wxSVGRect bbox = element->GetResultBBox(wxSVG_COORDINATES_VIEWPORT); wxSVGPoint LeftUp = wxSVGPoint(bbox.GetX(), bbox.GetY()); wxSVGMatrix new_matrix = wxSVGMatrix(); new_matrix = new_matrix.Translate(Xposition - LeftUp.GetX(), Yposition - LeftUp.GetY()); new_matrix = matrix.Multiply(CTM.Inverse().Multiply(new_matrix.Multiply(CTM))); transforms[transforms.Count()-1].SetMatrix(new_matrix); element->SetTransform(transforms); } }
void wxSVGCanvasCairo::DrawCanvasPath(wxSVGCanvasPathCairo& canvasPath, wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem) { // check Filter if (style.GetFilter().GetCSSPrimitiveType() == wxCSS_URI && style.GetFilter().GetStringValue().length() > 1) { wxString filterId = style.GetFilter().GetStringValue().substr(1); wxSVGElement* filterElem = (wxSVGElement*) svgElem.GetElementById(filterId); // feGaussianBlur if (filterElem && filterElem->GetDtd() == wxSVG_FILTER_ELEMENT && filterElem->GetFirstChild() != NULL && ((wxSVGSVGElement*) filterElem->GetFirstChild())->GetDtd() == wxSVG_FEGAUSSIANBLUR_ELEMENT) { float stdX = ((wxSVGFEGaussianBlurElement*) filterElem->GetFirstChild())->GetStdDeviationX().GetAnimVal(); float stdY = ((wxSVGFEGaussianBlurElement*) filterElem->GetFirstChild())->GetStdDeviationY().GetAnimVal(); if (stdX <= 0 || stdY <= 0) return; int dx = int(floor(stdX * 3 * sqrt(2 * M_PI) / 4 + 0.5)); int dy = int(floor(stdY * 3 * sqrt(2 * M_PI) / 4 + 0.5)); wxSVGRect rect = canvasPath.GetResultBBox(style, matrix.Inverse()); rect.SetX(rect.GetX() - 2*dx); rect.SetY(rect.GetY() - 2*dy); rect.SetWidth(rect.GetWidth() + 4*dx); rect.SetHeight(rect.GetHeight() + 4*dy); int width = (int) rect.GetWidth(); int height = (int) rect.GetHeight(); cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t* cr = cairo_create(surface); wxSVGMatrix matrix2 = wxSVGMatrix(1, 0, 0, 1, - rect.GetX(), - rect.GetY()).Multiply(matrix); DrawPath(cr, canvasPath, matrix2, style, svgElem); gaussianBlur(surface, dx, dy); // draw surface cairo_save(m_cr); SetMatrix(m_cr, wxSVGMatrix(1, 0, 0, 1, rect.GetX(), rect.GetY())); cairo_set_source_surface(m_cr, surface, 0, 0); cairo_rectangle(m_cr, 0, 0, width, height); cairo_paint(m_cr); // fill the rectangle using the pattern cairo_new_path(m_cr); cairo_restore(m_cr); cairo_destroy(cr); cairo_surface_destroy(surface); return; } } DrawPath(m_cr, canvasPath, matrix, style, svgElem); }
wxSVGMatrix wxSVGLocatable::GetCTM(const wxSVGElement* element) { if (element == NULL || element->GetType() != wxSVGXML_ELEMENT_NODE || element->GetDtd() == wxSVG_SVG_ELEMENT) return wxSVGMatrix(); wxSVGMatrix matrix = GetCTM((wxSVGElement*) (element->GetParent())); const wxSVGTransformable* transformable = wxSVGTransformable::GetSVGTransformable(*element); if (!transformable) return matrix; transformable->UpdateMatrix(matrix); return matrix; }
wxSVGMatrix wxSVGLocatable::GetScreenCTM(const wxSVGElement* element) { if (element == NULL || element->GetType() != wxSVGXML_ELEMENT_NODE) return wxSVGMatrix(); wxSVGMatrix matrix; if (element->GetParent()) matrix = GetScreenCTM((wxSVGElement*) (element->GetParent())); else if (element->GetOwnerDocument()) matrix = ((wxSVGDocument*) element->GetOwnerDocument())->GetScreenCTM(); if (element->GetDtd() == wxSVG_SVG_ELEMENT) { ((wxSVGSVGElement*) element)->UpdateMatrix(matrix); } else { const wxSVGTransformable* transformable = wxSVGTransformable::GetSVGTransformable(*element); if (transformable) transformable->UpdateMatrix(matrix); } return matrix; }
wxSVGMatrix wxSVGMatrix::SkewY(double angle) const { return Multiply(wxSVGMatrix(1, tan(angle * M_PI / 180), 0, 1, 0, 0)); }
wxSVGMatrix wxSVGMatrix::FlipY() const { return Multiply(wxSVGMatrix(1, 0, 0, -1, 0, 0)); }
wxSVGMatrix wxSVGMatrix::FlipX() const { return Multiply(wxSVGMatrix(-1, 0, 0, 1, 0, 0)); }
wxSVGMatrix wxSVGMatrix::RotateFromVector(double x, double y) const { return Multiply(wxSVGMatrix(1, 0, 0, 1, 0, 0)); }
wxSVGMatrix wxSVGMatrix::Rotate(double angle) const { angle = angle * M_PI / 180; return Multiply(wxSVGMatrix(cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0)); }
wxSVGMatrix wxSVGMatrix::ScaleNonUniform(double scaleFactorX, double scaleFactorY) const { return Multiply(wxSVGMatrix(scaleFactorX, 0, 0, scaleFactorY, 0, 0)); }
wxSVGMatrix wxSVGMatrix::Scale(double scaleFactor) const { return Multiply(wxSVGMatrix(scaleFactor, 0, 0, scaleFactor, 0, 0)); }
wxSVGMatrix wxSVGMatrix::Translate(double x, double y) const { return Multiply(wxSVGMatrix(1, 0, 0, 1, x, y)); }
wxSVGMatrix wxSVGCtrlBase::GetScreenCTM() const { if (m_doc && m_doc->GetRootElement()) return m_doc->GetRootElement()->GetScreenCTM(); return wxSVGMatrix(); }
/** 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(); }
wxSVGMatrix wxSVGSVGElement::CreateSVGMatrix() const { return wxSVGMatrix(); }