diff options
| -rw-r--r-- | core/jni/Android.mk | 3 | ||||
| -rw-r--r-- | core/jni/android/graphics/pdf/PdfRenderer.cpp | 138 | ||||
| -rw-r--r-- | graphics/java/android/graphics/pdf/PdfRenderer.java | 16 |
3 files changed, 45 insertions, 112 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk index af5fca2c0e42..2f9226f2375a 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -210,10 +210,7 @@ LOCAL_C_INCLUDES += \ $(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 6e7b6b8369d6..1001c05a891c 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 @@ static void nativeClosePage(JNIEnv* env, jclass thiz, jlong pagePtr) { 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 @@ static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong 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 99a042261c4d..7b7a2909b36d 100644 --- a/graphics/java/android/graphics/pdf/PdfRenderer.java +++ b/graphics/java/android/graphics/pdf/PdfRenderer.java @@ -411,7 +411,18 @@ public final class PdfRenderer implements AutoCloseable { 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 @@ public final class PdfRenderer implements AutoCloseable { 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); |