예제 #1
0
bool wxSFPrintout::OnPrintPage(int page)
{
	wxUnusedVar( page );

    wxASSERT_MSG(m_pCanvas, wxT("Shape canvas must be set in the wxSFPrintout class instance."));

    wxDC *dc = GetDC();
    if (dc && m_pCanvas)
    {
        // get grawing size
        wxRect fitRect, totalBB = m_pCanvas->GetTotalBoundingBox();
        wxCoord maxX = totalBB.GetRight();
        wxCoord maxY = totalBB.GetBottom();

        // set printing mode
        switch( m_pCanvas->GetPrintMode() )
        {
            case wxSFShapeCanvas::prnFIT_TO_PAGE:
                FitThisSizeToPage(wxSize(maxX, maxY));
                fitRect = GetLogicalPageRect();
                break;

            case wxSFShapeCanvas::prnFIT_TO_PAPER:
                FitThisSizeToPaper(wxSize(maxX, maxY));
                fitRect = GetLogicalPaperRect();
                break;

            case wxSFShapeCanvas::prnFIT_TO_MARGINS:
                FitThisSizeToPageMargins(wxSize(maxX, maxY), *g_pageSetupData);
                fitRect = GetLogicalPageMarginsRect(*g_pageSetupData);
                break;

            case wxSFShapeCanvas::prnMAP_TO_PAGE:
                MapScreenSizeToPage();
                fitRect = GetLogicalPageRect();
                break;

            case wxSFShapeCanvas::prnMAP_TO_PAPER:
                MapScreenSizeToPaper();
                fitRect = GetLogicalPaperRect();
                break;

            case wxSFShapeCanvas::prnMAP_TO_MARGINS:
                MapScreenSizeToPage();
                fitRect = GetLogicalPageMarginsRect(*g_pageSetupData);
                break;

            case wxSFShapeCanvas::prnMAP_TO_DEVICE:
                MapScreenSizeToDevice();
                fitRect = GetLogicalPageRect();
                break;
        }

        // This offsets the image so that it is centered within the reference
        // rectangle defined above.

        wxCoord xoff = ((fitRect.width - maxX - totalBB.GetLeft()) / 2) - fitRect.x;
        wxCoord yoff = ((fitRect.height - maxY - totalBB.GetTop()) / 2) - fitRect.y;

        switch( m_pCanvas->GetPrintHAlign() )
        {
            case wxSFShapeCanvas::halignLEFT:
                xoff = 0;
                break;

            case wxSFShapeCanvas::halignRIGHT:
                xoff = fitRect.width - totalBB.GetWidth();
                break;

            default:
                break;
        }

        switch( m_pCanvas->GetPrintVAlign() )
        {
            case wxSFShapeCanvas::valignTOP:
                yoff = 0;
                break;

            case wxSFShapeCanvas::valignBOTTOM:
                yoff = fitRect.height - totalBB.GetHeight();
                break;

            default:
                break;
        }

        OffsetLogicalOrigin(xoff, yoff);

        // store current canvas properties
        double prevScale = m_pCanvas->GetScale();
        long prevStyle = m_pCanvas->GetStyle();
        wxColour prevColour = m_pCanvas->GetCanvasColour();

        // disable canvas background drawing if required
        if( !m_pCanvas->ContainsStyle( wxSFShapeCanvas::sfsPRINT_BACKGROUND ) )
        {
            m_pCanvas->RemoveStyle( wxSFShapeCanvas::sfsGRADIENT_BACKGROUND );
            m_pCanvas->RemoveStyle( wxSFShapeCanvas::sfsGRID_SHOW );
            m_pCanvas->SetCanvasColour( *wxWHITE);
        }

        // draw the canvas content without any scale (dc is scaled by the printing framework)
#if wxVERSION_NUMBER < 2900
		double nScale = 1;
		if( wxSFShapeCanvas::IsGCEnabled() ) dc->GetUserScale( &nScale, &nScale );
        m_pCanvas->SetScale(1);

		#ifdef __WXMSW__
		wxSFScaledDC sdc( (wxWindowDC*)dc, nScale );
		sdc.PrepareGC();
        m_pCanvas->DrawContent(sdc, sfNOT_FROM_PAINT);
        #else
		m_pCanvas->DrawContent(*dc, sfNOT_FROM_PAINT);
		#endif

        m_pCanvas->SetScale(prevScale);
#else
		m_pCanvas->SetScale(1);
		m_pCanvas->DrawContent(*dc, sfNOT_FROM_PAINT);
		m_pCanvas->SetScale(prevScale);
#endif

        // restore previous canvas properties if needed
        if( !m_pCanvas->ContainsStyle( wxSFShapeCanvas::sfsPRINT_BACKGROUND ) )
        {
            m_pCanvas->SetStyle( prevStyle );
            m_pCanvas->SetCanvasColour( prevColour );
        }

        return true;
    }
    else
        return false;
}
/*
 * This is the real print function: print the active screen
 */
