wxSVGRect wxSVGCanvasPathCairo::GetBBox(const wxSVGMatrix& matrix) {
	if (&matrix) {
		cairo_matrix_t m;
		cairo_matrix_init(&m, matrix.GetA(), matrix.GetB(), matrix.GetC(), matrix.GetD(), matrix.GetE(), matrix.GetF());
		cairo_set_matrix(m_cr, &m);
	}
	double x1, y1, x2, y2;
	cairo_fill_extents(m_cr, &x1, &y1, &x2, &y2);
	if (&matrix) {
		cairo_matrix_t mat;
		cairo_matrix_init(&mat, 1, 0, 0, 1, 0, 0);
		cairo_set_matrix(m_cr, &mat);
	}
	return wxSVGRect(x1, y1, x2 - x1, y2 - y1);
}
Example #2
0
void wxSVGCanvasCairo::DrawMarker(const wxString& uri, wxSVGMark::Type type, wxSVGCanvasPathCairo& canvasPath,
		const wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem) {
	wxSVGMarkerElement* markerElem = GetMarkerElement(svgElem, uri);
	if (markerElem == NULL || markerElem->GetMarkerWidth().GetAnimVal() <= 0
				|| markerElem->GetMarkerHeight().GetAnimVal() <= 0)
		return;
	vector<wxSVGMark> markPoints = canvasPath.GetMarkPoints();
	for (vector<wxSVGMark>::iterator it = markPoints.begin(); it != markPoints.end(); it++) {
		if (it->type != type)
			continue;
		wxSVGMark& markPoint = *it;
		double scaleX = matrix.GetA() * style.GetStrokeWidth();
		double scaleY = matrix.GetD() * style.GetStrokeWidth();
		markerElem->SetOwnerSVGElement(&svgElem);
		markerElem->SetViewportElement(&svgElem);
		cairo_surface_t* surface = cairo_image_surface_create(
				CAIRO_FORMAT_ARGB32,
				lround(markerElem->GetMarkerWidth().GetAnimVal() * scaleX),
				lround(markerElem->GetMarkerHeight().GetAnimVal() * scaleY));
		cairo_t* cr = cairo_create(surface);
		wxSVGMatrix markerMatrix;
		markerMatrix = markerMatrix.ScaleNonUniform(scaleX, scaleY);
		wxCSSStyleDeclaration style;
		DrawMask(cr, markerElem, markerMatrix, style, svgElem);
		// draw surface
		cairo_save(m_cr);
		double refX = markerElem->GetRefX().GetAnimVal() * style.GetStrokeWidth();
		double refY = markerElem->GetRefY().GetAnimVal() * style.GetStrokeWidth();
		wxSVGPoint point(markPoint.x - refX, markPoint.y - refY);
		point = point.MatrixTransform(matrix);
		wxSVGMatrix m;
		m = m.Translate(point.GetX(), point.GetY());
		if (markPoint.angle != 0) {
			refX = markerElem->GetRefX().GetAnimVal() * scaleX;
			refY = markerElem->GetRefY().GetAnimVal() * scaleY;
			m = m.Translate(refX, refY).Rotate(markPoint.angle / M_PI * 180).Translate(-refX, -refY);
		}
		SetMatrix(m_cr, m);
		cairo_set_source_surface(m_cr, surface, 0, 0);
		cairo_paint(m_cr);
		cairo_restore(m_cr);
		cairo_destroy(cr);
		cairo_surface_destroy(surface);
	}
}
wxSVGRect wxSVGCanvasPathCairo::GetResultBBox(const wxCSSStyleDeclaration& style, const wxSVGMatrix& matrix) {
	if (&matrix) {
		cairo_matrix_t m;
		cairo_matrix_init(&m, matrix.GetA(), matrix.GetB(), matrix.GetC(), matrix.GetD(), matrix.GetE(), matrix.GetF());
		cairo_set_matrix(m_cr, &m);
	}
	ApplyStrokeStyle(m_cr, style);
	double x1, y1, x2, y2;
	if (style.GetStrokeWidth() > 0)
		cairo_stroke_extents(m_cr, &x1, &y1, &x2, &y2);
	else
		cairo_fill_extents(m_cr, &x1, &y1, &x2, &y2);
	if (&matrix) {
		cairo_matrix_t mat;
		cairo_matrix_init(&mat, 1, 0, 0, 1, 0, 0);
		cairo_set_matrix(m_cr, &mat);
	}
	return wxSVGRect(x1, y1, x2 - x1, y2 - y1);
}
Example #4
0
void wxSVGCanvas::DrawCanvasText(wxSVGCanvasText& canvasText,
  wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem)
{
  for (int i=0; i<(int)canvasText.m_chunks.Count(); i++)
  {
	wxSVGCanvasTextChunk& chunk = canvasText.m_chunks[i];
	chunk.style.SetFillRule(wxCSS_VALUE_EVENODD);
	wxSVGMatrix pathMatrix = matrix.Multiply(chunk.matrix);
	for (unsigned int j=0; j<chunk.chars.Count(); j++)
		DrawItem(*chunk.chars[j].path, pathMatrix, chunk.style, svgElem);
  }
}
Example #5
0
void wxSVGCanvas::GetRadialGradientTransform(wxSVGPoint& focus,
  wxSVGMatrix& matrix, const wxSVGRadialGradientElement& gradElem,
  wxSVGCanvasPath& path, bool scale)
{
    double r, cx, cy, fx, fy;
	r = gradElem.GetR().GetAnimVal();
	cx = gradElem.GetCx().GetAnimVal();
	cy = gradElem.GetCy().GetAnimVal();
	fx = gradElem.GetFx().GetAnimVal();
	fy = gradElem.GetFy().GetAnimVal();
    
    if (gradElem.GetGradientUnits().GetAnimVal() == wxSVG_UNIT_TYPE_UNKNOWN ||
        gradElem.GetGradientUnits().GetAnimVal() == wxSVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
    {
        wxSVGRect bbox = path.GetBBox();
        r = r*sqrt(bbox.GetWidth()*bbox.GetWidth() + bbox.GetHeight()*bbox.GetHeight());
        cx = bbox.GetX() + cx*bbox.GetWidth();
        cy = bbox.GetY() + cy*bbox.GetHeight();
        fx = bbox.GetX() + fx*bbox.GetWidth();
        fy = bbox.GetY() + fy*bbox.GetHeight();
    }

	// Compute gradient transformation matrix
	const wxSVGTransformList& transforms =  gradElem.GetGradientTransform().GetAnimVal();
	for (int i=0; i<(int)transforms.Count(); i++)
		matrix = matrix.Multiply(transforms[i].GetMatrix());
	
	// Apply Gradient parameters to transformation
	matrix = matrix.Translate(cx, cy); //.Scale(r);
    if (scale)
      matrix = matrix.Scale(r);
	
	// Change Focus reference to gradient reference
	focus.SetX((fx - cx) / r);
	focus.SetY((fy - cy) / r);
}
Example #6
0
wxSVGMatrix wxSVGMatrix::Multiply(const wxSVGMatrix& secondMatrix) const {
	wxSVGMatrix res;
	res.SetA(GetA() * secondMatrix.GetA() + GetC() * secondMatrix.GetB());
	res.SetB(GetB() * secondMatrix.GetA() + GetD() * secondMatrix.GetB());
	res.SetC(GetA() * secondMatrix.GetC() + GetC() * secondMatrix.GetD());
	res.SetD(GetB() * secondMatrix.GetC() + GetD() * secondMatrix.GetD());
	res.SetE(GetA() * secondMatrix.GetE() + GetC() * secondMatrix.GetF() + GetE());
	res.SetF(GetB() * secondMatrix.GetE() + GetD() * secondMatrix.GetF() + GetF());
	return res;
}
Example #7
0
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);
}
Example #8
0
void wxSVGTransformable::UpdateMatrix(wxSVGMatrix& matrix) const {
    const wxSVGTransformList& transforms = GetTransform().GetAnimVal();
    for (unsigned int i = 0; i < transforms.Count(); i++)
        matrix = matrix.Multiply(transforms[i].GetMatrix());
}
Example #9
0
wxSVGPoint wxSVGPoint::MatrixTransform(const wxSVGMatrix& matrix) const
{
  wxSVGPoint res(m_x*matrix.GetA() + m_y*matrix.GetC() + matrix.GetE(),
	m_x*matrix.GetB() + m_y*matrix.GetD() + matrix.GetF());
  return res;
}
Example #10
0
void wxSVGCanvasCairo::SetMatrix(cairo_t* cr, const wxSVGMatrix& matrix) {
	cairo_matrix_t mat;
	cairo_matrix_init(&mat, matrix.GetA(), matrix.GetB(), matrix.GetC(),
			matrix.GetD(), matrix.GetE(), matrix.GetF());
	cairo_set_matrix(cr, &mat);
}
Example #11
0
void wxSVGCanvasCairo::SetPaint(cairo_t* cr, const wxSVGPaint& paint, float opacity, wxSVGCanvasPathCairo& canvasPath,
		wxSVGSVGElement& svgElem, const wxSVGMatrix& matrix) {
	if (paint.GetPaintType() >= wxSVG_PAINTTYPE_URI_NONE && paint.GetPaintType() <= wxSVG_PAINTTYPE_URI) {
		wxSVGGradientElement* gradElem = GetGradientElement(svgElem, paint.GetUri());
		if (gradElem != NULL) {
			if (m_pattern != NULL) {
				cairo_pattern_destroy(m_pattern);
				m_pattern = NULL;
			}
			switch (gradElem->GetDtd()) {
			case wxSVG_LINEARGRADIENT_ELEMENT: {
				wxSVGPoint p1, p2;
				GetLinearGradientVector(p1, p2, (wxSVGLinearGradientElement&) *gradElem, canvasPath);
				m_pattern = cairo_pattern_create_linear(p1.GetX(), p1.GetY(), p2.GetX(), p2.GetY());
				break;
			}
			case wxSVG_RADIALGRADIENT_ELEMENT: {
				wxSVGRadialGradientElement* radialGradElem = (wxSVGRadialGradientElement*) gradElem;
				double r = radialGradElem->GetQualifiedR();
				double cx = radialGradElem->GetQualifiedCx();
				double cy = radialGradElem->GetQualifiedCy();
				double fx = radialGradElem->GetQualifiedFx();
				double fy = radialGradElem->GetQualifiedFy();
				
				if (gradElem->GetGradientUnits().GetAnimVal() == wxSVG_UNIT_TYPE_UNKNOWN
						|| gradElem->GetGradientUnits().GetAnimVal() == wxSVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
					wxSVGRect bbox = canvasPath.GetBBox();
					r = r * sqrt(bbox.GetWidth() * bbox.GetWidth() + bbox.GetHeight() * bbox.GetHeight());
					cx = bbox.GetX() + cx * bbox.GetWidth();
					cy = bbox.GetY() + cy * bbox.GetHeight();
					fx = bbox.GetX() + fx * bbox.GetWidth();
					fy = bbox.GetY() + fy * bbox.GetHeight();
				}
				m_pattern = cairo_pattern_create_radial(fx, fy, 0.0, cx, cy, r);
				const wxSVGTransformList& transforms =  gradElem->GetGradientTransform().GetAnimVal();
				if (transforms.GetCount() > 0) {
					wxSVGMatrix patMatrix;
					for (unsigned int i = 0; i < transforms.GetCount(); i++)
						patMatrix = patMatrix.Multiply(transforms[i].GetMatrix());
					patMatrix = patMatrix.Inverse();
					cairo_matrix_t mat;
					cairo_matrix_init(&mat, patMatrix.GetA(), patMatrix.GetB(), patMatrix.GetC(), patMatrix.GetD(), patMatrix.GetE(), patMatrix.GetF());
					cairo_pattern_set_matrix(m_pattern, &mat);
				}
				break;
			}
			default:
				break;
			}
			if (m_pattern != NULL) {
				int nstops = GetGradientStops(svgElem, gradElem, opacity);
				if (nstops) {
					cairo_set_source(cr, m_pattern);
				} else {
					cairo_pattern_destroy(m_pattern);
					m_pattern = NULL;
				}
			}
		}
		wxSVGPatternElement* patternElem = GetPatternElement(svgElem, paint.GetUri());
		if (patternElem != NULL && patternElem->GetWidth().GetAnimVal() > 0
				&& patternElem->GetHeight().GetAnimVal() > 0) {
			if (m_pattern != NULL) {
				cairo_pattern_destroy(m_pattern);
				m_pattern = NULL;
			}
			double scaleX = matrix.GetA();
			scaleX = lround(patternElem->GetWidth().GetAnimVal()*scaleX) / patternElem->GetWidth().GetAnimVal(); 
			double scaleY = matrix.GetD();
			scaleY = lround(patternElem->GetHeight().GetAnimVal()*scaleY) / patternElem->GetHeight().GetAnimVal(); 
			patternElem->SetOwnerSVGElement(&svgElem);
			patternElem->SetViewportElement(&svgElem);
			cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
					lround(patternElem->GetWidth().GetAnimVal()*scaleX),
					lround(patternElem->GetHeight().GetAnimVal()*scaleY));
			cairo_t* cr = cairo_create(surface);
			wxSVGMatrix patMatrix;
			patMatrix = patMatrix.ScaleNonUniform(scaleX, scaleY);
			wxCSSStyleDeclaration style;
			DrawMask(cr, patternElem, patMatrix, style, svgElem);
			m_pattern = cairo_pattern_create_for_surface(surface);
			
			if (patternElem->GetX().GetAnimVal() > 0 || patternElem->GetY().GetAnimVal() > 0) {
				patMatrix = patMatrix.Translate(patternElem->GetX().GetAnimVal(), patternElem->GetY().GetAnimVal());
			}
			if (patternElem->GetPatternTransform().GetAnimVal().size()) {
				const wxSVGTransformList& transforms = patternElem->GetPatternTransform().GetAnimVal();
				for (unsigned int i = 0; i < transforms.Count(); i++) {
					patMatrix = patMatrix.Multiply(transforms[i].GetMatrix().Inverse());
				}
			}
			cairo_matrix_t mat;
			cairo_matrix_init(&mat, patMatrix.GetA(), patMatrix.GetB(), patMatrix.GetC(), patMatrix.GetD(), patMatrix.GetE(), patMatrix.GetF());
			cairo_pattern_set_matrix(m_pattern, &mat);
			
			cairo_set_source(m_cr, m_pattern);
			cairo_pattern_set_extend(m_pattern, CAIRO_EXTEND_REPEAT);
			
			cairo_destroy(cr);
			cairo_surface_destroy(surface);
		}
	} else {
		wxRGBColor color = paint.GetRGBColor();
		cairo_set_source_rgba(cr, color.Red() / 255.0, color.Green() / 255.0, color.Blue() / 255.0, opacity);
	}
}