diff options
-rw-r--r-- | android/jni/mupdf.c | 174 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/MuPDFActivity.java | 55 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/PixmapView.java | 109 |
3 files changed, 174 insertions, 164 deletions
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c index ea11be2d..530f7e54 100644 --- a/android/jni/mupdf.c +++ b/android/jni/mupdf.c @@ -18,16 +18,18 @@ #define DEBUG 0 /* Globals */ -fz_colorspace *colorspace; -fz_glyphcache *glyphcache; -pdf_xref *xref; -int pagenum = 1; -int resolution = 160; -pdf_page *currentPage; -float pageWidth = 100; -float pageHeight = 100; - -JNIEXPORT int JNICALL Java_com_artifex_mupdf_PixmapView_mupdfOpenFile(JNIEnv * env, jobject thiz, jstring jfilename) +fz_colorspace *colorspace; +fz_glyphcache *glyphcache; +pdf_xref *xref; +int pagenum = 1; +int resolution = 160; +float pageWidth = 100; +float pageHeight = 100; +fz_displaylist *currentPageList; +fz_rect currentMediabox; +int currentRotate; + +JNIEXPORT int JNICALL Java_com_artifex_mupdf_MuPDFCore_openFile(JNIEnv * env, jobject thiz, jstring jfilename) { const char *filename; char *password = ""; @@ -66,7 +68,7 @@ JNIEXPORT int JNICALL Java_com_artifex_mupdf_PixmapView_mupdfOpenFile(JNIEnv * e return pdf_getpagecount(xref); } -JNIEXPORT void JNICALL Java_com_artifex_mupdf_PixmapView_mupdfGotoPage( +JNIEXPORT void JNICALL Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal( JNIEnv *env, jobject thiz, int page) @@ -76,19 +78,19 @@ JNIEXPORT void JNICALL Java_com_artifex_mupdf_PixmapView_mupdfGotoPage( fz_obj *pageobj; fz_bbox bbox; fz_error error; + fz_device *dev; + pdf_page *currentPage; /* In the event of an error, ensure we give a non-empty page */ pageWidth = 100; pageHeight = 100; - /* Free any current page */ - if (currentPage != NULL) + LOGE("Goto page %d...", page); + if (currentPageList != NULL) { - pdf_freepage(currentPage); - currentPage = NULL; + fz_freedisplaylist(currentPageList); + currentPageList = NULL; } - - LOGE("Goto page %d...", page); pagenum = page; pageobj = pdf_getpageobject(xref, pagenum); if (pageobj == NULL) @@ -97,16 +99,25 @@ JNIEXPORT void JNICALL Java_com_artifex_mupdf_PixmapView_mupdfGotoPage( if (error) return; zoom = resolution / 72; - ctm = fz_translate(0, -currentPage->mediabox.y1); + currentMediabox = currentPage->mediabox; + currentRotate = currentPage->rotate; + ctm = fz_translate(0, -currentMediabox.y1); ctm = fz_concat(ctm, fz_scale(zoom, -zoom)); - ctm = fz_concat(ctm, fz_rotate(currentPage->rotate)); - bbox = fz_roundrect(fz_transformrect(ctm, currentPage->mediabox)); + ctm = fz_concat(ctm, fz_rotate(currentRotate)); + bbox = fz_roundrect(fz_transformrect(ctm, currentMediabox)); pageWidth = bbox.x1-bbox.x0; pageHeight = bbox.y1-bbox.y0; - LOGE("Success [w=%g, h=%g]", pageWidth, pageHeight); + /* Render to list */ + currentPageList = fz_newdisplaylist(); + dev = fz_newlistdevice(currentPageList); + error = pdf_runpage(xref, currentPage, dev, fz_identity); + pdf_freepage(currentPage); + if (error) + LOGE("cannot make displaylist from page %d", pagenum); + fz_freedevice(dev); } -JNIEXPORT float JNICALL Java_com_artifex_mupdf_PixmapView_mupdfPageWidth( +JNIEXPORT float JNICALL Java_com_artifex_mupdf_MuPDFCore_getPageWidth( JNIEnv *env, jobject thiz) { @@ -114,7 +125,7 @@ JNIEXPORT float JNICALL Java_com_artifex_mupdf_PixmapView_mupdfPageWidth( return pageWidth; } -JNIEXPORT float JNICALL Java_com_artifex_mupdf_PixmapView_mupdfPageHeight( +JNIEXPORT float JNICALL Java_com_artifex_mupdf_MuPDFCore_getPageHeight( JNIEnv *env, jobject thiz) { @@ -123,7 +134,7 @@ JNIEXPORT float JNICALL Java_com_artifex_mupdf_PixmapView_mupdfPageHeight( } -JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_PixmapView_mupdfDrawPage( +JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_MuPDFCore_drawPage( JNIEnv *env, jobject thiz, jobject bitmap, @@ -135,8 +146,15 @@ JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_PixmapView_mupdfDrawPage( int patchH) { AndroidBitmapInfo info; - void* pixels; - int ret, i, c; + void *pixels; + int ret; + fz_error error; + fz_device *dev; + float zoom; + fz_matrix ctm; + fz_bbox bbox; + fz_pixmap *pix; + float xscale, yscale; LOGI("In native method\n"); if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) { @@ -156,84 +174,40 @@ JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_PixmapView_mupdfDrawPage( return 0; } - LOGI("render page\n"); - /* Call mupdf to render page */ + /* Call mupdf to render display list to screen */ + LOGE("Rendering page=%dx%d patch=[%d,%d,%d,%d]", + pageW, pageH, patchX, patchY, patchW, patchH); + + pix = fz_newpixmapwithdata(colorspace, + patchX, + patchY, + patchW, + patchH, + pixels); + if (currentPageList == NULL) { - fz_error error; - fz_displaylist *list; - fz_device *dev; - - /* Render to list */ - LOGI("make list\n"); - list = fz_newdisplaylist(); - LOGI("make device\n"); - dev = fz_newlistdevice(list); - LOGI("render to device\n"); - error = pdf_runpage(xref, currentPage, dev, fz_identity); - if (error) - { - LOGE("cannot draw page %d", pagenum); - return 0; - } - LOGI("free device\n"); - fz_freedevice(dev); - - /* Render to screen */ - LOGE("Rendering page=%dx%d patch=[%d,%d,%d,%d]", - pageW, pageH, patchX, patchY, patchW, patchH); - { - float zoom; - fz_matrix ctm; - fz_bbox bbox; - fz_pixmap *pix; - float xscale, yscale; - - zoom = resolution / 72; - ctm = fz_translate(0, -currentPage->mediabox.y1); - ctm = fz_concat(ctm, fz_scale(zoom, -zoom)); - ctm = fz_concat(ctm, fz_rotate(currentPage->rotate)); - bbox = fz_roundrect(fz_transformrect(ctm,currentPage->mediabox)); - - LOGE("mediabox=%g %g %g %g zoom=%g rotate=%d", - currentPage->mediabox.x0, - currentPage->mediabox.y0, - currentPage->mediabox.x1, - currentPage->mediabox.y1, - zoom, - currentPage->rotate); - LOGE("ctm = [%g %g %g %g %g %g] to [%d %d %d %d]", ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f, bbox.x0, bbox.y0, bbox.x1, bbox.y1); - /* Now, adjust ctm so that it would give the correct page width - * heights. */ - xscale = (float)pageW/(float)(bbox.x1-bbox.x0); - yscale = (float)pageH/(float)(bbox.y1-bbox.y0); - ctm = fz_concat(ctm, fz_scale(xscale, yscale)); - bbox = fz_roundrect(fz_transformrect(ctm,currentPage->mediabox)); - LOGE("ctm = [%g %g %g %g %g %g] to [%d %d %d %d]", ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f, bbox.x0, bbox.y0, bbox.x1, bbox.y1); - - pix = fz_newpixmapwithdata(colorspace, - patchX, - patchY, - patchW, - patchH, - pixels); - LOGE("Clearing"); - fz_clearpixmapwithcolor(pix, 0xff); - LOGE("Cleared"); - dev = fz_newdrawdevice(glyphcache, pix); - fz_executedisplaylist(list, dev, ctm); - fz_freedevice(dev); - fz_droppixmap(pix); - } - LOGE("Rendered"); - fz_freedisplaylist(list); + fz_clearpixmapwithcolor(pix, 0xd0); + return 0; } + fz_clearpixmapwithcolor(pix, 0xff); + + zoom = resolution / 72; + ctm = fz_translate(0, -currentMediabox.y1); + ctm = fz_concat(ctm, fz_scale(zoom, -zoom)); + ctm = fz_concat(ctm, fz_rotate(currentRotate)); + bbox = fz_roundrect(fz_transformrect(ctm,currentMediabox)); + /* Now, adjust ctm so that it would give the correct page width + * heights. */ + xscale = (float)pageW/(float)(bbox.x1-bbox.x0); + yscale = (float)pageH/(float)(bbox.y1-bbox.y0); + ctm = fz_concat(ctm, fz_scale(xscale, yscale)); + dev = fz_newdrawdevice(glyphcache, pix); + fz_executedisplaylist(currentPageList, dev, ctm); + fz_freedevice(dev); + fz_droppixmap(pix); + LOGE("Rendered"); AndroidBitmap_unlockPixels(env, bitmap); return 1; } - -void android_log(char *err, int n) -{ - LOGE(err, n); -} diff --git a/android/src/com/artifex/mupdf/MuPDFActivity.java b/android/src/com/artifex/mupdf/MuPDFActivity.java index f1dd1cc8..10c69f4f 100644 --- a/android/src/com/artifex/mupdf/MuPDFActivity.java +++ b/android/src/com/artifex/mupdf/MuPDFActivity.java @@ -13,29 +13,59 @@ import com.artifex.mupdf.PixmapView; public class MuPDFActivity extends Activity { - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) + /* The core rendering instance */ + private MuPDFCore core; + + private MuPDFCore openFile() { - String state = Environment.getExternalStorageState(); + String storageState = Environment.getExternalStorageState(); + File path, file; + MuPDFCore core; - if (Environment.MEDIA_MOUNTED.equals(state)) + if (Environment.MEDIA_MOUNTED.equals(storageState)) { System.out.println("Media mounted read/write"); } - else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) + else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(storageState)) { System.out.println("Media mounted read only"); } else { System.out.println("No media at all! Bale!\n"); - return; + return null; } - File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - File file = new File(path, "test.pdf"); + path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + file = new File(path, "test.pdf"); System.out.println("Trying to open "+file.toString()); - PixmapView pixmapView = new PixmapView(this, file.toString()); + try + { + core = new MuPDFCore(file.toString()); + } + catch (Exception e) + { + System.out.println(e); + return null; + } + return core; + } + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + PixmapView pixmapView; + + core = (MuPDFCore)getLastNonConfigurationInstance(); + if (core == null) + core = openFile(); + if (core == null) + { + /* FIXME: Error handling here! */ + return; + } + + pixmapView = new PixmapView(this, core); super.onCreate(savedInstanceState); /* Now create the UI */ @@ -86,6 +116,11 @@ public class MuPDFActivity extends Activity setContentView(layout); } + public Object onRetainNonConfigurationInstance() + { + return core; + } + private class MyButtonHandler implements OnClickListener { Button buttonStart; diff --git a/android/src/com/artifex/mupdf/PixmapView.java b/android/src/com/artifex/mupdf/PixmapView.java index 80fcb5f1..f3b99f01 100644 --- a/android/src/com/artifex/mupdf/PixmapView.java +++ b/android/src/com/artifex/mupdf/PixmapView.java @@ -16,16 +16,18 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback private SurfaceHolder holder; private MuPDFThread thread = null; private boolean threadStarted = false; + private MuPDFCore core; /* Constructor */ - public PixmapView(Context context, String filename) + public PixmapView(Context context, MuPDFCore core) { super(context); System.out.println("PixmapView construct"); + this.core = core; holder = getHolder(); - holder.addCallback(this); - thread = new MuPDFThread(holder, filename); - setFocusable(true); // need to get the key events + holder.addCallback(this); + thread = new MuPDFThread(holder, core); + setFocusable(true); // need to get the key events } /* load our native library */ @@ -86,7 +88,9 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; + System.out.println("Surface destroyed 1 this="+this); thread.setRunning(false); + System.out.println("Surface destroyed 2"); while (retry) { try @@ -99,6 +103,7 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback } } threadStarted = false; + System.out.println("Surface destroyed 3"); } class MuPDFThread extends Thread @@ -106,12 +111,11 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback private SurfaceHolder holder; private boolean running = false; private int keycode = -1; - private String filename; private int screenWidth; private int screenHeight; private int screenGeneration; private Bitmap bitmap; - private int numPages; + private MuPDFCore core; /* The following variables deal with the size of the current page; * specifically, its position on the screen, its raw size, its @@ -120,8 +124,6 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback */ private int pageOriginX; private int pageOriginY; - private float pageRawWidth; - private float pageRawHeight; private float pageScale; private int pageWidth; private int pageHeight; @@ -155,10 +157,10 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback private Rect srcRect; private RectF dstRect; - public MuPDFThread(SurfaceHolder holder, String filename) + public MuPDFThread(SurfaceHolder holder, MuPDFCore core) { this.holder = holder; - this.filename = filename; + this.core = core; touchZoomMidpoint = new PointF(0,0); srcRect = new Rect(0,0,0,0); dstRect = new RectF(0,0,0,0); @@ -167,6 +169,22 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback public void setRunning(boolean running) { this.running = running; + if (!running) + { + System.out.println("killing 1"); + synchronized(this) + { + System.out.println("killing 2"); + action = DIE; + if (wakeMe) + { + wakeMe = false; + System.out.println("killing 3"); + this.notify(); + System.out.println("killing 4"); + } + } + } } public void newScreenSize(int width, int height) @@ -193,14 +211,14 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback if (delta == Integer.MIN_VALUE) actionPageNum = 1; else if (delta == Integer.MAX_VALUE) - actionPageNum = numPages; + actionPageNum = core.numPages; else { actionPageNum += delta; if (actionPageNum < 1) actionPageNum = 1; - if (actionPageNum > numPages) - actionPageNum = numPages; + if (actionPageNum > core.numPages) + actionPageNum = core.numPages; } if (wakeMe) { @@ -270,24 +288,24 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback /* Find new scaled page sizes */ synchronized(this) { - pageWidth = (int)(pageRawWidth*scale+0.5); + pageWidth = (int)(core.pageWidth*scale+0.5); if (pageWidth < screenWidth/2) { - scale = screenWidth/2/pageRawWidth; - pageWidth = (int)(pageRawWidth*scale+0.5); + scale = screenWidth/2/core.pageWidth; + pageWidth = (int)(core.pageWidth*scale+0.5); } - pageHeight = (int)(pageRawHeight*scale+0.5); + pageHeight = (int)(core.pageHeight*scale+0.5); if (pageHeight < screenHeight/2) { - scale = screenHeight/2/pageRawHeight; - pageWidth = (int)(pageRawWidth *scale+0.5); - pageHeight = (int)(pageRawHeight*scale+0.5); + scale = screenHeight/2/core.pageHeight; + pageWidth = (int)(core.pageWidth *scale+0.5); + pageHeight = (int)(core.pageHeight*scale+0.5); } pageScale = scale; /* Now given this new scale, calculate page origins so that * x and y are at midpoint */ - float xscale = (float)pageWidth /(float)pageRawWidth; - float yscale = (float)pageHeight/(float)pageRawHeight; + float xscale = (float)pageWidth /core.pageWidth; + float yscale = (float)pageHeight/core.pageHeight; setPageOriginTo((int)(midpoint.x - x*xscale + 0.5), (int)(midpoint.y - y*yscale + 0.5)); } @@ -296,22 +314,22 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback public void scalePageToScreen() { float scaleX, scaleY; - scaleX = (float)screenWidth/pageRawWidth; - scaleY = (float)screenHeight/pageRawHeight; + scaleX = (float)screenWidth /core.pageWidth; + scaleY = (float)screenHeight/core.pageHeight; synchronized(this) { if (scaleX < scaleY) pageScale = scaleX; else pageScale = scaleY; - pageWidth = (int)(pageRawWidth * pageScale + 0.5); - pageHeight = (int)(pageRawHeight * pageScale + 0.5); + pageWidth = (int)(core.pageWidth * pageScale + 0.5); + pageHeight = (int)(core.pageHeight * pageScale + 0.5); pageOriginX = (screenWidth - pageWidth)/2; pageOriginY = (screenHeight - pageHeight)/2; forceRedraw(); } System.out.println("scalePageToScreen: Raw="+ - pageRawWidth+"x"+pageRawHeight+" scaled="+ + core.pageWidth+"x"+core.pageHeight+" scaled="+ pageWidth+","+pageHeight+" pageScale="+ pageScale); } @@ -386,16 +404,10 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback int localPageH = 0; int localScreenGeneration = screenGeneration; int localAction; - int localActionPageNum = 1; - numPages = mupdfOpenFile(filename); - if (numPages <= 0) - { - /* Error whilst loading file */ - } - System.out.println("File loaded: "+numPages+" pages"); + int localActionPageNum = core.pageNum; /* Set up our default action */ action = GOTOPAGE; - actionPageNum = 1; + actionPageNum = core.pageNum; while (action != DIE) { synchronized(this) @@ -421,6 +433,9 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback */ switch (action) { + case DIE: + System.out.println("Woken to die!"); + break; case GOTOPAGE: localActionPageNum = actionPageNum; break; @@ -429,7 +444,7 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback * redraw (in local variables, in docspace). * We'll always draw a screensized lump, unless * that's too big. */ - System.out.println("page="+pageWidth+","+pageHeight+" ("+pageRawWidth+","+pageRawHeight+"@"+pageScale+") @ "+pageOriginX+","+pageOriginY); + System.out.println("page="+pageWidth+","+pageHeight+" ("+core.pageWidth+","+core.pageHeight+"@"+pageScale+") @ "+pageOriginX+","+pageOriginY); localPageW = pageWidth; localPageH = pageHeight; patchW = pageWidth; @@ -490,7 +505,8 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback break; } localAction = action; - action = SLEEP; + if (action != DIE) + action = SLEEP; } /* In the redraw case: * pW, pH, pX, pY, localPageW, localPageH are now all set @@ -501,9 +517,7 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback switch (localAction) { case GOTOPAGE: - mupdfGotoPage(localActionPageNum); - pageRawWidth = mupdfPageWidth(); - pageRawHeight = mupdfPageHeight(); + core.gotoPage(localActionPageNum); scalePageToScreen(); action = REDRAW; break; @@ -517,7 +531,7 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback Bitmap.Config.ARGB_8888); } System.out.println("Calling redraw native method"); - mupdfDrawPage(bitmap, localPageW, localPageH, + core.drawPage(bitmap, localPageW, localPageH, patchX, patchY, patchW, patchH); System.out.println("Called native method"); { @@ -561,17 +575,4 @@ public class PixmapView extends SurfaceView implements SurfaceHolder.Callback canvas.drawBitmap(bitmap, srcRect, dstRect, (Paint)null); } } - - /* These should be native functions */ - private static native int mupdfOpenFile(String filename); - private static native void mupdfGotoPage(int localActionPageNum); - private static native float mupdfPageWidth(); - private static native float mupdfPageHeight(); - private static native void mupdfDrawPage(Bitmap bitmap, - int pageW, - int pageH, - int patchX, - int patchY, - int patchW, - int patchH); } |