]> git.saurik.com Git - wxWidgets.git/blame - src/common/dcsvg.cpp
X property data is long for format 32
[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
b0fc907f
VZ
18#if wxUSE_SVG
19
cdf3a589 20#ifndef WX_PRECOMP
98c38984
VZ
21 #include "wx/dcmemory.h"
22 #include "wx/dcscreen.h"
23 #include "wx/icon.h"
24 #include "wx/image.h"
cdf3a589 25#endif
3454ecd5 26
54429bb3 27#include "wx/dcsvg.h"
8e10778e 28#include "wx/wfstream.h"
cdf3a589
CE
29
30#define wxSVG_DEBUG FALSE
31// or TRUE to see the calls being executed
cdf3a589 32
18cea871
RD
33#define newline wxString(wxT("\n"))
34#define space wxString(wxT(" "))
35#define semicolon wxString(wxT(";"))
36#define wx_round(a) (int)((a)+.5)
cdf3a589 37
1bb592b8 38static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
cdf3a589
CE
39
40wxString 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
53wxString 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
621b83d9
RR
73// ----------------------------------------------------------
74// wxSVGFileDC
75// ----------------------------------------------------------
76
77IMPLEMENT_ABSTRACT_CLASS(wxSVGFileDC, wxDC)
cdf3a589
CE
78
79void wxSVGFileDC::Init (wxString f, int Width, int Height, float dpi)
80
81{
cdf3a589
CE
82 m_width = Width ;
83 m_height = Height ;
84
cdf3a589
CE
85 m_OK = TRUE;
86
87 m_mm_to_pix_x = dpi/25.4;
88 m_mm_to_pix_y = dpi/25.4;
89
cdf3a589
CE
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 ;
85b88942 111 write(s);
cdf3a589 112 s = wxT("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" ") + newline ;
85b88942 113 write(s);
cdf3a589 114 s = wxT("\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"> ")+ newline ;
85b88942 115 write(s);
cdf3a589 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 );
85b88942 117 write(s);
cdf3a589 118 s = wxT("<title>SVG Picture created as ") + wxFileNameFromPath(f) + wxT(" </title>") + newline ;
85b88942 119 write(s);
cdf3a589 120 s = wxString (wxT("<desc>Picture generated by wxSVG ")) + wxSVGVersion + wxT(" </desc>")+ newline ;
85b88942 121 write(s);
cdf3a589 122 s = wxT("<g style=\"fill:black; stroke:black; stroke-width:1\">") + newline ;
85b88942 123 write(s);
cdf3a589
CE
124
125 }
cdf3a589
CE
126}
127
128
129// constructors
130wxSVGFileDC::wxSVGFileDC (wxString f)
3454ecd5 131{
cdf3a589
CE
132 // quarter 640x480 screen display at 72 dpi
133 Init (f,320,240,72.0);
1bb592b8 134}
cdf3a589
CE
135
136wxSVGFileDC::wxSVGFileDC (wxString f, int Width, int Height)
137{
138 Init (f,Width,Height,72.0);
1bb592b8 139}
cdf3a589
CE
140
141wxSVGFileDC::wxSVGFileDC (wxString f, int Width, int Height, float dpi)
142{
143 Init (f,Width,Height,dpi);
1bb592b8 144}
cdf3a589
CE
145
146wxSVGFileDC::~wxSVGFileDC()
147{
148 wxString s = wxT("</g> \n</svg> \n") ;
85b88942 149 write(s);
cdf3a589
CE
150 delete m_outfile ;
151}
152
153
154//////////////////////////////////////////////////////////////////////////////////////////
155
156void 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 {
85b88942 163 write(s);
cdf3a589 164 }
cdf3a589
CE
165 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawLine Call executed")) ;
166 CalcBoundingBox(x1, y1) ;
167 CalcBoundingBox(x2, y2) ;
168 return;
1bb592b8 169}
cdf3a589
CE
170
171void 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
181void 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 ;
85b88942 186 write(s);
cdf3a589
CE
187 DrawLine ( x1,y1,x1,y1 );
188 s = wxT("</g>");
85b88942 189 write(s);
cdf3a589
CE
190}
191
192
193void wxSVGFileDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, wxCoord width, wxCoord height)
194{
195 wxDCBase::DoDrawCheckMark (x1,y1,width,height) ;
196}
197
198
199void 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
206void 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);
216db41f 220 CalcBoundingBox((wxCoord)(x + w*cos(rad)), (wxCoord)(y - h*sin(rad)));
cdf3a589
CE
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);
216db41f 226 CalcBoundingBox((wxCoord)(x + h*sin(rad)), (wxCoord)(y + h*cos(rad)));
cdf3a589
CE
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 ;
85b88942 239 write(s);
cdf3a589
CE
240 }
241 //now do the text itself
242 s.Printf (wxT(" <text x=\"%d\" y=\"%d\" "),x,y );
3454ecd5 243
cdf3a589
CE
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;
3454ecd5 250
cdf3a589
CE
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;
3454ecd5 253
cdf3a589
CE
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 {
85b88942 261 write(s);
cdf3a589 262 }
cdf3a589
CE
263 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawRotatedText Call executed")) ;
264
265}
266
267
268void wxSVGFileDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
269{
270 DoDrawRoundedRectangle(x, y, width, height, 0) ;
271}
272
273
274void wxSVGFileDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius )
275
276{
277 if (m_graphics_changed) NewGraphics ();
278 wxString s ;
279
3454ecd5 280 s.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" rx=\"%.2g\" "),
cdf3a589
CE
281 x, y, width, height, radius );
282
283 s = s + wxT(" /> ") + newline ;
85b88942 284 write(s);
cdf3a589
CE
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
293void 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 ;
85b88942 313 write(s);
cdf3a589
CE
314
315 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawPolygon Call executed")) ;
316}
317
318
319void 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
85b88942 331 write(s);
cdf3a589
CE
332
333 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawEllipse Call executed")) ;
334 CalcBoundingBox(x, y) ;
335 CalcBoundingBox(x + width, y + height) ;
336}
337
338
339void 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") ;
85b88942 361 write(s);
cdf3a589
CE
362 }
363
fb88ba48 364 double theta1 = atan2((double)(yc-y1),(double)(x1-xc));
3454ecd5 365 if ( theta1 < 0 ) theta1 = theta1 + M_PI * 2;
fb88ba48 366 double theta2 = atan2((double)(yc-y2), (double)(x2-xc));
3454ecd5
WS
367 if ( theta2 < 0 ) theta2 = theta2 + M_PI * 2;
368 if ( theta2 < theta1 ) theta2 = theta2 + M_PI *2 ;
cdf3a589
CE
369
370 int fArc ; // flag for large or small arc 0 means less than 180 degrees
3454ecd5 371 if ( fabs(theta2 - theta1) > M_PI ) fArc = 1; else fArc = 0 ;
cdf3a589
CE
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 {
85b88942 384 write(s);
cdf3a589 385 }
cdf3a589
CE
386
387 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawArc Call executed")) ;
388}
389
390
391void 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 ;
3454ecd5 437 if ( fabs(theta2 - theta1) > M_PI) fSweep = 1; else fSweep = 0 ;
cdf3a589
CE
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 {
85b88942 448 write(s);
cdf3a589 449 }
cdf3a589
CE
450
451 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawEllipticArc Call executed")) ;
452}
453
454
c94f845b 455void wxSVGFileDC::DoGetTextExtent(const wxString& string, wxCoord *w, wxCoord *h, wxCoord *descent , wxCoord *externalLeading , const wxFont *font) const
cdf3a589
CE
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
467wxCoord 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
479wxCoord 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 /////////////////////////////////////////////////////////////////
491void wxSVGFileDC::SetBackground( const wxBrush &brush )
492{
493
494 m_backgroundBrush = brush;
495 return;
496}
497
498
499void wxSVGFileDC::SetBackgroundMode( int mode )
500{
501 m_backgroundMode = mode;
502 return;
503}
504
505
506void 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
516void wxSVGFileDC::SetPen(const wxPen& pen)
517{
518 // width, color, ends, joins : currently implemented
519 // dashes, stipple : not implemented
520 m_pen = pen ;
3454ecd5 521
cdf3a589
CE
522 m_graphics_changed = TRUE ;
523 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetPen Call executed")) ;
524}
525
526void 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;
3454ecd5
WS
533
534 sBrush = wxT("</g>\n<g style=\"") + wxBrushString ( m_brush.GetColour (), m_brush.GetStyle () )
535 + wxT(" stroke:#") + wxColStr (c) + wxT("; ") ;
536
cdf3a589
CE
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
621b83d9
RR
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 );
cdf3a589
CE
577
578 s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + newline + sWarn;
85b88942 579 write(s);
cdf3a589
CE
580 m_graphics_changed = FALSE ;
581 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::NewGraphics Call executed")) ;
582}
583
584
585void wxSVGFileDC::SetFont(const wxFont& font)
586
587{
588 m_font = font ;
3454ecd5 589
cdf3a589
CE
590 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetFont Call executed")) ;
591}
592
593
cdf3a589
CE
594// export a bitmap as a raster image in png
595bool wxSVGFileDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
3454ecd5
WS
596 wxDC* source, wxCoord xsrc, wxCoord ysrc,
597 int logicalFunc /*= wxCOPY*/, bool useMask /*= FALSE*/,
598 wxCoord /*xsrcMask = -1*/, wxCoord /*ysrcMask = -1*/)
cdf3a589 599{
cdf3a589
CE
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
cdf3a589
CE
620void 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
1a55595e 632void wxSVGFileDC::DoDrawBitmap(const class wxBitmap & bmp, wxCoord x, wxCoord y , bool WXUNUSED(bTransparent) /*=0*/ )
cdf3a589
CE
633{
634 if (m_graphics_changed) NewGraphics ();
635
3454ecd5 636 wxString sTmp, s, sPNG ;
cdf3a589
CE
637 wxImage::AddHandler(new wxPNGHandler);
638
3454ecd5 639// create suitable file name
cdf3a589
CE
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 }
3454ecd5 648
cdf3a589
CE
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;
3454ecd5 661
cdf3a589
CE
662 if (m_OK && bPNG_OK)
663 {
85b88942 664 write(s);
cdf3a589
CE
665 }
666 m_OK = m_outfile->Ok () && bPNG_OK;
667 wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawBitmap Call executed")) ;
668
669 return ;
670}
671
621b83d9
RR
672void wxSVGFileDC::write(const wxString &s)
673{
6243633c 674 const wxCharBuffer buf = s.utf8_str();
621b83d9
RR
675 m_outfile->Write(buf, strlen((const char *)buf));
676 m_OK = m_outfile->Ok();
677}
cdf3a589
CE
678
679// ---------------------------------------------------------------------------
680// coordinates transformations
681// ---------------------------------------------------------------------------
682
04ab8b6d 683void wxSVGFileDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
85b88942 684{
04ab8b6d 685 wxDCBase::SetAxisOrientation( xLeftRight, yBottomUp );
85b88942 686}
cdf3a589 687
04ab8b6d 688void wxSVGFileDC::SetMapMode(int mode)
621b83d9 689{
04ab8b6d 690 wxDCBase::SetMapMode(mode);
621b83d9
RR
691}
692
04ab8b6d 693void wxSVGFileDC::SetUserScale(double x, double y)
621b83d9 694{
04ab8b6d 695 wxDCBase::SetUserScale(x,y);
621b83d9
RR
696}
697
04ab8b6d 698void wxSVGFileDC::SetLogicalScale(double x, double y)
621b83d9 699{
04ab8b6d 700 wxDCBase::SetLogicalScale(x,y);
621b83d9
RR
701}
702
04ab8b6d 703void wxSVGFileDC::SetLogicalOrigin(wxCoord x, wxCoord y)
621b83d9 704{
04ab8b6d 705 wxDCBase::SetLogicalOrigin(x,y);
621b83d9
RR
706}
707
04ab8b6d 708void wxSVGFileDC::SetDeviceOrigin(wxCoord x, wxCoord y)
621b83d9 709{
04ab8b6d 710 wxDCBase::SetDeviceOrigin(x,y);
621b83d9
RR
711}
712
621b83d9
RR
713
714
cdf3a589
CE
715#ifdef __BORLANDC__
716#pragma warn .rch
717#pragma warn .ccc
718#endif
8e10778e 719
b0fc907f
VZ
720#endif // wxUSE_SVG
721