예제 #1
0
파일: SVGMatrix.cpp 프로젝트: KastB/OpenCPN
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;
}
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);
}
예제 #3
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);
}
예제 #5
0
파일: SVGPoint.cpp 프로젝트: KastB/OpenCPN
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;
}
예제 #6
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);
}
예제 #7
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);
	}
}