void wxMacPrintPreview::DetermineScaling(void) { int screenWidth , screenHeight ; wxDisplaySize( &screenWidth , &screenHeight ) ; wxSize ppiScreen( 72 , 72 ) ; wxSize ppiPrinter( 72 , 72 ) ; // Note that with Leopard, screen dpi=72 is no longer a given m_previewPrintout->SetPPIScreen( ppiScreen.x , ppiScreen.y ) ; wxCoord w , h ; wxCoord ww, hh; wxRect paperRect; // Get a device context for the currently selected printer wxPrinterDC printerDC(m_printDialogData.GetPrintData()); if (printerDC.IsOk()) { printerDC.GetSizeMM(&ww, &hh); printerDC.GetSize( &w , &h ) ; ppiPrinter = printerDC.GetPPI() ; paperRect = printerDC.GetPaperRect(); m_isOk = true ; } else { // use some defaults w = 8 * 72 ; h = 11 * 72 ; ww = (wxCoord) (w * 25.4 / ppiPrinter.x) ; hh = (wxCoord) (h * 25.4 / ppiPrinter.y) ; paperRect = wxRect(0, 0, w, h); m_isOk = false ; } m_pageWidth = w; m_pageHeight = h; m_previewPrintout->SetPageSizePixels(w , h) ; m_previewPrintout->SetPageSizeMM(ww, hh); m_previewPrintout->SetPaperRectPixels(paperRect); m_previewPrintout->SetPPIPrinter( ppiPrinter.x , ppiPrinter.y ) ; m_previewScaleX = float(ppiScreen.x) / ppiPrinter.x; m_previewScaleY = float(ppiScreen.y) / ppiPrinter.y; }
void wxWindowsPrintPreview::DetermineScaling() { HDC dc = ::GetDC(NULL); int screenWidth = ::GetDeviceCaps(dc, HORZSIZE); int screenYRes = ::GetDeviceCaps(dc, VERTRES); int logPPIScreenX = ::GetDeviceCaps(dc, LOGPIXELSX); int logPPIScreenY = ::GetDeviceCaps(dc, LOGPIXELSY); m_previewPrintout->SetPPIScreen(logPPIScreenX, logPPIScreenY); ::ReleaseDC(NULL, dc); // Get a device context for the currently selected printer wxPrinterDC printerDC(m_printDialogData.GetPrintData()); int printerWidth = 150; int printerHeight wxDUMMY_INITIALIZE(250); int printerXRes = 1500; int printerYRes = 2500; dc = GetHdcOf(printerDC); if ( dc ) { printerWidth = ::GetDeviceCaps(dc, HORZSIZE); printerHeight = ::GetDeviceCaps(dc, VERTSIZE); printerXRes = ::GetDeviceCaps(dc, HORZRES); printerYRes = ::GetDeviceCaps(dc, VERTRES); int logPPIPrinterX = ::GetDeviceCaps(dc, LOGPIXELSX); int logPPIPrinterY = ::GetDeviceCaps(dc, LOGPIXELSY); m_previewPrintout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY); m_previewPrintout->SetPageSizeMM(printerWidth, printerHeight); if (logPPIPrinterX == 0 || logPPIPrinterY == 0 || printerWidth == 0 || printerHeight == 0) m_isOk = false; } else m_isOk = false; m_pageWidth = printerXRes; m_pageHeight = printerYRes; // At 100%, the page should look about page-size on the screen. m_previewScale = (float)((float)screenWidth/(float)printerWidth); m_previewScale = m_previewScale * (float)((float)screenYRes/(float)printerYRes); }
bool wxWindowsPrintPreview::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum) { // The preview, as implemented in wxPrintPreviewBase (and as used prior to // wx3) is inexact: it uses screen DC, which has much lower resolution and // has other properties different from printer DC, so the preview is not // quite right. // // To make matters worse, if the application depends heavily on // GetTextExtent() or does text layout itself, the output in preview and on // paper can be very different. In particular, wxHtmlEasyPrinting is // affected and the preview can be easily off by several pages. // // To fix this, we render the preview into high-resolution enhanced // metafile with properties identical to the printer DC. This guarantees // metrics correctness while still being fast. // print the preview into a metafile: wxPrinterDC printerDC(m_printDialogData.GetPrintData()); wxEnhMetaFileDC metaDC(printerDC, wxEmptyString, printerDC.GetSize().x, printerDC.GetSize().y); if ( !RenderPageIntoDC(metaDC, pageNum) ) return false; wxEnhMetaFile *metafile = metaDC.Close(); if ( !metafile ) return false; // now render the metafile: wxMemoryDC bmpDC; bmpDC.SelectObject(bmp); bmpDC.Clear(); wxRect outRect(0, 0, bmp.GetWidth(), bmp.GetHeight()); metafile->Play(&bmpDC, &outRect); delete metafile; // TODO: we should keep the metafile and reuse it when changing zoom level return true; }
void wxMacPrintPreview::DetermineScaling(void) { int screenWidth , screenHeight ; wxDisplaySize( &screenWidth , &screenHeight ) ; m_previewPrintout->SetPPIScreen( 72 , 72 ) ; m_previewPrintout->SetPPIPrinter( 72 , 72 ) ; m_previewPrintout->SetPageSizeMM( (int) (8.0 * 25.6), (int) (11.0 * 25.6) ); m_previewPrintout->SetPageSizePixels( 8 * 72 , 11 * 72 ) ; m_pageWidth = 8 * 72 ; m_pageHeight = 11 * 72 ; m_previewScale = 1 ; // Get a device context for the currently selected printer wxPrinterDC printerDC(m_printDialogData.GetPrintData()); if (printerDC.Ok()) { int x , y ; wxCoord ww, hh; printerDC.GetSizeMM(&ww, &hh); printerDC.GetSize( &x , &y ) ; m_previewPrintout->SetPageSizeMM((int)ww, (int)hh); m_previewPrintout->SetPageSizePixels( x , y) ; m_pageWidth = x ; m_pageHeight = y ; m_isOk = true ; } else { m_isOk = false ; } // At 100%, the page should look about page-size on the screen. // m_previewScale = (float)((float)screenWidth/(float)printerWidth); // m_previewScale = m_previewScale * (float)((float)screenXRes/(float)printerXRes); m_previewScale = 1 ; }
void wxWindowsPrintPreview::DetermineScaling() { ScreenHDC dc; int logPPIScreenX = ::GetDeviceCaps(dc, LOGPIXELSX); int logPPIScreenY = ::GetDeviceCaps(dc, LOGPIXELSY); m_previewPrintout->SetPPIScreen(logPPIScreenX, logPPIScreenY); // Get a device context for the currently selected printer wxPrinterDC printerDC(m_printDialogData.GetPrintData()); int printerWidthMM; int printerHeightMM; int printerXRes; int printerYRes; int logPPIPrinterX; int logPPIPrinterY; wxRect paperRect; if ( printerDC.IsOk() ) { wxPrinterDCImpl *impl = (wxPrinterDCImpl*) printerDC.GetImpl(); HDC hdc = GetHdcOf(*impl); printerWidthMM = ::GetDeviceCaps(hdc, HORZSIZE); printerHeightMM = ::GetDeviceCaps(hdc, VERTSIZE); printerXRes = ::GetDeviceCaps(hdc, HORZRES); printerYRes = ::GetDeviceCaps(hdc, VERTRES); logPPIPrinterX = ::GetDeviceCaps(hdc, LOGPIXELSX); logPPIPrinterY = ::GetDeviceCaps(hdc, LOGPIXELSY); paperRect = printerDC.GetPaperRect(); if ( logPPIPrinterX == 0 || logPPIPrinterY == 0 || printerWidthMM == 0 || printerHeightMM == 0 ) { m_isOk = false; } } else { // use some defaults printerWidthMM = 150; printerHeightMM = 250; printerXRes = 1500; printerYRes = 2500; logPPIPrinterX = 600; logPPIPrinterY = 600; paperRect = wxRect(0, 0, printerXRes, printerYRes); m_isOk = false; } m_pageWidth = printerXRes; m_pageHeight = printerYRes; m_previewPrintout->SetPageSizePixels(printerXRes, printerYRes); m_previewPrintout->SetPageSizeMM(printerWidthMM, printerHeightMM); m_previewPrintout->SetPaperRectPixels(paperRect); m_previewPrintout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY); // At 100%, the page should look about page-size on the screen. m_previewScaleX = float(logPPIScreenX) / logPPIPrinterX; m_previewScaleY = float(logPPIScreenY) / logPPIPrinterY; }
bool wxWindowsPrintPreview::RenderPageIntoBitmapHQ(wxBitmap& bmp, int pageNum) { wxLogTrace("printing", "rendering HQ preview of page %i", pageNum); wxPrinterDC printerDC(m_printDialogData.GetPrintData()); if ( !printerDC.IsOk() ) return false; // compute scale factor const float scaleX = float(bmp.GetWidth()) / float(m_pageWidth); const float scaleY = float(bmp.GetHeight()) / float(m_pageHeight); wxMemoryDC bmpDC; bmpDC.SelectObject(bmp); bmpDC.Clear(); const int initialStep = ComputeFragmentSize(printerDC.GetDepth(), m_pageWidth, m_pageHeight); wxRect todo(0, 0, m_pageWidth, initialStep); // rect to render int nextFinalLine = 0; // first not-yet-rendered output line while ( todo.y < m_pageHeight ) { todo.SetBottom(wxMin(todo.GetBottom(), m_pageHeight - 1)); if ( !RenderPageFragment(scaleX, scaleY, &nextFinalLine, printerDC, bmpDC, todo, pageNum) ) { if ( todo.height < 20 ) { // something is very wrong if we can't render even at this // slow space, let's bail out and fall back to low quality // preview wxLogTrace("printing", "it seems that HQ preview doesn't work at all"); return false; } // it's possible our memory calculation was off, or conditions // changed, or there's not enough _bitmap_ resources; try if using // smaller bitmap would help: todo.height /= 2; wxLogTrace("printing", "preview of fragment failed, reducing height to %ipx", todo.height); continue; // retry at the same position again } // move to the next segment todo.Offset(0, todo.height); } return true; }