diff options
| author | Svetoslav Ganov <svetoslavganov@google.com> | 2013-08-28 00:07:08 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-08-28 00:07:09 +0000 |
| commit | ca09dbc67b28d5d1d16b7966b855229697c6c549 (patch) | |
| tree | 0ca07ec7add60de57f04f43cb2cfcd9c39d035ac /core/java/android | |
| parent | bbbc8660cdbfb033291f1911742a942a42c85af0 (diff) | |
| parent | aec1417ca9eb63209668ac17da90cf8a07c6076c (diff) | |
Merge "Print APIs update." into klp-dev
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/print/PageRange.java | 2 | ||||
| -rw-r--r-- | core/java/android/print/PrintAttributes.java | 60 | ||||
| -rw-r--r-- | core/java/android/print/PrintDocumentAdapter.java | 22 | ||||
| -rw-r--r-- | core/java/android/print/PrintDocumentInfo.java | 255 | ||||
| -rw-r--r-- | core/java/android/print/PrinterCapabilitiesInfo.java | 4 | ||||
| -rw-r--r-- | core/java/android/print/PrinterInfo.java | 29 | ||||
| -rw-r--r-- | core/java/android/print/pdf/PdfDocument.java | 43 | ||||
| -rw-r--r-- | core/java/android/print/pdf/PrintedPdfDocument.java | 162 |
8 files changed, 501 insertions, 76 deletions
diff --git a/core/java/android/print/PageRange.java b/core/java/android/print/PageRange.java index ba455f622810..cdcd0c7d2e6a 100644 --- a/core/java/android/print/PageRange.java +++ b/core/java/android/print/PageRange.java @@ -42,8 +42,6 @@ public final class PageRange implements Parcelable { * @throws IllegalArgumentException If start is less than zero. * @throws IllegalArgumentException If end is less than zero. * @throws IllegalArgumentException If start greater than end. - * - * @hide */ public PageRange(int start, int end) { if (start < 0) { diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java index a902c7204bbd..caa10aee03b0 100644 --- a/core/java/android/print/PrintAttributes.java +++ b/core/java/android/print/PrintAttributes.java @@ -50,9 +50,15 @@ public final class PrintAttributes implements Parcelable { /** Fitting mode: No fitting. */ - public static final int FITTING_MODE_NONE = 0x00000001; - /** Fitting mode: Fit the content to the page. */ - public static final int FITTING_MODE_FIT_TO_PAGE = 0x00000002; + public static final int FITTING_MODE_NONE = 1 << 0; + /** Fitting mode: Scale the content to fit in the page + * without cropping it in any dimension. */ + public static final int FITTING_MODE_SCALE_TO_FIT = 1 << 1; + /** + * Fitting mode: Uniformly scale the content to fill the entire page + * potentially cropping the content if it overflows in one dimension. + */ + public static final int FITTING_MODE_SCALE_TO_FILL = 1 << 2; private static final int VALID_DUPLEX_MODES = @@ -62,7 +68,7 @@ public final class PrintAttributes implements Parcelable { COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR; private static final int VALID_FITTING_MODES = - FITTING_MODE_NONE | FITTING_MODE_FIT_TO_PAGE; + FITTING_MODE_NONE | FITTING_MODE_SCALE_TO_FIT | FITTING_MODE_SCALE_TO_FILL; private static final int VALID_ORIENTATIONS = ORIENTATION_PORTRAIT | ORIENTATION_LANDSCAPE; @@ -252,7 +258,8 @@ public final class PrintAttributes implements Parcelable { * @return The fitting mode or zero if not set. * * @see #FITTING_MODE_NONE - * @see #FITTING_MODE_FIT_TO_PAGE + * @see #FITTING_MODE_SCALE_TO_FILL + * @see #FITTING_MODE_SCALE_TO_FIT */ public int getFittingMode() { return mFittingMode; @@ -264,12 +271,13 @@ public final class PrintAttributes implements Parcelable { * @param The fitting mode. * * @see #FITTING_MODE_NONE - * @see #FITTING_MODE_FIT_TO_PAGE + * @see #FITTING_MODE_SCALE_TO_FILL + * @see #FITTING_MODE_SCALE_TO_FIT * * @hide */ public void setFittingMode(int fittingMode) { - enfoceValidFittingMode(fittingMode); + enforceValidFittingMode(fittingMode); mFittingMode = fittingMode; } @@ -1220,6 +1228,8 @@ public final class PrintAttributes implements Parcelable { * This class specifies content margins. */ public static final class Margins { + public static final Margins NO_MARGINS = new Margins(0, 0, 0, 0); + private final int mLeftMils; private final int mTopMils; private final int mRightMils; @@ -1232,24 +1242,13 @@ public final class PrintAttributes implements Parcelable { * @param topMils The top margin in mils (thousands of an inch). * @param rightMils The right margin in mils (thousands of an inch). * @param bottomMils The bottom margin in mils (thousands of an inch). - * - * @throws IllegalArgumentException If the leftMils is less than zero. - * @throws IllegalArgumentException If the topMils is less than zero. - * @throws IllegalArgumentException If the rightMils is less than zero. - * @throws IllegalArgumentException If the bottomMils is less than zero. */ public Margins(int leftMils, int topMils, int rightMils, int bottomMils) { - if (leftMils < 0) { - throw new IllegalArgumentException("leftMils cannot be less than zero."); + if (leftMils > rightMils) { + throw new IllegalArgumentException("leftMils cannot be less than rightMils."); } - if (topMils < 0) { - throw new IllegalArgumentException("topMils cannot be less than zero."); - } - if (rightMils < 0) { - throw new IllegalArgumentException("rightMils cannot be less than zero."); - } - if (bottomMils < 0) { - throw new IllegalArgumentException("bottomMils cannot be less than zero."); + if (topMils > bottomMils) { + throw new IllegalArgumentException("topMils cannot be less than bottomMils."); } mTopMils = topMils; mLeftMils = leftMils; @@ -1504,8 +1503,11 @@ public final class PrintAttributes implements Parcelable { case FITTING_MODE_NONE: { return "FITTING_MODE_NONE"; } - case FITTING_MODE_FIT_TO_PAGE: { - return "FITTING_MODE_FIT_TO_PAGE"; + case FITTING_MODE_SCALE_TO_FIT: { + return "FITTING_MODE_SCALE_TO_FIT"; + } + case FITTING_MODE_SCALE_TO_FILL: { + return "FITTING_MODE_SCALE_TO_FILL"; } default: return "FITTING_MODE_UNKNOWN"; @@ -1513,25 +1515,25 @@ public final class PrintAttributes implements Parcelable { } static void enforceValidDuplexMode(int duplexMode) { - if ((duplexMode & VALID_DUPLEX_MODES) == 0) { + if ((duplexMode & VALID_DUPLEX_MODES) == 0 && Integer.bitCount(duplexMode) == 1) { throw new IllegalArgumentException("invalid duplex mode: " + duplexMode); } } static void enforceValidColorMode(int colorMode) { - if ((colorMode & VALID_COLOR_MODES) == 0) { + if ((colorMode & VALID_COLOR_MODES) == 0 && Integer.bitCount(colorMode) == 1) { throw new IllegalArgumentException("invalid color mode: " + colorMode); } } - static void enfoceValidFittingMode(int fittingMode) { - if ((fittingMode & VALID_FITTING_MODES) == 0) { + static void enforceValidFittingMode(int fittingMode) { + if ((fittingMode & VALID_FITTING_MODES) == 0 && Integer.bitCount(fittingMode) == 1) { throw new IllegalArgumentException("invalid fitting mode: " + fittingMode); } } static void enforceValidOrientation(int orientation) { - if ((orientation & VALID_ORIENTATIONS) == 0) { + if ((orientation & VALID_ORIENTATIONS) == 0 && Integer.bitCount(orientation) == 1) { throw new IllegalArgumentException("invalid orientation: " + orientation); } } diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java index d3202262bbd5..8a64e85cd07d 100644 --- a/core/java/android/print/PrintDocumentAdapter.java +++ b/core/java/android/print/PrintDocumentAdapter.java @@ -101,6 +101,28 @@ public abstract class PrintDocumentAdapter { * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred. * </p> * <p> + * 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. + * </p> + * <p> * <strong>Note:</strong> 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 653ad4bfc4e4..b32961b641cf 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. + * <p> + * 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()}. + * </p> * * @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. + * <p> + * 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. + * </p> + * + * @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. + * <p> + * <strong>Default: </strong> {@link #PAGE_COUNT_UNKNOWN} + * </p> * * @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. + * <p> + * <strong>Default: </strong> {@link #CONTENT_TYPE_UNKNOWN} + * </p> * * @param type The content type. * @@ -235,6 +393,95 @@ public final class PrintDocumentInfo implements Parcelable { } /** + * Sets the orientation. + * <p> + * <strong>Default: </strong> {@link PrintAttributes#ORIENTATION_PORTRAIT + * PrintAttributes.ORIENTATION_PORTRAIT} + * </p> + * + * @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. + * <p> + * <strong>Default: </strong> {@link PrintAttributes#FITTING_MODE_NONE + * PrintAttributes.FITTING_MODE_NONE} + * </p> + * + * @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. + * <p> + * <strong>Default: </strong> {@link PrintAttributes#COLOR_MODE_COLOR + * PrintAttributes.COLOR_MODE_COLOR} + * </p> + * + * @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. + * <p> + * <strong>Default: </strong> {@link PrintAttributes.Margins#NO_MARGINS Margins.NO_MARGINS} + * </p> + * + * @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. + * <p> + * <strong>Default: </strong>#MEDIA_SIZE_UNKNOWN + * </p> + * + * @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. * * @return The new instance. diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java index 70b418c2a145..941e6e1f7d2c 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 6f567a64d709..0ea319be8b1d 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; @@ -237,6 +241,21 @@ public final class PrinterInfo implements Parcelable { } /** + * 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. * * @param name The 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 dbd7dd1448c5..a2883cf83e3a 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. */ @@ -307,15 +294,6 @@ public final class PdfDocument { } /** - * Gets the density of the page in DPI. - * - * @return The density. - */ - public int getDesity() { - return mDensity; - } - - /** * Builder for creating a {@link PageInfo}. */ public static final class Builder { @@ -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, <strong>not</strong> 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 000000000000..a3be38bb1f71 --- /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}. + * <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. + * @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}. + * <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()}. + * </p> + * + * @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. + * <p> + * <strong>Note:</strong> Do not call this method after {@link #close()}. + * </p> + * + * @param page The page. + * + * @see #startPage(int) + */ + public void finishPage(Page page) { + mDocument.finishPage(page); + } + + /** + * Writes the document to an output stream. + * <p> + * <strong>Note:</strong> Do not call this method after {@link #close()}. + * </p> + * + * @param out The output stream. + */ + public void writeTo(OutputStream out) { + mDocument.writeTo(out); + } + + /** + * Gets the pages of the document. + * + * @return The pages. + */ + public List<PageInfo> getPages() { + return mDocument.getPages(); + } + + /** + * Closes this document. This method should be called after you + * are done working with the document. After this call the document + * is considered closed and none of its methods should be called. + */ + public void close() { + mDocument.close(); + } +} |
