summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2013-02-03 15:21:02 +0000
committerPaul Gardiner <paulg.artifex@glidos.net>2013-02-03 15:21:02 +0000
commit340bb21f4982d7b6dab8236f8996c86cf2d5a4e2 (patch)
treed6bc0fb35d89b99de871f3b416ea8c6ab7703b77
parentef66c129e2451d4d929c21339fa6c36f9ece1a37 (diff)
downloadmupdf-340bb21f4982d7b6dab8236f8996c86cf2d5a4e2.tar.xz
Android: first attempt at reflow mode
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFActivity.java14
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFCore.java4
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java46
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFReflowView.java130
-rw-r--r--android/src/com/artifex/mupdfdemo/ReaderView.java25
5 files changed, 216 insertions, 3 deletions
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFActivity.java b/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
index f432c734..61b24170 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
@@ -122,6 +122,7 @@ public class MuPDFActivity extends Activity
private boolean mSelecting = false;
private final Handler mHandler = new Handler();
private boolean mAlertsActive= false;
+ private boolean mReflow = false;
private AsyncTask<Void,Void,MuPDFAlert> mAlertTask;
private AlertDialog mAlertDialog;
@@ -589,7 +590,8 @@ public class MuPDFActivity extends Activity
// Activate the search-preparing button
mSearchButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
- searchModeOn();
+ //searchModeOn();
+ toggleReflow();
}
});
@@ -794,6 +796,16 @@ public class MuPDFActivity extends Activity
return mycore;
}
+ private void toggleReflow() {
+ mReflow = !mReflow;
+ if (mReflow) {
+ mDocView.setAdapter(new MuPDFReflowAdapter(this, core));
+ } else {
+ mDocView.setAdapter(new MuPDFPageAdapter(this, core));
+ }
+ mDocView.refresh(mReflow);
+ }
+
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFCore.java b/android/src/com/artifex/mupdfdemo/MuPDFCore.java
index 6d4e5b67..356fd31d 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFCore.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFCore.java
@@ -205,7 +205,7 @@ public class MuPDFCore
TextChar[][][][] chars = text();
String res = new String();
- res += "<html><body>";
+ res += "<html><body><div>";
boolean first = true;
for (TextChar[][][] bl: chars) {
@@ -225,7 +225,7 @@ public class MuPDFCore
}
}
- res += "</body></html>";
+ res += "</div></body></html>";
return res;
}
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java b/android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java
new file mode 100644
index 00000000..5e90be92
--- /dev/null
+++ b/android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java
@@ -0,0 +1,46 @@
+package com.artifex.mupdfdemo;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+public class MuPDFReflowAdapter extends BaseAdapter {
+ private final Context mContext;
+ private final MuPDFCore mCore;
+
+ public MuPDFReflowAdapter(Context c, MuPDFCore core) {
+ mContext = c;
+ mCore = core;
+ }
+
+ public int getCount() {
+ return mCore.countPages();
+ }
+
+ public Object getItem(int arg0) {
+ return null;
+ }
+
+ public long getItemId(int arg0) {
+ return 0;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final MuPDFReflowView reflowView;
+ // Should reuse old views if possible, but WebViews seem to refuse to
+ // decrease height even when new content is loaded, so create a new view
+ // each time as a workaround
+ if (true || convertView == null) {
+ reflowView = new MuPDFReflowView(mContext, mCore, new Point(parent.getWidth(), parent.getHeight()));
+ } else {
+ reflowView = (MuPDFReflowView) convertView;
+ }
+
+ reflowView.setPage(position, new PointF());
+
+ return reflowView;
+ }
+}
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java b/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java
new file mode 100644
index 00000000..450f2c53
--- /dev/null
+++ b/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java
@@ -0,0 +1,130 @@
+package com.artifex.mupdfdemo;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.view.MotionEvent;
+import android.view.View;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+public class MuPDFReflowView extends WebView implements MuPDFView {
+ private final MuPDFCore mCore;
+ private final Point mParentSize;
+ private int mPage;
+ private int mContentHeight;
+ AsyncTask<Void,Void,String> mLoadHTML;
+
+ public MuPDFReflowView(Context c, MuPDFCore core, Point parentSize) {
+ super(c);
+ mCore = core;
+ mParentSize = parentSize;
+ mContentHeight = parentSize.y;
+ }
+
+ public void setPage(int page, PointF size) {
+ mPage = page;
+ getSettings().setJavaScriptEnabled(true);
+ addJavascriptInterface(new Object(){
+ public void reportContentHeight(String value) {
+ mContentHeight = (int)Float.parseFloat(value);
+ }
+ }, "HTMLOUT");
+ setWebViewClient(new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ // Get the webview to report the content height via the interface setup
+ // above. Workaround for getContentHeight not working
+ view.loadUrl("javascript:elem=document.getElementsByTagName('html')[0];window.HTMLOUT.reportContentHeight("+mParentSize.x+"*elem.offsetHeight/elem.offsetWidth)");
+ }
+ });
+ mLoadHTML = new AsyncTask<Void,Void,String>() {
+ @Override
+ protected String doInBackground(Void... params) {
+ return mCore.html(mPage);
+ }
+ @Override
+ protected void onPostExecute(String result) {
+ loadData(result, "text/html", null);
+ }
+ };
+ mLoadHTML.execute();
+ }
+
+ public int getPage() {
+ return mPage;
+ }
+
+ public void blank(int page) {
+ }
+
+ public boolean passClickEvent(float x, float y) {
+ return false;
+ }
+
+ public LinkInfo hitLink(float x, float y) {
+ return null;
+ }
+
+ public void selectText(float x0, float y0, float x1, float y1) {
+ }
+
+ public void deselectText() {
+ }
+
+ public boolean copySelection() {
+ return false;
+ }
+
+ public void strikeOutSelection() {
+ }
+
+ public void setSearchBoxes(RectF[] searchBoxes) {
+ }
+
+ public void setLinkHighlighting(boolean f) {
+ }
+
+ public void setChangeReporter(Runnable reporter) {
+ }
+
+ public void update() {
+ }
+
+ public void addHq(boolean update) {
+ }
+
+ public void removeHq() {
+ }
+
+ public void releaseResources() {
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int x, y;
+ switch(View.MeasureSpec.getMode(widthMeasureSpec)) {
+ case View.MeasureSpec.UNSPECIFIED:
+ x = mParentSize.x;
+ break;
+ default:
+ x = View.MeasureSpec.getSize(widthMeasureSpec);
+ }
+ switch(View.MeasureSpec.getMode(heightMeasureSpec)) {
+ case View.MeasureSpec.UNSPECIFIED:
+ y = mContentHeight;
+ break;
+ default:
+ y = View.MeasureSpec.getSize(heightMeasureSpec);
+ }
+
+ setMeasuredDimension(x, y);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+}
diff --git a/android/src/com/artifex/mupdfdemo/ReaderView.java b/android/src/com/artifex/mupdfdemo/ReaderView.java
index 1ef8db70..78eef71c 100644
--- a/android/src/com/artifex/mupdfdemo/ReaderView.java
+++ b/android/src/com/artifex/mupdfdemo/ReaderView.java
@@ -7,6 +7,7 @@ import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.SparseArray;
import android.view.GestureDetector;
import android.view.MotionEvent;
@@ -46,6 +47,7 @@ public class ReaderView extends AdapterView<Adapter>
private float mScale = 1.0f;
private int mXScroll; // Scroll amounts recorded from events.
private int mYScroll; // and then accounted for in onLayout
+ private boolean mReflow = false;
private final GestureDetector
mGestureDetector;
private final ScaleGestureDetector
@@ -286,6 +288,23 @@ public class ReaderView extends AdapterView<Adapter>
mapper.applyToView(mChildViews.valueAt(i));
}
+ public void refresh(boolean reflow) {
+ mReflow = reflow;
+
+ mXScroll = mYScroll = 0;
+
+ int numChildren = mChildViews.size();
+ for (int i = 0; i < numChildren; i++) {
+ View v = mChildViews.valueAt(i);
+ onNotInUse(v);
+ removeViewInLayout(v);
+ }
+ mChildViews.clear();
+ mViewCache.clear();
+
+ requestLayout();
+ }
+
protected void onChildSetup(int i, View v) {}
protected void onMoveToChild(int i) {}
@@ -662,12 +681,18 @@ public class ReaderView extends AdapterView<Adapter>
private void measureView(View v) {
// See what size the view wants to be
v.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+
+ if (!mReflow) {
// Work out a scale that will fit it to this view
float scale = Math.min((float)getWidth()/(float)v.getMeasuredWidth(),
(float)getHeight()/(float)v.getMeasuredHeight());
// Use the fitting values scaled by our current scale factor
v.measure(View.MeasureSpec.EXACTLY | (int)(v.getMeasuredWidth()*scale*mScale),
View.MeasureSpec.EXACTLY | (int)(v.getMeasuredHeight()*scale*mScale));
+ } else {
+ v.measure(View.MeasureSpec.EXACTLY | (int)(v.getMeasuredWidth()),
+ View.MeasureSpec.EXACTLY | (int)(v.getMeasuredHeight()));
+ }
}
private Rect getScrollBounds(int left, int top, int right, int bottom) {