Ejemplo n.º 1
0
void
Canvas::DrawTwoLines(PixelScalar ax, PixelScalar ay,
                  PixelScalar bx, PixelScalar by,
                  PixelScalar cx, PixelScalar cy)
{
  assert(IsDefined());

#ifndef NOLINETO
  ::MoveToEx(dc, ax, ay, NULL);
  ::LineTo(dc, bx, by);
  ::LineTo(dc, cx, cy);
#else
  RasterPoint p[2];

  p[0].x = ax;
  p[0].y = ay;
  p[1].x = bx;
  p[1].y = by;
  DrawPolyline(p, 2);

  p[0].x = cx;
  p[0].y = cy;
  DrawPolyline(p, 2);
#endif
}
Ejemplo n.º 2
0
//====================================================================
// DebugDrawRangeCircle
//====================================================================
void CAIDebugRenderer::DrawRangeCircle(const Vec3& vPos, float fRadius, float fWidth,
													const ColorB& colorFill, const ColorB& colorOutline, bool bDrawOutline)
{
	const unsigned npts = 24;

	Vec3	points[npts];
	Vec3	pointsOutline[npts];
	Vec3	tris[npts * 2 * 3];

	if (fWidth > fRadius) fWidth = fRadius;

	for (unsigned int i = 0; i < npts; i++)
	{
		float	a = ((float)i / (float)npts) * gf_PI2;
		points[i] = Vec3(cosf(a), sinf(a), 0);
		pointsOutline[i] = vPos + points[i] * fRadius;
	}

	unsigned int n = 0;
	for (unsigned int i = 0; i < npts; i++)
	{
		tris[n++] = vPos + points[i] * (fRadius - fWidth);
		tris[n++] = vPos + points[i] * fRadius;
		tris[n++] = vPos + points[(i+1) % npts] * fRadius;

		tris[n++] = vPos + points[i] * (fRadius - fWidth);
		tris[n++] = vPos + points[(i+1) % npts] * fRadius;
		tris[n++] = vPos + points[(i+1) % npts] * (fRadius - fWidth);
	}

	DrawTriangles(tris, npts * 2 * 3, colorFill);
	if (bDrawOutline)
		DrawPolyline(pointsOutline, npts, true, colorOutline);
}
Ejemplo n.º 3
0
/* {{{ proto bool GmagickDraw::polyline(array coordinates)
	Draws a polyline using the current stroke, stroke width, and fill color or texture, using the specified array of coordinates.
*/
PHP_METHOD(gmagickdraw, polyline)
{
	zval *coordinate_array;
	php_gmagickdraw_object *internd;
	PointInfo *coordinates;
	int num_elements = 0;

	/* Parse parameters given to function */
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &coordinate_array) == FAILURE) {
		return;
	}

	coordinates = get_pointinfo_array(coordinate_array, &num_elements TSRMLS_CC);

	if (coordinates == (PointInfo *)NULL) {
		GMAGICK_THROW_EXCEPTION_WITH_MESSAGE(GMAGICKDRAW_CLASS, "Unable to read coordinate array", 2);
	}

	internd = (php_gmagickdraw_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	DrawPolyline(internd->drawing_wand, num_elements, coordinates);

	efree(coordinates);
	GMAGICK_CHAIN_METHOD;

}
Ejemplo n.º 4
0
//====================================================================
// DebugDrawRange
//====================================================================
void CAIDebugRenderer::DrawRangeBox(const Vec3& vPos, const Vec3& vDir, float fSizeX, float fSizeY, float fWidth,
																		const ColorB& colorFill, const ColorB& colorOutline, bool bDrawOutline)
{
	float	minX = fSizeX - fWidth;
	float	maxX = fSizeX;
	float	minY = fSizeY - fWidth;
	float	maxY = fSizeY;

	if (maxX < 0.001f || maxY < 0.001f ||minX > maxX || minY > maxY)
		return;

	Vec3	points[8];
	Vec3	tris[8 * 3];
	Vec3	norm(vDir.y, -vDir.x, vDir.z);

	points[0] = vPos + norm * -minX + vDir * -minY;
	points[1] = vPos + norm *  minX + vDir * -minY;
	points[2] = vPos + norm *  minX + vDir *  minY;
	points[3] = vPos + norm * -minX + vDir *  minY;

	points[4] = vPos + norm * -maxX + vDir * -maxY;
	points[5] = vPos + norm *  maxX + vDir * -maxY;
	points[6] = vPos + norm *  maxX + vDir *  maxY;
	points[7] = vPos + norm * -maxX + vDir *  maxY;

	unsigned int n = 0;

	tris[n++] = points[0];
	tris[n++] = points[5];
	tris[n++] = points[1];
	tris[n++] = points[0];
	tris[n++] = points[4];
	tris[n++] = points[5];

	tris[n++] = points[1];
	tris[n++] = points[6];
	tris[n++] = points[2];
	tris[n++] = points[1];
	tris[n++] = points[5];
	tris[n++] = points[6];

	tris[n++] = points[2];
	tris[n++] = points[7];
	tris[n++] = points[3];
	tris[n++] = points[2];
	tris[n++] = points[6];
	tris[n++] = points[7];

	tris[n++] = points[3];
	tris[n++] = points[4];
	tris[n++] = points[0];
	tris[n++] = points[3];
	tris[n++] = points[7];
	tris[n++] = points[4];

	DrawTriangles(tris, 8 * 3, colorFill);
	if (bDrawOutline)
		DrawPolyline(&points[4], 4, true, colorOutline);
}
Ejemplo n.º 5
0
static bool HHVM_METHOD(ImagickDraw, polyline,
    const Array& coordinates) {
  auto wand = getDrawingWandResource(Object{this_});
  auto points = toPointInfoArray(coordinates);
  if (points.empty()) {
    IMAGICKDRAW_THROW("Unable to read coordinate array");
  }
  DrawPolyline(wand->getWand(), points.size(), points.data());
  return true;
}
Ejemplo n.º 6
0
//====================================================================
// DebugDrawCircleOutline
//====================================================================
void CAIDebugRenderer::DrawCircleOutline(const Vec3& vPos, float fRadius, const ColorB& color)
{
	Vec3 points[20];

	for (unsigned int i = 0; i < 20; i++)
	{
		float	a = ((float)i / 20.0f) * gf_PI2;
		points[i] = vPos + Vec3(cosf(a) * fRadius, sinf(a) * fRadius, 0);
	}
	DrawPolyline(points, 20, true, color);
}
Ejemplo n.º 7
0
//====================================================================
// DebugDrawWireSphere
//====================================================================
void CAIDebugRenderer::DrawWireSphere(const Vec3& vPos, float fRadius, const ColorB& color)
{
	const unsigned int npts = 32;
	Vec3	xpoints[npts];
	Vec3	ypoints[npts];
	Vec3	zpoints[npts];

	for (unsigned int i = 0; i < npts; i++)
	{
		float	a = ((float)i / (float)npts) * gf_PI2;
		float rx = cosf(a) * fRadius;
		float ry = sinf(a) * fRadius;
		xpoints[i] = vPos + Vec3(rx, ry, 0);
		ypoints[i] = vPos + Vec3(0, rx, ry);
		zpoints[i] = vPos + Vec3(ry, 0, rx);
	}

	DrawPolyline(xpoints, npts, true, color);
	DrawPolyline(ypoints, npts, true, color);
	DrawPolyline(zpoints, npts, true, color);
}
Ejemplo n.º 8
0
//====================================================================
// DebugDrawWireFOVCone
//====================================================================
void CAIDebugRenderer::DrawWireFOVCone(const Vec3& vPos, const Vec3& vDir, float fRadius, float fFOV, const ColorB& color)
{
	const unsigned int npts = 32;
	const unsigned int npts2 = 16;
	Vec3	points[npts];
	Vec3	pointsx[npts2];
	Vec3	pointsy[npts2];

	Matrix33	base;
	base.SetRotationVDir(vDir);

	float coneRadius = sinf(fFOV) * fRadius;
	float coneHeight = cosf(fFOV) * fRadius;

	for (unsigned int i = 0; i < npts; i++)
	{
		float	a = ((float)i / (float)npts) * gf_PI2;
		float rx = cosf(a) * coneRadius;
		float ry = sinf(a) * coneRadius;
		points[i] = vPos + base.TransformVector(Vec3(rx, coneHeight, ry));
	}

	for (unsigned int i = 0; i < npts2; i++)
	{
		float	a = -fFOV + ((float)i / (float)(npts2-1)) * (fFOV*2);
		float rx = sinf(a) * fRadius;
		float ry = cosf(a) * fRadius;
		pointsx[i] = vPos + base.TransformVector(Vec3(rx, ry, 0));
		pointsy[i] = vPos + base.TransformVector(Vec3(0, ry, rx));
	}

	DrawPolyline(points, npts, true, color);
	DrawPolyline(pointsx, npts2, false, color);
	DrawPolyline(pointsy, npts2, false, color);

	DrawLine(points[0], color, vPos, color);
	DrawLine(points[npts/4], color, vPos, color);
	DrawLine(points[npts/2], color, vPos, color);
	DrawLine(points[npts/2+npts/4], color, vPos, color);
}
Ejemplo n.º 9
0
void
Canvas::DrawLine(int ax, int ay, int bx, int by)
{
  assert(IsDefined());

#ifndef NOLINETO
  ::MoveToEx(dc, ax, ay, nullptr);
  ::LineTo(dc, bx, by);
#else
  RasterPoint p[2] = {{ax, ay}, {bx, by}};
  DrawPolyline(p, 2);
#endif
}
Ejemplo n.º 10
0
void
Canvas::line(PixelScalar ax, PixelScalar ay, PixelScalar bx, PixelScalar by)
{
  assert(IsDefined());

#ifndef NOLINETO
  ::MoveToEx(dc, ax, ay, NULL);
  ::LineTo(dc, bx, by);
#else
  RasterPoint p[2] = {{ax, ay}, {bx, by}};
  DrawPolyline(p, 2);
#endif
}
Ejemplo n.º 11
0
void
Canvas::DrawTwoLines(int ax, int ay, int bx, int by, int cx, int cy)
{
  assert(IsDefined());

#ifndef NOLINETO
  ::MoveToEx(dc, ax, ay, nullptr);
  ::LineTo(dc, bx, by);
  ::LineTo(dc, cx, cy);
#else
  RasterPoint p[2];

  p[0].x = ax;
  p[0].y = ay;
  p[1].x = bx;
  p[1].y = by;
  DrawPolyline(p, 2);

  p[0].x = cx;
  p[0].y = cy;
  DrawPolyline(p, 2);
#endif
}
Ejemplo n.º 12
0
//====================================================================
// DebugDrawEllipseOutline
//====================================================================
void CAIDebugRenderer::DrawEllipseOutline(const Vec3& vPos, float fRadiusX, float fRadiusY, float fOrientation, const ColorB& color)
{
	Vec3	points[20];

	float sin_o = sinf( fOrientation );
	float cos_o = cosf( fOrientation );
	for (unsigned int i = 0; i < 20; i++ )
	{
		float angle = ( (float) i / 20.0f ) * gf_PI2;
		float sin_a = sinf( angle );
		float cos_a = cosf( angle );
		float x = ( cos_o * cos_a * fRadiusX ) - ( sin_o * sin_a * fRadiusY );
		float y = ( cos_o * sin_a * fRadiusY ) + ( sin_o * cos_a * fRadiusX );
		points[i] = vPos + Vec3( x, y, 0.0f );
	}

	DrawPolyline( points, 20, true, color );
}
Ejemplo n.º 13
0
//====================================================================
// DebugDrawRangeArc
//====================================================================
void CAIDebugRenderer::DrawRangeArc(const Vec3& vPos, const Vec3& vDir, float fAngle, float fRadius, float fWidth,
																		const ColorB& colorFill, const ColorB& colorOutline, bool bDrawOutline)
{
	const unsigned npts = 12;

	Vec3	points[npts];
	Vec3	pointsOutline[npts];
	Vec3	tris[(npts - 1) * 2 * 3];

	Vec3	forw(vDir.x, vDir.y, 0.0f);
	forw.NormalizeSafe();
	Vec3	right(forw.y, -forw.x, 0);

	if (fWidth > fRadius) fWidth = fRadius;

	for (unsigned int i = 0; i < npts; i++)
	{
		float	a = ((float)i / (float)(npts - 1) - 0.5f) * fAngle;
		points[i] = forw * cosf(a) + right * sinf(a);
		pointsOutline[i] = vPos + points[i] * fRadius;
	}

	unsigned int n = 0;
	for (unsigned int i = 0; i < npts - 1; i++)
	{
		tris[n++] = vPos + points[i] * (fRadius - fWidth);
		tris[n++] = vPos + points[i+1] * fRadius;
		tris[n++] = vPos + points[i] * fRadius;

		tris[n++] = vPos + points[i] * (fRadius - fWidth);
		tris[n++] = vPos + points[i+1] * (fRadius - fWidth);
		tris[n++] = vPos + points[i+1] * fRadius;
	}

	DrawTriangles(tris, n, colorFill);
	if (bDrawOutline)
	{
		DrawPolyline(pointsOutline, npts, false, colorOutline);
		DrawLine(vPos + forw * (fRadius - fWidth/4), colorOutline, vPos + forw * (fRadius + fWidth/4), colorOutline);
	}
}
Ejemplo n.º 14
0
/* 
 * DrawSceneOutline() 
 *	- draws scene outline within main drawing area
 *
 * PARAMETERS
 *	data	- pointer to MyProgram structure
 *
 * RETURNS
 *	nothing
 */
