1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.print.pdf; 18 19 import android.annotation.IntRange; 20 import android.annotation.NonNull; 21 import android.content.Context; 22 import android.graphics.Rect; 23 import android.graphics.pdf.PdfDocument; 24 import android.print.PrintAttributes; 25 import android.print.PrintAttributes.Margins; 26 import android.print.PrintAttributes.MediaSize; 27 28 /** 29 * This class is a helper for creating a PDF file for given print attributes. It is useful for 30 * implementing printing via the native Android graphics APIs. 31 * <p> 32 * This class computes the page width, page height, and content rectangle from the provided print 33 * attributes and these precomputed values can be accessed via {@link #getPageWidth()}, 34 * {@link #getPageHeight()}, and {@link #getPageContentRect()}, respectively. The 35 * {@link #startPage(int)} methods creates pages whose 36 * {@link android.graphics.pdf.PdfDocument.PageInfo PageInfo} is initialized with the precomputed 37 * values for width, height, and content rectangle. 38 * <p> 39 * A typical use of the APIs looks like this: 40 * </p> 41 * <pre> 42 * // open a new document 43 * PrintedPdfDocument document = new PrintedPdfDocument(context, 44 * printAttributes); 45 * 46 * // start a page 47 * Page page = document.startPage(0); 48 * 49 * // draw something on the page 50 * View content = getContentView(); 51 * content.draw(page.getCanvas()); 52 * 53 * // finish the page 54 * document.finishPage(page); 55 * . . . 56 * // add more pages 57 * . . . 58 * // write the document content 59 * document.writeTo(getOutputStream()); 60 * 61 * //close the document 62 * document.close(); 63 * </pre> 64 */ 65 public class PrintedPdfDocument extends PdfDocument { 66 private static final int MILS_PER_INCH = 1000; 67 private static final int POINTS_IN_INCH = 72; 68 69 private final int mPageWidth; 70 private final int mPageHeight; 71 private final Rect mContentRect; 72 73 /** 74 * Creates a new document. 75 * <p> 76 * <strong>Note:</strong> You must close the document after you are 77 * done by calling {@link #close()}. 78 * </p> 79 * 80 * @param context Context instance for accessing resources. 81 * @param attributes The print attributes. 82 */ PrintedPdfDocument(@onNull Context context, @NonNull PrintAttributes attributes)83 public PrintedPdfDocument(@NonNull Context context, @NonNull PrintAttributes attributes) { 84 MediaSize mediaSize = attributes.getMediaSize(); 85 86 // Compute the size of the target canvas from the attributes. 87 mPageWidth = (int) (((float) mediaSize.getWidthMils() / MILS_PER_INCH) 88 * POINTS_IN_INCH); 89 mPageHeight = (int) (((float) mediaSize.getHeightMils() / MILS_PER_INCH) 90 * POINTS_IN_INCH); 91 92 // Compute the content size from the attributes. 93 Margins minMargins = attributes.getMinMargins(); 94 final int marginLeft = (int) (((float) minMargins.getLeftMils() / MILS_PER_INCH) 95 * POINTS_IN_INCH); 96 final int marginTop = (int) (((float) minMargins.getTopMils() / MILS_PER_INCH) 97 * POINTS_IN_INCH); 98 final int marginRight = (int) (((float) minMargins.getRightMils() / MILS_PER_INCH) 99 * POINTS_IN_INCH); 100 final int marginBottom = (int) (((float) minMargins.getBottomMils() / MILS_PER_INCH) 101 * POINTS_IN_INCH); 102 mContentRect = new Rect(marginLeft, marginTop, mPageWidth - marginRight, 103 mPageHeight - marginBottom); 104 } 105 106 /** 107 * Starts a new page. The page is created using width, height and content rectangle computed 108 * from the print attributes passed in the constructor and the given page number to create an 109 * appropriate {@link android.graphics.pdf.PdfDocument.PageInfo PageInfo}. 110 * <p> 111 * After the page is created you can draw arbitrary content on the page's canvas which you can 112 * get by calling {@link android.graphics.pdf.PdfDocument.Page#getCanvas() Page.getCanvas()}. 113 * After you are done drawing the content you should finish the page by calling 114 * {@link #finishPage(Page)}. After the page is finished you should no longer access the page or 115 * its canvas. 116 * </p> 117 * <p> 118 * <strong>Note:</strong> Do not call this method after {@link #close()}. Also do not call this 119 * method if the last page returned by this method is not finished by calling 120 * {@link #finishPage(Page)}. 121 * </p> 122 * 123 * @param pageNumber The page number. Must be a non negative. 124 * @return A blank page. 125 * 126 * @see #finishPage(Page) 127 */ startPage(@ntRangefrom = 0) int pageNumber)128 public @NonNull Page startPage(@IntRange(from = 0) int pageNumber) { 129 PageInfo pageInfo = new PageInfo 130 .Builder(mPageWidth, mPageHeight, pageNumber) 131 .setContentRect(mContentRect) 132 .create(); 133 return startPage(pageInfo); 134 } 135 136 /** 137 * Gets the page width. 138 * 139 * @return The page width in PostScript points (1/72th of an inch). 140 */ getPageWidth()141 public @IntRange(from = 0) int getPageWidth() { 142 return mPageWidth; 143 } 144 145 /** 146 * Gets the page height. 147 * 148 * @return The page height in PostScript points (1/72th of an inch). 149 */ getPageHeight()150 public @IntRange(from = 0) int getPageHeight() { 151 return mPageHeight; 152 } 153 154 /** 155 * Gets the content rectangle. This is the area of the page that 156 * contains printed data and is relative to the page top left. 157 * 158 * @return The content rectangle. 159 */ getPageContentRect()160 public @NonNull Rect getPageContentRect() { 161 return mContentRect; 162 } 163 } 164