void CalculateScale(PrintAttributes newAttributes) { int dpi = Math.Max(newAttributes.GetResolution().HorizontalDpi, newAttributes.GetResolution().VerticalDpi); int leftMargin = (int)(dpi * (float)newAttributes.MinMargins.LeftMils / 1000); int rightMargin = (int)(dpi * (float)newAttributes.MinMargins.RightMils / 1000); int topMargin = (int)(dpi * (float)newAttributes.MinMargins.TopMils / 1000); int bottomMargin = (int)(dpi * (float)newAttributes.MinMargins.BottomMils / 1000); int w = (int)(dpi * (float)newAttributes.GetMediaSize().WidthMils / 1000) - leftMargin - rightMargin; int h = (int)(dpi * (float)newAttributes.GetMediaSize().HeightMils / 1000) - topMargin - bottomMargin; scale = Math.Min((float)document.PageContentRect.Width() / w, (float)document.PageContentRect.Height() / h); }
public override void OnLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) { // If we are already cancelled, don't do any work. if (cancellationSignal.IsCanceled) { callback.OnLayoutCancelled(); return; } // Now we determined if the print attributes changed in a way that // would change the layout and if so we will do a layout pass. bool layoutNeeded = false; int density = System.Math.Max(newAttributes.GetResolution().HorizontalDpi, newAttributes.GetResolution().VerticalDpi); // Note that we are using the PrintedPdfDocument class which creates // a PDF generating canvas whose size is in points (1/72") not screen // pixels. Hence, this canvas is pretty small compared to the screen. // The recommended way is to layout the content in the desired size, // in this case as large as the printer can do, and set a translation // to the PDF canvas to shrink in. Note that PDF is a vector format // and you will not lose data during the transformation. // The content width is equal to the page width minus the margins times // the horizontal printer density. This way we get the maximal number // of pixels the printer can put horizontally. int marginLeft = (int)(density * (float)newAttributes.MinMargins.LeftMils / MILS_IN_INCH); int marginRight = (int)(density * (float)newAttributes.MinMargins.RightMils / MILS_IN_INCH); int contentWidth = (int)(density * (float)newAttributes.GetMediaSize() .WidthMils / MILS_IN_INCH) - marginLeft - marginRight; if (mRenderPageWidth != contentWidth) { mRenderPageWidth = contentWidth; layoutNeeded = true; } // The content height is equal to the page height minus the margins times // the vertical printer resolution. This way we get the maximal number // of pixels the printer can put vertically. int marginTop = (int)(density * (float)newAttributes.MinMargins.TopMils / MILS_IN_INCH); int marginBottom = (int)(density * (float)newAttributes.MinMargins.BottomMils / MILS_IN_INCH); int contentHeight = (int)(density * (float)newAttributes.GetMediaSize() .HeightMils / MILS_IN_INCH) - marginTop - marginBottom; if (mRenderPageHeight != contentHeight) { mRenderPageHeight = contentHeight; layoutNeeded = true; } // Create a context for resources at printer density. We will // be inflating views to render them and would like them to use // resources for a density the printer supports. if (mPrintContext == null || mPrintContext.Resources.Configuration.DensityDpi != density) { var configuration = new Configuration(); configuration.DensityDpi = density; mPrintContext = pcc.CreateConfigurationContext(configuration); mPrintContext.SetTheme(Android.Resource.Style.ThemeHoloLight); } // If no layout is needed that we did a layout at least once and // the document info is not null, also the second argument is false // to notify the system that the content did not change. This is // important as if the system has some pages and the content didn't // change the system will ask, the application to write them again. if (!layoutNeeded) { callback.OnLayoutFinished(mDocumentInfo, false); return; } // For demonstration purposes we will do the layout off the main // thread but for small content sizes like this one it is OK to do // that on the main thread. var asyncTask = new MyOnLayoutAsyncTask(this, newAttributes, cancellationSignal, callback); asyncTask.ExecuteOnExecutor(AsyncTask.ThreadPoolExecutor, (Java.Lang.Void[])null); }