PrintedPdfDocument.java revision d26d4898fcc9b78f4b66118895c375384098205e
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.print.PrintAttributes;
22import android.print.PrintAttributes.Margins;
23import android.print.PrintAttributes.MediaSize;
24import android.print.pdf.PdfDocument;
25import android.print.pdf.PdfDocument.Page;
26import android.print.pdf.PdfDocument.PageInfo;
27
28import java.io.OutputStream;
29import java.util.List;
30
31/**
32 * This class is a helper for printing content to a different media
33 * size. This class is responsible for computing a correct page size
34 * given some print constraints, i.e. {@link PrintAttributes}. It is
35 * an adapter around a {@link PdfDocument}.
36 */
37public final class PrintedPdfDocument {
38    private static final int MILS_PER_INCH = 1000;
39    private static final int POINTS_IN_INCH = 72;
40
41    private final PdfDocument mDocument = PdfDocument.open();
42    private final Rect mPageSize = new Rect();
43    private final Rect mContentSize = new Rect();
44
45    /**
46     * Opens a new document. The document pages are computed based on
47     * the passes in {@link PrintAttributes}.
48     * <p>
49     * <strong>Note:</strong> You must close the document after you are
50     * done by calling {@link #close()}
51     * </p>
52     *
53     * @param context Context instance for accessing resources.
54     * @param attributes The print attributes.
55     * @return The document.
56     *
57     * @see #close()
58     */
59    public static PrintedPdfDocument open(Context context, PrintAttributes attributes) {
60        return new PrintedPdfDocument(context, attributes);
61    }
62
63    /**
64     * Creates a new instance.
65     *
66     * @param context Context instance for accessing resources and services.
67     * @param attributes The {@link PrintAttributes} to user.
68     */
69    private PrintedPdfDocument(Context context, PrintAttributes attributes) {
70        MediaSize mediaSize = attributes.getMediaSize();
71
72        // Compute the size of the target canvas from the attributes.
73        final int pageWidth = (int) (((float) mediaSize.getWidthMils() / MILS_PER_INCH)
74                * POINTS_IN_INCH);
75        final int pageHeight = (int) (((float) mediaSize.getHeightMils() / MILS_PER_INCH)
76                * POINTS_IN_INCH);
77        mPageSize.set(0, 0, pageWidth, pageHeight);
78
79        // Compute the content size from the attributes.
80        Margins margins = attributes.getMargins();
81        final int marginLeft = (int) (((float) margins.getLeftMils() /MILS_PER_INCH)
82                * POINTS_IN_INCH);
83        final int marginTop = (int) (((float) margins.getTopMils() / MILS_PER_INCH)
84                * POINTS_IN_INCH);
85        final int marginRight = (int) (((float) margins.getRightMils() / MILS_PER_INCH)
86                * POINTS_IN_INCH);
87        final int marginBottom = (int) (((float) margins.getBottomMils() / MILS_PER_INCH)
88                * POINTS_IN_INCH);
89        mContentSize.set(mPageSize.left + marginLeft, mPageSize.top + marginTop,
90                mPageSize.right - marginRight, mPageSize.bottom - marginBottom);
91    }
92
93    /**
94     * Starts a page using a page size computed from the print attributes
95     * passed in {@link #open(Context, PrintAttributes)} and the given page
96     * number to create appropriate {@link PageInfo}.
97     * <p>
98     * After the page is created you can draw arbitrary content on the page's
99     * canvas which you can get by calling {@link Page#getCanvas() Page.getCanvas()}.
100     * After you are done drawing the content you should finish the page by calling
101     * {@link #finishPage(Page)}. After the page is finished you should no longer
102     * access the page or its canvas.
103     * </p>
104     * <p>
105     * <strong>Note:</strong> Do not call this method after {@link #close()}.
106     * </p>
107     *
108     * @param pageNumber The page number.
109     * @return A blank page.
110     *
111     * @see #finishPage(Page)
112     */
113    public Page startPage(int pageNumber) {
114        PageInfo pageInfo = new PageInfo
115                .Builder(mPageSize, 0)
116                .setContentSize(mContentSize)
117                .create();
118        Page page = mDocument.startPage(pageInfo);
119        return page;
120    }
121
122    /**
123     * Finishes a started page. You should always finish the last started page.
124     * <p>
125     * <strong>Note:</strong> Do not call this method after {@link #close()}.
126     * </p>
127     *
128     * @param page The page.
129     *
130     * @see #startPage(int)
131     */
132    public void finishPage(Page page) {
133        mDocument.finishPage(page);
134    }
135
136    /**
137     * Writes the document to an output stream.
138     * <p>
139     * <strong>Note:</strong> Do not call this method after {@link #close()}.
140     * </p>
141     *
142     * @param out The output stream.
143     */
144    public void writeTo(OutputStream out) {
145        mDocument.writeTo(out);
146    }
147
148    /**
149     * Gets the pages of the document.
150     *
151     * @return The pages.
152     */
153    public List<PageInfo> getPages() {
154        return mDocument.getPages();
155    }
156
157    /**
158     * Closes this document. This method should be called after you
159     * are done working with the document. After this call the document
160     * is considered closed and none of its methods should be called.
161     */
162    public void close() {
163        mDocument.close();
164    }
165}
166