1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Chris Elliott
7 // Licence: wxWindows licence
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
[],
293 wxCoord xoffset
, wxCoord yoffset
,
294 wxPolygonFillMode fillStyle
)
296 if (m_graphics_changed
) NewGraphics ();
298 s
= wxT("<polygon style=\"");
299 if ( fillStyle
== wxODDEVEN_RULE
)
300 s
= s
+ wxT("fill-rule:evenodd; ");
302 s
= s
+ wxT("fill-rule:nonzero; ");
304 s
= s
+ wxT("\" \npoints=\"");
306 for (int i
= 0; i
< n
; i
++)
308 sTmp
.Printf ( wxT("%d,%d"), points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
309 s
= s
+ sTmp
+ newline
;
310 CalcBoundingBox ( points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
312 s
= s
+ wxT("\" /> ");
316 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawPolygon Call executed"));
319 void wxSVGFileDCImpl::DoDrawEllipse (wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
322 if (m_graphics_changed
) NewGraphics ();
328 s
.Printf ( wxT("<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" "), x
+rw
,y
+rh
, rw
, rh
);
329 s
= s
+ wxT(" /> ") + newline
;
333 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipse Call executed"));
334 CalcBoundingBox(x
, y
);
335 CalcBoundingBox(x
+ width
, y
+ height
);
338 void wxSVGFileDCImpl::DoDrawArc(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
340 /* Draws an arc of a circle, centred on (xc, yc), with starting point
341 (x1, y1) and ending at (x2, y2). The current pen is used for the outline
342 and the current brush for filling the shape.
344 The arc is drawn in an anticlockwise direction from the start point to
347 Might be better described as Pie drawing */
349 if (m_graphics_changed
) NewGraphics ();
352 // we need the radius of the circle which has two estimates
353 double r1
= sqrt ( double( (x1
-xc
)*(x1
-xc
) ) + double( (y1
-yc
)*(y1
-yc
) ) );
354 double r2
= sqrt ( double( (x2
-xc
)*(x2
-xc
) ) + double( (y2
-yc
)*(y2
-yc
) ) );
356 wxASSERT_MSG( (fabs ( r2
-r1
) <= 3), wxT("wxSVGFileDC::DoDrawArc Error in getting radii of circle"));
357 if ( fabs ( r2
-r1
) > 3 ) //pixels
359 s
= wxT("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle --> \n");
363 double theta1
= atan2((double)(yc
-y1
),(double)(x1
-xc
));
364 if ( theta1
< 0 ) theta1
= theta1
+ M_PI
* 2;
365 double theta2
= atan2((double)(yc
-y2
), (double)(x2
-xc
));
366 if ( theta2
< 0 ) theta2
= theta2
+ M_PI
* 2;
367 if ( theta2
< theta1
) theta2
= theta2
+ M_PI
*2;
369 int fArc
; // flag for large or small arc 0 means less than 180 degrees
370 if ( fabs(theta2
- theta1
) > M_PI
) fArc
= 1; else fArc
= 0;
372 int fSweep
= 0; // flag for sweep always 0
374 s
.Printf ( wxT("<path d=\"M%d %d A%.2g %.2g 0.0 %d %d %d %d L%d %d z "),
375 x1
,y1
, r1
, r2
, fArc
, fSweep
, x2
, y2
, xc
, yc
);
377 // the z means close the path and fill
378 s
= s
+ wxT(" \" /> ") + newline
;
386 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawArc Call executed"));
389 void wxSVGFileDCImpl::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
)
392 Draws an arc of an ellipse. The current pen is used for drawing the arc
393 and the current brush is used for drawing the pie. This function is
394 currently only available for X window and PostScript device contexts.
396 x and y specify the x and y coordinates of the upper-left corner of the
397 rectangle that contains the ellipse.
399 width and height specify the width and height of the rectangle that
400 contains the ellipse.
402 start and end specify the start and end of the arc relative to the
403 three-o'clock position from the center of the rectangle. Angles are
404 specified in degrees (360 is a complete circle). Positive values mean
405 counter-clockwise motion. If start is equal to end, a complete ellipse
408 //known bug: SVG draws with the current pen along the radii, but this does not happen in wxMSW
410 if (m_graphics_changed
) NewGraphics ();
420 double xs
, ys
, xe
, ye
;
421 xs
= xc
+ rx
* cos (DegToRad(sa
));
422 xe
= xc
+ rx
* cos (DegToRad(ea
));
423 ys
= yc
- ry
* sin (DegToRad(sa
));
424 ye
= yc
- ry
* sin (DegToRad(ea
));
426 ///now same as circle arc...
428 double theta1
= atan2(ys
-yc
, xs
-xc
);
429 double theta2
= atan2(ye
-yc
, xe
-xc
);
431 int fArc
; // flag for large or small arc 0 means less than 180 degrees
432 if ( (theta2
- theta1
) > 0 ) fArc
= 1; else fArc
= 0;
435 if ( fabs(theta2
- theta1
) > M_PI
) fSweep
= 1; else fSweep
= 0;
437 s
.Printf ( wxT("<path d=\"M%d %d A%d %d 0.0 %d %d %d %d L %d %d z "),
438 int(xs
), int(ys
), int(rx
), int(ry
),
439 fArc
, fSweep
, int(xe
), int(ye
), int(xc
), int(yc
) );
442 s
= s
+ wxT(" \" /> ") + newline
;
449 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipticArc Call executed"));
452 void wxSVGFileDCImpl::DoGetTextExtent(const wxString
& string
, wxCoord
*w
, wxCoord
*h
, wxCoord
*descent
, wxCoord
*externalLeading
, const wxFont
*font
) const
457 sDC
.SetFont (m_font
);
458 if ( font
!= NULL
) sDC
.SetFont ( *font
);
459 sDC
.GetTextExtent(string
, w
, h
, descent
, externalLeading
);
460 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetTextExtent Call executed"));
463 wxCoord
wxSVGFileDCImpl::GetCharHeight() const
467 sDC
.SetFont (m_font
);
469 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharHeight Call executing"));
470 return ( sDC
.GetCharHeight() );
474 wxCoord
wxSVGFileDCImpl::GetCharWidth() const
477 sDC
.SetFont (m_font
);
479 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharWidth Call executing"));
480 return ( sDC
.GetCharWidth() );
485 // ----------------------------------------------------------
486 // wxSVGFileDCImpl - set functions
487 // ----------------------------------------------------------
489 void wxSVGFileDCImpl::SetBackground( const wxBrush
&brush
)
492 m_backgroundBrush
= brush
;
497 void wxSVGFileDCImpl::SetBackgroundMode( int mode
)
499 m_backgroundMode
= mode
;
504 void wxSVGFileDCImpl::SetBrush(const wxBrush
& brush
)
509 m_graphics_changed
= true;
510 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetBrush Call executed"));
514 void wxSVGFileDCImpl::SetPen(const wxPen
& pen
)
516 // width, color, ends, joins : currently implemented
517 // dashes, stipple : not implemented
520 m_graphics_changed
= true;
521 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetPen Call executed"));
524 void wxSVGFileDCImpl::NewGraphics ()
527 int w
= m_pen
.GetWidth ();
528 wxColour c
= m_pen
.GetColour ();
530 wxString s
, sBrush
, sPenCap
, sPenJoin
, sPenStyle
, sLast
, sWarn
;
532 sBrush
= wxT("</g>\n<g style=\"") + wxBrushString ( m_brush
.GetColour (), m_brush
.GetStyle () )
533 + wxT(" stroke:#") + wxColStr (c
) + wxT("; ");
535 switch ( m_pen
.GetCap () )
537 case wxCAP_PROJECTING
:
538 sPenCap
= wxT("stroke-linecap:square; ");
541 sPenCap
= wxT("stroke-linecap:butt; ");
545 sPenCap
= wxT("stroke-linecap:round; ");
547 switch ( m_pen
.GetJoin () )
550 sPenJoin
= wxT("stroke-linejoin:bevel; ");
553 sPenJoin
= wxT("stroke-linejoin:miter; ");
557 sPenJoin
= wxT("stroke-linejoin:round; ");
560 switch ( m_pen
.GetStyle () )
562 case wxPENSTYLE_SOLID
:
563 sPenStyle
= wxT("stroke-opacity:1.0; stroke-opacity:1.0; ");
565 case wxPENSTYLE_TRANSPARENT
:
566 sPenStyle
= wxT("stroke-opacity:0.0; stroke-opacity:0.0; ");
569 wxASSERT_MSG(false, wxT("wxSVGFileDC::SetPen Call called to set a Style which is not available"));
570 sWarn
= sWarn
+ wxT("<!--- wxSVGFileDC::SetPen Call called to set a Style which is not available --> \n");
573 sLast
.Printf( wxT("stroke-width:%d\" \n transform=\"translate(%.2g %.2g) scale(%.2g %.2g)\">"),
574 w
, double(m_logicalOriginX
), double(m_logicalOriginY
), m_scaleX
, m_scaleY
);
576 s
= sBrush
+ sPenCap
+ sPenJoin
+ sPenStyle
+ sLast
+ newline
+ sWarn
;
578 m_graphics_changed
= false;
579 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::NewGraphics Call executed"));
583 void wxSVGFileDCImpl::SetFont(const wxFont
& font
)
588 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetFont Call executed"));
591 // export a bitmap as a raster image in png
592 bool wxSVGFileDCImpl::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
593 wxDC
* source
, wxCoord xsrc
, wxCoord ysrc
,
594 wxRasterOperationMode logicalFunc
/*= wxCOPY*/, bool useMask
/*= false*/,
595 wxCoord
/*xsrcMask = -1*/, wxCoord
/*ysrcMask = -1*/)
597 if (logicalFunc
!= wxCOPY
)
599 wxASSERT_MSG(false, wxT("wxSVGFileDC::DoBlit Call requested nonCopy mode; this is not possible"));
602 if (useMask
!= false)
604 wxASSERT_MSG(false, wxT("wxSVGFileDC::DoBlit Call requested false mask; this is not possible"));
607 wxBitmap
myBitmap (width
, height
);
609 memDC
.SelectObject( myBitmap
);
610 memDC
.Blit(0, 0, width
, height
, source
, xsrc
, ysrc
);
611 memDC
.SelectObject( wxNullBitmap
);
612 DoDrawBitmap(myBitmap
, xdest
, ydest
);
613 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoBlit Call executed"));
617 void wxSVGFileDCImpl::DoDrawIcon(const class wxIcon
& myIcon
, wxCoord x
, wxCoord y
)
619 wxBitmap
myBitmap (myIcon
.GetWidth(), myIcon
.GetHeight() );
621 memDC
.SelectObject( myBitmap
);
622 memDC
.DrawIcon(myIcon
,0,0);
623 memDC
.SelectObject( wxNullBitmap
);
624 DoDrawBitmap(myBitmap
, x
, y
);
625 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawIcon Call executed"));
629 void wxSVGFileDCImpl::DoDrawBitmap(const class wxBitmap
& bmp
, wxCoord x
, wxCoord y
, bool WXUNUSED(bTransparent
) /*=0*/ )
631 if (m_graphics_changed
) NewGraphics ();
633 wxString sTmp
, s
, sPNG
;
634 if ( wxImage::FindHandler(wxBITMAP_TYPE_PNG
) == NULL
)
635 wxImage::AddHandler(new wxPNGHandler
);
637 // create suitable file name
638 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
639 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
640 while (wxFile::Exists(sPNG
) )
643 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
644 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
647 //create copy of bitmap (wxGTK doesn't like saving a constant bitmap)
648 wxBitmap myBitmap
= bmp
;
650 bool bPNG_OK
= myBitmap
.SaveFile(sPNG
,wxBITMAP_TYPE_PNG
);
652 // reference the bitmap from the SVG doc
653 // only use filename & ext
654 sPNG
= sPNG
.AfterLast(wxFileName::GetPathSeparator());
656 // reference the bitmap from the SVG doc
657 int w
= myBitmap
.GetWidth();
658 int h
= myBitmap
.GetHeight();
659 sTmp
.Printf ( wxT(" <image x=\"%d\" y=\"%d\" width=\"%dpx\" height=\"%dpx\" "), x
,y
,w
,h
);
661 sTmp
.Printf ( wxT(" xlink:href=\"%s\"> \n"), sPNG
.c_str() );
662 s
= s
+ sTmp
+ wxT("<title>Image from wxSVG</title> </image>") + newline
;
668 m_OK
= m_outfile
->Ok () && bPNG_OK
;
669 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawBitmap Call executed"));
674 void wxSVGFileDCImpl::write(const wxString
&s
)
676 const wxCharBuffer buf
= s
.utf8_str();
677 m_outfile
->Write(buf
, strlen((const char *)buf
));
678 m_OK
= m_outfile
->Ok();