void
DrawSceneOutline(MyProgram *data)
{
   XPoint	points[5];

   points[0].x = DEFAULT_SCENE_BOT_LEFT_X;
   points[0].y = InvertY(DEFAULT_SCENE_BOT_LEFT_Y);

   points[1].x = DEFAULT_SCENE_BOT_LEFT_X;
   points[1].y = InvertY(DEFAULT_SCENE_TOP_RIGHT_Y);

   points[2].x = DEFAULT_SCENE_TOP_RIGHT_X;
   points[2].y = InvertY(DEFAULT_SCENE_TOP_RIGHT_Y);

   points[3].x = DEFAULT_SCENE_TOP_RIGHT_X;
   points[3].y = InvertY(DEFAULT_SCENE_BOT_LEFT_Y);

   points[4].x = DEFAULT_SCENE_BOT_LEFT_X;
   points[4].y = InvertY(DEFAULT_SCENE_BOT_LEFT_Y);

   DrawPolyline( &points[0], 5 );
}
Ejemplo n.º 15
0
//====================================================================
// DebugDrawCapsuleOutline
//====================================================================
void CAIDebugRenderer::DrawCapsuleOutline(const Vec3& vPos0, const Vec3& vPos1, float fRadius, const ColorB& color)
{
	Vec3 points[20];
	Vec3 axisy = vPos1 - vPos0;
	axisy.Normalize();
	Vec3 axisx(axisy.y, -axisy.x, 0);
	axisx.Normalize();

	for (unsigned int i = 0; i < 10; i++)
	{
		float	a = ((float)i / 9.0f) * gf_PI;
		points[i] = vPos1 + axisx*cosf(a)*fRadius + axisy*sinf(a)*fRadius;
	}

	for (unsigned int i = 0; i < 10; i++)
	{
		float	a = gf_PI + ((float)i / 9.0f) * gf_PI;
		points[i+10] = vPos0 + axisx*cosf(a)*fRadius + axisy*sinf(a)*fRadius;
	}

	DrawPolyline(points, 20, true, color);
}
Ejemplo n.º 16
0
MAGICK_NET_EXPORT void DrawingWand_Polyline(DrawingWand *instance, const PointInfo *coordinates, const size_t length, ExceptionInfo **exception)
{
  DrawPolyline(instance, length, coordinates);
  MAGICK_NET_SET_DRAW_EXCEPTION;
}
Ejemplo n.º 17
0
void Draw::DrawPolyline(const Vector<Point>& vertices,
                        int width, Color color, Color doxor)
{
	DrawPolyline(vertices.Begin(), vertices.GetCount(), width, color, doxor);
}
Ejemplo n.º 18
0
void draw_object(Canvas *canvas, Quark *q)
{
    VPoint anchor;
    DObject *o = object_get_data(q);

    if (o == NULL) {
        return;
    }

    if (Apoint2Vpoint(q, &o->ap, &anchor) != RETURN_SUCCESS) {
        return;
    }
    anchor.x += o->offset.x;
    anchor.y += o->offset.y;

    setclipping(canvas, FALSE);

    activate_bbox(canvas, BBOX_TYPE_TEMP, TRUE);
    reset_bbox(canvas, BBOX_TYPE_TEMP);

    switch (o->type) {
    case DO_LINE:
    {
        DOLineData *l = (DOLineData *) o->odata;

        VPoint vp1;
        double x, y, co, si;

        x = l->vector.x;
        y = l->vector.y;

        co = cos(M_PI/180.0*o->angle);
        si = sin(M_PI/180.0*o->angle);

        vp1.x = anchor.x + x*co - y*si;
        vp1.y = anchor.y + x*si + y*co;

        setline(canvas, &o->line);
        DrawLine(canvas, &anchor, &vp1);

        switch (l->arrow_end) {
        case ARROW_AT_NONE:
            break;
        case ARROW_AT_BEGINNING:
            draw_arrowhead(canvas, &vp1, &anchor, &l->arrow,
                           &o->line.pen, &o->fillpen);
            break;
        case ARROW_AT_END:
            draw_arrowhead(canvas, &anchor, &vp1, &l->arrow,
                           &o->line.pen, &o->fillpen);
            break;
        case ARROW_AT_BOTH:
            draw_arrowhead(canvas, &vp1, &anchor, &l->arrow,
                           &o->line.pen, &o->fillpen);
            draw_arrowhead(canvas, &anchor, &vp1, &l->arrow,
                           &o->line.pen, &o->fillpen);
            break;
        }
    }
    break;
    case DO_BOX:
    {
        DOBoxData *b = (DOBoxData *) o->odata;
        if (o->angle == 0.0) {
            VPoint vp1, vp2;

            vp1.x = anchor.x - b->width/2;
            vp2.x = anchor.x + b->width/2;
            vp1.y = anchor.y - b->height/2;
            vp2.y = anchor.y + b->height/2;

            setpen(canvas, &o->fillpen);
            DrawFilledRect(canvas, &vp1, &vp2);

            setline(canvas, &o->line);
            DrawRect(canvas, &vp1, &vp2);
        } else {
            VPoint vps[4];
            double x, y, co, si;

            x = b->width/2;
            y = b->height/2;

            co = cos(M_PI/180.0*o->angle);
            si = sin(M_PI/180.0*o->angle);

            vps[0].x = anchor.x + x*co - y*si;
            vps[0].y = anchor.y + x*si + y*co;
            vps[1].x = anchor.x - x*co - y*si;
            vps[1].y = anchor.y - x*si + y*co;
            vps[2].x = anchor.x - x*co + y*si;
            vps[2].y = anchor.y - x*si - y*co;
            vps[3].x = anchor.x + x*co + y*si;
            vps[3].y = anchor.y + x*si - y*co;

            setpen(canvas, &o->fillpen);
            DrawPolygon(canvas, vps, 4);

            setline(canvas, &o->line);
            DrawPolyline(canvas, vps, 4, POLYLINE_CLOSED);
        }
    }
    break;
    case DO_ARC:
    {
        VPoint vp1, vp2;
        DOArcData *e = (DOArcData *) o->odata;

        vp1.x = anchor.x - e->width/2;
        vp2.x = anchor.x + e->width/2;
        vp1.y = anchor.y - e->height/2;
        vp2.y = anchor.y + e->height/2;

        setpen(canvas, &o->fillpen);
        /* FIXME: implement true ellipse rotation! */
        DrawFilledArc(canvas, &vp1, &vp2, e->angle1 + o->angle, e->angle2,
                      e->closure_type);

        setline(canvas, &o->line);
        DrawArc(canvas, &vp1, &vp2, e->angle1 + o->angle, e->angle2,
                e->closure_type, e->draw_closure);
    }
    break;
    case DO_NONE:
        break;
    }

    get_bbox(canvas, BBOX_TYPE_TEMP, &o->bb);
}
Ejemplo n.º 19
0
//====================================================================
// DebugDrawRangePolygon
//====================================================================
void CAIDebugRenderer::DrawRangePolygon(const Vec3 polygon[], int nVertices, float fWidth,
													 const ColorB& colorFill, const ColorB& colorOutline, bool bDrawOutline)
{
	static std::vector<Vec3>		verts;
	static std::vector<vtx_idx>	tris;
	static std::vector<Vec3>		outline;

	if (nVertices < 3) return;

	Vec3	prevDir(polygon[0] - polygon[nVertices - 1]);
	prevDir.NormalizeSafe();
	Vec3	prevNorm(-prevDir.y, prevDir.x, 0.0f);
	prevNorm.NormalizeSafe();
	Vec3	prevPos(polygon[nVertices - 1]);

	verts.clear();
	outline.clear();

	const Vec3* li, * linext;
	const Vec3* liend = polygon + nVertices;
	for (li = polygon; li != liend ; ++li)
	{
		linext = li;
		++linext;
		if (linext == liend)
			linext = polygon;

		const Vec3&	curPos(*li);
		const Vec3&	nextPos(*linext);
		Vec3	vDir(nextPos - curPos);
		Vec3	norm(-vDir.y, vDir.x, 0.0f);
		norm.NormalizeSafe();

		Vec3	mid((prevNorm + norm) * 0.5f);
		float	dmr2 = sqr(mid.x) + sqr(mid.y);
		if (dmr2 > 0.00001f)
			mid *= 1.0f / dmr2;

		float	cross = prevDir.x * vDir.y - vDir.x * prevDir.y;

		outline.push_back(curPos);

		if (cross < 0.0f)
		{
			if (dmr2 * sqr(2.5f) < 1.0f)
			{
				// bevel
				verts.push_back(curPos);
				verts.push_back(curPos + prevNorm * fWidth);
				verts.push_back(curPos);
				verts.push_back(curPos + norm * fWidth);
			}
			else
			{
				verts.push_back(curPos);
				verts.push_back(curPos + mid * fWidth);
			}
		}
		else
		{
			verts.push_back(curPos);
			verts.push_back(curPos + mid * fWidth);
		}

		prevDir = vDir;
		prevNorm = norm;
		prevPos = curPos;
	}

	tris.clear();
	size_t	n = verts.size()/2;
	for (size_t i = 0; i < n; ++i)
	{
		size_t	j = (i + 1) % n;
		tris.push_back(i*2);
		tris.push_back(j*2);
		tris.push_back(j*2+1);

		tris.push_back(i*2);
		tris.push_back(j*2+1);
		tris.push_back(i*2+1);
	}

	m_pRenderer->GetIRenderAuxGeom()->DrawTriangles(&verts[0], verts.size(), &tris[0], tris.size(), colorFill);
	if (bDrawOutline)
		DrawPolyline(&outline[0], outline.size(), true, colorOutline);
}
Ejemplo n.º 20
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;
  }
}