dcpsg.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,062 行 · 第 1/5 页

CPP
2,062
字号

        CalcBoundingBox( x - width, y - height );
        CalcBoundingBox( x + width, y + height );
    }
}

void wxPostScriptDC::DoDrawIcon( const wxIcon& icon, wxCoord x, wxCoord y )
{
    DrawBitmap( icon, x, y, true );
}

/* this has to be char, not wxChar */
static char hexArray[] = "0123456789ABCDEF";

void wxPostScriptDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool WXUNUSED(useMask) )
{
    wxCHECK_RET( m_ok, wxT("invalid postscript dc") );

    if (!bitmap.Ok()) return;

    wxImage image = bitmap.ConvertToImage();

    if (!image.Ok()) return;

    wxCoord w = image.GetWidth();
    wxCoord h = image.GetHeight();

    wxCoord ww = LogicalToDeviceXRel(image.GetWidth());
    wxCoord hh = LogicalToDeviceYRel(image.GetHeight());

    wxCoord xx = LogicalToDeviceX(x);
    wxCoord yy = LogicalToDeviceY(y + bitmap.GetHeight());

    PsPrintf( wxT("/origstate save def\n")
              wxT("20 dict begin\n")
              wxT("/pix %d string def\n")
              wxT("/grays %d string def\n")
              wxT("/npixels 0 def\n")
              wxT("/rgbindx 0 def\n")
              wxT("%d %d translate\n")
              wxT("%d %d scale\n")
              wxT("%d %d 8\n")
              wxT("[%d 0 0 %d 0 %d]\n")
              wxT("{currentfile pix readhexstring pop}\n")
              wxT("false 3 colorimage\n"),
            w, w, xx, yy, ww, hh, w, h, w, -h, h );

    unsigned char* data = image.GetData();

    // size of the buffer = width*rgb(3)*hexa(2)+'\n'
    wxCharBuffer buffer(w*6 + 1);
    int firstDigit, secondDigit;

    //rows
    for (int j = 0; j < h; j++)
    {
        char* bufferindex = buffer.data();

        //cols
        for (int i = 0; i < w*3; i++)
        {
            firstDigit = (int)(*data/16.0);
            secondDigit = (int)(*data - (firstDigit*16.0));
            *(bufferindex++) = hexArray[firstDigit];
            *(bufferindex++) = hexArray[secondDigit];

            data++;
        }
        *(bufferindex++) = '\n';
        *bufferindex = 0;
        PsPrint( buffer );
    }

    PsPrint( "end\n" );
    PsPrint( "origstate restore\n" );
}

void wxPostScriptDC::SetFont( const wxFont& font )
{
    wxCHECK_RET( m_ok, wxT("invalid postscript dc") );

    if (!font.Ok())  return;

    m_font = font;

    int Style = m_font.GetStyle();
    int Weight = m_font.GetWeight();

    const char *name;
    switch (m_font.GetFamily())
    {
        case wxTELETYPE:
        case wxMODERN:
        {
            if (Style == wxITALIC)
            {
                if (Weight == wxBOLD)
                    name = "/Courier-BoldOblique";
                else
                    name = "/Courier-Oblique";
            }
            else
            {
                if (Weight == wxBOLD)
                    name = "/Courier-Bold";
                else
                    name = "/Courier";
            }
            break;
        }
        case wxROMAN:
        {
            if (Style == wxITALIC)
            {
                if (Weight == wxBOLD)
                    name = "/Times-BoldItalic";
                else
                    name = "/Times-Italic";
            }
            else
            {
                if (Weight == wxBOLD)
                    name = "/Times-Bold";
                else
                    name = "/Times-Roman";
            }
            break;
        }
        case wxSCRIPT:
        {
            name = "/ZapfChancery-MediumItalic";
            break;
        }
        case wxSWISS:
        default:
        {
            if (Style == wxITALIC)
            {
                if (Weight == wxBOLD)
                    name = "/Helvetica-BoldOblique";
                else
                    name = "/Helvetica-Oblique";
            }
            else
            {
                if (Weight == wxBOLD)
                    name = "/Helvetica-Bold";
                else
                    name = "/Helvetica";
            }
            break;
        }
    }

    // We may legitimately call SetFont before BeginDoc
    if (!m_pstream)
        return;

    PsPrint( name );
    PsPrint( " reencodeISO def\n" );
    PsPrint( name );
    PsPrint( " findfont\n" );

    char buffer[100];
    sprintf( buffer, "%f scalefont setfont\n", LogicalToDeviceYRel(m_font.GetPointSize() * 1000) / 1000.0F);
    // this is a hack - we must scale font size (in pts) according to m_scaleY but
    // LogicalToDeviceYRel works with wxCoord type (int or longint). Se we first convert font size
    // to 1/1000th of pt and then back.
    for (int i = 0; i < 100; i++)
        if (buffer[i] == ',') buffer[i] = '.';
    PsPrint( buffer );
}

