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