summaryrefslogtreecommitdiff
path: root/android/src
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2013-03-25 12:59:54 +0000
committerPaul Gardiner <paulg.artifex@glidos.net>2013-03-25 12:59:54 +0000
commit199abe0069381d79fc34c86268e408083ad18397 (patch)
tree0dbefb3a08a5d44dae2d5e98635241a7224b231d /android/src
parent41f10c71dbae05fb538f51a495ef7aaa1861fd5d (diff)
downloadmupdf-199abe0069381d79fc34c86268e408083ad18397.tar.xz
Android: add support for Ink annotation creation
Diffstat (limited to 'android/src')
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFActivity.java78
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFCore.java6
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFPageView.java32
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFReaderView.java10
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFReflowView.java12
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFView.java4
-rw-r--r--android/src/com/artifex/mupdfdemo/PageView.java69
7 files changed, 204 insertions, 7 deletions
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFActivity.java b/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
index 01783ede..90e55887 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
@@ -28,6 +28,7 @@ import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
@@ -44,7 +45,7 @@ class ThreadPerTaskExecutor implements Executor {
public class MuPDFActivity extends Activity
{
/* The core rendering instance */
- enum TopBarMode {Main, Search, Text, Annotation};
+ enum TopBarMode {Main, Search, Text, AnnotSelect, AnnotCreate, InkCreate};
private MuPDFCore core;
private String mFileName;
@@ -68,6 +69,12 @@ public class MuPDFActivity extends Activity
private ImageButton mCancelButton;
private ImageButton mOutlineButton;
private ImageButton mDeleteButton;
+ private ImageButton mCancelDeleteButton;
+ private ImageButton mAnnotButton;
+ private ImageButton mCancelAnnotButton;
+ private ImageButton mInkButton;
+ private Button mSaveInkButton;
+ private ImageButton mCancelInkButton;
private ViewAnimator mTopBarSwitcher;
private ImageButton mLinkButton;
private TopBarMode mTopBarMode;
@@ -402,12 +409,12 @@ public class MuPDFActivity extends Activity
switch (item) {
case Annotation:
showButtons();
- mTopBarMode = TopBarMode.Annotation;
+ mTopBarMode = TopBarMode.AnnotSelect;
mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
break;
case Widget:
case Nothing:
- if (mTopBarMode == TopBarMode.Annotation) {
+ if (mTopBarMode == TopBarMode.AnnotSelect) {
mTopBarMode = TopBarMode.Main;
mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
}
@@ -468,6 +475,13 @@ public class MuPDFActivity extends Activity
}
});
+ mAnnotButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mTopBarMode = TopBarMode.AnnotCreate;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ });
+
// Activate the select button
mSelectButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
@@ -483,6 +497,58 @@ public class MuPDFActivity extends Activity
if (pageView != null)
pageView.deselectText();
mDocView.setMode(MuPDFReaderView.Mode.Viewing);
+ mTopBarMode = TopBarMode.AnnotCreate;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ });
+
+ mInkButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mDocView.setMode(MuPDFReaderView.Mode.Drawing);
+ mTopBarMode = TopBarMode.InkCreate;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ });
+
+ mCancelInkButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null)
+ pageView.cancelDraw();
+ mDocView.setMode(MuPDFReaderView.Mode.Viewing);
+ mTopBarMode = TopBarMode.AnnotCreate;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ });
+
+ mSaveInkButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null)
+ pageView.saveDraw();
+ mDocView.setMode(MuPDFReaderView.Mode.Viewing);
+ mTopBarMode = TopBarMode.Main;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ });
+
+ mCancelDeleteButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null)
+ pageView.deselectAnnotation();
+ mDocView.setMode(MuPDFReaderView.Mode.Viewing);
+ mTopBarMode = TopBarMode.Main;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ });
+
+ mCancelAnnotButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null)
+ pageView.deselectText();
+ mDocView.setMode(MuPDFReaderView.Mode.Viewing);
mTopBarMode = TopBarMode.Main;
mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
}
@@ -897,6 +963,12 @@ public class MuPDFActivity extends Activity
mCancelButton = (ImageButton)mButtonsView.findViewById(R.id.cancel);
mOutlineButton = (ImageButton)mButtonsView.findViewById(R.id.outlineButton);
mDeleteButton = (ImageButton)mButtonsView.findViewById(R.id.deleteButton);
+ mCancelDeleteButton = (ImageButton)mButtonsView.findViewById(R.id.cancelDeleteButton);
+ mAnnotButton = (ImageButton)mButtonsView.findViewById(R.id.annotButton);
+ mCancelAnnotButton = (ImageButton)mButtonsView.findViewById(R.id.cancelAnnotButton);
+ mInkButton = (ImageButton)mButtonsView.findViewById(R.id.inkButton);
+ mSaveInkButton = (Button)mButtonsView.findViewById(R.id.saveInkButton);
+ mCancelInkButton = (ImageButton)mButtonsView.findViewById(R.id.cancelInkButton);
mTopBarSwitcher = (ViewAnimator)mButtonsView.findViewById(R.id.switcher);
mSearchBack = (ImageButton)mButtonsView.findViewById(R.id.searchBack);
mSearchFwd = (ImageButton)mButtonsView.findViewById(R.id.searchForward);
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFCore.java b/android/src/com/artifex/mupdfdemo/MuPDFCore.java
index 424e3536..2443784a 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFCore.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFCore.java
@@ -40,6 +40,7 @@ public class MuPDFCore
private native TextChar[][][][] text();
private native byte[] textAsHtml();
private native void addMarkupAnnotationInternal(PointF[] quadPoints, int type);
+ private native void addInkAnnotationInternal(PointF[][] arcs);
private native void deleteAnnotationInternal(int annot_index);
private native int passClickEventInternal(int page, float x, float y);
private native void setFocusedWidgetChoiceSelectedInternal(String [] selected);
@@ -253,6 +254,11 @@ public class MuPDFCore
addMarkupAnnotationInternal(quadPoints, type.ordinal());
}
+ public synchronized void addInkAnnotation(int page, PointF[][] arcs) {
+ gotoPage(page);
+ addInkAnnotationInternal(arcs);
+ }
+
public synchronized void deleteAnnotation(int page, int annot_index) {
gotoPage(page);
deleteAnnotationInternal(annot_index);
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFPageView.java b/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
index 06c3827a..69f038bb 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
@@ -59,8 +59,6 @@ class PassClickResultChoice extends PassClickResult {
}
public class MuPDFPageView extends PageView implements MuPDFView {
- private static final float LINE_THICKNESS = 0.07f;
- private static final float STRIKE_HEIGHT = 0.375f;
private final MuPDFCore mCore;
private AsyncTask<Void,Void,PassClickResult> mPassClick;
private RectF mWidgetAreas[];
@@ -75,6 +73,7 @@ public class MuPDFPageView extends PageView implements MuPDFView {
private AsyncTask<String,Void,Boolean> mSetWidgetText;
private AsyncTask<String,Void,Void> mSetWidgetChoice;
private AsyncTask<PointF[],Void,Void> mAddStrikeOut;
+ private AsyncTask<PointF[][],Void,Void> mAddInk;
private AsyncTask<Integer,Void,Void> mDeleteAnnotation;
private Runnable changeReporter;
@@ -185,6 +184,7 @@ public class MuPDFPageView extends PageView implements MuPDFView {
case UNDERLINE:
case SQUIGGLY:
case STRIKEOUT:
+ case INK:
mSelectedAnnotationIndex = i;
setItemSelectBox(mAnnotations[i]);
return Hit.Annotation;
@@ -357,6 +357,34 @@ public class MuPDFPageView extends PageView implements MuPDFView {
setItemSelectBox(null);
}
+ public void saveDraw() {
+ PointF[][] path = getDraw();
+
+ if (path != null) {
+ if (mAddInk != null) {
+ mAddInk.cancel(true);
+ mAddInk = null;
+ }
+ mAddInk = new AsyncTask<PointF[][],Void,Void>() {
+ @Override
+ protected Void doInBackground(PointF[][]... params) {
+ mCore.addInkAnnotation(mPageNumber, params[0]);
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ loadAnnotations();
+ update();
+ }
+
+ };
+
+ mAddInk.execute(getDraw());
+ cancelDraw();
+ }
+ }
+
@Override
protected Bitmap drawPage(int sizeX, int sizeY,
int patchX, int patchY, int patchWidth, int patchHeight) {
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java b/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java
index 6ddb69da..0aa1909b 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java
@@ -95,15 +95,20 @@ public class MuPDFReaderView extends ReaderView {
}
@Override
- public void onShowPress(MotionEvent e) {
+ public boolean onDown(MotionEvent e) {
switch (mMode) {
case Drawing:
+ MuPDFView pageView = (MuPDFView)getDisplayedView();
+ if (pageView != null)
+ pageView.startDraw(e.getX(), e.getY());
break;
}
+ return super.onDown(e);
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
+ MuPDFView pageView = (MuPDFView)getDisplayedView();
switch (mMode) {
case Viewing:
if (!tapDisabled)
@@ -111,11 +116,12 @@ public class MuPDFReaderView extends ReaderView {
return super.onScroll(e1, e2, distanceX, distanceY);
case Selecting:
- MuPDFView pageView = (MuPDFView)getDisplayedView();
if (pageView != null)
pageView.selectText(e1.getX(), e1.getY(), e2.getX(), e2.getY());
return true;
case Drawing:
+ if (pageView != null)
+ pageView.continueDraw(e2.getX(), e2.getY());
return true;
default:
return true;
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java b/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java
index 1a2f1d91..9200982a 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java
@@ -103,6 +103,18 @@ public class MuPDFReflowView extends WebView implements MuPDFView {
return false;
}
+ public void startDraw(float x, float y) {
+ }
+
+ public void continueDraw(float x, float y) {
+ }
+
+ public void cancelDraw() {
+ }
+
+ public void saveDraw() {
+ }
+
public void setSearchBoxes(RectF[] searchBoxes) {
}
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFView.java b/android/src/com/artifex/mupdfdemo/MuPDFView.java
index 5f7f19e0..5731945d 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFView.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFView.java
@@ -20,6 +20,10 @@ public interface MuPDFView {
public void setSearchBoxes(RectF searchBoxes[]);
public void setLinkHighlighting(boolean f);
public void deselectAnnotation();
+ public void startDraw(float x, float y);
+ public void continueDraw(float x, float y);
+ public void cancelDraw();
+ public void saveDraw();
public void setChangeReporter(Runnable reporter);
public void update();
public void addHq(boolean update);
diff --git a/android/src/com/artifex/mupdfdemo/PageView.java b/android/src/com/artifex/mupdfdemo/PageView.java
index 3eb1e5a3..756ee2f5 100644
--- a/android/src/com/artifex/mupdfdemo/PageView.java
+++ b/android/src/com/artifex/mupdfdemo/PageView.java
@@ -7,6 +7,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -102,6 +103,8 @@ public abstract class PageView extends ViewGroup {
private static final int HIGHLIGHT_COLOR = 0x802572AC;
private static final int LINK_COLOR = 0x80AC7225;
private static final int BOX_COLOR = 0xFF4444FF;
+ private static final int INK_COLOR = 0xFFFF0000;
+ private static final float INK_THICKNESS = 10.0f;
private static final int BACKGROUND_COLOR = 0xFFFFFFFF;
private static final int PROGRESS_DIALOG_DELAY = 200;
protected final Context mContext;
@@ -126,6 +129,7 @@ public abstract class PageView extends ViewGroup {
private RectF mSelectBox;
private TextWord mText[][];
private RectF mItemSelectBox;
+ protected ArrayList<ArrayList<PointF>> mDrawing;
private View mSearchView;
private boolean mIsBlank;
private boolean mHighlightLinks;
@@ -346,6 +350,28 @@ public abstract class PageView extends ViewGroup {
paint.setColor(BOX_COLOR);
canvas.drawRect(mItemSelectBox.left*scale, mItemSelectBox.top*scale, mItemSelectBox.right*scale, mItemSelectBox.bottom*scale, paint);
}
+
+ if (mDrawing != null) {
+ Path path = new Path();
+ PointF p;
+ Iterator<ArrayList<PointF>> it = mDrawing.iterator();
+ while (it.hasNext()) {
+ ArrayList<PointF> arc = it.next();
+ if (arc.size() >= 2) {
+ Iterator<PointF> iit = arc.iterator();
+ p = iit.next();
+ path.moveTo(p.x*scale, p.y*scale);
+ while (iit.hasNext()) {
+ p = iit.next();
+ path.lineTo(p.x*scale, p.y*scale);
+ }
+ }
+ }
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeWidth(INK_THICKNESS*scale);
+ paint.setColor(INK_COLOR);
+ canvas.drawPath(path, paint);
+ }
}
};
@@ -402,6 +428,49 @@ public abstract class PageView extends ViewGroup {
}
}
+ public void startDraw(float x, float y) {
+ float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ float docRelX = (x - getLeft())/scale;
+ float docRelY = (y - getTop())/scale;
+ if (mDrawing == null)
+ mDrawing = new ArrayList<ArrayList<PointF>>();
+
+ ArrayList<PointF> arc = new ArrayList<PointF>();
+ arc.add(new PointF(docRelX, docRelY));
+ mDrawing.add(arc);
+ }
+
+ public void continueDraw(float x, float y) {
+ float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ float docRelX = (x - getLeft())/scale;
+ float docRelY = (y - getTop())/scale;
+
+ if (mDrawing != null && mDrawing.size() > 0) {
+ ArrayList<PointF> arc = mDrawing.get(mDrawing.size() - 1);
+ arc.add(new PointF(docRelX, docRelY));
+ mSearchView.invalidate();
+ }
+ }
+
+ public void cancelDraw() {
+ mDrawing = null;
+ mSearchView.invalidate();
+ }
+
+ protected PointF[][] getDraw() {
+ if (mDrawing == null)
+ return null;
+
+ PointF[][] path = new PointF[mDrawing.size()][];
+
+ for (int i = 0; i < mDrawing.size(); i++) {
+ ArrayList<PointF> arc = mDrawing.get(i);
+ path[i] = arc.toArray(new PointF[arc.size()]);
+ }
+
+ return path;
+ }
+
protected void processSelectedText(TextProcessor tp) {
(new TextSelector(mText, mSelectBox)).select(tp);
}