diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 23:46:49 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 23:46:49 +0200 |
commit | a4e229f4a11ed93f3c5527c84ea7032342410a7c (patch) | |
tree | 18739f4a7dfdb33a959bed66790469de70e97c95 /android | |
parent | 7cf6ccee8c6b59d8aac17ab6e4673bcb69f5e8d2 (diff) | |
download | mupdf-a4e229f4a11ed93f3c5527c84ea7032342410a7c.tar.xz |
android: Conform to coding convention.
Use tabs for indentation and no extra spaces to align stuff.
Diffstat (limited to 'android')
-rw-r--r-- | android/jni/mupdf.c | 348 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/MuPDFActivity.java | 266 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/MuPDFCore.java | 81 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/PixmapView.java | 1125 |
4 files changed, 904 insertions, 916 deletions
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c index c02c0f82..77ff39a2 100644 --- a/android/jni/mupdf.c +++ b/android/jni/mupdf.c @@ -10,203 +10,193 @@ #include "fitz.h" #include "mupdf.h" -#define LOG_TAG "libmupdf" -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) +#define LOG_TAG "libmupdf" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) /* Set to 1 to enable debug log traces. */ #define DEBUG 0 /* Globals */ -fz_colorspace *colorspace; -fz_glyph_cache *glyphcache; -pdf_xref *xref; -int pagenum = 1; -int resolution = 160; -float pageWidth = 100; -float pageHeight = 100; +fz_colorspace *colorspace; +fz_glyph_cache *glyphcache; +pdf_xref *xref; +int pagenum = 1; +int resolution = 160; +float pageWidth = 100; +float pageHeight = 100; fz_display_list *currentPageList; -fz_rect currentMediabox; -int currentRotate; +fz_rect currentMediabox; +int currentRotate; -JNIEXPORT int JNICALL Java_com_artifex_mupdf_MuPDFCore_openFile(JNIEnv * env, jobject thiz, jstring jfilename) +JNIEXPORT int JNICALL +Java_com_artifex_mupdf_MuPDFCore_openFile(JNIEnv * env, jobject thiz, jstring jfilename) { - const char *filename; - char *password = ""; - int accelerate = 1; - fz_error error; - - filename = (*env)->GetStringUTFChars(env, jfilename, NULL); - if (filename == NULL) - { - LOGE("Failed to get filename"); - return 0; - } - - if (accelerate) - fz_accelerate(); - glyphcache = fz_new_glyph_cache(); - colorspace = fz_device_rgb; - - LOGE("Opening document..."); - error = pdf_open_xref(&xref, filename, password); - if (error) - { - LOGE("Cannot open document: '%s'\n", filename); - return 0; - } - - LOGE("Loading page tree..."); - error = pdf_load_page_tree(xref); - if (error) - { - LOGE("Cannot load page tree: '%s'\n", filename); - return 0; - } - LOGE("Done! %d pages", pdf_get_page_count(xref)); - - return pdf_get_page_count(xref); + const char *filename; + char *password = ""; + int accelerate = 1; + fz_error error; + + filename = (*env)->GetStringUTFChars(env, jfilename, NULL); + if (filename == NULL) + { + LOGE("Failed to get filename"); + return 0; + } + + if (accelerate) + fz_accelerate(); + glyphcache = fz_new_glyph_cache(); + colorspace = fz_device_rgb; + + LOGE("Opening document..."); + error = pdf_open_xref(&xref, filename, password); + if (error) + { + LOGE("Cannot open document: '%s'\n", filename); + return 0; + } + + LOGE("Loading page tree..."); + error = pdf_load_page_tree(xref); + if (error) + { + LOGE("Cannot load page tree: '%s'\n", filename); + return 0; + } + LOGE("Done! %d pages", pdf_get_page_count(xref)); + + return pdf_get_page_count(xref); } -JNIEXPORT void JNICALL Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal( - JNIEnv *env, - jobject thiz, - int page) +JNIEXPORT void JNICALL +Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal(JNIEnv *env, jobject thiz, int page) { - float zoom; - fz_matrix ctm; - 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; - - LOGE("Goto page %d...", page); - if (currentPageList != NULL) - { - fz_free_display_list(currentPageList); - currentPageList = NULL; - } - pagenum = page; - pageobj = pdf_get_page_object(xref, pagenum); - if (pageobj == NULL) - return; - error = pdf_load_page(¤tPage, xref, pageobj); - if (error) - return; - zoom = resolution / 72; - 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(currentRotate)); - bbox = fz_round_rect(fz_transform_rect(ctm, currentMediabox)); - pageWidth = bbox.x1-bbox.x0; - pageHeight = bbox.y1-bbox.y0; - /* Render to list */ - currentPageList = fz_new_display_list(); - dev = fz_new_list_device(currentPageList); - error = pdf_run_page(xref, currentPage, dev, fz_identity); - pdf_free_page(currentPage); - if (error) - LOGE("cannot make displaylist from page %d", pagenum); - fz_free_device(dev); + float zoom; + fz_matrix ctm; + 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; + + LOGE("Goto page %d...", page); + if (currentPageList != NULL) + { + fz_free_display_list(currentPageList); + currentPageList = NULL; + } + pagenum = page; + pageobj = pdf_get_page_object(xref, pagenum); + if (pageobj == NULL) + return; + error = pdf_load_page(¤tPage, xref, pageobj); + if (error) + return; + zoom = resolution / 72; + 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(currentRotate)); + bbox = fz_round_rect(fz_transform_rect(ctm, currentMediabox)); + pageWidth = bbox.x1-bbox.x0; + pageHeight = bbox.y1-bbox.y0; + /* Render to list */ + currentPageList = fz_new_display_list(); + dev = fz_new_list_device(currentPageList); + error = pdf_run_page(xref, currentPage, dev, fz_identity); + pdf_free_page(currentPage); + if (error) + LOGE("cannot make displaylist from page %d", pagenum); + fz_free_device(dev); } -JNIEXPORT float JNICALL Java_com_artifex_mupdf_MuPDFCore_getPageWidth( - JNIEnv *env, - jobject thiz) +JNIEXPORT float JNICALL +Java_com_artifex_mupdf_MuPDFCore_getPageWidth(JNIEnv *env, jobject thiz) { - LOGE("PageWidth=%g", pageWidth); - return pageWidth; + LOGE("PageWidth=%g", pageWidth); + return pageWidth; } -JNIEXPORT float JNICALL Java_com_artifex_mupdf_MuPDFCore_getPageHeight( - JNIEnv *env, - jobject thiz) +JNIEXPORT float JNICALL +Java_com_artifex_mupdf_MuPDFCore_getPageHeight(JNIEnv *env, jobject thiz) { - LOGE("PageHeight=%g", pageHeight); - return pageHeight; + LOGE("PageHeight=%g", pageHeight); + return pageHeight; } -JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_MuPDFCore_drawPage( - JNIEnv *env, - jobject thiz, - jobject bitmap, - int pageW, - int pageH, - int patchX, - int patchY, - int patchW, - int patchH) +JNIEXPORT jboolean JNICALL +Java_com_artifex_mupdf_MuPDFCore_drawPage(JNIEnv *env, jobject thiz, jobject bitmap, + int pageW, int pageH, int patchX, int patchY, int patchW, int patchH) { - AndroidBitmapInfo info; - 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) { - LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); - return 0; - } - - LOGI("Checking format\n"); - if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { - LOGE("Bitmap format is not RGBA_8888 !"); - return 0; - } - - LOGI("locking pixels\n"); - if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) { - LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); - return 0; - } - - /* 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_new_pixmap_with_data(colorspace, - patchX, - patchY, - patchW, - patchH, - pixels); - if (currentPageList == NULL) - { - fz_clear_pixmap_with_color(pix, 0xd0); - return 0; - } - fz_clear_pixmap_with_color(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_round_rect(fz_transform_rect(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_new_draw_device(glyphcache, pix); - fz_execute_display_list(currentPageList, dev, ctm); - fz_free_device(dev); - fz_drop_pixmap(pix); - LOGE("Rendered"); - - AndroidBitmap_unlockPixels(env, bitmap); - - return 1; + AndroidBitmapInfo info; + 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) { + LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); + return 0; + } + + LOGI("Checking format\n"); + if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { + LOGE("Bitmap format is not RGBA_8888 !"); + return 0; + } + + LOGI("locking pixels\n"); + if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) { + LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); + return 0; + } + + /* 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_new_pixmap_with_data(colorspace, + patchX, + patchY, + patchW, + patchH, + pixels); + if (currentPageList == NULL) + { + fz_clear_pixmap_with_color(pix, 0xd0); + return 0; + } + fz_clear_pixmap_with_color(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_round_rect(fz_transform_rect(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_new_draw_device(glyphcache, pix); + fz_execute_display_list(currentPageList, dev, ctm); + fz_free_device(dev); + fz_drop_pixmap(pix); + LOGE("Rendered"); + + AndroidBitmap_unlockPixels(env, bitmap); + + return 1; } diff --git a/android/src/com/artifex/mupdf/MuPDFActivity.java b/android/src/com/artifex/mupdf/MuPDFActivity.java index 10c69f4f..0561f01b 100644 --- a/android/src/com/artifex/mupdf/MuPDFActivity.java +++ b/android/src/com/artifex/mupdf/MuPDFActivity.java @@ -13,137 +13,137 @@ import com.artifex.mupdf.PixmapView; public class MuPDFActivity extends Activity { - /* The core rendering instance */ - private MuPDFCore core; - - private MuPDFCore openFile() - { - String storageState = Environment.getExternalStorageState(); - File path, file; - MuPDFCore core; - - if (Environment.MEDIA_MOUNTED.equals(storageState)) - { - System.out.println("Media mounted read/write"); - } - 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 null; - } - path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - file = new File(path, "test.pdf"); - System.out.println("Trying to open "+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 */ - RelativeLayout layout; - LinearLayout bar; - MyButtonHandler bh = new MyButtonHandler(pixmapView); - - bar = new LinearLayout(this); - bar.setOrientation(LinearLayout.HORIZONTAL); - bh.buttonStart = new Button(this); - bh.buttonStart.setText("<<"); - bh.buttonStart.setOnClickListener(bh); - bar.addView(bh.buttonStart); - bh.buttonPrev = new Button(this); - bh.buttonPrev.setText("<"); - bh.buttonPrev.setOnClickListener(bh); - bar.addView(bh.buttonPrev); - bh.buttonNext = new Button(this); - bh.buttonNext.setText(">"); - bh.buttonNext.setOnClickListener(bh); - bar.addView(bh.buttonNext); - bh.buttonEnd = new Button(this); - bh.buttonEnd.setText(">>"); - bh.buttonEnd.setOnClickListener(bh); - bar.addView(bh.buttonEnd); - - layout = new RelativeLayout(this); - layout.setLayoutParams(new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.FILL_PARENT, - RelativeLayout.LayoutParams.FILL_PARENT)); - layout.setGravity(Gravity.FILL); - - RelativeLayout.LayoutParams barParams = - new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.FILL_PARENT, - RelativeLayout.LayoutParams.WRAP_CONTENT); - barParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); - bar.setId(100); - layout.addView(bar, barParams); - - RelativeLayout.LayoutParams pixmapParams = - new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.FILL_PARENT, - RelativeLayout.LayoutParams.FILL_PARENT); - pixmapParams.addRule(RelativeLayout.ABOVE,100); - layout.addView(pixmapView, pixmapParams); - - setContentView(layout); - } - - public Object onRetainNonConfigurationInstance() - { - return core; - } - - private class MyButtonHandler implements OnClickListener - { - Button buttonStart; - Button buttonPrev; - Button buttonNext; - Button buttonEnd; - PixmapView pixmapView; - - public MyButtonHandler(PixmapView pixmapView) - { - this.pixmapView = pixmapView; - } - - public void onClick(View v) - { - if (v == buttonStart) - pixmapView.changePage(Integer.MIN_VALUE); - else if (v == buttonPrev) - pixmapView.changePage(-1); - else if (v == buttonNext) - pixmapView.changePage(+1); - else if (v == buttonEnd) - pixmapView.changePage(Integer.MAX_VALUE); - } - } + /* The core rendering instance */ + private MuPDFCore core; + + private MuPDFCore openFile() + { + String storageState = Environment.getExternalStorageState(); + File path, file; + MuPDFCore core; + + if (Environment.MEDIA_MOUNTED.equals(storageState)) + { + System.out.println("Media mounted read/write"); + } + 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 null; + } + path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + file = new File(path, "test.pdf"); + System.out.println("Trying to open "+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 */ + RelativeLayout layout; + LinearLayout bar; + MyButtonHandler bh = new MyButtonHandler(pixmapView); + + bar = new LinearLayout(this); + bar.setOrientation(LinearLayout.HORIZONTAL); + bh.buttonStart = new Button(this); + bh.buttonStart.setText("<<"); + bh.buttonStart.setOnClickListener(bh); + bar.addView(bh.buttonStart); + bh.buttonPrev = new Button(this); + bh.buttonPrev.setText("<"); + bh.buttonPrev.setOnClickListener(bh); + bar.addView(bh.buttonPrev); + bh.buttonNext = new Button(this); + bh.buttonNext.setText(">"); + bh.buttonNext.setOnClickListener(bh); + bar.addView(bh.buttonNext); + bh.buttonEnd = new Button(this); + bh.buttonEnd.setText(">>"); + bh.buttonEnd.setOnClickListener(bh); + bar.addView(bh.buttonEnd); + + layout = new RelativeLayout(this); + layout.setLayoutParams(new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.FILL_PARENT, + RelativeLayout.LayoutParams.FILL_PARENT)); + layout.setGravity(Gravity.FILL); + + RelativeLayout.LayoutParams barParams = + new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.FILL_PARENT, + RelativeLayout.LayoutParams.WRAP_CONTENT); + barParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + bar.setId(100); + layout.addView(bar, barParams); + + RelativeLayout.LayoutParams pixmapParams = + new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.FILL_PARENT, + RelativeLayout.LayoutParams.FILL_PARENT); + pixmapParams.addRule(RelativeLayout.ABOVE,100); + layout.addView(pixmapView, pixmapParams); + + setContentView(layout); + } + + public Object onRetainNonConfigurationInstance() + { + return core; + } + + private class MyButtonHandler implements OnClickListener + { + Button buttonStart; + Button buttonPrev; + Button buttonNext; + Button buttonEnd; + PixmapView pixmapView; + + public MyButtonHandler(PixmapView pixmapView) + { + this.pixmapView = pixmapView; + } + + public void onClick(View v) + { + if (v == buttonStart) + pixmapView.changePage(Integer.MIN_VALUE); + else if (v == buttonPrev) + pixmapView.changePage(-1); + else if (v == buttonNext) + pixmapView.changePage(+1); + else if (v == buttonEnd) + pixmapView.changePage(Integer.MAX_VALUE); + } + } } diff --git a/android/src/com/artifex/mupdf/MuPDFCore.java b/android/src/com/artifex/mupdf/MuPDFCore.java index 245ffdc0..28408516 100644 --- a/android/src/com/artifex/mupdf/MuPDFCore.java +++ b/android/src/com/artifex/mupdf/MuPDFCore.java @@ -3,50 +3,47 @@ import android.graphics.*; public class MuPDFCore { - /* load our native library */ - static { - System.loadLibrary("mupdf"); - } + /* load our native library */ + static { + System.loadLibrary("mupdf"); + } - /* Readable members */ - public int pageNum; - public int numPages; - public float pageWidth; - public float pageHeight; + /* Readable members */ + public int pageNum; + public int numPages; + public float pageWidth; + public float pageHeight; - /* The native functions */ - private static native int openFile(String filename); - private static native void gotoPageInternal(int localActionPageNum); - private static native float getPageWidth(); - private static native float getPageHeight(); - public static native void drawPage(Bitmap bitmap, - int pageW, - int pageH, - int patchX, - int patchY, - int patchW, - int patchH); + /* The native functions */ + private static native int openFile(String filename); + private static native void gotoPageInternal(int localActionPageNum); + private static native float getPageWidth(); + private static native float getPageHeight(); + public static native void drawPage(Bitmap bitmap, + int pageW, int pageH, + int patchX, int patchY, + int patchW, int patchH); - public MuPDFCore(String filename) throws Exception - { - numPages = openFile(filename); - if (numPages <= 0) - { - throw new Exception("Failed to open "+filename); - } - pageNum = 1; - } + public MuPDFCore(String filename) throws Exception + { + numPages = openFile(filename); + if (numPages <= 0) + { + throw new Exception("Failed to open "+filename); + } + pageNum = 1; + } - /* Shim function */ - public void gotoPage(int page) - { - if (page > numPages) - page = numPages; - else if (page < 1) - page = 1; - gotoPageInternal(page); - this.pageNum = page; - this.pageWidth = getPageWidth(); - this.pageHeight = getPageHeight(); - } + /* Shim function */ + public void gotoPage(int page) + { + if (page > numPages) + page = numPages; + else if (page < 1) + page = 1; + gotoPageInternal(page); + this.pageNum = page; + this.pageWidth = getPageWidth(); + this.pageHeight = getPageHeight(); + } } diff --git a/android/src/com/artifex/mupdf/PixmapView.java b/android/src/com/artifex/mupdf/PixmapView.java index f3b99f01..c7ba9d72 100644 --- a/android/src/com/artifex/mupdf/PixmapView.java +++ b/android/src/com/artifex/mupdf/PixmapView.java @@ -13,566 +13,567 @@ import java.io.*; 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, MuPDFCore core) - { - super(context); - System.out.println("PixmapView construct"); - this.core = core; - holder = getHolder(); - holder.addCallback(this); - thread = new MuPDFThread(holder, core); - setFocusable(true); // need to get the key events - } - - /* load our native library */ - static { - System.loadLibrary("mupdf"); - } - - /* Handlers for keys - so we can actually do stuff */ - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) - { - if (thread.onKeyDown(keyCode, event)) - return true; - return super.onKeyDown(keyCode, event); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) - { - if (thread.onKeyUp(keyCode, event)) - return true; - return super.onKeyUp(keyCode, event); - } - - @Override - public boolean onTouchEvent(MotionEvent event) - { - if (thread.onTouchEvent(event)) - return true; - return super.onTouchEvent(event); - } - - public void changePage(int delta) - { - thread.changePage(delta); - } - - /* Handlers for SurfaceHolder callbacks; these are called when the - * surface is created/destroyed/changed. We need to ensure that we only - * draw into the surface between the created and destroyed calls. - * Therefore, we start/stop the thread that actually runs MuPDF on - * creation/destruction. */ - public void surfaceCreated(SurfaceHolder holder) - { - } - - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) - { - thread.newScreenSize(width, height); - if (!threadStarted) - { - threadStarted = true; - thread.setRunning(true); - thread.start(); - } - } - - 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 - { - thread.join(); - retry = false; - } - catch (InterruptedException e) - { - } - } - threadStarted = false; - System.out.println("Surface destroyed 3"); - } - - class MuPDFThread extends Thread - { - private SurfaceHolder holder; - private boolean running = false; - private int keycode = -1; - private int screenWidth; - private int screenHeight; - private int screenGeneration; - private Bitmap bitmap; - private MuPDFCore core; - - /* The following variables deal with the size of the current page; - * specifically, its position on the screen, its raw size, its - * current scale, and its current scaled size (in terms of whole - * pixels). - */ - private int pageOriginX; - private int pageOriginY; - private float pageScale; - private int pageWidth; - private int pageHeight; - - /* The following variables deal with the multitouch handling */ - private final int NONE = 0; - private final int DRAG = 1; - private final int ZOOM = 2; - private int touchMode = NONE; - private float touchInitialSpacing; - private float touchDragStartX; - private float touchDragStartY; - private float touchInitialOriginX; - private float touchInitialOriginY; - private float touchInitialScale; - private PointF touchZoomMidpoint; - - /* The following control the inner loop; other events etc cause - * action to be set. The inner loop runs around a tight loop - * performing the action requested of it. - */ - private boolean wakeMe = false; - private int action; - private final int SLEEP = 0; - private final int REDRAW = 1; - private final int DIE = 2; - private final int GOTOPAGE = 3; - private int actionPageNum; - - /* Members for blitting, declared here to avoid causing gcs */ - private Rect srcRect; - private RectF dstRect; - - public MuPDFThread(SurfaceHolder holder, MuPDFCore core) - { - this.holder = holder; - this.core = core; - touchZoomMidpoint = new PointF(0,0); - srcRect = new Rect(0,0,0,0); - dstRect = new RectF(0,0,0,0); - } - - 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) - { - this.screenWidth = width; - this.screenHeight = height; - this.screenGeneration++; - } - - public boolean onKeyDown(int keyCode, KeyEvent msg) - { - keycode = keyCode; - return false; - } - - public boolean onKeyUp(int keyCode, KeyEvent msg) - { - return false; - } - - public synchronized void changePage(int delta) - { - action = GOTOPAGE; - if (delta == Integer.MIN_VALUE) - actionPageNum = 1; - else if (delta == Integer.MAX_VALUE) - actionPageNum = core.numPages; - else - { - actionPageNum += delta; - if (actionPageNum < 1) - actionPageNum = 1; - if (actionPageNum > core.numPages) - actionPageNum = core.numPages; - } - if (wakeMe) - { - wakeMe = false; - this.notify(); - } - } - - private float spacing(MotionEvent event) - { - float x = event.getX(0) - event.getX(1); - float y = event.getY(0) - event.getY(1); - return FloatMath.sqrt(x*x+y*y); - } - - private void midpoint(PointF point, MotionEvent event) - { - float x = event.getX(0) + event.getX(1); - float y = event.getY(0) + event.getY(1); - point.set(x/2, y/2); - } - - private synchronized void forceRedraw() - { - if (wakeMe) - { - wakeMe = false; - this.notify(); - } - action = REDRAW; - } - - public synchronized void setPageOriginTo(int x, int y) - { - /* Adjust the coordinates so that the page always covers the - * centre of the screen. */ - if (x + pageWidth < screenWidth/2) - { - x = screenWidth/2 - pageWidth; - } - else if (x > screenWidth/2) - { - x = screenWidth/2; - } - if (y + pageHeight < screenHeight/2) - { - y = screenHeight/2 - pageHeight; - } - else if (y > screenHeight/2) - { - y = screenHeight/2; - } - if ((x != pageOriginX) || (y != pageOriginY)) - { - pageOriginX = x; - pageOriginY = y; - } - forceRedraw(); - } - - public void setPageScaleTo(float scale, PointF midpoint) - { - float x, y; - /* Convert midpoint (in screen coords) to page coords */ - x = (midpoint.x - pageOriginX)/pageScale; - y = (midpoint.y - pageOriginY)/pageScale; - /* Find new scaled page sizes */ - synchronized(this) - { - pageWidth = (int)(core.pageWidth*scale+0.5); - if (pageWidth < screenWidth/2) - { - scale = screenWidth/2/core.pageWidth; - pageWidth = (int)(core.pageWidth*scale+0.5); - } - pageHeight = (int)(core.pageHeight*scale+0.5); - if (pageHeight < screenHeight/2) - { - 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 /core.pageWidth; - float yscale = (float)pageHeight/core.pageHeight; - setPageOriginTo((int)(midpoint.x - x*xscale + 0.5), - (int)(midpoint.y - y*yscale + 0.5)); - } - } - - public void scalePageToScreen() - { - float scaleX, scaleY; - scaleX = (float)screenWidth /core.pageWidth; - scaleY = (float)screenHeight/core.pageHeight; - synchronized(this) - { - if (scaleX < scaleY) - pageScale = scaleX; - else - pageScale = scaleY; - 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="+ - core.pageWidth+"x"+core.pageHeight+" scaled="+ - pageWidth+","+pageHeight+" pageScale="+ - pageScale); - } - - public boolean onTouchEvent(MotionEvent event) - { - int action = event.getAction(); - boolean done = false; - switch (action & MotionEvent.ACTION_MASK) - { - case MotionEvent.ACTION_DOWN: - touchMode = DRAG; - touchDragStartX = event.getX(); - touchDragStartY = event.getY(); - touchInitialOriginX = pageOriginX; - touchInitialOriginY = pageOriginY; - System.out.println("Starting dragging from: "+touchDragStartX+","+touchDragStartY+" ("+pageOriginX+","+pageOriginY+")"); - done = true; - break; - case MotionEvent.ACTION_POINTER_DOWN: - touchInitialSpacing = spacing(event); - if (touchInitialSpacing > 10f) - { - System.out.println("Started zooming: spacing="+touchInitialSpacing); - touchInitialScale = pageScale; - touchMode = ZOOM; - done = true; - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_POINTER_UP: - if (touchMode != NONE) - { - System.out.println("Released!"); - touchMode = NONE; - done = true; - } - break; - case MotionEvent.ACTION_MOVE: - if (touchMode == DRAG) - { - float x = touchInitialOriginX+event.getX()-touchDragStartX; - float y = touchInitialOriginY+event.getY()-touchDragStartY; - System.out.println("Dragged to "+x+","+y); - setPageOriginTo((int)(x+0.5),(int)(y+0.5)); - done = true; - } - else if (touchMode == ZOOM) - { - float newSpacing = spacing(event); - if (newSpacing > 10f) - { - float newScale = touchInitialScale*newSpacing/touchInitialSpacing; - System.out.println("Zoomed to "+newSpacing); - midpoint(touchZoomMidpoint,event); - setPageScaleTo(newScale,touchZoomMidpoint); - done = true; - } - } - } - return done; - } - - public void run() - { - boolean redraw = false; - int patchW = 0; - int patchH = 0; - int patchX = 0; - int patchY = 0; - int localPageW = 0; - int localPageH = 0; - int localScreenGeneration = screenGeneration; - int localAction; - int localActionPageNum = core.pageNum; - /* Set up our default action */ - action = GOTOPAGE; - actionPageNum = core.pageNum; - while (action != DIE) - { - synchronized(this) - { - while (action == SLEEP) - { - wakeMe = true; - try - { - System.out.println("Render thread sleeping"); - this.wait(); - System.out.println("Render thread woken"); - } - catch (java.lang.InterruptedException e) - { - System.out.println("Render thread exception:"+e); - } - } - /* Now we do as little as we can get away with while - * synchronised. In general this means copying any action - * or global variables into local ones so that when we - * unsynchronoise, other people can alter them again. - */ - switch (action) - { - case DIE: - System.out.println("Woken to die!"); - break; - case GOTOPAGE: - localActionPageNum = actionPageNum; - break; - case REDRAW: - /* Figure out what area of the page we want to - * redraw (in local variables, in docspace). - * We'll always draw a screensized lump, unless - * that's too big. */ - System.out.println("page="+pageWidth+","+pageHeight+" ("+core.pageWidth+","+core.pageHeight+"@"+pageScale+") @ "+pageOriginX+","+pageOriginY); - localPageW = pageWidth; - localPageH = pageHeight; - patchW = pageWidth; - patchH = pageHeight; - patchX = -pageOriginX; - patchY = -pageOriginY; - if (patchX < 0) - patchX = 0; - if (patchW > screenWidth) - patchW = screenWidth; - srcRect.left = 0; - if (patchX+patchW > pageWidth) - { - srcRect.left += patchX+patchW-pageWidth; - patchX = pageWidth-patchW; - } - if (patchY < 0) - patchY = 0; - if (patchH > screenHeight) - patchH = screenHeight; - srcRect.top = 0; - if (patchY+patchH > pageHeight) - { - srcRect.top += patchY+patchH-pageHeight; - patchY = pageHeight-patchH; - } - dstRect.left = pageOriginX; - if (dstRect.left < 0) - dstRect.left = 0; - dstRect.top = pageOriginY; - if (dstRect.top < 0) - dstRect.top = 0; - dstRect.right = dstRect.left + patchW; - srcRect.right = srcRect.left + patchW; - if (srcRect.right > screenWidth) - { - dstRect.right -= srcRect.right-screenWidth; - srcRect.right = screenWidth; - } - if (dstRect.right > screenWidth) - { - srcRect.right -= dstRect.right-screenWidth; - dstRect.right = screenWidth; - } - dstRect.bottom = dstRect.top + patchH; - srcRect.bottom = srcRect.top + patchH; - if (srcRect.bottom > screenHeight) - { - dstRect.bottom -=srcRect.bottom-screenHeight; - srcRect.bottom = screenHeight; - } - if (dstRect.bottom > screenHeight) - { - srcRect.bottom -=dstRect.bottom-screenHeight; - dstRect.bottom = screenHeight; - } - System.out.println("patch=["+patchX+","+patchY+","+patchW+","+patchH+"]"); - break; - } - localAction = action; - if (action != DIE) - action = SLEEP; - } - /* In the redraw case: - * pW, pH, pX, pY, localPageW, localPageH are now all set - * in local variables, and we are safe from the global vars - * being altered in calls from other threads. This is all - * the information we need to actually do our render. - */ - switch (localAction) - { - case GOTOPAGE: - core.gotoPage(localActionPageNum); - scalePageToScreen(); - action = REDRAW; - break; - case REDRAW: - if ((bitmap == null) || - (bitmap.getWidth() != patchW) || - (bitmap.getHeight() != patchH)) - { - /* make bitmap of required size */ - bitmap = Bitmap.createBitmap(patchW, patchH, - Bitmap.Config.ARGB_8888); - } - System.out.println("Calling redraw native method"); - core.drawPage(bitmap, localPageW, localPageH, - patchX, patchY, patchW, patchH); - System.out.println("Called native method"); - { - Canvas c = null; - try - { - c = holder.lockCanvas(null); - synchronized(holder) - { - if (localScreenGeneration == screenGeneration) - { - doDraw(c); - } - else - { - /* Someone has changed the screen - * under us! Better redraw again... - */ - action = REDRAW; - } - } - } - finally - { - if (c != null) - holder.unlockCanvasAndPost(c); - } - } - } - } - } - - protected void doDraw(Canvas canvas) - { - if ((canvas == null) || (bitmap == null)) - return; - /* Clear the screen */ - canvas.drawRGB(128,128,128); - /* Draw our bitmap on top */ - System.out.println("Blitting bitmap from "+srcRect.left+","+srcRect.top+","+srcRect.right+","+srcRect.bottom+" to "+dstRect.left+","+dstRect.top+","+dstRect.right+","+dstRect.bottom); - canvas.drawBitmap(bitmap, srcRect, dstRect, (Paint)null); - } - } + private SurfaceHolder holder; + private MuPDFThread thread = null; + private boolean threadStarted = false; + private MuPDFCore core; + + /* Constructor */ + 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, core); + setFocusable(true); // need to get the key events + } + + /* load our native library */ + static { + System.loadLibrary("mupdf"); + } + + /* Handlers for keys - so we can actually do stuff */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + if (thread.onKeyDown(keyCode, event)) + return true; + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) + { + if (thread.onKeyUp(keyCode, event)) + return true; + return super.onKeyUp(keyCode, event); + } + + @Override + public boolean onTouchEvent(MotionEvent event) + { + if (thread.onTouchEvent(event)) + return true; + return super.onTouchEvent(event); + } + + public void changePage(int delta) + { + thread.changePage(delta); + } + + /* Handlers for SurfaceHolder callbacks; these are called when the + * surface is created/destroyed/changed. We need to ensure that we only + * draw into the surface between the created and destroyed calls. + * Therefore, we start/stop the thread that actually runs MuPDF on + * creation/destruction. */ + public void surfaceCreated(SurfaceHolder holder) + { + } + + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) + { + thread.newScreenSize(width, height); + if (!threadStarted) + { + threadStarted = true; + thread.setRunning(true); + thread.start(); + } + } + + 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 + { + thread.join(); + retry = false; + } + catch (InterruptedException e) + { + } + } + threadStarted = false; + System.out.println("Surface destroyed 3"); + } + + class MuPDFThread extends Thread + { + private SurfaceHolder holder; + private boolean running = false; + private int keycode = -1; + private int screenWidth; + private int screenHeight; + private int screenGeneration; + private Bitmap bitmap; + private MuPDFCore core; + + /* The following variables deal with the size of the current page; + * specifically, its position on the screen, its raw size, its + * current scale, and its current scaled size (in terms of whole + * pixels). + */ + private int pageOriginX; + private int pageOriginY; + private float pageScale; + private int pageWidth; + private int pageHeight; + + /* The following variables deal with the multitouch handling */ + private final int NONE = 0; + private final int DRAG = 1; + private final int ZOOM = 2; + private int touchMode = NONE; + private float touchInitialSpacing; + private float touchDragStartX; + private float touchDragStartY; + private float touchInitialOriginX; + private float touchInitialOriginY; + private float touchInitialScale; + private PointF touchZoomMidpoint; + + /* The following control the inner loop; other events etc cause + * action to be set. The inner loop runs around a tight loop + * performing the action requested of it. + */ + private boolean wakeMe = false; + private int action; + private final int SLEEP = 0; + private final int REDRAW = 1; + private final int DIE = 2; + private final int GOTOPAGE = 3; + private int actionPageNum; + + /* Members for blitting, declared here to avoid causing gcs */ + private Rect srcRect; + private RectF dstRect; + + public MuPDFThread(SurfaceHolder holder, MuPDFCore core) + { + this.holder = holder; + this.core = core; + touchZoomMidpoint = new PointF(0,0); + srcRect = new Rect(0,0,0,0); + dstRect = new RectF(0,0,0,0); + } + + 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) + { + this.screenWidth = width; + this.screenHeight = height; + this.screenGeneration++; + } + + public boolean onKeyDown(int keyCode, KeyEvent msg) + { + keycode = keyCode; + return false; + } + + public boolean onKeyUp(int keyCode, KeyEvent msg) + { + return false; + } + + public synchronized void changePage(int delta) + { + action = GOTOPAGE; + if (delta == Integer.MIN_VALUE) + actionPageNum = 1; + else if (delta == Integer.MAX_VALUE) + actionPageNum = core.numPages; + else + { + actionPageNum += delta; + if (actionPageNum < 1) + actionPageNum = 1; + if (actionPageNum > core.numPages) + actionPageNum = core.numPages; + } + if (wakeMe) + { + wakeMe = false; + this.notify(); + } + } + + private float spacing(MotionEvent event) + { + float x = event.getX(0) - event.getX(1); + float y = event.getY(0) - event.getY(1); + return FloatMath.sqrt(x*x+y*y); + } + + private void midpoint(PointF point, MotionEvent event) + { + float x = event.getX(0) + event.getX(1); + float y = event.getY(0) + event.getY(1); + point.set(x/2, y/2); + } + + private synchronized void forceRedraw() + { + if (wakeMe) + { + wakeMe = false; + this.notify(); + } + action = REDRAW; + } + + public synchronized void setPageOriginTo(int x, int y) + { + /* Adjust the coordinates so that the page always covers the + * centre of the screen. */ + if (x + pageWidth < screenWidth/2) + { + x = screenWidth/2 - pageWidth; + } + else if (x > screenWidth/2) + { + x = screenWidth/2; + } + if (y + pageHeight < screenHeight/2) + { + y = screenHeight/2 - pageHeight; + } + else if (y > screenHeight/2) + { + y = screenHeight/2; + } + if ((x != pageOriginX) || (y != pageOriginY)) + { + pageOriginX = x; + pageOriginY = y; + } + forceRedraw(); + } + + public void setPageScaleTo(float scale, PointF midpoint) + { + float x, y; + /* Convert midpoint (in screen coords) to page coords */ + x = (midpoint.x - pageOriginX)/pageScale; + y = (midpoint.y - pageOriginY)/pageScale; + /* Find new scaled page sizes */ + synchronized(this) + { + pageWidth = (int)(core.pageWidth*scale+0.5); + if (pageWidth < screenWidth/2) + { + scale = screenWidth/2/core.pageWidth; + pageWidth = (int)(core.pageWidth*scale+0.5); + } + pageHeight = (int)(core.pageHeight*scale+0.5); + if (pageHeight < screenHeight/2) + { + 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 /core.pageWidth; + float yscale = (float)pageHeight/core.pageHeight; + setPageOriginTo((int)(midpoint.x - x*xscale + 0.5), + (int)(midpoint.y - y*yscale + 0.5)); + } + } + + public void scalePageToScreen() + { + float scaleX, scaleY; + scaleX = (float)screenWidth /core.pageWidth; + scaleY = (float)screenHeight/core.pageHeight; + synchronized(this) + { + if (scaleX < scaleY) + pageScale = scaleX; + else + pageScale = scaleY; + 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="+ + core.pageWidth+"x"+core.pageHeight+" scaled="+ + pageWidth+","+pageHeight+" pageScale="+ + pageScale); + } + + public boolean onTouchEvent(MotionEvent event) + { + int action = event.getAction(); + boolean done = false; + switch (action & MotionEvent.ACTION_MASK) + { + case MotionEvent.ACTION_DOWN: + touchMode = DRAG; + touchDragStartX = event.getX(); + touchDragStartY = event.getY(); + touchInitialOriginX = pageOriginX; + touchInitialOriginY = pageOriginY; + System.out.println("Starting dragging from: "+touchDragStartX+","+touchDragStartY+" ("+pageOriginX+","+pageOriginY+")"); + done = true; + break; + case MotionEvent.ACTION_POINTER_DOWN: + touchInitialSpacing = spacing(event); + if (touchInitialSpacing > 10f) + { + System.out.println("Started zooming: spacing="+touchInitialSpacing); + touchInitialScale = pageScale; + touchMode = ZOOM; + done = true; + } + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_UP: + if (touchMode != NONE) + { + System.out.println("Released!"); + touchMode = NONE; + done = true; + } + break; + case MotionEvent.ACTION_MOVE: + if (touchMode == DRAG) + { + float x = touchInitialOriginX+event.getX()-touchDragStartX; + float y = touchInitialOriginY+event.getY()-touchDragStartY; + System.out.println("Dragged to "+x+","+y); + setPageOriginTo((int)(x+0.5),(int)(y+0.5)); + done = true; + } + else if (touchMode == ZOOM) + { + float newSpacing = spacing(event); + if (newSpacing > 10f) + { + float newScale = touchInitialScale*newSpacing/touchInitialSpacing; + System.out.println("Zoomed to "+newSpacing); + midpoint(touchZoomMidpoint,event); + setPageScaleTo(newScale,touchZoomMidpoint); + done = true; + } + } + } + return done; + } + + public void run() + { + boolean redraw = false; + int patchW = 0; + int patchH = 0; + int patchX = 0; + int patchY = 0; + int localPageW = 0; + int localPageH = 0; + int localScreenGeneration = screenGeneration; + int localAction; + int localActionPageNum = core.pageNum; + + /* Set up our default action */ + action = GOTOPAGE; + actionPageNum = core.pageNum; + while (action != DIE) + { + synchronized(this) + { + while (action == SLEEP) + { + wakeMe = true; + try + { + System.out.println("Render thread sleeping"); + this.wait(); + System.out.println("Render thread woken"); + } + catch (java.lang.InterruptedException e) + { + System.out.println("Render thread exception:"+e); + } + } + + /* Now we do as little as we can get away with while + * synchronised. In general this means copying any action + * or global variables into local ones so that when we + * unsynchronoise, other people can alter them again. + */ + switch (action) + { + case DIE: + System.out.println("Woken to die!"); + break; + case GOTOPAGE: + localActionPageNum = actionPageNum; + break; + case REDRAW: + /* Figure out what area of the page we want to + * redraw (in local variables, in docspace). + * We'll always draw a screensized lump, unless + * that's too big. */ + System.out.println("page="+pageWidth+","+pageHeight+" ("+core.pageWidth+","+core.pageHeight+"@"+pageScale+") @ "+pageOriginX+","+pageOriginY); + localPageW = pageWidth; + localPageH = pageHeight; + patchW = pageWidth; + patchH = pageHeight; + patchX = -pageOriginX; + patchY = -pageOriginY; + if (patchX < 0) + patchX = 0; + if (patchW > screenWidth) + patchW = screenWidth; + srcRect.left = 0; + if (patchX+patchW > pageWidth) + { + srcRect.left += patchX+patchW-pageWidth; + patchX = pageWidth-patchW; + } + if (patchY < 0) + patchY = 0; + if (patchH > screenHeight) + patchH = screenHeight; + srcRect.top = 0; + if (patchY+patchH > pageHeight) + { + srcRect.top += patchY+patchH-pageHeight; + patchY = pageHeight-patchH; + } + dstRect.left = pageOriginX; + if (dstRect.left < 0) + dstRect.left = 0; + dstRect.top = pageOriginY; + if (dstRect.top < 0) + dstRect.top = 0; + dstRect.right = dstRect.left + patchW; + srcRect.right = srcRect.left + patchW; + if (srcRect.right > screenWidth) + { + dstRect.right -= srcRect.right-screenWidth; + srcRect.right = screenWidth; + } + if (dstRect.right > screenWidth) + { + srcRect.right -= dstRect.right-screenWidth; + dstRect.right = screenWidth; + } + dstRect.bottom = dstRect.top + patchH; + srcRect.bottom = srcRect.top + patchH; + if (srcRect.bottom > screenHeight) + { + dstRect.bottom -=srcRect.bottom-screenHeight; + srcRect.bottom = screenHeight; + } + if (dstRect.bottom > screenHeight) + { + srcRect.bottom -=dstRect.bottom-screenHeight; + dstRect.bottom = screenHeight; + } + System.out.println("patch=["+patchX+","+patchY+","+patchW+","+patchH+"]"); + break; + } + localAction = action; + if (action != DIE) + action = SLEEP; + } + + /* In the redraw case: + * pW, pH, pX, pY, localPageW, localPageH are now all set + * in local variables, and we are safe from the global vars + * being altered in calls from other threads. This is all + * the information we need to actually do our render. + */ + switch (localAction) + { + case GOTOPAGE: + core.gotoPage(localActionPageNum); + scalePageToScreen(); + action = REDRAW; + break; + case REDRAW: + if ((bitmap == null) || + (bitmap.getWidth() != patchW) || + (bitmap.getHeight() != patchH)) + { + /* make bitmap of required size */ + bitmap = Bitmap.createBitmap(patchW, patchH, Bitmap.Config.ARGB_8888); + } + System.out.println("Calling redraw native method"); + core.drawPage(bitmap, localPageW, localPageH, patchX, patchY, patchW, patchH); + System.out.println("Called native method"); + { + Canvas c = null; + try + { + c = holder.lockCanvas(null); + synchronized(holder) + { + if (localScreenGeneration == screenGeneration) + { + doDraw(c); + } + else + { + /* Someone has changed the screen + * under us! Better redraw again... + */ + action = REDRAW; + } + } + } + finally + { + if (c != null) + holder.unlockCanvasAndPost(c); + } + } + } + } + } + + protected void doDraw(Canvas canvas) + { + if ((canvas == null) || (bitmap == null)) + return; + /* Clear the screen */ + canvas.drawRGB(128,128,128); + /* Draw our bitmap on top */ + System.out.println("Blitting bitmap from "+srcRect.left+","+srcRect.top+","+srcRect.right+","+srcRect.bottom+" to "+dstRect.left+","+dstRect.top+","+dstRect.right+","+dstRect.bottom); + canvas.drawBitmap(bitmap, srcRect, dstRect, (Paint)null); + } + } } |