diff options
Diffstat (limited to 'android')
-rw-r--r-- | android/res/drawable-ldpi/ic_select.png | bin | 0 -> 247 bytes | |||
-rw-r--r-- | android/res/drawable-mdpi/ic_select.png | bin | 0 -> 280 bytes | |||
-rw-r--r-- | android/res/layout/buttons.xml | 12 | ||||
-rw-r--r-- | android/res/values/strings.xml | 1 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/MuPDFActivity.java | 36 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/MuPDFPageView.java | 5 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/PageView.java | 118 |
7 files changed, 141 insertions, 31 deletions
diff --git a/android/res/drawable-ldpi/ic_select.png b/android/res/drawable-ldpi/ic_select.png Binary files differnew file mode 100644 index 00000000..81af6738 --- /dev/null +++ b/android/res/drawable-ldpi/ic_select.png diff --git a/android/res/drawable-mdpi/ic_select.png b/android/res/drawable-mdpi/ic_select.png Binary files differnew file mode 100644 index 00000000..9eaf6924 --- /dev/null +++ b/android/res/drawable-mdpi/ic_select.png diff --git a/android/res/layout/buttons.xml b/android/res/layout/buttons.xml index 642e6e6a..c8c95153 100644 --- a/android/res/layout/buttons.xml +++ b/android/res/layout/buttons.xml @@ -35,12 +35,22 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_toLeftOf="@+id/outlineButton" + android:layout_toLeftOf="@+id/selectButton" android:contentDescription="@string/link_control" android:background="@drawable/button" android:src="@drawable/ic_link" /> <ImageButton + android:id="@+id/selectButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_toLeftOf="@+id/outlineButton" + android:contentDescription="@string/select" + android:background="@drawable/button" + android:src="@drawable/ic_select" /> + + <ImageButton android:id="@+id/outlineButton" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 729b5445..2022e3eb 100644 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -16,4 +16,5 @@ <string name="searching_">Searching...</string> <string name="link_control">Link highlighting and enabling</string> <string name="no_further_occurences_found">No further occurences found</string> + <string name="select">Select</string> </resources> diff --git a/android/src/com/artifex/mupdf/MuPDFActivity.java b/android/src/com/artifex/mupdf/MuPDFActivity.java index 0c35cadf..d083fc60 100644 --- a/android/src/com/artifex/mupdf/MuPDFActivity.java +++ b/android/src/com/artifex/mupdf/MuPDFActivity.java @@ -11,6 +11,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.Color; +import android.graphics.PorterDuff; import android.graphics.RectF; import android.net.Uri; import android.os.Bundle; @@ -95,6 +96,7 @@ public class MuPDFActivity extends Activity private int mPageSliderRes; private TextView mPageNumberView; private ImageButton mSearchButton; + private ImageButton mSelectButton; private ImageButton mCancelButton; private ImageButton mOutlineButton; private ViewSwitcher mTopBarSwitcher; @@ -107,6 +109,7 @@ public class MuPDFActivity extends Activity //private SearchTaskResult mSearchTaskResult; private AlertDialog.Builder mAlertBuilder; private boolean mLinkHighlight = false; + private boolean mSelecting = false; private final Handler mHandler = new Handler(); private boolean mAlertsActive= false; private AsyncTask<Void,Void,MuPDFAlert> mAlertTask; @@ -343,7 +346,7 @@ public class MuPDFActivity extends Activity private boolean showButtonsDisabled; public boolean onSingleTapUp(MotionEvent e) { - if (!showButtonsDisabled) { + if (!mSelecting && !showButtonsDisabled) { MuPDFPageView pageView = (MuPDFPageView) mDocView.getDisplayedView(); if (MuPDFCore.javascriptSupported() && pageView.passClickEvent(e.getX(), e.getY())) { // If the page consumes the event do nothing else @@ -385,10 +388,26 @@ public class MuPDFActivity extends Activity } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - if (!showButtonsDisabled) - hideButtons(); + if (!mSelecting) { + if (!showButtonsDisabled) + hideButtons(); - return super.onScroll(e1, e2, distanceX, distanceY); + return super.onScroll(e1, e2, distanceX, distanceY); + } else { + MuPDFPageView pageView = (MuPDFPageView) mDocView.getDisplayedView(); + if (pageView != null) + pageView.selectText(e1.getX(), e1.getY(), e2.getX(), e2.getY()); + return true; + } + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, + float velocityX, float velocityY) { + if (!mSelecting) + return super.onFling(e1, e2, velocityX, velocityY); + else + return true; } public boolean onScaleBegin(ScaleGestureDetector d) { @@ -489,6 +508,14 @@ public class MuPDFActivity extends Activity } }); + // Activate the select button + mSelectButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + mSelecting = !mSelecting; + mSelectButton.setColorFilter(Color.WHITE, mSelecting?PorterDuff.Mode.XOR: PorterDuff.Mode.DST); + } + }); + mCancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { searchModeOff(); @@ -776,6 +803,7 @@ public class MuPDFActivity extends Activity mPageSlider = (SeekBar)mButtonsView.findViewById(R.id.pageSlider); mPageNumberView = (TextView)mButtonsView.findViewById(R.id.pageNumber); mSearchButton = (ImageButton)mButtonsView.findViewById(R.id.searchButton); + mSelectButton = (ImageButton)mButtonsView.findViewById(R.id.selectButton); mCancelButton = (ImageButton)mButtonsView.findViewById(R.id.cancel); mOutlineButton = (ImageButton)mButtonsView.findViewById(R.id.outlineButton); mTopBarSwitcher = (ViewSwitcher)mButtonsView.findViewById(R.id.switcher); diff --git a/android/src/com/artifex/mupdf/MuPDFPageView.java b/android/src/com/artifex/mupdf/MuPDFPageView.java index 68031837..8360ba09 100644 --- a/android/src/com/artifex/mupdf/MuPDFPageView.java +++ b/android/src/com/artifex/mupdf/MuPDFPageView.java @@ -217,6 +217,11 @@ public class MuPDFPageView extends PageView { } @Override + protected TextWord[][] getText() { + return mCore.textLines(mPageNumber); + } + + @Override public void setPage(final int page, PointF size) { mLoadWidgetAreas = new AsyncTask<Void,Void,RectF[]> () { @Override diff --git a/android/src/com/artifex/mupdf/PageView.java b/android/src/com/artifex/mupdf/PageView.java index bdbed438..e45aff83 100644 --- a/android/src/com/artifex/mupdf/PageView.java +++ b/android/src/com/artifex/mupdf/PageView.java @@ -1,5 +1,8 @@ package com.artifex.mupdf; +import java.util.ArrayList; +import java.util.Iterator; + import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; @@ -53,6 +56,7 @@ public abstract class PageView extends ViewGroup { private ImageView mEntire; // Image rendered at minimum zoom private BitmapHolder mEntireBm; + private AsyncTask<Void,Void,TextWord[][]> mGetText; private AsyncTask<Void,Void,LinkInfo[]> mGetLinkInfo; private AsyncTask<Void,Void,Void> mDrawEntire; @@ -63,6 +67,8 @@ public abstract class PageView extends ViewGroup { private AsyncTask<PatchInfo,Void,PatchInfo> mDrawPatch; private RectF mSearchBoxes[]; protected LinkInfo mLinks[]; + private RectF mSelectBox; + private TextWord mText[][]; private View mSearchView; private boolean mIsBlank; private boolean mHighlightLinks; @@ -82,8 +88,9 @@ public abstract class PageView extends ViewGroup { protected abstract void drawPage(BitmapHolder h, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); protected abstract void updatePage(BitmapHolder h, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); protected abstract LinkInfo[] getLinkInfo(); + protected abstract TextWord[][] getText(); - public void releaseResources() { + private void reinit() { // Cancel pending render task if (mDrawEntire != null) { mDrawEntire.cancel(true); @@ -95,6 +102,16 @@ public abstract class PageView extends ViewGroup { mDrawPatch = null; } + if (mGetLinkInfo != null) { + mGetLinkInfo.cancel(true); + mGetLinkInfo = null; + } + + if (mGetText != null) { + mGetText.cancel(true); + mGetText = null; + } + mIsBlank = true; mPageNumber = 0; @@ -111,6 +128,15 @@ public abstract class PageView extends ViewGroup { mPatch.setImageBitmap(null); } + mSearchBoxes = null; + mLinks = null; + mSelectBox = null; + mText = null; + } + + public void releaseResources() { + reinit(); + if (mBusyIndicator != null) { removeView(mBusyIndicator); mBusyIndicator = null; @@ -118,33 +144,9 @@ public abstract class PageView extends ViewGroup { } public void blank(int page) { - // Cancel pending render task - if (mDrawEntire != null) { - mDrawEntire.cancel(true); - mDrawEntire = null; - } - - if (mDrawPatch != null) { - mDrawPatch.cancel(true); - mDrawPatch = null; - } - - mIsBlank = true; + reinit(); mPageNumber = page; - if (mSize == null) - mSize = mParentSize; - - if (mEntire != null) { - mEntireBm.setBm(null); - mEntire.setImageBitmap(null); - } - - if (mPatch != null) { - mPatchBm.setBm(null); - mPatch.setImageBitmap(null); - } - if (mBusyIndicator == null) { mBusyIndicator = new ProgressBar(mContext); mBusyIndicator.setIndeterminate(true); @@ -255,6 +257,41 @@ public abstract class PageView extends ViewGroup { link.rect.right*scale, link.rect.bottom*scale, paint); } + + if (mSelectBox != null && mText != null) { + paint.setColor(HIGHLIGHT_COLOR); + + ArrayList<TextWord[]> lines = new ArrayList<TextWord[]>(); + for (TextWord[] line : mText) + if (line[0].bottom > mSelectBox.top && line[0].top < mSelectBox.bottom) + lines.add(line); + + Iterator<TextWord[]> it = lines.iterator(); + while (it.hasNext()) { + TextWord[] line = it.next(); + boolean startLine = line[0].top < mSelectBox.top; + boolean endLine = line[0].bottom > mSelectBox.bottom; + float start = Float.NEGATIVE_INFINITY; + float end = Float.POSITIVE_INFINITY; + + if (startLine && endLine) { + start = Math.min(mSelectBox.left, mSelectBox.right); + end = Math.max(mSelectBox.left, mSelectBox.right); + } else if (startLine) { + start = mSelectBox.left; + } else if (endLine) { + end = mSelectBox.right; + } + + RectF rect = new RectF(); + for (TextWord word : line) + if (word.right > start && word.left < end) + rect.union(word); + + if (!rect.isEmpty()) + canvas.drawRect(rect.left*scale, rect.top*scale, rect.right*scale, rect.bottom*scale, paint); + } + } } }; @@ -275,6 +312,35 @@ public abstract class PageView extends ViewGroup { mSearchView.invalidate(); } + public void selectText(float x0, float y0, float x1, float y1) { + float scale = mSourceScale*(float)getWidth()/(float)mSize.x; + float docRelX0 = (x0 - getLeft())/scale; + float docRelY0 = (y0 - getTop())/scale; + float docRelX1 = (x1 - getLeft())/scale; + float docRelY1 = (y1 - getTop())/scale; + // Order on Y but maintain the point grouping + if (docRelY0 <= docRelY1) + mSelectBox = new RectF(docRelX0, docRelY0, docRelX1, docRelY1); + else + mSelectBox = new RectF(docRelX1, docRelY1, docRelX0, docRelY0); + + if (mText == null) { + mGetText = new AsyncTask<Void,Void,TextWord[][]>() { + @Override + protected TextWord[][] doInBackground(Void... params) { + return getText(); + } + @Override + protected void onPostExecute(TextWord[][] result) { + mText = result; + mSearchView.invalidate(); + } + }; + + mGetText.execute(); + } + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int x, y; |