]>
git.saurik.com Git - wxWidgets.git/blob - src/common/dcsvg.cpp
7397e437250f2dc4014688bd655594c06d5906ad
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Chris Elliott
7 // Licence: wxWindows license
8 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
21 #include "wx/dcmemory.h"
22 #include "wx/dcscreen.h"
28 #include "wx/wfstream.h"
29 #include "wx/filename.h"
31 #define wxSVG_DEBUG false
32 // or true to see the calls being executed
34 #define newline wxString(wxT("\n"))
35 #define space wxString(wxT(" "))
36 #define semicolon wxString(wxT(";"))
37 #define wx_round(a) (int)((a)+.5)
40 // ----------------------------------------------------------
42 // ----------------------------------------------------------
44 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
46 wxString
wxColStr ( wxColour c
)
48 unsigned char r
, g
, b
;
53 // possible Unicode bug here
54 wxString s
= wxDecToHex(r
) + wxDecToHex(g
) + wxDecToHex(b
);
59 wxString
wxBrushString ( wxColour c
, int style
)
61 wxString s
= wxT("fill:#") + wxColStr (c
) + semicolon
+ space
;
64 case wxBRUSHSTYLE_SOLID
:
65 s
= s
+ wxT("fill-opacity:1.0; ");
67 case wxBRUSHSTYLE_TRANSPARENT
:
68 s
= s
+ wxT("fill-opacity:0.0; ");
72 wxASSERT_MSG(false, wxT("wxSVGFileDC::Requested Brush Style not available"));
79 // ----------------------------------------------------------
81 // ----------------------------------------------------------
83 IMPLEMENT_ABSTRACT_CLASS(wxSVGFileDCImpl
, wxDC
)
85 wxSVGFileDCImpl::wxSVGFileDCImpl( wxSVGFileDC
*owner
, const wxString
&filename
,
86 int width
, int height
, double dpi
) :
89 Init( filename
, width
, height
, dpi
);
92 void wxSVGFileDCImpl::Init (const wxString
&filename
, int Width
, int Height
, double dpi
)
101 m_mm_to_pix_x
= dpi
/25.4;
102 m_mm_to_pix_y
= dpi
/25.4;
104 m_backgroundBrush
= *wxTRANSPARENT_BRUSH
;
105 m_textForegroundColour
= *wxBLACK
;
106 m_textBackgroundColour
= *wxWHITE
;
107 m_colour
= wxColourDisplay();
109 m_pen
= *wxBLACK_PEN
;
110 m_font
= *wxNORMAL_FONT
;
111 m_brush
= *wxWHITE_BRUSH
;
113 m_graphics_changed
= true;
115 ////////////////////code here
117 m_outfile
= new wxFileOutputStream(filename
);
118 m_OK
= m_outfile
->Ok ();
121 m_filename
= filename
;
124 s
= wxT("<?xml version=\"1.0\" standalone=\"no\"?>"); s
= s
+ newline
;
126 s
= wxT("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" ") + newline
;
128 s
= wxT("\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"> ") + newline
;
130 s
= wxT("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" ") + newline
;
132 s
.Printf( wxT(" width=\"%.2gcm\" height=\"%.2gcm\" viewBox=\"0 0 %d %d \"> \n"), float(Width
)/dpi
*2.54, float(Height
)/dpi
*2.54, Width
, Height
);
134 s
= wxT("<title>SVG Picture created as ") + wxFileName(filename
).GetFullName() + wxT(" </title>") + newline
;
136 s
= wxString (wxT("<desc>Picture generated by wxSVG ")) + wxSVGVersion
+ wxT(" </desc>")+ newline
;
138 s
= wxT("<g style=\"fill:black; stroke:black; stroke-width:1\">") + newline
;
143 wxSVGFileDCImpl::~wxSVGFileDCImpl()
145 wxString s
= wxT("</g> \n</svg> \n");
150 void wxSVGFileDCImpl::DoGetSizeMM( int *width
, int *height
) const
153 *width
= wxRound( (double)m_width
/ m_mm_to_pix_x
);
156 *height
= wxRound( (double)m_height
/ m_mm_to_pix_y
);
159 wxSize
wxSVGFileDCImpl::GetPPI() const
161 return wxSize( wxRound(m_dpi
), wxRound(m_dpi
) );
164 void wxSVGFileDCImpl::DoDrawLine (wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
166 if (m_graphics_changed
) NewGraphics ();
168 s
.Printf ( wxT("<path d=\"M%d %d L%d %d\" /> \n"), x1
,y1
,x2
,y2
);
173 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawLine Call executed"));
174 CalcBoundingBox(x1
, y1
);
175 CalcBoundingBox(x2
, y2
);
179 void wxSVGFileDCImpl::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
181 for ( int i
= 1; i
< n
; i
++ )
183 DoDrawLine ( points
[i
-1].x
+ xoffset
, points
[i
-1].y
+ yoffset
,
184 points
[ i
].x
+ xoffset
, points
[ i
].y
+ yoffset
);
188 void wxSVGFileDCImpl::DoDrawPoint (wxCoord x1
, wxCoord y1
)
191 if (m_graphics_changed
) NewGraphics ();
192 s
= wxT("<g style = \"stroke-linecap:round;\" > ") + newline
;
194 DoDrawLine ( x1
,y1
,x1
,y1
);
199 void wxSVGFileDCImpl::DoDrawCheckMark(wxCoord x1
, wxCoord y1
, wxCoord width
, wxCoord height
)
201 wxDCImpl::DoDrawCheckMark (x1
,y1
,width
,height
);
204 void wxSVGFileDCImpl::DoDrawText(const wxString
& text
, wxCoord x1
, wxCoord y1
)
206 DoDrawRotatedText(text
, x1
,y1
,0.0);
207 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawText Call executed"));
210 void wxSVGFileDCImpl::DoDrawRotatedText(const wxString
& sText
, wxCoord x
, wxCoord y
, double angle
)
212 //known bug; if the font is drawn in a scaled DC, it will not behave exactly as wxMSW
213 if (m_graphics_changed
) NewGraphics ();
216 // calculate bounding box
218 DoGetTextExtent(sText
, &w
, &h
, &desc
);
220 double rad
= DegToRad(angle
);
222 // wxT("upper left") and wxT("upper right")
223 CalcBoundingBox(x
, y
);
224 CalcBoundingBox((wxCoord
)(x
+ w
*cos(rad
)), (wxCoord
)(y
- h
*sin(rad
)));
226 // wxT("bottom left") and wxT("bottom right")
227 x
+= (wxCoord
)(h
*sin(rad
));
228 y
+= (wxCoord
)(h
*cos(rad
));
229 CalcBoundingBox(x
, y
);
230 CalcBoundingBox((wxCoord
)(x
+ h
*sin(rad
)), (wxCoord
)(y
+ h
*cos(rad
)));
232 if (m_backgroundMode
== wxBRUSHSTYLE_SOLID
)
234 // draw background first
235 // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background
237 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background"));
238 sTmp
.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x
,y
+desc
-h
, w
, h
);
239 s
= sTmp
+ wxT("style=\"fill:#") + wxColStr (m_textBackgroundColour
) + wxT("; ");
240 s
= s
+ wxT("stroke-width:1; stroke:#") + wxColStr (m_textBackgroundColour
) + wxT("; ");
241 sTmp
.Printf ( wxT("\" transform=\"rotate( %.2g %d %d ) \">"), -angle
, x
,y
);
242 s
= s
+ sTmp
+ newline
;
245 //now do the text itself
246 s
.Printf (wxT(" <text x=\"%d\" y=\"%d\" "),x
,y
);
248 sTmp
= m_font
.GetFaceName ();
249 if (sTmp
.Len () > 0) s
= s
+ wxT("style=\"font-family:") + sTmp
+ wxT("; ");
250 else s
= s
+ wxT("style=\" ");
252 wxString fontweights
[3] = { wxT("normal"), wxT("lighter"), wxT("bold") };
253 s
= s
+ wxT("font-weight:") + fontweights
[m_font
.GetWeight() - wxNORMAL
] + semicolon
+ space
;
255 wxString fontstyles
[5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };
256 s
= s
+ wxT("font-style:") + fontstyles
[m_font
.GetStyle() - wxNORMAL
] + semicolon
+ space
;
258 sTmp
.Printf (wxT("font-size:%dpt; fill:#"), m_font
.GetPointSize () );
260 s
= s
+ wxColStr (m_textForegroundColour
) + wxT("; stroke:#") + wxColStr (m_textForegroundColour
) + wxT("; ");
261 sTmp
.Printf ( wxT("stroke-width:0;\" transform=\"rotate( %.2g %d %d ) \" >"), -angle
, x
,y
);
262 s
= s
+ sTmp
+ sText
+ wxT("</text> ") + newline
;
267 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawRotatedText Call executed"));
270 void wxSVGFileDCImpl::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
272 DoDrawRoundedRectangle(x
, y
, width
, height
, 0);
275 void wxSVGFileDCImpl::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
278 if (m_graphics_changed
) NewGraphics ();
281 s
.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" rx=\"%.2g\" "),
282 x
, y
, width
, height
, radius
);
284 s
= s
+ wxT(" /> ") + newline
;
287 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawRoundedRectangle Call executed"));
288 CalcBoundingBox(x
, y
);
289 CalcBoundingBox(x
+ width
, y
+ height
);
292 void wxSVGFileDCImpl::DoDrawPolygon(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
,int fillStyle
)
294 if (m_graphics_changed
) NewGraphics ();
296 s
= wxT("<polygon style=\"");
297 if ( fillStyle
== wxODDEVEN_RULE
)
298 s
= s
+ wxT("fill-rule:evenodd; ");
300 s
= s
+ wxT("fill-rule:nonzero; ");
302 s
= s
+ wxT("\" \npoints=\"");
304 for (int i
= 0; i
< n
; i
++)
306 sTmp
.Printf ( wxT("%d,%d"), points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
307 s
= s
+ sTmp
+ newline
;
308 CalcBoundingBox ( points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
310 s
= s
+ wxT("\" /> ");
314 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawPolygon Call executed"));
317 void wxSVGFileDCImpl::DoDrawEllipse (wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
320 if (m_graphics_changed
) NewGraphics ();
326 s
.Printf ( wxT("<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" "), x
+rw
,y
+rh
, rw
, rh
);
327 s
= s
+ wxT(" /> ") + newline
;
331 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipse Call executed"));
332 CalcBoundingBox(x
, y
);
333 CalcBoundingBox(x
+ width
, y
+ height
);
336 void wxSVGFileDCImpl::DoDrawArc(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
338 /* Draws an arc of a circle, centred on (xc, yc), with starting point
339 (x1, y1) and ending at (x2, y2). The current pen is used for the outline
340 and the current brush for filling the shape.
342 The arc is drawn in an anticlockwise direction from the start point to
345 Might be better described as Pie drawing */
347 if (m_graphics_changed
) NewGraphics ();
350 // we need the radius of the circle which has two estimates
351 double r1
= sqrt ( double( (x1
-xc
)*(x1
-xc
) ) + double( (y1
-yc
)*(y1
-yc
) ) );
352 double r2
= sqrt ( double( (x2
-xc
)*(x2
-xc
) ) + double( (y2
-yc
)*(y2
-yc
) ) );
354 wxASSERT_MSG( (fabs ( r2
-r1
) <= 3), wxT("wxSVGFileDC::DoDrawArc Error in getting radii of circle"));
355 if ( fabs ( r2
-r1
) > 3 ) //pixels
357 s
= wxT("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle --> \n");
361 double theta1
= atan2((double)(yc
-y1
),(double)(x1
-xc
));
362 if ( theta1
< 0 ) theta1
= theta1
+ M_PI
* 2;
363 double theta2
= atan2((double)(yc
-y2
), (double)(x2
-xc
));
364 if ( theta2
< 0 ) theta2
= theta2
+ M_PI
* 2;
365 if ( theta2
< theta1
) theta2
= theta2
+ M_PI
*2;
367 int fArc
; // flag for large or small arc 0 means less than 180 degrees
368 if ( fabs(theta2
- theta1
) > M_PI
) fArc
= 1; else fArc
= 0;
370 int fSweep
= 0; // flag for sweep always 0
372 s
.Printf ( wxT("<path d=\"M%d %d A%.2g %.2g 0.0 %d %d %d %d L%d %d z "),
373 x1
,y1
, r1
, r2
, fArc
, fSweep
, x2
, y2
, xc
, yc
);
375 // the z means close the path and fill
376 s
= s
+ wxT(" \" /> ") + newline
;
384 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawArc Call executed"));
387 void wxSVGFileDCImpl::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
)
390 Draws an arc of an ellipse. The current pen is used for drawing the arc
391 and the current brush is used for drawing the pie. This function is
392 currently only available for X window and PostScript device contexts.
394 x and y specify the x and y coordinates of the upper-left corner of the
395 rectangle that contains the ellipse.
397 width and height specify the width and height of the rectangle that
398 contains the ellipse.
400 start and end specify the start and end of the arc relative to the
401 three-o'clock position from the center of the rectangle. Angles are
402 specified in degrees (360 is a complete circle). Positive values mean
403 counter-clockwise motion. If start is equal to end, a complete ellipse
406 //known bug: SVG draws with the current pen along the radii, but this does not happen in wxMSW
408 if (m_graphics_changed
) NewGraphics ();
418 double xs
, ys
, xe
, ye
;
419 xs
= xc
+ rx
* cos (DegToRad(sa
));
420 xe
= xc
+ rx
* cos (DegToRad(ea
));
421 ys
= yc
- ry
* sin (DegToRad(sa
));
422 ye
= yc
- ry
* sin (DegToRad(ea
));
424 ///now same as circle arc...
426 double theta1
= atan2(ys
-yc
, xs
-xc
);
427 double theta2
= atan2(ye
-yc
, xe
-xc
);
429 int fArc
; // flag for large or small arc 0 means less than 180 degrees
430 if ( (theta2
- theta1
) > 0 ) fArc
= 1; else fArc
= 0;
433 if ( fabs(theta2
- theta1
) > M_PI
) fSweep
= 1; else fSweep
= 0;
435 s
.Printf ( wxT("<path d=\"M%d %d A%d %d 0.0 %d %d %d %d L %d %d z "),
436 int(xs
), int(ys
), int(rx
), int(ry
),
437 fArc
, fSweep
, int(xe
), int(ye
), int(xc
), int(yc
) );
440 s
= s
+ wxT(" \" /> ") + newline
;
447 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipticArc Call executed"));
450 void wxSVGFileDCImpl::DoGetTextExtent(const wxString
& string
, wxCoord
*w
, wxCoord
*h
, wxCoord
*descent
, wxCoord
*externalLeading
, const wxFont
*font
) const
455 sDC
.SetFont (m_font
);
456 if ( font
!= NULL
) sDC
.SetFont ( *font
);
457 sDC
.GetTextExtent(string
, w
, h
, descent
, externalLeading
);
458 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetTextExtent Call executed"));
461 wxCoord
wxSVGFileDCImpl::GetCharHeight() const
465 sDC
.SetFont (m_font
);
467 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharHeight Call executing"));
468 return ( sDC
.GetCharHeight() );
472 wxCoord
wxSVGFileDCImpl::GetCharWidth() const
475 sDC
.SetFont (m_font
);
477 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharWidth Call executing"));
478 return ( sDC
.GetCharWidth() );
483 // ----------------------------------------------------------
484 // wxSVGFileDCImpl - set functions
485 // ----------------------------------------------------------
487 void wxSVGFileDCImpl::SetBackground( const wxBrush
&brush
)
490 m_backgroundBrush
= brush
;
495 void wxSVGFileDCImpl::SetBackgroundMode( int mode
)
497 m_backgroundMode
= mode
;
502 void wxSVGFileDCImpl::SetBrush(const wxBrush
& brush
)
507 m_graphics_changed
= true;
508 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetBrush Call executed"));
512 void wxSVGFileDCImpl::SetPen(const wxPen
& pen
)
514 // width, color, ends, joins : currently implemented
515 // dashes, stipple : not implemented
518 m_graphics_changed
= true;
519 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetPen Call executed"));
522 void wxSVGFileDCImpl::NewGraphics ()
525 int w
= m_pen
.GetWidth ();
526 wxColour c
= m_pen
.GetColour ();
528 wxString s
, sBrush
, sPenCap
, sPenJoin
, sPenStyle
, sLast
, sWarn
;
530 sBrush
= wxT("</g>\n<g style=\"") + wxBrushString ( m_brush
.GetColour (), m_brush
.GetStyle () )
531 + wxT(" stroke:#") + wxColStr (c
) + wxT("; ");
533 switch ( m_pen
.GetCap () )
535 case wxCAP_PROJECTING
:
536 sPenCap
= wxT("stroke-linecap:square; ");
539 sPenCap
= wxT("stroke-linecap:butt; ");
543 sPenCap
= wxT("stroke-linecap:round; ");
545 switch ( m_pen
.GetJoin () )
548 sPenJoin
= wxT("stroke-linejoin:bevel; ");
551 sPenJoin
= wxT("stroke-linejoin:miter; ");
555 sPenJoin
= wxT("stroke-linejoin:round; ");
558 switch ( m_pen
.GetStyle () )
560 case wxPENSTYLE_SOLID
:
561 sPenStyle
= wxT("stroke-opacity:1.0; stroke-opacity:1.0; ");
563 case wxPENSTYLE_TRANSPARENT
:
564 sPenStyle
= wxT("stroke-opacity:0.0; stroke-opacity:0.0; ");
567 wxASSERT_MSG(false, wxT("wxSVGFileDC::SetPen Call called to set a Style which is not available"));
568 sWarn
= sWarn
+ wxT("<!--- wxSVGFileDC::SetPen Call called to set a Style which is not available --> \n");
571 sLast
.Printf( wxT("stroke-width:%d\" \n transform=\"translate(%.2g %.2g) scale(%.2g %.2g)\">"),
572 w
, double(m_logicalOriginX
), double(m_logicalOriginY
), m_scaleX
, m_scaleY
);
574 s
= sBrush
+ sPenCap
+ sPenJoin
+ sPenStyle
+ sLast
+ newline
+ sWarn
;
576 m_graphics_changed
= false;
577 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::NewGraphics Call executed"));
581 void wxSVGFileDCImpl::SetFont(const wxFont
& font
)
586 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetFont Call executed"));
589 // export a bitmap as a raster image in png
590 bool wxSVGFileDCImpl::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
591 wxDC
* source
, wxCoord xsrc
, wxCoord ysrc
,
592 int logicalFunc
/*= wxCOPY*/, bool useMask
/*= false*/,
593 wxCoord
/*xsrcMask = -1*/, wxCoord
/*ysrcMask = -1*/)
595 if (logicalFunc
!= wxCOPY
)
597 wxASSERT_MSG(false, wxT("wxSVGFileDC::DoBlit Call requested nonCopy mode; this is not possible"));
600 if (useMask
!= false)
602 wxASSERT_MSG(false, wxT("wxSVGFileDC::DoBlit Call requested false mask; this is not possible"));
605 wxBitmap
myBitmap (width
, height
);
607 memDC
.SelectObject( myBitmap
);
608 memDC
.Blit(0, 0, width
, height
, source
, xsrc
, ysrc
);
609 memDC
.SelectObject( wxNullBitmap
);
610 DoDrawBitmap(myBitmap
, xdest
, ydest
);
611 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoBlit Call executed"));
615 void wxSVGFileDCImpl::DoDrawIcon(const class wxIcon
& myIcon
, wxCoord x
, wxCoord y
)
617 wxBitmap
myBitmap (myIcon
.GetWidth(), myIcon
.GetHeight() );
619 memDC
.SelectObject( myBitmap
);
620 memDC
.DrawIcon(myIcon
,0,0);
621 memDC
.SelectObject( wxNullBitmap
);
622 DoDrawBitmap(myBitmap
, x
, y
);
623 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawIcon Call executed"));
627 void wxSVGFileDCImpl::DoDrawBitmap(const class wxBitmap
& bmp
, wxCoord x
, wxCoord y
, bool WXUNUSED(bTransparent
) /*=0*/ )
629 if (m_graphics_changed
) NewGraphics ();
631 wxString sTmp
, s
, sPNG
;
632 if ( wxImage::FindHandler(wxBITMAP_TYPE_PNG
) == NULL
)
633 wxImage::AddHandler(new wxPNGHandler
);
635 // create suitable file name
636 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
637 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
638 while (wxFile::Exists(sPNG
) )
641 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
642 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
645 //create copy of bitmap (wxGTK doesn't like saving a constant bitmap)
646 wxBitmap myBitmap
= bmp
;
648 bool bPNG_OK
= myBitmap
.SaveFile(sPNG
,wxBITMAP_TYPE_PNG
);
650 // reference the bitmap from the SVG doc
651 // only use filename & ext
652 sPNG
= sPNG
.AfterLast(wxFileName::GetPathSeparator());
654 // reference the bitmap from the SVG doc
655 int w
= myBitmap
.GetWidth();
656 int h
= myBitmap
.GetHeight();
657 sTmp
.Printf ( wxT(" <image x=\"%d\" y=\"%d\" width=\"%dpx\" height=\"%dpx\" "), x
,y
,w
,h
);
659 sTmp
.Printf ( wxT(" xlink:href=\"%s\"> \n"), sPNG
.c_str() );
660 s
= s
+ sTmp
+ wxT("<title>Image from wxSVG</title> </image>") + newline
;
666 m_OK
= m_outfile
->Ok () && bPNG_OK
;
667 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawBitmap Call executed"));
672 void wxSVGFileDCImpl::write(const wxString
&s
)
674 const wxCharBuffer buf
= s
.utf8_str();
675 m_outfile
->Write(buf
, strlen((const char *)buf
));
676 m_OK
= m_outfile
->Ok();