/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.print.pdf;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.pdf.PdfDocument;
import android.graphics.pdf.PdfDocument.Page;
import android.graphics.pdf.PdfDocument.PageInfo;
import android.print.PrintAttributes;
import android.print.PrintAttributes.Margins;
import android.print.PrintAttributes.MediaSize;
/**
* This class is a helper for creating a PDF file for given print
* attributes. It is useful for implementing printing via the native
* Android graphics APIs.
* <p>
* This class computes the page width, page height, and content rectangle
* from the provided print attributes and these precomputed values can be
* accessed via {@link #getPageWidth()}, {@link #getPageHeight()}, and
* {@link #getPageContentRect()}, respectively. The {@link #startPage(int)}
* methods creates pages whose {@link PageInfo} is initialized with the
* precomputed values for width, height, and content rectangle.
* <p>
* A typical use of the APIs looks like this:
* </p>
* <pre>
* // open a new document
* PrintedPdfDocument document = new PrintedPdfDocument(context,
* printAttributes);
*
* // start a page
* Page page = document.startPage(0);
*
* // draw something on the page
* View content = getContentView();
* content.draw(page.getCanvas());
*
* // finish the page
* document.finishPage(page);
* . . .
* // add more pages
* . . .
* // write the document content
* document.writeTo(getOutputStream());
*
* //close the document
* document.close();
* </pre>
*/
public class PrintedPdfDocument extends PdfDocument {
private static final int MILS_PER_INCH = 1000;
private static final int POINTS_IN_INCH = 72;
private final int mPageWidth;
private final int mPageHeight;
private final Rect mContentRect;
/**
* Creates a new document.
* <p>
* <strong>Note:</strong> You must close the document after you are
* done by calling {@link #close()}.
* </p>
*
* @param context Context instance for accessing resources.
* @param attributes The print attributes.
*/
public PrintedPdfDocument(Context context, PrintAttributes attributes) {
MediaSize mediaSize = attributes.getMediaSize();
// Compute the size of the target canvas from the attributes.
mPageWidth = (int) (((float) mediaSize.getWidthMils() / MILS_PER_INCH)
* POINTS_IN_INCH);
mPageHeight = (int) (((float) mediaSize.getHeightMils() / MILS_PER_INCH)
* POINTS_IN_INCH);
// Compute the content size from the attributes.
Margins minMargins = attributes.getMinMargins();
final int marginLeft = (int) (((float) minMargins.getLeftMils() / MILS_PER_INCH)
* POINTS_IN_INCH);
final int marginTop = (int) (((float) minMargins.getTopMils() / MILS_PER_INCH)
* POINTS_IN_INCH);
final int marginRight = (int) (((float) minMargins.getRightMils() / MILS_PER_INCH)
* POINTS_IN_INCH);
final int marginBottom = (int) (((float) minMargins.getBottomMils() / MILS_PER_INCH)
* POINTS_IN_INCH);
mContentRect = new Rect(marginLeft, marginTop, mPageWidth - marginRight,
mPageHeight - marginBottom);
}
/**
* Starts a new page. The page is created using width, height and content
* rectangle computed from the print attributes passed in the constructor
* and the given page number to create an appropriate {@link PageInfo}.
* <p>
* After the page is created you can draw arbitrary content on the page's
* canvas which you can get by calling {@link Page#getCanvas() Page.getCanvas()}.
* After you are done drawing the content you should finish the page by calling
* {@link #finishPage(Page)}. After the page is finished you should no longer
* access the page or its canvas.
* </p>
* <p>
* <strong>Note:</strong> Do not call this method after {@link #close()}.
* Also do not call this method if the last page returned by this method
* is not finished by calling {@link #finishPage(Page)}.
* </p>
*
* @param pageNumber The page number. Must be a positive value.
* @return A blank page.
*
* @see #finishPage(Page)
*/
public Page startPage(int pageNumber) {
PageInfo pageInfo = new PageInfo
.Builder(mPageWidth, mPageHeight, pageNumber)
.setContentRect(mContentRect)
.create();
return startPage(pageInfo);
}
/**
* Gets the page width.
*
* @return The page width in PostScript points (1/72th of an inch).
*/
public int getPageWidth() {
return mPageWidth;
}
/**
* Gets the page height.
*
* @return The page height in PostScript points (1/72th of an inch).
*/
public int getPageHeight() {
return mPageHeight;
}
/**
* Gets the content rectangle. This is the area of the page that
* contains printed data and is relative to the page top left.
*
* @return The content rectangle.
*/
public Rect getPageContentRect() {
return mContentRect;
}
}