From 2369a34a21788e3d330d329ca077f7cbaa4571e5 Mon Sep 17 00:00:00 2001 From: fred ross-perry Date: Thu, 1 Sep 2016 10:28:20 -0700 Subject: Android example - Add proofing support. --- .../example/app/src/main/AndroidManifest.xml | 2 +- .../example/mupdf/src/main/AndroidManifest.xml | 5 + .../main/assets/profiles/CMYK/CoatedFOGRA39.icc | Bin 0 -> 654352 bytes .../main/assets/profiles/CMYK/EuroscaleCoated.icc | Bin 0 -> 557164 bytes .../main/assets/profiles/CMYK/JapanWebCoated.icc | Bin 0 -> 557164 bytes .../main/assets/profiles/CMYK/USWebCoatedSWOP.icc | Bin 0 -> 557168 bytes .../src/main/assets/profiles/RGB/AdobeRGB1998.icc | Bin 0 -> 560 bytes .../mupdf/src/main/assets/profiles/RGB/CIERGB.icc | Bin 0 -> 552 bytes .../src/main/assets/profiles/RGB/WideGamutRGB.icc | Bin 0 -> 560 bytes .../profiles/RGB/sRGB Color Space Profile.icm | Bin 0 -> 3144 bytes .../com/artifex/mupdf/android/DocActivityView.java | 161 +++++ .../com/artifex/mupdf/android/DocPageView.java | 41 +- .../com/artifex/mupdf/android/DocProofView.java | 116 ++++ .../com/artifex/mupdf/android/DocViewBase.java | 68 ++- .../com/artifex/mupdf/android/ProofActivity.java | 430 ++++++++++++++ .../mupdf/src/main/res/activity_doc_view.xml | 13 + .../mupdf/src/main/res/drawable/color_box.xml | 5 + .../mupdf/src/main/res/drawable/icon_next_page.xml | 24 + .../mupdf/src/main/res/drawable/icon_prev_page.xml | 24 + .../mupdf/src/main/res/drawable/icon_proof.xml | 19 + .../main/res/drawable/icon_proof_colors_down.xml | 648 +++++++++++++++++++++ .../src/main/res/drawable/icon_proof_colors_up.xml | 648 +++++++++++++++++++++ .../mupdf/src/main/res/drawable/rectangle.xml | 4 + .../mupdf/src/main/res/drawable/spinner_back.xml | 5 + .../src/main/res/layout/activity_proof_view.xml | 66 +++ .../mupdf/src/main/res/layout/annotate_toolbar.xml | 3 +- .../example/mupdf/src/main/res/layout/doc_view.xml | 4 + .../mupdf/src/main/res/layout/file_toolbar.xml | 26 + .../src/main/res/layout/proof_color_list_entry.xml | 33 ++ .../mupdf/src/main/res/layout/proof_dialog.xml | 144 +++++ .../mupdf/src/main/res/layout/proof_toolbar.xml | 213 +++++++ .../mupdf/src/main/res/layout/wait_spinner.xml | 14 + .../example/mupdf/src/main/res/values/strings.xml | 40 ++ .../example/mupdf/src/main/res/values/styles.xml | 5 + .../example/mupdf/src/main/res/wait_spinner.xml | 14 + 35 files changed, 2739 insertions(+), 36 deletions(-) create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/CMYK/CoatedFOGRA39.icc create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/CMYK/EuroscaleCoated.icc create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/CMYK/JapanWebCoated.icc create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/CMYK/USWebCoatedSWOP.icc create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/RGB/AdobeRGB1998.icc create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/RGB/CIERGB.icc create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/RGB/WideGamutRGB.icc create mode 100755 platform/android/example/mupdf/src/main/assets/profiles/RGB/sRGB Color Space Profile.icm create mode 100644 platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocProofView.java create mode 100644 platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/ProofActivity.java create mode 100755 platform/android/example/mupdf/src/main/res/activity_doc_view.xml create mode 100644 platform/android/example/mupdf/src/main/res/drawable/color_box.xml create mode 100755 platform/android/example/mupdf/src/main/res/drawable/icon_next_page.xml create mode 100755 platform/android/example/mupdf/src/main/res/drawable/icon_prev_page.xml create mode 100644 platform/android/example/mupdf/src/main/res/drawable/icon_proof.xml create mode 100755 platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_down.xml create mode 100755 platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_up.xml create mode 100644 platform/android/example/mupdf/src/main/res/drawable/rectangle.xml create mode 100644 platform/android/example/mupdf/src/main/res/drawable/spinner_back.xml create mode 100755 platform/android/example/mupdf/src/main/res/layout/activity_proof_view.xml create mode 100644 platform/android/example/mupdf/src/main/res/layout/proof_color_list_entry.xml create mode 100644 platform/android/example/mupdf/src/main/res/layout/proof_dialog.xml create mode 100644 platform/android/example/mupdf/src/main/res/layout/proof_toolbar.xml create mode 100644 platform/android/example/mupdf/src/main/res/layout/wait_spinner.xml create mode 100644 platform/android/example/mupdf/src/main/res/wait_spinner.xml (limited to 'platform/android') diff --git a/platform/android/example/app/src/main/AndroidManifest.xml b/platform/android/example/app/src/main/AndroidManifest.xml index bdd8e804..d88f9e01 100644 --- a/platform/android/example/app/src/main/AndroidManifest.xml +++ b/platform/android/example/app/src/main/AndroidManifest.xml @@ -39,7 +39,7 @@ - + diff --git a/platform/android/example/mupdf/src/main/AndroidManifest.xml b/platform/android/example/mupdf/src/main/AndroidManifest.xml index 4065d7fd..e38f7206 100644 --- a/platform/android/example/mupdf/src/main/AndroidManifest.xml +++ b/platform/android/example/mupdf/src/main/AndroidManifest.xml @@ -6,5 +6,10 @@ android:label="@string/app_name" android:supportsRtl="true" > + + + + diff --git a/platform/android/example/mupdf/src/main/assets/profiles/CMYK/CoatedFOGRA39.icc b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/CoatedFOGRA39.icc new file mode 100755 index 00000000..61cb86a5 Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/CoatedFOGRA39.icc differ diff --git a/platform/android/example/mupdf/src/main/assets/profiles/CMYK/EuroscaleCoated.icc b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/EuroscaleCoated.icc new file mode 100755 index 00000000..78e4bb3c Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/EuroscaleCoated.icc differ diff --git a/platform/android/example/mupdf/src/main/assets/profiles/CMYK/JapanWebCoated.icc b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/JapanWebCoated.icc new file mode 100755 index 00000000..004b8b9d Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/JapanWebCoated.icc differ diff --git a/platform/android/example/mupdf/src/main/assets/profiles/CMYK/USWebCoatedSWOP.icc b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/USWebCoatedSWOP.icc new file mode 100755 index 00000000..078a6443 Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/CMYK/USWebCoatedSWOP.icc differ diff --git a/platform/android/example/mupdf/src/main/assets/profiles/RGB/AdobeRGB1998.icc b/platform/android/example/mupdf/src/main/assets/profiles/RGB/AdobeRGB1998.icc new file mode 100755 index 00000000..a79f576b Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/RGB/AdobeRGB1998.icc differ diff --git a/platform/android/example/mupdf/src/main/assets/profiles/RGB/CIERGB.icc b/platform/android/example/mupdf/src/main/assets/profiles/RGB/CIERGB.icc new file mode 100755 index 00000000..1d99a710 Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/RGB/CIERGB.icc differ diff --git a/platform/android/example/mupdf/src/main/assets/profiles/RGB/WideGamutRGB.icc b/platform/android/example/mupdf/src/main/assets/profiles/RGB/WideGamutRGB.icc new file mode 100755 index 00000000..de37f3cd Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/RGB/WideGamutRGB.icc differ diff --git a/platform/android/example/mupdf/src/main/assets/profiles/RGB/sRGB Color Space Profile.icm b/platform/android/example/mupdf/src/main/assets/profiles/RGB/sRGB Color Space Profile.icm new file mode 100755 index 00000000..7f9d18d0 Binary files /dev/null and b/platform/android/example/mupdf/src/main/assets/profiles/RGB/sRGB Color Space Profile.icm differ diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java index 26624ab5..c305555b 100644 --- a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java +++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java @@ -1,15 +1,19 @@ package com.artifex.mupdf.android; import android.app.Activity; +import android.app.Dialog; import android.content.Context; +import android.content.Intent; import android.graphics.Color; import android.graphics.PorterDuff; +import android.net.Uri; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewTreeObserver; +import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; @@ -18,6 +22,7 @@ import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.Spinner; import android.widget.TabHost; import android.widget.TextView; import android.widget.Toast; @@ -27,6 +32,12 @@ import com.artifex.mupdf.fitz.Link; import com.artifex.mupdf.fitz.Outline; import com.artifex.mupdf.fitz.R; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.UUID; + public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeListener, View.OnClickListener, DocView.SelectionChangeListener { private DocView mDocView; @@ -66,6 +77,8 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL private ImageButton mLineColorButton; private ImageButton mLineThicknessButton; + private ImageButton mProofButton; + public DocActivityView(Context context) { super(context); @@ -341,6 +354,9 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL mOpenInButton = (ImageButton)findViewById(R.id.open_in_button); mOpenInButton.setOnClickListener(this); + mProofButton = (ImageButton)findViewById(R.id.proof_button); + mProofButton.setOnClickListener(this); + // this listener will mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @@ -555,6 +571,10 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL onLineColorButton(); if (v == mLineThicknessButton) onLineThicknessButton(); + + if (v == mProofButton) + onProof(); + } public void onSearchNextButton() @@ -746,6 +766,147 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL } } + private void onProof() + { + proofSetup(); + if (!proofSupported()) + { + Utilities.showMessage((Activity)getContext(), "gprf not supported", "gprf not supported"); + return; + } + + + + + + // show a dialog to collect the resolution and profiles + final Activity activity = (Activity)getContext(); + + final Dialog dialog = new Dialog(activity); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.setContentView(R.layout.proof_dialog); + + final Spinner sp1 = (Spinner)(dialog.findViewById(R.id.print_profile_spinner)); + final Spinner sp2 = (Spinner)(dialog.findViewById(R.id.display_profile_spinner)); + final Spinner sp3 = (Spinner)(dialog.findViewById(R.id.resolution_spinner)); + + dialog.findViewById(R.id.cancel_button).setOnClickListener(new OnClickListener() + { + @Override + public void onClick(View v) + { + // Cancel + dialog.dismiss(); + } + }); + + dialog.findViewById(R.id.ok_button).setOnClickListener(new OnClickListener() + { + @Override + public void onClick(View v) + { + // OK + dialog.dismiss(); + doProof(sp1.getSelectedItemPosition(), sp2.getSelectedItemPosition(), sp3.getSelectedItemPosition()); + + } + }); + + dialog.show(); + } + + private static boolean proofSetupDone = false; + private static boolean proofCodeSupported = false; + private static boolean proofGsLibLoaded = false; + private static void proofSetup() + { + if (proofSetupDone) + return; + + proofCodeSupported = (com.artifex.mupdf.fitz.Context.gprfSupportedNative()==1); + + if (proofCodeSupported) + { + try + { + System.loadLibrary("gs"); + proofGsLibLoaded = true; + } + catch (UnsatisfiedLinkError e) + { + } + } + + proofSetupDone = true; + } + + private static boolean proofSupported() + { + return (proofCodeSupported && proofGsLibLoaded); + } + + private void doProof(int printProfileIndex, int displayProfileIndex, int resolutionIndex) + { + // get the resolution + String[] resolutions = getResources().getStringArray(R.array.proof_resolutions); + String resolutionString = resolutions[resolutionIndex]; + int resolution = Integer.parseInt(resolutionString); + + // get the print profile as a temp file + String[] printProfiles = getResources().getStringArray(R.array.proof_print_profile_files); + String printProfileFile = printProfiles[printProfileIndex]; + String printProfilePath = extractProfileAsset("profiles/CMYK/" + printProfileFile); + + // get the display profile as a temp file + String[] displayProfiles = getResources().getStringArray(R.array.proof_display_profile_files); + String displayProfileFile = displayProfiles[displayProfileIndex]; + String displayProfilePath = extractProfileAsset("profiles/RGB/" + displayProfileFile); + + // what page are we doing? + int thePage = mDocView.getMostVisiblePage(); + + String proofFile = mDocView.getDoc().makeProof(mDocView.getDoc().getPath(), printProfilePath, displayProfilePath, resolution); + + Uri uri = Uri.parse("file://" + proofFile); + Intent intent = new Intent((Activity)getContext(), ProofActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(uri); + // add the current page so it can be found when the activity is running + intent.putExtra("startingPage", thePage); + ((Activity)getContext()).startActivity(intent); + } + + private String extractProfileAsset(String profile) + { + try + { + InputStream inStream = getContext().getAssets().open(profile); + String tempfile = getContext().getExternalCacheDir() + "/shared/" + UUID.randomUUID() + ".profile"; + new File(tempfile).mkdirs(); + Utilities.deleteFile(tempfile); + + FileOutputStream outStream = new FileOutputStream(tempfile); + byte[] buffer = new byte[4096]; // To hold file contents + int bytes_read; // How many bytes in buffer + + // Read a chunk of bytes into the buffer, then write them out, + // looping until we reach the end of the file (when read() returns + // -1). Note the combination of assignment and comparison in this + // while loop. This is a common I/O programming idiom. + while ((bytes_read = inStream.read(buffer)) != -1) + // Read until EOF + outStream.write(buffer, 0, bytes_read); // write + + return tempfile; + } + catch (IOException e) + { + e.printStackTrace(); + } + + return ""; + } + private void onDeleteButton() { mDocView.onDelete(); diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocPageView.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocPageView.java index 0bde1f03..f722da52 100755 --- a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocPageView.java +++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocPageView.java @@ -344,6 +344,11 @@ public class DocPageView extends View implements Callback new RenderTask().execute(params, null, null); } + public void stopRender() + { + // TODO ?? + } + private void cachePage() { Cookie cookie = new Cookie(); @@ -637,10 +642,13 @@ public class DocPageView extends View implements Callback private StructuredText.TextBlock blockContainingPoint(StructuredText.TextBlock blocks[], Point p) { - for (StructuredText.TextBlock block : blocks) + if (blocks != null) { - if (block.bbox.contains(p.x, p.y)) - return block; + for (StructuredText.TextBlock block : blocks) + { + if (block.bbox.contains(p.x, p.y)) + return block; + } } return null; @@ -648,10 +656,13 @@ public class DocPageView extends View implements Callback private StructuredText.TextLine lineContainingPoint(StructuredText.TextLine lines[], Point p) { - for (StructuredText.TextLine line : lines) + if (lines != null) { - if (line.bbox.contains(p.x, p.y)) - return line; + for (StructuredText.TextLine line : lines) + { + if (line.bbox.contains(p.x, p.y)) + return line; + } } return null; @@ -659,10 +670,13 @@ public class DocPageView extends View implements Callback private StructuredText.TextSpan spanContainingPoint(StructuredText.TextSpan spans[], Point p) { - for (StructuredText.TextSpan span : spans) + if (spans != null) { - if (span.bbox.contains(p.x, p.y)) - return span; + for (StructuredText.TextSpan span : spans) + { + if (span.bbox.contains(p.x, p.y)) + return span; + } } return null; @@ -670,10 +684,13 @@ public class DocPageView extends View implements Callback private StructuredText.TextChar charContainingPoint(StructuredText.TextChar chars[], Point p) { - for (StructuredText.TextChar tchar : chars) + if (chars != null) { - if (tchar.bbox.contains(p.x, p.y)) - return tchar; + for (StructuredText.TextChar tchar : chars) + { + if (tchar.bbox.contains(p.x, p.y)) + return tchar; + } } return null; diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocProofView.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocProofView.java new file mode 100644 index 00000000..258af1f7 --- /dev/null +++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocProofView.java @@ -0,0 +1,116 @@ +package com.artifex.mupdf.android; + +import android.app.Activity; +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; + +public class DocProofView extends DocViewBase +{ + public DocProofView(Context context) + { + super(context); + initialize(context); + } + + public DocProofView(Context context, AttributeSet attrs) + { + super(context, attrs); + initialize(context); + } + + public DocProofView(Context context, AttributeSet attrs, int defStyle) + { + super(context, attrs, defStyle); + initialize(context); + } + + private void initialize(Context context) + { + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) + { + super.onLayout(changed, left, top, right, bottom); + + // not if we've been finished + if (finished()) + return; + + // see if we've been given a start page + handleStartPage(); + } + + @Override + public void handleStartPage() + { + // if we've been given a start page, go there. + if (getStartPage()>0) + { + setCurrentPage(getStartPage()-1); + setStartPage(0); // but only once + } + } + + private int mCurrentPage = 0; + public int getCurrentPage() {return mCurrentPage;} + + public void setCurrentPage(int pageNum) + { + if (pageNum != mCurrentPage) + { + // stop rendering the current page + DocPageView pv = (DocPageView)getOrCreateChild(0); + pv.stopRender(); + + mCurrentPage = pageNum; + + // when the page changes, reset what's in view. + clearChildViews(); + removeAllViewsInLayout(); + + // scroll to 0,0 and do a new layout. +// smoothScrollBy(getScrollX(),getScrollY()); + requestLayout(); + } + } + + @Override + protected int getPageCount() + { + int count = super.getPageCount(); + if (count==0) + return 0; // no pages yet + + // always return one page + return 1; + } + + @Override + protected View getViewFromAdapter(int index) + { + // only one view at a time, so we're not going to use the adapter + // we'll just create and reuse a single view + if (mDocPageView==null) { + final Activity activity = (Activity) mContext; + mDocPageView = new DocPageView(activity, getDoc()); + } + + mDocPageView.setupPage(mCurrentPage, getWidth(), 1); + return mDocPageView; + } + + private DocPageView mDocPageView = null; + + @Override + protected void doSingleTap(float fx, float fy) + { + } + + @Override + public boolean shouldAdjustScaleEnd() + { + return false; + } +} diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java index 6152851c..5ecc75d8 100755 --- a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java +++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java @@ -44,7 +44,7 @@ public class DocViewBase // bitmaps for rendering // these are created by the activity and set using setBitmaps() - private final static double OVERSIZE_FACTOR = 1.4; + private final static double OVERSIZE_FACTOR = 1.0; private final Bitmap[] bitmaps = {null, null}; private int bitmapIndex = 0; @@ -446,34 +446,42 @@ public class DocViewBase return true; } + public boolean shouldAdjustScaleEnd() + { + return true; + } + public void onScaleEnd(ScaleGestureDetector detector) { - // When a pinch-scale is done, we want to get n-across - // to fit properly. + if (shouldAdjustScaleEnd()) + { + // When a pinch-scale is done, we want to get n-across + // to fit properly. - // get current viewport - Rect viewport = new Rect(); - getGlobalVisibleRect(viewport); + // get current viewport + Rect viewport = new Rect(); + getGlobalVisibleRect(viewport); - // if we're at one column and wider than the viewport, - // leave it alone. - if (mLastLayoutColumns == 0 && mPageCollectionWidth >= viewport.width()) - { - mScaling = false; - return; - } + // if we're at one column and wider than the viewport, + // leave it alone. + if (mLastLayoutColumns == 0 && mPageCollectionWidth >= viewport.width()) + { + mScaling = false; + return; + } - // ratio of the viewport width to layout width - float ratio = ((float) (viewport.width())) / ((float) (mPageCollectionWidth)); + // ratio of the viewport width to layout width + float ratio = ((float) (viewport.width())) / ((float) (mPageCollectionWidth)); - // set a new scale factor - mScale *= ratio; - scaleChildren(); + // set a new scale factor + mScale *= ratio; + scaleChildren(); - // scroll so the left edged is flush to the viewport. - mXScroll += getScrollX(); + // scroll so the left edged is flush to the viewport. + mXScroll += getScrollX(); - requestLayout(); + requestLayout(); + } mScaling = false; } @@ -509,7 +517,6 @@ public class DocViewBase protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); if (!mStarted) @@ -795,6 +802,11 @@ public class DocViewBase return v; } + protected void clearChildViews() + { + mChildViews.clear(); + } + protected View getViewFromAdapter(int index) { return getAdapter().getView(index, getCached(), this); @@ -868,6 +880,10 @@ public class DocViewBase // been requested, start it now renderPages(); } + else { + if (mIdleRenderListener != null) + mIdleRenderListener.onIdle(); + } } } }, mShowAnnotations); @@ -1023,4 +1039,12 @@ public class DocViewBase onSizeChange((float) (page_width_percentage + pagelist_width_percentage) / (float) (page_width_percentage)); } + private IdleRenderListener mIdleRenderListener = null; + public void setIdleRenderListener(IdleRenderListener l) {mIdleRenderListener=l;} + + public interface IdleRenderListener + { + public void onIdle(); + } + } diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/ProofActivity.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/ProofActivity.java new file mode 100644 index 00000000..0d11f063 --- /dev/null +++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/ProofActivity.java @@ -0,0 +1,430 @@ +package com.artifex.mupdf.android; + + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.WindowManager; +import android.view.animation.Animation; +import android.view.animation.TranslateAnimation; +import android.widget.Adapter; +import android.widget.BaseAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.ListView; +import android.widget.TextView; + +import com.artifex.mupdf.fitz.Document; +import com.artifex.mupdf.fitz.Page; +import com.artifex.mupdf.fitz.R; +import com.artifex.mupdf.fitz.Separation; + +import java.util.LinkedList; + +public class ProofActivity extends Activity implements View.OnClickListener, DocViewBase.IdleRenderListener +{ + private DocProofView mDocView; + private Document mDoc=null; + private String mPath; + + private ToolbarButton mFirstPageButton; + private ToolbarButton mPreviousPageButton; + private ToolbarButton mNextPageButton; + private ToolbarButton mLastPageButton; + private ToolbarButton mColorsUpButton; + private ToolbarButton mColorsDownButton; + private ImageButton mBackButton; + private Button mApplyButton; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + // get the file path + Uri uri = getIntent().getData(); + final String path = Uri.decode(uri.getEncodedPath()); + mPath = path; + + // get the starting page + int startPage = getIntent().getIntExtra("startingPage", 0); + + // set up UI + setContentView(R.layout.activity_proof_view); + mDocView = (DocProofView) findViewById(R.id.proof_view); + + mFirstPageButton = (ToolbarButton)findViewById(R.id.proof_first_page); + mFirstPageButton.setOnClickListener(this); + + mPreviousPageButton = (ToolbarButton)findViewById(R.id.proof_previous_page); + mPreviousPageButton.setOnClickListener(this); + + mNextPageButton = (ToolbarButton)findViewById(R.id.proof_next_page); + mNextPageButton.setOnClickListener(this); + + mLastPageButton = (ToolbarButton)findViewById(R.id.proof_last_page); + mLastPageButton.setOnClickListener(this); + + mBackButton = (ImageButton) findViewById(R.id.proof_back_button); + mBackButton.setOnClickListener(this); + + mColorsUpButton = (ToolbarButton) findViewById(R.id.proof_colors_button_up); + mColorsUpButton.setOnClickListener(this); + + mColorsDownButton = (ToolbarButton) findViewById(R.id.proof_colors_button_down); + mColorsDownButton.setOnClickListener(this); + + mApplyButton = (Button) findViewById(R.id.proof_apply_button); + mApplyButton.setOnClickListener(this); + + // wait for layout to open the document + final ProofActivity activity = this; + mDocView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + public void onGlobalLayout() { + mDocView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + + spinner = createAndShowWaitSpinner(activity); + + // Go! + mWaitingForIdle = true; + mDoc = new Document(path); + mDocView.start(mDoc); + mDocView.setIdleRenderListener(activity); + } + }); + } + + private ProgressDialog spinner = null; + + @Override + public void finish() + { + // stop the view + mDocView.finish(); + + // delete the .gproof file + Utilities.deleteFile(mPath); + + super.finish(); + } + + @Override + public void onClick(View v) + { + int pageCount = mDocView.getDoc().countPages(); // the real page count + int currentPage = mDocView.getCurrentPage(); + + if (v == mFirstPageButton) + { + if (currentPage != 0) + gotoPage(v, 0); + } + else if (v == mPreviousPageButton) + { + if (currentPage>0) + gotoPage(v, currentPage-1); + } + else if (v == mNextPageButton) + { + if (currentPage+1> 24) & 0xFF; + int red = (sep.rgba >> 16) & 0xFF; + int green = (sep.rgba >> 8 ) & 0xFF; + int blue = (sep.rgba >> 0 ) & 0xFF; + int color = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0); + + mColorAdapter.add(new ChooseColorItem(sep.name, color, true, sep)); + } + + mColorList.getLayoutParams().width = getWidestView(getBaseContext(), mColorAdapter); + + } + mWaitingForIdle = false; + } + + public void updateColors() + { + // get the current page + DocPageView dpv = (DocPageView)mDocView.getViewFromAdapter(mDocView.getCurrentPage()); + Page page = dpv.getPage(); + + int numSeparations = mColorAdapter.getCount(); + for (int i=0; i maxWidth) { + maxWidth = width; + } + } + return maxWidth; + } + + private static ProgressDialog createAndShowWaitSpinner(Context mContext) + { + ProgressDialog dialog = new ProgressDialog(mContext); + try { + dialog.show(); + } + catch (WindowManager.BadTokenException e) { + } + dialog.setCancelable(false); + dialog.setIndeterminate(true); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + dialog.setContentView(R.layout.wait_spinner); + return dialog; + } + + //--------------------------------------------------------------------------------------------------------- + + public class ChooseColorItem + { + public String name; + public int color; + public boolean checked; + Separation separation; + + public ChooseColorItem(String name, int color, boolean checked, Separation separation) + { + this.checked = checked; + this.name = name; + this.color = color; + this.separation = separation; + } + } + + //--------------------------------------------------------------------------------------------------------- + + public class ChooseColorAdapter extends BaseAdapter + { + private final LinkedList mItems; + private final LayoutInflater mInflater; + + public ChooseColorAdapter(LayoutInflater inflater) + { + mInflater = inflater; + mItems = new LinkedList<>(); + } + + public void clear() + { + mItems.clear(); + } + + public void add(ChooseColorItem item) + { + mItems.add(item); + notifyDataSetChanged(); + } + + public int getCount() + { + return mItems.size(); + } + + public Object getItem(int i) + { + return mItems.get(i); + } + + public long getItemId(int arg0) + { + return 0; + } + + public View getView(int position, View convertView, ViewGroup parent) + { + View v; + if (convertView == null) + { + v = mInflater.inflate(R.layout.proof_color_list_entry, null); + } + else + { + v = convertView; + } + + final ChooseColorItem item = mItems.get(position); + + v.setTag(item); + + View swatch = v.findViewById(R.id.proof_entry_color_swatch); + swatch.setBackgroundColor(item.color); + + ((CheckBox) v.findViewById(R.id.proof_entry_checkbox)).setChecked(item.checked); + + ((CheckBox) v.findViewById(R.id.proof_entry_checkbox)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() + { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) + { + item.checked = isChecked; + } + }); + + ((TextView) v.findViewById(R.id.proof_entry_label)).setText(item.name); + + return v; + } + + } + + +} diff --git a/platform/android/example/mupdf/src/main/res/activity_doc_view.xml b/platform/android/example/mupdf/src/main/res/activity_doc_view.xml new file mode 100755 index 00000000..00065cf6 --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/activity_doc_view.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/platform/android/example/mupdf/src/main/res/drawable/color_box.xml b/platform/android/example/mupdf/src/main/res/drawable/color_box.xml new file mode 100644 index 00000000..c8b47a52 --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/color_box.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_next_page.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_next_page.xml new file mode 100755 index 00000000..3fe059c0 --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/icon_next_page.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_prev_page.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_prev_page.xml new file mode 100755 index 00000000..3e6b01ce --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/icon_prev_page.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_proof.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_proof.xml new file mode 100644 index 00000000..fb38e07a --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/icon_proof.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_down.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_down.xml new file mode 100755 index 00000000..78e38809 --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_down.xml @@ -0,0 +1,648 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_up.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_up.xml new file mode 100755 index 00000000..fead091c --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/icon_proof_colors_up.xml @@ -0,0 +1,648 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform/android/example/mupdf/src/main/res/drawable/rectangle.xml b/platform/android/example/mupdf/src/main/res/drawable/rectangle.xml new file mode 100644 index 00000000..158afcf8 --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/rectangle.xml @@ -0,0 +1,4 @@ + + + + diff --git a/platform/android/example/mupdf/src/main/res/drawable/spinner_back.xml b/platform/android/example/mupdf/src/main/res/drawable/spinner_back.xml new file mode 100644 index 00000000..c0d785a4 --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/drawable/spinner_back.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/platform/android/example/mupdf/src/main/res/layout/activity_proof_view.xml b/platform/android/example/mupdf/src/main/res/layout/activity_proof_view.xml new file mode 100755 index 00000000..726e783b --- /dev/null +++ b/platform/android/example/mupdf/src/main/res/layout/activity_proof_view.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + +