Merge branch 'wxsvgfiledc-improvements' of https://github.com/MaartenBent/wxWidgets

Fix wxSVGBitmapFileHandler directory for saving files and other
miscellaneous improvements to wxSVGFileDC code and documentation.

See https://github.com/wxWidgets/wxWidgets/pull/1290
This commit is contained in:
Vadim Zeitlin
2019-04-25 18:54:23 +02:00
3 changed files with 188 additions and 192 deletions

View File

@@ -12,6 +12,7 @@
#define _WX_DCSVG_H_ #define _WX_DCSVG_H_
#include "wx/string.h" #include "wx/string.h"
#include "wx/filename.h"
#include "wx/dc.h" #include "wx/dc.h"
#if wxUSE_SVG #if wxUSE_SVG
@@ -40,13 +41,26 @@ public:
}; };
// Predefined standard bitmap handler: creates a file, stores the bitmap in // Predefined standard bitmap handler: creates a file, stores the bitmap in
// this file and uses the file URI in the generated SVG. // this file and uses the file name in the generated SVG.
class WXDLLIMPEXP_CORE wxSVGBitmapFileHandler : public wxSVGBitmapHandler class WXDLLIMPEXP_CORE wxSVGBitmapFileHandler : public wxSVGBitmapHandler
{ {
public: public:
wxSVGBitmapFileHandler()
: m_path()
{
}
explicit wxSVGBitmapFileHandler(const wxFileName& path)
: m_path(path)
{
}
virtual bool ProcessBitmap(const wxBitmap& bitmap, virtual bool ProcessBitmap(const wxBitmap& bitmap,
wxCoord x, wxCoord y, wxCoord x, wxCoord y,
wxOutputStream& stream) const wxOVERRIDE; wxOutputStream& stream) const wxOVERRIDE;
private:
wxFileName m_path; // When set, name will be appended with _image#.png
}; };
// Predefined handler which embeds the bitmap (base64-encoding it) inside the // Predefined handler which embeds the bitmap (base64-encoding it) inside the
@@ -62,9 +76,9 @@ public:
class WXDLLIMPEXP_CORE wxSVGFileDCImpl : public wxDCImpl class WXDLLIMPEXP_CORE wxSVGFileDCImpl : public wxDCImpl
{ {
public: public:
wxSVGFileDCImpl( wxSVGFileDC *owner, const wxString &filename, wxSVGFileDCImpl(wxSVGFileDC *owner, const wxString &filename,
int width = 320, int height = 240, double dpi = 72.0, int width = 320, int height = 240, double dpi = 72.0,
const wxString &title = wxString() ); const wxString &title = wxString());
virtual ~wxSVGFileDCImpl(); virtual ~wxSVGFileDCImpl();
@@ -122,8 +136,8 @@ public:
m_graphics_changed = true; m_graphics_changed = true;
} }
virtual void SetBackground( const wxBrush &brush ) wxOVERRIDE; virtual void SetBackground(const wxBrush &brush) wxOVERRIDE;
virtual void SetBackgroundMode( int mode ) wxOVERRIDE; virtual void SetBackgroundMode(int mode) wxOVERRIDE;
virtual void SetBrush(const wxBrush& brush) wxOVERRIDE; virtual void SetBrush(const wxBrush& brush) wxOVERRIDE;
virtual void SetFont(const wxFont& font) wxOVERRIDE; virtual void SetFont(const wxFont& font) wxOVERRIDE;
virtual void SetPen(const wxPen& pen) wxOVERRIDE; virtual void SetPen(const wxPen& pen) wxOVERRIDE;
@@ -133,125 +147,124 @@ public:
void SetBitmapHandler(wxSVGBitmapHandler* handler); void SetBitmapHandler(wxSVGBitmapHandler* handler);
private: private:
virtual bool DoGetPixel(wxCoord, wxCoord, wxColour *) const wxOVERRIDE virtual bool DoGetPixel(wxCoord, wxCoord, wxColour *) const wxOVERRIDE
{ {
wxFAIL_MSG(wxT("wxSVGFILEDC::DoGetPixel Call not implemented")); wxFAIL_MSG(wxT("wxSVGFILEDC::DoGetPixel Call not implemented"));
return true; return true;
} }
virtual bool DoBlit(wxCoord, wxCoord, wxCoord, wxCoord, wxDC *, virtual bool DoBlit(wxCoord, wxCoord, wxCoord, wxCoord, wxDC *,
wxCoord, wxCoord, wxRasterOperationMode = wxCOPY, wxCoord, wxCoord, wxRasterOperationMode = wxCOPY,
bool = 0, int = -1, int = -1) wxOVERRIDE; bool = 0, int = -1, int = -1) wxOVERRIDE;
virtual void DoCrossHair(wxCoord, wxCoord) wxOVERRIDE virtual void DoCrossHair(wxCoord, wxCoord) wxOVERRIDE
{ {
wxFAIL_MSG(wxT("wxSVGFILEDC::CrossHair Call not implemented")); wxFAIL_MSG(wxT("wxSVGFILEDC::CrossHair Call not implemented"));
} }
virtual void DoDrawArc(wxCoord, wxCoord, wxCoord, wxCoord, wxCoord, wxCoord) wxOVERRIDE; virtual void DoDrawArc(wxCoord, wxCoord, wxCoord, wxCoord, wxCoord, wxCoord) wxOVERRIDE;
virtual void DoDrawBitmap(const wxBitmap &, wxCoord, wxCoord, bool = false) wxOVERRIDE; virtual void DoDrawBitmap(const wxBitmap &, wxCoord, wxCoord, bool = false) wxOVERRIDE;
virtual void DoDrawCheckMark(wxCoord x, wxCoord y, wxCoord w, wxCoord h) wxOVERRIDE; virtual void DoDrawCheckMark(wxCoord x, wxCoord y, wxCoord w, wxCoord h) wxOVERRIDE;
virtual void DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h) wxOVERRIDE; virtual void DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h) wxOVERRIDE;
virtual void DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, virtual void DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
double sa, double ea) wxOVERRIDE; double sa, double ea) wxOVERRIDE;
virtual void DoDrawIcon(const wxIcon &, wxCoord, wxCoord) wxOVERRIDE; virtual void DoDrawIcon(const wxIcon &, wxCoord, wxCoord) wxOVERRIDE;
virtual void DoDrawLine (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) wxOVERRIDE; virtual void DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) wxOVERRIDE;
virtual void DoDrawLines(int n, const wxPoint points[], virtual void DoDrawLines(int n, const wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0) wxOVERRIDE; wxCoord xoffset = 0, wxCoord yoffset = 0) wxOVERRIDE;
virtual void DoDrawPoint(wxCoord, wxCoord) wxOVERRIDE; virtual void DoDrawPoint(wxCoord, wxCoord) wxOVERRIDE;
virtual void DoDrawPolygon(int n, const wxPoint points[], virtual void DoDrawPolygon(int n, const wxPoint points[],
wxCoord xoffset, wxCoord yoffset, wxCoord xoffset, wxCoord yoffset,
wxPolygonFillMode fillStyle) wxOVERRIDE; wxPolygonFillMode fillStyle) wxOVERRIDE;
virtual void DoDrawPolyPolygon(int n, const int count[], const wxPoint points[], virtual void DoDrawPolyPolygon(int n, const int count[], const wxPoint points[],
wxCoord xoffset, wxCoord yoffset, wxCoord xoffset, wxCoord yoffset,
wxPolygonFillMode fillStyle) wxOVERRIDE; wxPolygonFillMode fillStyle) wxOVERRIDE;
virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h) wxOVERRIDE; virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h) wxOVERRIDE;
virtual void DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, virtual void DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y,
double angle) wxOVERRIDE; double angle) wxOVERRIDE;
virtual void DoDrawRoundedRectangle(wxCoord x, wxCoord y, virtual void DoDrawRoundedRectangle(wxCoord x, wxCoord y,
wxCoord w, wxCoord h, wxCoord w, wxCoord h,
double radius = 20) wxOVERRIDE ; double radius = 20) wxOVERRIDE;
virtual void DoDrawText(const wxString& text, wxCoord x, wxCoord y) wxOVERRIDE; virtual void DoDrawText(const wxString& text, wxCoord x, wxCoord y) wxOVERRIDE;
virtual bool DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), virtual bool DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
const wxColour& WXUNUSED(col), const wxColour& WXUNUSED(col),
wxFloodFillStyle WXUNUSED(style) = wxFLOOD_SURFACE) wxOVERRIDE wxFloodFillStyle WXUNUSED(style) = wxFLOOD_SURFACE) wxOVERRIDE
{ {
wxFAIL_MSG(wxT("wxSVGFILEDC::DoFloodFill Call not implemented")); wxFAIL_MSG(wxT("wxSVGFILEDC::DoFloodFill Call not implemented"));
return false; return false;
} }
virtual void DoGetSize(int * x, int *y) const wxOVERRIDE virtual void DoGetSize(int * x, int *y) const wxOVERRIDE
{ {
if ( x ) if ( x )
*x = m_width; *x = m_width;
if ( y ) if ( y )
*y = m_height; *y = m_height;
} }
virtual void DoGetTextExtent(const wxString& string, wxCoord *w, wxCoord *h, virtual void DoGetTextExtent(const wxString& string, wxCoord *w, wxCoord *h,
wxCoord *descent = NULL, wxCoord *descent = NULL,
wxCoord *externalLeading = NULL, wxCoord *externalLeading = NULL,
const wxFont *font = NULL) const wxOVERRIDE; const wxFont *font = NULL) const wxOVERRIDE;
virtual void DoSetDeviceClippingRegion(const wxRegion& region) wxOVERRIDE virtual void DoSetDeviceClippingRegion(const wxRegion& region) wxOVERRIDE
{ {
DoSetClippingRegion(region.GetBox().x, region.GetBox().y, DoSetClippingRegion(region.GetBox().x, region.GetBox().y,
region.GetBox().width, region.GetBox().height); region.GetBox().width, region.GetBox().height);
} }
virtual void DoSetClippingRegion(int x, int y, int width, int height) wxOVERRIDE; virtual void DoSetClippingRegion(int x, int y, int width, int height) wxOVERRIDE;
virtual void DoGetSizeMM( int *width, int *height ) const wxOVERRIDE; virtual void DoGetSizeMM(int *width, int *height) const wxOVERRIDE;
virtual wxSize GetPPI() const wxOVERRIDE; virtual wxSize GetPPI() const wxOVERRIDE;
void Init (const wxString &filename, int width, int height, void Init(const wxString &filename, int width, int height,
double dpi, const wxString &title); double dpi, const wxString &title);
void write( const wxString &s ); void write(const wxString &s);
private: private:
// If m_graphics_changed is true, close the current <g> element and start a // If m_graphics_changed is true, close the current <g> element and start a
// new one for the last pen/brush change. // new one for the last pen/brush change.
void NewGraphicsIfNeeded(); void NewGraphicsIfNeeded();
// Open a new graphics group setting up all the attributes according to // Open a new graphics group setting up all the attributes according to
// their current values in wxDC. // their current values in wxDC.
void DoStartNewGraphics(); void DoStartNewGraphics();
wxString m_filename; wxString m_filename;
int m_sub_images; // number of png format images we have bool m_OK;
bool m_OK; bool m_graphics_changed; // set by Set{Brush,Pen}()
bool m_graphics_changed; // set by Set{Brush,Pen}() int m_width, m_height;
int m_width, m_height; double m_dpi;
double m_dpi; wxScopedPtr<wxFileOutputStream> m_outfile;
wxScopedPtr<wxFileOutputStream> m_outfile; wxScopedPtr<wxSVGBitmapHandler> m_bmp_handler; // class to handle bitmaps
wxScopedPtr<wxSVGBitmapHandler> m_bmp_handler; // class to handle bitmaps
// The clipping nesting level is incremented by every call to // The clipping nesting level is incremented by every call to
// SetClippingRegion() and reset when DestroyClippingRegion() is called. // SetClippingRegion() and reset when DestroyClippingRegion() is called.
size_t m_clipNestingLevel; size_t m_clipNestingLevel;
// Unique ID for every clipping graphics group: this is simply always // Unique ID for every clipping graphics group: this is simply always
// incremented in each SetClippingRegion() call. // incremented in each SetClippingRegion() call.
size_t m_clipUniqueId; size_t m_clipUniqueId;
wxDECLARE_ABSTRACT_CLASS(wxSVGFileDCImpl); wxDECLARE_ABSTRACT_CLASS(wxSVGFileDCImpl);
}; };

View File

@@ -28,8 +28,9 @@
as the SVG file, however it is possible to change this behaviour by as the SVG file, however it is possible to change this behaviour by
replacing the built in bitmap handler using wxSVGFileDC::SetBitmapHandler(). replacing the built in bitmap handler using wxSVGFileDC::SetBitmapHandler().
A more substantial SVG library (for reading and writing) is available at More substantial SVG libraries (for reading and writing) are available at
the wxArt2D website <http://wxart2d.sourceforge.net/>. <a href="http://wxart2d.sourceforge.net/" target="_blank">wxArt2D</a> and
<a href="http://wxsvg.sourceforge.net/" target="_blank">wxSVG</a>.
@library{wxcore} @library{wxcore}
@category{dc} @category{dc}
@@ -39,28 +40,13 @@ class wxSVGFileDC : public wxDC
{ {
public: public:
/** /**
Initializes a wxSVGFileDC with the given @a f filename with the given Initializes a wxSVGFileDC with the given @a filename, @a width and
@a Width and @a Height at @a dpi resolution, and an optional @a title. @a height at @a dpi resolution, and an optional @a title.
The title provides a readable name for the SVG document. The title provides a readable name for the SVG document.
*/ */
wxSVGFileDC(const wxString& filename, int width = 320, int height = 240, wxSVGFileDC(const wxString& filename, int width = 320, int height = 240,
double dpi = 72, const wxString& title = wxString()); double dpi = 72, const wxString& title = wxString());
/**
Destructor.
*/
virtual ~wxSVGFileDC();
/**
Does nothing.
*/
void EndDoc();
/**
Does nothing.
*/
void EndPage();
/** /**
Draws a rectangle the size of the SVG using the wxDC::SetBackground() brush. Draws a rectangle the size of the SVG using the wxDC::SetBackground() brush.
*/ */
@@ -88,12 +74,6 @@ public:
*/ */
void SetBitmapHandler(wxSVGBitmapHandler* handler); void SetBitmapHandler(wxSVGBitmapHandler* handler);
/**
Does the same as wxDC::SetLogicalFunction(), except that only wxCOPY is
available. Trying to set one of the other values will fail.
*/
void SetLogicalFunction(wxRasterOperationMode function);
/** /**
Sets the clipping region for this device context to the intersection of Sets the clipping region for this device context to the intersection of
the given region described by the parameters of this method and the previously the given region described by the parameters of this method and the previously
@@ -105,24 +85,6 @@ public:
void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width, void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width,
wxCoord height); wxCoord height);
/**
This is an overloaded member function, provided for convenience. It differs from the
above function only in what argument(s) it accepts.
*/
void SetClippingRegion(const wxPoint& pt, const wxSize& sz);
/**
This is an overloaded member function, provided for convenience. It differs from the
above function only in what argument(s) it accepts.
*/
void SetClippingRegion(const wxRect& rect);
/**
This function is not implemented in this DC class.
It could be implemented in future if a GetPoints() function were made available on wxRegion.
*/
void SetClippingRegion(const wxRegion& region);
/** /**
Destroys the current clipping region so that none of the DC is clipped. Destroys the current clipping region so that none of the DC is clipped.
Since intersections arising from sequential calls to SetClippingRegion are represented Since intersections arising from sequential calls to SetClippingRegion are represented
@@ -133,15 +95,20 @@ public:
//@{ //@{
/** /**
Functions not implemented in this DC class. Function not implemented in this DC class.
*/ */
void CrossHair(wxCoord x, wxCoord y); void CrossHair(wxCoord x, wxCoord y);
bool FloodFill(wxCoord x, wxCoord y, const wxColour& colour, bool FloodFill(wxCoord x, wxCoord y, const wxColour& colour,
wxFloodFillStyle style = wxFLOOD_SURFACE); wxFloodFillStyle style = wxFLOOD_SURFACE);
void GetClippingBox(wxCoord *x, wxCoord *y, wxCoord *width, wxCoord *height) const;
bool GetPixel(wxCoord x, wxCoord y, wxColour* colour) const; bool GetPixel(wxCoord x, wxCoord y, wxColour* colour) const;
void SetPalette(const wxPalette& palette); void SetPalette(const wxPalette& palette);
int GetDepth() const;
void SetLogicalFunction(wxRasterOperationMode function);
wxRasterOperationMode GetLogicalFunction() const;
bool StartDoc(const wxString& message); bool StartDoc(const wxString& message);
void EndDoc();
void StartPage();
void EndPage();
//@} //@}
}; };
@@ -203,9 +170,17 @@ public:
}; };
/** /**
Handler saving a bitmap to an external file and linking to it from the SVG. Handler saving bitmaps to external PNG files and linking to it from the
SVG.
This handler is used by default by wxSVGFileDC. This handler is used by default by wxSVGFileDC. PNG files are created in
the same folder as the SVG file and are named using the SVG filename
appended with ``_image#.png``.
When using wxSVGFileDC::SetBitmapHandler() to set this handler with the
default constructor, the PNG files are created in the runtime location of
the application. The save location can be customized by using the
wxSVGBitmapFileHandler(const wxFileName&) constructor.
@see wxSVGFileDC::SetBitmapHandler(). @see wxSVGFileDC::SetBitmapHandler().
@@ -217,6 +192,17 @@ public:
class wxSVGBitmapFileHandler : public wxSVGBitmapHandler class wxSVGBitmapFileHandler : public wxSVGBitmapHandler
{ {
public: public:
/**
Create a wxSVGBitmapFileHandler and specify the location where the file
will be saved.
@param path The path of the save location. If @a path contains a
filename, the autogenerated filename will be appended to this name.
@since 3.1.3
*/
wxSVGBitmapFileHandler(const wxFileName& path);
virtual bool ProcessBitmap(const wxBitmap& bitmap, virtual bool ProcessBitmap(const wxBitmap& bitmap,
wxCoord x, wxCoord y, wxCoord x, wxCoord y,
wxOutputStream& stream) const; wxOutputStream& stream) const;

