summaryrefslogtreecommitdiff
path: root/libs/hwui/jni/pdf/PdfUtils.cpp
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2020-02-21 11:43:02 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-02-21 11:43:02 +0000
commit76e7430baead21c67fd4c81a36774a6461d2fb99 (patch)
tree239a62b59c57b4b95d8e82943bf9a48e84439819 /libs/hwui/jni/pdf/PdfUtils.cpp
parent1ab8e44c06ca05806a81c6737cb3f6e316d8d25a (diff)
parent2173ea286afff6766043227de0bc2d82d9595f77 (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.cpp136
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;
+}
+
+};