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