bool EditPrint::PrintScaling (wxDC *dc){ // check for dc, return if none if (!dc) return false; // get printer and screen sizing values wxSize ppiScr; GetPPIScreen (&ppiScr.x, &ppiScr.y); if (ppiScr.x == 0) { // most possible guess 96 dpi ppiScr.x = 96; ppiScr.y = 96; } wxSize ppiPrt; GetPPIPrinter (&ppiPrt.x, &ppiPrt.y); if (ppiPrt.x == 0) { // scaling factor to 1 ppiPrt.x = ppiScr.x; ppiPrt.y = ppiScr.y; } wxSize dcSize = dc->GetSize(); wxSize pageSize; GetPageSizePixels (&pageSize.x, &pageSize.y); // set user scale float scale_x = (float)(ppiPrt.x * dcSize.x) / (float)(ppiScr.x * pageSize.x); float scale_y = (float)(ppiPrt.y * dcSize.y) / (float)(ppiScr.y * pageSize.y); dc->SetUserScale (scale_x, scale_y); return true; }
void MunkHtmlPrintout::OnPreparePrinting() { int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h; float ppmm_h, ppmm_v; GetPageSizePixels(&pageWidth, &pageHeight); GetPageSizeMM(&mm_w, &mm_h); ppmm_h = (float)pageWidth / mm_w; ppmm_v = (float)pageHeight / mm_h; int ppiPrinterX, ppiPrinterY; GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); int ppiScreenX, ppiScreenY; GetPPIScreen(&ppiScreenX, &ppiScreenY); wxDisplaySize(&scr_w, &scr_h); GetDC()->GetSize(&dc_w, &dc_h); GetDC()->SetUserScale((double)dc_w / (double)pageWidth, (double)dc_h / (double)pageHeight); /* prepare headers/footers renderer: */ m_RendererHdr->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY); m_RendererHdr->SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)), (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom))); if (m_Headers[0] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[0], 1)); m_HeaderHeight = m_RendererHdr->GetTotalHeight(); } else if (m_Headers[1] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[1], 1)); m_HeaderHeight = m_RendererHdr->GetTotalHeight(); } if (m_Footers[0] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[0], 1)); m_FooterHeight = m_RendererHdr->GetTotalHeight(); } else if (m_Footers[1] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[1], 1)); m_FooterHeight = m_RendererHdr->GetTotalHeight(); } /* prepare main renderer: */ m_Renderer->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY); m_Renderer->SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)), (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom) - m_FooterHeight - m_HeaderHeight - ((m_HeaderHeight == 0) ? 0 : m_MarginSpace * ppmm_v) - ((m_FooterHeight == 0) ? 0 : m_MarginSpace * ppmm_v) )); m_Renderer->SetHtmlText(m_Document, m_BasePath, m_BasePathIsDir); CountPages(); }
float wxTextPrintout::GetScale() { // First calculate scale int pw=0,ph=0,sw=0,sh=0; GetPPIPrinter(&pw,&ph); GetPPIScreen(&sw,&sh); if ((sw==0)||(sh==0)) { return float(1);} return (float(pw)/sw+float(ph)/sh)/2; }
double MathPrintout::GetPPIScale() { int ppiScreenX, ppiScreenY; int ppiPrinterX, ppiPrinterY; GetPPIScreen(&ppiScreenX, &ppiScreenY); GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); #if defined __WXMAC__ return 0.6*((double)ppiPrinterY) / ((double)ppiScreenY); #else return ((double)ppiPrinterY) / ((double)ppiScreenY); #endif }
void wxHtmlPrintout::RenderPage(wxDC *dc, int page) { wxBusyCursor wait; int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h; float ppmm_h, ppmm_v; GetPageSizePixels(&pageWidth, &pageHeight); GetPageSizeMM(&mm_w, &mm_h); ppmm_h = (float)pageWidth / mm_w; ppmm_v = (float)pageHeight / mm_h; wxDisplaySize(&scr_w, &scr_h); dc->GetSize(&dc_w, &dc_h); int ppiPrinterX, ppiPrinterY; GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); wxUnusedVar(ppiPrinterX); int ppiScreenX, ppiScreenY; GetPPIScreen(&ppiScreenX, &ppiScreenY); wxUnusedVar(ppiScreenX); dc->SetUserScale((double)dc_w / (double)pageWidth, (double)dc_h / (double)pageHeight); m_Renderer->SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY); dc->SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); m_Renderer->Render((int) (ppmm_h * m_MarginLeft), (int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight), m_PageBreaks, m_PageBreaks[page-1], false, m_PageBreaks[page]-m_PageBreaks[page-1]); m_RendererHdr->SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY); if (m_Headers[page % 2] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[page % 2], page)); m_RendererHdr->Render((int) (ppmm_h * m_MarginLeft), (int) (ppmm_v * m_MarginTop), m_PageBreaks); } if (m_Footers[page % 2] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[page % 2], page)); m_RendererHdr->Render((int) (ppmm_h * m_MarginLeft), (int) (pageHeight - ppmm_v * m_MarginBottom - m_FooterHeight), m_PageBreaks); } }
//------------------------------------------------------------------------------ // bool PrintScaling(wxDC *dc) //------------------------------------------------------------------------------ bool EditorPrintout::PrintScaling(wxDC *dc) { #ifdef DEBUG_PRINTOUT MessageInterface::ShowMessage("EditorPrintout::PrintScaling() entered\n"); #endif // check for dc, return if none if(!dc) return false; // get printer and screen sizing values wxSize ppiScr; GetPPIScreen(&ppiScr.x, &ppiScr.y); if(ppiScr.x == 0) { // most possible guess 96 dpi ppiScr.x = 96; ppiScr.y = 96; } wxSize ppiPrt; GetPPIPrinter(&ppiPrt.x, &ppiPrt.y); if(ppiPrt.x == 0) { // scaling factor to 1 ppiPrt.x = ppiScr.x; ppiPrt.y = ppiScr.y; } wxSize dcSize = dc->GetSize(); wxSize pageSize; GetPageSizePixels(&pageSize.x, &pageSize.y); // set user scale float scale_x =(float)(ppiPrt.x * dcSize.x) / (float)(ppiScr.x * pageSize.x); float scale_y =(float)(ppiPrt.y * dcSize.y) / (float)(ppiScr.y * pageSize.y); dc->SetUserScale(scale_x, scale_y); #ifdef DEBUG_PRINTOUT MessageInterface::ShowMessage ("EditorPrintout::PrintScaling() returning true\n"); #endif return true; }
bool TrussPrintout::OnPrintPage(int pageNum) { assert(HasPage(pageNum) && "this should only be called if HasPage returns true"); wxDC *dc = GetDC(); if (!dc || !dc->IsOk()) return false; int printer_x, printer_y, screen_x, screen_y; GetPPIPrinter(&printer_x, &printer_y); GetPPIScreen(&screen_x, &screen_y); float scale = printer_x / (float)screen_x; // wxFont is stupid apparently and uses "points" that don't actually match // up on the page. wxFont &f = *wxTheFontList->FindOrCreateFont(12 * scale, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); dc->SetFont(f); pages[pageNum-1].print(*dc); return true; }
void BOARD_PRINTOUT_CONTROLLER::DrawPage() { wxPoint offset; double userscale; EDA_RECT boardBoundingBox; EDA_RECT drawRect; wxDC* dc = GetDC(); BASE_SCREEN* screen = m_Parent->GetScreen(); bool printMirror = m_PrintParams.m_PrintMirror; wxSize pageSizeIU = m_Parent->GetPageSizeIU(); wxBusyCursor dummy; #if defined (PCBNEW) BOARD * brd = ((PCB_BASE_FRAME*) m_Parent)->GetBoard(); boardBoundingBox = brd->ComputeBoundingBox(); wxString titleblockFilename = brd->GetFileName(); #elif defined (GERBVIEW) boardBoundingBox = ((GERBVIEW_FRAME*) m_Parent)->GetGerberLayoutBoundingBox(); wxString titleblockFilename; // TODO see if we uses the gerber file name #else #error BOARD_PRINTOUT_CONTROLLER::DrawPage() works only for PCBNEW or GERBVIEW #endif // Use the page size as the drawing area when the board is shown or the user scale // is less than 1. if( m_PrintParams.PrintBorderAndTitleBlock() ) boardBoundingBox = EDA_RECT( wxPoint( 0, 0 ), pageSizeIU ); wxLogTrace( tracePrinting, wxT( "Drawing bounding box: x=%d, y=%d, w=%d, h=%d" ), boardBoundingBox.GetX(), boardBoundingBox.GetY(), boardBoundingBox.GetWidth(), boardBoundingBox.GetHeight() ); // Compute the PCB size in internal units userscale = m_PrintParams.m_PrintScale; if( m_PrintParams.m_PrintScale == 0 ) // fit in page option { if(boardBoundingBox.GetWidth() && boardBoundingBox.GetHeight()) { int margin = Millimeter2iu( 10.0 ); // add a margin around the drawings double scaleX = (double)(pageSizeIU.x - (2 * margin)) / boardBoundingBox.GetWidth(); double scaleY = (double)(pageSizeIU.y - (2 * margin)) / boardBoundingBox.GetHeight(); userscale = (scaleX < scaleY) ? scaleX : scaleY; } else userscale = 1.0; } wxSize scaledPageSize = pageSizeIU; drawRect.SetSize( scaledPageSize ); scaledPageSize.x = wxRound( scaledPageSize.x / userscale ); scaledPageSize.y = wxRound( scaledPageSize.y / userscale ); if( m_PrintParams.m_PageSetupData ) { wxLogTrace( tracePrinting, wxT( "Fit size to page margins: x=%d, y=%d" ), scaledPageSize.x, scaledPageSize.y ); // Always scale to the size of the paper. FitThisSizeToPageMargins( scaledPageSize, *m_PrintParams.m_PageSetupData ); } // Compute Accurate scale 1 if( m_PrintParams.m_PrintScale == 1.0 ) { // We want a 1:1 scale, regardless the page setup // like page size, margin ... MapScreenSizeToPaper(); // set best scale and offset (scale is not used) int w, h; GetPPIPrinter( &w, &h ); double accurate_Xscale = (double) w / (IU_PER_MILS*1000); double accurate_Yscale = (double) h / (IU_PER_MILS*1000); if( IsPreview() ) // Scale must take in account the DC size in Preview { // Get the size of the DC in pixels wxSize PlotAreaSize; dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y ); GetPageSizePixels( &w, &h ); accurate_Xscale *= (double)PlotAreaSize.x / w; accurate_Yscale *= (double)PlotAreaSize.y / h; } // Fine scale adjust accurate_Xscale *= m_PrintParams.m_XScaleAdjust; accurate_Yscale *= m_PrintParams.m_YScaleAdjust; // Set print scale for 1:1 exact scale dc->SetUserScale( accurate_Xscale, accurate_Yscale ); } // Get the final size of the DC in pixels wxSize PlotAreaSizeInPixels; dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y ); wxLogTrace( tracePrinting, wxT( "Plot area in pixels: x=%d, y=%d" ), PlotAreaSizeInPixels.x, PlotAreaSizeInPixels.y ); double scalex, scaley; dc->GetUserScale( &scalex, &scaley ); wxLogTrace( tracePrinting, wxT( "DC user scale: x=%g, y=%g" ), scalex, scaley ); wxSize PlotAreaSizeInUserUnits; PlotAreaSizeInUserUnits.x = KiROUND( PlotAreaSizeInPixels.x / scalex ); PlotAreaSizeInUserUnits.y = KiROUND( PlotAreaSizeInPixels.y / scaley ); wxLogTrace( tracePrinting, wxT( "Scaled plot area in user units: x=%d, y=%d" ), PlotAreaSizeInUserUnits.x, PlotAreaSizeInUserUnits.y ); // In module editor, the module is located at 0,0 but for printing // it is moved to pageSizeIU.x/2, pageSizeIU.y/2. // So the equivalent board must be moved to the center of the page: if( m_Parent->IsType( MODULE_EDITOR_FRAME_TYPE ) ) { boardBoundingBox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) ); } // In some cases the plot origin is the centre of the board outline rather than the center // of the selected paper size. if( m_PrintParams.CenterOnBoardOutline() ) { // Here we are only drawing the board and it's contents. drawRect = boardBoundingBox; offset.x += wxRound( (double) -scaledPageSize.x / 2.0 ); offset.y += wxRound( (double) -scaledPageSize.y / 2.0 ); wxPoint center = boardBoundingBox.Centre(); if( printMirror ) { // Calculate the mirrored center of the board. center.x = m_Parent->GetPageSizeIU().x - boardBoundingBox.Centre().x; } offset += center; } GRResetPenAndBrush( dc ); EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); EDA_RECT tmp = *panel->GetClipBox(); // Set clip box to the max size #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 ) ) ); screen->m_IsPrinting = true; EDA_COLOR_T bg_color = g_DrawBgColor; // Print frame reference, if reqquested, before if( m_PrintParams.m_Print_Black_and_White ) GRForceBlackPen( true ); if( m_PrintParams.PrintBorderAndTitleBlock() ) m_Parent->DrawWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize, IU_PER_MILS, titleblockFilename ); if( printMirror ) { // To plot mirror, we reverse the x axis, and modify the plot x origin dc->SetAxisOrientation( false, false); /* Plot offset x is moved by the x plot area size in order to have * the old draw area in the new draw area, because the draw origin has not moved * (this is the upper left corner) but the X axis is reversed, therefore the plotting area * is the x coordinate values from - PlotAreaSize.x to 0 */ int x_dc_offset = PlotAreaSizeInPixels.x; x_dc_offset = KiROUND( x_dc_offset * userscale ); dc->SetDeviceOrigin( x_dc_offset, 0 ); wxLogTrace( tracePrinting, wxT( "Device origin: x=%d, y=%d" ), x_dc_offset, 0 ); panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE/2, -MAX_VALUE/2 ), panel->GetClipBox()->GetSize() ) ); } // screen->m_DrawOrg = offset; dc->SetLogicalOrigin( offset.x, offset.y ); wxLogTrace( tracePrinting, wxT( "Logical origin: x=%d, y=%d" ), offset.x, offset.y ); #if defined(wxUSE_LOG_TRACE) && defined( DEBUG ) wxRect paperRect = GetPaperRectPixels(); wxLogTrace( tracePrinting, wxT( "Paper rectangle: left=%d, top=%d, " "right=%d, bottom=%d" ), paperRect.GetLeft(), paperRect.GetTop(), paperRect.GetRight(), paperRect.GetBottom() ); int devLeft = dc->LogicalToDeviceX( drawRect.GetX() ); int devTop = dc->LogicalToDeviceY( drawRect.GetY() ); int devRight = dc->LogicalToDeviceX( drawRect.GetRight() ); int devBottom = dc->LogicalToDeviceY( drawRect.GetBottom() ); wxLogTrace( tracePrinting, wxT( "Final device rectangle: left=%d, top=%d, " "right=%d, bottom=%d\n" ), devLeft, devTop, devRight, devBottom ); #endif g_DrawBgColor = WHITE; /* when printing in color mode, we use the graphic OR mode that gives the same look as * the screen but because the background is white when printing, we must use a trick: * In order to plot on a white background in OR mode we must: * 1 - Plot all items in black, this creates a local black background * 2 - Plot in OR mode on black "local" background */ if( !m_PrintParams.m_Print_Black_and_White ) { // Creates a "local" black background GRForceBlackPen( true ); m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); GRForceBlackPen( false ); } else GRForceBlackPen( true ); #if defined (GERBVIEW) // In B&W mode, do not force black pen for Gerbview // because negative objects need a white pen, not a black pen // B&W mode is handled in print page GRForceBlackPen( false ); #endif m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); g_DrawBgColor = bg_color; screen->m_IsPrinting = false; panel->SetClipBox( tmp ); GRForceBlackPen( false ); }
/// Calculate scaling and rectangles, setting the device context scaling void wxRichTextPrintout::CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& headerRect, wxRect& footerRect) { // Get the logical pixels per inch of screen and printer int ppiScreenX, ppiScreenY; GetPPIScreen(&ppiScreenX, &ppiScreenY); int ppiPrinterX, ppiPrinterY; GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); // This scales the DC so that the printout roughly represents the // the screen scaling. float scale = (float)((float)ppiPrinterX/(float)ppiScreenX); // Now we have to check in case our real page size is reduced // (e.g. because we're drawing to a print preview memory DC) int pageWidth, pageHeight; int w, h; dc->GetSize(&w, &h); GetPageSizePixels(&pageWidth, &pageHeight); // If printer pageWidth == current DC width, then this doesn't // change. But w might be the preview bitmap width, so scale down. float previewScale = (float)(w/(float)pageWidth); float overallScale = scale * previewScale; // The dimensions used for indentation etc. have to be unscaled // during printing to be correct when scaling is applied. if (!IsPreview()) m_richTextBuffer->SetScale(scale); // Calculate margins int marginLeft = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginLeft); int marginTop = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginTop); int marginRight = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginRight); int marginBottom = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginBottom); // Header and footer margins int headerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetHeaderMargin()); int footerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetFooterMargin()); dc->SetUserScale(overallScale, overallScale); wxRect rect((int) (marginLeft/scale), (int) (marginTop/scale), (int) ((pageWidth - marginLeft - marginRight)/scale), (int)((pageHeight - marginTop - marginBottom)/scale)); headerRect = wxRect(0, 0, 0, 0); if (!m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT).IsEmpty() || !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE).IsEmpty() || !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT).IsEmpty() || !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT).IsEmpty() || !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() || !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty()) { if (m_headerFooterData.GetFont().Ok()) dc->SetFont(m_headerFooterData.GetFont()); else dc->SetFont(*wxNORMAL_FONT); int charHeight = dc->GetCharHeight(); int headerHeight = (int) (charHeight + headerMargin/scale); headerRect = wxRect(rect.x, rect.y, rect.width, headerHeight); rect.y += headerHeight; rect.height -= headerHeight; } footerRect = wxRect(0, 0, 0, 0); if (!m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT).IsEmpty() || !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE).IsEmpty() || !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT).IsEmpty() || !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT).IsEmpty() || !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() || !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty()) { if (m_headerFooterData.GetFont().Ok()) dc->SetFont(m_headerFooterData.GetFont()); else dc->SetFont(*wxNORMAL_FONT); int charHeight = dc->GetCharHeight(); int footerHeight = (int) (charHeight + footerMargin/scale); footerRect = wxRect(rect.x, rect.y + rect.height, rect.width, footerHeight); rect.height -= footerHeight; } textRect = rect; }
void MyPrintout::DrawPageTwo() { // You might use THIS code to set the printer DC to ROUGHLY reflect // the screen text size. This page also draws lines of actual length // 5cm on the page. // Compare this to DrawPageOne(), which uses the really convenient routines // from wxPrintout to fit the screen image onto the printed page. This page // illustrates how to do all the scaling calculations yourself, if you're so // inclined. wxDC *dc = GetDC(); // Get the logical pixels per inch of screen and printer int ppiScreenX, ppiScreenY; GetPPIScreen(&ppiScreenX, &ppiScreenY); int ppiPrinterX, ppiPrinterY; GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); // This scales the DC so that the printout roughly represents the screen // scaling. The text point size _should_ be the right size but in fact is // too small for some reason. This is a detail that will need to be // addressed at some point but can be fudged for the moment. float scale = (float)((float)ppiPrinterX/(float)ppiScreenX); // Now we have to check in case our real page size is reduced (e.g. because // we're drawing to a print preview memory DC) int pageWidth, pageHeight; int w, h; dc->GetSize(&w, &h); GetPageSizePixels(&pageWidth, &pageHeight); // If printer pageWidth == current DC width, then this doesn't change. But w // might be the preview bitmap width, so scale down. float overallScale = scale * (float)(w/(float)pageWidth); dc->SetUserScale(overallScale, overallScale); // Calculate conversion factor for converting millimetres into logical // units. There are approx. 25.4 mm to the inch. There are ppi device units // to the inch. Therefore 1 mm corresponds to ppi/25.4 device units. We also // divide by the screen-to-printer scaling factor, because we need to // unscale to pass logical units to DrawLine. // Draw 50 mm by 50 mm L shape float logUnitsFactor = (float)(ppiPrinterX/(scale*25.4)); float logUnits = (float)(50*logUnitsFactor); dc->SetPen(* wxBLACK_PEN); dc->DrawLine(50, 250, (long)(50.0 + logUnits), 250); dc->DrawLine(50, 250, 50, (long)(250.0 + logUnits)); dc->SetBackgroundMode(wxTRANSPARENT); dc->SetBrush(*wxTRANSPARENT_BRUSH); { // GetTextExtent demo: wxString words[7] = { wxT("This "), wxT("is "), wxT("GetTextExtent "), wxT("testing "), wxT("string. "), wxT("Enjoy "), wxT("it!") }; wxCoord w, h; long x = 200, y= 250; wxFont fnt(15, wxSWISS, wxNORMAL, wxNORMAL); dc->SetFont(fnt); for (int i = 0; i < 7; i++) { wxString word = words[i]; word.Remove( word.Len()-1, 1 ); dc->GetTextExtent(word, &w, &h); dc->DrawRectangle(x, y, w, h); dc->GetTextExtent(words[i], &w, &h); dc->DrawText(words[i], x, y); x += w; } } dc->SetFont(wxGetApp().GetTestFont()); dc->DrawText(wxT("Some test text"), 200, 300 ); // TESTING int leftMargin = 20; int rightMargin = 20; int topMargin = 20; int bottomMargin = 20; int pageWidthMM, pageHeightMM; GetPageSizeMM(&pageWidthMM, &pageHeightMM); float leftMarginLogical = (float)(logUnitsFactor*leftMargin); float topMarginLogical = (float)(logUnitsFactor*topMargin); float bottomMarginLogical = (float)(logUnitsFactor*(pageHeightMM - bottomMargin)); float rightMarginLogical = (float)(logUnitsFactor*(pageWidthMM - rightMargin)); dc->SetPen(* wxRED_PEN); dc->DrawLine( (long)leftMarginLogical, (long)topMarginLogical, (long)rightMarginLogical, (long)topMarginLogical); dc->DrawLine( (long)leftMarginLogical, (long)bottomMarginLogical, (long)rightMarginLogical, (long)bottomMarginLogical); WritePageHeader(this, dc, wxT("A header"), logUnitsFactor); }
void TrussPrintout::OnPreparePrinting() { int page_width, page_height; int current_page_y = 0; GetPageSizePixels(&page_width, &page_height); wxDC *dc = GetDC(); int printer_x, printer_y, screen_x, screen_y; GetPPIPrinter(&printer_x, &printer_y); GetPPIScreen(&screen_x, &screen_y); float scale = printer_x / (float)screen_x; // Use a 12pt font. For some reason wxFont doesn't use real points, so // we still have to scale it. wxFont &font = *wxTheFontList->FindOrCreateFont( 12 * scale, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL ); dc->SetFont(font); // Margins: int ml, mt, mr, mb; int widthmm, heightmm; GetPageSizeMM(&widthmm, &heightmm); double one_mm_px = page_width / (double)widthmm; wxPoint margintl = page_setup_dialog_data->GetMarginTopLeft(); wxPoint marginbr = page_setup_dialog_data->GetMarginBottomRight(); ml = margintl.x * one_mm_px; mt = margintl.y * one_mm_px; mr = marginbr.x * one_mm_px; mb = marginbr.y * one_mm_px; page_height -= mt + mb; page_width -= ml + mr; for (int i = 0; i < printitems.size(); ++i) { if (printitems[i]->isbreak()) { PageBreak *pb = static_cast<PageBreak *>(printitems[i]); // Add room for the page header/title. current_page_y = get_text_height(*dc, pb->header); pages.push_back(Page(pb->header, ml, mt, mr, mb)); delete pb; } else { Truss *truss = static_cast<TrussContainer *>(printitems[i])->truss; int truss_height_px = truss->getHeight() * page_width / (60.0 * 12.0); int total_height = truss_height_px + get_text_height(*dc, truss->gettext()); if (!truss->getnotes().empty()) { total_height += get_text_height(*dc, truss->getnotes()); // Add the 1/2 line padding in between title and notes total_height += get_text_height(*dc, wxT("X")) / 2; } if (current_page_y + total_height > page_height) { current_page_y = get_text_height(*dc, "continuation..."); pages.push_back(Page("continuation...", ml, mt, mr, mb)); } pages.back().add(truss); current_page_y += total_height; // Add 3 blank lines of padding before the next truss. current_page_y += get_text_height(*dc, wxT("X")) * 3; delete static_cast<TrussContainer *>(printitems[i]); } } printitems.clear(); }
/* * This is the real print function: print the active screen */ void BOARD_PRINTOUT_CONTROLER::DrawPage() { int tmpzoom; wxPoint tmp_startvisu; wxPoint old_org; wxPoint DrawOffset; // Offset de trace double userscale; double DrawZoom = 1; wxDC* dc = GetDC(); PCB_SCREEN* screen = (PCB_SCREEN*) m_Parent->GetScreen(); bool printMirror = m_PrintParams.m_PrintMirror; wxBusyCursor dummy; // Save old draw scale and draw offset tmp_startvisu = screen->m_StartVisu; tmpzoom = screen->GetZoom(); old_org = screen->m_DrawOrg; // Change draw scale and offset to draw the whole page screen->SetScalingFactor( DrawZoom ); screen->m_DrawOrg.x = screen->m_DrawOrg.y = 0; screen->m_StartVisu.x = screen->m_StartVisu.y = 0; PCB_BASE_FRAME* pcbframe = (PCB_BASE_FRAME*) m_Parent; wxSize pageSizeIU = pcbframe->GetPageSizeIU(); // internal units EDA_RECT bbbox = pcbframe->GetBoard()->ComputeBoundingBox(); // In module editor, the module is located at 0,0 but for printing // it is moved to pageSizeIU.x/2, pageSizeIU.y/2. // So the equivalent board must be moved: if( m_Parent->IsType( MODULE_EDITOR_FRAME ) ) { bbbox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) ); } // Compute the PCB size in internal units userscale = m_PrintParams.m_PrintScale; if( userscale == 0 ) // fit in page { // Margin = 0.4 inch #if defined(KICAD_NANOMETRE) int extra_margin = int( 0.4 * 25400 ); // nanometers #else int extra_margin = int( 0.4 * 1000 ); // deci-mils #endif pageSizeIU.x = bbbox.GetWidth() + extra_margin * 2; pageSizeIU.y = bbbox.GetHeight() + extra_margin * 2; userscale = 0.99; } if( (m_PrintParams.m_PrintScale > 1.0) // scale > 1 -> Recadrage || (m_PrintParams.m_PrintScale == 0) ) // fit in page { DrawOffset += bbbox.Centre(); } if( m_PrintParams.m_PageSetupData ) { wxSize pagesize; pagesize.x = int( pageSizeIU.x / userscale ); pagesize.y = int( pageSizeIU.y / userscale ); FitThisSizeToPageMargins( pagesize, *m_PrintParams.m_PageSetupData ); } // Compute Accurate scale 1 if( userscale == 1.0 ) { // We want a 1:1 scale and margins for printing MapScreenSizeToPaper(); int w, h; GetPPIPrinter( &w, &h ); double accurate_Xscale = ( (double) ( DrawZoom * w ) ) / (double) PCB_INTERNAL_UNIT; double accurate_Yscale = ( (double) ( DrawZoom * h ) ) / (double) PCB_INTERNAL_UNIT; if( IsPreview() ) // Scale must take in account the DC size in Preview { // Get the size of the DC in pixels wxSize PlotAreaSize; dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y ); GetPageSizePixels( &w, &h ); accurate_Xscale *= PlotAreaSize.x; accurate_Xscale /= (double) w; accurate_Yscale *= PlotAreaSize.y; accurate_Yscale /= (double) h; } accurate_Xscale *= m_PrintParams.m_XScaleAdjust; accurate_Yscale *= m_PrintParams.m_YScaleAdjust; // Fine scale adjust dc->SetUserScale( accurate_Xscale, accurate_Yscale ); } // Get the final size of the DC in pixels wxSize PlotAreaSizeInPixels; dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y ); double scalex, scaley; dc->GetUserScale(&scalex, &scaley); wxSize PlotAreaSizeInUserUnits; PlotAreaSizeInUserUnits.x = (int) (PlotAreaSizeInPixels.x/scalex); PlotAreaSizeInUserUnits.y = (int) (PlotAreaSizeInPixels.y/scaley); /* In some cases the plot origin is the centre of the page * when: * - Asked * - scale > 1 * - fit in page */ if( m_PrintParams.m_ForceCentered || (m_PrintParams.m_PrintScale > 1.0) // scale > 1 || (m_PrintParams.m_PrintScale == 0) ) // fit in page { DrawOffset.x -= PlotAreaSizeInUserUnits.x / 2; DrawOffset.y -= PlotAreaSizeInUserUnits.y / 2; } screen->m_DrawOrg = DrawOffset; GRResetPenAndBrush( dc ); if( m_PrintParams.m_Print_Black_and_White ) GRForceBlackPen( true ); EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); EDA_RECT tmp = *panel->GetClipBox(); // Set clip box to the max size #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 ) ) ); m_Parent->GetScreen()->m_IsPrinting = true; int bg_color = g_DrawBgColor; if( m_PrintParams.m_Print_Sheet_Ref ) m_Parent->TraceWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize ); if( printMirror ) { // To plot mirror, we reverse the y axis, and modify the plot y origin dc->SetAxisOrientation( true, true ); if( userscale < 1.0 ) scaley /= userscale; /* Plot offset y is moved by the y plot area size in order to have * the old draw area in the new draw area, because the draw origin has not moved * (this is the upper left corner) but the Y axis is reversed, therefore the plotting area * is the y coordinate values from - PlotAreaSize.y to 0 */ int y_dc_offset = PlotAreaSizeInPixels.y; y_dc_offset = (int) ( ( double ) y_dc_offset * userscale ); dc->SetDeviceOrigin( 0, y_dc_offset ); int ysize = (int) ( PlotAreaSizeInPixels.y / scaley ); DrawOffset.y += ysize; /* in order to keep the board position in the sheet * (when user scale <= 1) the y offset in moved by the distance between * the middle of the page and the middle of the board * This is equivalent to put the mirror axis to the board centre * for scales > 1, the DrawOffset was already computed to have the board centre * to the middle of the page. */ wxPoint pcb_centre = bbbox.Centre(); if( userscale <= 1.0 ) DrawOffset.y += pcb_centre.y - (ysize / 2); dc->SetLogicalOrigin( screen->m_DrawOrg.x, screen->m_DrawOrg.y ); panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE/2, -MAX_VALUE/2 ), panel->GetClipBox()->GetSize() ) ); } g_DrawBgColor = WHITE; /* when printing in color mode, we use the graphic OR mode that gives the same look as the screen * But because the background is white when printing, we must use a trick: * In order to plot on a white background in OR mode we must: * 1 - Plot all items in black, this creates a local black backgroud * 2 - Plot in OR mode on black "local" background */ if( !m_PrintParams.m_Print_Black_and_White ) { // Creates a "local" black background GRForceBlackPen( true ); m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); GRForceBlackPen( false ); } m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); g_DrawBgColor = bg_color; m_Parent->GetScreen()->m_IsPrinting = false; panel->SetClipBox( tmp ); GRForceBlackPen( false ); screen->m_StartVisu = tmp_startvisu; screen->m_DrawOrg = old_org; screen->SetZoom( tmpzoom ); }
void wxHtmlPrintout::OnPreparePrinting() { int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h; float ppmm_h, ppmm_v; GetPageSizePixels(&pageWidth, &pageHeight); GetPageSizeMM(&mm_w, &mm_h); ppmm_h = (float)pageWidth / mm_w; ppmm_v = (float)pageHeight / mm_h; int ppiPrinterX, ppiPrinterY; GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); wxUnusedVar(ppiPrinterX); int ppiScreenX, ppiScreenY; GetPPIScreen(&ppiScreenX, &ppiScreenY); wxUnusedVar(ppiScreenX); wxDisplaySize(&scr_w, &scr_h); GetDC()->GetSize(&dc_w, &dc_h); GetDC()->SetUserScale((double)dc_w / (double)pageWidth, (double)dc_h / (double)pageHeight); /* prepare headers/footers renderer: */ m_RendererHdr->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY); m_RendererHdr->SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)), (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom))); if (m_Headers[0] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[0], 1)); m_HeaderHeight = m_RendererHdr->GetTotalHeight(); } else if (m_Headers[1] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[1], 1)); m_HeaderHeight = m_RendererHdr->GetTotalHeight(); } if (m_Footers[0] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[0], 1)); m_FooterHeight = m_RendererHdr->GetTotalHeight(); } else if (m_Footers[1] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[1], 1)); m_FooterHeight = m_RendererHdr->GetTotalHeight(); } /* prepare main renderer: */ m_Renderer->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY); const int printAreaW = int(ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)); int printAreaH = int(ppmm_v * (mm_h - m_MarginTop - m_MarginBottom)); if ( m_HeaderHeight ) printAreaH -= int(m_HeaderHeight + m_MarginSpace * ppmm_v); if ( m_FooterHeight ) printAreaH -= int(m_FooterHeight + m_MarginSpace * ppmm_v); m_Renderer->SetSize(printAreaW, printAreaH); m_Renderer->SetHtmlText(m_Document, m_BasePath, m_BasePathIsDir); if ( CheckFit(wxSize(printAreaW, printAreaH), wxSize(m_Renderer->GetTotalWidth(), m_Renderer->GetTotalHeight())) ) { // do paginate the document CountPages(); } //else: if we don't call CountPages() m_PageBreaks remains empty and our // GetPageInfo() will return 0 as max page and so nothing will be // printed }
void RawDataVisualizePrintout::DrawPageOne(wxDC *dc) { // You might use THIS code if you were scaling // graphics of known size to fit on the page. // We know the graphic is 200x200. If we didn't know this, // we'd need to calculate it. /* float maxX = 1200; float maxY = 915; // Let's have at least 50 device units margin float marginX = 50; float marginY = 50; // Add the margin to the graphic size maxX += (2*marginX); maxY += (2*marginY); // Get the size of the DC in pixels int w, h; dc->GetSize(&w, &h); // Calculate a suitable scaling factor float scaleX=(float)(w/maxX); float scaleY=(float)(h/maxY); // Use x or y scaling factor, whichever fits on the DC float actualScale = wxMin(scaleX,scaleY); // Calculate the position on the DC for centring the graphic float posX = (float)((w - (200*actualScale))/2.0); float posY = (float)((h - (200*actualScale))/2.0); // Set the scale and origin dc->SetUserScale(actualScale, actualScale); dc->SetDeviceOrigin( (long)posX, (long)posY ); */ // Get the logical pixels per inch of screen and printer int ppiScreenX, ppiScreenY; GetPPIScreen(&ppiScreenX, &ppiScreenY); int ppiPrinterX, ppiPrinterY; GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); // This scales the DC so that the printout roughly represents the // the screen scaling. The text point size _should_ be the right size // but in fact is too small for some reason. This is a detail that will // need to be addressed at some point but can be fudged for the // moment. float scale = 1.0; //(float)((float)ppiPrinterX/(float)ppiScreenX); // Now we have to check in case our real page size is reduced // (e.g. because we're drawing to a print preview memory DC) int pageWidth, pageHeight; int w, h; dc->GetSize(&w, &h); GetPageSizePixels(&pageWidth, &pageHeight); // If printer pageWidth == current DC width, then this doesn't // change. But w might be the preview bitmap width, so scale down. float overallScale = scale * ((float)w/(float)pageWidth); dc->SetUserScale(overallScale, overallScale); wxPrintf(_T("%d %d\n"),w,h); wxPrintf(_T("%d %d\n"),pageWidth, pageHeight); wxPrintf(_T("%d %d\n"),ppiScreenX, ppiScreenY); wxPrintf(_T("%d %d\n"),ppiPrinterX, ppiPrinterY); if (frame->currentplot == 1) frame->DrawRawBoxplot(*dc); else if (frame->currentplot == 2) frame->DrawRawDensityPlot(*dc); }
void EDA_Printout::DrawPage(void) /********************************/ /* This is the real print function: print the active screen */ { int tmpzoom; wxPoint tmp_startvisu; wxSize PageSize_in_mm; wxSize SheetSize; // Sheet size in internal units wxSize PlotAreaSize; // Taille de la surface utile de trace (pixels) double scaleX, scaleY, scale; wxPoint old_org; wxPoint DrawOffset; // Offset de trace double userscale; wxDC * dc = GetDC(); int DrawZoom = 1; wxBusyCursor dummy; GetPageSizeMM(&PageSize_in_mm.x, &PageSize_in_mm.y); /* Save old draw scale and draw offset */ tmp_startvisu = ActiveScreen->m_StartVisu; tmpzoom = ActiveScreen->GetZoom(); old_org = ActiveScreen->m_DrawOrg; /* Change draw scale and offset to draw the whole page*/ ActiveScreen->SetZoom(DrawZoom); ActiveScreen->m_DrawOrg.x = ActiveScreen->m_DrawOrg.y = 0; ActiveScreen->m_StartVisu.x = ActiveScreen->m_StartVisu.y = 0; SheetSize = ActiveScreen->m_CurrentSheet->m_Size; // size in 1/1000 inch SheetSize.x *= m_Parent->m_InternalUnits / 1000; SheetSize.y *= m_Parent->m_InternalUnits / 1000; // size in pixels // Get the size of the DC in pixels dc->GetSize(&PlotAreaSize.x, &PlotAreaSize.y); #ifdef PCBNEW WinEDA_BasePcbFrame * pcbframe = (WinEDA_BasePcbFrame*) m_Parent; pcbframe->m_Pcb->ComputeBoundaryBox(); /* calcul des dimensions du PCB */ if (s_ScaleList[s_Scale_Select] == 0) // fit in page { int extra_margin = 8000; // Margin = 8000/2 units pcb = 0,4 inch SheetSize.x = pcbframe->m_Pcb->m_BoundaryBox.GetWidth() + extra_margin; SheetSize.y = pcbframe->m_Pcb->m_BoundaryBox.GetHeight() + extra_margin; userscale = 0.99; } else userscale = s_ScaleList[s_Scale_Select]; if ( (s_ScaleList[s_Scale_Select] > 1.0) || // scale > 1 -> Recadrage (s_ScaleList[s_Scale_Select] == 0) ) // fit in page { DrawOffset.x += pcbframe->m_Pcb->m_BoundaryBox.Centre().x; DrawOffset.y += pcbframe->m_Pcb->m_BoundaryBox.Centre().y; } #endif // Calculate a suitable scaling factor scaleX = (double)SheetSize.x / PlotAreaSize.x; scaleY = (double)SheetSize.y / PlotAreaSize.y; scale = wxMax(scaleX,scaleY) / userscale; // Use x or y scaling factor, whichever fits on the DC // ajust the real draw scale #ifdef PCBNEW double accurate_Xscale, accurate_Yscale; dc->SetUserScale(DrawZoom / scale * m_PrintFrame->m_XScaleAdjust, DrawZoom / scale * m_PrintFrame->m_YScaleAdjust); // Compute Accurate scale 1 { int w, h; GetPPIPrinter(&w, &h); accurate_Xscale = ((double)(DrawZoom * w))/ PCB_INTERNAL_UNIT; accurate_Yscale = ((double)(DrawZoom * h))/ PCB_INTERNAL_UNIT; if ( IsPreview() ) // Scale must take in account the DC size in Preview { // Get the size of the DC in pixels dc->GetSize(&PlotAreaSize.x, &PlotAreaSize.y); GetPageSizePixels(&w, &h); accurate_Xscale *= PlotAreaSize.x; accurate_Xscale /= w; accurate_Yscale *= PlotAreaSize.y; accurate_Yscale /= h; } accurate_Xscale *= m_PrintFrame->m_XScaleAdjust; accurate_Yscale *= m_PrintFrame->m_YScaleAdjust; } #else dc->SetUserScale(DrawZoom / scale, DrawZoom / scale); #endif #ifdef PCBNEW if ( (s_ScaleList[s_Scale_Select] > 1.0) || // scale > 1 -> Recadrage (s_ScaleList[s_Scale_Select] == 0) ) // fit in page { DrawOffset.x -= (int)( (PlotAreaSize.x/2) * scale); DrawOffset.y -= (int)( (PlotAreaSize.y/2) * scale ); } DrawOffset.x += (int)( (SheetSize.x/2) * (m_PrintFrame->m_XScaleAdjust -1.0)); DrawOffset.y += (int)( (SheetSize.y/2) * (m_PrintFrame->m_YScaleAdjust -1.0)); #endif ActiveScreen->m_DrawOrg = DrawOffset; GRResetPenAndBrush(dc); if( s_Print_Black_and_White ) GRForceBlackPen(TRUE); #ifdef EESCHEMA /* set Pen min width */ float ftmp; // PenMinWidth est donné en 1/100 mm, a convertir en pixels ftmp = (float)PenMinWidth / 100; // ftmp est en mm ftmp *= (float)PlotAreaSize.x / PageSize_in_mm.x; /* ftmp est en pixels */ SetPenMinWidth((int)ftmp); #else SetPenMinWidth(1); #endif WinEDA_DrawPanel * panel = m_Parent->DrawPanel; EDA_Rect tmp = panel->m_ClipBox; panel->m_ClipBox.SetOrigin(wxPoint(0,0)); panel->m_ClipBox.SetSize(wxSize(0x7FFFFF0, 0x7FFFFF0)); g_IsPrinting = TRUE; #ifdef EESCHEMA if( s_Print_Black_and_White ) g_PrintFillMask = FILLED_WITH_BG_BODYCOLOR; #endif #ifdef PCBNEW if ( userscale == 1.0 ) // Draw the Sheet refs at optimum scale, and board at 1.0 scale { if ( m_Print_Sheet_Ref ) m_Parent->TraceWorkSheet( dc, ActiveScreen); m_Print_Sheet_Ref = FALSE; dc->SetUserScale( accurate_Yscale, accurate_Yscale); } #endif panel->PrintPage(dc, m_Print_Sheet_Ref, s_PrintMaskLayer); #ifdef EESCHEMA g_PrintFillMask = 0; #endif g_IsPrinting = FALSE; panel->m_ClipBox = tmp; SetPenMinWidth(1); GRForceBlackPen(FALSE); ActiveScreen->m_StartVisu = tmp_startvisu; ActiveScreen->m_DrawOrg = old_org; ActiveScreen->SetZoom(tmpzoom); }
void BOARD_PRINTOUT_CONTROLLER::DrawPage() { wxPoint offset; double userscale; EDA_RECT boardBoundingBox; EDA_RECT drawRect; wxDC* dc = GetDC(); BASE_SCREEN* screen = m_Parent->GetScreen(); bool printMirror = m_PrintParams.m_PrintMirror; wxSize pageSizeIU = m_Parent->GetPageSizeIU(); wxBusyCursor dummy; boardBoundingBox = ((GERBVIEW_FRAME*) m_Parent)->GetGerberLayoutBoundingBox(); wxString titleblockFilename; // TODO see if we uses the gerber file name // Use the page size as the drawing area when the board is shown or the user scale // is less than 1. if( m_PrintParams.PrintBorderAndTitleBlock() ) boardBoundingBox = EDA_RECT( wxPoint( 0, 0 ), pageSizeIU ); // Compute the PCB size in internal units userscale = m_PrintParams.m_PrintScale; if( m_PrintParams.m_PrintScale == 0 ) // fit in page option { if(boardBoundingBox.GetWidth() && boardBoundingBox.GetHeight()) { int margin = Millimeter2iu( 10.0 ); // add a margin around the drawings double scaleX = (double)(pageSizeIU.x - (2 * margin)) / boardBoundingBox.GetWidth(); double scaleY = (double)(pageSizeIU.y - (2 * margin)) / boardBoundingBox.GetHeight(); userscale = (scaleX < scaleY) ? scaleX : scaleY; } else userscale = 1.0; } wxSize scaledPageSize = pageSizeIU; drawRect.SetSize( scaledPageSize ); scaledPageSize.x = wxRound( scaledPageSize.x / userscale ); scaledPageSize.y = wxRound( scaledPageSize.y / userscale ); if( m_PrintParams.m_PageSetupData ) { // Always scale to the size of the paper. FitThisSizeToPageMargins( scaledPageSize, *m_PrintParams.m_PageSetupData ); } // Compute Accurate scale 1 if( m_PrintParams.m_PrintScale == 1.0 ) { // We want a 1:1 scale, regardless the page setup // like page size, margin ... MapScreenSizeToPaper(); // set best scale and offset (scale is not used) int w, h; GetPPIPrinter( &w, &h ); double accurate_Xscale = (double) w / (IU_PER_MILS*1000); double accurate_Yscale = (double) h / (IU_PER_MILS*1000); if( IsPreview() ) // Scale must take in account the DC size in Preview { // Get the size of the DC in pixels wxSize PlotAreaSize; dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y ); GetPageSizePixels( &w, &h ); accurate_Xscale *= (double)PlotAreaSize.x / w; accurate_Yscale *= (double)PlotAreaSize.y / h; } // Fine scale adjust accurate_Xscale *= m_PrintParams.m_XScaleAdjust; accurate_Yscale *= m_PrintParams.m_YScaleAdjust; // Set print scale for 1:1 exact scale dc->SetUserScale( accurate_Xscale, accurate_Yscale ); } // Get the final size of the DC in pixels wxSize PlotAreaSizeInPixels; dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y ); double scalex, scaley; dc->GetUserScale( &scalex, &scaley ); // In some cases the plot origin is the centre of the board outline rather than the center // of the selected paper size. if( m_PrintParams.CenterOnBoardOutline() ) { // Here we are only drawing the board and it's contents. drawRect = boardBoundingBox; offset.x += wxRound( (double) -scaledPageSize.x / 2.0 ); offset.y += wxRound( (double) -scaledPageSize.y / 2.0 ); wxPoint center = boardBoundingBox.Centre(); if( printMirror ) { // Calculate the mirrored center of the board. center.x = m_Parent->GetPageSizeIU().x - boardBoundingBox.Centre().x; } offset += center; } GRResetPenAndBrush( dc ); EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); EDA_RECT tmp = *panel->GetClipBox(); // Set clip box to the max size #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 ) ) ); screen->m_IsPrinting = true; EDA_COLOR_T bg_color = m_Parent->GetDrawBgColor(); // Print frame reference, if requested, before printing draw layers if( m_PrintParams.m_Print_Black_and_White ) GRForceBlackPen( true ); if( m_PrintParams.PrintBorderAndTitleBlock() ) m_Parent->DrawWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize, IU_PER_MILS, titleblockFilename ); if( printMirror ) { // To plot mirror, we reverse the x axis, and modify the plot x origin dc->SetAxisOrientation( false, false ); /* Change plot offset in order to have the draw area at the same location. * The plot origin X is just moved from 0 to PlotAreaSizeInPixels.x. * just set offset x at PlotAreaSizeInPixels.x. */ int x_dc_offset = PlotAreaSizeInPixels.x; x_dc_offset = KiROUND( x_dc_offset * userscale ); dc->SetDeviceOrigin( x_dc_offset, 0 ); panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE / 2, -MAX_VALUE / 2 ), panel->GetClipBox()->GetSize() ) ); } // screen->m_DrawOrg = offset; dc->SetLogicalOrigin( offset.x, offset.y ); m_Parent->SetDrawBgColor( WHITE ); // Never force black pen to print draw layers // because negative objects need a white pen, not a black pen // B&W mode is handled in print page function GRForceBlackPen( false ); m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); m_Parent->SetDrawBgColor( bg_color ); screen->m_IsPrinting = false; panel->SetClipBox( tmp ); }