void wxPostScriptDC::SetPen( const wxPen& pen )
{
    wxCHECK_RET( m_ok, wxT("invalid postscript dc") );

    if (!pen.Ok()) return;

    int oldStyle = m_pen.GetStyle();

    m_pen = pen;

    char buffer[100];
    sprintf( buffer, "%f setlinewidth\n", LogicalToDeviceXRel(1000 * m_pen.GetWidth()) / 1000.0f );
    for (int i = 0; i < 100; i++)
        if (buffer[i] == ',') buffer[i] = '.';
    PsPrint( buffer );

/*
     Line style - WRONG: 2nd arg is OFFSET

     Here, I'm afraid you do not conceive meaning of parameters of 'setdash'
     operator correctly. You should look-up this in the Red Book: the 2nd parame-
     ter is not number of values in the array of the first one, but an offset
     into this description of the pattern. I mean a real *offset* not index
     into array. I.e. If the command is [3 4] 1 setdash   is used, then there
     will be first black line *2* units wxCoord, then space 4 units, then the
     pattern of *3* units black, 4 units space will be repeated.
*/

    static const char *dotted = "[2 5] 2";
    static const char *short_dashed = "[4 4] 2";
    static const char *wxCoord_dashed = "[4 8] 2";
    static const char *dotted_dashed = "[6 6 2 6] 4";

    const char *psdash;

    switch (m_pen.GetStyle())
    {
        case wxDOT:           psdash = dotted;         break;
        case wxSHORT_DASH:    psdash = short_dashed;   break;
        case wxLONG_DASH:     psdash = wxCoord_dashed; break;
        case wxDOT_DASH:      psdash = dotted_dashed;  break;
        case wxUSER_DASH:
        {
            wxDash *dashes;
            int nDashes = m_pen.GetDashes (&dashes);
            PsPrint ("[");
            for (int i = 0; i < nDashes; ++i)
            {
                sprintf( buffer, "%d ", dashes [i] );
                PsPrint( buffer );
            }
            PsPrint ("] 0 setdash\n");
            psdash = 0; 
        } 
        break;
        case wxSOLID:
        case wxTRANSPARENT:
        default:              psdash = "[] 0";         break;
    }

    if (psdash && (oldStyle != m_pen.GetStyle()) )
    {
        PsPrint( psdash );
        PsPrint( " setdash\n" );
    }

    // Line colour
    unsigned char red = m_pen.GetColour().Red();
    unsigned char blue = m_pen.GetColour().Blue();
    unsigned char green = m_pen.GetColour().Green();

    if (!m_colour)
    {
        // Anything not white is black
        if (! (red == (unsigned char) 255 &&
               blue == (unsigned char) 255 &&
               green == (unsigned char) 255) )
        {
            red = (unsigned char) 0;
            green = (unsigned char) 0;
            blue = (unsigned char) 0;
        }
        // setgray here ?
    }

    if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
    {
        double redPS = (double)(red) / 255.0;
        double bluePS = (double)(blue) / 255.0;
        double greenPS = (double)(green) / 255.0;

        char buffer[100];
        sprintf( buffer,
            "%.8f %.8f %.8f setrgbcolor\n",
            redPS, greenPS, bluePS );
        for (int i = 0; i < 100; i++)
            if (buffer[i] == ',') buffer[i] = '.';

        PsPrint( buffer );

        m_currentRed = red;
        m_currentBlue = blue;
        m_currentGreen = green;
    }
}

