#ifndef __KICAD_DCSVG_H #define __KICAD_DCSVG_H #include #include #include #define wxSVGVersion wxT( "v0101" ) #if wxCHECK_VERSION( 2, 9, 0 ) // We could do nothing, because wxWidgets 3 supports the SVG format // (previously, it was a contribution library, not included in wxWidgets) // However arcs are drawn as pies, and we must change it. // Unfortunately most of functions are private, and we cannot derive // our KicadSVGFileDCImpl from wxSVGFileDCImpl // and just override the 2 incorrect functions // Just wxWidget dcsvg is copied here and 2 functions are modified: // KicadSVGFileDCImpl::DoDrawArc() and KicadSVGFileDCImpl::DoDrawEllipticArc() // Also note: SetLogicalFunction() does not set an error in debug mode class WXDLLIMPEXP_FWD_BASE wxFileOutputStream; class WXDLLIMPEXP_FWD_CORE KicadSVGFileDC; class WXDLLIMPEXP_CORE KicadSVGFileDCImpl : public wxDCImpl { public: KicadSVGFileDCImpl( KicadSVGFileDC *owner, const wxString &aFilename, wxPoint aOrigin, wxSize aSize, double aDpi ); virtual ~KicadSVGFileDCImpl(); bool IsOk() const { return m_OK; } virtual bool CanDrawBitmap() const { return true; } virtual bool CanGetTextExtent() const { return true; } virtual int GetDepth() const { wxFAIL_MSG(wxT("wxSVGFILEDC::GetDepth Call not implemented")); return -1; } virtual void Clear() { wxFAIL_MSG(wxT("wxSVGFILEDC::Clear() Call not implemented \nNot sensible for an output file?")); } virtual void DestroyClippingRegion() { wxFAIL_MSG(wxT("wxSVGFILEDC::void Call not yet implemented")); } virtual wxCoord GetCharHeight() const; virtual wxCoord GetCharWidth() const; virtual void SetClippingRegion(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxCoord WXUNUSED(w), wxCoord WXUNUSED(h)) { wxFAIL_MSG(wxT("wxSVGFILEDC::SetClippingRegion not implemented")); } virtual void SetPalette(const wxPalette& WXUNUSED(palette)) { wxFAIL_MSG(wxT("wxSVGFILEDC::SetPalette not implemented")); } virtual void GetClippingBox(wxCoord *WXUNUSED(x), wxCoord *WXUNUSED(y), wxCoord *WXUNUSED(w), wxCoord *WXUNUSED(h)) { wxFAIL_MSG(wxT("wxSVGFILEDC::GetClippingBox not implemented")); } virtual void SetLogicalFunction(wxRasterOperationMode WXUNUSED(function)) { // wxFAIL_MSG(wxT("KicadSVGFILEDC::SetLogicalFunction not implemented")); } virtual wxRasterOperationMode GetLogicalFunction() const { wxFAIL_MSG(wxT("wxSVGFILEDC::GetLogicalFunction() not implemented")); return wxCOPY; } virtual void SetBackground( const wxBrush &brush ); virtual void SetBackgroundMode( int mode ); virtual void SetBrush(const wxBrush& brush); virtual void SetFont(const wxFont& font); virtual void SetPen(const wxPen& pen); private: virtual bool DoGetPixel(wxCoord, wxCoord, wxColour *) const { wxFAIL_MSG(wxT("wxSVGFILEDC::DoGetPixel Call not implemented")); return true; } virtual bool DoBlit(wxCoord, wxCoord, wxCoord, wxCoord, wxDC *, wxCoord, wxCoord, wxRasterOperationMode = wxCOPY, bool = 0, int = -1, int = -1); virtual void DoCrossHair(wxCoord, wxCoord) { wxFAIL_MSG(wxT("wxSVGFILEDC::CrossHair Call not implemented")); } virtual void DoDrawArc(wxCoord, wxCoord, wxCoord, wxCoord, wxCoord, wxCoord); virtual void DoDrawBitmap(const wxBitmap &, wxCoord, wxCoord, bool = false); virtual void DoDrawCheckMark(wxCoord x, wxCoord y, wxCoord w, wxCoord h); virtual void DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h); virtual void DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea); virtual void DoDrawIcon(const wxIcon &, wxCoord, wxCoord); virtual void DoDrawLine (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2); virtual void DoDrawLines(int n, wxPoint points[], wxCoord xoffset = 0, wxCoord yoffset = 0); virtual void DoDrawPoint(wxCoord, wxCoord); virtual void DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, wxPolygonFillMode fillStyle); virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h); virtual void DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle); virtual void DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double radius = 20) ; virtual void DoDrawText(const wxString& text, wxCoord x, wxCoord y); virtual bool DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxColour& WXUNUSED(col), wxFloodFillStyle WXUNUSED(style) = wxFLOOD_SURFACE) { wxFAIL_MSG(wxT("wxSVGFILEDC::DoFloodFill Call not implemented")); return false; } virtual void DoGetSize(int * x, int *y) const { if ( x ) *x = m_width; if ( y ) *y = m_height; } virtual void DoGetTextExtent(const wxString& string, wxCoord *w, wxCoord *h, wxCoord *descent = NULL, wxCoord *externalLeading = NULL, const wxFont *font = NULL) const; virtual void DoSetDeviceClippingRegion(const wxRegion& WXUNUSED(region)) { wxFAIL_MSG(wxT("wxSVGFILEDC::DoSetDeviceClippingRegion not yet implemented")); } virtual void DoSetClippingRegion( int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) ) { wxFAIL_MSG(wxT("wxSVGFILEDC::DoSetClippingRegion not yet implemented")); } virtual void DoGetSizeMM( int *width, int *height ) const; virtual wxSize GetPPI() const; void Init (const wxString &aFilename, wxPoint aOrigin, wxSize aSize, double aDpi); void NewGraphics(); void write( const wxString &s ); private: wxFileOutputStream *m_outfile; wxString m_filename; int m_sub_images; // number of png format images we have bool m_OK; bool m_graphics_changed; int m_width, m_height; double m_dpi; private: DECLARE_ABSTRACT_CLASS(KicadSVGFileDCImpl) }; class WXDLLIMPEXP_CORE KicadSVGFileDC : public wxDC { public: KicadSVGFileDC(const wxString& aFilename, wxPoint aOrigin, wxSize aSize, double aDpi = 300.0) : wxDC(new KicadSVGFileDCImpl(this, aFilename, aOrigin, aSize, aDpi)) { } }; #else class wxSVGFileDC : public wxDC { private: wxFileOutputStream* m_outfile; wxString m_filename; //holds number of png format images we have int m_sub_images; bool m_OK, m_graphics_changed; int m_width, m_height; double m_logicalScaleX, m_logicalScaleY, m_userScaleX, m_userScaleY, m_scaleX, m_scaleY, m_OriginX, m_OriginY, m_mm_to_pix_x, m_mm_to_pix_y; bool m_needComputeScaleX, m_needComputeScaleY; // not yet used bool DoGetPixel( wxCoord, wxCoord, class wxColour* ) const { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::DoGetPixel Call not implemented" ) ); return true; }; virtual bool DoBlit( wxCoord, wxCoord, wxCoord, wxCoord, class wxDC*, wxCoord, wxCoord, int = wxCOPY, bool = 0, int = -1, int = -1 ); void DoCrossHair( wxCoord, wxCoord ) { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::CrossHair Call not implemented" ) ); return; }; void DoDrawArc( wxCoord, wxCoord, wxCoord, wxCoord, wxCoord, wxCoord ); void DoDrawBitmap( const class wxBitmap&, wxCoord, wxCoord, bool = 0 ); void DoDrawCheckMark( wxCoord x, wxCoord y, wxCoord width, wxCoord height ); void DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ); void DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea ); void DoDrawIcon( const class wxIcon&, wxCoord, wxCoord ); void DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ); void DoDrawPoint( wxCoord, wxCoord ); void DoDrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle ); void DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height ); void DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord y, double angle ); void DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius = 20 ); void DoDrawText( const wxString& text, wxCoord x, wxCoord y ); bool DoFloodFill( wxCoord WXUNUSED (x), wxCoord WXUNUSED (y), const wxColour& WXUNUSED (col), int WXUNUSED (style) = wxFLOOD_SURFACE ) { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::DoFloodFill Call not implemented" ) ); return false; }; void DoGetSize( int* x, int* y ) const { *x = m_width; *y = m_height; return; }; void DoGetTextExtent( const wxString& string, wxCoord* w, wxCoord* h, wxCoord* descent = NULL, wxCoord* externalLeading = NULL, wxFont* font = NULL ) const; void DoSetClippingRegionAsRegion( const class wxRegion& ) { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::DoSetClippingRegionAsRegion Call not yet implemented" ) ); return; }; void Init( const wxString& aFilename, wxPoint aOrigin, wxSize aSize, double aDpi ); void NewGraphics(); #ifdef XDEV2LOG #undef XDEV2LOG #endif wxCoord XDEV2LOG( wxCoord x ) const { wxCoord new_x = x - m_deviceOriginX; if( new_x > 0 ) return (wxCoord) ( (double) (new_x) / m_scaleX + 0.5 ) * m_signX + m_logicalOriginX; else return (wxCoord) ( (double) (new_x) / m_scaleX - 0.5 ) * m_signX + m_logicalOriginX; } #ifdef XDEV2LOGREL #undef XDEV2LOGREL #endif wxCoord XDEV2LOGREL( wxCoord x ) const { if( x > 0 ) return (wxCoord) ( (double) (x) / m_scaleX + 0.5 ); else return (wxCoord) ( (double) (x) / m_scaleX - 0.5 ); } #ifdef YDEV2LOG #undef YDEV2LOG #endif wxCoord YDEV2LOG( wxCoord y ) const { wxCoord new_y = y - m_deviceOriginY; if( new_y > 0 ) return (wxCoord) ( (double) (new_y) / m_scaleY + 0.5 ) * m_signY + m_logicalOriginY; else return (wxCoord) ( (double) (new_y) / m_scaleY - 0.5 ) * m_signY + m_logicalOriginY; } #ifdef YDEV2LOGREL #undef YDEV2LOGREL #endif wxCoord YDEV2LOGREL( wxCoord y ) const { if( y > 0 ) return (wxCoord) ( (double) (y) / m_scaleY + 0.5 ); else return (wxCoord) ( (double) (y) / m_scaleY - 0.5 ); } #ifdef XLOG2DEV #undef XLOG2DEV #endif wxCoord XLOG2DEV( wxCoord x ) const { wxCoord new_x = x - m_logicalOriginX; if( new_x > 0 ) return (wxCoord) ( (double) (new_x) * m_scaleX + 0.5 ) * m_signX + m_deviceOriginX; else return (wxCoord) ( (double) (new_x) * m_scaleX - 0.5 ) * m_signX + m_deviceOriginX; } #ifdef XLOG2DEVREL #undef XLOG2DEVREL #endif wxCoord XLOG2DEVREL( wxCoord x ) const { if( x > 0 ) return (wxCoord) ( (double) (x) * m_scaleX + 0.5 ); else return (wxCoord) ( (double) (x) * m_scaleX - 0.5 ); } #ifdef YLOG2DEV #undef YLOG2DEV #endif wxCoord YLOG2DEV( wxCoord y ) const { wxCoord new_y = y - m_logicalOriginY; if( new_y > 0 ) return (wxCoord) ( (double) (new_y) * m_scaleY + 0.5 ) * m_signY + m_deviceOriginY; else return (wxCoord) ( (double) (new_y) * m_scaleY - 0.5 ) * m_signY + m_deviceOriginY; } #ifdef YLOG2DEVREL #undef YLOG2DEVREL #endif wxCoord YLOG2DEVREL( wxCoord y ) const { if( y > 0 ) return (wxCoord) ( (double) (y) * m_scaleY + 0.5 ); else return (wxCoord) ( (double) (y) * m_scaleY - 0.5 ); } void write( const wxString& s ); public: wxSVGFileDC( const wxString& aFilename, wxPoint aOrigin, wxSize aSize, double aDpi ); ~wxSVGFileDC(); bool CanDrawBitmap() const { return true; }; bool CanGetTextExtent() const { return true; }; int GetDepth() const { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::GetDepth Call not implemented" ) ); return -1; }; void BeginDrawing() { return; }; bool Blit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC* source, wxCoord xsrc, wxCoord ysrc, int logicalFunc = wxCOPY, bool useMask = false ) { return DoBlit( xdest, ydest, width, height, source, xsrc, ysrc, logicalFunc, useMask ); }; void Clear() { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::Clear() Call not implemented \nNot sensible for an output file?" ) ); return; }; void CrossHair( wxCoord x, wxCoord y ) { DoCrossHair( x, y ); return; }; virtual void ComputeScaleAndOrigin(); void DestroyClippingRegion() { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::void Call not yet implemented" ) ); return; }; wxCoord DeviceToLogicalX( wxCoord x ) const; wxCoord DeviceToLogicalXRel( wxCoord x ) const; wxCoord DeviceToLogicalY( wxCoord y ) const; wxCoord DeviceToLogicalYRel( wxCoord y ) const; void DrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool transparent ) { DoDrawBitmap( bitmap, x, y, transparent ); return; }; void DrawIcon( const wxIcon& icon, wxCoord x, wxCoord y ) { DoDrawIcon( icon, x, y ); return; }; void DoDrawLines( int n, wxPoint points[], wxCoord xoffset = 0, wxCoord yoffset = 0 ); void EndDoc() { return; }; void EndDrawing() { return; }; void EndPage() { return; }; void FloodFill( wxCoord x, wxCoord y, wxColour* colour, int style = wxFLOOD_SURFACE ) { DoFloodFill( x, y, *colour, style ); return; }; wxCoord GetCharHeight() const; wxCoord GetCharWidth() const; void GetClippingBox( wxCoord* WXUNUSED (x), wxCoord* WXUNUSED (y), wxCoord* WXUNUSED (width), wxCoord* WXUNUSED (height) ) { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::GetClippingBox Call not yet implemented" ) ); return; }; int GetLogicalFunction() { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::GetLogicalFunction() Call not implemented" ) ); return wxCOPY; }; int GetMapMode(); bool GetPixel( wxCoord x, wxCoord y, wxColour* colour ) { return DoGetPixel( x, y, colour ); }; void GetUserScale( double* x, double* y ) const; wxCoord LogicalToDeviceX( wxCoord x ) const; wxCoord LogicalToDeviceXRel( wxCoord x ) const; wxCoord LogicalToDeviceY( wxCoord y ) const; wxCoord LogicalToDeviceYRel( wxCoord y ) const; bool Ok() const { return m_OK; }; void SetAxisOrientation( bool xLeftRight, bool yBottomUp ); void SetClippingRegion( wxCoord WXUNUSED (x), wxCoord WXUNUSED (y), wxCoord WXUNUSED (width), wxCoord WXUNUSED (height) ) { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::SetClippingRegion Call not yet implemented" ) ); return; }; void SetPalette( const wxPalette& WXUNUSED (palette) ) { wxASSERT_MSG( false, wxT( "wxSVGFILEDC::SetPalette Call not yet implemented" ) ); return; }; void SetBackground( const wxBrush& brush ); void SetBackgroundMode( int mode ); void SetBrush( const wxBrush& brush ); void SetFont( const wxFont& font ); void SetLogicalFunction( int WXUNUSED (function) ) { //wxASSERT_MSG (false, wxT("wxSVGFILEDC::SetLogicalFunction not implemented")); return; }; void SetLogicalScale( double x, double y ); void SetLogicalOrigin( wxCoord x, wxCoord y ); void SetDeviceOrigin( wxCoord x, wxCoord y ); void SetMapMode( int anint ); void SetPen( const wxPen& pen ); void SetUserScale( double xScale, double yScale ); bool StartDoc( const wxString& WXUNUSED (message) ) { return false; }; void StartPage() { return; }; }; typedef wxSVGFileDC KicadSVGFileDC; #endif // wxCHECK_VERSION #endif // __KICAD_DCSVG_H