Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aec1417c authored by Svetoslav Ganov's avatar Svetoslav Ganov
Browse files

Print APIs update.

1. Added scale to fit and scale to fill fitting modes.

2. Added APIs for a print app to specify which constraints imposed
   by the print attributes were satsified during a layout so they
   are not handled by the printer again, e.g. if the content is to
   be in landscape the the app generated such content the printer
   should rotate the content again.

3. Added some printer statuses.

4. Added a helper class that generates PDF documents with correct
   size based on the passed in print attributes.

5. Exposed a ctor for PageRange which was hidden by mistake and apps
   could not create page ranges. Added API for changing the printer
   status.

Change-Id: If1334a61d2d931027b98075f653018d456b1b768
parent 94366313
Loading
Loading
Loading
Loading
+30 −4
Original line number Diff line number Diff line
@@ -18877,6 +18877,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();
@@ -18904,8 +18905,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
  }
@@ -18930,6 +18932,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 {
@@ -19017,21 +19020,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);
  }
@@ -19119,7 +19134,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 {
@@ -19129,6 +19146,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);
  }
}
@@ -19151,19 +19169,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<android.print.pdf.PdfDocument.PageInfo> getPages();
    method public static android.print.pdf.PrintedPdfDocument open(android.content.Context, android.print.PrintAttributes);
    method public android.print.pdf.PdfDocument.Page startPage(int);
    method public void writeTo(java.io.OutputStream);
  }
}
package android.printservice {
+0 −2
Original line number Diff line number Diff line
@@ -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) {
+31 −29
Original line number Diff line number Diff line
@@ -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);
        }
    }
+22 −0
Original line number Diff line number Diff line
@@ -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
+251 −4
Original line number Diff line number Diff line
@@ -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.
         *
@@ -234,6 +392,95 @@ public final class PrintDocumentInfo implements Parcelable {
            return this;
        }

        /**
         * 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.
         *
Loading