⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcsvg.cpp

📁 wxGTK 是 wxWidgets 的 linux GTK+ (>2.2.3)版本。wxWidgets 是一个跨平台的 GUI 框架
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        svg.cpp// Purpose:     SVG sample// Author:      Chris Elliott// Modified by:// RCS-ID:      $Id: dcsvg.cpp,v 1.7 2004/12/13 20:10:59 ABX Exp $// Licence:     wxWindows license/////////////////////////////////////////////////////////////////////////////// For compilers that support precompilation, includes "wx/wx.h".#include "wx/wxprec.h"#ifdef __BORLANDC__#pragma hdrstop#endif#ifndef WX_PRECOMP#include "wx/wx.h"#endif#include "wx/svg/dcsvg.h"#include "wx/image.h"#define wxSVG_DEBUG FALSE// or TRUE to see the calls being executed#define newline    wxString(wxT("\n"))#define space      wxString(wxT(" "))#define semicolon  wxString(wxT(";"))#define     wx_round(a)    (int)((a)+.5)#ifdef __BORLANDC__#pragma warn -rch#pragma warn -ccc#endifstatic inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; } ;wxString wxColStr ( wxColour c ){    unsigned char r, g, b ;    r = c.Red ();    g = c.Green ();    b = c. Blue ();    // possible Unicode bug here    wxString s = wxDecToHex(r) + wxDecToHex(g) + wxDecToHex(b) ;    return s ;}wxString wxBrushString ( wxColour c, int style ){    wxString s = wxT("fill:#") + wxColStr (c)  + semicolon + space ;    switch ( style )    {        case wxSOLID :            s = s + wxT("fill-opacity:1.0; ");            break ;        case wxTRANSPARENT:            s = s + wxT("fill-opacity:0.0; ");            break ;        default :            wxASSERT_MSG(FALSE, wxT("wxSVGFileDC::Requested Brush Style not available")) ;    }    s = s + newline ;    return s ;}void wxSVGFileDC::Init (wxString f, int Width, int Height, float dpi){    //set up things first  wxDCBase does all this?    m_width = Width ;    m_height = Height ;    m_clipping = FALSE;    m_OK = TRUE;    m_mm_to_pix_x = dpi/25.4;    m_mm_to_pix_y = dpi/25.4;    m_signX = m_signY = 1;    m_userScaleX = m_userScaleY =        m_deviceOriginX = m_deviceOriginY = 0;    m_OriginX = m_OriginY = 0;    m_logicalOriginX = m_logicalOriginY = 0;    m_logicalScaleX = m_logicalScaleY = 0 ;    m_scaleX = m_scaleY = 1.0 ;    m_logicalFunction = wxCOPY;    m_backgroundMode = wxTRANSPARENT;    m_mappingMode = wxMM_TEXT;    m_backgroundBrush = *wxTRANSPARENT_BRUSH;    m_textForegroundColour = *wxBLACK;    m_textBackgroundColour = *wxWHITE;    m_colour = wxColourDisplay();    m_pen   = *wxBLACK_PEN;    m_font  = *wxNORMAL_FONT;    m_brush = *wxWHITE_BRUSH;    m_graphics_changed = TRUE ;    ////////////////////code here    m_outfile = new wxFileOutputStream(f) ;    m_OK = m_outfile->Ok ();    if (m_OK)    {        m_filename = f ;        m_sub_images = 0 ;        wxString s ;        s = wxT("<?xml version=\"1.0\" standalone=\"no\"?>") ; s = s + newline ;        write(s);        s = wxT("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" ") + newline ;        write(s);        s = wxT("\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"> ")+ newline ;        write(s);        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 );        write(s);        s = wxT("<title>SVG Picture created as ") + wxFileNameFromPath(f) + wxT(" </title>") + newline ;        write(s);        s = wxString (wxT("<desc>Picture generated by wxSVG ")) + wxSVGVersion + wxT(" </desc>")+ newline ;        write(s);        s =  wxT("<g style=\"fill:black; stroke:black; stroke-width:1\">") + newline ;        write(s);    }}// constructorswxSVGFileDC::wxSVGFileDC (wxString f){    // quarter 640x480 screen display at 72 dpi    Init (f,320,240,72.0);};wxSVGFileDC::wxSVGFileDC (wxString f, int Width, int Height){    Init (f,Width,Height,72.0);};wxSVGFileDC::wxSVGFileDC (wxString f, int Width, int Height, float dpi){    Init (f,Width,Height,dpi);};wxSVGFileDC::~wxSVGFileDC(){    wxString s = wxT("</g> \n</svg> \n") ;    write(s);    delete m_outfile ;}//////////////////////////////////////////////////////////////////////////////////////////void wxSVGFileDC::DoDrawLine (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2){    if (m_graphics_changed) NewGraphics ();    wxString s ;    s.Printf ( wxT("<path d=\"M%d %d L%d %d\" /> \n"), x1,y1,x2,y2 );    if (m_OK)    {        write(s);    }    wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawLine Call executed")) ;    CalcBoundingBox(x1, y1) ;    CalcBoundingBox(x2, y2) ;    return;};void wxSVGFileDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset , wxCoord yoffset ){    for ( int i = 1; i < n ; i++ )    {        DoDrawLine ( points [i-1].x + xoffset, points [i-1].y + yoffset,            points [ i ].x + xoffset, points [ i ].y + yoffset ) ;    }}void wxSVGFileDC::DoDrawPoint (wxCoord x1, wxCoord y1){    wxString s;    if (m_graphics_changed) NewGraphics ();    s = wxT("<g style = \"stroke-linecap:round;\" > ") + newline ;    write(s);    DrawLine ( x1,y1,x1,y1 );    s = wxT("</g>");    write(s);}void wxSVGFileDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, wxCoord width, wxCoord height){    wxDCBase::DoDrawCheckMark (x1,y1,width,height) ;}void wxSVGFileDC::DoDrawText(const wxString& text, wxCoord x1, wxCoord y1){    DoDrawRotatedText(text, x1,y1,0.0);    wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawText Call executed")) ;}void wxSVGFileDC::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoord y, double angle){    //known bug; if the font is drawn in a scaled DC, it will not behave exactly as wxMSW    if (m_graphics_changed) NewGraphics ();    wxString s, sTmp;    // calculate bounding box    wxCoord w, h, desc ;    DoGetTextExtent(sText, &w, &h, &desc);    double rad = DegToRad(angle);    // wxT("upper left") and wxT("upper right")    CalcBoundingBox(x, y);    CalcBoundingBox((wxCoord)(x + w*cos(rad)), (wxCoord)(y - h*sin(rad)));    // wxT("bottom left") and wxT("bottom right")    x += (wxCoord)(h*sin(rad));    y += (wxCoord)(h*cos(rad));    CalcBoundingBox(x, y);    CalcBoundingBox((wxCoord)(x + h*sin(rad)), (wxCoord)(y + h*cos(rad)));    if (m_backgroundMode == wxSOLID)    {        // draw background first        // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background        wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background")) ;        sTmp.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"  "), x,y+desc-h, w, h );        s = sTmp + wxT("style=\"fill:#") + wxColStr (m_textBackgroundColour) + wxT("; ") ;        s = s + wxT("stroke-width:1; stroke:#") + wxColStr (m_textBackgroundColour) + wxT("; ") ;        sTmp.Printf ( wxT("\" transform=\"rotate( %.2g %d %d )  \">"), -angle, x,y ) ;        s = s + sTmp + newline ;        write(s);    }    //now do the text itself    s.Printf (wxT(" <text x=\"%d\" y=\"%d\" "),x,y );    sTmp = m_font.GetFaceName () ;    if (sTmp.Len () > 0)  s = s + wxT("style=\"font-family:") + sTmp + wxT("; ");    else s = s + wxT("style=\" ") ;    wxString fontweights [3] = { wxT("normal"), wxT("lighter"), wxT("bold") };    s = s + wxT("font-weight:") + fontweights[m_font.GetWeight() - wxNORMAL] + semicolon + space;    wxString fontstyles [5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };    s = s + wxT("font-style:") + fontstyles[m_font.GetStyle() - wxNORMAL] + semicolon  + space;    sTmp.Printf (wxT("font-size:%dpt; fill:#"), m_font.GetPointSize () );    s = s + sTmp ;    s = s + wxColStr (m_textForegroundColour) + wxT("; stroke:#") + wxColStr (m_textForegroundColour) + wxT("; ") ;    sTmp.Printf ( wxT("stroke-width:0;\"  transform=\"rotate( %.2g %d %d )  \" >"),  -angle, x,y ) ;    s = s + sTmp + sText + wxT("</text> ") + newline ;    if (m_OK)    {        write(s);    }    wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DrawRotatedText Call executed")) ;}void wxSVGFileDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height){    DoDrawRoundedRectangle(x, y, width, height, 0)  ;}void wxSVGFileDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius ){    if (m_graphics_changed) NewGraphics ();    wxString s ;    s.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" rx=\"%.2g\" "),               x, y, width, height, radius );    s = s + wxT(" /> ") + newline ;    write(s);    wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawRoundedRectangle Call executed")) ;    CalcBoundingBox(x, y) ;    CalcBoundingBox(x + width, y + height) ;}void wxSVGFileDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset,int fillStyle){    if (m_graphics_changed) NewGraphics ();    wxString s, sTmp ;    s = wxT("<polygon style=\"") ;    if ( fillStyle == wxODDEVEN_RULE )        s = s + wxT("fill-rule:evenodd; ");    else        s = s + wxT("fill-rule:nonzero; ");    s = s  + wxT("\" \npoints=\"") ;    for (int i = 0; i < n;  i++)    {        sTmp.Printf ( wxT("%d,%d"), points [i].x+xoffset, points[i].y+yoffset );        s = s + sTmp + newline ;        CalcBoundingBox ( points [i].x+xoffset, points[i].y+yoffset);    }    s = s + wxT("\" /> ") ;    s = s + newline ;    write(s);    wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawPolygon Call executed")) ;}void wxSVGFileDC::DoDrawEllipse (wxCoord x, wxCoord y, wxCoord width, wxCoord height){    if (m_graphics_changed) NewGraphics ();    int rh = height /2 ;    int rw = width  /2 ;    wxString s;    s.Printf ( wxT("<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" "), x+rw,y+rh, rw, rh );    s = s + wxT(" /> ") + newline ;    write(s);    wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawEllipse Call executed")) ;    CalcBoundingBox(x, y) ;    CalcBoundingBox(x + width, y + height) ;}void wxSVGFileDC::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc){    /* Draws an arc of a circle, centred on (xc, yc), with starting point    (x1, y1) and ending at (x2, y2). The current pen is used for the outline    and the current brush for filling the shape.    The arc is drawn in an anticlockwise direction from the start point to    the end point.    Might be better described as Pie drawing */    if (m_graphics_changed) NewGraphics ();    wxString s ;    // 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 r2 = sqrt ( double( (x2-xc)*(x2-xc) ) + double( (y2-yc)*(y2-yc) ) );    wxASSERT_MSG( (fabs ( r2-r1 ) <= 3), wxT("wxSVGFileDC::DoDrawArc Error in getting radii of circle")) ;    if ( fabs ( r2-r1 ) > 3 )    //pixels    {        s = wxT("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle --> \n") ;        write(s);    }    double theta1 = atan2((double)(yc-y1),(double)(x1-xc));    if ( theta1 < 0 ) theta1 = theta1 + M_PI * 2;    double theta2 = atan2((double)(yc-y2), (double)(x2-xc));    if ( theta2 < 0 ) theta2 = theta2 + M_PI * 2;    if ( theta2 < theta1 ) theta2 = theta2 + M_PI *2 ;    int fArc  ;                  // flag for large or small arc 0 means less than 180 degrees    if ( fabs(theta2 - theta1) > M_PI ) fArc = 1; else fArc = 0 ;    int fSweep = 0 ;             // flag for sweep always 0    s.Printf ( wxT("<path d=\"M%d %d A%.2g %.2g 0.0 %d %d %d %d L%d %d z "),        x1,y1, r1, r2, fArc, fSweep, x2, y2, xc, yc );    // the z means close the path and fill    s = s + wxT(" \" /> ") + newline ;    if (m_OK)    {        write(s);    }    wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::DoDrawArc Call executed")) ;}void wxSVGFileDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea){    /*    Draws an arc of an ellipse. The current pen is used for drawing the arc    and the current brush is used for drawing the pie. This function is    currently only available for X window and PostScript device contexts.    x and y specify the x and y coordinates of the upper-left corner of the    rectangle that contains the ellipse.    width and height specify the width and height of the rectangle that    contains the ellipse.    start and end specify the start and end of the arc relative to the    three-o'clock position from the center of the rectangle. Angles are    specified in degrees (360 is a complete circle). Positive values mean    counter-clockwise motion. If start is equal to end, a complete ellipse    will be drawn. */    //known bug: SVG draws with the current pen along the radii, but this does not happen in wxMSW    if (m_graphics_changed) NewGraphics ();    wxString s ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -