PrintedPdfDocument.java revision 651dd4e6ee6510caf9f15c51094a11121af17ec2
1aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov/*
2aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project
3aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov *
4aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
5aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * you may not use this file except in compliance with the License.
6aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * You may obtain a copy of the License at
7aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov *
8aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
9aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov *
10aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software
11aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
12aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * See the License for the specific language governing permissions and
14aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * limitations under the License.
15aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov */
16aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
17aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovpackage android.print.pdf;
18aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
19aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.content.Context;
20aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.graphics.Rect;
21aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.print.PrintAttributes;
22aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.print.PrintAttributes.Margins;
23aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.print.PrintAttributes.MediaSize;
24aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.print.pdf.PdfDocument;
25aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.print.pdf.PdfDocument.Page;
26aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport android.print.pdf.PdfDocument.PageInfo;
27aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
28aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport java.io.OutputStream;
29aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovimport java.util.List;
30aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
31aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov/**
32aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * This class is a helper for printing content to a different media
33aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * size. This class is responsible for computing a correct page size
34aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * given some print constraints, i.e. {@link PrintAttributes}. It is
35aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov * an adapter around a {@link PdfDocument}.
36aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov */
37aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganovpublic final class PrintedPdfDocument {
38aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    private static final int MILS_PER_INCH = 1000;
39aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    private static final int POINTS_IN_INCH = 72;
40aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
41aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    private final PdfDocument mDocument = PdfDocument.open();
42aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    private final Rect mPageSize = new Rect();
43aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    private final Rect mContentSize = new Rect();
44aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
45aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    /**
46aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * Opens a new document. The document pages are computed based on
47aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * the passes in {@link PrintAttributes}.
48aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <p>
49aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <strong>Note:</strong> You must close the document after you are
50aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * done by calling {@link #close()}
51aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * </p>
52aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
53aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @param context Context instance for accessing resources.
54aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @param attributes The print attributes.
55aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @return The document.
56aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
57aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @see #close()
58aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     */
59aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    public static PrintedPdfDocument open(Context context, PrintAttributes attributes) {
60aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        return new PrintedPdfDocument(context, attributes);
61aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    }
62aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
63aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    /**
64aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * Creates a new instance.
65aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
66aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @param context Context instance for accessing resources and services.
67aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @param attributes The {@link PrintAttributes} to user.
68aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     */
69aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    private PrintedPdfDocument(Context context, PrintAttributes attributes) {
70aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        MediaSize mediaSize = attributes.getMediaSize();
71aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
72aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        // Compute the size of the target canvas from the attributes.
73aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        final int pageWidth = (int) (((float) mediaSize.getWidthMils() / MILS_PER_INCH)
74aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov                * POINTS_IN_INCH);
75aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        final int pageHeight = (int) (((float) mediaSize.getHeightMils() / MILS_PER_INCH)
76aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov                * POINTS_IN_INCH);
77aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        mPageSize.set(0, 0, pageWidth, pageHeight);
78aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
79aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        // Compute the content size from the attributes.
80651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav        Margins minMargins = attributes.getMinMargins();
81651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav        final int marginLeft = (int) (((float) minMargins.getLeftMils() /MILS_PER_INCH)
82aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov                * POINTS_IN_INCH);
83651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav        final int marginTop = (int) (((float) minMargins.getTopMils() / MILS_PER_INCH)
84aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov                * POINTS_IN_INCH);
85651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav        final int marginRight = (int) (((float) minMargins.getRightMils() / MILS_PER_INCH)
86aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov                * POINTS_IN_INCH);
87651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav        final int marginBottom = (int) (((float) minMargins.getBottomMils() / MILS_PER_INCH)
88aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov                * POINTS_IN_INCH);
89aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        mContentSize.set(mPageSize.left + marginLeft, mPageSize.top + marginTop,
90aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov                mPageSize.right - marginRight, mPageSize.bottom - marginBottom);
91aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    }
92aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
93aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    /**
94aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * Starts a page using a page size computed from the print attributes
95aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * passed in {@link #open(Context, PrintAttributes)} and the given page
96aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * number to create appropriate {@link PageInfo}.
97aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <p>
98aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * After the page is created you can draw arbitrary content on the page's
99aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * canvas which you can get by calling {@link Page#getCanvas() Page.getCanvas()}.
100aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * After you are done drawing the content you should finish the page by calling
101aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * {@link #finishPage(Page)}. After the page is finished you should no longer
102aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * access the page or its canvas.
103aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * </p>
104aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <p>
105aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <strong>Note:</strong> Do not call this method after {@link #close()}.
106aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * </p>
107aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
108aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @param pageNumber The page number.
109aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @return A blank page.
110aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
111aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @see #finishPage(Page)
112aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     */
113aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    public Page startPage(int pageNumber) {
114d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        PageInfo pageInfo = new PageInfo
115d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov                .Builder(mPageSize, 0)
116d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov                .setContentSize(mContentSize)
117d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov                .create();
118aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        Page page = mDocument.startPage(pageInfo);
119aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        return page;
120aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    }
121aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
122aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    /**
123aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * Finishes a started page. You should always finish the last started page.
124aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <p>
125aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <strong>Note:</strong> Do not call this method after {@link #close()}.
126aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * </p>
127aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
128aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @param page The page.
129aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
130aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @see #startPage(int)
131aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     */
132aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    public void finishPage(Page page) {
133aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        mDocument.finishPage(page);
134aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    }
135aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
136aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    /**
137aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * Writes the document to an output stream.
138aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <p>
139aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * <strong>Note:</strong> Do not call this method after {@link #close()}.
140aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * </p>
141aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
142aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @param out The output stream.
143aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     */
144aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    public void writeTo(OutputStream out) {
145aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        mDocument.writeTo(out);
146aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    }
147aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
148aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    /**
149aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * Gets the pages of the document.
150aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     *
151aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * @return The pages.
152aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     */
153aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    public List<PageInfo> getPages() {
154aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        return mDocument.getPages();
155aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    }
156aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov
157aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    /**
158aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * Closes this document. This method should be called after you
159aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * are done working with the document. After this call the document
160aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     * is considered closed and none of its methods should be called.
161aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov     */
162aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    public void close() {
163aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov        mDocument.close();
164aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov    }
165aec1417ca9eb63209668ac17da90cf8a07c6076cSvetoslav Ganov}
166