162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav/* 262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Copyright (C) 2014 The Android Open Source Project 362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Licensed under the Apache License, Version 2.0 (the "License"); 562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * you may not use this file except in compliance with the License. 662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * You may obtain a copy of the License at 762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * http://www.apache.org/licenses/LICENSE-2.0 962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 1062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Unless required by applicable law or agreed to in writing, software 1162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * distributed under the License is distributed on an "AS IS" BASIS, 1262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * See the License for the specific language governing permissions and 1462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * limitations under the License. 1562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav */ 1662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 1762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavpackage android.graphics.pdf; 1862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 1962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport android.annotation.NonNull; 20bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslavimport android.annotation.Nullable; 21bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslavimport android.graphics.Matrix; 22bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslavimport android.graphics.Point; 23bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslavimport android.graphics.Rect; 2462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport android.os.ParcelFileDescriptor; 2562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport android.system.ErrnoException; 2662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport android.system.OsConstants; 2762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport dalvik.system.CloseGuard; 2862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport libcore.io.IoUtils; 2962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport libcore.io.Libcore; 3062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 3162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavimport java.io.IOException; 3262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 3362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav/** 3462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Class for editing PDF files. 3562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 3662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * @hide 3762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav */ 3862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslavpublic final class PdfEditor { 3962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 4062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private final CloseGuard mCloseGuard = CloseGuard.get(); 4162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 4262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private final long mNativeDocument; 4362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 4462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private int mPageCount; 4562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 4662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private ParcelFileDescriptor mInput; 4762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 4862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav /** 4962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Creates a new instance. 5062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * <p> 5162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * <strong>Note:</strong> The provided file descriptor must be <strong>seekable</strong>, 5262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * i.e. its data being randomly accessed, e.g. pointing to a file. After finishing 5362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * with this class you must call {@link #close()}. 5462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * </p> 5562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * <p> 5662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * <strong>Note:</strong> This class takes ownership of the passed in file descriptor 5762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * and is responsible for closing it when the editor is closed. 5862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * </p> 5962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 6062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * @param input Seekable file descriptor to read from. 6162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 62fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov * @throws java.io.IOException If an error occurs while reading the file. 63fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov * @throws java.lang.SecurityException If the file requires a password or 64fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov * the security scheme is not supported. 65fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov * 6662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * @see #close() 6762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav */ 6862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav public PdfEditor(@NonNull ParcelFileDescriptor input) throws IOException { 6962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav if (input == null) { 7062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throw new NullPointerException("input cannot be null"); 7162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 7262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 7362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav final long size; 7462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav try { 7562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav Libcore.os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET); 7662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav size = Libcore.os.fstat(input.getFileDescriptor()).st_size; 7762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } catch (ErrnoException ee) { 7862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throw new IllegalArgumentException("file descriptor not seekable"); 7962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 8062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 8162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mInput = input; 8262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mNativeDocument = nativeOpen(mInput.getFd(), size); 8362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mPageCount = nativeGetPageCount(mNativeDocument); 8462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mCloseGuard.open("close"); 8562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 8662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 8762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav /** 8862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Gets the number of pages in the document. 8962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 9062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * @return The page count. 9162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav */ 9262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav public int getPageCount() { 9362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throwIfClosed(); 9462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav return mPageCount; 9562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 9662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 9762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav /** 9862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Removes the page with a given index. 9962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * 10062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * @param pageIndex The page to remove. 10162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav */ 10262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav public void removePage(int pageIndex) { 10362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throwIfClosed(); 10462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throwIfPageNotInDocument(pageIndex); 10562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mPageCount = nativeRemovePage(mNativeDocument, pageIndex); 10662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 10762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 10862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav /** 109bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * Sets a transformation and clip for a given page. The transformation matrix if 110bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * non-null must be affine as per {@link android.graphics.Matrix#isAffine()}. If 111bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * the clip is null, then no clipping is performed. 112bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * 113bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param pageIndex The page whose transform to set. 114bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param transform The transformation to apply. 115bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param clip The clip to apply. 116bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav */ 117bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav public void setTransformAndClip(int pageIndex, @Nullable Matrix transform, 118bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav @Nullable Rect clip) { 119bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfClosed(); 120bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfPageNotInDocument(pageIndex); 121bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfNotNullAndNotAfine(transform); 122bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (transform == null) { 123bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav transform = Matrix.IDENTITY_MATRIX; 124bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 125bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (clip == null) { 126bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav Point size = new Point(); 127bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav getPageSize(pageIndex, size); 128bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance, 129bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 0, 0, size.x, size.y); 130bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } else { 131bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance, 132bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav clip.left, clip.top, clip.right, clip.bottom); 133bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 134bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 135bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 136bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav /** 137bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * Gets the size of a given page in mils (1/72"). 138bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * 139bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param pageIndex The page index. 140bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param outSize The size output. 141bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav */ 142bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav public void getPageSize(int pageIndex, @NonNull Point outSize) { 143bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfClosed(); 144bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfOutSizeNull(outSize); 145bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfPageNotInDocument(pageIndex); 146bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav nativeGetPageSize(mNativeDocument, pageIndex, outSize); 147bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 148bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 149bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav /** 150bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * Gets the media box of a given page in mils (1/72"). 151bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * 152bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param pageIndex The page index. 153bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param outMediaBox The media box output. 154bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav */ 155bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav public boolean getPageMediaBox(int pageIndex, @NonNull Rect outMediaBox) { 156bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfClosed(); 157bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfOutMediaBoxNull(outMediaBox); 158bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfPageNotInDocument(pageIndex); 159bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox); 160bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 161bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 162bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav /** 163bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * Sets the media box of a given page in mils (1/72"). 164bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * 165bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param pageIndex The page index. 166bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param mediaBox The media box. 167bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav */ 168bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav public void setPageMediaBox(int pageIndex, @NonNull Rect mediaBox) { 169bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfClosed(); 170bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfMediaBoxNull(mediaBox); 171bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfPageNotInDocument(pageIndex); 172bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox); 173bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 174bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 175bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav /** 176bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * Gets the crop box of a given page in mils (1/72"). 177bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * 178bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param pageIndex The page index. 179bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param outCropBox The crop box output. 180bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav */ 181bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav public boolean getPageCropBox(int pageIndex, @NonNull Rect outCropBox) { 182bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfClosed(); 183bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfOutCropBoxNull(outCropBox); 184bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfPageNotInDocument(pageIndex); 185bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox); 186bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 187bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 188bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav /** 189bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * Sets the crop box of a given page in mils (1/72"). 190bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * 191bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param pageIndex The page index. 192bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @param cropBox The crop box. 193bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav */ 194bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav public void setPageCropBox(int pageIndex, @NonNull Rect cropBox) { 195bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfClosed(); 196bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfCropBoxNull(cropBox); 197bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfPageNotInDocument(pageIndex); 198bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox); 199bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 200bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 201bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav /** 202bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * Gets whether the document prefers to be scaled for printing. 203bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * 204bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav * @return Whether to scale the document. 205bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav */ 206bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav public boolean shouldScaleForPrinting() { 207bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throwIfClosed(); 208bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav return nativeScaleForPrinting(mNativeDocument); 209bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 210bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 211bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav /** 21262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Writes the PDF file to the provided destination. 21362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * <p> 21462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * <strong>Note:</strong> This method takes ownership of the passed in file 21562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * descriptor and is responsible for closing it when writing completes. 21662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * </p> 21762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * @param output The destination. 21862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav */ 21962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav public void write(ParcelFileDescriptor output) throws IOException { 22062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav try { 22162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throwIfClosed(); 22262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav nativeWrite(mNativeDocument, output.getFd()); 22362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } finally { 22462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav IoUtils.closeQuietly(output); 22562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 22662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 22762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 22862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav /** 22962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * Closes this editor. You should not use this instance 23062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav * after this method is called. 23162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav */ 23262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav public void close() { 23362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throwIfClosed(); 23462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav doClose(); 23562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 23662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 23762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav @Override 23862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav protected void finalize() throws Throwable { 23962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav try { 24062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mCloseGuard.warnIfOpen(); 24162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav if (mInput != null) { 24262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav doClose(); 24362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 24462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } finally { 24562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav super.finalize(); 24662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 24762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 24862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 24962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private void doClose() { 25062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav nativeClose(mNativeDocument); 25162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav IoUtils.closeQuietly(mInput); 25262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mInput = null; 25362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav mCloseGuard.close(); 25462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 25562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 25662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private void throwIfClosed() { 25762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav if (mInput == null) { 25862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throw new IllegalStateException("Already closed"); 25962ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 26062ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 26162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 26262ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private void throwIfPageNotInDocument(int pageIndex) { 26362ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav if (pageIndex < 0 || pageIndex >= mPageCount) { 26462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav throw new IllegalArgumentException("Invalid page index"); 26562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 26662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav } 26762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav 268bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private void throwIfNotNullAndNotAfine(Matrix matrix) { 269bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (matrix != null && !matrix.isAffine()) { 270bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throw new IllegalStateException("Matrix must be afine"); 271bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 272bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 273bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 274bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private void throwIfOutSizeNull(Point outSize) { 275bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (outSize == null) { 276bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throw new NullPointerException("outSize cannot be null"); 277bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 278bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 279bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 280bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private void throwIfOutMediaBoxNull(Rect outMediaBox) { 281bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (outMediaBox == null) { 282bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throw new NullPointerException("outMediaBox cannot be null"); 283bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 284bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 285bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 286bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private void throwIfMediaBoxNull(Rect mediaBox) { 287bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (mediaBox == null) { 288bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throw new NullPointerException("mediaBox cannot be null"); 289bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 290bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 291bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 292bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private void throwIfOutCropBoxNull(Rect outCropBox) { 293bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (outCropBox == null) { 294bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throw new NullPointerException("outCropBox cannot be null"); 295bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 296bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 297bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 298bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private void throwIfCropBoxNull(Rect cropBox) { 299bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav if (cropBox == null) { 300bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav throw new NullPointerException("cropBox cannot be null"); 301bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 302bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav } 303bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav 30462ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private static native long nativeOpen(int fd, long size); 30562ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private static native void nativeClose(long documentPtr); 30662ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private static native int nativeGetPageCount(long documentPtr); 30762ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private static native int nativeRemovePage(long documentPtr, int pageIndex); 30862ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav private static native void nativeWrite(long documentPtr, int fd); 309bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private static native void nativeSetTransformAndClip(long documentPtr, int pageIndex, 310bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav long transformPtr, int clipLeft, int clipTop, int clipRight, int clipBottom); 311bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private static native void nativeGetPageSize(long documentPtr, int pageIndex, Point outSize); 312bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private static native boolean nativeGetPageMediaBox(long documentPtr, int pageIndex, 313bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav Rect outMediaBox); 314bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private static native void nativeSetPageMediaBox(long documentPtr, int pageIndex, 315bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav Rect mediaBox); 316bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private static native boolean nativeGetPageCropBox(long documentPtr, int pageIndex, 317bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav Rect outMediaBox); 318bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private static native void nativeSetPageCropBox(long documentPtr, int pageIndex, 319bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav Rect mediaBox); 320bec22beb99b279d381f720d761ca75fe3e7414dcSvetoslav private static native boolean nativeScaleForPrinting(long documentPtr); 32162ce332c141cf7bc7200c4c87d63e395874fc3ecSvetoslav} 322