]>
git.saurik.com Git - wxWidgets.git/blob - src/common/dcsvg.cpp
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"
30 #define wxSVG_DEBUG FALSE
31 // or TRUE to see the calls being executed
33 #define newline wxString(wxT("\n"))
34 #define space wxString(wxT(" "))
35 #define semicolon wxString(wxT(";"))
36 #define wx_round(a) (int)((a)+.5)
38 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
40 wxString
wxColStr ( wxColour c
)
42 unsigned char r
, g
, b
;
47 // possible Unicode bug here
48 wxString s
= wxDecToHex(r
) + wxDecToHex(g
) + wxDecToHex(b
) ;
53 wxString
wxBrushString ( wxColour c
, int style
)
55 wxString s
= wxT("fill:#") + wxColStr (c
) + semicolon
+ space
;
58 case wxBRUSHSTYLE_SOLID
:
59 s
= s
+ wxT("fill-opacity:1.0; ");
61 case wxBRUSHSTYLE_TRANSPARENT
:
62 s
= s
+ wxT("fill-opacity:0.0; ");
66 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::Requested Brush Style not available")) ;
73 // ----------------------------------------------------------
75 // ----------------------------------------------------------
77 IMPLEMENT_ABSTRACT_CLASS(wxSVGFileDCImpl
, wxDC
)
79 wxSVGFileDCImpl::wxSVGFileDCImpl( wxSVGFileDC
*owner
, const wxString
&filename
,
80 int width
, int height
, double dpi
) :
83 Init( filename
, width
, height
, dpi
);
86 void wxSVGFileDCImpl::Init (const wxString
&filename
, int Width
, int Height
, double dpi
)
95 m_mm_to_pix_x
= dpi
/25.4;
96 m_mm_to_pix_y
= dpi
/25.4;
98 m_backgroundBrush
= *wxTRANSPARENT_BRUSH
;
99 m_textForegroundColour
= *wxBLACK
;
100 m_textBackgroundColour
= *wxWHITE
;
101 m_colour
= wxColourDisplay();
103 m_pen
= *wxBLACK_PEN
;
104 m_font
= *wxNORMAL_FONT
;
105 m_brush
= *wxWHITE_BRUSH
;
107 m_graphics_changed
= TRUE
;
109 ////////////////////code here
111 m_outfile
= new wxFileOutputStream(filename
) ;
112 m_OK
= m_outfile
->Ok ();
115 m_filename
= filename
;
118 s
= wxT("<?xml version=\"1.0\" standalone=\"no\"?>") ; s
= s
+ newline
;
120 s
= wxT("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" ") + newline
;
122 s
= wxT("\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"> ")+ newline
;
124 s
.Printf ( wxT("<svg width=\"%.2gcm\" height=\"%.2gcm\" viewBox=\"0 0 %d %d \"> \n"), float(Width
)/dpi
*2.54, float(Height
)/dpi
*2.54, Width
, Height
);
126 s
= wxT("<title>SVG Picture created as ") + wxFileNameFromPath(filename
) + wxT(" </title>") + newline
;
128 s
= wxString (wxT("<desc>Picture generated by wxSVG ")) + wxSVGVersion
+ wxT(" </desc>")+ newline
;
130 s
= wxT("<g style=\"fill:black; stroke:black; stroke-width:1\">") + newline
;
138 wxSVGFileDCImpl::~wxSVGFileDCImpl()
140 wxString s
= wxT("</g> \n</svg> \n") ;
145 void wxSVGFileDCImpl::DoGetSizeMM( int *width
, int *height
) const
148 *width
= wxRound( (double)m_width
/ m_mm_to_pix_x
);
151 *height
= wxRound( (double)m_height
/ m_mm_to_pix_y
);
154 wxSize
wxSVGFileDCImpl::GetPPI() const
156 return wxSize( wxRound(m_dpi
), wxRound(m_dpi
) );
159 void wxSVGFileDCImpl::DoDrawLine (wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
161 if (m_graphics_changed
) NewGraphics ();
163 s
.Printf ( wxT("<path d=\"M%d %d L%d %d\" /> \n"), x1
,y1
,x2
,y2
);
168 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawLine Call executed")) ;
169 CalcBoundingBox(x1
, y1
) ;
170 CalcBoundingBox(x2
, y2
) ;
174 void wxSVGFileDCImpl::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
176 for ( int i
= 1; i
< n
; i
++ )
178 DoDrawLine ( points
[i
-1].x
+ xoffset
, points
[i
-1].y
+ yoffset
,
179 points
[ i
].x
+ xoffset
, points
[ i
].y
+ yoffset
) ;
184 void wxSVGFileDCImpl::DoDrawPoint (wxCoord x1
, wxCoord y1
)
187 if (m_graphics_changed
) NewGraphics ();
188 s
= wxT("<g style = \"stroke-linecap:round;\" > ") + newline
;
190 DoDrawLine ( x1
,y1
,x1
,y1
);
196 void wxSVGFileDCImpl::DoDrawCheckMark(wxCoord x1
, wxCoord y1
, wxCoord width
, wxCoord height
)
198 wxDCImpl::DoDrawCheckMark (x1
,y1
,width
,height
) ;
202 void wxSVGFileDCImpl::DoDrawText(const wxString
& text
, wxCoord x1
, wxCoord y1
)
204 DoDrawRotatedText(text
, x1
,y1
,0.0);
205 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawText Call executed")) ;
209 void wxSVGFileDCImpl::DoDrawRotatedText(const wxString
& sText
, wxCoord x
, wxCoord y
, double angle
)
211 //known bug; if the font is drawn in a scaled DC, it will not behave exactly as wxMSW
212 if (m_graphics_changed
) NewGraphics ();
215 // calculate bounding box
217 DoGetTextExtent(sText
, &w
, &h
, &desc
);
219 double rad
= DegToRad(angle
);
221 // wxT("upper left") and wxT("upper right")
222 CalcBoundingBox(x
, y
);
223 CalcBoundingBox((wxCoord
)(x
+ w
*cos(rad
)), (wxCoord
)(y
- h
*sin(rad
)));
225 // wxT("bottom left") and wxT("bottom right")
226 x
+= (wxCoord
)(h
*sin(rad
));
227 y
+= (wxCoord
)(h
*cos(rad
));
228 CalcBoundingBox(x
, y
);
229 CalcBoundingBox((wxCoord
)(x
+ h
*sin(rad
)), (wxCoord
)(y
+ h
*cos(rad
)));
231 if (m_backgroundMode
== wxBRUSHSTYLE_SOLID
)
233 // draw background first
234 // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background
236 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background")) ;
237 sTmp
.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x
,y
+desc
-h
, w
, h
);
238 s
= sTmp
+ wxT("style=\"fill:#") + wxColStr (m_textBackgroundColour
) + wxT("; ") ;
239 s
= s
+ wxT("stroke-width:1; stroke:#") + wxColStr (m_textBackgroundColour
) + wxT("; ") ;
240 sTmp
.Printf ( wxT("\" transform=\"rotate( %.2g %d %d ) \">"), -angle
, x
,y
) ;
241 s
= s
+ sTmp
+ newline
;
244 //now do the text itself
245 s
.Printf (wxT(" <text x=\"%d\" y=\"%d\" "),x
,y
);
247 sTmp
= m_font
.GetFaceName () ;
248 if (sTmp
.Len () > 0) s
= s
+ wxT("style=\"font-family:") + sTmp
+ wxT("; ");
249 else s
= s
+ wxT("style=\" ") ;
251 wxString fontweights
[3] = { wxT("normal"), wxT("lighter"), wxT("bold") };
252 s
= s
+ wxT("font-weight:") + fontweights
[m_font
.GetWeight() - wxNORMAL
] + semicolon
+ space
;
254 wxString fontstyles
[5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };
255 s
= s
+ wxT("font-style:") + fontstyles
[m_font
.GetStyle() - wxNORMAL
] + semicolon
+ space
;
257 sTmp
.Printf (wxT("font-size:%dpt; fill:#"), m_font
.GetPointSize () );
259 s
= s
+ wxColStr (m_textForegroundColour
) + wxT("; stroke:#") + wxColStr (m_textForegroundColour
) + wxT("; ") ;
260 sTmp
.Printf ( wxT("stroke-width:0;\" transform=\"rotate( %.2g %d %d ) \" >"), -angle
, x
,y
) ;
261 s
= s
+ sTmp
+ sText
+ wxT("</text> ") + newline
;
266 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawRotatedText Call executed")) ;
271 void wxSVGFileDCImpl::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
273 DoDrawRoundedRectangle(x
, y
, width
, height
, 0) ;
277 void wxSVGFileDCImpl::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
280 if (m_graphics_changed
) NewGraphics ();
283 s
.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" rx=\"%.2g\" "),
284 x
, y
, width
, height
, radius
);
286 s
= s
+ wxT(" /> ") + newline
;
289 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawRoundedRectangle Call executed")) ;
290 CalcBoundingBox(x
, y
) ;
291 CalcBoundingBox(x
+ width
, y
+ height
) ;
296 void wxSVGFileDCImpl::DoDrawPolygon(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
,int fillStyle
)
298 if (m_graphics_changed
) NewGraphics ();
300 s
= wxT("<polygon style=\"") ;
301 if ( fillStyle
== wxODDEVEN_RULE
)
302 s
= s
+ wxT("fill-rule:evenodd; ");
304 s
= s
+ wxT("fill-rule:nonzero; ");
306 s
= s
+ wxT("\" \npoints=\"") ;
308 for (int i
= 0; i
< n
; i
++)
310 sTmp
.Printf ( wxT("%d,%d"), points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
311 s
= s
+ sTmp
+ newline
;
312 CalcBoundingBox ( points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
314 s
= s
+ wxT("\" /> ") ;
318 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawPolygon Call executed")) ;
322 void wxSVGFileDCImpl::DoDrawEllipse (wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
325 if (m_graphics_changed
) NewGraphics ();
331 s
.Printf ( wxT("<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" "), x
+rw
,y
+rh
, rw
, rh
);
332 s
= s
+ wxT(" /> ") + newline
;
336 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipse Call executed")) ;
337 CalcBoundingBox(x
, y
) ;
338 CalcBoundingBox(x
+ width
, y
+ height
) ;
342 void wxSVGFileDCImpl::DoDrawArc(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
344 /* Draws an arc of a circle, centred on (xc, yc), with starting point
345 (x1, y1) and ending at (x2, y2). The current pen is used for the outline
346 and the current brush for filling the shape.
348 The arc is drawn in an anticlockwise direction from the start point to
351 Might be better described as Pie drawing */
353 if (m_graphics_changed
) NewGraphics ();
356 // we need the radius of the circle which has two estimates
357 double r1
= sqrt ( double( (x1
-xc
)*(x1
-xc
) ) + double( (y1
-yc
)*(y1
-yc
) ) );
358 double r2
= sqrt ( double( (x2
-xc
)*(x2
-xc
) ) + double( (y2
-yc
)*(y2
-yc
) ) );
360 wxASSERT_MSG( (fabs ( r2
-r1
) <= 3), wxT("wxSVGFileDC::DoDrawArc Error in getting radii of circle")) ;
361 if ( fabs ( r2
-r1
) > 3 ) //pixels
363 s
= wxT("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle --> \n") ;
367 double theta1
= atan2((double)(yc
-y1
),(double)(x1
-xc
));
368 if ( theta1
< 0 ) theta1
= theta1
+ M_PI
* 2;
369 double theta2
= atan2((double)(yc
-y2
), (double)(x2
-xc
));
370 if ( theta2
< 0 ) theta2
= theta2
+ M_PI
* 2;
371 if ( theta2
< theta1
) theta2
= theta2
+ M_PI
*2 ;
373 int fArc
; // flag for large or small arc 0 means less than 180 degrees
374 if ( fabs(theta2
- theta1
) > M_PI
) fArc
= 1; else fArc
= 0 ;
376 int fSweep
= 0 ; // flag for sweep always 0
378 s
.Printf ( wxT("<path d=\"M%d %d A%.2g %.2g 0.0 %d %d %d %d L%d %d z "),
379 x1
,y1
, r1
, r2
, fArc
, fSweep
, x2
, y2
, xc
, yc
);
381 // the z means close the path and fill
382 s
= s
+ wxT(" \" /> ") + newline
;
390 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawArc Call executed")) ;
394 void wxSVGFileDCImpl::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
)
397 Draws an arc of an ellipse. The current pen is used for drawing the arc
398 and the current brush is used for drawing the pie. This function is
399 currently only available for X window and PostScript device contexts.
401 x and y specify the x and y coordinates of the upper-left corner of the
402 rectangle that contains the ellipse.
404 width and height specify the width and height of the rectangle that
405 contains the ellipse.
407 start and end specify the start and end of the arc relative to the
408 three-o'clock position from the center of the rectangle. Angles are
409 specified in degrees (360 is a complete circle). Positive values mean
410 counter-clockwise motion. If start is equal to end, a complete ellipse
413 //known bug: SVG draws with the current pen along the radii, but this does not happen in wxMSW
415 if (m_graphics_changed
) NewGraphics ();
425 double xs
, ys
, xe
, ye
;
426 xs
= xc
+ rx
* cos (DegToRad(sa
)) ;
427 xe
= xc
+ rx
* cos (DegToRad(ea
)) ;
428 ys
= yc
- ry
* sin (DegToRad(sa
)) ;
429 ye
= yc
- ry
* sin (DegToRad(ea
)) ;
431 ///now same as circle arc...
433 double theta1
= atan2(ys
-yc
, xs
-xc
);
434 double theta2
= atan2(ye
-yc
, xe
-xc
);
436 int fArc
; // flag for large or small arc 0 means less than 180 degrees
437 if ( (theta2
- theta1
) > 0 ) fArc
= 1; else fArc
= 0 ;
440 if ( fabs(theta2
- theta1
) > M_PI
) fSweep
= 1; else fSweep
= 0 ;
442 s
.Printf ( wxT("<path d=\"M%d %d A%d %d 0.0 %d %d %d %d L %d %d z "),
443 int(xs
), int(ys
), int(rx
), int(ry
),
444 fArc
, fSweep
, int(xe
), int(ye
), int(xc
), int(yc
) );
447 s
= s
+ wxT(" \" /> ") + newline
;
454 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipticArc Call executed")) ;
458 void wxSVGFileDCImpl::DoGetTextExtent(const wxString
& string
, wxCoord
*w
, wxCoord
*h
, wxCoord
*descent
, wxCoord
*externalLeading
, const wxFont
*font
) const
463 sDC
.SetFont (m_font
);
464 if ( font
!= NULL
) sDC
.SetFont ( *font
);
465 sDC
.GetTextExtent(string
, w
, h
, descent
, externalLeading
);
466 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetTextExtent Call executed")) ;
470 wxCoord
wxSVGFileDCImpl::GetCharHeight() const
474 sDC
.SetFont (m_font
);
476 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharHeight Call executing")) ;
477 return ( sDC
.GetCharHeight() );
482 wxCoord
wxSVGFileDCImpl::GetCharWidth() const
485 sDC
.SetFont (m_font
);
487 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharWidth Call executing")) ;
488 return ( sDC
.GetCharWidth() ) ;
493 /// Set Functions /////////////////////////////////////////////////////////////////
494 void wxSVGFileDCImpl::SetBackground( const wxBrush
&brush
)
497 m_backgroundBrush
= brush
;
502 void wxSVGFileDCImpl::SetBackgroundMode( int mode
)
504 m_backgroundMode
= mode
;
509 void wxSVGFileDCImpl::SetBrush(const wxBrush
& brush
)
514 m_graphics_changed
= TRUE
;
515 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetBrush Call executed")) ;
519 void wxSVGFileDCImpl::SetPen(const wxPen
& pen
)
521 // width, color, ends, joins : currently implemented
522 // dashes, stipple : not implemented
525 m_graphics_changed
= TRUE
;
526 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetPen Call executed")) ;
529 void wxSVGFileDCImpl::NewGraphics ()
532 int w
= m_pen
.GetWidth ();
533 wxColour c
= m_pen
.GetColour () ;
535 wxString s
, sBrush
, sPenCap
, sPenJoin
, sPenStyle
, sLast
, sWarn
;
537 sBrush
= wxT("</g>\n<g style=\"") + wxBrushString ( m_brush
.GetColour (), m_brush
.GetStyle () )
538 + wxT(" stroke:#") + wxColStr (c
) + wxT("; ") ;
540 switch ( m_pen
.GetCap () )
542 case wxCAP_PROJECTING
:
543 sPenCap
= wxT("stroke-linecap:square; ") ;
546 sPenCap
= wxT("stroke-linecap:butt; ") ;
550 sPenCap
= wxT("stroke-linecap:round; ") ;
552 switch ( m_pen
.GetJoin () )
555 sPenJoin
= wxT("stroke-linejoin:bevel; ") ;
558 sPenJoin
= wxT("stroke-linejoin:miter; ") ;
562 sPenJoin
= wxT("stroke-linejoin:round; ") ;
565 switch ( m_pen
.GetStyle () )
567 case wxPENSTYLE_SOLID
:
568 sPenStyle
= wxT("stroke-opacity:1.0; stroke-opacity:1.0; ") ;
570 case wxPENSTYLE_TRANSPARENT
:
571 sPenStyle
= wxT("stroke-opacity:0.0; stroke-opacity:0.0; ") ;
574 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::SetPen Call called to set a Style which is not available")) ;
575 sWarn
= sWarn
+ wxT("<!--- wxSVGFileDC::SetPen Call called to set a Style which is not available --> \n") ;
578 sLast
.Printf( wxT("stroke-width:%d\" \n transform=\"translate(%.2g %.2g) scale(%.2g %.2g)\">"),
579 w
, (double)m_logicalOriginX
, m_logicalOriginY
, m_scaleX
, m_scaleY
);
581 s
= sBrush
+ sPenCap
+ sPenJoin
+ sPenStyle
+ sLast
+ newline
+ sWarn
;
583 m_graphics_changed
= FALSE
;
584 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::NewGraphics Call executed")) ;
588 void wxSVGFileDCImpl::SetFont(const wxFont
& font
)
593 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetFont Call executed")) ;
597 // export a bitmap as a raster image in png
598 bool wxSVGFileDCImpl::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
599 wxDC
* source
, wxCoord xsrc
, wxCoord ysrc
,
600 int logicalFunc
/*= wxCOPY*/, bool useMask
/*= FALSE*/,
601 wxCoord
/*xsrcMask = -1*/, wxCoord
/*ysrcMask = -1*/)
603 if (logicalFunc
!= wxCOPY
)
605 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::DoBlit Call requested nonCopy mode; this is not possible")) ;
608 if (useMask
!= FALSE
)
610 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::DoBlit Call requested False mask ; this is not possible")) ;
613 wxBitmap
myBitmap (width
, height
) ;
615 memDC
.SelectObject( myBitmap
);
616 memDC
.Blit(0, 0, width
, height
, source
, xsrc
, ysrc
);
617 memDC
.SelectObject( wxNullBitmap
);
618 DoDrawBitmap(myBitmap
, xdest
, ydest
);
619 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoBlit Call executed")) ;
623 void wxSVGFileDCImpl::DoDrawIcon(const class wxIcon
& myIcon
, wxCoord x
, wxCoord y
)
625 wxBitmap
myBitmap (myIcon
.GetWidth(), myIcon
.GetHeight() ) ;
627 memDC
.SelectObject( myBitmap
);
628 memDC
.DrawIcon(myIcon
,0,0);
629 memDC
.SelectObject( wxNullBitmap
);
630 DoDrawBitmap(myBitmap
, x
, y
);
631 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawIcon Call executed")) ;
635 void wxSVGFileDCImpl::DoDrawBitmap(const class wxBitmap
& bmp
, wxCoord x
, wxCoord y
, bool WXUNUSED(bTransparent
) /*=0*/ )
637 if (m_graphics_changed
) NewGraphics ();
639 wxString sTmp
, s
, sPNG
;
640 if ( wxImage::FindHandler(wxBITMAP_TYPE_PNG
) == NULL
)
641 wxImage::AddHandler(new wxPNGHandler
);
643 // create suitable file name
644 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
645 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
646 while (wxFile::Exists(sPNG
) )
649 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
650 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
653 //create copy of bitmap (wxGTK doesn't like saving a constant bitmap)
654 wxBitmap myBitmap
= bmp
;
656 bool bPNG_OK
= myBitmap
.SaveFile(sPNG
,wxBITMAP_TYPE_PNG
);
658 // refrence the bitmap from the SVG doc
659 int w
= myBitmap
.GetWidth();
660 int h
= myBitmap
.GetHeight();
661 sTmp
.Printf ( wxT(" <image x=\"%d\" y=\"%d\" width=\"%dpx\" height=\"%dpx\" "), x
,y
,w
,h
);
663 sTmp
.Printf ( wxT(" xlink:href=\"%s\"> \n"), sPNG
.c_str() );
664 s
= s
+ sTmp
+ wxT("<title>Image from wxSVG</title> </image>") + newline
;
670 m_OK
= m_outfile
->Ok () && bPNG_OK
;
671 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawBitmap Call executed")) ;
676 void wxSVGFileDCImpl::write(const wxString
&s
)
678 const wxCharBuffer buf
= s
.utf8_str();
679 m_outfile
->Write(buf
, strlen((const char *)buf
));
680 m_OK
= m_outfile
->Ok();