void SCH_PRINTOUT::DrawPage( SCH_SCREEN* aScreen )
{
    int      oldZoom;
    wxPoint  tmp_startvisu;
    wxSize   pageSizeIU;             // Page size in internal units
    wxPoint  old_org;
    EDA_RECT oldClipBox;
    wxRect   fitRect;
    wxDC*    dc = GetDC();
    auto panel = m_parent->GetCanvas();

    wxBusyCursor dummy;

    // Save current scale factor, offsets, and clip box.
    tmp_startvisu = aScreen->m_StartVisu;
    oldZoom = aScreen->GetZoom();
    old_org = aScreen->m_DrawOrg;

    oldClipBox = *panel->GetClipBox();

    // Change clip box to print the whole page.
    #define MAX_VALUE (INT_MAX/2)   // MAX_VALUE is the max we can use in an integer
                                    // and that allows calculations without overflow
    panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) );

    // Change scale factor and offset to print the whole page.
    bool printReference = m_parent->GetPrintSheetReference();

    pageSizeIU = aScreen->GetPageSettings().GetSizeIU();
    FitThisSizeToPaper( pageSizeIU );
    fitRect = GetLogicalPaperRect();

    wxLogDebug( wxT( "Fit rectangle: x = %d, y = %d, w = %d, h = %d" ),
                fitRect.x, fitRect.y, fitRect.width, fitRect.height );

    // When is the actual paper size does not match the schematic page
    // size, the drawing is not perfectly centered on X or Y axis.
    // Give a draw offset centers the schematic page on the paper draw area
    // Because the sizes are fitted, only an Y or X offset is needed
    // and both are 0 when sizes are identical.
    // Y or Y offset is not null when the X/Y size ratio differs between
    // the actual paper size and the schematic page
    int xoffset = ( fitRect.width - pageSizeIU.x ) / 2;

    // For an obscure reason, OffsetLogicalOrigin creates issues,
    // under some circumstances, when yoffset is not always null
    // and changes from a page to another page
    // This is only a workaround, not a fix
    // see https://bugs.launchpad.net/kicad/+bug/1464773
    // xoffset does not create issues.
#if 0   // FIX ME
    int yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
#else
    // the Y centering will be not perfect, but this is less annoying
    // than a blank page or a buggy centering
    int yoffset = 0;
#endif
    OffsetLogicalOrigin( xoffset, yoffset );

    GRResetPenAndBrush( dc );

    if( m_parent->GetPrintMonochrome() )
        GRForceBlackPen( true );

    aScreen->m_IsPrinting = true;

    COLOR4D bgColor = m_parent->GetDrawBgColor();

    aScreen->Draw( panel, dc, (GR_DRAWMODE) 0 );

    if( printReference )
        m_parent->DrawWorkSheet( dc, aScreen, GetDefaultLineThickness(),
                IU_PER_MILS, aScreen->GetFileName() );

    m_parent->SetDrawBgColor( bgColor );
    aScreen->m_IsPrinting = false;
    panel->SetClipBox( oldClipBox );

    GRForceBlackPen( false );

    aScreen->m_StartVisu = tmp_startvisu;
    aScreen->m_DrawOrg   = old_org;
    aScreen->SetZoom( oldZoom );
}