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