📄 dcsvg.cpp
字号:
//radius
double rx = w / 2 ;
double ry = h / 2 ;
// center
double xc = x + rx ;
double yc = y + ry ;
double xs, ys, xe, ye ;
xs = xc + rx * cos (DegToRad(sa)) ;
xe = xc + rx * cos (DegToRad(ea)) ;
ys = yc - ry * sin (DegToRad(sa)) ;
ye = yc - ry * sin (DegToRad(ea)) ;
///now same as circle arc...
double theta1 = atan2(ys-yc, xs-xc);
double theta2 = atan2(ye-yc, xe-xc);
int fArc ; // flag for large or small arc 0 means less than 180 degrees
if ( (theta2 - theta1) > 0 ) fArc = 1; else fArc = 0 ;
int fSweep ;
if ( fabs(theta2 - theta1) > M_PI) fSweep = 1; else fSweep = 0 ;
s.Printf ( wxT("<path d=\"M%d %d A%d %d 0.0 %d %d %d %d L %d %d z "),
int(xs), int(ys), int(rx), int(ry),
fArc, fSweep, int(xe), int(ye), int(xc), int(yc) );
s = s + wxT(" \" /> ") + newline ;
if (m_OK)
{
write(s);
}
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawEllipticArc Call executed")) ;
}
void wxSVGFileDC::DoGetTextExtent(const wxString& string, wxCoord *w, wxCoord *h, wxCoord *descent , wxCoord *externalLeading , wxFont *font) const
{
wxScreenDC sDC ;
sDC.SetFont (m_font);
if ( font != NULL ) sDC.SetFont ( *font );
sDC.GetTextExtent(string, w, h, descent, externalLeading );
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::GetTextExtent Call executed")) ;
}
wxCoord wxSVGFileDC::GetCharHeight() const
{
wxScreenDC sDC ;
sDC.SetFont (m_font);
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::GetCharHeight Call executing")) ;
return ( sDC.GetCharHeight() );
}
wxCoord wxSVGFileDC::GetCharWidth() const
{
wxScreenDC sDC ;
sDC.SetFont (m_font);
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::GetCharWidth Call executing")) ;
return ( sDC.GetCharWidth() ) ;
}
/// Set Functions /////////////////////////////////////////////////////////////////
void wxSVGFileDC::SetBackground( const wxBrush &brush )
{
m_backgroundBrush = brush;
return;
}
void wxSVGFileDC::SetBackgroundMode( int mode )
{
m_backgroundMode = mode;
return;
}
void wxSVGFileDC::SetBrush(const wxBrush& brush)
{
m_brush = brush ;
m_graphics_changed = TRUE ;
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetBrush Call executed")) ;
}
void wxSVGFileDC::SetPen(const wxPen& pen)
{
// width, color, ends, joins : currently implemented
// dashes, stipple : not implemented
m_pen = pen ;
m_graphics_changed = TRUE ;
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetPen Call executed")) ;
}
void wxSVGFileDC::NewGraphics ()
{
int w = m_pen.GetWidth ();
wxColour c = m_pen.GetColour () ;
wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast, sWarn;
sBrush = wxT("</g>\n<g style=\"") + wxBrushString ( m_brush.GetColour (), m_brush.GetStyle () )
+ wxT(" stroke:#") + wxColStr (c) + wxT("; ") ;
switch ( m_pen.GetCap () )
{
case wxCAP_PROJECTING :
sPenCap = wxT("stroke-linecap:square; ") ;
break ;
case wxCAP_BUTT :
sPenCap = wxT("stroke-linecap:butt; ") ;
break ;
case wxCAP_ROUND :
default :
sPenCap = wxT("stroke-linecap:round; ") ;
};
switch ( m_pen.GetJoin () )
{
case wxJOIN_BEVEL :
sPenJoin = wxT("stroke-linejoin:bevel; ") ;
break ;
case wxJOIN_MITER :
sPenJoin = wxT("stroke-linejoin:miter; ") ;
break ;
case wxJOIN_ROUND :
default :
sPenJoin = wxT("stroke-linejoin:round; ") ;
};
switch ( m_pen.GetStyle () )
{
case wxSOLID :
sPenStyle = wxT("stroke-opacity:1.0; stroke-opacity:1.0; ") ;
break ;
case wxTRANSPARENT :
sPenStyle = wxT("stroke-opacity:0.0; stroke-opacity:0.0; ") ;
break ;
default :
wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::SetPen Call called to set a Style which is not available")) ;
sWarn = sWarn + wxT("<!--- wxSVGFileDC::SetPen Call called to set a Style which is not available --> \n") ;
}
sLast.Printf ( wxT("stroke-width:%d\" \n transform=\"translate(%.2g %.2g) scale(%.2g %.2g)\">"),
w, m_OriginX, m_OriginY, m_scaleX, m_scaleY );
s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + newline + sWarn;
write(s);
m_graphics_changed = FALSE ;
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::NewGraphics Call executed")) ;
}
void wxSVGFileDC::SetFont(const wxFont& font)
{
m_font = font ;
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::SetFont Call executed")) ;
}
void wxSVGFileDC::ComputeScaleAndOrigin()
{
m_scaleX = m_logicalScaleX * m_userScaleX;
m_scaleY = m_logicalScaleY * m_userScaleY;
m_OriginX = m_logicalOriginX * m_logicalScaleX + m_deviceOriginX ;
m_OriginY = m_logicalOriginY * m_logicalScaleY + m_deviceOriginY ;
m_graphics_changed = TRUE;
}
int wxSVGFileDC::GetMapMode()
{
return m_mappingMode ;
}
void wxSVGFileDC::SetMapMode( int mode )
{
switch (mode)
{
case wxMM_TWIPS:
SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
break;
case wxMM_POINTS:
SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
break;
case wxMM_METRIC:
SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
break;
case wxMM_LOMETRIC:
SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
break;
default:
case wxMM_TEXT:
SetLogicalScale( 1.0, 1.0 );
break;
}
m_mappingMode = mode;
/* we don't do this mega optimisation
if (mode != wxMM_TEXT)
{
m_needComputeScaleX = TRUE;
m_needComputeScaleY = TRUE;
}
*/
}
void wxSVGFileDC::GetUserScale(double *x, double *y) const
{
*x = m_userScaleX ;
*y = m_userScaleY ;
}
void wxSVGFileDC::SetUserScale( double x, double y )
{
// allow negative ? -> no
m_userScaleX = x;
m_userScaleY = y;
ComputeScaleAndOrigin();
}
void wxSVGFileDC::SetLogicalScale( double x, double y )
{
// allow negative ?
m_logicalScaleX = x;
m_logicalScaleY = y;
ComputeScaleAndOrigin();
}
void wxSVGFileDC::SetLogicalOrigin( wxCoord x, wxCoord y )
{
// is this still correct ?
m_logicalOriginX = x * m_signX;
m_logicalOriginY = y * m_signY;
ComputeScaleAndOrigin();
}
void wxSVGFileDC::SetDeviceOrigin( wxCoord x, wxCoord y )
{
// only wxPostScripDC has m_signX = -1,
m_deviceOriginX = x;
m_deviceOriginY = y;
ComputeScaleAndOrigin();
}
void wxSVGFileDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
{
// only wxPostScripDC has m_signX = -1,
m_signX = (xLeftRight ? 1 : -1);
m_signY = (yBottomUp ? -1 : 1);
ComputeScaleAndOrigin();
}
// export a bitmap as a raster image in png
bool wxSVGFileDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
wxDC* source, wxCoord xsrc, wxCoord ysrc,
int logicalFunc /*= wxCOPY*/, bool useMask /*= FALSE*/,
wxCoord /*xsrcMask = -1*/, wxCoord /*ysrcMask = -1*/)
{
if (logicalFunc != wxCOPY)
{
wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::DoBlit Call requested nonCopy mode; this is not possible")) ;
return FALSE ;
}
if (useMask != FALSE)
{
wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::DoBlit Call requested False mask ; this is not possible")) ;
return FALSE ;
}
wxBitmap myBitmap (width, height) ;
wxMemoryDC memDC;
memDC.SelectObject( myBitmap );
memDC.Blit(0, 0, width, height, source, xsrc, ysrc);
memDC.SelectObject( wxNullBitmap );
DoDrawBitmap(myBitmap, xdest, ydest);
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoBlit Call executed")) ;
return FALSE ;
}
void wxSVGFileDC::DoDrawIcon(const class wxIcon & myIcon, wxCoord x, wxCoord y)
{
wxBitmap myBitmap (myIcon.GetWidth(), myIcon.GetHeight() ) ;
wxMemoryDC memDC;
memDC.SelectObject( myBitmap );
memDC.DrawIcon(myIcon,0,0);
memDC.SelectObject( wxNullBitmap );
DoDrawBitmap(myBitmap, x, y);
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawIcon Call executed")) ;
return ;
}
void wxSVGFileDC::DoDrawBitmap(const class wxBitmap & bmp, wxCoord x, wxCoord y , bool WXUNUSED(bTransparent) /*=0*/ )
{
if (m_graphics_changed) NewGraphics ();
wxString sTmp, s, sPNG ;
wxImage::AddHandler(new wxPNGHandler);
// create suitable file name
sTmp.Printf ( wxT("_image%d.png"), m_sub_images);
sPNG = m_filename.BeforeLast(wxT('.')) + sTmp;
while (wxFile::Exists(sPNG) )
{
m_sub_images ++ ;
sTmp.Printf ( wxT("_image%d.png"), m_sub_images);
sPNG = m_filename.BeforeLast(wxT('.')) + sTmp;
}
//create copy of bitmap (wxGTK doesn't like saving a constant bitmap)
wxBitmap myBitmap = bmp ;
//save it
bool bPNG_OK = myBitmap.SaveFile(sPNG,wxBITMAP_TYPE_PNG);
// refrence the bitmap from the SVG doc
int w = myBitmap.GetWidth();
int h = myBitmap.GetHeight();
sTmp.Printf ( wxT(" <image x=\"%d\" y=\"%d\" width=\"%dpx\" height=\"%dpx\" "), x,y,w,h );
s = s + sTmp ;
sTmp.Printf ( wxT(" xlink:href=\"%s\"> \n"), sPNG.c_str() );
s = s + sTmp + wxT("<title>Image from wxSVG</title> </image>") + newline;
if (m_OK && bPNG_OK)
{
write(s);
}
m_OK = m_outfile->Ok () && bPNG_OK;
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawBitmap Call executed")) ;
return ;
}
// ---------------------------------------------------------------------------
// coordinates transformations
// ---------------------------------------------------------------------------
wxCoord wxSVGFileDC::DeviceToLogicalX(wxCoord x) const
{
return XDEV2LOG(x);
}
wxCoord wxSVGFileDC::DeviceToLogicalY(wxCoord y) const
{
return YDEV2LOG(y);
}
wxCoord wxSVGFileDC::DeviceToLogicalXRel(wxCoord x) const
{
return XDEV2LOGREL(x);
}
wxCoord wxSVGFileDC::DeviceToLogicalYRel(wxCoord y) const
{
return YDEV2LOGREL(y);
}
wxCoord wxSVGFileDC::LogicalToDeviceX(wxCoord x) const
{
return XLOG2DEV(x);
}
wxCoord wxSVGFileDC::LogicalToDeviceY(wxCoord y) const
{
return YLOG2DEV(y);
}
wxCoord wxSVGFileDC::LogicalToDeviceXRel(wxCoord x) const
{
return XLOG2DEVREL(x);
}
wxCoord wxSVGFileDC::LogicalToDeviceYRel(wxCoord y) const
{
return YLOG2DEVREL(y);
}
void wxSVGFileDC::write(const wxString &s)
{
const wxWX2MBbuf buf = s.mb_str(wxConvUTF8);
m_outfile->Write(buf, strlen((const char *)buf));
m_OK = m_outfile->Ok();
}
#ifdef __BORLANDC__
#pragma warn .rch
#pragma warn .ccc
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -