Use only official pdfium APIs
Fixes: 28051413 Test: cts-tradefed run cts-dev -m CtsGraphicsTestCases -t android.graphics.pdf.cts cts-tradefed run cts-dev -m Print -t android.print.pdf.cts Change-Id: Iab52463ba225d3cddb1e97fe52cb9f56318cce68
This commit is contained in:
@ -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 \
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user