]> git.saurik.com Git - wxWidgets.git/blob - src/common/dcsvg.cpp
Fixed URL saving/loading
[wxWidgets.git] / src / common / dcsvg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: svg.cpp
3 // Purpose: SVG sample
4 // Author: Chris Elliott
5 // Modified by:
6 // RCS-ID: $Id$
7 // Licence: wxWindows license
8 /////////////////////////////////////////////////////////////////////////////
9
10
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #if wxUSE_SVG
19
20 #ifndef WX_PRECOMP
21 #include "wx/dcmemory.h"
22 #include "wx/dcscreen.h"
23 #include "wx/icon.h"
24 #include "wx/image.h"
25 #endif
26
27 #include "wx/dcsvg.h"
28 #include "wx/wfstream.h"
29
30 #define wxSVG_DEBUG FALSE
31 // or TRUE to see the calls being executed
32
33 #define newline wxString(wxT("\n"))
34 #define space wxString(wxT(" "))
35 #define semicolon wxString(wxT(";"))
36 #define wx_round(a) (int)((a)+.5)
37
38 static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
39
40 wxString wxColStr ( wxColour c )
41 {
42 unsigned char r, g, b ;
43 r = c.Red ();
44 g = c.Green ();
45 b = c. Blue ();
46
47 // possible Unicode bug here
48 wxString s = wxDecToHex(r) + wxDecToHex(g) + wxDecToHex(b) ;
49 return s ;
50 }
51
52
53 wxString wxBrushString ( wxColour c, int style )
54 {
55 wxString s = wxT("fill:#") + wxColStr (c) + semicolon + space ;
56 switch ( style )
57 {
58 case wxSOLID :
59 s = s + wxT("fill-opacity:1.0; ");
60 break ;
61 case wxTRANSPARENT:
62 s = s + wxT("fill-opacity:0.0; ");
63 break ;
64
65 default :
66 wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::Requested Brush Style not available")) ;
67
68 }
69 s = s + newline ;
70 return s ;
71 }
72
73 // ----------------------------------------------------------
74 // wxSVGFileDC
75 // ----------------------------------------------------------
76
77 IMPLEMENT_ABSTRACT_CLASS(wxSVGFileDC, wxDC)
78
79 void wxSVGFileDC::Init (wxString f, int Width, int Height, float dpi)
80
81 {
82 m_width = Width ;
83 m_height = Height ;
84
85 m_OK = TRUE;
86
87 m_mm_to_pix_x = dpi/25.4;
88 m_mm_to_pix_y = dpi/25.4;
89
90 m_backgroundBrush = *wxTRANSPARENT_BRUSH;
91 m_textForegroundColour = *wxBLACK;
92 m_textBackgroundColour = *wxWHITE;
93 m_colour = wxColourDisplay();
94
95 m_pen = *wxBLACK_PEN;
96 m_font = *wxNORMAL_FONT;
97 m_brush = *wxWHITE_BRUSH;
98
99 m_graphics_changed = TRUE ;
100
101 ////////////////////code here
102
103 m_outfile = new wxFileOutputStream(f) ;
104 m_OK = m_outfile->Ok ();
105 if (m_OK)
106 {
107 m_filename = f ;
108 m_sub_images = 0 ;
109 wxString s ;
110 s = wxT("<?xml version=\"1.0\" standalone=\"no\"?>") ; s = s + newline ;
111 write(s);
112 s = wxT("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" ") + newline ;
113 write(s);
114 s = wxT("\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"> ")+ newline ;
115 write(s);
116 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 );
117 write(s);
118 s = wxT("<title>SVG Picture created as ") + wxFileNameFromPath(f) + wxT(" </title>") + newline ;
119 write(s);
120 s = wxString (wxT("<desc>Picture generated by wxSVG ")) + wxSVGVersion + wxT(" </desc>")+ newline ;
121 write(s);
122 s = wxT("<g style=\"fill:black; stroke:black; stroke-width:1\">") + newline ;
123 write(s);
124
125 }
126 }
127
128
129 // constructors
130 wxSVGFileDC::wxSVGFileDC (wxString f)
131 {
132 // quarter 640x480 screen display at 72 dpi
133 Init (f,320,240,72.0);
134 }
135
136 wxSVGFileDC::wxSVGFileDC (wxString f, int Width, int Height)
137 {
138 Init (f,Width,Height,72.0);
139 }
140
141 wxSVGFileDC::wxSVGFileDC (wxString f, int Width, int Height, float dpi)
142 {
143 Init (f,Width,Height,dpi);
144 }
145
146 wxSVGFileDC::~wxSVGFileDC()
147 {
148 wxString s = wxT("</g> \n</svg> \n") ;
149 write(s);
150 delete m_outfile ;
151 }
152
153
154 //////////////////////////////////////////////////////////////////////////////////////////
155
156 void wxSVGFileDC::DoDrawLine (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
157 {
158 if (m_graphics_changed) NewGraphics ();
159 wxString s ;
160 s.Printf ( wxT("<path d=\"M%d %d L%d %d\" /> \n"), x1,y1,x2,y2 );
161 if (m_OK)
162 {
163 write(s);
164 }
165 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawLine Call executed")) ;
166 CalcBoundingBox(x1, y1) ;
167 CalcBoundingBox(x2, y2) ;
168 return;
169 }
170
171 void wxSVGFileDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset , wxCoord yoffset )
172 {
173 for ( int i = 1; i < n ; i++ )
174 {
175 DoDrawLine ( points [i-1].x + xoffset, points [i-1].y + yoffset,
176 points [ i ].x + xoffset, points [ i ].y + yoffset ) ;
177 }
178 }
179
180
181 void wxSVGFileDC::DoDrawPoint (wxCoord x1, wxCoord y1)
182 {
183 wxString s;
184 if (m_graphics_changed) NewGraphics ();
185 s = wxT("<g style = \"stroke-linecap:round;\" > ") + newline ;
186 write(s);
187 DrawLine ( x1,y1,x1,y1 );
188 s = wxT("</g>");
189 write(s);
190 }
191
192
193 void wxSVGFileDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, wxCoord width, wxCoord height)
194 {
195 wxDCBase::DoDrawCheckMark (x1,y1,width,height) ;
196 }
197
198
199 void wxSVGFileDC::DoDrawText(const wxString& text, wxCoord x1, wxCoord y1)
200 {
201 DoDrawRotatedText(text, x1,y1,0.0);
202 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawText Call executed")) ;
203 }
204
205
206 void wxSVGFileDC::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoord y, double angle)
207 {
208 //known bug; if the font is drawn in a scaled DC, it will not behave exactly as wxMSW
209 if (m_graphics_changed) NewGraphics ();
210 wxString s, sTmp;
211
212 // calculate bounding box
213 wxCoord w, h, desc ;
214 DoGetTextExtent(sText, &w, &h, &desc);
215
216 double rad = DegToRad(angle);
217
218 // wxT("upper left") and wxT("upper right")
219 CalcBoundingBox(x, y);
220 CalcBoundingBox((wxCoord)(x + w*cos(rad)), (wxCoord)(y - h*sin(rad)));
221
222 // wxT("bottom left") and wxT("bottom right")
223 x += (wxCoord)(h*sin(rad));
224 y += (wxCoord)(h*cos(rad));
225 CalcBoundingBox(x, y);
226 CalcBoundingBox((wxCoord)(x + h*sin(rad)), (wxCoord)(y + h*cos(rad)));
227
228 if (m_backgroundMode == wxSOLID)
229 {
230 // draw background first
231 // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background
232
233 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background")) ;
234 sTmp.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x,y+desc-h, w, h );
235 s = sTmp + wxT("style=\"fill:#") + wxColStr (m_textBackgroundColour) + wxT("; ") ;
236 s = s + wxT("stroke-width:1; stroke:#") + wxColStr (m_textBackgroundColour) + wxT("; ") ;
237 sTmp.Printf ( wxT("\" transform=\"rotate( %.2g %d %d ) \">"), -angle, x,y ) ;
238 s = s + sTmp + newline ;
239 write(s);
240 }
241 //now do the text itself
242 s.Printf (wxT(" <text x=\"%d\" y=\"%d\" "),x,y );
243
244 sTmp = m_font.GetFaceName () ;
245 if (sTmp.Len () > 0) s = s + wxT("style=\"font-family:") + sTmp + wxT("; ");
246 else s = s + wxT("style=\" ") ;
247
248 wxString fontweights [3] = { wxT("normal"), wxT("lighter"), wxT("bold") };
249 s = s + wxT("font-weight:") + fontweights[m_font.GetWeight() - wxNORMAL] + semicolon + space;
250
251 wxString fontstyles [5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };
252 s = s + wxT("font-style:") + fontstyles[m_font.GetStyle() - wxNORMAL] + semicolon + space;
253
254 sTmp.Printf (wxT("font-size:%dpt; fill:#"), m_font.GetPointSize () );
255 s = s + sTmp ;
256 s = s + wxColStr (m_textForegroundColour) + wxT("; stroke:#") + wxColStr (m_textForegroundColour) + wxT("; ") ;
257 sTmp.Printf ( wxT("stroke-width:0;\" transform=\"rotate( %.2g %d %d ) \" >"), -angle, x,y ) ;
258 s = s + sTmp + sText + wxT("</text> ") + newline ;
259 if (m_OK)
260 {
261 write(s);
262 }
263 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawRotatedText Call executed")) ;
264
265 }
266
267
268 void wxSVGFileDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
269 {
270 DoDrawRoundedRectangle(x, y, width, height, 0) ;
271 }
272
273
274 void wxSVGFileDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius )
275
276 {
277 if (m_graphics_changed) NewGraphics ();
278 wxString s ;
279
280 s.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" rx=\"%.2g\" "),
281 x, y, width, height, radius );
282
283 s = s + wxT(" /> ") + newline ;
284 write(s);
285
286 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawRoundedRectangle Call executed")) ;
287 CalcBoundingBox(x, y) ;
288 CalcBoundingBox(x + width, y + height) ;
289
290 }
291
292
293 void wxSVGFileDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset,int fillStyle)
294 {
295 if (m_graphics_changed) NewGraphics ();
296 wxString s, sTmp ;
297 s = wxT("<polygon style=\"") ;
298 if ( fillStyle == wxODDEVEN_RULE )
299 s = s + wxT("fill-rule:evenodd; ");
300 else
301 s = s + wxT("fill-rule:nonzero; ");
302
303 s = s + wxT("\" \npoints=\"") ;
304
305 for (int i = 0; i < n; i++)
306 {
307 sTmp.Printf ( wxT("%d,%d"), points [i].x+xoffset, points[i].y+yoffset );
308 s = s + sTmp + newline ;
309 CalcBoundingBox ( points [i].x+xoffset, points[i].y+yoffset);
310 }
311 s = s + wxT("\" /> ") ;
312 s = s + newline ;
313 write(s);
314
315 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawPolygon Call executed")) ;
316 }
317
318
319 void wxSVGFileDC::DoDrawEllipse (wxCoord x, wxCoord y, wxCoord width, wxCoord height)
320
321 {
322 if (m_graphics_changed) NewGraphics ();
323
324 int rh = height /2 ;
325 int rw = width /2 ;
326
327 wxString s;
328 s.Printf ( wxT("<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" "), x+rw,y+rh, rw, rh );
329 s = s + wxT(" /> ") + newline ;
330
331 write(s);
332
333 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawEllipse Call executed")) ;
334 CalcBoundingBox(x, y) ;
335 CalcBoundingBox(x + width, y + height) ;
336 }
337
338
339 void wxSVGFileDC::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc)
340 {
341 /* Draws an arc of a circle, centred on (xc, yc), with starting point
342 (x1, y1) and ending at (x2, y2). The current pen is used for the outline
343 and the current brush for filling the shape.
344
345 The arc is drawn in an anticlockwise direction from the start point to
346 the end point.
347
348 Might be better described as Pie drawing */
349
350 if (m_graphics_changed) NewGraphics ();
351 wxString s ;
352
353 // we need the radius of the circle which has two estimates
354 double r1 = sqrt ( double( (x1-xc)*(x1-xc) ) + double( (y1-yc)*(y1-yc) ) );
355 double r2 = sqrt ( double( (x2-xc)*(x2-xc) ) + double( (y2-yc)*(y2-yc) ) );
356
357 wxASSERT_MSG( (fabs ( r2-r1 ) <= 3), wxT("wxSVGFileDC::DoDrawArc Error in getting radii of circle")) ;
358 if ( fabs ( r2-r1 ) > 3 ) //pixels
359 {
360 s = wxT("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle --> \n") ;
361 write(s);
362 }
363
364 double theta1 = atan2((double)(yc-y1),(double)(x1-xc));
365 if ( theta1 < 0 ) theta1 = theta1 + M_PI * 2;
366 double theta2 = atan2((double)(yc-y2), (double)(x2-xc));
367 if ( theta2 < 0 ) theta2 = theta2 + M_PI * 2;
368 if ( theta2 < theta1 ) theta2 = theta2 + M_PI *2 ;
369
370 int fArc ; // flag for large or small arc 0 means less than 180 degrees
371 if ( fabs(theta2 - theta1) > M_PI ) fArc = 1; else fArc = 0 ;
372
373 int fSweep = 0 ; // flag for sweep always 0
374
375 s.Printf ( wxT("<path d=\"M%d %d A%.2g %.2g 0.0 %d %d %d %d L%d %d z "),
376 x1,y1, r1, r2, fArc, fSweep, x2, y2, xc, yc );
377
378 // the z means close the path and fill
379 s = s + wxT(" \" /> ") + newline ;
380
381
382 if (m_OK)
383 {
384 write(s);
385 }
386
387 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawArc Call executed")) ;
388 }
389
390
391 void wxSVGFileDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea)
392 {
393 /*
394 Draws an arc of an ellipse. The current pen is used for drawing the arc
395 and the current brush is used for drawing the pie. This function is
396 currently only available for X window and PostScript device contexts.
397
398 x and y specify the x and y coordinates of the upper-left corner of the
399 rectangle that contains the ellipse.
400
401 width and height specify the width and height of the rectangle that
402 contains the ellipse.
403
404 start and end specify the start and end of the arc relative to the
405 three-o'clock position from the center of the rectangle. Angles are
406 specified in degrees (360 is a complete circle). Positive values mean
407 counter-clockwise motion. If start is equal to end, a complete ellipse
408 will be drawn. */
409
410 //known bug: SVG draws with the current pen along the radii, but this does not happen in wxMSW
411
412 if (m_graphics_changed) NewGraphics ();
413
414 wxString s ;
415 //radius
416 double rx = w / 2 ;
417 double ry = h / 2 ;
418 // center
419 double xc = x + rx ;
420 double yc = y + ry ;
421
422 double xs, ys, xe, ye ;
423 xs = xc + rx * cos (DegToRad(sa)) ;
424 xe = xc + rx * cos (DegToRad(ea)) ;
425 ys = yc - ry * sin (DegToRad(sa)) ;
426 ye = yc - ry * sin (DegToRad(ea)) ;
427
428 ///now same as circle arc...
429
430 double theta1 = atan2(ys-yc, xs-xc);
431 double theta2 = atan2(ye-yc, xe-xc);
432
433 int fArc ; // flag for large or small arc 0 means less than 180 degrees
434 if ( (theta2 - theta1) > 0 ) fArc = 1; else fArc = 0 ;
435
436 int fSweep ;
437 if ( fabs(theta2 - theta1) > M_PI) fSweep = 1; else fSweep = 0 ;
438
439 s.Printf ( wxT("<path d=\"M%d %d A%d %d 0.0 %d %d %d %d L %d %d z "),
440 int(xs), int(ys), int(rx), int(ry),
441 fArc, fSweep, int(xe), int(ye), int(xc), int(yc) );
442
443
444 s = s + wxT(" \" /> ") + newline ;
445
446 if (m_OK)
447 {
448 write(s);
449 }
450
451 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawEllipticArc Call executed")) ;
452 }
453
454
455 void wxSVGFileDC::DoGetTextExtent(const wxString& string, wxCoord *w, wxCoord *h, wxCoord *descent , wxCoord *externalLeading , const wxFont *font) const
456
457 {
458 wxScreenDC sDC ;
459
460 sDC.SetFont (m_font);
461 if ( font != NULL ) sDC.SetFont ( *font );
462 sDC.GetTextExtent(string, w, h, descent, externalLeading );
463 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::GetTextExtent Call executed")) ;
464 }
465
466
467 wxCoord wxSVGFileDC::GetCharHeight() const
468
469 {
470 wxScreenDC sDC ;
471 sDC.SetFont (m_font);
472
473 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::GetCharHeight Call executing")) ;
474 return ( sDC.GetCharHeight() );
475
476 }
477
478
479 wxCoord wxSVGFileDC::GetCharWidth() const
480 {
481 wxScreenDC sDC ;
482 sDC.SetFont (m_font);
483
484 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::GetCharWidth Call executing")) ;
485 return ( sDC.GetCharWidth() ) ;
486
487 }
488
489
490 /// Set Functions /////////////////////////////////////////////////////////////////
491 void wxSVGFileDC::SetBackground( const wxBrush &brush )
492 {
493
494 m_backgroundBrush = brush;
495 return;
496 }
497
498
499 void wxSVGFileDC::SetBackgroundMode( int mode )
500 {
501 m_backgroundMode = mode;
502 return;
503 }
504
505
506 void wxSVGFileDC::SetBrush(const wxBrush& brush)
507
508 {
509 m_brush = brush ;
510
511 m_graphics_changed = TRUE ;
512 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetBrush Call executed")) ;
513 }
514
515
516 void wxSVGFileDC::SetPen(const wxPen& pen)
517 {
518 // width, color, ends, joins : currently implemented
519 // dashes, stipple : not implemented
520 m_pen = pen ;
521
522 m_graphics_changed = TRUE ;
523 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetPen Call executed")) ;
524 }
525
526 void wxSVGFileDC::NewGraphics ()
527 {
528
529 int w = m_pen.GetWidth ();
530 wxColour c = m_pen.GetColour () ;
531
532 wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast, sWarn;
533
534 sBrush = wxT("</g>\n<g style=\"") + wxBrushString ( m_brush.GetColour (), m_brush.GetStyle () )
535 + wxT(" stroke:#") + wxColStr (c) + wxT("; ") ;
536
537 switch ( m_pen.GetCap () )
538 {
539 case wxCAP_PROJECTING :
540 sPenCap = wxT("stroke-linecap:square; ") ;
541 break ;
542 case wxCAP_BUTT :
543 sPenCap = wxT("stroke-linecap:butt; ") ;
544 break ;
545 case wxCAP_ROUND :
546 default :
547 sPenCap = wxT("stroke-linecap:round; ") ;
548 };
549 switch ( m_pen.GetJoin () )
550 {
551 case wxJOIN_BEVEL :
552 sPenJoin = wxT("stroke-linejoin:bevel; ") ;
553 break ;
554 case wxJOIN_MITER :
555 sPenJoin = wxT("stroke-linejoin:miter; ") ;
556 break ;
557 case wxJOIN_ROUND :
558 default :
559 sPenJoin = wxT("stroke-linejoin:round; ") ;
560 };
561
562 switch ( m_pen.GetStyle () )
563 {
564 case wxSOLID :
565 sPenStyle = wxT("stroke-opacity:1.0; stroke-opacity:1.0; ") ;
566 break ;
567 case wxTRANSPARENT :
568 sPenStyle = wxT("stroke-opacity:0.0; stroke-opacity:0.0; ") ;
569 break ;
570 default :
571 wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::SetPen Call called to set a Style which is not available")) ;
572 sWarn = sWarn + wxT("<!--- wxSVGFileDC::SetPen Call called to set a Style which is not available --> \n") ;
573 }
574
575 sLast.Printf( wxT("stroke-width:%d\" \n transform=\"translate(%.2g %.2g) scale(%.2g %.2g)\">"),
576 w, (double)m_logicalOriginX, m_logicalOriginY, m_scaleX, m_scaleY );
577
578 s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + newline + sWarn;
579 write(s);
580 m_graphics_changed = FALSE ;
581 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::NewGraphics Call executed")) ;
582 }
583
584
585 void wxSVGFileDC::SetFont(const wxFont& font)
586
587 {
588 m_font = font ;
589
590 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetFont Call executed")) ;
591 }
592
593
594 // export a bitmap as a raster image in png
595 bool wxSVGFileDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
596 wxDC* source, wxCoord xsrc, wxCoord ysrc,
597 int logicalFunc /*= wxCOPY*/, bool useMask /*= FALSE*/,
598 wxCoord /*xsrcMask = -1*/, wxCoord /*ysrcMask = -1*/)
599 {
600 if (logicalFunc != wxCOPY)
601 {
602 wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::DoBlit Call requested nonCopy mode; this is not possible")) ;
603 return FALSE ;
604 }
605 if (useMask != FALSE)
606 {
607 wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::DoBlit Call requested False mask ; this is not possible")) ;
608 return FALSE ;
609 }
610 wxBitmap myBitmap (width, height) ;
611 wxMemoryDC memDC;
612 memDC.SelectObject( myBitmap );
613 memDC.Blit(0, 0, width, height, source, xsrc, ysrc);
614 memDC.SelectObject( wxNullBitmap );
615 DoDrawBitmap(myBitmap, xdest, ydest);
616 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoBlit Call executed")) ;
617 return FALSE ;
618 }
619
620 void wxSVGFileDC::DoDrawIcon(const class wxIcon & myIcon, wxCoord x, wxCoord y)
621 {
622 wxBitmap myBitmap (myIcon.GetWidth(), myIcon.GetHeight() ) ;
623 wxMemoryDC memDC;
624 memDC.SelectObject( myBitmap );
625 memDC.DrawIcon(myIcon,0,0);
626 memDC.SelectObject( wxNullBitmap );
627 DoDrawBitmap(myBitmap, x, y);
628 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawIcon Call executed")) ;
629 return ;
630 }
631
632 void wxSVGFileDC::DoDrawBitmap(const class wxBitmap & bmp, wxCoord x, wxCoord y , bool WXUNUSED(bTransparent) /*=0*/ )
633 {
634 if (m_graphics_changed) NewGraphics ();
635
636 wxString sTmp, s, sPNG ;
637 wxImage::AddHandler(new wxPNGHandler);
638
639 // create suitable file name
640 sTmp.Printf ( wxT("_image%d.png"), m_sub_images);
641 sPNG = m_filename.BeforeLast(wxT('.')) + sTmp;
642 while (wxFile::Exists(sPNG) )
643 {
644 m_sub_images ++ ;
645 sTmp.Printf ( wxT("_image%d.png"), m_sub_images);
646 sPNG = m_filename.BeforeLast(wxT('.')) + sTmp;
647 }
648
649 //create copy of bitmap (wxGTK doesn't like saving a constant bitmap)
650 wxBitmap myBitmap = bmp ;
651 //save it
652 bool bPNG_OK = myBitmap.SaveFile(sPNG,wxBITMAP_TYPE_PNG);
653
654 // refrence 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 );
658 s = s + sTmp ;
659 sTmp.Printf ( wxT(" xlink:href=\"%s\"> \n"), sPNG.c_str() );
660 s = s + sTmp + wxT("<title>Image from wxSVG</title> </image>") + newline;
661
662 if (m_OK && bPNG_OK)
663 {
664 write(s);
665 }
666 m_OK = m_outfile->Ok () && bPNG_OK;
667 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawBitmap Call executed")) ;
668
669 return ;
670 }
671
672 void wxSVGFileDC::write(const wxString &s)
673 {
674 const wxCharBuffer buf = s.utf8_str();
675 m_outfile->Write(buf, strlen((const char *)buf));
676 m_OK = m_outfile->Ok();
677 }
678
679 // ---------------------------------------------------------------------------
680 // coordinates transformations
681 // ---------------------------------------------------------------------------
682
683 void wxSVGFileDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
684 {
685 wxDCBase::SetAxisOrientation( xLeftRight, yBottomUp );
686 }
687
688 void wxSVGFileDC::SetMapMode(int mode)
689 {
690 wxDCBase::SetMapMode(mode);
691 }
692
693 void wxSVGFileDC::SetUserScale(double x, double y)
694 {
695 wxDCBase::SetUserScale(x,y);
696 }
697
698 void wxSVGFileDC::SetLogicalScale(double x, double y)
699 {
700 wxDCBase::SetLogicalScale(x,y);
701 }
702
703 void wxSVGFileDC::SetLogicalOrigin(wxCoord x, wxCoord y)
704 {
705 wxDCBase::SetLogicalOrigin(x,y);
706 }
707
708 void wxSVGFileDC::SetDeviceOrigin(wxCoord x, wxCoord y)
709 {
710 wxDCBase::SetDeviceOrigin(x,y);
711 }
712
713
714
715 #ifdef __BORLANDC__
716 #pragma warn .rch
717 #pragma warn .ccc
718 #endif
719
720 #endif // wxUSE_SVG
721