PrintedPdfDocument.java revision aec1417ca9eb63209668ac17da90cf8a07c6076c
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.Builder(mPageSize, 0).create();
115        Page page = mDocument.startPage(pageInfo);
116        return page;
117    }
118
119    /**
120     * Finishes a started page. You should always finish the last started page.
121     * <p>
122     * <strong>Note:</strong> Do not call this method after {@link #close()}.
123     * </p>
124     *
125     * @param page The page.
126     *
127     * @see #startPage(int)
128     */
129    public void finishPage(Page page) {
130        mDocument.finishPage(page);
131    }
132
133    /**
134     * Writes the document to an output stream.
135     * <p>
136     * <strong>Note:</strong> Do not call this method after {@link #close()}.
137     * </p>
138     *
139     * @param out The output stream.
140     */
141    public void writeTo(OutputStream out) {
142        mDocument.writeTo(out);
143    }
144
145    /**
146     * Gets the pages of the document.
147     *
148     * @return The pages.
149     */
150    public List<PageInfo> getPages() {
151        return mDocument.getPages();
152    }
153
154    /**
155     * Closes this document. This method should be called after you
156     * are done working with the document. After this call the document
157     * is considered closed and none of its methods should be called.
158     */
159    public void close() {
160        mDocument.close();
161    }
162}
163