Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a4486e1 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by Android (Google) Code Review
Browse files

Merge "Use only official pdfium APIs"

parents b251fad0 d55f20d3
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -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 \
+31 −107
Original line number Diff line number Diff line
@@ -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();
}
+14 −2
Original line number Diff line number Diff line
@@ -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);