From 34884282f7465aca016a3fa9a06618b9116cb8e1 Mon Sep 17 00:00:00 2001 From: Arnaud Delubac Date: Wed, 18 Dec 2019 13:04:29 +0100 Subject: [PATCH 1/5] adding option to display pdf in dual mode and the isLandscape property --- .../barteksc/pdfviewer/DecodingAsyncTask.java | 4 +-- .../github/barteksc/pdfviewer/PDFView.java | 32 +++++++++++++++++++ .../github/barteksc/pdfviewer/PdfFile.java | 10 ++++-- .../pdfviewer/scroll/DefaultScrollHandle.java | 6 +++- .../pdfviewer/util/PageSizeCalculator.java | 12 +++++-- .../barteksc/sample/PDFViewActivity.java | 20 ++++++++++-- 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java index 24292ac9..6e5cdb8d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java @@ -52,8 +52,8 @@ protected Throwable doInBackground(Void... params) { if (pdfView != null) { PdfDocument pdfDocument = docSource.createDocument(pdfView.getContext(), pdfiumCore, password); pdfFile = new PdfFile(pdfiumCore, pdfDocument, pdfView.getPageFitPolicy(), getViewSize(pdfView), - userPages, pdfView.isSwipeVertical(), pdfView.getSpacingPx(), pdfView.isAutoSpacingEnabled(), - pdfView.isFitEachPage()); + userPages, pdfView.isOnDualPageMode(), pdfView.isSwipeVertical(), pdfView.getSpacingPx(), pdfView.isAutoSpacingEnabled(), + pdfView.isFitEachPage(), pdfView.isOnLandscapeOrientation()); return null; } else { return new NullPointerException("pdfView == null"); diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java index b8374721..4bb2938f 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java @@ -176,6 +176,10 @@ enum ScrollDir { private int defaultPage = 0; + private boolean dualPageMode = false; + + private boolean isLandscapeOrientation = false; + /** True if should scroll through pages vertically instead of horizontally */ private boolean swipeVertical = true; @@ -1179,6 +1183,18 @@ public boolean isBestQuality() { return bestQuality; } + public boolean isOnDualPageMode() { + return dualPageMode; + } + + public boolean isOnLandscapeOrientation() { return isLandscapeOrientation; } + + public void setLandscapeOrientation(boolean landscapeOrientation) {this.isLandscapeOrientation = landscapeOrientation; } + + public void setDualPageMode(boolean dualPageMode) { + this.dualPageMode = dualPageMode; + } + public boolean isSwipeVertical() { return swipeVertical; } @@ -1353,6 +1369,10 @@ public class Configurator { private int defaultPage = 0; + private boolean landscapeOrientation = false; + + private boolean dualPageMode = false; + private boolean swipeHorizontal = false; private boolean annotationRendering = false; @@ -1461,6 +1481,16 @@ public Configurator defaultPage(int defaultPage) { return this; } + public Configurator landscapeOrientation(boolean landscapeOrientation) { + this.landscapeOrientation = landscapeOrientation; + return this; + } + + public Configurator dualPageMode(boolean dualPageMode) { + this.dualPageMode = dualPageMode; + return this; + } + public Configurator swipeHorizontal(boolean swipeHorizontal) { this.swipeHorizontal = swipeHorizontal; return this; @@ -1542,6 +1572,8 @@ public void load() { PDFView.this.setNightMode(nightMode); PDFView.this.enableDoubletap(enableDoubletap); PDFView.this.setDefaultPage(defaultPage); + PDFView.this.setLandscapeOrientation(landscapeOrientation); + PDFView.this.setDualPageMode(dualPageMode); PDFView.this.setSwipeVertical(!swipeHorizontal); PDFView.this.enableAnnotationRendering(annotationRendering); PDFView.this.setScrollHandle(scrollHandle); diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java index fdc104f2..3610bcbb 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java @@ -51,6 +51,8 @@ class PdfFile { private SizeF maxHeightPageSize = new SizeF(0, 0); /** Scaled page with maximum width */ private SizeF maxWidthPageSize = new SizeF(0, 0); + /** True if dualPageMode is on*/ + private boolean showTwoPages; /** True if scrolling is vertical, else it's horizontal */ private boolean isVertical; /** Fixed spacing between pages in pixels */ @@ -69,6 +71,8 @@ class PdfFile { * else the largest page fits and other pages scale relatively */ private final boolean fitEachPage; + + private final boolean isLandscape; /** * The pages the user want to display in order * (ex: 0, 2, 2, 8, 8, 1, 1, 1) @@ -76,7 +80,8 @@ class PdfFile { private int[] originalUserPages; PdfFile(PdfiumCore pdfiumCore, PdfDocument pdfDocument, FitPolicy pageFitPolicy, Size viewSize, int[] originalUserPages, - boolean isVertical, int spacing, boolean autoSpacing, boolean fitEachPage) { + boolean showTwoPages, boolean isVertical, int spacing, boolean autoSpacing, boolean fitEachPage, boolean isLandscape) { + this.showTwoPages = showTwoPages; this.pdfiumCore = pdfiumCore; this.pdfDocument = pdfDocument; this.pageFitPolicy = pageFitPolicy; @@ -85,6 +90,7 @@ class PdfFile { this.spacingPx = spacing; this.autoSpacing = autoSpacing; this.fitEachPage = fitEachPage; + this.isLandscape = isLandscape; setup(viewSize); } @@ -122,7 +128,7 @@ public void recalculatePageSizes(Size viewSize) { maxHeightPageSize = calculator.getOptimalMaxHeightPageSize(); for (Size size : originalPageSizes) { - pageSizes.add(calculator.calculate(size)); + pageSizes.add(calculator.calculate(size, showTwoPages, isLandscape)); } if (autoSpacing) { prepareAutoSpacing(viewSize); diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java index 8195a540..42c1feab 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java @@ -149,7 +149,11 @@ private void calculateMiddle() { pos = getY(); viewSize = getHeight(); pdfViewSize = pdfView.getHeight(); - } else { + } else if (pdfView.isOnDualPageMode()){ + pos = getX(); + viewSize = getWidth() / 2; + pdfViewSize = pdfView.getWidth() / 2; + } else { pos = getX(); viewSize = getWidth(); pdfViewSize = pdfView.getWidth(); diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java index 4d678c98..e7f35a3b 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java @@ -15,6 +15,9 @@ */ package com.github.barteksc.pdfviewer.util; +import android.app.Activity; +import android.util.Log; +import android.content.pm.ActivityInfo; import com.shockwave.pdfium.util.Size; import com.shockwave.pdfium.util.SizeF; @@ -40,11 +43,16 @@ public PageSizeCalculator(FitPolicy fitPolicy, Size originalMaxWidthPageSize, Si calculateMaxPages(); } - public SizeF calculate(Size pageSize) { + public SizeF calculate(Size pageSize, boolean showTwoPages, boolean isLandscape) { if (pageSize.getWidth() <= 0 || pageSize.getHeight() <= 0) { return new SizeF(0, 0); } - float maxWidth = fitEachPage ? viewSize.getWidth() : pageSize.getWidth() * widthRatio; + float maxWidth = 0; + if(showTwoPages && !isLandscape){ + maxWidth = fitEachPage ? viewSize.getWidth() : pageSize.getWidth() / 2 * widthRatio; + } else { + maxWidth = fitEachPage ? viewSize.getWidth() : pageSize.getWidth() * widthRatio; + } float maxHeight = fitEachPage ? viewSize.getHeight() : pageSize.getHeight() * heightRatio; switch (fitPolicy) { case HEIGHT: diff --git a/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java b/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java index d23b0008..a17da127 100755 --- a/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java +++ b/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java @@ -18,6 +18,7 @@ import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; @@ -71,6 +72,8 @@ public class PDFViewActivity extends AppCompatActivity implements OnPageChangeLi String pdfFileName; + + @OptionsItem(R.id.pickFile) void pickFile() { int permissionCheck = ContextCompat.checkSelfPermission(this, @@ -112,6 +115,9 @@ void afterViews() { } private void displayFromAsset(String assetFileName) { + boolean isLandscape = false; + int orientation = this.getResources().getConfiguration().orientation; + isLandscape = orientation == Configuration.ORIENTATION_LANDSCAPE; pdfFileName = assetFileName; pdfView.fromAsset(SAMPLE_FILE) @@ -119,8 +125,14 @@ private void displayFromAsset(String assetFileName) { .onPageChange(this) .enableAnnotationRendering(true) .onLoad(this) + .landscapeOrientation(isLandscape) + .dualPageMode(true) .scrollHandle(new DefaultScrollHandle(this)) - .spacing(10) // in dp + .spacing(0) // in dp + .enableSwipe(true) + .swipeHorizontal(true) + .pageFling(true) + .fitEachPage(false) .onPageError(this) .pageFitPolicy(FitPolicy.BOTH) .load(); @@ -135,7 +147,11 @@ private void displayFromUri(Uri uri) { .enableAnnotationRendering(true) .onLoad(this) .scrollHandle(new DefaultScrollHandle(this)) - .spacing(10) // in dp + .spacing(0) // in dp + .dualPageMode(true) + .enableSwipe(true) + .swipeHorizontal(true) + .pageFling(true) .onPageError(this) .load(); } From 6f00b6d34e2fcd82781245f5c38ba9fd238e53a7 Mon Sep 17 00:00:00 2001 From: Arnaud Delubac Date: Wed, 18 Dec 2019 13:31:16 +0100 Subject: [PATCH 2/5] nothng new --- .../java/com/github/barteksc/pdfviewer/AnimationManager.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/CacheManager.java | 2 +- .../java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java | 2 +- .../java/com/github/barteksc/pdfviewer/DragPinchManager.java | 2 +- .../src/main/java/com/github/barteksc/pdfviewer/PDFView.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/PagesLoader.java | 2 +- .../src/main/java/com/github/barteksc/pdfviewer/PdfFile.java | 2 +- .../java/com/github/barteksc/pdfviewer/RenderingHandler.java | 2 +- .../barteksc/pdfviewer/exception/FileNotFoundException.java | 2 +- .../barteksc/pdfviewer/exception/PageRenderingException.java | 2 +- .../com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java | 2 +- .../java/com/github/barteksc/pdfviewer/link/LinkHandler.java | 2 +- .../java/com/github/barteksc/pdfviewer/listener/Callbacks.java | 2 +- .../com/github/barteksc/pdfviewer/listener/OnDrawListener.java | 2 +- .../com/github/barteksc/pdfviewer/listener/OnErrorListener.java | 2 +- .../barteksc/pdfviewer/listener/OnLoadCompleteListener.java | 2 +- .../github/barteksc/pdfviewer/listener/OnLongPressListener.java | 2 +- .../barteksc/pdfviewer/listener/OnPageChangeListener.java | 2 +- .../github/barteksc/pdfviewer/listener/OnPageErrorListener.java | 2 +- .../barteksc/pdfviewer/listener/OnPageScrollListener.java | 2 +- .../github/barteksc/pdfviewer/listener/OnRenderListener.java | 2 +- .../com/github/barteksc/pdfviewer/listener/OnTapListener.java | 2 +- .../java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/model/PagePart.java | 2 +- .../github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java | 2 +- .../java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java | 2 +- .../java/com/github/barteksc/pdfviewer/source/AssetSource.java | 2 +- .../com/github/barteksc/pdfviewer/source/ByteArraySource.java | 2 +- .../com/github/barteksc/pdfviewer/source/DocumentSource.java | 2 +- .../java/com/github/barteksc/pdfviewer/source/FileSource.java | 2 +- .../com/github/barteksc/pdfviewer/source/InputStreamSource.java | 2 +- .../java/com/github/barteksc/pdfviewer/source/UriSource.java | 2 +- .../java/com/github/barteksc/pdfviewer/util/ArrayUtils.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/util/Constants.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/util/FileUtils.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/util/MathUtils.java | 2 +- .../com/github/barteksc/pdfviewer/util/PageSizeCalculator.java | 2 +- .../main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java | 2 +- .../src/main/java/com/github/barteksc/pdfviewer/util/Util.java | 2 +- 40 files changed, 40 insertions(+), 40 deletions(-) diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java index e7e9439f..a7c6470d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.animation.Animator; import android.animation.Animator.AnimatorListener; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java index 082ca3bf..66f8385f 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.graphics.RectF; import android.support.annotation.Nullable; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java index 6e5cdb8d..1c9d58d6 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.os.AsyncTask; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java index 3860bc73..5ca5b77d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.graphics.PointF; import android.graphics.RectF; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java index 4bb2938f..5946100a 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.content.Context; import android.graphics.Bitmap; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java index 26c30f4b..70be2cc0 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.graphics.RectF; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java index 3610bcbb..01ce993f 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.graphics.Bitmap; import android.graphics.Rect; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java index 22f55f4f..eb6fce44 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer; +package android.lib.pdfviewer; import android.graphics.Bitmap; import android.graphics.Color; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java index f0fc6f80..db341137 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.exception; +package android.lib.pdfviewer.exception; @Deprecated public class FileNotFoundException extends RuntimeException { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java index b6ff2b89..fa459059 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java @@ -1,4 +1,4 @@ -package com.github.barteksc.pdfviewer.exception; +package android.lib.pdfviewer.exception; public class PageRenderingException extends Exception { private final int page; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java index 0849da38..018b67ec 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.link; +package android.lib.pdfviewer.link; import android.content.Context; import android.content.Intent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java index f09dc11e..5ea3ba9e 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.link; +package android.lib.pdfviewer.link; import com.github.barteksc.pdfviewer.model.LinkTapEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java index 09becb1c..f0a97436 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; import android.view.MotionEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java index cb9af8b3..189c05bf 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; import android.graphics.Canvas; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java index 876bacfc..45becf9d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; public interface OnErrorListener { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java index c319fc58..d5cd970f 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; /** * Implement this interface to receive events from PDFView diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java index fc94c726..052f9703 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; import android.view.MotionEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java index dfb758a5..4fd4432e 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; /** * Implements this interface to receive events from PDFView diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java index 3fb38a2e..40a4de38 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; public interface OnPageErrorListener { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java index 6eda1fd1..521eba5c 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; /** * Implements this interface to receive events from PDFView diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java index 99982497..d3e209fe 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; public interface OnRenderListener { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java index 081a3a26..6adc13ed 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.listener; +package android.lib.pdfviewer.listener; import android.view.MotionEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java index 7e72bdd3..660b70e3 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.model; +package android.lib.pdfviewer.model; import android.graphics.RectF; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java index 376d2ccd..e1d03c0b 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.model; +package android.lib.pdfviewer.model; import android.graphics.Bitmap; import android.graphics.RectF; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java index 42c1feab..957adfc0 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java @@ -1,4 +1,4 @@ -package com.github.barteksc.pdfviewer.scroll; +package android.lib.pdfviewer.scroll; import android.content.Context; import android.graphics.Color; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java index b58de5a4..8cf886c1 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java @@ -1,4 +1,4 @@ -package com.github.barteksc.pdfviewer.scroll; +package android.lib.pdfviewer.scroll; import com.github.barteksc.pdfviewer.PDFView; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java index 3e24e204..e82c48c5 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.source; +package android.lib.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java index 245c78fc..38a72984 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.source; +package android.lib.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java index 4c76c5ab..2938d4f1 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.source; +package android.lib.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java index cfe092c8..ea09e9fa 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.source; +package android.lib.pdfviewer.source; import android.content.Context; import android.os.ParcelFileDescriptor; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java index 26e60a8d..bdcae2f4 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.source; +package android.lib.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java index 15215f0c..a4014f7b 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.source; +package android.lib.pdfviewer.source; import android.content.Context; import android.net.Uri; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java index 1ff38398..a390dd9e 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; import java.util.ArrayList; import java.util.List; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java index e03de0c3..79de4842 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; public class Constants { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java index 0aa325e9..0dc054e5 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java index 6e90dd55..21f0365f 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; public enum FitPolicy { WIDTH, HEIGHT, BOTH diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java index 119ae8ce..dfcdcc71 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; public class MathUtils { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java index e7f35a3b..d8fbc712 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; import android.app.Activity; import android.util.Log; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java index e2e73ab7..b419a950 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; public enum SnapEdge { START, CENTER, END, NONE diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java index 58e473e0..0d8dff09 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.barteksc.pdfviewer.util; +package android.lib.pdfviewer.util; import android.content.Context; import android.util.TypedValue; From b35f7d4cce95578b984f2907fb9b0d8f9d29a479 Mon Sep 17 00:00:00 2001 From: Arnaud Delubac Date: Wed, 18 Dec 2019 14:17:20 +0100 Subject: [PATCH 3/5] correcting package name --- .../barteksc/pdfviewer/AnimationManager.java | 442 +-- .../barteksc/pdfviewer/CacheManager.java | 384 +- .../barteksc/pdfviewer/DecodingAsyncTask.java | 2 +- .../barteksc/pdfviewer/DragPinchManager.java | 634 ++-- .../github/barteksc/pdfviewer/PDFView.java | 3190 ++++++++--------- .../barteksc/pdfviewer/PagesLoader.java | 2 +- .../github/barteksc/pdfviewer/PdfFile.java | 2 +- .../barteksc/pdfviewer/RenderingHandler.java | 322 +- .../exception/FileNotFoundException.java | 2 +- .../exception/PageRenderingException.java | 2 +- .../pdfviewer/link/DefaultLinkHandler.java | 2 +- .../barteksc/pdfviewer/link/LinkHandler.java | 2 +- .../pdfviewer/listener/Callbacks.java | 2 +- .../pdfviewer/listener/OnDrawListener.java | 76 +- .../pdfviewer/listener/OnErrorListener.java | 2 +- .../listener/OnLoadCompleteListener.java | 58 +- .../listener/OnLongPressListener.java | 2 +- .../listener/OnPageChangeListener.java | 64 +- .../listener/OnPageErrorListener.java | 2 +- .../listener/OnPageScrollListener.java | 2 +- .../pdfviewer/listener/OnRenderListener.java | 2 +- .../pdfviewer/listener/OnTapListener.java | 2 +- .../pdfviewer/model/LinkTapEvent.java | 2 +- .../barteksc/pdfviewer/model/PagePart.java | 160 +- .../pdfviewer/scroll/DefaultScrollHandle.java | 2 +- .../pdfviewer/scroll/ScrollHandle.java | 2 +- .../pdfviewer/source/AssetSource.java | 2 +- .../pdfviewer/source/ByteArraySource.java | 2 +- .../pdfviewer/source/DocumentSource.java | 2 +- .../barteksc/pdfviewer/source/FileSource.java | 2 +- .../pdfviewer/source/InputStreamSource.java | 2 +- .../barteksc/pdfviewer/source/UriSource.java | 2 +- .../barteksc/pdfviewer/util/ArrayUtils.java | 148 +- .../barteksc/pdfviewer/util/Constants.java | 102 +- .../barteksc/pdfviewer/util/FileUtils.java | 2 +- .../barteksc/pdfviewer/util/FitPolicy.java | 2 +- .../barteksc/pdfviewer/util/MathUtils.java | 210 +- .../pdfviewer/util/PageSizeCalculator.java | 2 +- .../barteksc/pdfviewer/util/SnapEdge.java | 2 +- .../github/barteksc/pdfviewer/util/Util.java | 2 +- 40 files changed, 2923 insertions(+), 2923 deletions(-) diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java index a7c6470d..89e813af 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java @@ -1,221 +1,221 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer; - -import android.animation.Animator; -import android.animation.Animator.AnimatorListener; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.graphics.PointF; -import android.view.animation.DecelerateInterpolator; -import android.widget.OverScroller; - - -/** - * This manager is used by the PDFView to launch animations. - * It uses the ValueAnimator appeared in API 11 to start - * an animation, and call moveTo() on the PDFView as a result - * of each animation update. - */ -class AnimationManager { - - private PDFView pdfView; - - private ValueAnimator animation; - - private OverScroller scroller; - - private boolean flinging = false; - - private boolean pageFlinging = false; - - public AnimationManager(PDFView pdfView) { - this.pdfView = pdfView; - scroller = new OverScroller(pdfView.getContext()); - } - - public void startXAnimation(float xFrom, float xTo) { - stopAll(); - animation = ValueAnimator.ofFloat(xFrom, xTo); - XAnimation xAnimation = new XAnimation(); - animation.setInterpolator(new DecelerateInterpolator()); - animation.addUpdateListener(xAnimation); - animation.addListener(xAnimation); - animation.setDuration(400); - animation.start(); - } - - public void startYAnimation(float yFrom, float yTo) { - stopAll(); - animation = ValueAnimator.ofFloat(yFrom, yTo); - YAnimation yAnimation = new YAnimation(); - animation.setInterpolator(new DecelerateInterpolator()); - animation.addUpdateListener(yAnimation); - animation.addListener(yAnimation); - animation.setDuration(400); - animation.start(); - } - - public void startZoomAnimation(float centerX, float centerY, float zoomFrom, float zoomTo) { - stopAll(); - animation = ValueAnimator.ofFloat(zoomFrom, zoomTo); - animation.setInterpolator(new DecelerateInterpolator()); - ZoomAnimation zoomAnim = new ZoomAnimation(centerX, centerY); - animation.addUpdateListener(zoomAnim); - animation.addListener(zoomAnim); - animation.setDuration(400); - animation.start(); - } - - public void startFlingAnimation(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) { - stopAll(); - flinging = true; - scroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); - } - - public void startPageFlingAnimation(float targetOffset) { - if (pdfView.isSwipeVertical()) { - startYAnimation(pdfView.getCurrentYOffset(), targetOffset); - } else { - startXAnimation(pdfView.getCurrentXOffset(), targetOffset); - } - pageFlinging = true; - } - - void computeFling() { - if (scroller.computeScrollOffset()) { - pdfView.moveTo(scroller.getCurrX(), scroller.getCurrY()); - pdfView.loadPageByOffset(); - } else if (flinging) { // fling finished - flinging = false; - pdfView.loadPages(); - hideHandle(); - pdfView.performPageSnap(); - } - } - - public void stopAll() { - if (animation != null) { - animation.cancel(); - animation = null; - } - stopFling(); - } - - public void stopFling() { - flinging = false; - scroller.forceFinished(true); - } - - public boolean isFlinging() { - return flinging || pageFlinging; - } - - class XAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float offset = (Float) animation.getAnimatedValue(); - pdfView.moveTo(offset, pdfView.getCurrentYOffset()); - pdfView.loadPageByOffset(); - } - - @Override - public void onAnimationCancel(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - - @Override - public void onAnimationEnd(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - } - - class YAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float offset = (Float) animation.getAnimatedValue(); - pdfView.moveTo(pdfView.getCurrentXOffset(), offset); - pdfView.loadPageByOffset(); - } - - @Override - public void onAnimationCancel(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - - @Override - public void onAnimationEnd(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - } - - class ZoomAnimation implements AnimatorUpdateListener, AnimatorListener { - - private final float centerX; - private final float centerY; - - public ZoomAnimation(float centerX, float centerY) { - this.centerX = centerX; - this.centerY = centerY; - } - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float zoom = (Float) animation.getAnimatedValue(); - pdfView.zoomCenteredTo(zoom, new PointF(centerX, centerY)); - } - - @Override - public void onAnimationCancel(Animator animation) { - pdfView.loadPages(); - hideHandle(); - } - - @Override - public void onAnimationEnd(Animator animation) { - pdfView.loadPages(); - pdfView.performPageSnap(); - hideHandle(); - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - - @Override - public void onAnimationStart(Animator animation) { - } - - } - - private void hideHandle() { - if (pdfView.getScrollHandle() != null) { - pdfView.getScrollHandle().hideDelayed(); - } - } - -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.graphics.PointF; +import android.view.animation.DecelerateInterpolator; +import android.widget.OverScroller; + + +/** + * This manager is used by the PDFView to launch animations. + * It uses the ValueAnimator appeared in API 11 to start + * an animation, and call moveTo() on the PDFView as a result + * of each animation update. + */ +class AnimationManager { + + private PDFView pdfView; + + private ValueAnimator animation; + + private OverScroller scroller; + + private boolean flinging = false; + + private boolean pageFlinging = false; + + public AnimationManager(PDFView pdfView) { + this.pdfView = pdfView; + scroller = new OverScroller(pdfView.getContext()); + } + + public void startXAnimation(float xFrom, float xTo) { + stopAll(); + animation = ValueAnimator.ofFloat(xFrom, xTo); + XAnimation xAnimation = new XAnimation(); + animation.setInterpolator(new DecelerateInterpolator()); + animation.addUpdateListener(xAnimation); + animation.addListener(xAnimation); + animation.setDuration(400); + animation.start(); + } + + public void startYAnimation(float yFrom, float yTo) { + stopAll(); + animation = ValueAnimator.ofFloat(yFrom, yTo); + YAnimation yAnimation = new YAnimation(); + animation.setInterpolator(new DecelerateInterpolator()); + animation.addUpdateListener(yAnimation); + animation.addListener(yAnimation); + animation.setDuration(400); + animation.start(); + } + + public void startZoomAnimation(float centerX, float centerY, float zoomFrom, float zoomTo) { + stopAll(); + animation = ValueAnimator.ofFloat(zoomFrom, zoomTo); + animation.setInterpolator(new DecelerateInterpolator()); + ZoomAnimation zoomAnim = new ZoomAnimation(centerX, centerY); + animation.addUpdateListener(zoomAnim); + animation.addListener(zoomAnim); + animation.setDuration(400); + animation.start(); + } + + public void startFlingAnimation(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) { + stopAll(); + flinging = true; + scroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); + } + + public void startPageFlingAnimation(float targetOffset) { + if (pdfView.isSwipeVertical()) { + startYAnimation(pdfView.getCurrentYOffset(), targetOffset); + } else { + startXAnimation(pdfView.getCurrentXOffset(), targetOffset); + } + pageFlinging = true; + } + + void computeFling() { + if (scroller.computeScrollOffset()) { + pdfView.moveTo(scroller.getCurrX(), scroller.getCurrY()); + pdfView.loadPageByOffset(); + } else if (flinging) { // fling finished + flinging = false; + pdfView.loadPages(); + hideHandle(); + pdfView.performPageSnap(); + } + } + + public void stopAll() { + if (animation != null) { + animation.cancel(); + animation = null; + } + stopFling(); + } + + public void stopFling() { + flinging = false; + scroller.forceFinished(true); + } + + public boolean isFlinging() { + return flinging || pageFlinging; + } + + class XAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float offset = (Float) animation.getAnimatedValue(); + pdfView.moveTo(offset, pdfView.getCurrentYOffset()); + pdfView.loadPageByOffset(); + } + + @Override + public void onAnimationCancel(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + + @Override + public void onAnimationEnd(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + } + + class YAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float offset = (Float) animation.getAnimatedValue(); + pdfView.moveTo(pdfView.getCurrentXOffset(), offset); + pdfView.loadPageByOffset(); + } + + @Override + public void onAnimationCancel(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + + @Override + public void onAnimationEnd(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + } + + class ZoomAnimation implements AnimatorUpdateListener, AnimatorListener { + + private final float centerX; + private final float centerY; + + public ZoomAnimation(float centerX, float centerY) { + this.centerX = centerX; + this.centerY = centerY; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float zoom = (Float) animation.getAnimatedValue(); + pdfView.zoomCenteredTo(zoom, new PointF(centerX, centerY)); + } + + @Override + public void onAnimationCancel(Animator animation) { + pdfView.loadPages(); + hideHandle(); + } + + @Override + public void onAnimationEnd(Animator animation) { + pdfView.loadPages(); + pdfView.performPageSnap(); + hideHandle(); + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public void onAnimationStart(Animator animation) { + } + + } + + private void hideHandle() { + if (pdfView.getScrollHandle() != null) { + pdfView.getScrollHandle().hideDelayed(); + } + } + +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java index 66f8385f..97e6914d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java @@ -1,192 +1,192 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer; - -import android.graphics.RectF; -import android.support.annotation.Nullable; - -import com.github.barteksc.pdfviewer.model.PagePart; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.PriorityQueue; - -import static com.github.barteksc.pdfviewer.util.Constants.Cache.CACHE_SIZE; -import static com.github.barteksc.pdfviewer.util.Constants.Cache.THUMBNAILS_CACHE_SIZE; - -class CacheManager { - - private final PriorityQueue passiveCache; - - private final PriorityQueue activeCache; - - private final List thumbnails; - - private final Object passiveActiveLock = new Object(); - - private final PagePartComparator orderComparator = new PagePartComparator(); - - public CacheManager() { - activeCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); - passiveCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); - thumbnails = new ArrayList<>(); - } - - public void cachePart(PagePart part) { - synchronized (passiveActiveLock) { - // If cache too big, remove and recycle - makeAFreeSpace(); - - // Then add part - activeCache.offer(part); - } - } - - public void makeANewSet() { - synchronized (passiveActiveLock) { - passiveCache.addAll(activeCache); - activeCache.clear(); - } - } - - private void makeAFreeSpace() { - synchronized (passiveActiveLock) { - while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && - !passiveCache.isEmpty()) { - PagePart part = passiveCache.poll(); - part.getRenderedBitmap().recycle(); - } - - while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && - !activeCache.isEmpty()) { - activeCache.poll().getRenderedBitmap().recycle(); - } - } - } - - public void cacheThumbnail(PagePart part) { - synchronized (thumbnails) { - // If cache too big, remove and recycle - while (thumbnails.size() >= THUMBNAILS_CACHE_SIZE) { - thumbnails.remove(0).getRenderedBitmap().recycle(); - } - - // Then add thumbnail - addWithoutDuplicates(thumbnails, part); - } - - } - - public boolean upPartIfContained(int page, RectF pageRelativeBounds, int toOrder) { - PagePart fakePart = new PagePart(page, null, pageRelativeBounds, false, 0); - - PagePart found; - synchronized (passiveActiveLock) { - if ((found = find(passiveCache, fakePart)) != null) { - passiveCache.remove(found); - found.setCacheOrder(toOrder); - activeCache.offer(found); - return true; - } - - return find(activeCache, fakePart) != null; - } - } - - /** - * Return true if already contains the described PagePart - */ - public boolean containsThumbnail(int page, RectF pageRelativeBounds) { - PagePart fakePart = new PagePart(page, null, pageRelativeBounds, true, 0); - synchronized (thumbnails) { - for (PagePart part : thumbnails) { - if (part.equals(fakePart)) { - return true; - } - } - return false; - } - } - - /** - * Add part if it doesn't exist, recycle bitmap otherwise - */ - private void addWithoutDuplicates(Collection collection, PagePart newPart) { - for (PagePart part : collection) { - if (part.equals(newPart)) { - newPart.getRenderedBitmap().recycle(); - return; - } - } - collection.add(newPart); - } - - @Nullable - private static PagePart find(PriorityQueue vector, PagePart fakePart) { - for (PagePart part : vector) { - if (part.equals(fakePart)) { - return part; - } - } - return null; - } - - public List getPageParts() { - synchronized (passiveActiveLock) { - List parts = new ArrayList<>(passiveCache); - parts.addAll(activeCache); - return parts; - } - } - - public List getThumbnails() { - synchronized (thumbnails) { - return thumbnails; - } - } - - public void recycle() { - synchronized (passiveActiveLock) { - for (PagePart part : passiveCache) { - part.getRenderedBitmap().recycle(); - } - passiveCache.clear(); - for (PagePart part : activeCache) { - part.getRenderedBitmap().recycle(); - } - activeCache.clear(); - } - synchronized (thumbnails) { - for (PagePart part : thumbnails) { - part.getRenderedBitmap().recycle(); - } - thumbnails.clear(); - } - } - - class PagePartComparator implements Comparator { - @Override - public int compare(PagePart part1, PagePart part2) { - if (part1.getCacheOrder() == part2.getCacheOrder()) { - return 0; - } - return part1.getCacheOrder() > part2.getCacheOrder() ? 1 : -1; - } - } - -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer; + +import android.graphics.RectF; +import android.support.annotation.Nullable; + +import com.github.barteksc.pdfviewer.model.PagePart; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +import static com.github.barteksc.pdfviewer.util.Constants.Cache.CACHE_SIZE; +import static com.github.barteksc.pdfviewer.util.Constants.Cache.THUMBNAILS_CACHE_SIZE; + +class CacheManager { + + private final PriorityQueue passiveCache; + + private final PriorityQueue activeCache; + + private final List thumbnails; + + private final Object passiveActiveLock = new Object(); + + private final PagePartComparator orderComparator = new PagePartComparator(); + + public CacheManager() { + activeCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); + passiveCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); + thumbnails = new ArrayList<>(); + } + + public void cachePart(PagePart part) { + synchronized (passiveActiveLock) { + // If cache too big, remove and recycle + makeAFreeSpace(); + + // Then add part + activeCache.offer(part); + } + } + + public void makeANewSet() { + synchronized (passiveActiveLock) { + passiveCache.addAll(activeCache); + activeCache.clear(); + } + } + + private void makeAFreeSpace() { + synchronized (passiveActiveLock) { + while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && + !passiveCache.isEmpty()) { + PagePart part = passiveCache.poll(); + part.getRenderedBitmap().recycle(); + } + + while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && + !activeCache.isEmpty()) { + activeCache.poll().getRenderedBitmap().recycle(); + } + } + } + + public void cacheThumbnail(PagePart part) { + synchronized (thumbnails) { + // If cache too big, remove and recycle + while (thumbnails.size() >= THUMBNAILS_CACHE_SIZE) { + thumbnails.remove(0).getRenderedBitmap().recycle(); + } + + // Then add thumbnail + addWithoutDuplicates(thumbnails, part); + } + + } + + public boolean upPartIfContained(int page, RectF pageRelativeBounds, int toOrder) { + PagePart fakePart = new PagePart(page, null, pageRelativeBounds, false, 0); + + PagePart found; + synchronized (passiveActiveLock) { + if ((found = find(passiveCache, fakePart)) != null) { + passiveCache.remove(found); + found.setCacheOrder(toOrder); + activeCache.offer(found); + return true; + } + + return find(activeCache, fakePart) != null; + } + } + + /** + * Return true if already contains the described PagePart + */ + public boolean containsThumbnail(int page, RectF pageRelativeBounds) { + PagePart fakePart = new PagePart(page, null, pageRelativeBounds, true, 0); + synchronized (thumbnails) { + for (PagePart part : thumbnails) { + if (part.equals(fakePart)) { + return true; + } + } + return false; + } + } + + /** + * Add part if it doesn't exist, recycle bitmap otherwise + */ + private void addWithoutDuplicates(Collection collection, PagePart newPart) { + for (PagePart part : collection) { + if (part.equals(newPart)) { + newPart.getRenderedBitmap().recycle(); + return; + } + } + collection.add(newPart); + } + + @Nullable + private static PagePart find(PriorityQueue vector, PagePart fakePart) { + for (PagePart part : vector) { + if (part.equals(fakePart)) { + return part; + } + } + return null; + } + + public List getPageParts() { + synchronized (passiveActiveLock) { + List parts = new ArrayList<>(passiveCache); + parts.addAll(activeCache); + return parts; + } + } + + public List getThumbnails() { + synchronized (thumbnails) { + return thumbnails; + } + } + + public void recycle() { + synchronized (passiveActiveLock) { + for (PagePart part : passiveCache) { + part.getRenderedBitmap().recycle(); + } + passiveCache.clear(); + for (PagePart part : activeCache) { + part.getRenderedBitmap().recycle(); + } + activeCache.clear(); + } + synchronized (thumbnails) { + for (PagePart part : thumbnails) { + part.getRenderedBitmap().recycle(); + } + thumbnails.clear(); + } + } + + class PagePartComparator implements Comparator { + @Override + public int compare(PagePart part1, PagePart part2) { + if (part1.getCacheOrder() == part2.getCacheOrder()) { + return 0; + } + return part1.getCacheOrder() > part2.getCacheOrder() ? 1 : -1; + } + } + +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java index 1c9d58d6..6e5cdb8d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer; +package com.github.barteksc.pdfviewer; import android.os.AsyncTask; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java index 5ca5b77d..edca09f6 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DragPinchManager.java @@ -1,317 +1,317 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.ScaleGestureDetector; -import android.view.View; - -import com.github.barteksc.pdfviewer.model.LinkTapEvent; -import com.github.barteksc.pdfviewer.scroll.ScrollHandle; -import com.github.barteksc.pdfviewer.util.SnapEdge; -import com.shockwave.pdfium.PdfDocument; -import com.shockwave.pdfium.util.SizeF; - -import static com.github.barteksc.pdfviewer.util.Constants.Pinch.MAXIMUM_ZOOM; -import static com.github.barteksc.pdfviewer.util.Constants.Pinch.MINIMUM_ZOOM; - -/** - * This Manager takes care of moving the PDFView, - * set its zoom track user actions. - */ -class DragPinchManager implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, ScaleGestureDetector.OnScaleGestureListener, View.OnTouchListener { - - private PDFView pdfView; - private AnimationManager animationManager; - - private GestureDetector gestureDetector; - private ScaleGestureDetector scaleGestureDetector; - - private boolean scrolling = false; - private boolean scaling = false; - private boolean enabled = false; - - DragPinchManager(PDFView pdfView, AnimationManager animationManager) { - this.pdfView = pdfView; - this.animationManager = animationManager; - gestureDetector = new GestureDetector(pdfView.getContext(), this); - scaleGestureDetector = new ScaleGestureDetector(pdfView.getContext(), this); - pdfView.setOnTouchListener(this); - } - - void enable() { - enabled = true; - } - - void disable() { - enabled = false; - } - - void disableLongpress(){ - gestureDetector.setIsLongpressEnabled(false); - } - - @Override - public boolean onSingleTapConfirmed(MotionEvent e) { - boolean onTapHandled = pdfView.callbacks.callOnTap(e); - boolean linkTapped = checkLinkTapped(e.getX(), e.getY()); - if (!onTapHandled && !linkTapped) { - ScrollHandle ps = pdfView.getScrollHandle(); - if (ps != null && !pdfView.documentFitsView()) { - if (!ps.shown()) { - ps.show(); - } else { - ps.hide(); - } - } - } - pdfView.performClick(); - return true; - } - - private boolean checkLinkTapped(float x, float y) { - PdfFile pdfFile = pdfView.pdfFile; - if (pdfFile == null) { - return false; - } - float mappedX = -pdfView.getCurrentXOffset() + x; - float mappedY = -pdfView.getCurrentYOffset() + y; - int page = pdfFile.getPageAtOffset(pdfView.isSwipeVertical() ? mappedY : mappedX, pdfView.getZoom()); - SizeF pageSize = pdfFile.getScaledPageSize(page, pdfView.getZoom()); - int pageX, pageY; - if (pdfView.isSwipeVertical()) { - pageX = (int) pdfFile.getSecondaryPageOffset(page, pdfView.getZoom()); - pageY = (int) pdfFile.getPageOffset(page, pdfView.getZoom()); - } else { - pageY = (int) pdfFile.getSecondaryPageOffset(page, pdfView.getZoom()); - pageX = (int) pdfFile.getPageOffset(page, pdfView.getZoom()); - } - for (PdfDocument.Link link : pdfFile.getPageLinks(page)) { - RectF mapped = pdfFile.mapRectToDevice(page, pageX, pageY, (int) pageSize.getWidth(), - (int) pageSize.getHeight(), link.getBounds()); - mapped.sort(); - if (mapped.contains(mappedX, mappedY)) { - pdfView.callbacks.callLinkHandler(new LinkTapEvent(x, y, mappedX, mappedY, mapped, link)); - return true; - } - } - return false; - } - - private void startPageFling(MotionEvent downEvent, MotionEvent ev, float velocityX, float velocityY) { - if (!checkDoPageFling(velocityX, velocityY)) { - return; - } - - int direction; - if (pdfView.isSwipeVertical()) { - direction = velocityY > 0 ? -1 : 1; - } else { - direction = velocityX > 0 ? -1 : 1; - } - // get the focused page during the down event to ensure only a single page is changed - float delta = pdfView.isSwipeVertical() ? ev.getY() - downEvent.getY() : ev.getX() - downEvent.getX(); - float offsetX = pdfView.getCurrentXOffset() - delta * pdfView.getZoom(); - float offsetY = pdfView.getCurrentYOffset() - delta * pdfView.getZoom(); - int startingPage = pdfView.findFocusPage(offsetX, offsetY); - int targetPage = Math.max(0, Math.min(pdfView.getPageCount() - 1, startingPage + direction)); - - SnapEdge edge = pdfView.findSnapEdge(targetPage); - float offset = pdfView.snapOffsetForPage(targetPage, edge); - animationManager.startPageFlingAnimation(-offset); - } - - @Override - public boolean onDoubleTap(MotionEvent e) { - if (!pdfView.isDoubletapEnabled()) { - return false; - } - - if (pdfView.getZoom() < pdfView.getMidZoom()) { - pdfView.zoomWithAnimation(e.getX(), e.getY(), pdfView.getMidZoom()); - } else if (pdfView.getZoom() < pdfView.getMaxZoom()) { - pdfView.zoomWithAnimation(e.getX(), e.getY(), pdfView.getMaxZoom()); - } else { - pdfView.resetZoomWithAnimation(); - } - return true; - } - - @Override - public boolean onDoubleTapEvent(MotionEvent e) { - return false; - } - - @Override - public boolean onDown(MotionEvent e) { - animationManager.stopFling(); - return true; - } - - @Override - public void onShowPress(MotionEvent e) { - - } - - @Override - public boolean onSingleTapUp(MotionEvent e) { - return false; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - scrolling = true; - if (pdfView.isZooming() || pdfView.isSwipeEnabled()) { - pdfView.moveRelativeTo(-distanceX, -distanceY); - } - if (!scaling || pdfView.doRenderDuringScale()) { - pdfView.loadPageByOffset(); - } - return true; - } - - private void onScrollEnd(MotionEvent event) { - pdfView.loadPages(); - hideHandle(); - if (!animationManager.isFlinging()) { - pdfView.performPageSnap(); - } - } - - @Override - public void onLongPress(MotionEvent e) { - pdfView.callbacks.callOnLongPress(e); - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (!pdfView.isSwipeEnabled()) { - return false; - } - if (pdfView.isPageFlingEnabled()) { - if (pdfView.pageFillsScreen()) { - onBoundedFling(velocityX, velocityY); - } else { - startPageFling(e1, e2, velocityX, velocityY); - } - return true; - } - - int xOffset = (int) pdfView.getCurrentXOffset(); - int yOffset = (int) pdfView.getCurrentYOffset(); - - float minX, minY; - PdfFile pdfFile = pdfView.pdfFile; - if (pdfView.isSwipeVertical()) { - minX = -(pdfView.toCurrentScale(pdfFile.getMaxPageWidth()) - pdfView.getWidth()); - minY = -(pdfFile.getDocLen(pdfView.getZoom()) - pdfView.getHeight()); - } else { - minX = -(pdfFile.getDocLen(pdfView.getZoom()) - pdfView.getWidth()); - minY = -(pdfView.toCurrentScale(pdfFile.getMaxPageHeight()) - pdfView.getHeight()); - } - - animationManager.startFlingAnimation(xOffset, yOffset, (int) (velocityX), (int) (velocityY), - (int) minX, 0, (int) minY, 0); - return true; - } - - private void onBoundedFling(float velocityX, float velocityY) { - int xOffset = (int) pdfView.getCurrentXOffset(); - int yOffset = (int) pdfView.getCurrentYOffset(); - - PdfFile pdfFile = pdfView.pdfFile; - - float pageStart = -pdfFile.getPageOffset(pdfView.getCurrentPage(), pdfView.getZoom()); - float pageEnd = pageStart - pdfFile.getPageLength(pdfView.getCurrentPage(), pdfView.getZoom()); - float minX, minY, maxX, maxY; - if (pdfView.isSwipeVertical()) { - minX = -(pdfView.toCurrentScale(pdfFile.getMaxPageWidth()) - pdfView.getWidth()); - minY = pageEnd + pdfView.getHeight(); - maxX = 0; - maxY = pageStart; - } else { - minX = pageEnd + pdfView.getWidth(); - minY = -(pdfView.toCurrentScale(pdfFile.getMaxPageHeight()) - pdfView.getHeight()); - maxX = pageStart; - maxY = 0; - } - - animationManager.startFlingAnimation(xOffset, yOffset, (int) (velocityX), (int) (velocityY), - (int) minX, (int) maxX, (int) minY, (int) maxY); - } - - @Override - public boolean onScale(ScaleGestureDetector detector) { - float dr = detector.getScaleFactor(); - float wantedZoom = pdfView.getZoom() * dr; - float minZoom = Math.min(MINIMUM_ZOOM, pdfView.getMinZoom()); - float maxZoom = Math.min(MAXIMUM_ZOOM, pdfView.getMaxZoom()); - if (wantedZoom < minZoom) { - dr = minZoom / pdfView.getZoom(); - } else if (wantedZoom > maxZoom) { - dr = maxZoom / pdfView.getZoom(); - } - pdfView.zoomCenteredRelativeTo(dr, new PointF(detector.getFocusX(), detector.getFocusY())); - return true; - } - - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - scaling = true; - return true; - } - - @Override - public void onScaleEnd(ScaleGestureDetector detector) { - pdfView.loadPages(); - hideHandle(); - scaling = false; - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - if (!enabled) { - return false; - } - - boolean retVal = scaleGestureDetector.onTouchEvent(event); - retVal = gestureDetector.onTouchEvent(event) || retVal; - - if (event.getAction() == MotionEvent.ACTION_UP) { - if (scrolling) { - scrolling = false; - onScrollEnd(event); - } - } - return retVal; - } - - private void hideHandle() { - ScrollHandle scrollHandle = pdfView.getScrollHandle(); - if (scrollHandle != null && scrollHandle.shown()) { - scrollHandle.hideDelayed(); - } - } - - private boolean checkDoPageFling(float velocityX, float velocityY) { - float absX = Math.abs(velocityX); - float absY = Math.abs(velocityY); - return pdfView.isSwipeVertical() ? absY > absX : absX > absY; - } -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer; + +import android.graphics.PointF; +import android.graphics.RectF; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.view.View; + +import com.github.barteksc.pdfviewer.model.LinkTapEvent; +import com.github.barteksc.pdfviewer.scroll.ScrollHandle; +import com.github.barteksc.pdfviewer.util.SnapEdge; +import com.shockwave.pdfium.PdfDocument; +import com.shockwave.pdfium.util.SizeF; + +import static com.github.barteksc.pdfviewer.util.Constants.Pinch.MAXIMUM_ZOOM; +import static com.github.barteksc.pdfviewer.util.Constants.Pinch.MINIMUM_ZOOM; + +/** + * This Manager takes care of moving the PDFView, + * set its zoom track user actions. + */ +class DragPinchManager implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, ScaleGestureDetector.OnScaleGestureListener, View.OnTouchListener { + + private PDFView pdfView; + private AnimationManager animationManager; + + private GestureDetector gestureDetector; + private ScaleGestureDetector scaleGestureDetector; + + private boolean scrolling = false; + private boolean scaling = false; + private boolean enabled = false; + + DragPinchManager(PDFView pdfView, AnimationManager animationManager) { + this.pdfView = pdfView; + this.animationManager = animationManager; + gestureDetector = new GestureDetector(pdfView.getContext(), this); + scaleGestureDetector = new ScaleGestureDetector(pdfView.getContext(), this); + pdfView.setOnTouchListener(this); + } + + void enable() { + enabled = true; + } + + void disable() { + enabled = false; + } + + void disableLongpress(){ + gestureDetector.setIsLongpressEnabled(false); + } + + @Override + public boolean onSingleTapConfirmed(MotionEvent e) { + boolean onTapHandled = pdfView.callbacks.callOnTap(e); + boolean linkTapped = checkLinkTapped(e.getX(), e.getY()); + if (!onTapHandled && !linkTapped) { + ScrollHandle ps = pdfView.getScrollHandle(); + if (ps != null && !pdfView.documentFitsView()) { + if (!ps.shown()) { + ps.show(); + } else { + ps.hide(); + } + } + } + pdfView.performClick(); + return true; + } + + private boolean checkLinkTapped(float x, float y) { + PdfFile pdfFile = pdfView.pdfFile; + if (pdfFile == null) { + return false; + } + float mappedX = -pdfView.getCurrentXOffset() + x; + float mappedY = -pdfView.getCurrentYOffset() + y; + int page = pdfFile.getPageAtOffset(pdfView.isSwipeVertical() ? mappedY : mappedX, pdfView.getZoom()); + SizeF pageSize = pdfFile.getScaledPageSize(page, pdfView.getZoom()); + int pageX, pageY; + if (pdfView.isSwipeVertical()) { + pageX = (int) pdfFile.getSecondaryPageOffset(page, pdfView.getZoom()); + pageY = (int) pdfFile.getPageOffset(page, pdfView.getZoom()); + } else { + pageY = (int) pdfFile.getSecondaryPageOffset(page, pdfView.getZoom()); + pageX = (int) pdfFile.getPageOffset(page, pdfView.getZoom()); + } + for (PdfDocument.Link link : pdfFile.getPageLinks(page)) { + RectF mapped = pdfFile.mapRectToDevice(page, pageX, pageY, (int) pageSize.getWidth(), + (int) pageSize.getHeight(), link.getBounds()); + mapped.sort(); + if (mapped.contains(mappedX, mappedY)) { + pdfView.callbacks.callLinkHandler(new LinkTapEvent(x, y, mappedX, mappedY, mapped, link)); + return true; + } + } + return false; + } + + private void startPageFling(MotionEvent downEvent, MotionEvent ev, float velocityX, float velocityY) { + if (!checkDoPageFling(velocityX, velocityY)) { + return; + } + + int direction; + if (pdfView.isSwipeVertical()) { + direction = velocityY > 0 ? -1 : 1; + } else { + direction = velocityX > 0 ? -1 : 1; + } + // get the focused page during the down event to ensure only a single page is changed + float delta = pdfView.isSwipeVertical() ? ev.getY() - downEvent.getY() : ev.getX() - downEvent.getX(); + float offsetX = pdfView.getCurrentXOffset() - delta * pdfView.getZoom(); + float offsetY = pdfView.getCurrentYOffset() - delta * pdfView.getZoom(); + int startingPage = pdfView.findFocusPage(offsetX, offsetY); + int targetPage = Math.max(0, Math.min(pdfView.getPageCount() - 1, startingPage + direction)); + + SnapEdge edge = pdfView.findSnapEdge(targetPage); + float offset = pdfView.snapOffsetForPage(targetPage, edge); + animationManager.startPageFlingAnimation(-offset); + } + + @Override + public boolean onDoubleTap(MotionEvent e) { + if (!pdfView.isDoubletapEnabled()) { + return false; + } + + if (pdfView.getZoom() < pdfView.getMidZoom()) { + pdfView.zoomWithAnimation(e.getX(), e.getY(), pdfView.getMidZoom()); + } else if (pdfView.getZoom() < pdfView.getMaxZoom()) { + pdfView.zoomWithAnimation(e.getX(), e.getY(), pdfView.getMaxZoom()); + } else { + pdfView.resetZoomWithAnimation(); + } + return true; + } + + @Override + public boolean onDoubleTapEvent(MotionEvent e) { + return false; + } + + @Override + public boolean onDown(MotionEvent e) { + animationManager.stopFling(); + return true; + } + + @Override + public void onShowPress(MotionEvent e) { + + } + + @Override + public boolean onSingleTapUp(MotionEvent e) { + return false; + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + scrolling = true; + if (pdfView.isZooming() || pdfView.isSwipeEnabled()) { + pdfView.moveRelativeTo(-distanceX, -distanceY); + } + if (!scaling || pdfView.doRenderDuringScale()) { + pdfView.loadPageByOffset(); + } + return true; + } + + private void onScrollEnd(MotionEvent event) { + pdfView.loadPages(); + hideHandle(); + if (!animationManager.isFlinging()) { + pdfView.performPageSnap(); + } + } + + @Override + public void onLongPress(MotionEvent e) { + pdfView.callbacks.callOnLongPress(e); + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + if (!pdfView.isSwipeEnabled()) { + return false; + } + if (pdfView.isPageFlingEnabled()) { + if (pdfView.pageFillsScreen()) { + onBoundedFling(velocityX, velocityY); + } else { + startPageFling(e1, e2, velocityX, velocityY); + } + return true; + } + + int xOffset = (int) pdfView.getCurrentXOffset(); + int yOffset = (int) pdfView.getCurrentYOffset(); + + float minX, minY; + PdfFile pdfFile = pdfView.pdfFile; + if (pdfView.isSwipeVertical()) { + minX = -(pdfView.toCurrentScale(pdfFile.getMaxPageWidth()) - pdfView.getWidth()); + minY = -(pdfFile.getDocLen(pdfView.getZoom()) - pdfView.getHeight()); + } else { + minX = -(pdfFile.getDocLen(pdfView.getZoom()) - pdfView.getWidth()); + minY = -(pdfView.toCurrentScale(pdfFile.getMaxPageHeight()) - pdfView.getHeight()); + } + + animationManager.startFlingAnimation(xOffset, yOffset, (int) (velocityX), (int) (velocityY), + (int) minX, 0, (int) minY, 0); + return true; + } + + private void onBoundedFling(float velocityX, float velocityY) { + int xOffset = (int) pdfView.getCurrentXOffset(); + int yOffset = (int) pdfView.getCurrentYOffset(); + + PdfFile pdfFile = pdfView.pdfFile; + + float pageStart = -pdfFile.getPageOffset(pdfView.getCurrentPage(), pdfView.getZoom()); + float pageEnd = pageStart - pdfFile.getPageLength(pdfView.getCurrentPage(), pdfView.getZoom()); + float minX, minY, maxX, maxY; + if (pdfView.isSwipeVertical()) { + minX = -(pdfView.toCurrentScale(pdfFile.getMaxPageWidth()) - pdfView.getWidth()); + minY = pageEnd + pdfView.getHeight(); + maxX = 0; + maxY = pageStart; + } else { + minX = pageEnd + pdfView.getWidth(); + minY = -(pdfView.toCurrentScale(pdfFile.getMaxPageHeight()) - pdfView.getHeight()); + maxX = pageStart; + maxY = 0; + } + + animationManager.startFlingAnimation(xOffset, yOffset, (int) (velocityX), (int) (velocityY), + (int) minX, (int) maxX, (int) minY, (int) maxY); + } + + @Override + public boolean onScale(ScaleGestureDetector detector) { + float dr = detector.getScaleFactor(); + float wantedZoom = pdfView.getZoom() * dr; + float minZoom = Math.min(MINIMUM_ZOOM, pdfView.getMinZoom()); + float maxZoom = Math.min(MAXIMUM_ZOOM, pdfView.getMaxZoom()); + if (wantedZoom < minZoom) { + dr = minZoom / pdfView.getZoom(); + } else if (wantedZoom > maxZoom) { + dr = maxZoom / pdfView.getZoom(); + } + pdfView.zoomCenteredRelativeTo(dr, new PointF(detector.getFocusX(), detector.getFocusY())); + return true; + } + + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + scaling = true; + return true; + } + + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + pdfView.loadPages(); + hideHandle(); + scaling = false; + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (!enabled) { + return false; + } + + boolean retVal = scaleGestureDetector.onTouchEvent(event); + retVal = gestureDetector.onTouchEvent(event) || retVal; + + if (event.getAction() == MotionEvent.ACTION_UP) { + if (scrolling) { + scrolling = false; + onScrollEnd(event); + } + } + return retVal; + } + + private void hideHandle() { + ScrollHandle scrollHandle = pdfView.getScrollHandle(); + if (scrollHandle != null && scrollHandle.shown()) { + scrollHandle.hideDelayed(); + } + } + + private boolean checkDoPageFling(float velocityX, float velocityY) { + float absX = Math.abs(velocityX); + float absY = Math.abs(velocityY); + return pdfView.isSwipeVertical() ? absY > absX : absX > absY; + } +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java index 5946100a..8f37f7ea 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java @@ -1,1595 +1,1595 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.PaintFlagsDrawFilter; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.HandlerThread; -import android.util.AttributeSet; -import android.util.Log; -import android.widget.RelativeLayout; - -import com.github.barteksc.pdfviewer.exception.PageRenderingException; -import com.github.barteksc.pdfviewer.link.DefaultLinkHandler; -import com.github.barteksc.pdfviewer.link.LinkHandler; -import com.github.barteksc.pdfviewer.listener.Callbacks; -import com.github.barteksc.pdfviewer.listener.OnDrawListener; -import com.github.barteksc.pdfviewer.listener.OnErrorListener; -import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener; -import com.github.barteksc.pdfviewer.listener.OnLongPressListener; -import com.github.barteksc.pdfviewer.listener.OnPageChangeListener; -import com.github.barteksc.pdfviewer.listener.OnPageErrorListener; -import com.github.barteksc.pdfviewer.listener.OnPageScrollListener; -import com.github.barteksc.pdfviewer.listener.OnRenderListener; -import com.github.barteksc.pdfviewer.listener.OnTapListener; -import com.github.barteksc.pdfviewer.model.PagePart; -import com.github.barteksc.pdfviewer.scroll.ScrollHandle; -import com.github.barteksc.pdfviewer.source.AssetSource; -import com.github.barteksc.pdfviewer.source.ByteArraySource; -import com.github.barteksc.pdfviewer.source.DocumentSource; -import com.github.barteksc.pdfviewer.source.FileSource; -import com.github.barteksc.pdfviewer.source.InputStreamSource; -import com.github.barteksc.pdfviewer.source.UriSource; -import com.github.barteksc.pdfviewer.util.Constants; -import com.github.barteksc.pdfviewer.util.FitPolicy; -import com.github.barteksc.pdfviewer.util.MathUtils; -import com.github.barteksc.pdfviewer.util.SnapEdge; -import com.github.barteksc.pdfviewer.util.Util; -import com.shockwave.pdfium.PdfDocument; -import com.shockwave.pdfium.PdfiumCore; -import com.shockwave.pdfium.util.Size; -import com.shockwave.pdfium.util.SizeF; - -import java.io.File; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * It supports animations, zoom, cache, and swipe. - *

- * To fully understand this class you must know its principles : - * - The PDF document is seen as if we always want to draw all the pages. - * - The thing is that we only draw the visible parts. - * - All parts are the same size, this is because we can't interrupt a native page rendering, - * so we need these renderings to be as fast as possible, and be able to interrupt them - * as soon as we can. - * - The parts are loaded when the current offset or the current zoom level changes - *

- * Important : - * - DocumentPage = A page of the PDF document. - * - UserPage = A page as defined by the user. - * By default, they're the same. But the user can change the pages order - * using {@link #load(DocumentSource, String, int[])}. In this - * particular case, a userPage of 5 can refer to a documentPage of 17. - */ -public class PDFView extends RelativeLayout { - - private static final String TAG = PDFView.class.getSimpleName(); - - public static final float DEFAULT_MAX_SCALE = 3.0f; - public static final float DEFAULT_MID_SCALE = 1.75f; - public static final float DEFAULT_MIN_SCALE = 1.0f; - - private float minZoom = DEFAULT_MIN_SCALE; - private float midZoom = DEFAULT_MID_SCALE; - private float maxZoom = DEFAULT_MAX_SCALE; - - /** - * START - scrolling in first page direction - * END - scrolling in last page direction - * NONE - not scrolling - */ - enum ScrollDir { - NONE, START, END - } - - private ScrollDir scrollDir = ScrollDir.NONE; - - /** Rendered parts go to the cache manager */ - CacheManager cacheManager; - - /** Animation manager manage all offset and zoom animation */ - private AnimationManager animationManager; - - /** Drag manager manage all touch events */ - private DragPinchManager dragPinchManager; - - PdfFile pdfFile; - - /** The index of the current sequence */ - private int currentPage; - - /** - * If you picture all the pages side by side in their optimal width, - * and taking into account the zoom level, the current offset is the - * position of the left border of the screen in this big picture - */ - private float currentXOffset = 0; - - /** - * If you picture all the pages side by side in their optimal width, - * and taking into account the zoom level, the current offset is the - * position of the left border of the screen in this big picture - */ - private float currentYOffset = 0; - - /** The zoom level, always >= 1 */ - private float zoom = 1f; - - /** True if the PDFView has been recycled */ - private boolean recycled = true; - - /** Current state of the view */ - private State state = State.DEFAULT; - - /** Async task used during the loading phase to decode a PDF document */ - private DecodingAsyncTask decodingAsyncTask; - - /** The thread {@link #renderingHandler} will run on */ - private HandlerThread renderingHandlerThread; - /** Handler always waiting in the background and rendering tasks */ - RenderingHandler renderingHandler; - - private PagesLoader pagesLoader; - - Callbacks callbacks = new Callbacks(); - - /** Paint object for drawing */ - private Paint paint; - - /** Paint object for drawing debug stuff */ - private Paint debugPaint; - - /** Policy for fitting pages to screen */ - private FitPolicy pageFitPolicy = FitPolicy.WIDTH; - - private boolean fitEachPage = false; - - private int defaultPage = 0; - - private boolean dualPageMode = false; - - private boolean isLandscapeOrientation = false; - - /** True if should scroll through pages vertically instead of horizontally */ - private boolean swipeVertical = true; - - private boolean enableSwipe = true; - - private boolean doubletapEnabled = true; - - private boolean nightMode = false; - - private boolean pageSnap = true; - - /** Pdfium core for loading and rendering PDFs */ - private PdfiumCore pdfiumCore; - - private ScrollHandle scrollHandle; - - private boolean isScrollHandleInit = false; - - ScrollHandle getScrollHandle() { - return scrollHandle; - } - - /** - * True if bitmap should use ARGB_8888 format and take more memory - * False if bitmap should be compressed by using RGB_565 format and take less memory - */ - private boolean bestQuality = false; - - /** - * True if annotations should be rendered - * False otherwise - */ - private boolean annotationRendering = false; - - /** - * True if the view should render during scaling
- * Can not be forced on older API versions (< Build.VERSION_CODES.KITKAT) as the GestureDetector does - * not detect scrolling while scaling.
- * False otherwise - */ - private boolean renderDuringScale = false; - - /** Antialiasing and bitmap filtering */ - private boolean enableAntialiasing = true; - private PaintFlagsDrawFilter antialiasFilter = - new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); - - /** Spacing between pages, in px */ - private int spacingPx = 0; - - /** Add dynamic spacing to fit each page separately on the screen. */ - private boolean autoSpacing = false; - - /** Fling a single page at a time */ - private boolean pageFling = true; - - /** Pages numbers used when calling onDrawAllListener */ - private List onDrawPagesNums = new ArrayList<>(10); - - /** Holds info whether view has been added to layout and has width and height */ - private boolean hasSize = false; - - /** Holds last used Configurator that should be loaded when view has size */ - private Configurator waitingDocumentConfigurator; - - /** Construct the initial view */ - public PDFView(Context context, AttributeSet set) { - super(context, set); - - renderingHandlerThread = new HandlerThread("PDF renderer"); - - if (isInEditMode()) { - return; - } - - cacheManager = new CacheManager(); - animationManager = new AnimationManager(this); - dragPinchManager = new DragPinchManager(this, animationManager); - pagesLoader = new PagesLoader(this); - - paint = new Paint(); - debugPaint = new Paint(); - debugPaint.setStyle(Style.STROKE); - - pdfiumCore = new PdfiumCore(context); - setWillNotDraw(false); - } - - private void load(DocumentSource docSource, String password) { - load(docSource, password, null); - } - - private void load(DocumentSource docSource, String password, int[] userPages) { - - if (!recycled) { - throw new IllegalStateException("Don't call load on a PDF View without recycling it first."); - } - - recycled = false; - // Start decoding document - decodingAsyncTask = new DecodingAsyncTask(docSource, password, userPages, this, pdfiumCore); - decodingAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - /** - * Go to the given page. - * - * @param page Page index. - */ - public void jumpTo(int page, boolean withAnimation) { - if (pdfFile == null) { - return; - } - - page = pdfFile.determineValidPageNumberFrom(page); - float offset = page == 0 ? 0 : -pdfFile.getPageOffset(page, zoom); - if (swipeVertical) { - if (withAnimation) { - animationManager.startYAnimation(currentYOffset, offset); - } else { - moveTo(currentXOffset, offset); - } - } else { - if (withAnimation) { - animationManager.startXAnimation(currentXOffset, offset); - } else { - moveTo(offset, currentYOffset); - } - } - showPage(page); - } - - public void jumpTo(int page) { - jumpTo(page, false); - } - - void showPage(int pageNb) { - if (recycled) { - return; - } - - // Check the page number and makes the - // difference between UserPages and DocumentPages - pageNb = pdfFile.determineValidPageNumberFrom(pageNb); - currentPage = pageNb; - - loadPages(); - - if (scrollHandle != null && !documentFitsView()) { - scrollHandle.setPageNum(currentPage + 1); - } - - callbacks.callOnPageChange(currentPage, pdfFile.getPagesCount()); - } - - /** - * Get current position as ratio of document length to visible area. - * 0 means that document start is visible, 1 that document end is visible - * - * @return offset between 0 and 1 - */ - public float getPositionOffset() { - float offset; - if (swipeVertical) { - offset = -currentYOffset / (pdfFile.getDocLen(zoom) - getHeight()); - } else { - offset = -currentXOffset / (pdfFile.getDocLen(zoom) - getWidth()); - } - return MathUtils.limit(offset, 0, 1); - } - - /** - * @param progress must be between 0 and 1 - * @param moveHandle whether to move scroll handle - * @see PDFView#getPositionOffset() - */ - public void setPositionOffset(float progress, boolean moveHandle) { - if (swipeVertical) { - moveTo(currentXOffset, (-pdfFile.getDocLen(zoom) + getHeight()) * progress, moveHandle); - } else { - moveTo((-pdfFile.getDocLen(zoom) + getWidth()) * progress, currentYOffset, moveHandle); - } - loadPageByOffset(); - } - - public void setPositionOffset(float progress) { - setPositionOffset(progress, true); - } - - public void stopFling() { - animationManager.stopFling(); - } - - public int getPageCount() { - if (pdfFile == null) { - return 0; - } - return pdfFile.getPagesCount(); - } - - public void setSwipeEnabled(boolean enableSwipe) { - this.enableSwipe = enableSwipe; - } - - public void setNightMode(boolean nightMode) { - this.nightMode = nightMode; - if (nightMode) { - ColorMatrix colorMatrixInverted = - new ColorMatrix(new float[]{ - -1, 0, 0, 0, 255, - 0, -1, 0, 0, 255, - 0, 0, -1, 0, 255, - 0, 0, 0, 1, 0}); - - ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrixInverted); - paint.setColorFilter(filter); - } else { - paint.setColorFilter(null); - } - } - - void enableDoubletap(boolean enableDoubletap) { - this.doubletapEnabled = enableDoubletap; - } - - boolean isDoubletapEnabled() { - return doubletapEnabled; - } - - void onPageError(PageRenderingException ex) { - if (!callbacks.callOnPageError(ex.getPage(), ex.getCause())) { - Log.e(TAG, "Cannot open page " + ex.getPage(), ex.getCause()); - } - } - - public void recycle() { - waitingDocumentConfigurator = null; - - animationManager.stopAll(); - dragPinchManager.disable(); - - // Stop tasks - if (renderingHandler != null) { - renderingHandler.stop(); - renderingHandler.removeMessages(RenderingHandler.MSG_RENDER_TASK); - } - if (decodingAsyncTask != null) { - decodingAsyncTask.cancel(true); - } - - // Clear caches - cacheManager.recycle(); - - if (scrollHandle != null && isScrollHandleInit) { - scrollHandle.destroyLayout(); - } - - if (pdfFile != null) { - pdfFile.dispose(); - pdfFile = null; - } - - renderingHandler = null; - scrollHandle = null; - isScrollHandleInit = false; - currentXOffset = currentYOffset = 0; - zoom = 1f; - recycled = true; - callbacks = new Callbacks(); - state = State.DEFAULT; - } - - public boolean isRecycled() { - return recycled; - } - - /** Handle fling animation */ - @Override - public void computeScroll() { - super.computeScroll(); - if (isInEditMode()) { - return; - } - animationManager.computeFling(); - } - - @Override - protected void onDetachedFromWindow() { - recycle(); - if (renderingHandlerThread != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - renderingHandlerThread.quitSafely(); - } else { - renderingHandlerThread.quit(); - } - renderingHandlerThread = null; - } - super.onDetachedFromWindow(); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - hasSize = true; - if (waitingDocumentConfigurator != null) { - waitingDocumentConfigurator.load(); - } - if (isInEditMode() || state != State.SHOWN) { - return; - } - - // calculates the position of the point which in the center of view relative to big strip - float centerPointInStripXOffset = -currentXOffset + oldw * 0.5f; - float centerPointInStripYOffset = -currentYOffset + oldh * 0.5f; - - float relativeCenterPointInStripXOffset; - float relativeCenterPointInStripYOffset; - - if (swipeVertical){ - relativeCenterPointInStripXOffset = centerPointInStripXOffset / pdfFile.getMaxPageWidth(); - relativeCenterPointInStripYOffset = centerPointInStripYOffset / pdfFile.getDocLen(zoom); - }else { - relativeCenterPointInStripXOffset = centerPointInStripXOffset / pdfFile.getDocLen(zoom); - relativeCenterPointInStripYOffset = centerPointInStripYOffset / pdfFile.getMaxPageHeight(); - } - - animationManager.stopAll(); - pdfFile.recalculatePageSizes(new Size(w, h)); - - if (swipeVertical) { - currentXOffset = -relativeCenterPointInStripXOffset * pdfFile.getMaxPageWidth() + w * 0.5f; - currentYOffset = -relativeCenterPointInStripYOffset * pdfFile.getDocLen(zoom) + h * 0.5f ; - }else { - currentXOffset = -relativeCenterPointInStripXOffset * pdfFile.getDocLen(zoom) + w * 0.5f; - currentYOffset = -relativeCenterPointInStripYOffset * pdfFile.getMaxPageHeight() + h * 0.5f; - } - moveTo(currentXOffset,currentYOffset); - loadPageByOffset(); - } - - @Override - public boolean canScrollHorizontally(int direction) { - if (pdfFile == null) { - return true; - } - - if (swipeVertical) { - if (direction < 0 && currentXOffset < 0) { - return true; - } else if (direction > 0 && currentXOffset + toCurrentScale(pdfFile.getMaxPageWidth()) > getWidth()) { - return true; - } - } else { - if (direction < 0 && currentXOffset < 0) { - return true; - } else if (direction > 0 && currentXOffset + pdfFile.getDocLen(zoom) > getWidth()) { - return true; - } - } - return false; - } - - @Override - public boolean canScrollVertically(int direction) { - if (pdfFile == null) { - return true; - } - - if (swipeVertical) { - if (direction < 0 && currentYOffset < 0) { - return true; - } else if (direction > 0 && currentYOffset + pdfFile.getDocLen(zoom) > getHeight()) { - return true; - } - } else { - if (direction < 0 && currentYOffset < 0) { - return true; - } else if (direction > 0 && currentYOffset + toCurrentScale(pdfFile.getMaxPageHeight()) > getHeight()) { - return true; - } - } - return false; - } - - @Override - protected void onDraw(Canvas canvas) { - if (isInEditMode()) { - return; - } - // As I said in this class javadoc, we can think of this canvas as a huge - // strip on which we draw all the images. We actually only draw the rendered - // parts, of course, but we render them in the place they belong in this huge - // strip. - - // That's where Canvas.translate(x, y) becomes very helpful. - // This is the situation : - // _______________________________________________ - // | | | - // | the actual | The big strip | - // | canvas | | - // |_____________| | - // |_______________________________________________| - // - // If the rendered part is on the bottom right corner of the strip - // we can draw it but we won't see it because the canvas is not big enough. - - // But if we call translate(-X, -Y) on the canvas just before drawing the object : - // _______________________________________________ - // | _____________| - // | The big strip | | - // | | the actual | - // | | canvas | - // |_________________________________|_____________| - // - // The object will be on the canvas. - // This technique is massively used in this method, and allows - // abstraction of the screen position when rendering the parts. - - // Draws background - - if (enableAntialiasing) { - canvas.setDrawFilter(antialiasFilter); - } - - Drawable bg = getBackground(); - if (bg == null) { - canvas.drawColor(nightMode ? Color.BLACK : Color.WHITE); - } else { - bg.draw(canvas); - } - - if (recycled) { - return; - } - - if (state != State.SHOWN) { - return; - } - - // Moves the canvas before drawing any element - float currentXOffset = this.currentXOffset; - float currentYOffset = this.currentYOffset; - canvas.translate(currentXOffset, currentYOffset); - - // Draws thumbnails - for (PagePart part : cacheManager.getThumbnails()) { - drawPart(canvas, part); - - } - - // Draws parts - for (PagePart part : cacheManager.getPageParts()) { - drawPart(canvas, part); - if (callbacks.getOnDrawAll() != null - && !onDrawPagesNums.contains(part.getPage())) { - onDrawPagesNums.add(part.getPage()); - } - } - - for (Integer page : onDrawPagesNums) { - drawWithListener(canvas, page, callbacks.getOnDrawAll()); - } - onDrawPagesNums.clear(); - - drawWithListener(canvas, currentPage, callbacks.getOnDraw()); - - // Restores the canvas position - canvas.translate(-currentXOffset, -currentYOffset); - } - - private void drawWithListener(Canvas canvas, int page, OnDrawListener listener) { - if (listener != null) { - float translateX, translateY; - if (swipeVertical) { - translateX = 0; - translateY = pdfFile.getPageOffset(page, zoom); - } else { - translateY = 0; - translateX = pdfFile.getPageOffset(page, zoom); - } - - canvas.translate(translateX, translateY); - SizeF size = pdfFile.getPageSize(page); - listener.onLayerDrawn(canvas, - toCurrentScale(size.getWidth()), - toCurrentScale(size.getHeight()), - page); - - canvas.translate(-translateX, -translateY); - } - } - - /** Draw a given PagePart on the canvas */ - private void drawPart(Canvas canvas, PagePart part) { - // Can seem strange, but avoid lot of calls - RectF pageRelativeBounds = part.getPageRelativeBounds(); - Bitmap renderedBitmap = part.getRenderedBitmap(); - - if (renderedBitmap.isRecycled()) { - return; - } - - // Move to the target page - float localTranslationX = 0; - float localTranslationY = 0; - SizeF size = pdfFile.getPageSize(part.getPage()); - - if (swipeVertical) { - localTranslationY = pdfFile.getPageOffset(part.getPage(), zoom); - float maxWidth = pdfFile.getMaxPageWidth(); - localTranslationX = toCurrentScale(maxWidth - size.getWidth()) / 2; - } else { - localTranslationX = pdfFile.getPageOffset(part.getPage(), zoom); - float maxHeight = pdfFile.getMaxPageHeight(); - localTranslationY = toCurrentScale(maxHeight - size.getHeight()) / 2; - } - canvas.translate(localTranslationX, localTranslationY); - - Rect srcRect = new Rect(0, 0, renderedBitmap.getWidth(), - renderedBitmap.getHeight()); - - float offsetX = toCurrentScale(pageRelativeBounds.left * size.getWidth()); - float offsetY = toCurrentScale(pageRelativeBounds.top * size.getHeight()); - float width = toCurrentScale(pageRelativeBounds.width() * size.getWidth()); - float height = toCurrentScale(pageRelativeBounds.height() * size.getHeight()); - - // If we use float values for this rectangle, there will be - // a possible gap between page parts, especially when - // the zoom level is high. - RectF dstRect = new RectF((int) offsetX, (int) offsetY, - (int) (offsetX + width), - (int) (offsetY + height)); - - // Check if bitmap is in the screen - float translationX = currentXOffset + localTranslationX; - float translationY = currentYOffset + localTranslationY; - if (translationX + dstRect.left >= getWidth() || translationX + dstRect.right <= 0 || - translationY + dstRect.top >= getHeight() || translationY + dstRect.bottom <= 0) { - canvas.translate(-localTranslationX, -localTranslationY); - return; - } - - canvas.drawBitmap(renderedBitmap, srcRect, dstRect, paint); - - if (Constants.DEBUG_MODE) { - debugPaint.setColor(part.getPage() % 2 == 0 ? Color.RED : Color.BLUE); - canvas.drawRect(dstRect, debugPaint); - } - - // Restore the canvas position - canvas.translate(-localTranslationX, -localTranslationY); - - } - - /** - * Load all the parts around the center of the screen, - * taking into account X and Y offsets, zoom level, and - * the current page displayed - */ - public void loadPages() { - if (pdfFile == null || renderingHandler == null) { - return; - } - - // Cancel all current tasks - renderingHandler.removeMessages(RenderingHandler.MSG_RENDER_TASK); - cacheManager.makeANewSet(); - - pagesLoader.loadPages(); - redraw(); - } - - /** Called when the PDF is loaded */ - void loadComplete(PdfFile pdfFile) { - state = State.LOADED; - - this.pdfFile = pdfFile; - - if (!renderingHandlerThread.isAlive()) { - renderingHandlerThread.start(); - } - renderingHandler = new RenderingHandler(renderingHandlerThread.getLooper(), this); - renderingHandler.start(); - - if (scrollHandle != null) { - scrollHandle.setupLayout(this); - isScrollHandleInit = true; - } - - dragPinchManager.enable(); - - callbacks.callOnLoadComplete(pdfFile.getPagesCount()); - - jumpTo(defaultPage, false); - } - - void loadError(Throwable t) { - state = State.ERROR; - // store reference, because callbacks will be cleared in recycle() method - OnErrorListener onErrorListener = callbacks.getOnError(); - recycle(); - invalidate(); - if (onErrorListener != null) { - onErrorListener.onError(t); - } else { - Log.e("PDFView", "load pdf error", t); - } - } - - void redraw() { - invalidate(); - } - - /** - * Called when a rendering task is over and - * a PagePart has been freshly created. - * - * @param part The created PagePart. - */ - public void onBitmapRendered(PagePart part) { - // when it is first rendered part - if (state == State.LOADED) { - state = State.SHOWN; - callbacks.callOnRender(pdfFile.getPagesCount()); - } - - if (part.isThumbnail()) { - cacheManager.cacheThumbnail(part); - } else { - cacheManager.cachePart(part); - } - redraw(); - } - - public void moveTo(float offsetX, float offsetY) { - moveTo(offsetX, offsetY, true); - } - - /** - * Move to the given X and Y offsets, but check them ahead of time - * to be sure not to go outside the the big strip. - * - * @param offsetX The big strip X offset to use as the left border of the screen. - * @param offsetY The big strip Y offset to use as the right border of the screen. - * @param moveHandle whether to move scroll handle or not - */ - public void moveTo(float offsetX, float offsetY, boolean moveHandle) { - if (swipeVertical) { - // Check X offset - float scaledPageWidth = toCurrentScale(pdfFile.getMaxPageWidth()); - if (scaledPageWidth < getWidth()) { - offsetX = getWidth() / 2 - scaledPageWidth / 2; - } else { - if (offsetX > 0) { - offsetX = 0; - } else if (offsetX + scaledPageWidth < getWidth()) { - offsetX = getWidth() - scaledPageWidth; - } - } - - // Check Y offset - float contentHeight = pdfFile.getDocLen(zoom); - if (contentHeight < getHeight()) { // whole document height visible on screen - offsetY = (getHeight() - contentHeight) / 2; - } else { - if (offsetY > 0) { // top visible - offsetY = 0; - } else if (offsetY + contentHeight < getHeight()) { // bottom visible - offsetY = -contentHeight + getHeight(); - } - } - - if (offsetY < currentYOffset) { - scrollDir = ScrollDir.END; - } else if (offsetY > currentYOffset) { - scrollDir = ScrollDir.START; - } else { - scrollDir = ScrollDir.NONE; - } - } else { - // Check Y offset - float scaledPageHeight = toCurrentScale(pdfFile.getMaxPageHeight()); - if (scaledPageHeight < getHeight()) { - offsetY = getHeight() / 2 - scaledPageHeight / 2; - } else { - if (offsetY > 0) { - offsetY = 0; - } else if (offsetY + scaledPageHeight < getHeight()) { - offsetY = getHeight() - scaledPageHeight; - } - } - - // Check X offset - float contentWidth = pdfFile.getDocLen(zoom); - if (contentWidth < getWidth()) { // whole document width visible on screen - offsetX = (getWidth() - contentWidth) / 2; - } else { - if (offsetX > 0) { // left visible - offsetX = 0; - } else if (offsetX + contentWidth < getWidth()) { // right visible - offsetX = -contentWidth + getWidth(); - } - } - - if (offsetX < currentXOffset) { - scrollDir = ScrollDir.END; - } else if (offsetX > currentXOffset) { - scrollDir = ScrollDir.START; - } else { - scrollDir = ScrollDir.NONE; - } - } - - currentXOffset = offsetX; - currentYOffset = offsetY; - float positionOffset = getPositionOffset(); - - if (moveHandle && scrollHandle != null && !documentFitsView()) { - scrollHandle.setScroll(positionOffset); - } - - callbacks.callOnPageScroll(getCurrentPage(), positionOffset); - - redraw(); - } - - void loadPageByOffset() { - if (0 == pdfFile.getPagesCount()) { - return; - } - - float offset, screenCenter; - if (swipeVertical) { - offset = currentYOffset; - screenCenter = ((float) getHeight()) / 2; - } else { - offset = currentXOffset; - screenCenter = ((float) getWidth()) / 2; - } - - int page = pdfFile.getPageAtOffset(-(offset - screenCenter), zoom); - - if (page >= 0 && page <= pdfFile.getPagesCount() - 1 && page != getCurrentPage()) { - showPage(page); - } else { - loadPages(); - } - } - - /** - * Animate to the nearest snapping position for the current SnapPolicy - */ - public void performPageSnap() { - if (!pageSnap || pdfFile == null || pdfFile.getPagesCount() == 0) { - return; - } - int centerPage = findFocusPage(currentXOffset, currentYOffset); - SnapEdge edge = findSnapEdge(centerPage); - if (edge == SnapEdge.NONE) { - return; - } - - float offset = snapOffsetForPage(centerPage, edge); - if (swipeVertical) { - animationManager.startYAnimation(currentYOffset, -offset); - } else { - animationManager.startXAnimation(currentXOffset, -offset); - } - } - - /** - * Find the edge to snap to when showing the specified page - */ - SnapEdge findSnapEdge(int page) { - if (!pageSnap || page < 0) { - return SnapEdge.NONE; - } - float currentOffset = swipeVertical ? currentYOffset : currentXOffset; - float offset = -pdfFile.getPageOffset(page, zoom); - int length = swipeVertical ? getHeight() : getWidth(); - float pageLength = pdfFile.getPageLength(page, zoom); - - if (length >= pageLength) { - return SnapEdge.CENTER; - } else if (currentOffset >= offset) { - return SnapEdge.START; - } else if (offset - pageLength > currentOffset - length) { - return SnapEdge.END; - } else { - return SnapEdge.NONE; - } - } - - /** - * Get the offset to move to in order to snap to the page - */ - float snapOffsetForPage(int pageIndex, SnapEdge edge) { - float offset = pdfFile.getPageOffset(pageIndex, zoom); - - float length = swipeVertical ? getHeight() : getWidth(); - float pageLength = pdfFile.getPageLength(pageIndex, zoom); - - if (edge == SnapEdge.CENTER) { - offset = offset - length / 2f + pageLength / 2f; - } else if (edge == SnapEdge.END) { - offset = offset - length + pageLength; - } - return offset; - } - - int findFocusPage(float xOffset, float yOffset) { - float currOffset = swipeVertical ? yOffset : xOffset; - float length = swipeVertical ? getHeight() : getWidth(); - // make sure first and last page can be found - if (currOffset > -1) { - return 0; - } else if (currOffset < -pdfFile.getDocLen(zoom) + length + 1) { - return pdfFile.getPagesCount() - 1; - } - // else find page in center - float center = currOffset - length / 2f; - return pdfFile.getPageAtOffset(-center, zoom); - } - - /** - * @return true if single page fills the entire screen in the scrolling direction - */ - public boolean pageFillsScreen() { - float start = -pdfFile.getPageOffset(currentPage, zoom); - float end = start - pdfFile.getPageLength(currentPage, zoom); - if (isSwipeVertical()) { - return start > currentYOffset && end < currentYOffset - getHeight(); - } else { - return start > currentXOffset && end < currentXOffset - getWidth(); - } - } - - /** - * Move relatively to the current position. - * - * @param dx The X difference you want to apply. - * @param dy The Y difference you want to apply. - * @see #moveTo(float, float) - */ - public void moveRelativeTo(float dx, float dy) { - moveTo(currentXOffset + dx, currentYOffset + dy); - } - - /** - * Change the zoom level - */ - public void zoomTo(float zoom) { - this.zoom = zoom; - } - - /** - * Change the zoom level, relatively to a pivot point. - * It will call moveTo() to make sure the given point stays - * in the middle of the screen. - * - * @param zoom The zoom level. - * @param pivot The point on the screen that should stays. - */ - public void zoomCenteredTo(float zoom, PointF pivot) { - float dzoom = zoom / this.zoom; - zoomTo(zoom); - float baseX = currentXOffset * dzoom; - float baseY = currentYOffset * dzoom; - baseX += (pivot.x - pivot.x * dzoom); - baseY += (pivot.y - pivot.y * dzoom); - moveTo(baseX, baseY); - } - - /** - * @see #zoomCenteredTo(float, PointF) - */ - public void zoomCenteredRelativeTo(float dzoom, PointF pivot) { - zoomCenteredTo(zoom * dzoom, pivot); - } - - /** - * Checks if whole document can be displayed on screen, doesn't include zoom - * - * @return true if whole document can displayed at once, false otherwise - */ - public boolean documentFitsView() { - float len = pdfFile.getDocLen(1); - if (swipeVertical) { - return len < getHeight(); - } else { - return len < getWidth(); - } - } - - public void fitToWidth(int page) { - if (state != State.SHOWN) { - Log.e(TAG, "Cannot fit, document not rendered yet"); - return; - } - zoomTo(getWidth() / pdfFile.getPageSize(page).getWidth()); - jumpTo(page); - } - - public SizeF getPageSize(int pageIndex) { - if (pdfFile == null) { - return new SizeF(0, 0); - } - return pdfFile.getPageSize(pageIndex); - } - - public int getCurrentPage() { - return currentPage; - } - - public float getCurrentXOffset() { - return currentXOffset; - } - - public float getCurrentYOffset() { - return currentYOffset; - } - - public float toRealScale(float size) { - return size / zoom; - } - - public float toCurrentScale(float size) { - return size * zoom; - } - - public float getZoom() { - return zoom; - } - - public boolean isZooming() { - return zoom != minZoom; - } - - private void setDefaultPage(int defaultPage) { - this.defaultPage = defaultPage; - } - - public void resetZoom() { - zoomTo(minZoom); - } - - public void resetZoomWithAnimation() { - zoomWithAnimation(minZoom); - } - - public void zoomWithAnimation(float centerX, float centerY, float scale) { - animationManager.startZoomAnimation(centerX, centerY, zoom, scale); - } - - public void zoomWithAnimation(float scale) { - animationManager.startZoomAnimation(getWidth() / 2, getHeight() / 2, zoom, scale); - } - - private void setScrollHandle(ScrollHandle scrollHandle) { - this.scrollHandle = scrollHandle; - } - - /** - * Get page number at given offset - * - * @param positionOffset scroll offset between 0 and 1 - * @return page number at given offset, starting from 0 - */ - public int getPageAtPositionOffset(float positionOffset) { - return pdfFile.getPageAtOffset(pdfFile.getDocLen(zoom) * positionOffset, zoom); - } - - public float getMinZoom() { - return minZoom; - } - - public void setMinZoom(float minZoom) { - this.minZoom = minZoom; - } - - public float getMidZoom() { - return midZoom; - } - - public void setMidZoom(float midZoom) { - this.midZoom = midZoom; - } - - public float getMaxZoom() { - return maxZoom; - } - - public void setMaxZoom(float maxZoom) { - this.maxZoom = maxZoom; - } - - public void useBestQuality(boolean bestQuality) { - this.bestQuality = bestQuality; - } - - public boolean isBestQuality() { - return bestQuality; - } - - public boolean isOnDualPageMode() { - return dualPageMode; - } - - public boolean isOnLandscapeOrientation() { return isLandscapeOrientation; } - - public void setLandscapeOrientation(boolean landscapeOrientation) {this.isLandscapeOrientation = landscapeOrientation; } - - public void setDualPageMode(boolean dualPageMode) { - this.dualPageMode = dualPageMode; - } - - public boolean isSwipeVertical() { - return swipeVertical; - } - - public boolean isSwipeEnabled() { - return enableSwipe; - } - - private void setSwipeVertical(boolean swipeVertical) { - this.swipeVertical = swipeVertical; - } - - public void enableAnnotationRendering(boolean annotationRendering) { - this.annotationRendering = annotationRendering; - } - - public boolean isAnnotationRendering() { - return annotationRendering; - } - - public void enableRenderDuringScale(boolean renderDuringScale) { - this.renderDuringScale = renderDuringScale; - } - - public boolean isAntialiasing() { - return enableAntialiasing; - } - - public void enableAntialiasing(boolean enableAntialiasing) { - this.enableAntialiasing = enableAntialiasing; - } - - public int getSpacingPx() { - return spacingPx; - } - - public boolean isAutoSpacingEnabled() { - return autoSpacing; - } - - public void setPageFling(boolean pageFling) { - this.pageFling = pageFling; - } - - public boolean isPageFlingEnabled() { - return pageFling; - } - - private void setSpacing(int spacingDp) { - this.spacingPx = Util.getDP(getContext(), spacingDp); - } - - private void setAutoSpacing(boolean autoSpacing) { - this.autoSpacing = autoSpacing; - } - - private void setPageFitPolicy(FitPolicy pageFitPolicy) { - this.pageFitPolicy = pageFitPolicy; - } - - public FitPolicy getPageFitPolicy() { - return pageFitPolicy; - } - - private void setFitEachPage(boolean fitEachPage) { - this.fitEachPage = fitEachPage; - } - - public boolean isFitEachPage() { - return fitEachPage; - } - - public boolean isPageSnap() { - return pageSnap; - } - - public void setPageSnap(boolean pageSnap) { - this.pageSnap = pageSnap; - } - - public boolean doRenderDuringScale() { - return renderDuringScale; - } - - /** Returns null if document is not loaded */ - public PdfDocument.Meta getDocumentMeta() { - if (pdfFile == null) { - return null; - } - return pdfFile.getMetaData(); - } - - /** Will be empty until document is loaded */ - public List getTableOfContents() { - if (pdfFile == null) { - return Collections.emptyList(); - } - return pdfFile.getBookmarks(); - } - - /** Will be empty until document is loaded */ - public List getLinks(int page) { - if (pdfFile == null) { - return Collections.emptyList(); - } - return pdfFile.getPageLinks(page); - } - - /** Use an asset file as the pdf source */ - public Configurator fromAsset(String assetName) { - return new Configurator(new AssetSource(assetName)); - } - - /** Use a file as the pdf source */ - public Configurator fromFile(File file) { - return new Configurator(new FileSource(file)); - } - - /** Use URI as the pdf source, for use with content providers */ - public Configurator fromUri(Uri uri) { - return new Configurator(new UriSource(uri)); - } - - /** Use bytearray as the pdf source, documents is not saved */ - public Configurator fromBytes(byte[] bytes) { - return new Configurator(new ByteArraySource(bytes)); - } - - /** Use stream as the pdf source. Stream will be written to bytearray, because native code does not support Java Streams */ - public Configurator fromStream(InputStream stream) { - return new Configurator(new InputStreamSource(stream)); - } - - /** Use custom source as pdf source */ - public Configurator fromSource(DocumentSource docSource) { - return new Configurator(docSource); - } - - private enum State {DEFAULT, LOADED, SHOWN, ERROR} - - public class Configurator { - - private final DocumentSource documentSource; - - private int[] pageNumbers = null; - - private boolean enableSwipe = true; - - private boolean enableDoubletap = true; - - private OnDrawListener onDrawListener; - - private OnDrawListener onDrawAllListener; - - private OnLoadCompleteListener onLoadCompleteListener; - - private OnErrorListener onErrorListener; - - private OnPageChangeListener onPageChangeListener; - - private OnPageScrollListener onPageScrollListener; - - private OnRenderListener onRenderListener; - - private OnTapListener onTapListener; - - private OnLongPressListener onLongPressListener; - - private OnPageErrorListener onPageErrorListener; - - private LinkHandler linkHandler = new DefaultLinkHandler(PDFView.this); - - private int defaultPage = 0; - - private boolean landscapeOrientation = false; - - private boolean dualPageMode = false; - - private boolean swipeHorizontal = false; - - private boolean annotationRendering = false; - - private String password = null; - - private ScrollHandle scrollHandle = null; - - private boolean antialiasing = true; - - private int spacing = 0; - - private boolean autoSpacing = false; - - private FitPolicy pageFitPolicy = FitPolicy.WIDTH; - - private boolean fitEachPage = false; - - private boolean pageFling = false; - - private boolean pageSnap = false; - - private boolean nightMode = false; - - private Configurator(DocumentSource documentSource) { - this.documentSource = documentSource; - } - - public Configurator pages(int... pageNumbers) { - this.pageNumbers = pageNumbers; - return this; - } - - public Configurator enableSwipe(boolean enableSwipe) { - this.enableSwipe = enableSwipe; - return this; - } - - public Configurator enableDoubletap(boolean enableDoubletap) { - this.enableDoubletap = enableDoubletap; - return this; - } - - public Configurator enableAnnotationRendering(boolean annotationRendering) { - this.annotationRendering = annotationRendering; - return this; - } - - public Configurator onDraw(OnDrawListener onDrawListener) { - this.onDrawListener = onDrawListener; - return this; - } - - public Configurator onDrawAll(OnDrawListener onDrawAllListener) { - this.onDrawAllListener = onDrawAllListener; - return this; - } - - public Configurator onLoad(OnLoadCompleteListener onLoadCompleteListener) { - this.onLoadCompleteListener = onLoadCompleteListener; - return this; - } - - public Configurator onPageScroll(OnPageScrollListener onPageScrollListener) { - this.onPageScrollListener = onPageScrollListener; - return this; - } - - public Configurator onError(OnErrorListener onErrorListener) { - this.onErrorListener = onErrorListener; - return this; - } - - public Configurator onPageError(OnPageErrorListener onPageErrorListener) { - this.onPageErrorListener = onPageErrorListener; - return this; - } - - public Configurator onPageChange(OnPageChangeListener onPageChangeListener) { - this.onPageChangeListener = onPageChangeListener; - return this; - } - - public Configurator onRender(OnRenderListener onRenderListener) { - this.onRenderListener = onRenderListener; - return this; - } - - public Configurator onTap(OnTapListener onTapListener) { - this.onTapListener = onTapListener; - return this; - } - - public Configurator onLongPress(OnLongPressListener onLongPressListener) { - this.onLongPressListener = onLongPressListener; - return this; - } - - public Configurator linkHandler(LinkHandler linkHandler) { - this.linkHandler = linkHandler; - return this; - } - - public Configurator defaultPage(int defaultPage) { - this.defaultPage = defaultPage; - return this; - } - - public Configurator landscapeOrientation(boolean landscapeOrientation) { - this.landscapeOrientation = landscapeOrientation; - return this; - } - - public Configurator dualPageMode(boolean dualPageMode) { - this.dualPageMode = dualPageMode; - return this; - } - - public Configurator swipeHorizontal(boolean swipeHorizontal) { - this.swipeHorizontal = swipeHorizontal; - return this; - } - - public Configurator password(String password) { - this.password = password; - return this; - } - - public Configurator scrollHandle(ScrollHandle scrollHandle) { - this.scrollHandle = scrollHandle; - return this; - } - - public Configurator enableAntialiasing(boolean antialiasing) { - this.antialiasing = antialiasing; - return this; - } - - public Configurator spacing(int spacing) { - this.spacing = spacing; - return this; - } - - public Configurator autoSpacing(boolean autoSpacing) { - this.autoSpacing = autoSpacing; - return this; - } - - public Configurator pageFitPolicy(FitPolicy pageFitPolicy) { - this.pageFitPolicy = pageFitPolicy; - return this; - } - - public Configurator fitEachPage(boolean fitEachPage) { - this.fitEachPage = fitEachPage; - return this; - } - - public Configurator pageSnap(boolean pageSnap) { - this.pageSnap = pageSnap; - return this; - } - - public Configurator pageFling(boolean pageFling) { - this.pageFling = pageFling; - return this; - } - - public Configurator nightMode(boolean nightMode) { - this.nightMode = nightMode; - return this; - } - - public Configurator disableLongpress() { - PDFView.this.dragPinchManager.disableLongpress(); - return this; - } - - public void load() { - if (!hasSize) { - waitingDocumentConfigurator = this; - return; - } - PDFView.this.recycle(); - PDFView.this.callbacks.setOnLoadComplete(onLoadCompleteListener); - PDFView.this.callbacks.setOnError(onErrorListener); - PDFView.this.callbacks.setOnDraw(onDrawListener); - PDFView.this.callbacks.setOnDrawAll(onDrawAllListener); - PDFView.this.callbacks.setOnPageChange(onPageChangeListener); - PDFView.this.callbacks.setOnPageScroll(onPageScrollListener); - PDFView.this.callbacks.setOnRender(onRenderListener); - PDFView.this.callbacks.setOnTap(onTapListener); - PDFView.this.callbacks.setOnLongPress(onLongPressListener); - PDFView.this.callbacks.setOnPageError(onPageErrorListener); - PDFView.this.callbacks.setLinkHandler(linkHandler); - PDFView.this.setSwipeEnabled(enableSwipe); - PDFView.this.setNightMode(nightMode); - PDFView.this.enableDoubletap(enableDoubletap); - PDFView.this.setDefaultPage(defaultPage); - PDFView.this.setLandscapeOrientation(landscapeOrientation); - PDFView.this.setDualPageMode(dualPageMode); - PDFView.this.setSwipeVertical(!swipeHorizontal); - PDFView.this.enableAnnotationRendering(annotationRendering); - PDFView.this.setScrollHandle(scrollHandle); - PDFView.this.enableAntialiasing(antialiasing); - PDFView.this.setSpacing(spacing); - PDFView.this.setAutoSpacing(autoSpacing); - PDFView.this.setPageFitPolicy(pageFitPolicy); - PDFView.this.setFitEachPage(fitEachPage); - PDFView.this.setPageSnap(pageSnap); - PDFView.this.setPageFling(pageFling); - - if (pageNumbers != null) { - PDFView.this.load(documentSource, password, pageNumbers); - } else { - PDFView.this.load(documentSource, password); - } - } - } -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.graphics.PaintFlagsDrawFilter; +import android.graphics.PointF; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.HandlerThread; +import android.util.AttributeSet; +import android.util.Log; +import android.widget.RelativeLayout; + +import com.github.barteksc.pdfviewer.exception.PageRenderingException; +import com.github.barteksc.pdfviewer.link.DefaultLinkHandler; +import com.github.barteksc.pdfviewer.link.LinkHandler; +import com.github.barteksc.pdfviewer.listener.Callbacks; +import com.github.barteksc.pdfviewer.listener.OnDrawListener; +import com.github.barteksc.pdfviewer.listener.OnErrorListener; +import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener; +import com.github.barteksc.pdfviewer.listener.OnLongPressListener; +import com.github.barteksc.pdfviewer.listener.OnPageChangeListener; +import com.github.barteksc.pdfviewer.listener.OnPageErrorListener; +import com.github.barteksc.pdfviewer.listener.OnPageScrollListener; +import com.github.barteksc.pdfviewer.listener.OnRenderListener; +import com.github.barteksc.pdfviewer.listener.OnTapListener; +import com.github.barteksc.pdfviewer.model.PagePart; +import com.github.barteksc.pdfviewer.scroll.ScrollHandle; +import com.github.barteksc.pdfviewer.source.AssetSource; +import com.github.barteksc.pdfviewer.source.ByteArraySource; +import com.github.barteksc.pdfviewer.source.DocumentSource; +import com.github.barteksc.pdfviewer.source.FileSource; +import com.github.barteksc.pdfviewer.source.InputStreamSource; +import com.github.barteksc.pdfviewer.source.UriSource; +import com.github.barteksc.pdfviewer.util.Constants; +import com.github.barteksc.pdfviewer.util.FitPolicy; +import com.github.barteksc.pdfviewer.util.MathUtils; +import com.github.barteksc.pdfviewer.util.SnapEdge; +import com.github.barteksc.pdfviewer.util.Util; +import com.shockwave.pdfium.PdfDocument; +import com.shockwave.pdfium.PdfiumCore; +import com.shockwave.pdfium.util.Size; +import com.shockwave.pdfium.util.SizeF; + +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * It supports animations, zoom, cache, and swipe. + *

+ * To fully understand this class you must know its principles : + * - The PDF document is seen as if we always want to draw all the pages. + * - The thing is that we only draw the visible parts. + * - All parts are the same size, this is because we can't interrupt a native page rendering, + * so we need these renderings to be as fast as possible, and be able to interrupt them + * as soon as we can. + * - The parts are loaded when the current offset or the current zoom level changes + *

+ * Important : + * - DocumentPage = A page of the PDF document. + * - UserPage = A page as defined by the user. + * By default, they're the same. But the user can change the pages order + * using {@link #load(DocumentSource, String, int[])}. In this + * particular case, a userPage of 5 can refer to a documentPage of 17. + */ +public class PDFView extends RelativeLayout { + + private static final String TAG = PDFView.class.getSimpleName(); + + public static final float DEFAULT_MAX_SCALE = 3.0f; + public static final float DEFAULT_MID_SCALE = 1.75f; + public static final float DEFAULT_MIN_SCALE = 1.0f; + + private float minZoom = DEFAULT_MIN_SCALE; + private float midZoom = DEFAULT_MID_SCALE; + private float maxZoom = DEFAULT_MAX_SCALE; + + /** + * START - scrolling in first page direction + * END - scrolling in last page direction + * NONE - not scrolling + */ + enum ScrollDir { + NONE, START, END + } + + private ScrollDir scrollDir = ScrollDir.NONE; + + /** Rendered parts go to the cache manager */ + CacheManager cacheManager; + + /** Animation manager manage all offset and zoom animation */ + private AnimationManager animationManager; + + /** Drag manager manage all touch events */ + private DragPinchManager dragPinchManager; + + PdfFile pdfFile; + + /** The index of the current sequence */ + private int currentPage; + + /** + * If you picture all the pages side by side in their optimal width, + * and taking into account the zoom level, the current offset is the + * position of the left border of the screen in this big picture + */ + private float currentXOffset = 0; + + /** + * If you picture all the pages side by side in their optimal width, + * and taking into account the zoom level, the current offset is the + * position of the left border of the screen in this big picture + */ + private float currentYOffset = 0; + + /** The zoom level, always >= 1 */ + private float zoom = 1f; + + /** True if the PDFView has been recycled */ + private boolean recycled = true; + + /** Current state of the view */ + private State state = State.DEFAULT; + + /** Async task used during the loading phase to decode a PDF document */ + private DecodingAsyncTask decodingAsyncTask; + + /** The thread {@link #renderingHandler} will run on */ + private HandlerThread renderingHandlerThread; + /** Handler always waiting in the background and rendering tasks */ + RenderingHandler renderingHandler; + + private PagesLoader pagesLoader; + + Callbacks callbacks = new Callbacks(); + + /** Paint object for drawing */ + private Paint paint; + + /** Paint object for drawing debug stuff */ + private Paint debugPaint; + + /** Policy for fitting pages to screen */ + private FitPolicy pageFitPolicy = FitPolicy.WIDTH; + + private boolean fitEachPage = false; + + private int defaultPage = 0; + + private boolean dualPageMode = false; + + private boolean isLandscapeOrientation = false; + + /** True if should scroll through pages vertically instead of horizontally */ + private boolean swipeVertical = true; + + private boolean enableSwipe = true; + + private boolean doubletapEnabled = true; + + private boolean nightMode = false; + + private boolean pageSnap = true; + + /** Pdfium core for loading and rendering PDFs */ + private PdfiumCore pdfiumCore; + + private ScrollHandle scrollHandle; + + private boolean isScrollHandleInit = false; + + ScrollHandle getScrollHandle() { + return scrollHandle; + } + + /** + * True if bitmap should use ARGB_8888 format and take more memory + * False if bitmap should be compressed by using RGB_565 format and take less memory + */ + private boolean bestQuality = false; + + /** + * True if annotations should be rendered + * False otherwise + */ + private boolean annotationRendering = false; + + /** + * True if the view should render during scaling
+ * Can not be forced on older API versions (< Build.VERSION_CODES.KITKAT) as the GestureDetector does + * not detect scrolling while scaling.
+ * False otherwise + */ + private boolean renderDuringScale = false; + + /** Antialiasing and bitmap filtering */ + private boolean enableAntialiasing = true; + private PaintFlagsDrawFilter antialiasFilter = + new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + + /** Spacing between pages, in px */ + private int spacingPx = 0; + + /** Add dynamic spacing to fit each page separately on the screen. */ + private boolean autoSpacing = false; + + /** Fling a single page at a time */ + private boolean pageFling = true; + + /** Pages numbers used when calling onDrawAllListener */ + private List onDrawPagesNums = new ArrayList<>(10); + + /** Holds info whether view has been added to layout and has width and height */ + private boolean hasSize = false; + + /** Holds last used Configurator that should be loaded when view has size */ + private Configurator waitingDocumentConfigurator; + + /** Construct the initial view */ + public PDFView(Context context, AttributeSet set) { + super(context, set); + + renderingHandlerThread = new HandlerThread("PDF renderer"); + + if (isInEditMode()) { + return; + } + + cacheManager = new CacheManager(); + animationManager = new AnimationManager(this); + dragPinchManager = new DragPinchManager(this, animationManager); + pagesLoader = new PagesLoader(this); + + paint = new Paint(); + debugPaint = new Paint(); + debugPaint.setStyle(Style.STROKE); + + pdfiumCore = new PdfiumCore(context); + setWillNotDraw(false); + } + + private void load(DocumentSource docSource, String password) { + load(docSource, password, null); + } + + private void load(DocumentSource docSource, String password, int[] userPages) { + + if (!recycled) { + throw new IllegalStateException("Don't call load on a PDF View without recycling it first."); + } + + recycled = false; + // Start decoding document + decodingAsyncTask = new DecodingAsyncTask(docSource, password, userPages, this, pdfiumCore); + decodingAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + /** + * Go to the given page. + * + * @param page Page index. + */ + public void jumpTo(int page, boolean withAnimation) { + if (pdfFile == null) { + return; + } + + page = pdfFile.determineValidPageNumberFrom(page); + float offset = page == 0 ? 0 : -pdfFile.getPageOffset(page, zoom); + if (swipeVertical) { + if (withAnimation) { + animationManager.startYAnimation(currentYOffset, offset); + } else { + moveTo(currentXOffset, offset); + } + } else { + if (withAnimation) { + animationManager.startXAnimation(currentXOffset, offset); + } else { + moveTo(offset, currentYOffset); + } + } + showPage(page); + } + + public void jumpTo(int page) { + jumpTo(page, false); + } + + void showPage(int pageNb) { + if (recycled) { + return; + } + + // Check the page number and makes the + // difference between UserPages and DocumentPages + pageNb = pdfFile.determineValidPageNumberFrom(pageNb); + currentPage = pageNb; + + loadPages(); + + if (scrollHandle != null && !documentFitsView()) { + scrollHandle.setPageNum(currentPage + 1); + } + + callbacks.callOnPageChange(currentPage, pdfFile.getPagesCount()); + } + + /** + * Get current position as ratio of document length to visible area. + * 0 means that document start is visible, 1 that document end is visible + * + * @return offset between 0 and 1 + */ + public float getPositionOffset() { + float offset; + if (swipeVertical) { + offset = -currentYOffset / (pdfFile.getDocLen(zoom) - getHeight()); + } else { + offset = -currentXOffset / (pdfFile.getDocLen(zoom) - getWidth()); + } + return MathUtils.limit(offset, 0, 1); + } + + /** + * @param progress must be between 0 and 1 + * @param moveHandle whether to move scroll handle + * @see PDFView#getPositionOffset() + */ + public void setPositionOffset(float progress, boolean moveHandle) { + if (swipeVertical) { + moveTo(currentXOffset, (-pdfFile.getDocLen(zoom) + getHeight()) * progress, moveHandle); + } else { + moveTo((-pdfFile.getDocLen(zoom) + getWidth()) * progress, currentYOffset, moveHandle); + } + loadPageByOffset(); + } + + public void setPositionOffset(float progress) { + setPositionOffset(progress, true); + } + + public void stopFling() { + animationManager.stopFling(); + } + + public int getPageCount() { + if (pdfFile == null) { + return 0; + } + return pdfFile.getPagesCount(); + } + + public void setSwipeEnabled(boolean enableSwipe) { + this.enableSwipe = enableSwipe; + } + + public void setNightMode(boolean nightMode) { + this.nightMode = nightMode; + if (nightMode) { + ColorMatrix colorMatrixInverted = + new ColorMatrix(new float[]{ + -1, 0, 0, 0, 255, + 0, -1, 0, 0, 255, + 0, 0, -1, 0, 255, + 0, 0, 0, 1, 0}); + + ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrixInverted); + paint.setColorFilter(filter); + } else { + paint.setColorFilter(null); + } + } + + void enableDoubletap(boolean enableDoubletap) { + this.doubletapEnabled = enableDoubletap; + } + + boolean isDoubletapEnabled() { + return doubletapEnabled; + } + + void onPageError(PageRenderingException ex) { + if (!callbacks.callOnPageError(ex.getPage(), ex.getCause())) { + Log.e(TAG, "Cannot open page " + ex.getPage(), ex.getCause()); + } + } + + public void recycle() { + waitingDocumentConfigurator = null; + + animationManager.stopAll(); + dragPinchManager.disable(); + + // Stop tasks + if (renderingHandler != null) { + renderingHandler.stop(); + renderingHandler.removeMessages(RenderingHandler.MSG_RENDER_TASK); + } + if (decodingAsyncTask != null) { + decodingAsyncTask.cancel(true); + } + + // Clear caches + cacheManager.recycle(); + + if (scrollHandle != null && isScrollHandleInit) { + scrollHandle.destroyLayout(); + } + + if (pdfFile != null) { + pdfFile.dispose(); + pdfFile = null; + } + + renderingHandler = null; + scrollHandle = null; + isScrollHandleInit = false; + currentXOffset = currentYOffset = 0; + zoom = 1f; + recycled = true; + callbacks = new Callbacks(); + state = State.DEFAULT; + } + + public boolean isRecycled() { + return recycled; + } + + /** Handle fling animation */ + @Override + public void computeScroll() { + super.computeScroll(); + if (isInEditMode()) { + return; + } + animationManager.computeFling(); + } + + @Override + protected void onDetachedFromWindow() { + recycle(); + if (renderingHandlerThread != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + renderingHandlerThread.quitSafely(); + } else { + renderingHandlerThread.quit(); + } + renderingHandlerThread = null; + } + super.onDetachedFromWindow(); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + hasSize = true; + if (waitingDocumentConfigurator != null) { + waitingDocumentConfigurator.load(); + } + if (isInEditMode() || state != State.SHOWN) { + return; + } + + // calculates the position of the point which in the center of view relative to big strip + float centerPointInStripXOffset = -currentXOffset + oldw * 0.5f; + float centerPointInStripYOffset = -currentYOffset + oldh * 0.5f; + + float relativeCenterPointInStripXOffset; + float relativeCenterPointInStripYOffset; + + if (swipeVertical){ + relativeCenterPointInStripXOffset = centerPointInStripXOffset / pdfFile.getMaxPageWidth(); + relativeCenterPointInStripYOffset = centerPointInStripYOffset / pdfFile.getDocLen(zoom); + }else { + relativeCenterPointInStripXOffset = centerPointInStripXOffset / pdfFile.getDocLen(zoom); + relativeCenterPointInStripYOffset = centerPointInStripYOffset / pdfFile.getMaxPageHeight(); + } + + animationManager.stopAll(); + pdfFile.recalculatePageSizes(new Size(w, h)); + + if (swipeVertical) { + currentXOffset = -relativeCenterPointInStripXOffset * pdfFile.getMaxPageWidth() + w * 0.5f; + currentYOffset = -relativeCenterPointInStripYOffset * pdfFile.getDocLen(zoom) + h * 0.5f ; + }else { + currentXOffset = -relativeCenterPointInStripXOffset * pdfFile.getDocLen(zoom) + w * 0.5f; + currentYOffset = -relativeCenterPointInStripYOffset * pdfFile.getMaxPageHeight() + h * 0.5f; + } + moveTo(currentXOffset,currentYOffset); + loadPageByOffset(); + } + + @Override + public boolean canScrollHorizontally(int direction) { + if (pdfFile == null) { + return true; + } + + if (swipeVertical) { + if (direction < 0 && currentXOffset < 0) { + return true; + } else if (direction > 0 && currentXOffset + toCurrentScale(pdfFile.getMaxPageWidth()) > getWidth()) { + return true; + } + } else { + if (direction < 0 && currentXOffset < 0) { + return true; + } else if (direction > 0 && currentXOffset + pdfFile.getDocLen(zoom) > getWidth()) { + return true; + } + } + return false; + } + + @Override + public boolean canScrollVertically(int direction) { + if (pdfFile == null) { + return true; + } + + if (swipeVertical) { + if (direction < 0 && currentYOffset < 0) { + return true; + } else if (direction > 0 && currentYOffset + pdfFile.getDocLen(zoom) > getHeight()) { + return true; + } + } else { + if (direction < 0 && currentYOffset < 0) { + return true; + } else if (direction > 0 && currentYOffset + toCurrentScale(pdfFile.getMaxPageHeight()) > getHeight()) { + return true; + } + } + return false; + } + + @Override + protected void onDraw(Canvas canvas) { + if (isInEditMode()) { + return; + } + // As I said in this class javadoc, we can think of this canvas as a huge + // strip on which we draw all the images. We actually only draw the rendered + // parts, of course, but we render them in the place they belong in this huge + // strip. + + // That's where Canvas.translate(x, y) becomes very helpful. + // This is the situation : + // _______________________________________________ + // | | | + // | the actual | The big strip | + // | canvas | | + // |_____________| | + // |_______________________________________________| + // + // If the rendered part is on the bottom right corner of the strip + // we can draw it but we won't see it because the canvas is not big enough. + + // But if we call translate(-X, -Y) on the canvas just before drawing the object : + // _______________________________________________ + // | _____________| + // | The big strip | | + // | | the actual | + // | | canvas | + // |_________________________________|_____________| + // + // The object will be on the canvas. + // This technique is massively used in this method, and allows + // abstraction of the screen position when rendering the parts. + + // Draws background + + if (enableAntialiasing) { + canvas.setDrawFilter(antialiasFilter); + } + + Drawable bg = getBackground(); + if (bg == null) { + canvas.drawColor(nightMode ? Color.BLACK : Color.WHITE); + } else { + bg.draw(canvas); + } + + if (recycled) { + return; + } + + if (state != State.SHOWN) { + return; + } + + // Moves the canvas before drawing any element + float currentXOffset = this.currentXOffset; + float currentYOffset = this.currentYOffset; + canvas.translate(currentXOffset, currentYOffset); + + // Draws thumbnails + for (PagePart part : cacheManager.getThumbnails()) { + drawPart(canvas, part); + + } + + // Draws parts + for (PagePart part : cacheManager.getPageParts()) { + drawPart(canvas, part); + if (callbacks.getOnDrawAll() != null + && !onDrawPagesNums.contains(part.getPage())) { + onDrawPagesNums.add(part.getPage()); + } + } + + for (Integer page : onDrawPagesNums) { + drawWithListener(canvas, page, callbacks.getOnDrawAll()); + } + onDrawPagesNums.clear(); + + drawWithListener(canvas, currentPage, callbacks.getOnDraw()); + + // Restores the canvas position + canvas.translate(-currentXOffset, -currentYOffset); + } + + private void drawWithListener(Canvas canvas, int page, OnDrawListener listener) { + if (listener != null) { + float translateX, translateY; + if (swipeVertical) { + translateX = 0; + translateY = pdfFile.getPageOffset(page, zoom); + } else { + translateY = 0; + translateX = pdfFile.getPageOffset(page, zoom); + } + + canvas.translate(translateX, translateY); + SizeF size = pdfFile.getPageSize(page); + listener.onLayerDrawn(canvas, + toCurrentScale(size.getWidth()), + toCurrentScale(size.getHeight()), + page); + + canvas.translate(-translateX, -translateY); + } + } + + /** Draw a given PagePart on the canvas */ + private void drawPart(Canvas canvas, PagePart part) { + // Can seem strange, but avoid lot of calls + RectF pageRelativeBounds = part.getPageRelativeBounds(); + Bitmap renderedBitmap = part.getRenderedBitmap(); + + if (renderedBitmap.isRecycled()) { + return; + } + + // Move to the target page + float localTranslationX = 0; + float localTranslationY = 0; + SizeF size = pdfFile.getPageSize(part.getPage()); + + if (swipeVertical) { + localTranslationY = pdfFile.getPageOffset(part.getPage(), zoom); + float maxWidth = pdfFile.getMaxPageWidth(); + localTranslationX = toCurrentScale(maxWidth - size.getWidth()) / 2; + } else { + localTranslationX = pdfFile.getPageOffset(part.getPage(), zoom); + float maxHeight = pdfFile.getMaxPageHeight(); + localTranslationY = toCurrentScale(maxHeight - size.getHeight()) / 2; + } + canvas.translate(localTranslationX, localTranslationY); + + Rect srcRect = new Rect(0, 0, renderedBitmap.getWidth(), + renderedBitmap.getHeight()); + + float offsetX = toCurrentScale(pageRelativeBounds.left * size.getWidth()); + float offsetY = toCurrentScale(pageRelativeBounds.top * size.getHeight()); + float width = toCurrentScale(pageRelativeBounds.width() * size.getWidth()); + float height = toCurrentScale(pageRelativeBounds.height() * size.getHeight()); + + // If we use float values for this rectangle, there will be + // a possible gap between page parts, especially when + // the zoom level is high. + RectF dstRect = new RectF((int) offsetX, (int) offsetY, + (int) (offsetX + width), + (int) (offsetY + height)); + + // Check if bitmap is in the screen + float translationX = currentXOffset + localTranslationX; + float translationY = currentYOffset + localTranslationY; + if (translationX + dstRect.left >= getWidth() || translationX + dstRect.right <= 0 || + translationY + dstRect.top >= getHeight() || translationY + dstRect.bottom <= 0) { + canvas.translate(-localTranslationX, -localTranslationY); + return; + } + + canvas.drawBitmap(renderedBitmap, srcRect, dstRect, paint); + + if (Constants.DEBUG_MODE) { + debugPaint.setColor(part.getPage() % 2 == 0 ? Color.RED : Color.BLUE); + canvas.drawRect(dstRect, debugPaint); + } + + // Restore the canvas position + canvas.translate(-localTranslationX, -localTranslationY); + + } + + /** + * Load all the parts around the center of the screen, + * taking into account X and Y offsets, zoom level, and + * the current page displayed + */ + public void loadPages() { + if (pdfFile == null || renderingHandler == null) { + return; + } + + // Cancel all current tasks + renderingHandler.removeMessages(RenderingHandler.MSG_RENDER_TASK); + cacheManager.makeANewSet(); + + pagesLoader.loadPages(); + redraw(); + } + + /** Called when the PDF is loaded */ + void loadComplete(PdfFile pdfFile) { + state = State.LOADED; + + this.pdfFile = pdfFile; + + if (!renderingHandlerThread.isAlive()) { + renderingHandlerThread.start(); + } + renderingHandler = new RenderingHandler(renderingHandlerThread.getLooper(), this); + renderingHandler.start(); + + if (scrollHandle != null) { + scrollHandle.setupLayout(this); + isScrollHandleInit = true; + } + + dragPinchManager.enable(); + + callbacks.callOnLoadComplete(pdfFile.getPagesCount()); + + jumpTo(defaultPage, false); + } + + void loadError(Throwable t) { + state = State.ERROR; + // store reference, because callbacks will be cleared in recycle() method + OnErrorListener onErrorListener = callbacks.getOnError(); + recycle(); + invalidate(); + if (onErrorListener != null) { + onErrorListener.onError(t); + } else { + Log.e("PDFView", "load pdf error", t); + } + } + + void redraw() { + invalidate(); + } + + /** + * Called when a rendering task is over and + * a PagePart has been freshly created. + * + * @param part The created PagePart. + */ + public void onBitmapRendered(PagePart part) { + // when it is first rendered part + if (state == State.LOADED) { + state = State.SHOWN; + callbacks.callOnRender(pdfFile.getPagesCount()); + } + + if (part.isThumbnail()) { + cacheManager.cacheThumbnail(part); + } else { + cacheManager.cachePart(part); + } + redraw(); + } + + public void moveTo(float offsetX, float offsetY) { + moveTo(offsetX, offsetY, true); + } + + /** + * Move to the given X and Y offsets, but check them ahead of time + * to be sure not to go outside the the big strip. + * + * @param offsetX The big strip X offset to use as the left border of the screen. + * @param offsetY The big strip Y offset to use as the right border of the screen. + * @param moveHandle whether to move scroll handle or not + */ + public void moveTo(float offsetX, float offsetY, boolean moveHandle) { + if (swipeVertical) { + // Check X offset + float scaledPageWidth = toCurrentScale(pdfFile.getMaxPageWidth()); + if (scaledPageWidth < getWidth()) { + offsetX = getWidth() / 2 - scaledPageWidth / 2; + } else { + if (offsetX > 0) { + offsetX = 0; + } else if (offsetX + scaledPageWidth < getWidth()) { + offsetX = getWidth() - scaledPageWidth; + } + } + + // Check Y offset + float contentHeight = pdfFile.getDocLen(zoom); + if (contentHeight < getHeight()) { // whole document height visible on screen + offsetY = (getHeight() - contentHeight) / 2; + } else { + if (offsetY > 0) { // top visible + offsetY = 0; + } else if (offsetY + contentHeight < getHeight()) { // bottom visible + offsetY = -contentHeight + getHeight(); + } + } + + if (offsetY < currentYOffset) { + scrollDir = ScrollDir.END; + } else if (offsetY > currentYOffset) { + scrollDir = ScrollDir.START; + } else { + scrollDir = ScrollDir.NONE; + } + } else { + // Check Y offset + float scaledPageHeight = toCurrentScale(pdfFile.getMaxPageHeight()); + if (scaledPageHeight < getHeight()) { + offsetY = getHeight() / 2 - scaledPageHeight / 2; + } else { + if (offsetY > 0) { + offsetY = 0; + } else if (offsetY + scaledPageHeight < getHeight()) { + offsetY = getHeight() - scaledPageHeight; + } + } + + // Check X offset + float contentWidth = pdfFile.getDocLen(zoom); + if (contentWidth < getWidth()) { // whole document width visible on screen + offsetX = (getWidth() - contentWidth) / 2; + } else { + if (offsetX > 0) { // left visible + offsetX = 0; + } else if (offsetX + contentWidth < getWidth()) { // right visible + offsetX = -contentWidth + getWidth(); + } + } + + if (offsetX < currentXOffset) { + scrollDir = ScrollDir.END; + } else if (offsetX > currentXOffset) { + scrollDir = ScrollDir.START; + } else { + scrollDir = ScrollDir.NONE; + } + } + + currentXOffset = offsetX; + currentYOffset = offsetY; + float positionOffset = getPositionOffset(); + + if (moveHandle && scrollHandle != null && !documentFitsView()) { + scrollHandle.setScroll(positionOffset); + } + + callbacks.callOnPageScroll(getCurrentPage(), positionOffset); + + redraw(); + } + + void loadPageByOffset() { + if (0 == pdfFile.getPagesCount()) { + return; + } + + float offset, screenCenter; + if (swipeVertical) { + offset = currentYOffset; + screenCenter = ((float) getHeight()) / 2; + } else { + offset = currentXOffset; + screenCenter = ((float) getWidth()) / 2; + } + + int page = pdfFile.getPageAtOffset(-(offset - screenCenter), zoom); + + if (page >= 0 && page <= pdfFile.getPagesCount() - 1 && page != getCurrentPage()) { + showPage(page); + } else { + loadPages(); + } + } + + /** + * Animate to the nearest snapping position for the current SnapPolicy + */ + public void performPageSnap() { + if (!pageSnap || pdfFile == null || pdfFile.getPagesCount() == 0) { + return; + } + int centerPage = findFocusPage(currentXOffset, currentYOffset); + SnapEdge edge = findSnapEdge(centerPage); + if (edge == SnapEdge.NONE) { + return; + } + + float offset = snapOffsetForPage(centerPage, edge); + if (swipeVertical) { + animationManager.startYAnimation(currentYOffset, -offset); + } else { + animationManager.startXAnimation(currentXOffset, -offset); + } + } + + /** + * Find the edge to snap to when showing the specified page + */ + SnapEdge findSnapEdge(int page) { + if (!pageSnap || page < 0) { + return SnapEdge.NONE; + } + float currentOffset = swipeVertical ? currentYOffset : currentXOffset; + float offset = -pdfFile.getPageOffset(page, zoom); + int length = swipeVertical ? getHeight() : getWidth(); + float pageLength = pdfFile.getPageLength(page, zoom); + + if (length >= pageLength) { + return SnapEdge.CENTER; + } else if (currentOffset >= offset) { + return SnapEdge.START; + } else if (offset - pageLength > currentOffset - length) { + return SnapEdge.END; + } else { + return SnapEdge.NONE; + } + } + + /** + * Get the offset to move to in order to snap to the page + */ + float snapOffsetForPage(int pageIndex, SnapEdge edge) { + float offset = pdfFile.getPageOffset(pageIndex, zoom); + + float length = swipeVertical ? getHeight() : getWidth(); + float pageLength = pdfFile.getPageLength(pageIndex, zoom); + + if (edge == SnapEdge.CENTER) { + offset = offset - length / 2f + pageLength / 2f; + } else if (edge == SnapEdge.END) { + offset = offset - length + pageLength; + } + return offset; + } + + int findFocusPage(float xOffset, float yOffset) { + float currOffset = swipeVertical ? yOffset : xOffset; + float length = swipeVertical ? getHeight() : getWidth(); + // make sure first and last page can be found + if (currOffset > -1) { + return 0; + } else if (currOffset < -pdfFile.getDocLen(zoom) + length + 1) { + return pdfFile.getPagesCount() - 1; + } + // else find page in center + float center = currOffset - length / 2f; + return pdfFile.getPageAtOffset(-center, zoom); + } + + /** + * @return true if single page fills the entire screen in the scrolling direction + */ + public boolean pageFillsScreen() { + float start = -pdfFile.getPageOffset(currentPage, zoom); + float end = start - pdfFile.getPageLength(currentPage, zoom); + if (isSwipeVertical()) { + return start > currentYOffset && end < currentYOffset - getHeight(); + } else { + return start > currentXOffset && end < currentXOffset - getWidth(); + } + } + + /** + * Move relatively to the current position. + * + * @param dx The X difference you want to apply. + * @param dy The Y difference you want to apply. + * @see #moveTo(float, float) + */ + public void moveRelativeTo(float dx, float dy) { + moveTo(currentXOffset + dx, currentYOffset + dy); + } + + /** + * Change the zoom level + */ + public void zoomTo(float zoom) { + this.zoom = zoom; + } + + /** + * Change the zoom level, relatively to a pivot point. + * It will call moveTo() to make sure the given point stays + * in the middle of the screen. + * + * @param zoom The zoom level. + * @param pivot The point on the screen that should stays. + */ + public void zoomCenteredTo(float zoom, PointF pivot) { + float dzoom = zoom / this.zoom; + zoomTo(zoom); + float baseX = currentXOffset * dzoom; + float baseY = currentYOffset * dzoom; + baseX += (pivot.x - pivot.x * dzoom); + baseY += (pivot.y - pivot.y * dzoom); + moveTo(baseX, baseY); + } + + /** + * @see #zoomCenteredTo(float, PointF) + */ + public void zoomCenteredRelativeTo(float dzoom, PointF pivot) { + zoomCenteredTo(zoom * dzoom, pivot); + } + + /** + * Checks if whole document can be displayed on screen, doesn't include zoom + * + * @return true if whole document can displayed at once, false otherwise + */ + public boolean documentFitsView() { + float len = pdfFile.getDocLen(1); + if (swipeVertical) { + return len < getHeight(); + } else { + return len < getWidth(); + } + } + + public void fitToWidth(int page) { + if (state != State.SHOWN) { + Log.e(TAG, "Cannot fit, document not rendered yet"); + return; + } + zoomTo(getWidth() / pdfFile.getPageSize(page).getWidth()); + jumpTo(page); + } + + public SizeF getPageSize(int pageIndex) { + if (pdfFile == null) { + return new SizeF(0, 0); + } + return pdfFile.getPageSize(pageIndex); + } + + public int getCurrentPage() { + return currentPage; + } + + public float getCurrentXOffset() { + return currentXOffset; + } + + public float getCurrentYOffset() { + return currentYOffset; + } + + public float toRealScale(float size) { + return size / zoom; + } + + public float toCurrentScale(float size) { + return size * zoom; + } + + public float getZoom() { + return zoom; + } + + public boolean isZooming() { + return zoom != minZoom; + } + + private void setDefaultPage(int defaultPage) { + this.defaultPage = defaultPage; + } + + public void resetZoom() { + zoomTo(minZoom); + } + + public void resetZoomWithAnimation() { + zoomWithAnimation(minZoom); + } + + public void zoomWithAnimation(float centerX, float centerY, float scale) { + animationManager.startZoomAnimation(centerX, centerY, zoom, scale); + } + + public void zoomWithAnimation(float scale) { + animationManager.startZoomAnimation(getWidth() / 2, getHeight() / 2, zoom, scale); + } + + private void setScrollHandle(ScrollHandle scrollHandle) { + this.scrollHandle = scrollHandle; + } + + /** + * Get page number at given offset + * + * @param positionOffset scroll offset between 0 and 1 + * @return page number at given offset, starting from 0 + */ + public int getPageAtPositionOffset(float positionOffset) { + return pdfFile.getPageAtOffset(pdfFile.getDocLen(zoom) * positionOffset, zoom); + } + + public float getMinZoom() { + return minZoom; + } + + public void setMinZoom(float minZoom) { + this.minZoom = minZoom; + } + + public float getMidZoom() { + return midZoom; + } + + public void setMidZoom(float midZoom) { + this.midZoom = midZoom; + } + + public float getMaxZoom() { + return maxZoom; + } + + public void setMaxZoom(float maxZoom) { + this.maxZoom = maxZoom; + } + + public void useBestQuality(boolean bestQuality) { + this.bestQuality = bestQuality; + } + + public boolean isBestQuality() { + return bestQuality; + } + + public boolean isOnDualPageMode() { + return dualPageMode; + } + + public boolean isOnLandscapeOrientation() { return isLandscapeOrientation; } + + public void setLandscapeOrientation(boolean landscapeOrientation) {this.isLandscapeOrientation = landscapeOrientation; } + + public void setDualPageMode(boolean dualPageMode) { + this.dualPageMode = dualPageMode; + } + + public boolean isSwipeVertical() { + return swipeVertical; + } + + public boolean isSwipeEnabled() { + return enableSwipe; + } + + private void setSwipeVertical(boolean swipeVertical) { + this.swipeVertical = swipeVertical; + } + + public void enableAnnotationRendering(boolean annotationRendering) { + this.annotationRendering = annotationRendering; + } + + public boolean isAnnotationRendering() { + return annotationRendering; + } + + public void enableRenderDuringScale(boolean renderDuringScale) { + this.renderDuringScale = renderDuringScale; + } + + public boolean isAntialiasing() { + return enableAntialiasing; + } + + public void enableAntialiasing(boolean enableAntialiasing) { + this.enableAntialiasing = enableAntialiasing; + } + + public int getSpacingPx() { + return spacingPx; + } + + public boolean isAutoSpacingEnabled() { + return autoSpacing; + } + + public void setPageFling(boolean pageFling) { + this.pageFling = pageFling; + } + + public boolean isPageFlingEnabled() { + return pageFling; + } + + private void setSpacing(int spacingDp) { + this.spacingPx = Util.getDP(getContext(), spacingDp); + } + + private void setAutoSpacing(boolean autoSpacing) { + this.autoSpacing = autoSpacing; + } + + private void setPageFitPolicy(FitPolicy pageFitPolicy) { + this.pageFitPolicy = pageFitPolicy; + } + + public FitPolicy getPageFitPolicy() { + return pageFitPolicy; + } + + private void setFitEachPage(boolean fitEachPage) { + this.fitEachPage = fitEachPage; + } + + public boolean isFitEachPage() { + return fitEachPage; + } + + public boolean isPageSnap() { + return pageSnap; + } + + public void setPageSnap(boolean pageSnap) { + this.pageSnap = pageSnap; + } + + public boolean doRenderDuringScale() { + return renderDuringScale; + } + + /** Returns null if document is not loaded */ + public PdfDocument.Meta getDocumentMeta() { + if (pdfFile == null) { + return null; + } + return pdfFile.getMetaData(); + } + + /** Will be empty until document is loaded */ + public List getTableOfContents() { + if (pdfFile == null) { + return Collections.emptyList(); + } + return pdfFile.getBookmarks(); + } + + /** Will be empty until document is loaded */ + public List getLinks(int page) { + if (pdfFile == null) { + return Collections.emptyList(); + } + return pdfFile.getPageLinks(page); + } + + /** Use an asset file as the pdf source */ + public Configurator fromAsset(String assetName) { + return new Configurator(new AssetSource(assetName)); + } + + /** Use a file as the pdf source */ + public Configurator fromFile(File file) { + return new Configurator(new FileSource(file)); + } + + /** Use URI as the pdf source, for use with content providers */ + public Configurator fromUri(Uri uri) { + return new Configurator(new UriSource(uri)); + } + + /** Use bytearray as the pdf source, documents is not saved */ + public Configurator fromBytes(byte[] bytes) { + return new Configurator(new ByteArraySource(bytes)); + } + + /** Use stream as the pdf source. Stream will be written to bytearray, because native code does not support Java Streams */ + public Configurator fromStream(InputStream stream) { + return new Configurator(new InputStreamSource(stream)); + } + + /** Use custom source as pdf source */ + public Configurator fromSource(DocumentSource docSource) { + return new Configurator(docSource); + } + + private enum State {DEFAULT, LOADED, SHOWN, ERROR} + + public class Configurator { + + private final DocumentSource documentSource; + + private int[] pageNumbers = null; + + private boolean enableSwipe = true; + + private boolean enableDoubletap = true; + + private OnDrawListener onDrawListener; + + private OnDrawListener onDrawAllListener; + + private OnLoadCompleteListener onLoadCompleteListener; + + private OnErrorListener onErrorListener; + + private OnPageChangeListener onPageChangeListener; + + private OnPageScrollListener onPageScrollListener; + + private OnRenderListener onRenderListener; + + private OnTapListener onTapListener; + + private OnLongPressListener onLongPressListener; + + private OnPageErrorListener onPageErrorListener; + + private LinkHandler linkHandler = new DefaultLinkHandler(PDFView.this); + + private int defaultPage = 0; + + private boolean landscapeOrientation = false; + + private boolean dualPageMode = false; + + private boolean swipeHorizontal = false; + + private boolean annotationRendering = false; + + private String password = null; + + private ScrollHandle scrollHandle = null; + + private boolean antialiasing = true; + + private int spacing = 0; + + private boolean autoSpacing = false; + + private FitPolicy pageFitPolicy = FitPolicy.WIDTH; + + private boolean fitEachPage = false; + + private boolean pageFling = false; + + private boolean pageSnap = false; + + private boolean nightMode = false; + + private Configurator(DocumentSource documentSource) { + this.documentSource = documentSource; + } + + public Configurator pages(int... pageNumbers) { + this.pageNumbers = pageNumbers; + return this; + } + + public Configurator enableSwipe(boolean enableSwipe) { + this.enableSwipe = enableSwipe; + return this; + } + + public Configurator enableDoubletap(boolean enableDoubletap) { + this.enableDoubletap = enableDoubletap; + return this; + } + + public Configurator enableAnnotationRendering(boolean annotationRendering) { + this.annotationRendering = annotationRendering; + return this; + } + + public Configurator onDraw(OnDrawListener onDrawListener) { + this.onDrawListener = onDrawListener; + return this; + } + + public Configurator onDrawAll(OnDrawListener onDrawAllListener) { + this.onDrawAllListener = onDrawAllListener; + return this; + } + + public Configurator onLoad(OnLoadCompleteListener onLoadCompleteListener) { + this.onLoadCompleteListener = onLoadCompleteListener; + return this; + } + + public Configurator onPageScroll(OnPageScrollListener onPageScrollListener) { + this.onPageScrollListener = onPageScrollListener; + return this; + } + + public Configurator onError(OnErrorListener onErrorListener) { + this.onErrorListener = onErrorListener; + return this; + } + + public Configurator onPageError(OnPageErrorListener onPageErrorListener) { + this.onPageErrorListener = onPageErrorListener; + return this; + } + + public Configurator onPageChange(OnPageChangeListener onPageChangeListener) { + this.onPageChangeListener = onPageChangeListener; + return this; + } + + public Configurator onRender(OnRenderListener onRenderListener) { + this.onRenderListener = onRenderListener; + return this; + } + + public Configurator onTap(OnTapListener onTapListener) { + this.onTapListener = onTapListener; + return this; + } + + public Configurator onLongPress(OnLongPressListener onLongPressListener) { + this.onLongPressListener = onLongPressListener; + return this; + } + + public Configurator linkHandler(LinkHandler linkHandler) { + this.linkHandler = linkHandler; + return this; + } + + public Configurator defaultPage(int defaultPage) { + this.defaultPage = defaultPage; + return this; + } + + public Configurator landscapeOrientation(boolean landscapeOrientation) { + this.landscapeOrientation = landscapeOrientation; + return this; + } + + public Configurator dualPageMode(boolean dualPageMode) { + this.dualPageMode = dualPageMode; + return this; + } + + public Configurator swipeHorizontal(boolean swipeHorizontal) { + this.swipeHorizontal = swipeHorizontal; + return this; + } + + public Configurator password(String password) { + this.password = password; + return this; + } + + public Configurator scrollHandle(ScrollHandle scrollHandle) { + this.scrollHandle = scrollHandle; + return this; + } + + public Configurator enableAntialiasing(boolean antialiasing) { + this.antialiasing = antialiasing; + return this; + } + + public Configurator spacing(int spacing) { + this.spacing = spacing; + return this; + } + + public Configurator autoSpacing(boolean autoSpacing) { + this.autoSpacing = autoSpacing; + return this; + } + + public Configurator pageFitPolicy(FitPolicy pageFitPolicy) { + this.pageFitPolicy = pageFitPolicy; + return this; + } + + public Configurator fitEachPage(boolean fitEachPage) { + this.fitEachPage = fitEachPage; + return this; + } + + public Configurator pageSnap(boolean pageSnap) { + this.pageSnap = pageSnap; + return this; + } + + public Configurator pageFling(boolean pageFling) { + this.pageFling = pageFling; + return this; + } + + public Configurator nightMode(boolean nightMode) { + this.nightMode = nightMode; + return this; + } + + public Configurator disableLongpress() { + PDFView.this.dragPinchManager.disableLongpress(); + return this; + } + + public void load() { + if (!hasSize) { + waitingDocumentConfigurator = this; + return; + } + PDFView.this.recycle(); + PDFView.this.callbacks.setOnLoadComplete(onLoadCompleteListener); + PDFView.this.callbacks.setOnError(onErrorListener); + PDFView.this.callbacks.setOnDraw(onDrawListener); + PDFView.this.callbacks.setOnDrawAll(onDrawAllListener); + PDFView.this.callbacks.setOnPageChange(onPageChangeListener); + PDFView.this.callbacks.setOnPageScroll(onPageScrollListener); + PDFView.this.callbacks.setOnRender(onRenderListener); + PDFView.this.callbacks.setOnTap(onTapListener); + PDFView.this.callbacks.setOnLongPress(onLongPressListener); + PDFView.this.callbacks.setOnPageError(onPageErrorListener); + PDFView.this.callbacks.setLinkHandler(linkHandler); + PDFView.this.setSwipeEnabled(enableSwipe); + PDFView.this.setNightMode(nightMode); + PDFView.this.enableDoubletap(enableDoubletap); + PDFView.this.setDefaultPage(defaultPage); + PDFView.this.setLandscapeOrientation(landscapeOrientation); + PDFView.this.setDualPageMode(dualPageMode); + PDFView.this.setSwipeVertical(!swipeHorizontal); + PDFView.this.enableAnnotationRendering(annotationRendering); + PDFView.this.setScrollHandle(scrollHandle); + PDFView.this.enableAntialiasing(antialiasing); + PDFView.this.setSpacing(spacing); + PDFView.this.setAutoSpacing(autoSpacing); + PDFView.this.setPageFitPolicy(pageFitPolicy); + PDFView.this.setFitEachPage(fitEachPage); + PDFView.this.setPageSnap(pageSnap); + PDFView.this.setPageFling(pageFling); + + if (pageNumbers != null) { + PDFView.this.load(documentSource, password, pageNumbers); + } else { + PDFView.this.load(documentSource, password); + } + } + } +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java index 70be2cc0..26c30f4b 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PagesLoader.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer; +package com.github.barteksc.pdfviewer; import android.graphics.RectF; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java index 01ce993f..3610bcbb 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer; +package com.github.barteksc.pdfviewer; import android.graphics.Bitmap; import android.graphics.Rect; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java index eb6fce44..aa9471fa 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/RenderingHandler.java @@ -1,161 +1,161 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Rect; -import android.graphics.RectF; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import com.github.barteksc.pdfviewer.exception.PageRenderingException; -import com.github.barteksc.pdfviewer.model.PagePart; - -/** - * A {@link Handler} that will process incoming {@link RenderingTask} messages - * and alert {@link PDFView#onBitmapRendered(PagePart)} when the portion of the - * PDF is ready to render. - */ -class RenderingHandler extends Handler { - /** - * {@link Message#what} kind of message this handler processes. - */ - static final int MSG_RENDER_TASK = 1; - - private static final String TAG = RenderingHandler.class.getName(); - - private PDFView pdfView; - - private RectF renderBounds = new RectF(); - private Rect roundedRenderBounds = new Rect(); - private Matrix renderMatrix = new Matrix(); - private boolean running = false; - - RenderingHandler(Looper looper, PDFView pdfView) { - super(looper); - this.pdfView = pdfView; - } - - void addRenderingTask(int page, float width, float height, RectF bounds, boolean thumbnail, int cacheOrder, boolean bestQuality, boolean annotationRendering) { - RenderingTask task = new RenderingTask(width, height, bounds, page, thumbnail, cacheOrder, bestQuality, annotationRendering); - Message msg = obtainMessage(MSG_RENDER_TASK, task); - sendMessage(msg); - } - - @Override - public void handleMessage(Message message) { - RenderingTask task = (RenderingTask) message.obj; - try { - final PagePart part = proceed(task); - if (part != null) { - if (running) { - pdfView.post(new Runnable() { - @Override - public void run() { - pdfView.onBitmapRendered(part); - } - }); - } else { - part.getRenderedBitmap().recycle(); - } - } - } catch (final PageRenderingException ex) { - pdfView.post(new Runnable() { - @Override - public void run() { - pdfView.onPageError(ex); - } - }); - } - } - - private PagePart proceed(RenderingTask renderingTask) throws PageRenderingException { - PdfFile pdfFile = pdfView.pdfFile; - pdfFile.openPage(renderingTask.page); - - int w = Math.round(renderingTask.width); - int h = Math.round(renderingTask.height); - - if (w == 0 || h == 0 || pdfFile.pageHasError(renderingTask.page)) { - return null; - } - - Bitmap render; - try { - render = Bitmap.createBitmap(w, h, renderingTask.bestQuality ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Cannot create bitmap", e); - return null; - } - calculateBounds(w, h, renderingTask.bounds); - - pdfFile.renderPageBitmap(render, renderingTask.page, roundedRenderBounds, renderingTask.annotationRendering); - - return new PagePart(renderingTask.page, render, - renderingTask.bounds, renderingTask.thumbnail, - renderingTask.cacheOrder); - } - - private void calculateBounds(int width, int height, RectF pageSliceBounds) { - renderMatrix.reset(); - renderMatrix.postTranslate(-pageSliceBounds.left * width, -pageSliceBounds.top * height); - renderMatrix.postScale(1 / pageSliceBounds.width(), 1 / pageSliceBounds.height()); - - renderBounds.set(0, 0, width, height); - renderMatrix.mapRect(renderBounds); - renderBounds.round(roundedRenderBounds); - } - - void stop() { - running = false; - } - - void start() { - running = true; - } - - private class RenderingTask { - - float width, height; - - RectF bounds; - - int page; - - boolean thumbnail; - - int cacheOrder; - - boolean bestQuality; - - boolean annotationRendering; - - RenderingTask(float width, float height, RectF bounds, int page, boolean thumbnail, int cacheOrder, boolean bestQuality, boolean annotationRendering) { - this.page = page; - this.width = width; - this.height = height; - this.bounds = bounds; - this.thumbnail = thumbnail; - this.cacheOrder = cacheOrder; - this.bestQuality = bestQuality; - this.annotationRendering = annotationRendering; - } - } -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer; + +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.graphics.RectF; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.util.Log; + +import com.github.barteksc.pdfviewer.exception.PageRenderingException; +import com.github.barteksc.pdfviewer.model.PagePart; + +/** + * A {@link Handler} that will process incoming {@link RenderingTask} messages + * and alert {@link PDFView#onBitmapRendered(PagePart)} when the portion of the + * PDF is ready to render. + */ +class RenderingHandler extends Handler { + /** + * {@link Message#what} kind of message this handler processes. + */ + static final int MSG_RENDER_TASK = 1; + + private static final String TAG = RenderingHandler.class.getName(); + + private PDFView pdfView; + + private RectF renderBounds = new RectF(); + private Rect roundedRenderBounds = new Rect(); + private Matrix renderMatrix = new Matrix(); + private boolean running = false; + + RenderingHandler(Looper looper, PDFView pdfView) { + super(looper); + this.pdfView = pdfView; + } + + void addRenderingTask(int page, float width, float height, RectF bounds, boolean thumbnail, int cacheOrder, boolean bestQuality, boolean annotationRendering) { + RenderingTask task = new RenderingTask(width, height, bounds, page, thumbnail, cacheOrder, bestQuality, annotationRendering); + Message msg = obtainMessage(MSG_RENDER_TASK, task); + sendMessage(msg); + } + + @Override + public void handleMessage(Message message) { + RenderingTask task = (RenderingTask) message.obj; + try { + final PagePart part = proceed(task); + if (part != null) { + if (running) { + pdfView.post(new Runnable() { + @Override + public void run() { + pdfView.onBitmapRendered(part); + } + }); + } else { + part.getRenderedBitmap().recycle(); + } + } + } catch (final PageRenderingException ex) { + pdfView.post(new Runnable() { + @Override + public void run() { + pdfView.onPageError(ex); + } + }); + } + } + + private PagePart proceed(RenderingTask renderingTask) throws PageRenderingException { + PdfFile pdfFile = pdfView.pdfFile; + pdfFile.openPage(renderingTask.page); + + int w = Math.round(renderingTask.width); + int h = Math.round(renderingTask.height); + + if (w == 0 || h == 0 || pdfFile.pageHasError(renderingTask.page)) { + return null; + } + + Bitmap render; + try { + render = Bitmap.createBitmap(w, h, renderingTask.bestQuality ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Cannot create bitmap", e); + return null; + } + calculateBounds(w, h, renderingTask.bounds); + + pdfFile.renderPageBitmap(render, renderingTask.page, roundedRenderBounds, renderingTask.annotationRendering); + + return new PagePart(renderingTask.page, render, + renderingTask.bounds, renderingTask.thumbnail, + renderingTask.cacheOrder); + } + + private void calculateBounds(int width, int height, RectF pageSliceBounds) { + renderMatrix.reset(); + renderMatrix.postTranslate(-pageSliceBounds.left * width, -pageSliceBounds.top * height); + renderMatrix.postScale(1 / pageSliceBounds.width(), 1 / pageSliceBounds.height()); + + renderBounds.set(0, 0, width, height); + renderMatrix.mapRect(renderBounds); + renderBounds.round(roundedRenderBounds); + } + + void stop() { + running = false; + } + + void start() { + running = true; + } + + private class RenderingTask { + + float width, height; + + RectF bounds; + + int page; + + boolean thumbnail; + + int cacheOrder; + + boolean bestQuality; + + boolean annotationRendering; + + RenderingTask(float width, float height, RectF bounds, int page, boolean thumbnail, int cacheOrder, boolean bestQuality, boolean annotationRendering) { + this.page = page; + this.width = width; + this.height = height; + this.bounds = bounds; + this.thumbnail = thumbnail; + this.cacheOrder = cacheOrder; + this.bestQuality = bestQuality; + this.annotationRendering = annotationRendering; + } + } +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java index db341137..f0fc6f80 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/FileNotFoundException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.exception; +package com.github.barteksc.pdfviewer.exception; @Deprecated public class FileNotFoundException extends RuntimeException { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java index fa459059..b6ff2b89 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/exception/PageRenderingException.java @@ -1,4 +1,4 @@ -package android.lib.pdfviewer.exception; +package com.github.barteksc.pdfviewer.exception; public class PageRenderingException extends Exception { private final int page; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java index 018b67ec..0849da38 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.link; +package com.github.barteksc.pdfviewer.link; import android.content.Context; import android.content.Intent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java index 5ea3ba9e..f09dc11e 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/LinkHandler.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.link; +package com.github.barteksc.pdfviewer.link; import com.github.barteksc.pdfviewer.model.LinkTapEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java index f0a97436..09becb1c 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/Callbacks.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.listener; +package com.github.barteksc.pdfviewer.listener; import android.view.MotionEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java index 189c05bf..a318ebb6 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnDrawListener.java @@ -1,38 +1,38 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer.listener; - -import android.graphics.Canvas; - -/** - * This interface allows an extern class to draw - * something on the PDFView canvas, above all images. - */ -public interface OnDrawListener { - - /** - * This method is called when the PDFView is - * drawing its view. - *

- * The page is starting at (0,0) - * - * @param canvas The canvas on which to draw things. - * @param pageWidth The width of the current page. - * @param pageHeight The height of the current page. - * @param displayedPage The current page index - */ - void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage); -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer.listener; + +import android.graphics.Canvas; + +/** + * This interface allows an extern class to draw + * something on the PDFView canvas, above all images. + */ +public interface OnDrawListener { + + /** + * This method is called when the PDFView is + * drawing its view. + *

+ * The page is starting at (0,0) + * + * @param canvas The canvas on which to draw things. + * @param pageWidth The width of the current page. + * @param pageHeight The height of the current page. + * @param displayedPage The current page index + */ + void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage); +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java index 45becf9d..876bacfc 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnErrorListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.listener; +package com.github.barteksc.pdfviewer.listener; public interface OnErrorListener { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java index d5cd970f..a52cbc92 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java @@ -1,29 +1,29 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer.listener; - -/** - * Implement this interface to receive events from PDFView - * when loading is complete. - */ -public interface OnLoadCompleteListener { - - /** - * Called when the PDF is loaded - * @param nbPages the number of pages in this PDF file - */ - void loadComplete(int nbPages); -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer.listener; + +/** + * Implement this interface to receive events from PDFView + * when loading is complete. + */ +public interface OnLoadCompleteListener { + + /** + * Called when the PDF is loaded + * @param nbPages the number of pages in this PDF file + */ + void loadComplete(int nbPages); +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java index 052f9703..fc94c726 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLongPressListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.listener; +package com.github.barteksc.pdfviewer.listener; import android.view.MotionEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java index 4fd4432e..0945ca8e 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java @@ -1,32 +1,32 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer.listener; - -/** - * Implements this interface to receive events from PDFView - * when a page has changed through swipe - */ -public interface OnPageChangeListener { - - /** - * Called when the user use swipe to change page - * - * @param page the new page displayed, starting from 0 - * @param pageCount the total page count - */ - void onPageChanged(int page, int pageCount); - -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer.listener; + +/** + * Implements this interface to receive events from PDFView + * when a page has changed through swipe + */ +public interface OnPageChangeListener { + + /** + * Called when the user use swipe to change page + * + * @param page the new page displayed, starting from 0 + * @param pageCount the total page count + */ + void onPageChanged(int page, int pageCount); + +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java index 40a4de38..3fb38a2e 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageErrorListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.listener; +package com.github.barteksc.pdfviewer.listener; public interface OnPageErrorListener { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java index 521eba5c..6eda1fd1 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageScrollListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.listener; +package com.github.barteksc.pdfviewer.listener; /** * Implements this interface to receive events from PDFView diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java index d3e209fe..99982497 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnRenderListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.listener; +package com.github.barteksc.pdfviewer.listener; public interface OnRenderListener { diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java index 6adc13ed..081a3a26 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnTapListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.listener; +package com.github.barteksc.pdfviewer.listener; import android.view.MotionEvent; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java index 660b70e3..7e72bdd3 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/LinkTapEvent.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.model; +package com.github.barteksc.pdfviewer.model; import android.graphics.RectF; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java index e1d03c0b..19a2186f 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java @@ -1,80 +1,80 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer.model; - -import android.graphics.Bitmap; -import android.graphics.RectF; - -public class PagePart { - - private int page; - - private Bitmap renderedBitmap; - - private RectF pageRelativeBounds; - - private boolean thumbnail; - - private int cacheOrder; - - public PagePart(int page, Bitmap renderedBitmap, RectF pageRelativeBounds, boolean thumbnail, int cacheOrder) { - super(); - this.page = page; - this.renderedBitmap = renderedBitmap; - this.pageRelativeBounds = pageRelativeBounds; - this.thumbnail = thumbnail; - this.cacheOrder = cacheOrder; - } - - public int getCacheOrder() { - return cacheOrder; - } - - public int getPage() { - return page; - } - - public Bitmap getRenderedBitmap() { - return renderedBitmap; - } - - public RectF getPageRelativeBounds() { - return pageRelativeBounds; - } - - public boolean isThumbnail() { - return thumbnail; - } - - public void setCacheOrder(int cacheOrder) { - this.cacheOrder = cacheOrder; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof PagePart)) { - return false; - } - - PagePart part = (PagePart) obj; - return part.getPage() == page - && part.getPageRelativeBounds().left == pageRelativeBounds.left - && part.getPageRelativeBounds().right == pageRelativeBounds.right - && part.getPageRelativeBounds().top == pageRelativeBounds.top - && part.getPageRelativeBounds().bottom == pageRelativeBounds.bottom; - } - -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer.model; + +import android.graphics.Bitmap; +import android.graphics.RectF; + +public class PagePart { + + private int page; + + private Bitmap renderedBitmap; + + private RectF pageRelativeBounds; + + private boolean thumbnail; + + private int cacheOrder; + + public PagePart(int page, Bitmap renderedBitmap, RectF pageRelativeBounds, boolean thumbnail, int cacheOrder) { + super(); + this.page = page; + this.renderedBitmap = renderedBitmap; + this.pageRelativeBounds = pageRelativeBounds; + this.thumbnail = thumbnail; + this.cacheOrder = cacheOrder; + } + + public int getCacheOrder() { + return cacheOrder; + } + + public int getPage() { + return page; + } + + public Bitmap getRenderedBitmap() { + return renderedBitmap; + } + + public RectF getPageRelativeBounds() { + return pageRelativeBounds; + } + + public boolean isThumbnail() { + return thumbnail; + } + + public void setCacheOrder(int cacheOrder) { + this.cacheOrder = cacheOrder; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof PagePart)) { + return false; + } + + PagePart part = (PagePart) obj; + return part.getPage() == page + && part.getPageRelativeBounds().left == pageRelativeBounds.left + && part.getPageRelativeBounds().right == pageRelativeBounds.right + && part.getPageRelativeBounds().top == pageRelativeBounds.top + && part.getPageRelativeBounds().bottom == pageRelativeBounds.bottom; + } + +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java index 957adfc0..42c1feab 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java @@ -1,4 +1,4 @@ -package android.lib.pdfviewer.scroll; +package com.github.barteksc.pdfviewer.scroll; import android.content.Context; import android.graphics.Color; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java index 8cf886c1..b58de5a4 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java @@ -1,4 +1,4 @@ -package android.lib.pdfviewer.scroll; +package com.github.barteksc.pdfviewer.scroll; import com.github.barteksc.pdfviewer.PDFView; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java index e82c48c5..3e24e204 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/AssetSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.source; +package com.github.barteksc.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java index 38a72984..245c78fc 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/ByteArraySource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.source; +package com.github.barteksc.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java index 2938d4f1..4c76c5ab 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/DocumentSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.source; +package com.github.barteksc.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java index ea09e9fa..cfe092c8 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/FileSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.source; +package com.github.barteksc.pdfviewer.source; import android.content.Context; import android.os.ParcelFileDescriptor; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java index bdcae2f4..26e60a8d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/InputStreamSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.source; +package com.github.barteksc.pdfviewer.source; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java index a4014f7b..15215f0c 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/source/UriSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.source; +package com.github.barteksc.pdfviewer.source; import android.content.Context; import android.net.Uri; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java index a390dd9e..3fb887d6 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java @@ -1,74 +1,74 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer.util; - -import java.util.ArrayList; -import java.util.List; - -public class ArrayUtils { - - private ArrayUtils() { - // Prevents instantiation - } - - /** Transforms (0,1,2,2,3) to (0,1,2,3) */ - public static int[] deleteDuplicatedPages(int[] pages) { - List result = new ArrayList<>(); - int lastInt = -1; - for (Integer currentInt : pages) { - if (lastInt != currentInt) { - result.add(currentInt); - } - lastInt = currentInt; - } - int[] arrayResult = new int[result.size()]; - for (int i = 0; i < result.size(); i++) { - arrayResult[i] = result.get(i); - } - return arrayResult; - } - - /** Transforms (0, 4, 4, 6, 6, 6, 3) into (0, 1, 1, 2, 2, 2, 3) */ - public static int[] calculateIndexesInDuplicateArray(int[] originalUserPages) { - int[] result = new int[originalUserPages.length]; - if (originalUserPages.length == 0) { - return result; - } - - int index = 0; - result[0] = index; - for (int i = 1; i < originalUserPages.length; i++) { - if (originalUserPages[i] != originalUserPages[i - 1]) { - index++; - } - result[i] = index; - } - - return result; - } - - public static String arrayToString(int[] array) { - StringBuilder builder = new StringBuilder("["); - for (int i = 0; i < array.length; i++) { - builder.append(array[i]); - if (i != array.length - 1) { - builder.append(","); - } - } - builder.append("]"); - return builder.toString(); - } -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer.util; + +import java.util.ArrayList; +import java.util.List; + +public class ArrayUtils { + + private ArrayUtils() { + // Prevents instantiation + } + + /** Transforms (0,1,2,2,3) to (0,1,2,3) */ + public static int[] deleteDuplicatedPages(int[] pages) { + List result = new ArrayList<>(); + int lastInt = -1; + for (Integer currentInt : pages) { + if (lastInt != currentInt) { + result.add(currentInt); + } + lastInt = currentInt; + } + int[] arrayResult = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + arrayResult[i] = result.get(i); + } + return arrayResult; + } + + /** Transforms (0, 4, 4, 6, 6, 6, 3) into (0, 1, 1, 2, 2, 2, 3) */ + public static int[] calculateIndexesInDuplicateArray(int[] originalUserPages) { + int[] result = new int[originalUserPages.length]; + if (originalUserPages.length == 0) { + return result; + } + + int index = 0; + result[0] = index; + for (int i = 1; i < originalUserPages.length; i++) { + if (originalUserPages[i] != originalUserPages[i - 1]) { + index++; + } + result[i] = index; + } + + return result; + } + + public static String arrayToString(int[] array) { + StringBuilder builder = new StringBuilder("["); + for (int i = 0; i < array.length; i++) { + builder.append(array[i]); + if (i != array.length - 1) { + builder.append(","); + } + } + builder.append("]"); + return builder.toString(); + } +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java index 79de4842..bea7e1b6 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Constants.java @@ -1,51 +1,51 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer.util; - -public class Constants { - - public static boolean DEBUG_MODE = false; - - /** Between 0 and 1, the thumbnails quality (default 0.3). Increasing this value may cause performance decrease */ - public static float THUMBNAIL_RATIO = 0.3f; - - /** - * The size of the rendered parts (default 256) - * Tinier : a little bit slower to have the whole page rendered but more reactive. - * Bigger : user will have to wait longer to have the first visual results - */ - public static float PART_SIZE = 256; - - /** Part of document above and below screen that should be preloaded, in dp */ - public static int PRELOAD_OFFSET = 20; - - public static class Cache { - - /** The size of the cache (number of bitmaps kept) */ - public static int CACHE_SIZE = 120; - - public static int THUMBNAILS_CACHE_SIZE = 8; - } - - public static class Pinch { - - public static float MAXIMUM_ZOOM = 10; - - public static float MINIMUM_ZOOM = 1; - - } - -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer.util; + +public class Constants { + + public static boolean DEBUG_MODE = false; + + /** Between 0 and 1, the thumbnails quality (default 0.3). Increasing this value may cause performance decrease */ + public static float THUMBNAIL_RATIO = 0.3f; + + /** + * The size of the rendered parts (default 256) + * Tinier : a little bit slower to have the whole page rendered but more reactive. + * Bigger : user will have to wait longer to have the first visual results + */ + public static float PART_SIZE = 256; + + /** Part of document above and below screen that should be preloaded, in dp */ + public static int PRELOAD_OFFSET = 20; + + public static class Cache { + + /** The size of the cache (number of bitmaps kept) */ + public static int CACHE_SIZE = 120; + + public static int THUMBNAILS_CACHE_SIZE = 8; + } + + public static class Pinch { + + public static float MAXIMUM_ZOOM = 10; + + public static float MINIMUM_ZOOM = 1; + + } + +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java index 0dc054e5..0aa325e9 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FileUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.util; +package com.github.barteksc.pdfviewer.util; import android.content.Context; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java index 21f0365f..6e90dd55 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/FitPolicy.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.util; +package com.github.barteksc.pdfviewer.util; public enum FitPolicy { WIDTH, HEIGHT, BOTH diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java index dfcdcc71..8d9b224f 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/MathUtils.java @@ -1,105 +1,105 @@ -/** - * Copyright 2016 Bartosz Schiller - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.lib.pdfviewer.util; - -public class MathUtils { - - static private final int BIG_ENOUGH_INT = 16 * 1024; - static private final double BIG_ENOUGH_FLOOR = BIG_ENOUGH_INT; - static private final double BIG_ENOUGH_CEIL = 16384.999999999996; - - private MathUtils() { - // Prevents instantiation - } - - /** - * Limits the given number between the other values - * @param number The number to limit. - * @param between The smallest value the number can take. - * @param and The biggest value the number can take. - * @return The limited number. - */ - public static int limit(int number, int between, int and) { - if (number <= between) { - return between; - } - if (number >= and) { - return and; - } - return number; - } - - /** - * Limits the given number between the other values - * @param number The number to limit. - * @param between The smallest value the number can take. - * @param and The biggest value the number can take. - * @return The limited number. - */ - public static float limit(float number, float between, float and) { - if (number <= between) { - return between; - } - if (number >= and) { - return and; - } - return number; - } - - public static float max(float number, float max) { - if (number > max) { - return max; - } - return number; - } - - public static float min(float number, float min) { - if (number < min) { - return min; - } - return number; - } - - public static int max(int number, int max) { - if (number > max) { - return max; - } - return number; - } - - public static int min(int number, int min) { - if (number < min) { - return min; - } - return number; - } - - /** - * Methods from libGDX - https://github.com/libgdx/libgdx - */ - - /** Returns the largest integer less than or equal to the specified float. This method will only properly floor floats from - * -(2^14) to (Float.MAX_VALUE - 2^14). */ - static public int floor(float value) { - return (int) (value + BIG_ENOUGH_FLOOR) - BIG_ENOUGH_INT; - } - - /** Returns the smallest integer greater than or equal to the specified float. This method will only properly ceil floats from - * -(2^14) to (Float.MAX_VALUE - 2^14). */ - static public int ceil(float value) { - return (int) (value + BIG_ENOUGH_CEIL) - BIG_ENOUGH_INT; - } -} +/** + * Copyright 2016 Bartosz Schiller + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer.util; + +public class MathUtils { + + static private final int BIG_ENOUGH_INT = 16 * 1024; + static private final double BIG_ENOUGH_FLOOR = BIG_ENOUGH_INT; + static private final double BIG_ENOUGH_CEIL = 16384.999999999996; + + private MathUtils() { + // Prevents instantiation + } + + /** + * Limits the given number between the other values + * @param number The number to limit. + * @param between The smallest value the number can take. + * @param and The biggest value the number can take. + * @return The limited number. + */ + public static int limit(int number, int between, int and) { + if (number <= between) { + return between; + } + if (number >= and) { + return and; + } + return number; + } + + /** + * Limits the given number between the other values + * @param number The number to limit. + * @param between The smallest value the number can take. + * @param and The biggest value the number can take. + * @return The limited number. + */ + public static float limit(float number, float between, float and) { + if (number <= between) { + return between; + } + if (number >= and) { + return and; + } + return number; + } + + public static float max(float number, float max) { + if (number > max) { + return max; + } + return number; + } + + public static float min(float number, float min) { + if (number < min) { + return min; + } + return number; + } + + public static int max(int number, int max) { + if (number > max) { + return max; + } + return number; + } + + public static int min(int number, int min) { + if (number < min) { + return min; + } + return number; + } + + /** + * Methods from libGDX - https://github.com/libgdx/libgdx + */ + + /** Returns the largest integer less than or equal to the specified float. This method will only properly floor floats from + * -(2^14) to (Float.MAX_VALUE - 2^14). */ + static public int floor(float value) { + return (int) (value + BIG_ENOUGH_FLOOR) - BIG_ENOUGH_INT; + } + + /** Returns the smallest integer greater than or equal to the specified float. This method will only properly ceil floats from + * -(2^14) to (Float.MAX_VALUE - 2^14). */ + static public int ceil(float value) { + return (int) (value + BIG_ENOUGH_CEIL) - BIG_ENOUGH_INT; + } +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java index d8fbc712..e7f35a3b 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.util; +package com.github.barteksc.pdfviewer.util; import android.app.Activity; import android.util.Log; diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java index b419a950..e2e73ab7 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/SnapEdge.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.util; +package com.github.barteksc.pdfviewer.util; public enum SnapEdge { START, CENTER, END, NONE diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java index 0d8dff09..58e473e0 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/Util.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.lib.pdfviewer.util; +package com.github.barteksc.pdfviewer.util; import android.content.Context; import android.util.TypedValue; From fa43c89c227b1c66168ba4e981bd00b7378fcb62 Mon Sep 17 00:00:00 2001 From: Arnaud Delubac Date: Thu, 19 Dec 2019 11:49:33 +0100 Subject: [PATCH 4/5] updating gradle tool --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0a9a0ba0..03a38f03 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.android.tools.build:gradle:3.5.2' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } From 2d54d51d19f9cca4432f4626d2cf7b8406e6e2d2 Mon Sep 17 00:00:00 2001 From: Arnaud Delubac Date: Fri, 20 Dec 2019 08:52:32 +0100 Subject: [PATCH 5/5] Fixing compilation issue because of gradle version --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- sample/src/main/res/layout/activity_main.xml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 03a38f03..cddca95e 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.4.2' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } @@ -16,4 +16,4 @@ allprojects { google() jcenter() } -} +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1a59b22b..285c4261 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index a14dd73d..fb1cf589 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -3,9 +3,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + \ No newline at end of file