/***** Print a single page of the document. *****/ bool RFPrintout::OnPrintPage(int page) { // Set the DC scale to map the total image width to the page margins rect // width and put the origin at the top left of the page margins rect. wxRect pmRect = GetLogicalPageMarginsRect(*gApp->GetPageSetupDialogData()); #ifdef __WXGTK__ /* With wxGTK 2.8.0rc1 (print code @ CVS @ 061118), each page's image appears more and more offset towards the top. It's probably a wx issue, so this is a temporary fix - CAF */ OffsetLogicalOrigin(pmRect.x, -page * pmRect.y); #else OffsetLogicalOrigin(pmRect.x, pmRect.y); #endif gCanvas->mDCScale = double(pmRect.width) / gCanvas->mImageWidth; gCanvas->mIsPrinting = true; gCanvas->mPrintPage = page; gCanvas->DoDraw(*GetDC()); gCanvas->mIsPrinting = false; return true; }
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; }
void MyPrintout::DrawPageOne() { // You might use THIS code if you were scaling graphics of known size to fit // on the page. The commented-out code illustrates different ways of scaling // the graphics. // We know the graphic is 230x350. If we didn't know this, we'd need to // calculate it. wxCoord maxX = 230; wxCoord maxY = 350; // This sets the user scale and origin of the DC so that the image fits // within the paper rectangle (but the edges could be cut off by printers // that can't print to the edges of the paper -- which is most of them. Use // this if your image already has its own margins. // FitThisSizeToPaper(wxSize(maxX, maxY)); // wxRect fitRect = GetLogicalPaperRect(); // This sets the user scale and origin of the DC so that the image fits // within the page rectangle, which is the printable area on Mac and MSW // and is the entire page on other platforms. // FitThisSizeToPage(wxSize(maxX, maxY)); // wxRect fitRect = GetLogicalPageRect(); // This sets the user scale and origin of the DC so that the image fits // within the page margins as specified by g_PageSetupData, which you can // change (on some platforms, at least) in the Page Setup dialog. Note that // on Mac, the native Page Setup dialog doesn't let you change the margins // of a wxPageSetupDialogData object, so you'll have to write your own dialog or // use the Mac-only wxMacPageMarginsDialog, as we do in this program. FitThisSizeToPageMargins(wxSize(maxX, maxY), *g_pageSetupData); wxRect fitRect = GetLogicalPageMarginsRect(*g_pageSetupData); // This sets the user scale and origin of the DC so that the image appears // on the paper at the same size that it appears on screen (i.e., 10-point // type on screen is 10-point on the printed page) and is positioned in the // top left corner of the page rectangle (just as the screen image appears // in the top left corner of the window). // MapScreenSizeToPage(); // wxRect fitRect = GetLogicalPageRect(); // You could also map the screen image to the entire paper at the same size // as it appears on screen. // MapScreenSizeToPaper(); // wxRect fitRect = GetLogicalPaperRect(); // You might also wish to do you own scaling in order to draw objects at // full native device resolution. In this case, you should do the following. // Note that you can use the GetLogicalXXXRect() commands to obtain the // appropriate rect to scale to. // MapScreenSizeToDevice(); // wxRect fitRect = GetLogicalPageRect(); // Each of the preceding Fit or Map routines positions the origin so that // the drawn image is positioned at the top left corner of the reference // rectangle. You can easily center or right- or bottom-justify the image as // follows. // This offsets the image so that it is centered within the reference // rectangle defined above. wxCoord xoff = (fitRect.width - maxX) / 2; wxCoord yoff = (fitRect.height - maxY) / 2; OffsetLogicalOrigin(xoff, yoff); // This offsets the image so that it is positioned at the bottom right of // the reference rectangle defined above. // wxCoord xoff = (fitRect.width - maxX); // wxCoord yoff = (fitRect.height - maxY); // OffsetLogicalOrigin(xoff, yoff); wxGetApp().Draw(*GetDC()); }
/* * 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 ); }