Home | History | Annotate | Download | only in pdf
      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      */
     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      */
    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      */
    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      */
    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      */
    160     public @NonNull Rect getPageContentRect() {
    161         return mContentRect;
    162     }
    163 }
    164