Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. #include <jni.h>
  2. #include <time.h>
  3. #include <android/log.h>
  4. #include <android/bitmap.h>
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9.  
  10. #include "fitz.h"
  11. #include "mupdf.h"
  12.  
  13. #define LOG_TAG "libmupdf"
  14. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
  15. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
  16.  
  17. /* Set to 1 to enable debug log traces. */
  18. #define DEBUG 0
  19.  
  20. /* Globals */
  21. fz_colorspace *colorspace;
  22. fz_glyph_cache *glyphcache;
  23. pdf_xref *xref;
  24. int pagenum = 1;
  25. int resolution = 160;
  26. float pageWidth = 100;
  27. float pageHeight = 100;
  28. fz_display_list *currentPageList;
  29. fz_rect currentMediabox;
  30. int currentRotate;
  31.  
  32. JNIEXPORT int JNICALL
  33. Java_com_artifex_mupdf_MuPDFCore_openFile(JNIEnv * env, jobject thiz, jstring jfilename)
  34. {
  35.         const char *filename;
  36.         char *password = "";
  37.         int accelerate = 1;
  38.         fz_error error;
  39.         int pages;
  40.  
  41.         filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  42.         if (filename == NULL)
  43.         {
  44.                 LOGE("Failed to get filename");
  45.                 return 0;
  46.         }
  47.  
  48.         if (accelerate)
  49.                 fz_accelerate();
  50.         glyphcache = fz_new_glyph_cache();
  51.         colorspace = fz_device_rgb;
  52.  
  53.         LOGE("Opening document...");
  54.         error = pdf_open_xref(&xref, filename, password);
  55.         if (error)
  56.         {
  57.                 LOGE("Cannot open document: '%s'\n", filename);
  58.                 return 0;
  59.         }
  60.  
  61.         LOGE("Loading page tree...");
  62.         error = pdf_load_page_tree(xref);
  63.         if (error)
  64.         {
  65.                 LOGE("Cannot load page tree: '%s'\n", filename);
  66.                 return 0;
  67.         }
  68.         pages = pdf_count_pages(xref);
  69.         LOGE("Done! %d pages", pages);
  70.  
  71.         return pages;
  72. }
  73.  
  74. JNIEXPORT void JNICALL
  75. Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal(JNIEnv *env, jobject thiz, int page)
  76. {
  77.         float zoom;
  78.         fz_matrix ctm;
  79.         fz_bbox bbox;
  80.         fz_error error;
  81.         fz_device *dev;
  82.         pdf_page *currentPage;
  83.  
  84.         /* In the event of an error, ensure we give a non-empty page */
  85.         pageWidth = 100;
  86.         pageHeight = 100;
  87.  
  88.         LOGE("Goto page %d...", page);
  89.         if (currentPageList != NULL)
  90.         {
  91.                 fz_free_display_list(currentPageList);
  92.                 currentPageList = NULL;
  93.         }
  94.         pagenum = page;
  95.         error = pdf_load_page(&currentPage, xref, pagenum);
  96.         if (error)
  97.                 return;
  98.         zoom = resolution / 72;
  99.         currentMediabox = currentPage->mediabox;
  100.         currentRotate = currentPage->rotate;
  101.         ctm = fz_translate(0, -currentMediabox.y1);
  102.         ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
  103.         ctm = fz_concat(ctm, fz_rotate(currentRotate));
  104.         bbox = fz_round_rect(fz_transform_rect(ctm, currentMediabox));
  105.         pageWidth = bbox.x1-bbox.x0;
  106.         pageHeight = bbox.y1-bbox.y0;
  107.         /* Render to list */
  108.         currentPageList = fz_new_display_list();
  109.         dev = fz_new_list_device(currentPageList);
  110.         error = pdf_run_page(xref, currentPage, dev, fz_identity);
  111.         pdf_free_page(currentPage);
  112.         if (error)
  113.                 LOGE("cannot make displaylist from page %d", pagenum);
  114.         fz_free_device(dev);
  115. }
  116.  
  117. JNIEXPORT float JNICALL
  118. Java_com_artifex_mupdf_MuPDFCore_getPageWidth(JNIEnv *env, jobject thiz)
  119. {
  120.         LOGE("PageWidth=%g", pageWidth);
  121.         return pageWidth;
  122. }
  123.  
  124. JNIEXPORT float JNICALL
  125. Java_com_artifex_mupdf_MuPDFCore_getPageHeight(JNIEnv *env, jobject thiz)
  126. {
  127.         LOGE("PageHeight=%g", pageHeight);
  128.         return pageHeight;
  129. }
  130.  
  131. JNIEXPORT jboolean JNICALL
  132. Java_com_artifex_mupdf_MuPDFCore_drawPage(JNIEnv *env, jobject thiz, jobject bitmap,
  133.                 int pageW, int pageH, int patchX, int patchY, int patchW, int patchH)
  134. {
  135.         AndroidBitmapInfo info;
  136.         void *pixels;
  137.         int ret;
  138.         fz_error error;
  139.         fz_device *dev;
  140.         float zoom;
  141.         fz_matrix ctm;
  142.         fz_bbox bbox;
  143.         fz_pixmap *pix;
  144.         float xscale, yscale;
  145.         fz_bbox rect;
  146.  
  147.         LOGI("In native method\n");
  148.         if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
  149.                 LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
  150.                 return 0;
  151.         }
  152.  
  153.         LOGI("Checking format\n");
  154.         if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
  155.                 LOGE("Bitmap format is not RGBA_8888 !");
  156.                 return 0;
  157.         }
  158.  
  159.         LOGI("locking pixels\n");
  160.         if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
  161.                 LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
  162.                 return 0;
  163.         }
  164.  
  165.         /* Call mupdf to render display list to screen */
  166.         LOGE("Rendering page=%dx%d patch=[%d,%d,%d,%d]",
  167.                         pageW, pageH, patchX, patchY, patchW, patchH);
  168.  
  169.         rect.x0 = patchX;
  170.         rect.y0 = patchY;
  171.         rect.x1 = patchX + patchW;
  172.         rect.y1 = patchY + patchH;
  173.         pix = fz_new_pixmap_with_rect_and_data(colorspace, rect, pixels);
  174.         if (currentPageList == NULL)
  175.         {
  176.                 fz_clear_pixmap_with_color(pix, 0xd0);
  177.                 return 0;
  178.         }
  179.         fz_clear_pixmap_with_color(pix, 0xff);
  180.  
  181.         zoom = resolution / 72;
  182.         ctm = fz_translate(-currentMediabox.x0, -currentMediabox.y1);
  183.         ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
  184.         ctm = fz_concat(ctm, fz_rotate(currentRotate));
  185.         bbox = fz_round_rect(fz_transform_rect(ctm,currentMediabox));
  186.         /* Now, adjust ctm so that it would give the correct page width
  187.          * heights. */
  188.         xscale = (float)pageW/(float)(bbox.x1-bbox.x0);
  189.         yscale = (float)pageH/(float)(bbox.y1-bbox.y0);
  190.         ctm = fz_concat(ctm, fz_scale(xscale, yscale));
  191.         bbox = fz_round_rect(fz_transform_rect(ctm,currentMediabox));
  192.         dev = fz_new_draw_device(glyphcache, pix);
  193.         fz_execute_display_list(currentPageList, dev, ctm, bbox);
  194.         fz_free_device(dev);
  195.         fz_drop_pixmap(pix);
  196.         LOGE("Rendered");
  197.  
  198.         AndroidBitmap_unlockPixels(env, bitmap);
  199.  
  200.         return 1;
  201. }
  202.  
  203. JNIEXPORT void JNICALL
  204. Java_com_artifex_mupdf_MuPDFCore_destroying(JNIEnv * env, jobject thiz)
  205. {
  206.         fz_free_display_list(currentPageList);
  207.         currentPageList = NULL;
  208.         pdf_free_xref(xref);
  209.         xref = NULL;
  210.         fz_free_glyph_cache(glyphcache);
  211.         glyphcache = NULL;
  212. }
  213.