void wxPostScriptDC::SetBrush( const wxBrush& brush )
{
    wxCHECK_RET( m_ok, wxT("invalid postscript dc") );

    if (!brush.Ok()) return;

    m_brush = brush;

    // Brush colour
    unsigned char red = m_brush.GetColour().Red();
    unsigned char blue = m_brush.GetColour().Blue();
    unsigned char green = m_brush.GetColour().Green();

    if (!m_colour)
    {
        // Anything not white is black
        if (! (red == (unsigned char) 255 &&
               blue == (unsigned char) 255 &&
               green == (unsigned char) 255) )
        {
            red = (unsigned char) 0;
            green = (unsigned char) 0;
            blue = (unsigned char) 0;
        }
        // setgray here ?
    }

    if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
    {
        double redPS = (double)(red) / 255.0;
        double bluePS = (double)(blue) / 255.0;
        double greenPS = (double)(green) / 255.0;

        char buffer[100];
        sprintf( buffer,
                "%.8f %.8f %.8f setrgbcolor\n",
                redPS, greenPS, bluePS );
        for (int i = 0; i < 100; i++)
            if (buffer[i] == ',') buffer[i] = '.';

        PsPrint( buffer );

        m_currentRed = red;
        m_currentBlue = blue;
        m_currentGreen = green;
    }
}

void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
{
    wxCHECK_RET( m_ok, wxT("invalid postscript dc") );

    if (m_textForegroundColour.Ok())
    {
        unsigned char red = m_textForegroundColour.Red();
        unsigned char blue = m_textForegroundColour.Blue();
        unsigned char green = m_textForegroundColour.Green();

        if (!m_colour)
        {
            // Anything not white is black
            if (! (red == (unsigned char) 255 &&
                        blue == (unsigned char) 255 &&
                        green == (unsigned char) 255))
            {
                red = (unsigned char) 0;
                green = (unsigned char) 0;
                blue = (unsigned char) 0;
            }
        }

        // maybe setgray here ?
        if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
        {
            double redPS = (double)(red) / 255.0;
            double bluePS = (double)(blue) / 255.0;
            double greenPS = (double)(green) / 255.0;

            char buffer[100];
            sprintf( buffer,
                "%.8f %.8f %.8f setrgbcolor\n",
                redPS, greenPS, bluePS );
            for (size_t i = 0; i < strlen(buffer); i++)
                if (buffer[i] == ',') buffer[i] = '.';
            PsPrint( buffer );

            m_currentRed = red;
            m_currentBlue = blue;
            m_currentGreen = green;
        }
    }

    wxCoord text_w, text_h, text_descent;

    GetTextExtent(text, &text_w, &text_h, &text_descent);

    // VZ: this seems to be unnecessary, so taking it out for now, if it
    //     doesn't create any problems, remove this comment entirely
    //SetFont( m_font );


    int size = m_font.GetPointSize();

//    wxCoord by = y + (wxCoord)floor( double(size) * 2.0 / 3.0 ); // approximate baseline
//    commented by V. Slavik and replaced by accurate version
//        - note that there is still rounding error in text_descent!
    wxCoord by = y + size - text_descent; // baseline

    PsPrintf( wxT("%d %d moveto\n"), LogicalToDeviceX(x), LogicalToDeviceY(by) );
    PsPrint( "(" );

    const wxWX2MBbuf textbuf = text.mb_str();
    size_t len = strlen(textbuf);
    size_t i;
    for (i = 0; i < len; i++)
    {
        int c = (unsigned char) textbuf[i];
        if (c == ')' || c == '(' || c == '\\')
        {
            /* Cope with special characters */
            PsPrint( "\\" );
            PsPrint(c);
        }
        else if ( c >= 128 )
        {
            /* Cope with character codes > 127 */
            PsPrintf( wxT("\\%o"), c);
        }
        else
        {
            PsPrint(c);
        }
    }

⌨️ 快捷键说明

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