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);