View File

@@ -74,7 +74,7 @@ wxString Col2SVG(wxColour c, float *opacity)
wxString wxPenString(wxColour c, int style = wxPENSTYLE_SOLID) wxString wxPenString(wxColour c, int style = wxPENSTYLE_SOLID)
{ {
float opacity; float opacity;
wxString s = wxS("stroke:") + Col2SVG(c, &opacity) + wxS("; "); wxString s = wxS("stroke:") + Col2SVG(c, &opacity) + wxS("; ");
switch ( style ) switch ( style )
{ {
@@ -89,7 +89,7 @@ wxString wxPenString(wxColour c, int style = wxPENSTYLE_SOLID)
case wxPENSTYLE_TRANSPARENT: case wxPENSTYLE_TRANSPARENT:
s += wxS("stroke-opacity:0.0; "); s += wxS("stroke-opacity:0.0; ");
break; break;
default : default:
wxASSERT_MSG(false, wxS("wxSVGFileDC::Requested Pen Style not available")); wxASSERT_MSG(false, wxS("wxSVGFileDC::Requested Pen Style not available"));
} }
@@ -99,7 +99,7 @@ wxString wxPenString(wxColour c, int style = wxPENSTYLE_SOLID)
wxString wxBrushString(wxColour c, int style = wxBRUSHSTYLE_SOLID) wxString wxBrushString(wxColour c, int style = wxBRUSHSTYLE_SOLID)
{ {
float opacity; float opacity;
wxString s = wxS("fill:") + Col2SVG(c, &opacity) + wxS("; "); wxString s = wxS("fill:") + Col2SVG(c, &opacity) + wxS("; ");
switch ( style ) switch ( style )
{ {
@@ -114,7 +114,7 @@ wxString wxBrushString(wxColour c, int style = wxBRUSHSTYLE_SOLID)
case wxBRUSHSTYLE_TRANSPARENT: case wxBRUSHSTYLE_TRANSPARENT:
s += wxS("fill-opacity:0.0; "); s += wxS("fill-opacity:0.0; ");
break; break;
default : default:
wxASSERT_MSG(false, wxS("wxSVGFileDC::Requested Brush Style not available")); wxASSERT_MSG(false, wxS("wxSVGFileDC::Requested Brush Style not available"));
} }
@@ -335,28 +335,28 @@ wxSVGBitmapFileHandler::ProcessBitmap(const wxBitmap& bmp,
wxImage::AddHandler(new wxPNGHandler); wxImage::AddHandler(new wxPNGHandler);
// find a suitable file name // find a suitable file name
wxString sPNG; wxFileName sPNG = m_path;
do do
{ {
sPNG = wxString::Format("image%d.png", sub_images++); sPNG.SetFullName(wxString::Format("%s%simage%d.png",
sPNG.GetName(),
sPNG.GetName().IsEmpty() ? "" : "_",
sub_images++));
} }
while (wxFile::Exists(sPNG)); while ( sPNG.FileExists() );
if ( !bmp.SaveFile(sPNG, wxBITMAP_TYPE_PNG) ) if ( !bmp.SaveFile(sPNG.GetFullPath(), wxBITMAP_TYPE_PNG) )
return false; return false;
// reference the bitmap from the SVG doc using only filename & ext
sPNG = sPNG.AfterLast(wxFileName::GetPathSeparator());
// reference the bitmap from the SVG doc // reference the bitmap from the SVG doc
wxString s; wxString s;
s += wxString::Format(" <image x=\"%d\" y=\"%d\" width=\"%dpx\" height=\"%dpx\"", s += wxString::Format(" <image x=\"%d\" y=\"%d\" width=\"%dpx\" height=\"%dpx\"",
x, y, bmp.GetWidth(), bmp.GetHeight()); x, y, bmp.GetWidth(), bmp.GetHeight());
s += wxString::Format(" xlink:href=\"%s\"/>\n", sPNG); s += wxString::Format(" xlink:href=\"%s\"/>\n", sPNG.GetFullName());
// write to the SVG file // write to the SVG file
const wxCharBuffer buf = s.utf8_str(); const wxCharBuffer buf = s.utf8_str();
stream.Write(buf, strlen((const char *)buf)); stream.Write(buf, strlen((const char*)buf));
return stream.IsOk(); return stream.IsOk();
} }
@@ -403,13 +403,12 @@ void wxSVGFileDCImpl::Init(const wxString &filename, int Width, int Height,
m_textForegroundColour = *wxBLACK; m_textForegroundColour = *wxBLACK;
m_textBackgroundColour = *wxWHITE; m_textBackgroundColour = *wxWHITE;
m_pen = *wxBLACK_PEN; m_pen = *wxBLACK_PEN;
m_font = *wxNORMAL_FONT; m_font = *wxNORMAL_FONT;
m_brush = *wxWHITE_BRUSH; m_brush = *wxWHITE_BRUSH;
m_filename = filename; m_filename = filename;
m_graphics_changed = true; m_graphics_changed = true;
m_sub_images = 0;
////////////////////code here ////////////////////code here
@@ -420,7 +419,7 @@ void wxSVGFileDCImpl::Init(const wxString &filename, int Width, int Height,
s += wxS("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); s += wxS("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
s += wxS("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n\n"); s += wxS("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n\n");
s += wxS("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\""); s += wxS("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
s += wxString::Format(wxS(" width=\"%scm\" height=\"%scm\" viewBox=\"0 0 %d %d\">\n"), NumStr(float(Width) / dpi*2.54), NumStr(float(Height) / dpi*2.54), Width, Height); s += wxString::Format(wxS(" width=\"%scm\" height=\"%scm\" viewBox=\"0 0 %d %d\">\n"), NumStr(float(Width) / dpi * 2.54), NumStr(float(Height) / dpi * 2.54), Width, Height);
s += wxString::Format(wxS("<title>%s</title>\n"), title); s += wxString::Format(wxS("<title>%s</title>\n"), title);
s += wxString(wxS("<desc>Picture generated by wxSVG ")) + wxSVGVersion + wxS("</desc>\n\n"); s += wxString(wxS("<desc>Picture generated by wxSVG ")) + wxSVGVersion + wxS("</desc>\n\n");
s += wxS("<g style=\"fill:black; stroke:black; stroke-width:1\">\n"); s += wxS("<g style=\"fill:black; stroke:black; stroke-width:1\">\n");
@@ -538,11 +537,11 @@ void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoor
// wxS("upper left") and wxS("upper right") // wxS("upper left") and wxS("upper right")
CalcBoundingBox(x, y); CalcBoundingBox(x, y);
CalcBoundingBox((wxCoord)(x + w*cos(rad)), (wxCoord)(y - h*sin(rad))); CalcBoundingBox((wxCoord)(x + w * cos(rad)), (wxCoord)(y - h * sin(rad)));
// wxS("bottom left") and wxS("bottom right") // wxS("bottom left") and wxS("bottom right")
CalcBoundingBox((wxCoord)(x + h*sin(rad)), (wxCoord)(y + h*cos(rad))); CalcBoundingBox((wxCoord)(x + h * sin(rad)), (wxCoord)(y + h * cos(rad)));
CalcBoundingBox((wxCoord)(x + h*sin(rad) + w*cos(rad)), (wxCoord)(y + h*cos(rad) - w*sin(rad))); CalcBoundingBox((wxCoord)(x + h * sin(rad) + w * cos(rad)), (wxCoord)(y + h * cos(rad) - w * sin(rad)));
if (m_backgroundMode == wxBRUSHSTYLE_SOLID) if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
{ {
@@ -575,7 +574,7 @@ void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoor
else else
s += wxS("style=\" "); s += wxS("style=\" ");
wxString fontweight = wxString::Format(wxS("%d"),m_font.GetWeight()); wxString fontweight = wxString::Format(wxS("%d"), m_font.GetWeight());
s += wxS("font-weight:") + fontweight + wxS("; "); s += wxS("font-weight:") + fontweight + wxS("; ");
@@ -618,11 +617,11 @@ void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoor
s += wxBrushString(m_textForegroundColour) + wxPenString(m_textForegroundColour); s += wxBrushString(m_textForegroundColour) + wxPenString(m_textForegroundColour);
s += wxString::Format(wxS("stroke-width:0;\" transform=\"rotate(%s %d %d)\""), NumStr(-angle), xx, yy); s += wxString::Format(wxS("stroke-width:0;\" transform=\"rotate(%s %d %d)\""), NumStr(-angle), xx, yy);
s += wxS(" xml:space=\"preserve\">"); s += wxS(" xml:space=\"preserve\">");
#if wxUSE_MARKUP #if wxUSE_MARKUP
s += wxMarkupParser::Quote(lines[lineNum]) + wxS("</text>\n"); s += wxMarkupParser::Quote(lines[lineNum]) + wxS("</text>\n");
#else #else
s += lines[lineNum] + wxS("</text>\n"); s += lines[lineNum] + wxS("</text>\n");
#endif #endif
write(s); write(s);
} }
@@ -746,11 +745,11 @@ void wxSVGFileDCImpl::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
wxString s; wxString s;
// we need the radius of the circle which has two estimates // we need the radius of the circle which has two estimates
double r1 = sqrt ( double( (x1-xc)*(x1-xc) ) + double( (y1-yc)*(y1-yc) ) ); double r1 = sqrt( double( (x1 - xc)*(x1 - xc) ) + double( (y1 - yc)*(y1 - yc) ) );
double r2 = sqrt ( double( (x2-xc)*(x2-xc) ) + double( (y2-yc)*(y2-yc) ) ); double r2 = sqrt( double( (x2 - xc)*(x2 - xc) ) + double( (y2 - yc)*(y2 - yc) ) );
wxASSERT_MSG( (fabs ( r2-r1 ) <= 3), wxS("wxSVGFileDC::DoDrawArc Error in getting radii of circle")); wxASSERT_MSG((fabs( r2 - r1 ) <= 3), wxS("wxSVGFileDC::DoDrawArc Error in getting radii of circle"));
if ( fabs ( r2-r1 ) > 3 ) //pixels if ( fabs( r2 - r1 ) > 3 ) //pixels
{ {
s = wxS("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle -->\n"); s = wxS("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle -->\n");
write(s); write(s);
@@ -822,10 +821,10 @@ void wxSVGFileDCImpl::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord
// start and end coords // start and end coords
double xs, ys, xe, ye; double xs, ys, xe, ye;
xs = xc + rx * cos (wxDegToRad(sa)); xs = xc + rx * cos(wxDegToRad(sa));
xe = xc + rx * cos (wxDegToRad(ea)); xe = xc + rx * cos(wxDegToRad(ea));
ys = yc - ry * sin (wxDegToRad(sa)); ys = yc - ry * sin(wxDegToRad(sa));
ye = yc - ry * sin (wxDegToRad(ea)); ye = yc - ry * sin(wxDegToRad(ea));
// svg arcs have 0 degrees at 12-o'clock instead of 3-o'clock // svg arcs have 0 degrees at 12-o'clock instead of 3-o'clock
double start = (sa - 90); double start = (sa - 90);
@@ -1004,8 +1003,6 @@ void wxSVGFileDCImpl::SetBrush(const wxBrush& brush)
void wxSVGFileDCImpl::SetPen(const wxPen& pen) void wxSVGFileDCImpl::SetPen(const wxPen& pen)
{ {
// width, color, ends, joins : currently implemented
// dashes, stipple : not implemented
m_pen = pen; m_pen = pen;
m_graphics_changed = true; m_graphics_changed = true;
@@ -1028,40 +1025,40 @@ void wxSVGFileDCImpl::DoStartNewGraphics()
wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast; wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast;
sBrush = wxS("<g style=\"") + wxBrushString(m_brush.GetColour(), m_brush.GetStyle()) sBrush = wxS("<g style=\"") + wxBrushString(m_brush.GetColour(), m_brush.GetStyle())
+ wxPenString(m_pen.GetColour(), m_pen.GetStyle()); + wxPenString(m_pen.GetColour(), m_pen.GetStyle());
switch ( m_pen.GetCap() ) switch ( m_pen.GetCap() )
{ {
case wxCAP_PROJECTING : case wxCAP_PROJECTING:
sPenCap = wxS("stroke-linecap:square; "); sPenCap = wxS("stroke-linecap:square; ");
break; break;
case wxCAP_BUTT : case wxCAP_BUTT:
sPenCap = wxS("stroke-linecap:butt; "); sPenCap = wxS("stroke-linecap:butt; ");
break; break;
case wxCAP_ROUND : case wxCAP_ROUND:
default : default:
sPenCap = wxS("stroke-linecap:round; "); sPenCap = wxS("stroke-linecap:round; ");
} }
switch ( m_pen.GetJoin() ) switch (m_pen.GetJoin())
{ {
case wxJOIN_BEVEL : case wxJOIN_BEVEL:
sPenJoin = wxS("stroke-linejoin:bevel; "); sPenJoin = wxS("stroke-linejoin:bevel; ");
break; break;
case wxJOIN_MITER : case wxJOIN_MITER:
sPenJoin = wxS("stroke-linejoin:miter; "); sPenJoin = wxS("stroke-linejoin:miter; ");
break; break;
case wxJOIN_ROUND : case wxJOIN_ROUND:
default : default:
sPenJoin = wxS("stroke-linejoin:round; "); sPenJoin = wxS("stroke-linejoin:round; ");
} }
sLast = wxString::Format(wxS("stroke-width:%d\" transform=\"translate(%s %s) scale(%s %s)\">"), sLast = wxString::Format(wxS("stroke-width:%d\" transform=\"translate(%s %s) scale(%s %s)\">"),
m_pen.GetWidth(), m_pen.GetWidth(),
NumStr((m_deviceOriginX - m_logicalOriginX)* m_signX), NumStr((m_deviceOriginX - m_logicalOriginX)* m_signX),
NumStr((m_deviceOriginY - m_logicalOriginY)* m_signY), NumStr((m_deviceOriginY - m_logicalOriginY)* m_signY),
NumStr(m_scaleX * m_signX), NumStr(m_scaleX * m_signX),
NumStr(m_scaleY * m_signY)); NumStr(m_scaleY * m_signY));
s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + wxS("\n"); s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + wxS("\n");
write(s); write(s);
@@ -1074,9 +1071,9 @@ void wxSVGFileDCImpl::SetFont(const wxFont& font)
// export a bitmap as a raster image in png // export a bitmap as a raster image in png
bool wxSVGFileDCImpl::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, bool wxSVGFileDCImpl::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
wxDC* source, wxCoord xsrc, wxCoord ysrc, wxDC* source, wxCoord xsrc, wxCoord ysrc,
wxRasterOperationMode logicalFunc /*= wxCOPY*/, bool useMask /*= false*/, wxRasterOperationMode logicalFunc /*= wxCOPY*/, bool useMask /*= false*/,
wxCoord /*xsrcMask = -1*/, wxCoord /*ysrcMask = -1*/) wxCoord /*xsrcMask = -1*/, wxCoord /*ysrcMask = -1*/)
{ {
if (logicalFunc != wxCOPY) if (logicalFunc != wxCOPY)
{ {
@@ -1107,13 +1104,13 @@ void wxSVGFileDCImpl::DoDrawIcon(const class wxIcon & myIcon, wxCoord x, wxCoord
DoDrawBitmap(myBitmap, x, y); DoDrawBitmap(myBitmap, x, y);
} }
void wxSVGFileDCImpl::DoDrawBitmap(const class wxBitmap & bmp, wxCoord x, wxCoord y, bool WXUNUSED(bTransparent) /*=0*/) void wxSVGFileDCImpl::DoDrawBitmap(const class wxBitmap & bmp, wxCoord x, wxCoord y, bool WXUNUSED(bTransparent) /*=0*/)
{ {
NewGraphicsIfNeeded(); NewGraphicsIfNeeded();
// If we don't have any bitmap handler yet, use the default one. // If we don't have any bitmap handler yet, use the default one.
if ( !m_bmp_handler ) if ( !m_bmp_handler )
m_bmp_handler.reset(new wxSVGBitmapFileHandler()); m_bmp_handler.reset(new wxSVGBitmapFileHandler(m_filename));
m_bmp_handler->ProcessBitmap(bmp, x, y, *m_outfile); m_bmp_handler->ProcessBitmap(bmp, x, y, *m_outfile);
} }