| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "PdfUtils.h" |
| |
| #include "GraphicsJNI.h" |
| #include "SkBitmap.h" |
| #include "SkMatrix.h" |
| #include "fpdfview.h" |
| |
| #include <vector> |
| #include <utils/Log.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| |
| namespace android { |
| |
| static const int RENDER_MODE_FOR_DISPLAY = 1; |
| static const int RENDER_MODE_FOR_PRINT = 2; |
| |
| static struct { |
| jfieldID x; |
| jfieldID y; |
| } gPointClassInfo; |
| |
| static jlong nativeOpenPageAndGetSize(JNIEnv* env, jclass thiz, jlong documentPtr, |
| jint pageIndex, jobject outSize) { |
| FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); |
| |
| FPDF_PAGE page = FPDF_LoadPage(document, pageIndex); |
| if (!page) { |
| jniThrowException(env, "java/lang/IllegalStateException", |
| "cannot load page"); |
| return -1; |
| } |
| |
| double width = 0; |
| double height = 0; |
| |
| int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height); |
| if (!result) { |
| jniThrowException(env, "java/lang/IllegalStateException", |
| "cannot get page size"); |
| return -1; |
| } |
| |
| env->SetIntField(outSize, gPointClassInfo.x, width); |
| env->SetIntField(outSize, gPointClassInfo.y, height); |
| |
| return reinterpret_cast<jlong>(page); |
| } |
| |
| static void nativeClosePage(JNIEnv* env, jclass thiz, jlong pagePtr) { |
| FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr); |
| FPDF_ClosePage(page); |
| } |
| |
| static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr, |
| jlong bitmapPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom, |
| jlong transformPtr, jint renderMode) { |
| FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr); |
| |
| SkBitmap skBitmap; |
| bitmap::toBitmap(bitmapPtr).getSkBitmap(&skBitmap); |
| |
| const int stride = skBitmap.width() * 4; |
| |
| FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(), |
| FPDFBitmap_BGRA, skBitmap.getPixels(), stride); |
| |
| 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; |
| } |
| |
| SkMatrix matrix = *reinterpret_cast<SkMatrix*>(transformPtr); |
| SkScalar transformValues[6]; |
| if (!matrix.asAffine(transformValues)) { |
| jniThrowException(env, "java/lang/IllegalArgumentException", |
| "transform matrix has perspective. Only affine matrices are allowed."); |
| return; |
| } |
| |
| 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); |
| |
| skBitmap.notifyPixelsChanged(); |
| } |
| |
| static const JNINativeMethod gPdfRenderer_Methods[] = { |
| {"nativeCreate", "(IJ)J", (void*) nativeOpen}, |
| {"nativeClose", "(J)V", (void*) nativeClose}, |
| {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount}, |
| {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting}, |
| {"nativeRenderPage", "(JJJIIIIJI)V", (void*) nativeRenderPage}, |
| {"nativeOpenPageAndGetSize", "(JILandroid/graphics/Point;)J", (void*) nativeOpenPageAndGetSize}, |
| {"nativeClosePage", "(J)V", (void*) nativeClosePage} |
| }; |
| |
| int register_android_graphics_pdf_PdfRenderer(JNIEnv* env) { |
| int result = RegisterMethodsOrDie( |
| env, "android/graphics/pdf/PdfRenderer", gPdfRenderer_Methods, |
| NELEM(gPdfRenderer_Methods)); |
| |
| jclass clazz = FindClassOrDie(env, "android/graphics/Point"); |
| gPointClassInfo.x = GetFieldIDOrDie(env, clazz, "x", "I"); |
| gPointClassInfo.y = GetFieldIDOrDie(env, clazz, "y", "I"); |
| |
| return result; |
| }; |
| |
| }; |