diff --git a/api/current.txt b/api/current.txt
index ca8a7dd2092f7..4b66d086b2cb1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19017,6 +19017,7 @@ package android.preference {
package android.print {
public final class PageRange implements android.os.Parcelable {
+ ctor public PageRange(int, int);
method public int describeContents();
method public int getEnd();
method public int getStart();
@@ -19044,8 +19045,9 @@ package android.print {
field public static final int DUPLEX_MODE_LONG_EDGE = 2; // 0x2
field public static final int DUPLEX_MODE_NONE = 1; // 0x1
field public static final int DUPLEX_MODE_SHORT_EDGE = 4; // 0x4
- field public static final int FITTING_MODE_FIT_TO_PAGE = 2; // 0x2
field public static final int FITTING_MODE_NONE = 1; // 0x1
+ field public static final int FITTING_MODE_SCALE_TO_FILL = 4; // 0x4
+ field public static final int FITTING_MODE_SCALE_TO_FIT = 2; // 0x2
field public static final int ORIENTATION_LANDSCAPE = 2; // 0x2
field public static final int ORIENTATION_PORTRAIT = 1; // 0x1
}
@@ -19070,6 +19072,7 @@ package android.print {
method public int getLeftMils();
method public int getRightMils();
method public int getTopMils();
+ field public static final android.print.PrintAttributes.Margins NO_MARGINS;
}
public static final class PrintAttributes.MediaSize {
@@ -19157,21 +19160,33 @@ package android.print {
public final class PrintDocumentInfo implements android.os.Parcelable {
method public int describeContents();
+ method public int getColorMode();
method public int getContentType();
+ method public int getFittingMode();
+ method public android.print.PrintAttributes.Margins getMargins();
+ method public android.print.PrintAttributes.MediaSize getMediaSize();
method public java.lang.String getName();
+ method public int getOrientation();
method public int getPageCount();
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_TYPE_DOCUMENT = 0; // 0x0
field public static final int CONTENT_TYPE_PHOTO = 1; // 0x1
field public static final int CONTENT_TYPE_UNKNOWN = -1; // 0xffffffff
field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final android.print.PrintAttributes.MediaSize MEDIA_SIZE_UNKNOWN;
field public static final int PAGE_COUNT_UNKNOWN = -1; // 0xffffffff
}
public static final class PrintDocumentInfo.Builder {
+ ctor public PrintDocumentInfo.Builder(java.lang.String, android.print.PrintAttributes);
ctor public PrintDocumentInfo.Builder(java.lang.String);
method public android.print.PrintDocumentInfo create();
+ method public android.print.PrintDocumentInfo.Builder setColorMode(int);
method public android.print.PrintDocumentInfo.Builder setContentType(int);
+ method public android.print.PrintDocumentInfo.Builder setFittingMode(int);
+ method public android.print.PrintDocumentInfo.Builder setMargins(android.print.PrintAttributes.Margins);
+ method public android.print.PrintDocumentInfo.Builder setMediaSize(android.print.PrintAttributes.MediaSize);
+ method public android.print.PrintDocumentInfo.Builder setOrientation(int);
method public android.print.PrintDocumentInfo.Builder setPageCount(int);
}
@@ -19259,7 +19274,9 @@ package android.print {
method public int getStatus();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
- field public static final int STATUS_READY = 1; // 0x1
+ field public static final int STATUS_BUSY = 2; // 0x2
+ field public static final int STATUS_IDLE = 1; // 0x1
+ field public static final int STATUS_UNAVAILABLE = 3; // 0x3
}
public static final class PrinterInfo.Builder {
@@ -19269,6 +19286,7 @@ package android.print {
method public android.print.PrinterInfo.Builder setCapabilities(android.print.PrinterCapabilitiesInfo);
method public android.print.PrinterInfo.Builder setDescription(java.lang.String);
method public android.print.PrinterInfo.Builder setName(java.lang.String);
+ method public android.print.PrinterInfo.Builder setStatus(int);
}
}
@@ -19291,19 +19309,27 @@ package android.print.pdf {
public static final class PdfDocument.PageInfo {
method public android.graphics.Rect getContentSize();
- method public int getDesity();
method public android.graphics.Matrix getInitialTransform();
method public int getPageNumber();
method public android.graphics.Rect getPageSize();
}
public static final class PdfDocument.PageInfo.Builder {
- ctor public PdfDocument.PageInfo.Builder(android.graphics.Rect, int, int);
+ ctor public PdfDocument.PageInfo.Builder(android.graphics.Rect, int);
method public android.print.pdf.PdfDocument.PageInfo create();
method public android.print.pdf.PdfDocument.PageInfo.Builder setContentSize(android.graphics.Rect);
method public android.print.pdf.PdfDocument.PageInfo.Builder setInitialTransform(android.graphics.Matrix);
}
+ public final class PrintedPdfDocument {
+ method public void close();
+ method public void finishPage(android.print.pdf.PdfDocument.Page);
+ method public java.util.List
+ * When doing a layout you may satisfy some of the constraints in the print + * attributes such as applying the appropriate fitting, emitting content in the + * requested orientation, using the specified margins, generating content with + * the desired color mode, producing output with the given media size. Ideally, + * you will satisfy all of these constraints. It is important that if you + * satisfy a given constraint, you update the {@link PrintDocumentInfo} that + * is returned in the given {@link LayoutResultCallback}. This way the printer + * will have more accurate information about the content, thus producing a + * better output. For example, assume that your application is printing + * an image and the print attributes request landscape and fitting mode scale + * to fill. The result of this operation should be the entire media is filled + * and the content is rotated ninety degrees. In this case it is beneficial + * you do the rotation and select a higher resolution image to utilize + * the wider media (the height is now the width), rather to use a lower + * resolution image that is later stretched by the printer. If you applied + * the rotation you have to update the returned print document info to + * reflect that the content is already in landscape by calling + * {@link PrintDocumentInfo.Builder#setOrientation(int)} with {@link + * PrintAttributes#ORIENTATION_LANDSCAPE}. In this case the printer does not + * have to rotate the content. + *
+ ** Note: If the content is large and a layout will be * performed, it is a good practice to schedule the work on a dedicated * thread and register an observer in the provided {@link diff --git a/core/java/android/print/PrintDocumentInfo.java b/core/java/android/print/PrintDocumentInfo.java index 653ad4bfc4e4a..b32961b641cf8 100644 --- a/core/java/android/print/PrintDocumentInfo.java +++ b/core/java/android/print/PrintDocumentInfo.java @@ -18,6 +18,8 @@ package android.print; import android.os.Parcel; import android.os.Parcelable; +import android.print.PrintAttributes.Margins; +import android.print.PrintAttributes.MediaSize; import android.text.TextUtils; /** @@ -26,12 +28,17 @@ import android.text.TextUtils; public final class PrintDocumentInfo implements Parcelable { /** - * Constant for unknown page count (default). + * Constant for an unknown media size. + */ + public static final MediaSize MEDIA_SIZE_UNKNOWN = new MediaSize("Unknown", "Unknown", 1, 1); + + /** + * Constant for unknown page count.. */ public static final int PAGE_COUNT_UNKNOWN = -1; /** - * Content type: unknown (default). + * Content type: unknown. */ public static final int CONTENT_TYPE_UNKNOWN = -1; @@ -48,13 +55,17 @@ public final class PrintDocumentInfo implements Parcelable { private String mName; private int mPageCount; private int mContentType; + private int mOrientation; + private int mFittingMode; + private int mColorMode; + private Margins mMargins; + private MediaSize mMediaSize; /** * Creates a new instance. */ private PrintDocumentInfo() { - mPageCount = PAGE_COUNT_UNKNOWN; - mContentType = CONTENT_TYPE_UNKNOWN; + /* do nothing */ } /** @@ -66,6 +77,11 @@ public final class PrintDocumentInfo implements Parcelable { mName = prototype.mName; mPageCount = prototype.mPageCount; mContentType = prototype.mContentType; + mOrientation = prototype.mOrientation; + mFittingMode = prototype.mFittingMode; + mColorMode = prototype.mColorMode; + mMargins = prototype.mMargins; + mMediaSize = prototype.mMediaSize; } /** @@ -77,6 +93,11 @@ public final class PrintDocumentInfo implements Parcelable { mName = parcel.readString(); mPageCount = parcel.readInt(); mContentType = parcel.readInt(); + mOrientation = parcel.readInt(); + mFittingMode = parcel.readInt(); + mColorMode = parcel.readInt(); + mMargins = Margins.createFromParcel(parcel); + mMediaSize = MediaSize.createFromParcel(parcel); } /** @@ -112,6 +133,61 @@ public final class PrintDocumentInfo implements Parcelable { return mContentType; } + /** + * Gets the document orientation. + * + * @return The orientation. + * + * @see PrintAttributes#ORIENTATION_PORTRAIT PrintAttributes.ORIENTATION_PORTRAIT + * @see PrintAttributes#ORIENTATION_LANDSCAPE PrintAttributes.ORIENTATION_LANDSCAPE + */ + public int getOrientation() { + return mOrientation; + } + + /** + * Gets the document fitting mode. + * + * @return The fitting mode. + * + * @see PrintAttributes#FITTING_MODE_NONE PrintAttributes.FITTING_MODE_NONE + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FILL PrintAttributes.FITTING_MODE_SCALE_TO_FILL + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FIT PrintAttributes.FITTING_MODE_SCALE_TO_FIT + */ + public int getFittingMode() { + return mFittingMode; + } + + /** + * Gets document color mode. + * + * @return The color mode. + * + * @see PrintAttributes#COLOR_MODE_COLOR PrintAttributes.COLOR_MODE_COLOR + * @see PrintAttributes#COLOR_MODE_MONOCHROME PrintAttributes.COLOR_MODE_MONOCHROME + */ + public int getColorMode() { + return mColorMode; + } + + /** + * Gets the document margins. + * + * @return The margins. + */ + public Margins getMargins() { + return mMargins; + } + + /** + * Gets the media size. + * + * @return The media size. + */ + public MediaSize getMediaSize() { + return mMediaSize; + } + @Override public int describeContents() { return 0; @@ -122,6 +198,11 @@ public final class PrintDocumentInfo implements Parcelable { parcel.writeString(mName); parcel.writeInt(mPageCount); parcel.writeInt(mContentType); + parcel.writeInt(mOrientation); + parcel.writeInt(mFittingMode); + parcel.writeInt(mColorMode); + mMargins.writeToParcel(parcel); + mMediaSize.writeToParcel(parcel); } @Override @@ -131,6 +212,11 @@ public final class PrintDocumentInfo implements Parcelable { result = prime * result + ((mName != null) ? mName.hashCode() : 0); result = prime * result + mContentType; result = prime * result + mPageCount; + result = prime * result + mOrientation; + result = prime * result + mFittingMode; + result = prime * result + mColorMode; + result = prime * result + (mMargins != null ? mMargins.hashCode() : 0); + result = prime * result + (mMediaSize != null ? mMediaSize.hashCode() : 0); return result; } @@ -155,6 +241,29 @@ public final class PrintDocumentInfo implements Parcelable { if (mPageCount != other.mPageCount) { return false; } + if (mOrientation != other.mOrientation) { + return false; + } + if (mFittingMode != other.mFittingMode) { + return false; + } + if (mColorMode != other.mColorMode) { + return false; + } + if (mMargins == null) { + if (other.mMargins != null) { + return false; + } + } else if (!mMargins.equals(other.mMargins)) { + return false; + } + if (mMediaSize == null) { + if (other.mMediaSize != null) { + return false; + } + } else if (!mMediaSize.equals(other.mMediaSize)) { + return false; + } return true; } @@ -165,6 +274,11 @@ public final class PrintDocumentInfo implements Parcelable { builder.append("name=").append(mName); builder.append(", pageCount=").append(mPageCount); builder.append(", contentType=").append(contentTyepToString(mContentType)); + builder.append(", orientation=").append(PrintAttributes.orientationToString(mOrientation)); + builder.append(", fittingMode=").append(PrintAttributes.fittingModeToString(mFittingMode)); + builder.append(", colorMode=").append(PrintAttributes.colorModeToString(mColorMode)); + builder.append(", margins=").append(mMargins); + builder.append(", mediaSize=").append(mMediaSize); builder.append("}"); return builder.toString(); } @@ -191,21 +305,62 @@ public final class PrintDocumentInfo implements Parcelable { /** * Constructor. + *
+ * The values of the relevant properties are initialized from the + * provided print attributes. For example, the orientation is set + * to be the same as the orientation returned by calling {@link + * PrintAttributes#getOrientation() PrintAttributes.getOrientation()}. + *
* * @param name The document name. Cannot be empty. + * @param attributes Print attributes. Cannot be null. * * @throws IllegalArgumentException If the name is empty. */ + public Builder(String name, PrintAttributes attributes) { + if (TextUtils.isEmpty(name)) { + throw new IllegalArgumentException("name cannot be empty"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes cannot be null"); + } + mPrototype = new PrintDocumentInfo(); + mPrototype.mName = name; + mPrototype.mOrientation = attributes.getOrientation(); + mPrototype.mFittingMode = attributes.getFittingMode(); + mPrototype.mColorMode = attributes.getColorMode(); + mPrototype.mMargins = attributes.getMargins(); + mPrototype.mMediaSize = attributes.getMediaSize(); + } + + /** + * Constructor. + *+ * The values of the relevant properties are initialized with default + * values. Please refer to the documentation of the individual setters + * for information about the default values. + *
+ * + * @param name The document name. Cannot be empty. + */ public Builder(String name) { if (TextUtils.isEmpty(name)) { throw new IllegalArgumentException("name cannot be empty"); } mPrototype = new PrintDocumentInfo(); mPrototype.mName = name; + mPrototype.mOrientation = PrintAttributes.ORIENTATION_PORTRAIT; + mPrototype.mFittingMode = PrintAttributes.FITTING_MODE_NONE; + mPrototype.mColorMode = PrintAttributes.COLOR_MODE_COLOR; + mPrototype.mMargins = Margins.NO_MARGINS; + mPrototype.mMediaSize = MEDIA_SIZE_UNKNOWN; } /** * Sets the total number of pages. + *+ * Default: {@link #PAGE_COUNT_UNKNOWN} + *
* * @param pageCount The number of pages. Must be greater than * or equal to zero or {@link PrintDocumentInfo#PAGE_COUNT_UNKNOWN}. @@ -222,6 +377,9 @@ public final class PrintDocumentInfo implements Parcelable { /** * Sets the content type. + *+ * Default: {@link #CONTENT_TYPE_UNKNOWN} + *
* * @param type The content type. * @@ -234,6 +392,95 @@ public final class PrintDocumentInfo implements Parcelable { return this; } + /** + * Sets the orientation. + *+ * Default: {@link PrintAttributes#ORIENTATION_PORTRAIT + * PrintAttributes.ORIENTATION_PORTRAIT} + *
+ * + * @param orientation The orientation. + * + * @see PrintAttributes#ORIENTATION_PORTRAIT PrintAttributes.ORIENTATION_PORTRAIT + * @see PrintAttributes#ORIENTATION_LANDSCAPE PrintAttributes.ORIENTATION_LANDSCAPE + */ + public Builder setOrientation(int orientation) { + PrintAttributes.enforceValidOrientation(orientation); + mPrototype.mOrientation = orientation; + return this; + } + + /** + * Sets the content fitting mode. + *+ * Default: {@link PrintAttributes#FITTING_MODE_NONE + * PrintAttributes.FITTING_MODE_NONE} + *
+ * + * @param fittingMode The fitting mode. + * + * @see PrintAttributes#FITTING_MODE_NONE PrintAttributes.FITTING_MODE_NONE + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FILL PrintAttributes.FITTING_MODE_SCALE_TO_FILL + * @see PrintAttributes#FITTING_MODE_SCALE_TO_FIT PrintAttributes.FITTING_MODE_SCALE_TO_FIT + */ + public Builder setFittingMode(int fittingMode) { + PrintAttributes.enforceValidFittingMode(fittingMode); + mPrototype.mFittingMode = fittingMode; + return this; + } + + /** + * Sets the content color mode. + *+ * Default: {@link PrintAttributes#COLOR_MODE_COLOR + * PrintAttributes.COLOR_MODE_COLOR} + *
+ * + * @param colorMode The color mode. + * + * @see PrintAttributes#COLOR_MODE_COLOR PrintAttributes.COLOR_MODE_COLOR + * @see PrintAttributes#COLOR_MODE_MONOCHROME PrintAttributes.COLOR_MODE_MONOCHROME + */ + public Builder setColorMode(int colorMode) { + PrintAttributes.enforceValidColorMode(colorMode); + mPrototype.mColorMode = colorMode; + return this; + } + + /** + * Sets the document margins. + *+ * Default: {@link PrintAttributes.Margins#NO_MARGINS Margins.NO_MARGINS} + *
+ * + * @param margins The margins. Cannot be null. + */ + public Builder setMargins(Margins margins) { + if (margins == null) { + throw new IllegalArgumentException("margins cannot be null"); + } + mPrototype.mMargins = margins; + return this; + } + + /** + * Sets the document media size. + *+ * Default: #MEDIA_SIZE_UNKNOWN + *
+ * + * @param mediaSize The media size. Cannot be null. + * + * @see #MEDIA_SIZE_UNKNOWN + */ + public Builder setMediaSize(MediaSize mediaSize) { + if (mediaSize == null) { + throw new IllegalArgumentException("media size cannot be null"); + } + mPrototype.mMediaSize = mediaSize; + return this; + } + /** * Creates a new {@link PrintDocumentInfo} instance. * diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java index 70b418c2a1458..941e6e1f7d2c9 100644 --- a/core/java/android/print/PrinterCapabilitiesInfo.java +++ b/core/java/android/print/PrinterCapabilitiesInfo.java @@ -863,12 +863,12 @@ public final class PrinterCapabilitiesInfo implements Parcelable { while (currentModes > 0) { final int currentMode = (1 << Integer.numberOfTrailingZeros(currentModes)); currentModes &= ~currentMode; - PrintAttributes.enfoceValidFittingMode(currentMode); + PrintAttributes.enforceValidFittingMode(currentMode); } if ((fittingModes & defaultFittingMode) == 0) { throw new IllegalArgumentException("Default fitting mode not in fiting modes."); } - PrintAttributes.enfoceValidFittingMode(defaultFittingMode); + PrintAttributes.enforceValidFittingMode(defaultFittingMode); mPrototype.mFittingModes = fittingModes; mPrototype.mDefaults[PROPERTY_FITTING_MODE] = defaultFittingMode; return this; diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java index 6f567a64d709e..0ea319be8b1df 100644 --- a/core/java/android/print/PrinterInfo.java +++ b/core/java/android/print/PrinterInfo.java @@ -25,10 +25,14 @@ import android.text.TextUtils; */ public final class PrinterInfo implements Parcelable { - /** Printer status: the printer is ready to print. */ - public static final int STATUS_READY = 1; + /** Printer status: the printer is idle and ready to print. */ + public static final int STATUS_IDLE = 1; - // TODO: Add printer status constants. + /** Printer status: the printer is busy printing. */ + public static final int STATUS_BUSY = 2; + + /** Printer status: the printer is not available. */ + public static final int STATUS_UNAVAILABLE = 3; private PrinterId mId; @@ -236,6 +240,21 @@ public final class PrinterInfo implements Parcelable { mPrototype.copyFrom(other); } + /** + * Sets the printer status. + * + * @param status The status. + * @return This builder. + * + * @see PrinterInfo#STATUS_IDLE + * @see PrinterInfo#STATUS_BUSY + * @see PrinterInfo#STATUS_UNAVAILABLE + */ + public Builder setStatus(int status) { + mPrototype.mStatus = status; + return this; + } + /** * Sets the printer name. * @@ -279,7 +298,9 @@ public final class PrinterInfo implements Parcelable { } private boolean isValidStatus(int status) { - return (status == PrinterInfo.STATUS_READY); + return (status == STATUS_IDLE + || status == STATUS_IDLE + || status == STATUS_UNAVAILABLE); } } diff --git a/core/java/android/print/pdf/PdfDocument.java b/core/java/android/print/pdf/PdfDocument.java index dbd7dd1448c54..a2883cf83e3aa 100644 --- a/core/java/android/print/pdf/PdfDocument.java +++ b/core/java/android/print/pdf/PdfDocument.java @@ -44,7 +44,7 @@ import java.util.List; * PdfDocument document = PdfDocument.open(); * * // crate a page description - * PageInfo pageInfo = new PageInfo.Builder(new Rect(0, 0, 100, 100), 1, 300).create(); + * PageInfo pageInfo = new PageInfo.Builder(new Rect(0, 0, 100, 100), 1).create(); * * // start a page * Page page = document.startPage(pageInfo); @@ -125,8 +125,7 @@ public final class PdfDocument { throw new IllegalStateException("Previous page not finished!"); } Canvas canvas = new PdfCanvas(nativeCreatePage(pageInfo.mPageSize, - pageInfo.mContentSize, pageInfo.mInitialTransform.native_instance), - pageInfo.mDensity); + pageInfo.mContentSize, pageInfo.mInitialTransform.native_instance)); mCurrentPage = new Page(canvas, pageInfo); return mCurrentPage; } @@ -230,25 +229,14 @@ public final class PdfDocument { private final class PdfCanvas extends Canvas { - public PdfCanvas(int nativeCanvas, int density) { + public PdfCanvas(int nativeCanvas) { super(nativeCanvas); - super.setDensity(density); } @Override public void setBitmap(Bitmap bitmap) { throw new UnsupportedOperationException(); } - - @Override - public void setDensity(int density) { - throw new UnsupportedOperationException(); - } - - @Override - public void setScreenDensity(int density) { - throw new UnsupportedOperationException(); - } } /** @@ -259,7 +247,6 @@ public final class PdfDocument { private Rect mContentSize; private Matrix mInitialTransform; private int mPageNumber; - private int mDensity; /** * Creates a new instance. @@ -269,7 +256,7 @@ public final class PdfDocument { } /** - * Gets the page size in pixels. + * Gets the page size in PostScript points (1/72th of an inch). * * @return The page size. */ @@ -278,7 +265,7 @@ public final class PdfDocument { } /** - * Get the content size in pixels. + * Get the content size in PostScript points (1/72th of an inch). * * @return The content size. */ @@ -306,15 +293,6 @@ public final class PdfDocument { return mPageNumber; } - /** - * Gets the density of the page in DPI. - * - * @return The density. - */ - public int getDesity() { - return mDensity; - } - /** * Builder for creating a {@link PageInfo}. */ @@ -324,11 +302,10 @@ public final class PdfDocument { /** * Creates a new builder with the mandatory page info attributes. * - * @param pageSize The page size in points, not dips. + * @param pageSize The page size in PostScript (1/72th of an inch). * @param pageNumber The page number. - * @param density The page density in DPI. */ - public Builder(Rect pageSize, int pageNumber, int density) { + public Builder(Rect pageSize, int pageNumber) { if (pageSize.width() == 0 || pageSize.height() == 0) { throw new IllegalArgumentException("page width and height" + " must be greater than zero!"); @@ -336,16 +313,12 @@ public final class PdfDocument { if (pageNumber < 0) { throw new IllegalArgumentException("pageNumber cannot be less than zero!"); } - if (density <= 0) { - throw new IllegalArgumentException("density must be greater than zero!"); - } mPageInfo.mPageSize = pageSize; mPageInfo.mPageNumber = pageNumber; - mPageInfo.mDensity = density; } /** - * Sets the content size in pixels. + * Sets the content size in PostScript point (1/72th of an inch). * * @param contentSize The content size. */ diff --git a/core/java/android/print/pdf/PrintedPdfDocument.java b/core/java/android/print/pdf/PrintedPdfDocument.java new file mode 100644 index 0000000000000..a3be38bb1f716 --- /dev/null +++ b/core/java/android/print/pdf/PrintedPdfDocument.java @@ -0,0 +1,162 @@ +/* + * 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.print.PrintAttributes; +import android.print.PrintAttributes.Margins; +import android.print.PrintAttributes.MediaSize; +import android.print.pdf.PdfDocument; +import android.print.pdf.PdfDocument.Page; +import android.print.pdf.PdfDocument.PageInfo; + +import java.io.OutputStream; +import java.util.List; + +/** + * This class is a helper for printing content to a different media + * size. This class is responsible for computing a correct page size + * given some print constraints, i.e. {@link PrintAttributes}. It is + * an adapter around a {@link PdfDocument}. + */ +public final class PrintedPdfDocument { + private static final int MILS_PER_INCH = 1000; + private static final int POINTS_IN_INCH = 72; + + private final PdfDocument mDocument = PdfDocument.open(); + private final Rect mPageSize = new Rect(); + private final Rect mContentSize = new Rect(); + + /** + * Opens a new document. The document pages are computed based on + * the passes in {@link PrintAttributes}. + *+ * Note: You must close the document after you are + * done by calling {@link #close()} + *
+ * + * @param context Context instance for accessing resources. + * @param attributes The print attributes. + * @return The document. + * + * @see #close() + */ + public static PrintedPdfDocument open(Context context, PrintAttributes attributes) { + return new PrintedPdfDocument(context, attributes); + } + + /** + * Creates a new instance. + * + * @param context Context instance for accessing resources and services. + * @param attributes The {@link PrintAttributes} to user. + */ + private PrintedPdfDocument(Context context, PrintAttributes attributes) { + MediaSize mediaSize = attributes.getMediaSize(); + + // Compute the size of the target canvas from the attributes. + final int pageWidth = (int) (((float) mediaSize.getWidthMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + final int pageHeight = (int) (((float) mediaSize.getHeightMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + mPageSize.set(0, 0, pageWidth, pageHeight); + + // Compute the content size from the attributes. + Margins margins = attributes.getMargins(); + final int marginLeft = (int) (((float) margins.getLeftMils() /MILS_PER_INCH) + * POINTS_IN_INCH); + final int marginTop = (int) (((float) margins.getTopMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + final int marginRight = (int) (((float) margins.getRightMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + final int marginBottom = (int) (((float) margins.getBottomMils() / MILS_PER_INCH) + * POINTS_IN_INCH); + mContentSize.set(mPageSize.left + marginLeft, mPageSize.top + marginTop, + mPageSize.right - marginRight, mPageSize.bottom - marginBottom); + } + + /** + * Starts a page using a page size computed from the print attributes + * passed in {@link #open(Context, PrintAttributes)} and the given page + * number to create appropriate {@link PageInfo}. + *+ * 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. + *
+ *+ * Note: Do not call this method after {@link #close()}. + *
+ * + * @param pageNumber The page number. + * @return A blank page. + * + * @see #finishPage(Page) + */ + public Page startPage(int pageNumber) { + PageInfo pageInfo = new PageInfo.Builder(mPageSize, 0).create(); + Page page = mDocument.startPage(pageInfo); + return page; + } + + /** + * Finishes a started page. You should always finish the last started page. + *+ * Note: Do not call this method after {@link #close()}. + *
+ * + * @param page The page. + * + * @see #startPage(int) + */ + public void finishPage(Page page) { + mDocument.finishPage(page); + } + + /** + * Writes the document to an output stream. + *+ * Note: Do not call this method after {@link #close()}. + *
+ * + * @param out The output stream. + */ + public void writeTo(OutputStream out) { + mDocument.writeTo(out); + } + + /** + * Gets the pages of the document. + * + * @return The pages. + */ + public List