]>
git.saurik.com Git - wxWidgets.git/blob - src/common/dcsvg.cpp
d59ecb0277ac2dfd67943b1b9183ec61014e28b8
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"
22 #include "wx/svg/dcsvg.h"
27 #define wxSVG_DEBUG FALSE
28 // or TRUE to see the calls being executed
29 #define newline wxString(wxT("\n"))
30 #define space wxString(wxT(" "))
31 #define semicolon wxString(wxT(";"))
32 #define wx_round(a) (int)((a)+.5)
39 static inline double DegToRad(double deg
) { return (deg
* 3.14) / 180.0; } ;
41 wxString
wxColStr ( wxColour c
)
43 unsigned char r
, g
, b
;
48 // possible Unicode bug here
49 wxString s
= wxDecToHex(r
) + wxDecToHex(g
) + wxDecToHex(b
) ;
54 wxString
wxBrushString ( wxColour c
, int style
)
56 wxString s
= wxT("fill:#") + wxColStr (c
) + semicolon
+ space
;
60 s
= s
+ wxT("fill-opacity:1.0; ");
63 s
= s
+ wxT("fill-opacity:0.0; ");
67 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::Requested Brush Style not available")) ;
75 void wxSVGFileDC::Init (wxString f
, int Width
, int Height
, float dpi
)
78 //set up things first wxDCBase does all this?
85 m_mm_to_pix_x
= dpi
/25.4;
86 m_mm_to_pix_y
= dpi
/25.4;
88 m_signX
= m_signY
= 1;
90 m_userScaleX
= m_userScaleY
=
91 m_deviceOriginX
= m_deviceOriginY
= 0;
93 m_OriginX
= m_OriginY
= 0;
94 m_logicalOriginX
= m_logicalOriginY
= 0;
95 m_logicalScaleX
= m_logicalScaleY
= 0 ;
96 m_scaleX
= m_scaleY
= 1.0 ;
98 m_logicalFunction
= wxCOPY
;
99 m_backgroundMode
= wxTRANSPARENT
;
100 m_mappingMode
= wxMM_TEXT
;
102 m_backgroundBrush
= *wxTRANSPARENT_BRUSH
;
103 m_textForegroundColour
= *wxBLACK
;
104 m_textBackgroundColour
= *wxWHITE
;
105 m_colour
= wxColourDisplay();
107 m_pen
= *wxBLACK_PEN
;
108 m_font
= *wxNORMAL_FONT
;
109 m_brush
= *wxWHITE_BRUSH
;
111 m_graphics_changed
= TRUE
;
113 ////////////////////code here
115 m_outfile
= new wxFileOutputStream(f
) ;
116 m_OK
= m_outfile
->Ok ();
122 s
= wxT("<?xml version=\"1.0\" standalone=\"no\"?>") ; s
= s
+ newline
;
123 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
124 s
= wxT("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" ") + newline
;
125 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
126 s
= wxT("\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"> ")+ newline
;
127 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
128 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
);
129 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
130 s
= wxT("<title>SVG Picture created as ") + wxFileNameFromPath(f
) + wxT(" </title>") + newline
;
131 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
132 s
= wxString (wxT("<desc>Picture generated by wxSVG ")) + wxSVGVersion
+ wxT(" </desc>")+ newline
;
133 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
134 s
= wxT("<g style=\"fill:black; stroke:black; stroke-width:1\">") + newline
;
135 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
138 m_OK
= m_outfile
->Ok ();
143 wxSVGFileDC::wxSVGFileDC (wxString f
)
145 // quarter 640x480 screen display at 72 dpi
146 Init (f
,320,240,72.0);
149 wxSVGFileDC::wxSVGFileDC (wxString f
, int Width
, int Height
)
151 Init (f
,Width
,Height
,72.0);
154 wxSVGFileDC::wxSVGFileDC (wxString f
, int Width
, int Height
, float dpi
)
156 Init (f
,Width
,Height
,dpi
);
159 wxSVGFileDC::~wxSVGFileDC()
161 wxString s
= wxT("</g> \n</svg> \n") ;
162 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
163 m_OK
= m_outfile
->Ok ();
168 //////////////////////////////////////////////////////////////////////////////////////////
170 void wxSVGFileDC::DoDrawLine (wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
172 if (m_graphics_changed
) NewGraphics ();
174 s
.Printf ( wxT("<path d=\"M%d %d L%d %d\" /> \n"), x1
,y1
,x2
,y2
);
177 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
179 m_OK
= m_outfile
->Ok ();
180 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawLine Call executed")) ;
181 CalcBoundingBox(x1
, y1
) ;
182 CalcBoundingBox(x2
, y2
) ;
186 void wxSVGFileDC::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
188 for ( int i
= 1; i
< n
; i
++ )
190 DoDrawLine ( points
[i
-1].x
+ xoffset
, points
[i
-1].y
+ yoffset
,
191 points
[ i
].x
+ xoffset
, points
[ i
].y
+ yoffset
) ;
196 void wxSVGFileDC::DoDrawPoint (wxCoord x1
, wxCoord y1
)
199 if (m_graphics_changed
) NewGraphics ();
200 s
= wxT("<g style = \"stroke-linecap:round;\" > ") + newline
;
201 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
202 DrawLine ( x1
,y1
,x1
,y1
);
204 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
205 m_OK
= m_outfile
->Ok ();
209 void wxSVGFileDC::DoDrawCheckMark(wxCoord x1
, wxCoord y1
, wxCoord width
, wxCoord height
)
211 wxDCBase::DoDrawCheckMark (x1
,y1
,width
,height
) ;
215 void wxSVGFileDC::DoDrawText(const wxString
& text
, wxCoord x1
, wxCoord y1
)
217 DoDrawRotatedText(text
, x1
,y1
,0.0);
218 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawText Call executed")) ;
222 void wxSVGFileDC::DoDrawRotatedText(const wxString
& sText
, wxCoord x
, wxCoord y
, double angle
)
224 //known bug; if the font is drawn in a scaled DC, it will not behave exactly as wxMSW
225 if (m_graphics_changed
) NewGraphics ();
228 // calculate bounding box
230 DoGetTextExtent(sText
, &w
, &h
, &desc
);
232 double rad
= DegToRad(angle
);
234 // wxT("upper left") and wxT("upper right")
235 CalcBoundingBox(x
, y
);
236 CalcBoundingBox(x
+ w
*cos(rad
), y
- h
*sin(rad
));
238 // wxT("bottom left") and wxT("bottom right")
239 x
+= (wxCoord
)(h
*sin(rad
));
240 y
+= (wxCoord
)(h
*cos(rad
));
241 CalcBoundingBox(x
, y
);
242 CalcBoundingBox(x
+ h
*sin(rad
), y
+ h
*cos(rad
));
244 if (m_backgroundMode
== wxSOLID
)
246 // draw background first
247 // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background
249 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background")) ;
250 sTmp
.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x
,y
+desc
-h
, w
, h
);
251 s
= sTmp
+ wxT("style=\"fill:#") + wxColStr (m_textBackgroundColour
) + wxT("; ") ;
252 s
= s
+ wxT("stroke-width:1; stroke:#") + wxColStr (m_textBackgroundColour
) + wxT("; ") ;
253 sTmp
.Printf ( wxT("\" transform=\"rotate( %.2g %d %d ) \">"), -angle
, x
,y
) ;
254 s
= s
+ sTmp
+ newline
;
255 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
257 //now do the text itself
258 s
.Printf (wxT(" <text x=\"%d\" y=\"%d\" "),x
,y
);
260 sTmp
= m_font
.GetFaceName () ;
261 if (sTmp
.Len () > 0) s
= s
+ wxT("style=\"font-family:") + sTmp
+ wxT("; ");
262 else s
= s
+ wxT("style=\" ") ;
264 wxString fontweights
[3] = { wxT("normal"), wxT("lighter"), wxT("bold") };
265 s
= s
+ wxT("font-weight:") + fontweights
[m_font
.GetWeight() - wxNORMAL
] + semicolon
+ space
;
267 wxString fontstyles
[5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };
268 s
= s
+ wxT("font-style:") + fontstyles
[m_font
.GetStyle() - wxNORMAL
] + semicolon
+ space
;
270 sTmp
.Printf (wxT("font-size:%dpt; fill:#"), m_font
.GetPointSize () );
272 s
= s
+ wxColStr (m_textForegroundColour
) + wxT("; stroke:#") + wxColStr (m_textForegroundColour
) + wxT("; ") ;
273 sTmp
.Printf ( wxT("stroke-width:0;\" transform=\"rotate( %.2g %d %d ) \" >"), -angle
, x
,y
) ;
274 s
= s
+ sTmp
+ sText
+ wxT("</text> ") + newline
;
277 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
279 m_OK
= m_outfile
->Ok ();
280 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DrawRotatedText Call executed")) ;
285 void wxSVGFileDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
287 DoDrawRoundedRectangle(x
, y
, width
, height
, 0) ;
291 void wxSVGFileDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
294 if (m_graphics_changed
) NewGraphics ();
297 s
.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" rx=\"%.2g\" "),
298 x
, y
, width
, height
, radius
);
300 s
= s
+ wxT(" /> ") + newline
;
301 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
302 m_OK
= m_outfile
->Ok ();
304 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawRoundedRectangle Call executed")) ;
305 CalcBoundingBox(x
, y
) ;
306 CalcBoundingBox(x
+ width
, y
+ height
) ;
311 void wxSVGFileDC::DoDrawPolygon(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
,int fillStyle
)
313 if (m_graphics_changed
) NewGraphics ();
315 s
= wxT("<polygon style=\"") ;
316 if ( fillStyle
== wxODDEVEN_RULE
)
317 s
= s
+ wxT("fill-rule:evenodd; ");
319 s
= s
+ wxT("fill-rule:nonzero; ");
321 s
= s
+ wxT("\" \npoints=\"") ;
323 for (int i
= 0; i
< n
; i
++)
325 sTmp
.Printf ( wxT("%d,%d"), points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
326 s
= s
+ sTmp
+ newline
;
327 CalcBoundingBox ( points
[i
].x
+xoffset
, points
[i
].y
+yoffset
);
329 s
= s
+ wxT("\" /> ") ;
331 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
332 m_OK
= m_outfile
->Ok ();
334 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawPolygon Call executed")) ;
338 void wxSVGFileDC::DoDrawEllipse (wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
341 if (m_graphics_changed
) NewGraphics ();
347 s
.Printf ( wxT("<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" "), x
+rw
,y
+rh
, rw
, rh
);
348 s
= s
+ wxT(" /> ") + newline
;
350 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
351 m_OK
= m_outfile
->Ok ();
353 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipse Call executed")) ;
354 CalcBoundingBox(x
, y
) ;
355 CalcBoundingBox(x
+ width
, y
+ height
) ;
359 void wxSVGFileDC::DoDrawArc(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
361 /* Draws an arc of a circle, centred on (xc, yc), with starting point
362 (x1, y1) and ending at (x2, y2). The current pen is used for the outline
363 and the current brush for filling the shape.
365 The arc is drawn in an anticlockwise direction from the start point to
368 Might be better described as Pie drawing */
370 if (m_graphics_changed
) NewGraphics ();
373 // we need the radius of the circle which has two estimates
374 double r1
= sqrt ( double( (x1
-xc
)*(x1
-xc
) ) + double( (y1
-yc
)*(y1
-yc
) ) );
375 double r2
= sqrt ( double( (x2
-xc
)*(x2
-xc
) ) + double( (y2
-yc
)*(y2
-yc
) ) );
377 wxASSERT_MSG( (fabs ( r2
-r1
) <= 3), wxT("wxSVGFileDC::DoDrawArc Error in getting radii of circle")) ;
378 if ( fabs ( r2
-r1
) > 3 ) //pixels
380 s
= wxT("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle --> \n") ;
381 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
384 double theta1
= atan2(yc
-y1
,x1
-xc
);
385 if ( theta1
< 0 ) theta1
= theta1
+ 3.14 * 2;
386 double theta2
= atan2(yc
-y2
, x2
-xc
);
387 if ( theta2
< 0 ) theta2
= theta2
+ 3.14 * 2;
388 if ( theta2
< theta1
) theta2
= theta2
+ 3.14 *2 ;
390 int fArc
; // flag for large or small arc 0 means less than 180 degrees
391 if ( fabs((theta2
- theta1
) > 3.14 )) fArc
= 1; else fArc
= 0 ;
393 int fSweep
= 0 ; // flag for sweep always 0
395 s
.Printf ( wxT("<path d=\"M%d %d A%.2g %.2g 0.0 %d %d %d %d L%d %d z "),
396 x1
,y1
, r1
, r2
, fArc
, fSweep
, x2
, y2
, xc
, yc
);
398 // the z means close the path and fill
399 s
= s
+ wxT(" \" /> ") + newline
;
404 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
406 m_OK
= m_outfile
->Ok ();
408 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawArc Call executed")) ;
412 void wxSVGFileDC::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
)
415 Draws an arc of an ellipse. The current pen is used for drawing the arc
416 and the current brush is used for drawing the pie. This function is
417 currently only available for X window and PostScript device contexts.
419 x and y specify the x and y coordinates of the upper-left corner of the
420 rectangle that contains the ellipse.
422 width and height specify the width and height of the rectangle that
423 contains the ellipse.
425 start and end specify the start and end of the arc relative to the
426 three-o'clock position from the center of the rectangle. Angles are
427 specified in degrees (360 is a complete circle). Positive values mean
428 counter-clockwise motion. If start is equal to end, a complete ellipse
431 //known bug: SVG draws with the current pen along the radii, but this does not happen in wxMSW
433 if (m_graphics_changed
) NewGraphics ();
443 double xs
, ys
, xe
, ye
;
444 xs
= xc
+ rx
* cos (DegToRad(sa
)) ;
445 xe
= xc
+ rx
* cos (DegToRad(ea
)) ;
446 ys
= yc
- ry
* sin (DegToRad(sa
)) ;
447 ye
= yc
- ry
* sin (DegToRad(ea
)) ;
449 ///now same as circle arc...
451 double theta1
= atan2(ys
-yc
, xs
-xc
);
452 double theta2
= atan2(ye
-yc
, xe
-xc
);
454 int fArc
; // flag for large or small arc 0 means less than 180 degrees
455 if ( (theta2
- theta1
) > 0 ) fArc
= 1; else fArc
= 0 ;
458 if ( fabs( (theta2
- theta1
) > 3.14)) fSweep
= 1; else fSweep
= 0 ;
460 s
.Printf ( wxT("<path d=\"M%d %d A%d %d 0.0 %d %d %d %d L %d %d z "),
461 int(xs
), int(ys
), int(rx
), int(ry
),
462 fArc
, fSweep
, int(xe
), int(ye
), int(xc
), int(yc
) );
465 s
= s
+ wxT(" \" /> ") + newline
;
469 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
471 m_OK
= m_outfile
->Ok ();
473 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawEllipticArc Call executed")) ;
477 void wxSVGFileDC::DoGetTextExtent(const wxString
& string
, wxCoord
*w
, wxCoord
*h
, wxCoord
*descent
, wxCoord
*externalLeading
, wxFont
*font
) const
482 sDC
.SetFont (m_font
);
483 if ( font
!= NULL
) sDC
.SetFont ( *font
);
484 sDC
.GetTextExtent(string
, w
, h
, descent
, externalLeading
);
485 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetTextExtent Call executed")) ;
489 wxCoord
wxSVGFileDC::GetCharHeight() const
493 sDC
.SetFont (m_font
);
495 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharHeight Call executing")) ;
496 return ( sDC
.GetCharHeight() );
501 wxCoord
wxSVGFileDC::GetCharWidth() const
504 sDC
.SetFont (m_font
);
506 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::GetCharWidth Call executing")) ;
507 return ( sDC
.GetCharWidth() ) ;
512 /// Set Functions /////////////////////////////////////////////////////////////////
513 void wxSVGFileDC::SetBackground( const wxBrush
&brush
)
516 m_backgroundBrush
= brush
;
521 void wxSVGFileDC::SetBackgroundMode( int mode
)
523 m_backgroundMode
= mode
;
528 void wxSVGFileDC::SetBrush(const wxBrush
& brush
)
533 m_graphics_changed
= TRUE
;
534 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetBrush Call executed")) ;
538 void wxSVGFileDC::SetPen(const wxPen
& pen
)
540 // width, color, ends, joins : currently implemented
541 // dashes, stipple : not implemented
544 m_graphics_changed
= TRUE
;
545 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetPen Call executed")) ;
548 void wxSVGFileDC::NewGraphics ()
551 int w
= m_pen
.GetWidth ();
552 wxColour c
= m_pen
.GetColour () ;
554 wxString s
, sBrush
, sPenCap
, sPenJoin
, sPenStyle
, sLast
, sWarn
;
556 sBrush
= wxT("</g>\n<g style=\"") + wxBrushString ( m_brush
.GetColour (), m_brush
.GetStyle () )
557 + wxT(" stroke:#") + wxColStr (c
) + wxT("; ") ;
559 switch ( m_pen
.GetCap () )
561 case wxCAP_PROJECTING
:
562 sPenCap
= wxT("stroke-linecap:square; ") ;
565 sPenCap
= wxT("stroke-linecap:butt; ") ;
569 sPenCap
= wxT("stroke-linecap:round; ") ;
571 switch ( m_pen
.GetJoin () )
574 sPenJoin
= wxT("stroke-linejoin:bevel; ") ;
577 sPenJoin
= wxT("stroke-linejoin:miter; ") ;
581 sPenJoin
= wxT("stroke-linejoin:round; ") ;
584 switch ( m_pen
.GetStyle () )
587 sPenStyle
= wxT("stroke-opacity:1.0; stroke-opacity:1.0; ") ;
590 sPenStyle
= wxT("stroke-opacity:0.0; stroke-opacity:0.0; ") ;
593 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::SetPen Call called to set a Style which is not available")) ;
594 sWarn
= sWarn
+ wxT("<!--- wxSVGFileDC::SetPen Call called to set a Style which is not available --> \n") ;
597 sLast
.Printf ( wxT("stroke-width:%d\" \n transform=\"translate(%.2g %.2g) scale(%.2g %.2g)\">"),
598 w
, m_OriginX
, m_OriginY
, m_scaleX
, m_scaleY
);
600 s
= sBrush
+ sPenCap
+ sPenJoin
+ sPenStyle
+ sLast
+ newline
+ sWarn
;
601 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
602 m_OK
= m_outfile
->Ok ();
603 m_graphics_changed
= FALSE
;
604 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::NewGraphics Call executed")) ;
608 void wxSVGFileDC::SetFont(const wxFont
& font
)
613 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::SetFont Call executed")) ;
617 void wxSVGFileDC::ComputeScaleAndOrigin()
619 m_scaleX
= m_logicalScaleX
* m_userScaleX
;
620 m_scaleY
= m_logicalScaleY
* m_userScaleY
;
621 m_OriginX
= m_logicalOriginX
* m_logicalScaleX
+ m_deviceOriginX
;
622 m_OriginY
= m_logicalOriginY
* m_logicalScaleY
+ m_deviceOriginY
;
623 m_graphics_changed
= TRUE
;
627 int wxSVGFileDC::GetMapMode()
629 return m_mappingMode
;
633 void wxSVGFileDC::SetMapMode( int mode
)
638 SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y
);
641 SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y
);
644 SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y
);
647 SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 );
651 SetLogicalScale( 1.0, 1.0 );
654 m_mappingMode
= mode
;
656 /* we don't do this mega optimisation
657 if (mode != wxMM_TEXT)
659 m_needComputeScaleX = TRUE;
660 m_needComputeScaleY = TRUE;
666 void wxSVGFileDC::GetUserScale(double *x
, double *y
) const
673 void wxSVGFileDC::SetUserScale( double x
, double y
)
675 // allow negative ? -> no
678 ComputeScaleAndOrigin();
682 void wxSVGFileDC::SetLogicalScale( double x
, double y
)
687 ComputeScaleAndOrigin();
691 void wxSVGFileDC::SetLogicalOrigin( wxCoord x
, wxCoord y
)
693 // is this still correct ?
694 m_logicalOriginX
= x
* m_signX
;
695 m_logicalOriginY
= y
* m_signY
;
696 ComputeScaleAndOrigin();
700 void wxSVGFileDC::SetDeviceOrigin( wxCoord x
, wxCoord y
)
702 // only wxPostScripDC has m_signX = -1,
705 ComputeScaleAndOrigin();
709 void wxSVGFileDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
711 // only wxPostScripDC has m_signX = -1,
712 m_signX
= (xLeftRight
? 1 : -1);
713 m_signY
= (yBottomUp
? -1 : 1);
714 ComputeScaleAndOrigin();
718 // export a bitmap as a raster image in png
719 bool wxSVGFileDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
720 wxDC
* source
, wxCoord xsrc
, wxCoord ysrc
,
721 int logicalFunc
/*= wxCOPY*/, bool useMask
/*= FALSE*/,
722 wxCoord
/*xsrcMask = -1*/, wxCoord
/*ysrcMask = -1*/)
725 if (logicalFunc
!= wxCOPY
)
727 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::DoBlit Call requested nonCopy mode; this is not possible")) ;
730 if (useMask
!= FALSE
)
732 wxASSERT_MSG(FALSE
, wxT("wxSVGFileDC::DoBlit Call requested False mask ; this is not possible")) ;
735 wxBitmap
myBitmap (width
, height
) ;
737 memDC
.SelectObject( myBitmap
);
738 memDC
.Blit(0, 0, width
, height
, source
, xsrc
, ysrc
);
739 memDC
.SelectObject( wxNullBitmap
);
740 DoDrawBitmap(myBitmap
, xdest
, ydest
);
741 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoBlit Call executed")) ;
746 void wxSVGFileDC::DoDrawIcon(const class wxIcon
& myIcon
, wxCoord x
, wxCoord y
)
748 wxBitmap
myBitmap (myIcon
.GetWidth(), myIcon
.GetHeight() ) ;
750 memDC
.SelectObject( myBitmap
);
751 memDC
.DrawIcon(myIcon
,0,0);
752 memDC
.SelectObject( wxNullBitmap
);
753 DoDrawBitmap(myBitmap
, x
, y
);
754 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawIcon Call executed")) ;
760 void wxSVGFileDC::DoDrawBitmap(const class wxBitmap
& bmp
, wxCoord x
, wxCoord y
, bool bTransparent
/*=0*/ )
762 if (m_graphics_changed
) NewGraphics ();
764 wxString sTmp
, s
, sPNG
;
765 wxImage::AddHandler(new wxPNGHandler
);
767 // create suitable file name
768 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
769 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
770 while (wxFile::Exists(sPNG
) )
773 sTmp
.Printf ( wxT("_image%d.png"), m_sub_images
);
774 sPNG
= m_filename
.BeforeLast(wxT('.')) + sTmp
;
777 //create copy of bitmap (wxGTK doesn't like saving a constant bitmap)
778 wxBitmap myBitmap
= bmp
;
780 bool bPNG_OK
= myBitmap
.SaveFile(sPNG
,wxBITMAP_TYPE_PNG
);
782 // refrence the bitmap from the SVG doc
783 int w
= myBitmap
.GetWidth();
784 int h
= myBitmap
.GetHeight();
785 sTmp
.Printf ( wxT(" <image x=\"%d\" y=\"%d\" width=\"%dpx\" height=\"%dpx\" "), x
,y
,w
,h
);
787 sTmp
.Printf ( wxT(" xlink:href=\"%s\"> \n"), sPNG
.c_str() );
788 s
= s
+ sTmp
+ wxT("<title>Image from wxSVG</title> </image>") + newline
;
792 m_outfile
->Write (s
.c_str(), s
.Len() ) ;
794 m_OK
= m_outfile
->Ok () && bPNG_OK
;
795 wxASSERT_MSG(!wxSVG_DEBUG
, wxT("wxSVGFileDC::DoDrawBitmap Call executed")) ;
801 // ---------------------------------------------------------------------------
802 // coordinates transformations
803 // ---------------------------------------------------------------------------
805 wxCoord
wxSVGFileDC::DeviceToLogicalX(wxCoord x
) const
811 wxCoord
wxSVGFileDC::DeviceToLogicalY(wxCoord y
) const
817 wxCoord
wxSVGFileDC::DeviceToLogicalXRel(wxCoord x
) const
819 return XDEV2LOGREL(x
);
823 wxCoord
wxSVGFileDC::DeviceToLogicalYRel(wxCoord y
) const
825 return YDEV2LOGREL(y
);
829 wxCoord
wxSVGFileDC::LogicalToDeviceX(wxCoord x
) const
835 wxCoord
wxSVGFileDC::LogicalToDeviceY(wxCoord y
) const
841 wxCoord
wxSVGFileDC::LogicalToDeviceXRel(wxCoord x
) const
843 return XLOG2DEVREL(x
);
847 wxCoord
wxSVGFileDC::LogicalToDeviceYRel(wxCoord y
) const
849 return YLOG2DEVREL(y
);