PdfRenderer.cpp revision 525a66b2bb5abf844aff2109bdc9ed819566bece
115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/*
215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2014 The Android Open Source Project
315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License.
615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at
715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software
1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and
1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License.
1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */
1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
1907330791116513710d879c45b2f095cd314cbfd0Jeff Brown#include "GraphicsJNI.h"
2007330791116513710d879c45b2f095cd314cbfd0Jeff Brown#include "SkBitmap.h"
2107330791116513710d879c45b2f095cd314cbfd0Jeff Brown#include "SkMatrix.h"
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "fpdfview.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "fsdk_rendercontext.h"
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
268a4c9721a9e09d20c63381c13fa29bd9f7cbc3e3Jeff Sharkey#include <vector>
278a4c9721a9e09d20c63381c13fa29bd9f7cbc3e3Jeff Sharkey#include <utils/Log.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
298a4c9721a9e09d20c63381c13fa29bd9f7cbc3e3Jeff Sharkey#include <sys/types.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
318a4c9721a9e09d20c63381c13fa29bd9f7cbc3e3Jeff Sharkey
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const int RENDER_MODE_FOR_DISPLAY = 1;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const int RENDER_MODE_FOR_PRINT = 2;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID x;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID y;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gPointClassInfo;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic Mutex sLock;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int sUnmatchedInitRequestCount = 0;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void initializeLibraryIfNeeded() {
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Mutex::Autolock _l(sLock);
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sUnmatchedInitRequestCount == 0) {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FPDF_InitLibrary(NULL);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sUnmatchedInitRequestCount++;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void destroyLibraryIfNeeded() {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Mutex::Autolock _l(sLock);
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sUnmatchedInitRequestCount--;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sUnmatchedInitRequestCount == 0) {
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       FPDF_DestroyLibrary();
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int getBlock(void* param, unsigned long position, unsigned char* outBuffer,
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unsigned long size) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int fd = reinterpret_cast<intptr_t>(param);
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int readCount = pread(fd, outBuffer, size, position);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (readCount < 0) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGE("Cannot read from file descriptor. Error:%d", errno);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 1;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong nativeCreate(JNIEnv* env, jclass thiz, jint fd, jlong size) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    initializeLibraryIfNeeded();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FPDF_FILEACCESS loader;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    loader.m_FileLen = size;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    loader.m_Param = reinterpret_cast<void*>(intptr_t(fd));
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    loader.m_GetBlock = &getBlock;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FPDF_DOCUMENT document = FPDF_LoadCustomDocument(&loader, NULL);
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!document) {
84181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate        const long error = FPDF_GetLastError();
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/io/IOException",
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "cannot create document. Error:" + error);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        destroyLibraryIfNeeded();
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
89181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate    }
90181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate
91181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate    return reinterpret_cast<jlong>(document);
92181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate}
93181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate
94181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tatestatic jlong nativeOpenPageAndGetSize(JNIEnv* env, jclass thiz, jlong documentPtr,
95181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate        jint pageIndex, jobject outSize) {
964a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
98269248d112e35fe8e9f0d5d11c96dcb2ac1118b0Adam Powell    FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
99269248d112e35fe8e9f0d5d11c96dcb2ac1118b0Adam Powell
100269248d112e35fe8e9f0d5d11c96dcb2ac1118b0Adam Powell    if (!page) {
101269248d112e35fe8e9f0d5d11c96dcb2ac1118b0Adam Powell        jniThrowException(env, "java/lang/IllegalStateException",
102269248d112e35fe8e9f0d5d11c96dcb2ac1118b0Adam Powell                "cannot load page");
103269248d112e35fe8e9f0d5d11c96dcb2ac1118b0Adam Powell        return -1;
104269248d112e35fe8e9f0d5d11c96dcb2ac1118b0Adam Powell    }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    double width = 0;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    double height = 0;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!result) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException",
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "cannot get page size");
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(outSize, gPointClassInfo.x, width);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(outSize, gPointClassInfo.y, height);
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return reinterpret_cast<jlong>(page);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void nativeClosePage(JNIEnv* env, jclass thiz, jlong pagePtr) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FPDF_ClosePage(page);
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void nativeClose(JNIEnv* env, jclass thiz, jlong documentPtr) {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FPDF_CloseDocument(document);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    destroyLibraryIfNeeded();
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint nativeGetPageCount(JNIEnv* env, jclass thiz, jlong documentPtr) {
135181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return FPDF_GetPageCount(document);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean nativeScaleForPrinting(JNIEnv* env, jclass thiz, jlong documentPtr) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return FPDF_VIEWERREF_GetPrintScaling(document);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DropContext(void* data) {
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    delete (CRenderContext*) data;
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void renderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page, int destLeft, int destTop,
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int destRight, int destBottom, SkMatrix* transform, int flags) {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Note: this code ignores the currently unused RENDER_NO_NATIVETEXT,
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // FPDF_RENDER_LIMITEDIMAGECACHE, FPDF_RENDER_FORCEHALFTONE, FPDF_GRAYSCALE,
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // and FPDF_ANNOT flags. To add support for that refer to FPDF_RenderPage_Retail
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // in fpdfview.cpp
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CRenderContext* pContext = FX_NEW CRenderContext;
156851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn
157851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn    CPDF_Page* pPage = (CPDF_Page*) page;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pPage->SetPrivateData((void*) 1, pContext, DropContext);
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
160851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn    CFX_FxgeDevice* fxgeDevice = FX_NEW CFX_FxgeDevice;
161851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn    pContext->m_pDevice = fxgeDevice;
1627f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn
1637f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn    // Reverse the bytes (last argument TRUE) since the Android
1647f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn    // format is ARGB while the renderer uses BGRA internally.
165851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn    fxgeDevice->Attach((CFX_DIBitmap*) bitmap, 0, TRUE);
166a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn
167ade3ecad94d1f4431576f53bae26c35efbf7a2c9Dianne Hackborn    CPDF_RenderOptions* renderOptions = pContext->m_pOptions;
168ade3ecad94d1f4431576f53bae26c35efbf7a2c9Dianne Hackborn
1695c1e00b14d2ef10ec76abf3e951fa8003a67f558Dianne Hackborn    if (!renderOptions) {
170723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn        renderOptions = FX_NEW CPDF_RenderOptions;
171723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn        pContext->m_pOptions = renderOptions;
172723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    }
1735c1e00b14d2ef10ec76abf3e951fa8003a67f558Dianne Hackborn
174723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    if (flags & FPDF_LCD_TEXT) {
175723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn        renderOptions->m_Flags |= RENDER_CLEARTYPE;
176723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    } else {
177723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn        renderOptions->m_Flags &= ~RENDER_CLEARTYPE;
178723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    }
179723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn
180723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    const CPDF_OCContext::UsageType usage = (flags & FPDF_PRINTING)
181723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn            ? CPDF_OCContext::Print : CPDF_OCContext::View;
182723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn
183723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    renderOptions->m_AddFlags = flags >> 8;
184723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    renderOptions->m_pOCContext = new CPDF_OCContext(pPage->m_pDocument, usage);
185723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn
186723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    fxgeDevice->SaveState();
187723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn
18822ec9ab3b881d71866279ba9363c644a9e4e7164Dianne Hackborn    FX_RECT clip;
189723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    clip.left = destLeft;
190723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn    clip.right = destRight;
1915c1e00b14d2ef10ec76abf3e951fa8003a67f558Dianne Hackborn    clip.top = destTop;
1925c1e00b14d2ef10ec76abf3e951fa8003a67f558Dianne Hackborn    clip.bottom = destBottom;
193c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn    fxgeDevice->SetClip_Rect(&clip);
194c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn
195c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn    CPDF_RenderContext* pageContext = FX_NEW CPDF_RenderContext;
196c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn    pContext->m_pContext = pageContext;
197c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn    pageContext->Create(pPage);
198c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn
199c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn    CFX_AffineMatrix matrix;
200c4db95c077f826585d20be2f3db4043c53d30cf5Dianne Hackborn    if (!transform) {
20111b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn        pPage->GetDisplayMatrix(matrix, destLeft, destTop, destRight - destLeft,
20211b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn                destBottom - destTop, 0);
20311b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn    } else {
20411b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn        // PDF's coordinate system origin is left-bottom while
20511b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn        // in graphics it is the top-left, so remap the origin.
20611b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn        matrix.Set(1, 0, 0, -1, 0, pPage->GetPageHeight());
20711b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn
20811b822d2a91ea17c34c0cb1c11e80a9a30d72864Dianne Hackborn        SkScalar transformValues[6];
20923085b781e145ed684e7270af1d5ced6800b8effBen Cheng        transform->asAffine(transformValues);
21023085b781e145ed684e7270af1d5ced6800b8effBen Cheng
211ef3f5ddc2137ed99e41f00441b688fb56b855179Ben Cheng        matrix.Concat(transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
212ef3f5ddc2137ed99e41f00441b688fb56b855179Ben Cheng                transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
21323085b781e145ed684e7270af1d5ced6800b8effBen Cheng                transformValues[SkMatrix::kATransX], transformValues[SkMatrix::kATransY]);
21423085b781e145ed684e7270af1d5ced6800b8effBen Cheng    }
21523085b781e145ed684e7270af1d5ced6800b8effBen Cheng    pageContext->AppendObjectList(pPage, &matrix);
21623085b781e145ed684e7270af1d5ced6800b8effBen Cheng
2173de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    pContext->m_pRenderer = FX_NEW CPDF_ProgressiveRenderer;
2183de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    pContext->m_pRenderer->Start(pageContext, fxgeDevice, renderOptions, NULL);
219181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate
2203de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    fxgeDevice->RestoreState();
2213de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate
2223de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    pPage->RemovePrivateData((void*) 1);
223181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate
22423085b781e145ed684e7270af1d5ced6800b8effBen Cheng    delete pContext;
2255e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate}
2265e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate
2273de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tatestatic void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr,
2283de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate        jlong bitmapPtr, jint destLeft, jint destTop, jint destRight, jint destBottom,
2293de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate        jlong matrixPtr, jint renderMode) {
2303de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate
2313de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
2325e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate    FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
2333de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    SkBitmap* skBitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
2343de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    SkMatrix* skMatrix = reinterpret_cast<SkMatrix*>(matrixPtr);
2353de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate
2363de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    skBitmap->lockPixels();
2375e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate
2385e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate    const int stride = skBitmap->width() * 4;
2393de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate
2403de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap->width(), skBitmap->height(),
2413de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate            FPDFBitmap_BGRA, skBitmap->getPixels(), stride);
2425e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate
24323085b781e145ed684e7270af1d5ced6800b8effBen Cheng    if (!bitmap) {
2445e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate        ALOGE("Erorr creating bitmap");
2455e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate        return;
2463de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    }
2473de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate
2483de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    int renderFlags = 0;
2493de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    if (renderMode == RENDER_MODE_FOR_DISPLAY) {
2503de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate        renderFlags |= FPDF_LCD_TEXT;
2513de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    } else if (renderMode == RENDER_MODE_FOR_PRINT) {
2525e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate        renderFlags |= FPDF_PRINTING;
2533de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    }
2543de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate
2553de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    renderPageBitmap(bitmap, page, destLeft, destTop, destRight,
2563de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate            destBottom, skMatrix, renderFlags);
2575e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate
2585e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate    skBitmap->notifyPixelsChanged();
2593de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    skBitmap->unlockPixels();
2603de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate}
2613de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate
2625e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tatestatic JNINativeMethod gPdfRenderer_Methods[] = {
2633de55bcd34afd5871816526294f9514d1adf3fe5Christopher Tate    {"nativeCreate", "(IJ)J", (void*) nativeCreate},
2645e1ab335e6e8fbfa19c64d53880a22f472010953Christopher Tate    {"nativeClose", "(J)V", (void*) nativeClose},
265181fafaf48208978b8ba2022683ffa78aaeddde1Christopher Tate    {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
2663202d380226043fa665df3c92252f791f8c52d55Dianne Hackborn    {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting},
2673202d380226043fa665df3c92252f791f8c52d55Dianne Hackborn    {"nativeRenderPage", "(JJJIIIIJI)V", (void*) nativeRenderPage},
2683202d380226043fa665df3c92252f791f8c52d55Dianne Hackborn    {"nativeOpenPageAndGetSize", "(JILandroid/graphics/Point;)J", (void*) nativeOpenPageAndGetSize},
2693202d380226043fa665df3c92252f791f8c52d55Dianne Hackborn    {"nativeClosePage", "(J)V", (void*) nativeClosePage}
2703202d380226043fa665df3c92252f791f8c52d55Dianne Hackborn};
2713202d380226043fa665df3c92252f791f8c52d55Dianne Hackborn
272af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapuint register_android_graphics_pdf_PdfRenderer(JNIEnv* env) {
27394c567e1e344d49168603f5a0560215a4ce735e6Dianne Hackborn    int result = android::AndroidRuntime::registerNativeMethods(
274af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu            env, "android/graphics/pdf/PdfRenderer", gPdfRenderer_Methods,
275af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu            NELEM(gPdfRenderer_Methods));
27614cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn
27714cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn    jclass clazz = env->FindClass("android/graphics/Point");
27814cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn    gPointClassInfo.x = env->GetFieldID(clazz, "x", "I");
27922ec9ab3b881d71866279ba9363c644a9e4e7164Dianne Hackborn    gPointClassInfo.y = env->GetFieldID(clazz, "y", "I");
28014cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn
28114cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn    return result;
28214cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn};
28314cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn
2843b81bc18bb661c02ad8074c39dab16644c1e65d0Dianne Hackborn};
2853b81bc18bb661c02ad8074c39dab16644c1e65d0Dianne Hackborn