Merge "Use only official pdfium APIs"
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 95b25932..64e1620e 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -210,10 +210,7 @@
$(TOP)/system/media/camera/include \
$(TOP)/system/netd/include \
external/giflib \
- external/pdfium/core/include/fpdfapi \
- external/pdfium/fpdfsdk/include \
external/pdfium/public \
- external/pdfium \
external/skia/include/private \
external/skia/src/core \
external/skia/src/effects \
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index 6e7b6b8..1001c05 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -23,11 +23,6 @@
#include "SkMatrix.h"
#include "fpdfview.h"
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
-#include "fsdk_rendercontext.h"
-#pragma GCC diagnostic pop
-
#include "core_jni_helpers.h"
#include <vector>
#include <utils/Log.h>
@@ -80,103 +75,10 @@
HANDLE_PDFIUM_ERROR_STATE(env)
}
-static void DropContext(void* data) {
- delete (CRenderContext*) data;
-}
-
-static void renderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page, int destLeft, int destTop,
- int destRight, int destBottom, SkMatrix* transform, int flags) {
- // Note: this code ignores the currently unused RENDER_NO_NATIVETEXT,
- // FPDF_RENDER_LIMITEDIMAGECACHE, FPDF_RENDER_FORCEHALFTONE, FPDF_GRAYSCALE,
- // and FPDF_ANNOT flags. To add support for that refer to FPDF_RenderPage_Retail
- // in fpdfview.cpp
-
- CRenderContext* pContext = new CRenderContext;
-
- CPDF_Page* pPage = (CPDF_Page*) page;
- pPage->SetPrivateData((void*) 1, pContext, DropContext);
-
- CFX_FxgeDevice* fxgeDevice = new CFX_FxgeDevice;
- pContext->m_pDevice = fxgeDevice;
-
- // Reverse the bytes (last argument TRUE) since the Android
- // format is ARGB while the renderer uses BGRA internally.
- fxgeDevice->Attach((CFX_DIBitmap*) bitmap, 0, TRUE);
-
- CPDF_RenderOptions* renderOptions = pContext->m_pOptions;
-
- if (!renderOptions) {
- renderOptions = new CPDF_RenderOptions;
- pContext->m_pOptions = renderOptions;
- }
-
- if (flags & FPDF_LCD_TEXT) {
- renderOptions->m_Flags |= RENDER_CLEARTYPE;
- } else {
- renderOptions->m_Flags &= ~RENDER_CLEARTYPE;
- }
-
- const CPDF_OCContext::UsageType usage = (flags & FPDF_PRINTING)
- ? CPDF_OCContext::Print : CPDF_OCContext::View;
-
- renderOptions->m_AddFlags = flags >> 8;
- renderOptions->m_pOCContext = new CPDF_OCContext(pPage->m_pDocument, usage);
-
- fxgeDevice->SaveState();
-
- FX_RECT clip;
- clip.left = destLeft;
- clip.right = destRight;
- clip.top = destTop;
- clip.bottom = destBottom;
- fxgeDevice->SetClip_Rect(&clip);
-
- CPDF_RenderContext* pageContext = new CPDF_RenderContext(pPage);
- pContext->m_pContext = pageContext;
-
- CFX_Matrix matrix;
- if (!transform) {
- pPage->GetDisplayMatrix(matrix, destLeft, destTop, destRight - destLeft,
- destBottom - destTop, 0);
- } else {
- // PDF's coordinate system origin is left-bottom while
- // in graphics it is the top-left, so remap the origin.
- SkMatrix reflectOnX = SkMatrix::MakeScale(1, -1);
- SkMatrix moveUp = SkMatrix::MakeTrans(0, FPDF_GetPageHeight(page));
- SkMatrix m = SkMatrix::Concat(moveUp, reflectOnX);
-
- // Concatenate transformation and origin transformation
- m.setConcat(*transform, m);
-
- SkScalar transformValues[6];
- if (!m.asAffine(transformValues)) {
- // Already checked for a return value of false in the caller, so this should never
- // happen.
- ALOGE("Error rendering page!");
- }
-
- matrix = {transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
- transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
- transformValues[SkMatrix::kATransX], transformValues[SkMatrix::kATransY]};
- }
- pageContext->AppendObjectList(pPage, &matrix);
-
- pContext->m_pRenderer = new CPDF_ProgressiveRenderer(pageContext, fxgeDevice, renderOptions);
- pContext->m_pRenderer->Start(NULL);
-
- fxgeDevice->RestoreState();
-
- pPage->RemovePrivateData((void*) 1);
-
- delete pContext;
-}
-
static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr,
- jobject jbitmap, jint destLeft, jint destTop, jint destRight, jint destBottom,
- jlong matrixPtr, jint renderMode) {
-
+ jobject jbitmap, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom,
+ jlong transformPtr, jint renderMode) {
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
- SkMatrix* skMatrix = reinterpret_cast<SkMatrix*>(matrixPtr);
SkBitmap skBitmap;
GraphicsJNI::getSkBitmap(env, jbitmap, &skBitmap);
@@ -187,27 +89,49 @@
FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(),
FPDFBitmap_BGRA, skBitmap.getPixels(), stride);
-
- if (!bitmap) {
- ALOGE("Erorr creating bitmap");
+ bool isExceptionPending = forwardPdfiumError(env);
+ if (isExceptionPending || bitmap == NULL) {
+ ALOGE("Error creating bitmap");
return;
}
- int renderFlags = 0;
+ int renderFlags = FPDF_REVERSE_BYTE_ORDER;
if (renderMode == RENDER_MODE_FOR_DISPLAY) {
renderFlags |= FPDF_LCD_TEXT;
} else if (renderMode == RENDER_MODE_FOR_PRINT) {
renderFlags |= FPDF_PRINTING;
}
- if (skMatrix && !skMatrix->asAffine(NULL)) {
+ // PDF's coordinate system origin is left-bottom while in graphics it
+ // is the top-left. So, translate the PDF coordinates to ours.
+ SkMatrix reflectOnX = SkMatrix::MakeScale(1, -1);
+ SkMatrix moveUp = SkMatrix::MakeTrans(0, FPDF_GetPageHeight(page));
+ SkMatrix coordinateChange = SkMatrix::Concat(moveUp, reflectOnX);
+
+ // Apply the transformation
+ SkMatrix matrix;
+ if (transformPtr == 0) {
+ matrix = coordinateChange;
+ } else {
+ matrix = SkMatrix::Concat(*reinterpret_cast<SkMatrix*>(transformPtr), coordinateChange);
+ }
+
+ SkScalar transformValues[6];
+ if (!matrix.asAffine(transformValues)) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"transform matrix has perspective. Only affine matrices are allowed.");
return;
}
- renderPageBitmap(bitmap, page, destLeft, destTop, destRight,
- destBottom, skMatrix, renderFlags);
+ FS_MATRIX transform = {transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
+ transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
+ transformValues[SkMatrix::kATransX],
+ transformValues[SkMatrix::kATransY]};
+
+ FS_RECTF clip = {(float) clipLeft, (float) clipTop, (float) clipRight, (float) clipBottom};
+
+ FPDF_RenderPageBitmapWithMatrix(bitmap, page, &transform, &clip, renderFlags);
+ HANDLE_PDFIUM_ERROR_STATE(env);
skBitmap.notifyPixelsChanged();
}
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 99a0422..7b7a290 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -411,7 +411,18 @@
final int contentBottom = (destClip != null) ? destClip.bottom
: destination.getHeight();
- final long transformPtr = (transform != null) ? transform.native_instance : 0;
+ // If transform is not set, stretch page to whole clipped area
+ if (transform == null) {
+ int clipWidth = contentRight - contentLeft;
+ int clipHeight = contentBottom - contentTop;
+
+ transform = new Matrix();
+ transform.postScale((float)clipWidth / getWidth(),
+ (float)clipHeight / getHeight());
+ transform.postTranslate(contentLeft, contentTop);
+ }
+
+ final long transformPtr = transform.native_instance;
synchronized (sPdfiumLock) {
nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
@@ -463,7 +474,8 @@
private static native int nativeGetPageCount(long documentPtr);
private static native boolean nativeScaleForPrinting(long documentPtr);
private static native void nativeRenderPage(long documentPtr, long pagePtr, Bitmap dest,
- int destLeft, int destTop, int destRight, int destBottom, long matrixPtr, int renderMode);
+ int clipLeft, int clipTop, int clipRight, int clipBottom, long transformPtr,
+ int renderMode);
private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex,
Point outSize);
private static native void nativeClosePage(long pagePtr);