Loading core/jni/Android.mk +0 −3 Original line number Diff line number Diff line Loading @@ -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 \ Loading core/jni/android/graphics/pdf/PdfRenderer.cpp +31 −107 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); Loading @@ -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(); } Loading graphics/java/android/graphics/pdf/PdfRenderer.java +14 −2 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading Loading
core/jni/Android.mk +0 −3 Original line number Diff line number Diff line Loading @@ -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 \ Loading
core/jni/android/graphics/pdf/PdfRenderer.cpp +31 −107 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); Loading @@ -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(); } Loading
graphics/java/android/graphics/pdf/PdfRenderer.java +14 −2 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading