diff options
author | Paul Gardiner <paulg.artifex@glidos.net> | 2013-02-03 15:21:02 +0000 |
---|---|---|
committer | Paul Gardiner <paulg.artifex@glidos.net> | 2013-02-03 15:21:02 +0000 |
commit | 340bb21f4982d7b6dab8236f8996c86cf2d5a4e2 (patch) | |
tree | d6bc0fb35d89b99de871f3b416ea8c6ab7703b77 | |
parent | ef66c129e2451d4d929c21339fa6c36f9ece1a37 (diff) | |
download | mupdf-340bb21f4982d7b6dab8236f8996c86cf2d5a4e2.tar.xz |
Android: first attempt at reflow mode
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) { |