diff options
author | Derek Sollenberger <djsollen@google.com> | 2020-02-21 11:43:02 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-02-21 11:43:02 +0000 |
commit | 76e7430baead21c67fd4c81a36774a6461d2fb99 (patch) | |
tree | 239a62b59c57b4b95d8e82943bf9a48e84439819 /libs/hwui/jni/pdf/PdfUtils.cpp | |
parent | 1ab8e44c06ca05806a81c6737cb3f6e316d8d25a (diff) | |
parent | 2173ea286afff6766043227de0bc2d82d9595f77 (diff) |
Merge changes from topic "HWUI_JNI"
* changes:
Export symbols for the newly exposed APEX/internal headers
Remove dependence on libandroid_runtime from Bitmap.cpp
Update Region.cpp to use AParcel NDK APIs
Cleanup header and build targets for libhwui clients.
Remove dependencies on headers outside UI module
Cleanup LOG_TAG when bundled in HWUI
Move android.graphics JNI & APEX files into HWUI
Diffstat (limited to 'libs/hwui/jni/pdf/PdfUtils.cpp')
-rw-r--r-- | libs/hwui/jni/pdf/PdfUtils.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/libs/hwui/jni/pdf/PdfUtils.cpp b/libs/hwui/jni/pdf/PdfUtils.cpp new file mode 100644 index 000000000000..06d202828b85 --- /dev/null +++ b/libs/hwui/jni/pdf/PdfUtils.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2016 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. + */ + +#include "PdfUtils.h" + +#include "jni.h" +#include <nativehelper/JNIHelp.h> + +#include "fpdfview.h" + +#undef LOG_TAG +#define LOG_TAG "PdfUtils" +#include <utils/Log.h> + +namespace android { + +static int sUnmatchedPdfiumInitRequestCount = 0; + +int getBlock(void* param, unsigned long position, unsigned char* outBuffer, + unsigned long size) { + const int fd = reinterpret_cast<intptr_t>(param); + const int readCount = pread(fd, outBuffer, size, position); + if (readCount < 0) { + ALOGE("Cannot read from file descriptor. Error:%d", errno); + return 0; + } + return 1; +} + +// Check if the last pdfium command failed and if so, forward the error to java via an exception. If +// this function returns true an exception is pending. +bool forwardPdfiumError(JNIEnv* env) { + long error = FPDF_GetLastError(); + switch (error) { + case FPDF_ERR_SUCCESS: + return false; + case FPDF_ERR_FILE: + jniThrowException(env, "java/io/IOException", "file not found or cannot be opened"); + break; + case FPDF_ERR_FORMAT: + jniThrowException(env, "java/io/IOException", "file not in PDF format or corrupted"); + break; + case FPDF_ERR_PASSWORD: + jniThrowException(env, "java/lang/SecurityException", + "password required or incorrect password"); + break; + case FPDF_ERR_SECURITY: + jniThrowException(env, "java/lang/SecurityException", "unsupported security scheme"); + break; + case FPDF_ERR_PAGE: + jniThrowException(env, "java/io/IOException", "page not found or content error"); + break; +#ifdef PDF_ENABLE_XFA + case FPDF_ERR_XFALOAD: + jniThrowException(env, "java/lang/Exception", "load XFA error"); + break; + case FPDF_ERR_XFALAYOUT: + jniThrowException(env, "java/lang/Exception", "layout XFA error"); + break; +#endif // PDF_ENABLE_XFA + case FPDF_ERR_UNKNOWN: + default: + jniThrowExceptionFmt(env, "java/lang/Exception", "unknown error %d", error); + } + + return true; +} + +static void initializeLibraryIfNeeded(JNIEnv* env) { + if (sUnmatchedPdfiumInitRequestCount == 0) { + FPDF_InitLibrary(); + } + + sUnmatchedPdfiumInitRequestCount++; +} + +static void destroyLibraryIfNeeded(JNIEnv* env, bool handleError) { + if (sUnmatchedPdfiumInitRequestCount == 1) { + FPDF_DestroyLibrary(); + } + + sUnmatchedPdfiumInitRequestCount--; +} + +jlong nativeOpen(JNIEnv* env, jclass thiz, jint fd, jlong size) { + initializeLibraryIfNeeded(env); + + FPDF_FILEACCESS loader; + loader.m_FileLen = size; + loader.m_Param = reinterpret_cast<void*>(intptr_t(fd)); + loader.m_GetBlock = &getBlock; + + FPDF_DOCUMENT document = FPDF_LoadCustomDocument(&loader, NULL); + if (!document) { + forwardPdfiumError(env); + destroyLibraryIfNeeded(env, false); + return -1; + } + + return reinterpret_cast<jlong>(document); +} + +void nativeClose(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + FPDF_CloseDocument(document); + + destroyLibraryIfNeeded(env, true); +} + +jint nativeGetPageCount(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + + return FPDF_GetPageCount(document); +} + +jboolean nativeScaleForPrinting(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + FPDF_BOOL printScaling = FPDF_VIEWERREF_GetPrintScaling(document); + + return printScaling ? JNI_TRUE : JNI_FALSE; +} + +}; |